diff --git a/.editorconfig b/.editorconfig index 988cb95f5e42e..206960dd7dd15 100644 --- a/.editorconfig +++ b/.editorconfig @@ -86,6 +86,10 @@ indent_size = 8 [COMMIT_EDITMSG] max_line_length = 75 +# Patches +[{*.patch,*.diff}] +trim_trailing_whitespace = false + # Kconfig [Kconfig*] indent_style = tab diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 15d61c7169112..0beea159b462a 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -337,6 +337,7 @@ Arduino Platforms: - boards/arduino/ - boards/shields/arduino_*/ - drivers/*/*modulino* + - dts/vendor/arduino/ Base OS: status: maintained @@ -855,8 +856,6 @@ CPU Frequency Scaling: - seankyer files: - include/zephyr/cpu_freq/ - - include/zephyr/cpu_load/ - - subsys/cpu_load/ - subsys/cpu_freq/ - dts/bindings/p_state/ labels: @@ -1275,6 +1274,7 @@ Documentation Infrastructure: - martinjaeger - str4t0m files: + - boards/shields/canis_canpico/ - boards/shields/mcp2515/ - boards/shields/tcan4550evm/ - doc/connectivity/canbus/ @@ -3047,9 +3047,10 @@ JSON Web Token: - libraries.encoding.jwt Kconfig: - status: odd fixes - collaborators: + status: maintained + maintainers: - tejlmand + collaborators: - nashif files: - scripts/kconfig/ @@ -4882,10 +4883,13 @@ TI SimpleLink Platforms: status: maintained maintainers: - vaishnavachath + collaborators: + - bogdanovs files: - boards/ti/cc*/ - boards/ti/msp*/ - drivers/*/*cc13* + - drivers/*/*cc23* - drivers/*/*cc25* - drivers/*/*cc26* - drivers/*/*cc32* @@ -6099,10 +6103,7 @@ West: - thrift "West project: trusted-firmware-a": - status: maintained - maintainers: - - povergoing - - sgrrzhf + status: odd fixes collaborators: - wearyzen - ithinuel diff --git a/arch/Kconfig b/arch/Kconfig index 7bcfb4d3ffd8d..4fca0c3c60262 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -57,6 +57,7 @@ config ARM64 select ARCH_HAS_DEMAND_MAPPING select ARCH_SUPPORTS_EVICTION_TRACKING select EVICTION_TRACKING if DEMAND_PAGING + select MEM_DOMAIN_HAS_THREAD_LIST if ARM_MPU help ARM64 (AArch64) architecture diff --git a/arch/arm/core/mpu/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c index 0bf7a219c27d7..f5f725a75fb6a 100644 --- a/arch/arm/core/mpu/arm_mpu_regions.c +++ b/arch/arm/core/mpu/arm_mpu_regions.c @@ -7,7 +7,7 @@ #include #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { #ifdef CONFIG_XIP diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 3053d90cb75f6..69fc72acda35a 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -760,8 +760,8 @@ static int configure_domain_partitions(struct k_mem_domain *domain) struct k_thread *thread; int ret; - SYS_DLIST_FOR_EACH_CONTAINER(&domain->mem_domain_q, thread, - mem_domain_info.mem_domain_q_node) { + SYS_DLIST_FOR_EACH_CONTAINER(&domain->thread_mem_domain_list, thread, + mem_domain_info.thread_mem_domain_node) { ret = configure_dynamic_mpu_regions(thread); if (ret != 0) { return ret; diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index 7aca54e4eea08..9ecb2c975db9c 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -168,20 +168,35 @@ static inline void z_riscv_pmp_write_config(unsigned long *pmp_cfg, size_t pmp_c #endif } -static void dump_pmp_regs(const char *banner) +/** + * @brief Reads the PMP address CSRs (pmpaddrX) for all configured slots. + * + * This helper function abstracts the iterative logic required to read the + * individual PMP address registers (pmpaddr0, pmpaddr1, ..., pmpaddrN) + * up to the total number of PMP slots configured by CONFIG_PMP_SLOTS. + * + * @param pmp_addr Pointer to the array where the CSR contents will be stored. + * @param pmp_addr_size The size of the pmp_addr array, measured in unsigned long entries. + */ +static inline void z_riscv_pmp_read_addr(unsigned long *pmp_addr, size_t pmp_addr_size) { - unsigned long pmp_addr[CONFIG_PMP_SLOTS]; - unsigned long pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE]; + __ASSERT(pmp_addr_size == (size_t)(CONFIG_PMP_SLOTS), "PMP address array size mismatch"); #define PMPADDR_READ(x) pmp_addr[x] = csr_read(pmpaddr##x) - FOR_EACH(PMPADDR_READ, (;), 0, 1, 2, 3, 4, 5, 6, 7); + #if CONFIG_PMP_SLOTS > 8 FOR_EACH(PMPADDR_READ, (;), 8, 9, 10, 11, 12, 13, 14, 15); #endif - #undef PMPADDR_READ +} + +static void dump_pmp_regs(const char *banner) +{ + unsigned long pmp_addr[CONFIG_PMP_SLOTS]; + unsigned long pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE]; + z_riscv_pmp_read_addr(pmp_addr, (size_t)(CONFIG_PMP_SLOTS)); z_riscv_pmp_read_config(pmp_cfg, (size_t)(CONFIG_PMP_SLOTS / PMPCFG_STRIDE)); print_pmp_entries(0, CONFIG_PMP_SLOTS, pmp_addr, pmp_cfg, banner); } diff --git a/boards/01space/esp32c3_042_oled/doc/index.rst b/boards/01space/esp32c3_042_oled/doc/index.rst index 801e8651cfa67..f51a329b605f1 100644 --- a/boards/01space/esp32c3_042_oled/doc/index.rst +++ b/boards/01space/esp32c3_042_oled/doc/index.rst @@ -3,7 +3,7 @@ Overview ******** -ESP32C3 0.42 OLED is a mini development board based on the `Espressif ESP32-C3`_ +ESP32-C3 0.42 OLED is a mini development board based on the `Espressif ESP32-C3`_ RISC-V WiFi/Bluetooth dual-mode chip. For more details see the `01space ESP32C3 0.42 OLED`_ Github repo. @@ -31,10 +31,8 @@ It features: The ESP32-C3 does not have native USB, it has an on-chip USB-serial converter instead. -Supported Features -================== - -.. zephyr:board-supported-hw:: +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Connections and IOs =================== @@ -50,87 +48,28 @@ See the following image: It also features a 0.42 inch OLED display, driven by a SSD1306-compatible chip. It is connected over I2C: SDA on GPIO5, SCL on GPIO6. -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs. Run the command below to -retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +System Requirements +******************* - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Standalone application -====================== - -The board can be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - This mode does not provide any security features nor OTA updates. - -Use the following command to build a sample hello_world application: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_042_oled - :goals: build - -Sysbuild -======== - -:ref:`sysbuild` makes it possible to build and flash all necessary images needed to -bootstrap the board. - -By default, the ESP32 sysbuild configuration creates bootloader (MCUboot) and -application images. - -To build the sample application using sysbuild, use this command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32c3_042_oled - :goals: build - :west-args: --sysbuild - :compact: - -Flashing -======== - -For the :code:`Hello, world!` application, follow the instructions below. -Assuming the board is connected to ``/dev/ttyACM0`` on Linux. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_042_oled - :goals: flash - :flash-args: --esp-device /dev/ttyACM0 - -Since the Zephyr console is by default on the ``usb_serial`` device, we use -the espressif monitor utility to connect to the console. - -.. code-block:: console - - $ west espressif monitor -p /dev/ttyACM0 +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32c3_042_oled +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** diff --git a/boards/96boards/meerkat96/doc/index.rst b/boards/96boards/meerkat96/doc/index.rst index c76229de75b4a..52238cf795f66 100644 --- a/boards/96boards/meerkat96/doc/index.rst +++ b/boards/96boards/meerkat96/doc/index.rst @@ -1,4 +1,4 @@ -.. _96b_meerkat96: +.. zephyr:board:: 96b_meerkat96 96Boards Meerkat96 ################## @@ -35,10 +35,6 @@ Zephyr OS is ported to run on the Cortex®-M4 core. - 1x Blue Bluetooth LED - 1x Yellow WiFi LED -.. image:: img/96b_meerkat96.jpg - :align: center - :alt: 96Boards Meerkat96 - More information about the board can be found at the `96Boards website`_. @@ -91,27 +87,7 @@ More information about the i.MX7 SoC can be found here: Supported Features ================== -The Zephyr 96b_meerkat96 board configuration supports the following hardware -features: - -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ - -The default configuration can be found in the defconfig file: - - :zephyr_file:`boards/96boards/meerkat96/96b_meerkat96_mcimx7d_m4_defconfig` - -Other hardware features are not currently supported by the port. +.. zephyr:board-supported-hw:: Connections and IOs =================== diff --git a/boards/adafruit/feather_esp32/doc/index.rst b/boards/adafruit/feather_esp32/doc/index.rst index 9c6141ae0d7e9..a9c6928367b3d 100644 --- a/boards/adafruit/feather_esp32/doc/index.rst +++ b/boards/adafruit/feather_esp32/doc/index.rst @@ -6,6 +6,9 @@ Overview The Adafruit ESP32 Feather is an ESP32-based development board using the Feather standard layout. +Hardware +******** + It features the following integrated components: - ESP32-PICO-V3-02 chip (240MHz dual core, Wi-Fi + BLE) @@ -17,51 +20,42 @@ It features the following integrated components: - Reset and user buttons - STEMMA QT I2C connector +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run -the commands below to retrieve the files. - -.. code-block:: shell +System Requirements +******************* - west update - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Building & flashing -------------------- +Programming and Debugging +************************* -Use the standard build and flash process for this board. See -:ref:`build_an_application` and :ref:`application_run` for more details. +.. zephyr:board-supported-runners:: -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32/esp32/procpu - :goals: build flash +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -After flashing, view the serial monitor with the espressif monitor command. +Debugging +========= -.. code-block:: shell - - west espressif monitor +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging Testing -======= +******* On-board LED ------------- +============ Test the functionality of the user LED connected to pin 13 with the blinky sample program. @@ -72,7 +66,7 @@ sample program. :goals: build flash NeoPixel --------- +======== Test the on-board NeoPixel using the led_strip sample program. @@ -82,7 +76,7 @@ Test the on-board NeoPixel using the led_strip sample program. :goals: build flash User button ------------ +=========== Test the button labeled SW38 using the button input sample program. @@ -92,7 +86,7 @@ Test the button labeled SW38 using the button input sample program. :goals: build flash Wi-Fi ------ +===== Test ESP32 Wi-Fi functionality using the Wi-Fi shell module. @@ -106,8 +100,11 @@ Test ESP32 Wi-Fi functionality using the Wi-Fi shell module. References ********** -- `Adafruit ESP32 Feather V2 `_ -- `Adafruit ESP32 Feather V2 Pinouts `_ -- `Adafruit ESP32 Feather V2 Schematic `_ -- `ESP32-PICO-MINI-02 Datasheet `_ (PDF) -- `STEMMA QT `_ + +.. target-notes:: + +.. _`Adafruit ESP32 Feather V2`: https://www.adafruit.com/product/5400 +.. _`Adafruit ESP32 Feather V2 Pinouts`: https://learn.adafruit.com/adafruit-esp32-feather-v2/pinouts +.. _`Adafruit ESP32 Feather V2 Schematic`: https://learn.adafruit.com/adafruit-esp32-feather-v2/downloads#schematic-and-fab-print-3112284 +.. _`ESP32-PICO-MINI-02 Datasheet`: https://cdn-learn.adafruit.com/assets/assets/000/109/588/original/esp32-pico-mini-02_datasheet_en.pdf?1646852017 +.. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt diff --git a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2.rst b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2.rst index 00779bc87e3f0..b8cef7b3d7f98 100644 --- a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2.rst +++ b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2.rst @@ -38,14 +38,17 @@ Hardware NeoPixel and I2C QT port on ``rev B`` boards ``GPIO7`` (``i2c_reg``) needs to be set to LOW and on ``rev C`` boards it needs to be set HIGH. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: .. note:: - USB-OTG is until now not supported see `ESP32 development overview`_. To see a serial output - a FTDI-USB-RS232 or similar needs to be connected to the RX/TX pins on the feather connector. + USB-OTG is until now not supported. To see a serial output a FTDI-USB-RS232 or similar + needs to be connected to the RX/TX pins on the feather connector. Connections and IOs =================== @@ -56,211 +59,28 @@ pinouts and the schematic. - `Adafruit ESP32-S2 Feather Pinouts`_ - `Adafruit ESP32-S2 Feather Schematic`_ -Programming and Debugging -************************* - -.. zephyr:board-supported-runners:: - -Prerequisites -============= - -Espressif HAL requires WiFi binary blobs in order work. Run the command below -to retrieve those files. - -.. code-block:: console - - west update - west blobs fetch hal_espressif - -Building & Flashing +System Requirements ******************* -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -**Rev B** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@B - :goals: build - :west-args: --sysbuild - :compact: - -**Rev C** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@C - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual: - -**Rev B** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@B - :goals: build - -**Rev C** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@C - :goals: build - -The usual ``flash`` target will work. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -To enter ROM bootloader mode, hold down ``boot-button`` while clicking reset button. -When in the ROM bootloader, you can upload code and query the chip using ``west flash``. - - -**Rev B** - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@B - :goals: flash - -**Rev C** - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@C - :goals: flash - -After the flashing you will receive most likely this Error: - -.. code-block:: console - - WARNING: ESP32-S2FNR2 (revision v0.0) chip was placed into download mode using GPIO0. - esptool.py can not exit the download mode over USB. To run the app, reset the chip manually. - To suppress this note, set --after option to 'no_reset'. - FATAL ERROR: command exited with status 1: ... - -As stated in the Warning-Message ``esptool`` can't reset the board by itself and this message -can be ignored and the board needs to be reseted via the Reset-Button manually. - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor +Programming and Debugging +************************* -After the board has been manually reseted and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s2 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S2 support on OpenOCD is available at `OpenOCD`_. +========= -ESP32-S2 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor -in `JTAG debugging for ESP32-S2`_. - -You can debug an application in the usual way. Here is an example for -the :zephyr:code-sample:`hello_world` application. - -**Rev B** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@B - :goals: debug - -**Rev C** - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2@C - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging Testing the On-Board-LED ************************ @@ -392,10 +212,7 @@ References .. _`Adafruit ESP32-S2 Feather`: https://www.adafruit.com/product/5000 .. _`Adafruit ESP32-S2 Feather with BME280 Sensor`: https://www.adafruit.com/product/5303 -.. _`OpenOCD`: https://github.com/openocd-org/openocd -.. _`ESP32 development overview`: https://github.com/zephyrproject-rtos/zephyr/issues/29394#issuecomment-2635037831 .. _`Adafruit ESP32-S2 Feather Pinouts`: https://learn.adafruit.com/adafruit-esp32-s2-feather/pinouts .. _`Adafruit ESP32-S2 Feather Schematic`: https://learn.adafruit.com/adafruit-esp32-s2-feather/downloads .. _`SparkFun Qwiic`: https://www.sparkfun.com/qwiic .. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt -.. _`JTAG debugging for ESP32-S2`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-guides/jtag-debugging/index.html diff --git a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft.rst b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft.rst index 6629b57feee6d..b04a4e19400ea 100644 --- a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft.rst +++ b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft.rst @@ -31,14 +31,17 @@ Hardware - For the MAX17048 and LC709203F a driver in zephyr exists and is supported, but needs to be added via a devicetree overlay. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: .. note:: - USB-OTG is until now not supported see `ESP32 development overview`_. To see a serial output - a FTDI-USB-RS232 or similar needs to be connected to the RX/TX pins on the feather connector. + USB-OTG is until now not supported. To see a serial output a FTDI-USB-RS232 or similar + needs to be connected to the RX/TX pins on the feather connector. Connections and IOs =================== @@ -49,183 +52,28 @@ pinouts and the schematic. - `Adafruit ESP32-S2 TFT Feather Pinouts`_ - `Adafruit ESP32-S2 TFT Feather Schematic`_ -Programming and Debugging -************************* - -.. zephyr:board-supported-runners:: - -Prerequisites -============= - -Espressif HAL requires WiFi binary blobs in order work. Run the command below -to retrieve those files. - -.. code-block:: console - - west update - west blobs fetch hal_espressif - -Building & Flashing +System Requirements ******************* -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft - :goals: build - -The usual ``flash`` target will work. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -To enter ROM bootloader mode, hold down ``boot-button`` while clicking reset button. -When in the ROM bootloader, you can upload code and query the chip using ``west flash``. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft - :goals: flash - -After the flashing you will receive most likely this Error: - -.. code-block:: console - - WARNING: ESP32-S2FNR2 (revision v0.0) chip was placed into download mode using GPIO0. - esptool.py can not exit the download mode over USB. To run the app, reset the chip manually. - To suppress this note, set --after option to 'no_reset'. - FATAL ERROR: command exited with status 1: ... - -As stated in the Warning-Message ``esptool`` can't reset the board by itself and this message -can be ignored and the board needs to be reseted via the Reset-Button manually. - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor +Programming and Debugging +************************* -After the board has been manually reseted and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s2_tft +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S2 support on OpenOCD is available at `OpenOCD`_. - -ESP32-S2 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor -in `JTAG debugging for ESP32-S2`_. - -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: adafruit_feather_esp32s2_tft - :goals: debug - -Testing the On-Board-LED -************************ - -There is a sample available to verify that the LEDs on the board are -functioning correctly with Zephyr: - -.. zephyr-app-commands:: - :zephyr-app: samples/basic/blinky - :board: adafruit_feather_esp32s2_tft - :goals: build flash +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging Testing the NeoPixel ******************** @@ -318,10 +166,7 @@ References .. target-notes:: .. _`Adafruit ESP32-S2 TFT Feather`: https://www.adafruit.com/product/5300 -.. _`OpenOCD`: https://github.com/openocd-org/openocd -.. _`ESP32 development overview`: https://github.com/zephyrproject-rtos/zephyr/issues/29394#issuecomment-2635037831 .. _`Adafruit ESP32-S2 TFT Feather Pinouts`: https://learn.adafruit.com/adafruit-esp32-s2-tft-feather/pinouts .. _`Adafruit ESP32-S2 TFT Feather Schematic`: https://learn.adafruit.com/adafruit-esp32-s2-tft-feather/downloads .. _`SparkFun Qwiic`: https://www.sparkfun.com/qwiic .. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt -.. _`JTAG debugging for ESP32-S2`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-guides/jtag-debugging/index.html diff --git a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft_reverse.rst b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft_reverse.rst index ad90a07858204..3195a242aa6b2 100644 --- a/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft_reverse.rst +++ b/boards/adafruit/feather_esp32s2/doc/adafruit_feather_esp32s2_tft_reverse.rst @@ -27,14 +27,17 @@ Hardware - For the MAX17048 a driver in zephyr exists and is supported, but needs to be added via a devicetree overlay. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: .. note:: - USB-OTG is until now not supported see `ESP32 development overview`_. To see a serial output - a FTDI-USB-RS232 or similar needs to be connected to the RX/TX pins on the feather connector. + USB-OTG is until now not supported. To see a serial output a FTDI-USB-RS232 or similar + needs to be connected to the RX/TX pins on the feather connector. Connections and IOs =================== @@ -45,172 +48,28 @@ including pinouts and the schematic. - `Adafruit ESP32-S2 Reverse TFT Feather Pinouts`_ - `Adafruit ESP32-S2 Reverse TFT Feather Schematic`_ -Programming and Debugging -************************* - -.. zephyr:board-supported-runners:: - -Prerequisites -============= - -Espressif HAL requires WiFi binary blobs in order work. Run the command below -to retrieve those files. - -.. code-block:: console - - west update - west blobs fetch hal_espressif - -Building & Flashing +System Requirements ******************* -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft_reverse - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft_reverse - :goals: build - -The usual ``flash`` target will work. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -To enter ROM bootloader mode, hold down ``boot-button`` while clicking reset button. -When in the ROM bootloader, you can upload code and query the chip using ``west flash``. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s2_tft_reverse - :goals: flash - -After the flashing you will receive most likely this Error: - -.. code-block:: console - - WARNING: ESP32-S2FNR2 (revision v0.0) chip was placed into download mode using GPIO0. - esptool.py can not exit the download mode over USB. To run the app, reset the chip manually. - To suppress this note, set --after option to 'no_reset'. - FATAL ERROR: command exited with status 1: ... - -As stated in the Warning-Message ``esptool`` can't reset the board by itself and this message -can be ignored and the board needs to be reseted via the Reset-Button manually. - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor +Programming and Debugging +************************* -After the board has been manually reseted and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s2_tft_reverse +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S2 support on OpenOCD is available at `OpenOCD`_. - -ESP32-S2 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. +========= -Further documentation can be obtained from the SoC vendor -in `JTAG debugging for ESP32-S2`_. - -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: adafruit_feather_esp32s2_tft_reverse - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging Testing the On-Board-LED ************************ @@ -280,10 +139,7 @@ References .. target-notes:: .. _`Adafruit ESP32-S2 Reverse TFT Feather`: https://www.adafruit.com/product/5345 -.. _`OpenOCD`: https://github.com/openocd-org/openocd -.. _`ESP32 development overview`: https://github.com/zephyrproject-rtos/zephyr/issues/29394#issuecomment-2635037831 .. _`Adafruit ESP32-S2 Reverse TFT Feather Pinouts`: https://learn.adafruit.com/esp32-s2-reverse-tft-feather/pinouts .. _`Adafruit ESP32-S2 Reverse TFT Feather Schematic`: https://learn.adafruit.com/esp32-s2-reverse-tft-feather/downloads .. _`SparkFun Qwiic`: https://www.sparkfun.com/qwiic .. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt -.. _`JTAG debugging for ESP32-S2`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-guides/jtag-debugging/index.html diff --git a/boards/adafruit/feather_esp32s3/doc/index.rst b/boards/adafruit/feather_esp32s3/doc/index.rst index 17332ba68fab6..d4fc4a1d12a76 100644 --- a/boards/adafruit/feather_esp32s3/doc/index.rst +++ b/boards/adafruit/feather_esp32s3/doc/index.rst @@ -23,59 +23,13 @@ Hardware - Built-in NeoPixel indicator RGB LED - STEMMA QT connector for I2C devices, with switchable power for low-power mode -Asymmetric Multiprocessing (AMP) -================================ - -The ESP32-S3 SoC allows 2 different applications to be executed in asymmetric -multiprocessing. Due to its dual-core architecture, each core can be enabled to -execute customized tasks in stand-alone mode and/or exchanging data over OpenAMP -framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== -The current ``adafruit_feather_esp32s3`` board supports the following hardware -features: - -+------------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+============+============+=====================================+ -| UART | on-chip | serial port | -+------------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+------------+------------+-------------------------------------+ -| PINMUX | on-chip | pinmux | -+------------+------------+-------------------------------------+ -| USB-JTAG | on-chip | hardware interface | -+------------+------------+-------------------------------------+ -| SPI Master | on-chip | spi | -+------------+------------+-------------------------------------+ -| TWAI/CAN | on-chip | can | -+------------+------------+-------------------------------------+ -| ADC | on-chip | adc | -+------------+------------+-------------------------------------+ -| Timers | on-chip | counter | -+------------+------------+-------------------------------------+ -| Watchdog | on-chip | watchdog | -+------------+------------+-------------------------------------+ -| TRNG | on-chip | entropy | -+------------+------------+-------------------------------------+ -| LEDC | on-chip | pwm | -+------------+------------+-------------------------------------+ -| MCPWM | on-chip | pwm | -+------------+------------+-------------------------------------+ -| PCNT | on-chip | qdec | -+------------+------------+-------------------------------------+ -| GDMA | on-chip | dma | -+------------+------------+-------------------------------------+ -| USB-CDC | on-chip | serial | -+------------+------------+-------------------------------------+ -| Wi-Fi | on-chip | | -+------------+------------+-------------------------------------+ -| Bluetooth | on-chip | | -+------------+------------+-------------------------------------+ +.. zephyr:board-supported-hw:: Connections and IOs =================== @@ -83,199 +37,35 @@ Connections and IOs The `Adafruit Feather ESP32-S3 User Guide`_ has detailed information about the board including `pinouts`_ and the `schematic`_. +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the -command below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -=================== - -Simple boot ------------ - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader ------------------- - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be build (and flash) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild --------- - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-S3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-S3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` -documentation. - -Manual build ------------- - -During the development cycle, it is intended to build & flash as quickly -possible. For that reason, images can be build one at a time using traditional -build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``adafruit_feather_esp32s3`` board -. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ========= -ESP32-S3 support on OpenOCD is available upstream as of version 0.12.0. Download -and install OpenOCD from `OpenOCD`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging -for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3/esp32s3/procpu - :goals: build flash - -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: adafruit_feather_esp32s3/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _`Adafruit Feather ESP32-S3`: - https://www.adafruit.com/product/5323 - -.. _`OpenOCD`: - https://github.com/openocd-org/openocd - -.. _`JTAG debugging for ESP32-S3`: - https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ - -.. _Adafruit Feather ESP32-S3 User Guide: - https://learn.adafruit.com/adafruit-esp32-s3-feather - -.. _pinouts: - https://learn.adafruit.com/adafruit-esp32-s3-feather/pinouts - -.. _schematic: - https://learn.adafruit.com/adafruit-esp32-s3-feather/downloads - -.. _ESP32-S3 Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf - -.. _ESP32 Technical Reference Manual: - https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf +.. _`Adafruit Feather ESP32-S3`: https://www.adafruit.com/product/5323 +.. _`Adafruit Feather ESP32-S3 User Guide`: https://learn.adafruit.com/adafruit-esp32-s3-feather +.. _`pinouts`: https://learn.adafruit.com/adafruit-esp32-s3-feather/pinouts +.. _`schematic`: https://learn.adafruit.com/adafruit-esp32-s3-feather/downloads diff --git a/boards/adafruit/feather_esp32s3_tft/doc/index.rst b/boards/adafruit/feather_esp32s3_tft/doc/index.rst index 7324debe849da..af2e61d0a2f68 100644 --- a/boards/adafruit/feather_esp32s3_tft/doc/index.rst +++ b/boards/adafruit/feather_esp32s3_tft/doc/index.rst @@ -25,15 +25,8 @@ Hardware - STEMMA QT connector for I2C devices, with switchable power for low-power mode - 240x135 pixel IPS TFT color display with 1.14" diagonal and ST7789 chipset -Asymmetric Multiprocessing (AMP) -================================ - -The ESP32-S3 SoC allows 2 different applications to be executed in asymmetric -multiprocessing. Due to its dual-core architecture, each core can be enabled to -execute customized tasks in stand-alone mode and/or exchanging data over OpenAMP -framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== @@ -85,199 +78,35 @@ Connections and IOs The `Adafruit Feather ESP32-S3 TFT User Guide`_ has detailed information about the board including `pinouts`_ and the `schematic`_. +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the -command below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -=================== - -Simple boot ------------ - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader ------------------- - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be build (and flash) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild --------- - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-S3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-S3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` -documentation. - -Manual build ------------- - -During the development cycle, it is intended to build & flash as quickly -possible. For that reason, images can be build one at a time using traditional -build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``adafruit_feather_esp32s3_tft`` -board. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s3_tft +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ========= -ESP32-S3 support on OpenOCD is available upstream as of version 0.12.0. Download -and install OpenOCD from `OpenOCD`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging -for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft/esp32s3/procpu - :goals: build flash - -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: adafruit_feather_esp32s3_tft/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _`Adafruit Feather ESP32-S3 TFT`: - https://www.adafruit.com/product/5483 - -.. _`OpenOCD`: - https://github.com/openocd-org/openocd - -.. _`JTAG debugging for ESP32-S3`: - https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ - -.. _Adafruit Feather ESP32-S3 TFT User Guide: - https://learn.adafruit.com/adafruit-esp32-s3-tft-feather - -.. _pinouts: - https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/pinouts - -.. _schematic: - https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/downloads - -.. _ESP32-S3 Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf - -.. _ESP32 Technical Reference Manual: - https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf +.. _`Adafruit Feather ESP32-S3 TFT`: https://www.adafruit.com/product/5483 +.. _`Adafruit Feather ESP32-S3 TFT User Guide`: https://learn.adafruit.com/adafruit-esp32-s3-tft-feather +.. _`pinouts`: https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/pinouts +.. _`schematic`: https://learn.adafruit.com/adafruit-esp32-s3-tft-feather/downloads diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/doc/index.rst b/boards/adafruit/feather_esp32s3_tft_reverse/doc/index.rst index 98135629d74b2..2df52d4526a48 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/doc/index.rst +++ b/boards/adafruit/feather_esp32s3_tft_reverse/doc/index.rst @@ -29,16 +29,8 @@ Hardware - Three User Tactile buttons - D0, D1, and D2. D0/BOOT0 is also used for entering ROM bootloader mode if necessary. - -Asymmetric Multiprocessing (AMP) -================================ - -The ESP32-S3 SoC allows 2 different applications to be executed in asymmetric -multiprocessing. Due to its dual-core architecture, each core can be enabled to -execute customized tasks in stand-alone mode and/or exchanging data over OpenAMP -framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== @@ -51,199 +43,35 @@ Connections and IOs The `Adafruit ESP32-S3 Reverse TFT Feather User Guide`_ has detailed information about the board including `pinouts`_ and the `schematic`_. +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the -command below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -=================== - -Simple boot ------------ - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader ------------------- - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be build (and flash) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild --------- - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-S3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-S3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` -documentation. - -Manual build ------------- - -During the development cycle, it is intended to build & flash as quickly -possible. For that reason, images can be build one at a time using traditional -build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: :board: adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``adafruit_feather_esp32s3_tft_reverse`` -board. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ========= -ESP32-S3 support on OpenOCD is available upstream as of version 0.12.0. Download -and install OpenOCD from `OpenOCD`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging -for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu - :goals: build flash - -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: adafruit_feather_esp32s3_tft_reverse/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _`Adafruit ESP32-S3 Reverse TFT Feather`: - https://www.adafruit.com/product/5691 - -.. _`OpenOCD`: - https://github.com/openocd-org/openocd - -.. _`JTAG debugging for ESP32-S3`: - https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ - -.. _Adafruit ESP32-S3 Reverse TFT Feather User Guide: - https://learn.adafruit.com/esp32-s3-reverse-tft-feather - -.. _pinouts: - https://learn.adafruit.com/esp32-s3-reverse-tft-feather/pinouts - -.. _schematic: - https://learn.adafruit.com/esp32-s3-reverse-tft-feather/downloads - -.. _ESP32-S3 Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf - -.. _ESP32 Technical Reference Manual: - https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf +.. _`Adafruit ESP32-S3 Reverse TFT Feather`: https://www.adafruit.com/product/5691 +.. _`Adafruit ESP32-S3 Reverse TFT Feather User Guide`: https://learn.adafruit.com/esp32-s3-reverse-tft-feather +.. _`pinouts`: https://learn.adafruit.com/esp32-s3-reverse-tft-feather/pinouts +.. _`schematic`: https://learn.adafruit.com/esp32-s3-reverse-tft-feather/downloads diff --git a/boards/adafruit/qt_py_esp32s3/doc/index.rst b/boards/adafruit/qt_py_esp32s3/doc/index.rst index 8ad715a673c0d..57f47442c784e 100644 --- a/boards/adafruit/qt_py_esp32s3/doc/index.rst +++ b/boards/adafruit/qt_py_esp32s3/doc/index.rst @@ -23,222 +23,36 @@ bootloader or user input. Like many other Adafruit boards, it has a `SparkFun Qwiic`_-compatible `STEMMA QT`_ connector for the I2C bus so you don't even need to solder. -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated -2.4 GHz Wi-Fi and Bluetooth® Low Energy (Bluetooth LE). It consists of -high-performance dual-core microprocessor (Xtensa® 32-bit LX7), a low power -coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, RF module, and -numerous peripherals. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== .. zephyr:board-supported-hw:: -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the -command below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage -bootloader. It is the default option when building the application without -additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. +Programming and Debugging +************************* -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. tabs:: - - .. group-tab:: QT Py ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3/esp32s3/procpu - :goals: build - - .. group-tab:: QT Py ESP32S3 with PSRAM - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``adafruit_qt_py_esp32s3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. tabs:: - - .. group-tab:: QT Py ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3/esp32s3/procpu - :goals: flash - - .. group-tab:: QT Py ESP32S3 with PSRAM - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! adafruit_qt_py_esp32s3/esp32s3/procpu +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any -additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor -in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. tabs:: - - .. group-tab:: QT Py ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3/esp32s3/procpu - :goals: debug - - .. group-tab:: QT Py ESP32S3 with PSRAM - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu - :goals: debug - -You can debug an application in the usual way. Here is an example for -the :zephyr:code-sample:`hello_world` application. - -.. tabs:: - - .. group-tab:: QT Py ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3/esp32s3/procpu - :goals: debug - - .. group-tab:: QT Py ESP32S3 with PSRAM +========= - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -247,7 +61,5 @@ References .. _`Adafruit QT Py ESP32S3`: https://www.adafruit.com/product/5426 .. _`Adafruit QT Py ESP32S3 - PSRAM`: https://www.adafruit.com/product/5700 -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases .. _`SparkFun Qwiic`: https://www.sparkfun.com/qwiic .. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt diff --git a/boards/adi/max32658evkit/Kconfig.defconfig b/boards/adi/max32658evkit/Kconfig.defconfig new file mode 100644 index 0000000000000..8235ba516f2b5 --- /dev/null +++ b/boards/adi/max32658evkit/Kconfig.defconfig @@ -0,0 +1,48 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MAX32658EVKIT + +# Code Partition: +# +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +if BOARD_MAX32658EVKIT_MAX32658_NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +# MAX32658 has one UART interface, +# It can be used either on TFM or Zephyr +# Enabling debug (TFM_SPM_LOG_LEVEL || TFM_PARTITION_LOG_LEVEL) will transfer it to the TFM side +# Disabling TFM debug will transfer it to the Zephyr side. + +choice TFM_SPM_LOG_LEVEL + default TFM_SPM_LOG_LEVEL_SILENCE +endchoice + +choice TFM_PARTITION_LOG_LEVEL + default TFM_PARTITION_LOG_LEVEL_SILENCE +endchoice + +endif # BOARD_MAX32658EVKIT_MAX32658_NS + +config I3C + default y if ADXL367 + +endif # BOARD_MAX32658EVKIT diff --git a/boards/adi/max32658evkit/Kconfig.max32658evkit b/boards/adi/max32658evkit/Kconfig.max32658evkit new file mode 100644 index 0000000000000..d7b695e475872 --- /dev/null +++ b/boards/adi/max32658evkit/Kconfig.max32658evkit @@ -0,0 +1,6 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32658EVKIT + select SOC_MAX32658 if BOARD_MAX32658EVKIT_MAX32658 || \ + BOARD_MAX32658EVKIT_MAX32658_NS diff --git a/boards/adi/max32658evkit/board.cmake b/boards/adi/max32658evkit/board.cmake new file mode 100644 index 0000000000000..32e6669b7018b --- /dev/null +++ b/boards/adi/max32658evkit/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_MAX32658EVKIT_MAX32658_NS) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) +endif() + +board_runner_args(jlink "--device=MAX32658" "--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/max32658evkit/board.yml b/boards/adi/max32658evkit/board.yml new file mode 100644 index 0000000000000..07a2bd79226d8 --- /dev/null +++ b/boards/adi/max32658evkit/board.yml @@ -0,0 +1,10 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32658evkit + vendor: adi + socs: + - name: max32658 + variants: + - name: "ns" diff --git a/boards/adi/max32658evkit/doc/img/max32658evkit.webp b/boards/adi/max32658evkit/doc/img/max32658evkit.webp new file mode 100644 index 0000000000000..7bbf5b668eef6 Binary files /dev/null and b/boards/adi/max32658evkit/doc/img/max32658evkit.webp differ diff --git a/boards/adi/max32658evkit/doc/index.rst b/boards/adi/max32658evkit/doc/index.rst new file mode 100644 index 0000000000000..cd0999bac46b9 --- /dev/null +++ b/boards/adi/max32658evkit/doc/index.rst @@ -0,0 +1,571 @@ +.. zephyr:board:: max32658evkit + +Overview +******** + +The MAX32658 microcontroller (MCU) is an advanced system-on-chip (SoC) +featuring an Arm® Cortex®-M33 core with single-precision floating point unit (FPU) +with digital signal processing (DSP) instructions, large flash and SRAM memories, +and the latest generation Bluetooth® 5.4 Low Energy (LE) radio. +The nano-power modes increase battery life substantially. + +The MAX32658 is qualified to operate at a temperature range of -20°C to +85°C. +Bluetooth 5.4 LE radio supports Mesh, long-range (coded), and high-throughput modes. +A cryptographic toolbox (CTB) provides advanced root of trust security features, +including an Advanced Encryption Standard (AES) Engine, TRNG, and secure boot. +TrustZone is also included in the M33 Core. +Many high-speed interfaces are supported on the device, including multiple SPI, UART, +and I3C/I2C serial interfaces. +All interfaces support efficient DMA-driven transfers between peripheral and memory. + +The Zephyr port is running on the MAX32658 MCU. + +Hardware +******** + +- MAX32658 MCU: + + - Arm Cortex-M33 CPU with TrustZone® and FPU + - Single 1.8V Supply + - 50MHz Low Power Oscillator + - External Crystal Support + + - 32MHz required for BLE + + - 1MB Internal Flash with ECC + - 256kB Internal SRAM + - 8kB Cache + - 32.768kHz RTC external crystal + + - Typical Electrical Characteristics + + - ACTIVE: 50μA/MHz Arm Cortex-M33 Running Coremark (50MHz) + + - Bluetooth 5.4 LE Radio + + - Rx Sensitivity: -96dBm; Tx Power: +4.5dBm + - 15mW Tx Power at 0dBm at 1.5Vin + - 14mW Rx Power at 1.5Vin + - Single-Ended Antenna Connection (50Ω) + - Supports 802.15.4, and LE Audio + - High-Throughput (2Mbps) Mode + - Long-Range (125kbps and 500kbps) Modes + + - Optimal Peripheral Mix Provides Platform Scalability + + - 2 DMA Controllers (Secure and non-Secure) + - One SPI Controller/Peripheral + - One I2C/I3C + - 1 Low-Power UART (LPUART) + - Six 32-Bit Low Power Timers with PWM + - 14 Configurable GPIO with Internal Pullup/Pulldown Resistors + + - Cryptographic Tool Box (CTB) for IP/Data Security + + - True Random Number Generator (TRNG) + - AES-128/192/256 + - Unique ID + + - Secure Boot ROM + + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Connections and IOs +=================== + ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| Name | Name | Settings | Description | ++===========+===============+===============+==================================================================================================+ +| JP1 | F5 EN | | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects the 1.8V LDO output used to power supply input F5. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects the 1.8V LDO output used from power supply input F5. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP2 | VDD18 EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects system power to the MAX32658 by connecting VDD18 to VSYS_OUT. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects system power from the MAX32658 by disconnecting VDD18 from VSYS_OUT. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP3 | VLDO EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects LDO output to VSYS_IN. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects LDO output from VSYS_IN. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP4 | E5 EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects the 1.8V LDO output used to power supply input E5. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects the 1.8V LDO output used from power supply input E5. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP5 | VTREF EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects a reference voltage to the OBD circuit. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects a reference voltage from the OBD circuit. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP6 | OBD VBUS EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables the OBD by connecting OBD_VBUS to VBUS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disables the OBD by disconnecting OBD_VBUS from VBUS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| J7 | VSYS EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects system power to all peripherals by connecting VSYS to VSYS_OUT. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects system power to all peripherals by disconnecting VSYS from VSYS_OUT. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP7 | ACC VS EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables the accelerometer by connecting its supply voltage pin VS to VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disables the accelerometer by disconnecting its supply voltage pin VS from VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP8 | ACC VDD EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables the accelerometer by connecting its VDDIO pin to VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disables the accelerometer by disconnecting its VDDIO pin from VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP9 | ACC I2C EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Accelerometer SDA Pin is connected to MAX32658 I2C0_SDA. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Accelerometer SDA Pin is disconnected from MAX32658 I2C0_SDA. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP10 | ACC I2C EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Accelerometer SCL Pin is connected to MAX32658 I2C0_SCL. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Accelerometer SCL Pin is disconnected from MAX32658 I2C0_SCL. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP11 | BYP MAG SW | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Bypass Magnetic Switch. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Enables magnetic switch. The output of the switch is controlled by the AFE pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP12 | LOCK RSTN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | AFE Lock Pin is connected to MAX32658 RSTN pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | AFE Lock Pin is disconnected from MAX32658 RSTN pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP13 | LATCH CTRL | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects the AFE (LOCK) to the magnetic switch (OUTPUT LATCH CONTROL). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects the AFE (WAKE) to the magnetic switch (OUTPUT LATCH CONTROL). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP14 | AFE EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables the AFE (VBAT) by connecting it to VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disables the AFE (VBAT) by disconnecting it from VSYS. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP15 | AFE SPI EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | AFE CSB is connected to MAX32658 SPI0_CS0. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 3-4 | | | AFE SDI is connected to MAX32658 SPI0_MOSI. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 5-6 | | | AFE SCLK is connected to MAX32658 SPI0_SCK. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 7-8 | | | AFE SDO is connected to MAX32658 SPI0_MISO. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 9-10 | | | AFE INTB is connected to MAX32658 P0.7. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 11-12 | | | AFE GPIO2 is connected to MAX32658 P0.8. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open All | | | Disconnect SPI Interface from MAX32658. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP16 | I2C PU EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enable SCL PU resistor. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disable SCL PU resistor. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP17 | I2C PU EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enable SDA PU resistor. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disable SDA PU resistor. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP18 | OBD SWD EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 3-4 | | | OBD SWDIO is connected to the MAX32658 SWDIO. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 5-6 | | | OBD SWCLK is connected to the MAX32658 SWCLK. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 7-8 | | | OBD JTAG TDO Enable Jumper (It's not used on MAX32658). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 9-10 | | | OBD JTAG TDI Enable Jumper (It's not used on MAX32658). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 11-12 | | | OBD RSTN is connected to the MAX32658 RSTN. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 13-14 | | | OBD JTAG TRST Enable Jumper (It's not used on MAX32658). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open All | | | Disable OBD SWD Connection from MAX32658. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP19 | OBD VCOM EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 3-4 | | | OBD VCOM TXD is connected VCOM EN RX Jumper. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 5-6 | | | OBD VCOM RXD is connected VCOM EN TX Jumper. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 7-8 | | | OBD VCOM CTS Enable Jumper (It's not used on MAX32658). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 9-10 | | | OBD VCOM RTS Enable Jumper (It's not used on MAX32658). | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disable OBD VCOM connection from MAX32658. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP20 | VCOM EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects OBD VCOM RXD to the MAX32658 UART0A_TX. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects OBD VCOM RXD from the MAX32658 UART0A_TX. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP21 | VCOM EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects OBD VCOM TXD to the MAX32658 UART0A_RX. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects OBD VCOM TXD from the MAX32658 UART0A_RX. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP22 | EXT SWD EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects EXT SWD Connector Data Signals to the MAX32658 SWDIO pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects EXT SWD Connector Data Signals from the MAX32658 SWDIO pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP23 | EXT SWD EN | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects EXT SWD Connector Clock Signals to the MAX32658 SWDCLK pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects EXT SWD Connector Clock Signals from the MAX32658 SWDCLK pin. | | +| | | +-----------+ | +----------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ + + +Zephyr board options +******************** + +The MAX32658 microcontroller (MCU) is an advanced system-on-chip (SoC) +featuring an ARM Cortex-M33 architecture that provides Trustzone technology +which allow define secure and non-secure application. +Zephyr provides support for building for both Secure (S) and Non-Secure (NS) firmware. + +The BOARD options are summarized below: + ++-------------------------------+-------------------------------------------+ +| BOARD | Description | ++===============================+===========================================+ +| max32658evkit/max32658 | For building Trust Zone Disabled firmware | ++-------------------------------+-------------------------------------------+ +| max32658evkit/max32658/ns | Building with TF-M (includes NS+S images) | ++-------------------------------+-------------------------------------------+ + + +BOARD: max32658evkit/max32658 +============================= + +Build the zephyr app for ``max32658evkit/max32658`` board target will generate secure firmware +for zephyr. In this configuration 960KB of flash is used to store the code and 64KB +is used for storage section. In this mode tf-m is off and secure mode flag is on +(:kconfig:option:`CONFIG_TRUSTED_EXECUTION_SECURE` to ``y`` and +:kconfig:option:`CONFIG_BUILD_WITH_TFM` to ``n``) + ++----------+------------------+---------------------------------+ +| Name | Address[Size] | Comment | ++==========+==================+=================================+ +| slot0 | 0x1000000[960k] | Secure zephyr image | ++----------+------------------+---------------------------------+ +| storage | 0x10f0000[64k] | File system, persistent storage | ++----------+------------------+---------------------------------+ + +Here are the instructions to build zephyr with a secure configuration, +using :zephyr:code-sample:`blinky` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky/ + :board: max32658evkit/max32658 + :goals: build + + +BOARD: max32658evkit/max32658/ns +================================ + +The ``max32658evkit/max32658/ns`` board target is used to build the secure firmware +image using TF-M (:kconfig:option:`CONFIG_BUILD_WITH_TFM` to ``y``) and +the non-secure firmware image using Zephyr +(:kconfig:option:`CONFIG_TRUSTED_EXECUTION_NONSECURE` to ``y``). + +Here are the instructions to build zephyr with a non-secure configuration, +using :zephyr:code-sample:`blinky` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky/ + :board: max32658evkit/max32658/ns + :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. + + +Note: + +Zephyr build TF-M with :kconfig:option:`CONFIG_TFM_PROFILE_TYPE_NOT_SET` mode +that meet most use case configuration especially for BLE related applications. +if TF-M small profile meet your application requirement you can set TF-M profile as small +:kconfig:option:`CONFIG_TFM_PROFILE_TYPE_SMALL` to ``y`` to decrease TF-M RAM and flash use. + + +Memory mappings +--------------- + +MAX32658 1MB flash and 256KB RAM split to define section for MCUBoot, +TF-M (S), Zephyr (NS) and storage that used for secure services and configurations. +Default layout of MAX32658 is listed in below table. + ++----------+------------------+---------------------------------+ +| Name | Address[Size] | Comment | ++==========+==================+=================================+ +| boot | 0x1000000[64K] | MCU Bootloader | ++----------+------------------+---------------------------------+ +| slot0 | 0x1010000[320k] | Secure image slot0 (TF-M) | ++----------+------------------+---------------------------------+ +| slot0_ns | 0x1060000[576k] | Non-secure image slot0 (Zephyr) | ++----------+------------------+---------------------------------+ +| slot1 | 0x10F0000[0k] | Updates slot0 image | ++----------+------------------+---------------------------------+ +| slot1_ns | 0x10F0000[0k] | Updates slot0_ns image | ++----------+------------------+---------------------------------+ +| storage | 0x10f0000[64k] | Persistent storage | ++----------+------------------+---------------------------------+ + + ++----------------+------------------+-------------------+ +| RAM | Address[Size] | Comment | ++================+==================+===================+ +| secure_ram | 0x20000000[64k] | Secure memory | ++----------------+------------------+-------------------+ +| non_secure_ram | 0x20010000[192k] | Non-Secure memory | ++----------------+------------------+-------------------+ + + +Flash memory layout are defines both on zephyr board file and `Trusted Firmware M`_ (TF-M) project +these definition shall be match. Zephyr defines it in +:zephyr_file:`boards/adi/max32658evkit/max32658evkit_max32658_common.dtsi` +file under flash section. TF-M project define them in +../modules/tee/tf-m/trusted-firmware-m/platform/ext/target/adi/max32657/partition/flash_layout.h file.` +If you would like to update flash region for your application you shall update related section in +these files. + +Additionally if firmware update feature requires slot1 and slot1_ns section need to be +defined. On default the section size set as 0 due to firmware update not requires on default. + + +Peripherals and Memory Ownership +-------------------------------- + +The ARM Security Extensions model allows system developers to partition device hardware and +software resources, so that they exist in either the Secure world for the security subsystem, +or the Normal world for everything else. Correct system design can ensure that no Secure world +assets can be accessed from the Normal world. A Secure design places all sensitive resources +in the Secure world, and ideally has robust software running that can protect assets against +a wide range of possible software attacks (`1`_). + +MPC (Memory Protection Controller) and PPC (Peripheral Protection Controller) are allow to +protect memory and peripheral. Incase of need peripheral and flash ownership can be updated in +../modules/tee/tf-m/trusted-firmware-m/platform/ext/target/adi/max32657/s_ns_access.cmake` +file by updating cmake flags to ON/OFF. + +As an example for below configuration TRNG, SRAM_0 and SRAM_1 is not going to be accessible +by non-secure. All others is going to be accessible by NS world. + +.. code-block:: + + set(ADI_NS_PRPH_GCR ON CACHE BOOL "") + set(ADI_NS_PRPH_SIR ON CACHE BOOL "") + set(ADI_NS_PRPH_FCR ON CACHE BOOL "") + set(ADI_NS_PRPH_WDT ON CACHE BOOL "") + set(ADI_NS_PRPH_AES OFF CACHE BOOL "") + set(ADI_NS_PRPH_AESKEY OFF CACHE BOOL "") + set(ADI_NS_PRPH_CRC ON CACHE BOOL "") + set(ADI_NS_PRPH_GPIO0 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER0 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER1 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER2 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER3 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER4 ON CACHE BOOL "") + set(ADI_NS_PRPH_TIMER5 ON CACHE BOOL "") + set(ADI_NS_PRPH_I3C ON CACHE BOOL "") + set(ADI_NS_PRPH_UART ON CACHE BOOL "") + set(ADI_NS_PRPH_SPI ON CACHE BOOL "") + set(ADI_NS_PRPH_TRNG OFF CACHE BOOL "") + set(ADI_NS_PRPH_BTLE_DBB ON CACHE BOOL "") + set(ADI_NS_PRPH_BTLE_RFFE ON CACHE BOOL "") + set(ADI_NS_PRPH_RSTZ ON CACHE BOOL "") + set(ADI_NS_PRPH_BOOST ON CACHE BOOL "") + set(ADI_NS_PRPH_BBSIR ON CACHE BOOL "") + set(ADI_NS_PRPH_BBFCR ON CACHE BOOL "") + set(ADI_NS_PRPH_RTC ON CACHE BOOL "") + set(ADI_NS_PRPH_WUT0 ON CACHE BOOL "") + set(ADI_NS_PRPH_WUT1 ON CACHE BOOL "") + set(ADI_NS_PRPH_PWR ON CACHE BOOL "") + set(ADI_NS_PRPH_MCR ON CACHE BOOL "") + + # SRAMs + set(ADI_NS_SRAM_0 OFF CACHE BOOL "Size: 32KB") + set(ADI_NS_SRAM_1 OFF CACHE BOOL "Size: 32KB") + set(ADI_NS_SRAM_2 ON CACHE BOOL "Size: 64KB") + set(ADI_NS_SRAM_3 ON CACHE BOOL "Size: 64KB") + set(ADI_NS_SRAM_4 ON CACHE BOOL "Size: 64KB") + + # Ramfuncs section size + set(ADI_S_RAM_CODE_SIZE "0x800" CACHE STRING "Default: 2KB") + + # Flash: BL2, TFM and Zephyr are contiguous sections. + set(ADI_FLASH_AREA_BL2_SIZE "0x10000" CACHE STRING "Default: 64KB") + set(ADI_FLASH_S_PARTITION_SIZE "0x50000" CACHE STRING "Default: 320KB") + set(ADI_FLASH_NS_PARTITION_SIZE "0x90000" CACHE STRING "Default: 576KB") + set(ADI_FLASH_PS_AREA_SIZE "0x4000" CACHE STRING "Default: 16KB") + set(ADI_FLASH_ITS_AREA_SIZE "0x4000" CACHE STRING "Default: 16KB") + + # + # Allow user set S-NS resources ownership by overlay file + # + if(EXISTS "${CMAKE_BINARY_DIR}/../../s_ns_access_overlay.cmake") + include(${CMAKE_BINARY_DIR}/../../s_ns_access_overlay.cmake) + endif() + + +As an alternative method (which recommended) user can configurate ownership peripheral by +an cmake overlay file too without touching TF-M source files. For this path +create ``s_ns_access_overlay.cmake`` file under your project root folder and put peripheral/memory +you would like to be accessible by secure world. + +As an example if below configuration files been put in the ``s_ns_access_overlay.cmake`` file +TRNG, SRAM_0 and SRAM_1 will be accessible by secure world only. + +.. code-block:: + + set(ADI_NS_PRPH_TRNG OFF CACHE BOOL "") + set(ADI_NS_SRAM_0 OFF CACHE BOOL "Size: 32KB") + set(ADI_NS_SRAM_1 OFF CACHE BOOL "Size: 32KB") + + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: max32658evkit/max32658 + :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 v4.1.0 ***** + Hello World! max32658evkit/max32658 + +Building and flashing secure/non-secure with Arm |reg| TrustZone |reg| +---------------------------------------------------------------------- +The TF-M integration samples can be run using the +``max32658evkit/max32658/ns`` board target. To run we need to manually flash +the resulting image (``tfm_merged.hex``) with a J-Link as follows +(reset and erase are for recovering a locked core): + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: max32658evkit/max32658/ns + :goals: build + +.. code-block:: console + + west flash --hex-file build/zephyr/tfm_merged.hex + +.. code-block:: console + + [INF] Starting bootloader + [WRN] This device was provisioned with dummy keys. This device is NOT SECURE + [INF] PSA Crypto init done, sig_type: RSA-3072 + [WRN] Cannot upgrade: slots have non-compatible sectors + [WRN] Cannot upgrade: slots have non-compatible sectors + [INF] Bootloader chainload address offset: 0x10000 + [INF] Jumping to the first image slot + ***** Booting Zephyr OS build v4.2.0 ***** + Hello World! max32658evkit/max32658/ns + + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: max32658evkit/max32658 + :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 v4.2.0 ***** + Hello World! max32658evkit/max32658 + +References +********** + +.. _1: + https://developer.arm.com/documentation/100935/0100/The-TrustZone-hardware-architecture- + +.. _Trusted Firmware M: + https://tf-m-user-guide.trustedfirmware.org/building/tfm_build_instruction.html diff --git a/boards/adi/max32658evkit/max32658evkit_max32658.dts b/boards/adi/max32658evkit/max32658evkit_max32658.dts new file mode 100644 index 0000000000000..20b52890f76b3 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024-2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "max32658evkit_max32658_common.dtsi" + +/ { + chosen { + zephyr,sram = &secure_ram; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + secure_ram: partition@30000000 { + label = "secure-memory"; + reg = <0x30000000 DT_SIZE_K(256)>; + }; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0 DT_SIZE_K(960)>; + read-only; + }; + + storage_partition: partition@f0000 { + label = "storage"; + reg = <0xf0000 DT_SIZE_K(64)>; + }; + }; +}; + +&trng { + status = "okay"; +}; diff --git a/boards/adi/max32658evkit/max32658evkit_max32658.yaml b/boards/adi/max32658evkit/max32658evkit_max32658.yaml new file mode 100644 index 0000000000000..f4e7fdac7f8f4 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658.yaml @@ -0,0 +1,21 @@ +identifier: max32658evkit/max32658 +name: max32658evkit-max32658 +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - serial + - gpio + - trng + - watchdog + - dma + - counter + - pwm + - rtc_counter + - spi + - i3c +ram: 256 +flash: 960 diff --git a/boards/adi/max32658evkit/max32658evkit_max32658_common.dtsi b/boards/adi/max32658evkit/max32658evkit_max32658_common.dtsi new file mode 100644 index 0000000000000..9b65c7bffab63 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658_common.dtsi @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024-2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX32658EVKIT"; + compatible = "adi,max32658evkit"; + + chosen { + zephyr,console = &uart0; + zephyr,cortex-m-idle-timer = &counter_wut1; + zephyr,shell-uart = &uart0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb1: pb1 { + gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + accel0 = &adxl367; + led0 = &led1; + sw0 = &pb1; + watchdog0 = &wdt0; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0_tx_p0_9 &uart0_rx_p0_5>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_mosi_p0_2 &spi0_miso_p0_4 &spi0_sck_p0_6 &spi0_ss0_p0_3>; + pinctrl-names = "default"; +}; + +&rtc_counter { + status = "okay"; + clock-source = ; +}; + +&i3c0 { + status = "okay"; + pinctrl-0 = <&i3c_scl_p0_0 &i3c_sda_p0_1>; + pinctrl-names = "default"; + i2c-scl-hz = ; + i3c-scl-hz = ; + i3c-od-scl-hz = ; + + adxl367: adxl367@530000000000000000 { + compatible = "adi,adxl367"; + reg = <0x53 0x00 0x00>; + status = "okay"; + }; +}; + +&wut0 { + clock-source = ; +}; + +&wut1 { + status = "okay"; + clock-source = ; + wakeup-source; + counter_wut1: counter { + status = "okay"; + }; +}; diff --git a/boards/adi/max32658evkit/max32658evkit_max32658_defconfig b/boards/adi/max32658evkit/max32658evkit_max32658_defconfig new file mode 100644 index 0000000000000..25ef03ee5131b --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# It is secure fw, enable flags +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/adi/max32658evkit/max32658evkit_max32658_ns.dts b/boards/adi/max32658evkit/max32658evkit_max32658_ns.dts new file mode 100644 index 0000000000000..0cc9f08804802 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658_ns.dts @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024-2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "max32658evkit_max32658_common.dtsi" + +/ { + chosen { + zephyr,sram = &non_secure_ram; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; + + 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(64)>; + }; + + non_secure_ram: partition@20010000 { + label = "non-secure-memory"; + reg = <0x20010000 DT_SIZE_K(192)>; + }; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + read-only; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(320)>; + }; + + slot0_ns_partition: partition@60000 { + label = "image-0-nonsecure"; + reg = <0x60000 DT_SIZE_K(576)>; + }; + + /* + * slot1_partition: partition@f0000 { + * label = "image-1"; + * reg = <0xf0000 DT_SIZE_K(0)>; + * }; + * slot1_ns_partition: partition@f0000 { + * label = "image-1-nonsecure"; + * reg = <0xf0000 DT_SIZE_K(0)>; + * }; + */ + + storage_partition: partition@f0000 { + label = "storage"; + reg = <0xf0000 DT_SIZE_K(64)>; + }; + }; +}; diff --git a/boards/adi/max32658evkit/max32658evkit_max32658_ns.yaml b/boards/adi/max32658evkit/max32658evkit_max32658_ns.yaml new file mode 100644 index 0000000000000..9868c5bb8a710 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658_ns.yaml @@ -0,0 +1,20 @@ +identifier: max32658evkit/max32658/ns +name: max32658evkit-max32658-Non-Secure +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - serial + - gpio + - watchdog + - dma + - counter + - pwm + - rtc_counter + - spi + - i3c +ram: 192 +flash: 576 diff --git a/boards/adi/max32658evkit/max32658evkit_max32658_ns_defconfig b/boards/adi/max32658evkit/max32658evkit_max32658_ns_defconfig new file mode 100644 index 0000000000000..d808f79c54594 --- /dev/null +++ b/boards/adi/max32658evkit/max32658evkit_max32658_ns_defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2024-2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# It is non-secure fw, enable flags +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# Set TFM and Zephyr sign key +CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE="RSA-3072" diff --git a/boards/aithinker/ai_m62_12f/ai_m62_12f.yaml b/boards/aithinker/ai_m62_12f/ai_m62_12f.yaml index 7d242d4766461..3b7748f228f9b 100644 --- a/boards/aithinker/ai_m62_12f/ai_m62_12f.yaml +++ b/boards/aithinker/ai_m62_12f/ai_m62_12f.yaml @@ -17,4 +17,5 @@ supported: - gpio - pinctrl - uart + - dma vendor: bflb diff --git a/boards/aithinker/ai_wb2_12f/ai_wb2_12f.yaml b/boards/aithinker/ai_wb2_12f/ai_wb2_12f.yaml index e9dc0bc4f68a4..82bf92b4bcedc 100644 --- a/boards/aithinker/ai_wb2_12f/ai_wb2_12f.yaml +++ b/boards/aithinker/ai_wb2_12f/ai_wb2_12f.yaml @@ -17,4 +17,5 @@ supported: - gpio - pinctrl - uart + - dma vendor: bflb diff --git a/boards/aithinker/esp32_cam/doc/index.rst b/boards/aithinker/esp32_cam/doc/index.rst index 4e6efe50e34da..605abe9b3aa2a 100644 --- a/boards/aithinker/esp32_cam/doc/index.rst +++ b/boards/aithinker/esp32_cam/doc/index.rst @@ -5,6 +5,9 @@ Overview Ai-Thinker ESP32-CAM is an ESP32-based development board produced by `Ai-Thinker `_. +Hardware +******** + ESP32-CAM features the following components: - ESP32S module @@ -17,27 +20,19 @@ ESP32-CAM features the following components: ESP32's GPIO4 on the ESP32 is shared between the MicroSD data pin and the onboard flash LED. -For more information, check the datasheet at `ESP32 Datasheet`_ or the technical reference -manual at `ESP32 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features Supported Features -****************** +================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -50,23 +45,11 @@ Programming and Debugging .. include:: ../../../espressif/common/board-variants.rst :start-after: espressif-board-variants -Applications for the ``esp32_cam`` board can be built and flashed in the usual way -(see :ref:`build_an_application` and :ref:`application_run` for more details); -however, an external FTDI USB to TTL Serial Adapter is required since the board -does not have any on-board debug IC. - -The following pins of the Serial Adapter must be connected to the header pins: - -* VTref = VCC -* GND = GND -* TXD = U0TXD -* RXD = U0RXD -* Boot = GPIO0 (Must be low at boot) - Debugging ========= -ESP32 support on OpenOCD is available at `OpenOCD ESP32`_. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging +------------+-----------+ | ESP32 pin | JTAG pin | @@ -84,14 +67,21 @@ ESP32 support on OpenOCD is available at `OpenOCD ESP32`_. | IO15 | TDO | +------------+-----------+ -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32`_. +Sample Applications +******************* + +Applications for the ``esp32_cam`` board can be built and flashed in the usual way +(see :ref:`build_an_application` and :ref:`application_run` for more details); +however, an external FTDI USB to TTL Serial Adapter is required since the board +does not have any on-board debug IC. -Here is an example for building the :zephyr:code-sample:`hello_world` application. +The following pins of the Serial Adapter must be connected to the header pins: -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32_cam/esp32/procpu - :goals: build flash +* VTref = VCC +* GND = GND +* TXD = U0TXD +* RXD = U0RXD +* Boot = GPIO0 (Must be low at boot) References ********** @@ -99,7 +89,3 @@ References .. target-notes:: .. _`ESP32-CAM`: https://docs.ai-thinker.com/en/esp32-cam -.. _`ESP32 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf -.. _`ESP32 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/amd/versalnet_apu/board.yml b/boards/amd/versalnet_apu/board.yml index 230690e7c71c1..0c7b0dda2908d 100644 --- a/boards/amd/versalnet_apu/board.yml +++ b/boards/amd/versalnet_apu/board.yml @@ -1,5 +1,6 @@ board: name: versalnet_apu + full_name: Versal Net APU Development Board vendor: amd socs: - name: amd_versalnet_apu diff --git a/boards/arm/mps2/Kconfig.defconfig b/boards/arm/mps2/Kconfig.defconfig index 367e09c2a9a17..b6c51af651c41 100644 --- a/boards/arm/mps2/Kconfig.defconfig +++ b/boards/arm/mps2/Kconfig.defconfig @@ -33,7 +33,7 @@ config TEST_EXTRA_STACK_SIZE endif # COVERAGE_GCOV -endif +endif # BOARD_MPS2_AN383 || BOARD_MPS2_AN385 || BOARD_MPS2_AN386 || BOARD_MPS2_AN500 if BOARD_MPS2_AN521_CPU0 || BOARD_MPS2_AN521_CPU0_NS || BOARD_MPS2_AN521_CPU1 @@ -58,4 +58,11 @@ config UART_INTERRUPT_DRIVEN endif # SERIAL +endif # BOARD_MPS2_AN521_CPU0 || BOARD_MPS2_AN521_CPU0_NS || BOARD_MPS2_AN521_CPU1 + +if QEMU_TARGET + +config ISR_STACK_SIZE + default 4096 + endif diff --git a/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml b/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml index 1400cf1c4881b..4547744c446a1 100644 --- a/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml +++ b/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml @@ -17,4 +17,5 @@ supported: - gpio - pinctrl - uart + - dma vendor: bflb diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 1cc3856cee8ad..871cd600f8053 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -67,3 +67,6 @@ set(esp32_devkitc_wrover/esp32/appcpu_DEPRECATED set(scobc_module1_DEPRECATED scobc_a1 ) +set(raytac_an54l15q_db/nrf54l15/cpuapp_DEPRECATED + raytac_an54lq_db_15/nrf54l15/cpuapp +) diff --git a/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.yaml b/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.yaml index 79ee2e8c1f734..0b3b645a5afd8 100644 --- a/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.yaml +++ b/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.yaml @@ -16,4 +16,5 @@ supported: - gpio - pinctrl - uart + - dma vendor: doiting diff --git a/boards/doiting/dt_xt_zb1_devkit/dt_xt_zb1_devkit.yaml b/boards/doiting/dt_xt_zb1_devkit/dt_xt_zb1_devkit.yaml index 40f8b0f81b3c9..6c2b9bb6fcf15 100644 --- a/boards/doiting/dt_xt_zb1_devkit/dt_xt_zb1_devkit.yaml +++ b/boards/doiting/dt_xt_zb1_devkit/dt_xt_zb1_devkit.yaml @@ -16,4 +16,5 @@ supported: - gpio - pinctrl - uart + - dma vendor: doiting diff --git a/boards/dptechnics/walter/doc/index.rst b/boards/dptechnics/walter/doc/index.rst index eb5dc5e3d50f2..254686992e927 100644 --- a/boards/dptechnics/walter/doc/index.rst +++ b/boards/dptechnics/walter/doc/index.rst @@ -55,168 +55,36 @@ Form factor - Pin and footprint compatible with EOL Pycom GPy - Breadboard friendly +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be build (and flash) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-S3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :app: samples/hello_world - :board: walter/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. +Programming and Debugging +************************* -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be build one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: walter/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``walter`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: walter/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! walter/esp32s3/procpu +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: walter/esp32s3/procpu - :goals: build flash - -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: walter/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -225,5 +93,3 @@ References .. _`QuickSpot Website`: https://www.quickspot.io/ .. _`QuickSpot GitHub page`: https://github.com/QuickSpot -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/openocd-org/openocd diff --git a/boards/egis/egis_et171/doc/img/et171_snapshot.webp b/boards/egis/egis_et171/doc/img/egis_et171.webp similarity index 100% rename from boards/egis/egis_et171/doc/img/et171_snapshot.webp rename to boards/egis/egis_et171/doc/img/egis_et171.webp diff --git a/boards/egis/egis_et171/doc/index.rst b/boards/egis/egis_et171/doc/index.rst index 7b3cf0b67980b..adaa6292db3b2 100644 --- a/boards/egis/egis_et171/doc/index.rst +++ b/boards/egis/egis_et171/doc/index.rst @@ -22,10 +22,6 @@ The platform provides following hardware components: - DMA - USB -.. figure:: img/et171_snapshot.webp - :align: center - :alt: EGIS_ET171_SOC - Supported Features ================== diff --git a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts index 4f94a15fad6ba..5d062f59daf0a 100644 --- a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts +++ b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include / { model = "LiteX VexRiscV"; @@ -16,6 +17,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,sram = &ram0; + zephyr,entropy = &prbs0; }; aliases { @@ -26,85 +28,411 @@ device_type = "memory"; reg = <0x40000000 0x10000000>; }; -}; -&ctrl0 { - status = "okay"; -}; + soc { + ctrl0: soc_controller@e0000000 { + compatible = "litex,soc-controller"; + reg = <0xe0000000 0x4 + 0xe0000004 0x4 + 0xe0000008 0x4>; + reg-names = "reset", + "scratch", + "bus_errors"; + status = "okay"; + }; -&uart0 { - status = "okay"; - current-speed = <115200>; -}; + uart0: serial@e0001800 { + compatible = "litex,uart"; + interrupt-parent = <&intc0>; + interrupts = <2 10>; + reg = <0xe0001800 0x4 + 0xe0001804 0x4 + 0xe0001808 0x4 + 0xe000180c 0x4 + 0xe0001810 0x4 + 0xe0001814 0x4 + 0xe0001818 0x4 + 0xe000181c 0x4>; + reg-names = "rxtx", + "txfull", + "rxempty", + "ev_status", + "ev_pending", + "ev_enable", + "txempty", + "rxfull"; + status = "okay"; + current-speed = <115200>; + }; -&timer0 { - status = "okay"; -}; + timer0: timer@e0002800 { + compatible = "litex,timer0"; + interrupt-parent = <&intc0>; + interrupts = <1 0>; + reg = <0xe0002800 0x4 + 0xe0002804 0x4 + 0xe0002808 0x4 + 0xe000280c 0x4 + 0xe0002810 0x4 + 0xe0002814 0x4 + 0xe0002818 0x4 + 0xe000281c 0x4 + 0xe0002820 0x4 + 0xe0002824 0x8>; + reg-names = "load", + "reload", + "en", + "update_value", + "value", + "ev_status", + "ev_pending", + "ev_enable", + "uptime_latch", + "uptime_cycles"; + status = "okay"; + }; -&wdt0 { - status = "okay"; -}; + wdt0: watchdog@e000d000 { + compatible = "litex,watchdog"; + interrupt-parent = <&intc0>; + reg = <0xe000d000 0x4>, + <0xe000d004 0x4>, + <0xe000d008 0x4>, + <0xe000d00c 0x4>, + <0xe000d010 0x4>, + <0xe000d014 0x4>; + reg-names = "control", + "cycles", + "remaining", + "ev_status", + "ev_pending", + "ev_enable"; + interrupts = <8 15>; + status = "okay"; + }; -&mdio0 { - status = "okay"; -}; + mdio0: mdio@e0008000 { + compatible = "litex,liteeth-mdio"; + reg = <0xe0008000 0x4>, + <0xe0008004 0x4>, + <0xe0008008 0x4>; + reg-names = "crg_reset", + "mdio_w", + "mdio_r"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; -&phy0 { - status = "okay"; -}; + phy0: ethernet-phy@1 { + compatible = "ethernet-phy"; + reg = <1>; + status = "okay"; + }; + }; -ð0 { - status = "okay"; -}; + eth0: ethernet@e0009800 { + compatible = "litex,liteeth"; + interrupt-parent = <&intc0>; + interrupts = <3 0>; + reg = <0xe0009800 0x4 + 0xe0009804 0x4 + 0xe0009808 0x4 + 0xe000980c 0x4 + 0xe0009810 0x4 + 0xe0009814 0x4 + 0xe0009818 0x4 + 0xe000981c 0x4 + 0xe0009820 0x4 + 0xe0009824 0x4 + 0xe0009828 0x4 + 0xe000982c 0x4 + 0xe0009830 0x4 + 0xe0009834 0x4 + 0xb0000000 0x2000>; + local-mac-address = [10 e2 d5 00 00 02]; + reg-names = "rx_slot", + "rx_length", + "rx_errors", + "rx_ev_status", + "rx_ev_pending", + "rx_ev_enable", + "tx_start", + "tx_ready", + "tx_level", + "tx_slot", + "tx_length", + "tx_ev_status", + "tx_ev_pending", + "tx_ev_enable", + "buffers"; + phy-handle = <&phy0>; + status = "okay"; + }; -&dna0 { - status = "okay"; -}; + dna0: dna@e0003800 { + compatible = "litex,dna0"; + /* DNA data is 57-bits long, + * so it requires 8 bytes. + * In LiteX each 32-bit register holds + * only a single byte of meaningful data, + * hence 8 registers. + */ + reg = <0xe0003800 0x20>; + reg-names = "mem"; + status = "okay"; + }; -&spi0 { - status = "okay"; -}; + spi0: spi@e0002000 { + compatible = "litex,spi"; + reg = <0xe0002000 0x4 + 0xe0002004 0x4 + 0xe0002008 0x4 + 0xe000200c 0x4 + 0xe0002010 0x4 + 0xe0002014 0x4>; + reg-names = "control", + "status", + "mosi", + "miso", + "cs", + "loopback"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + }; -&prbs0 { - status = "okay"; -}; + spi1: spi@e000c000 { + compatible = "litex,spi-litespi"; + interrupt-parent = <&intc0>; + reg = <0xe000c000 0x4>, + <0xe000c004 0x4>, + <0xe000c008 0x4>, + <0xe000c00c 0x4>, + <0xe000c010 0x4>, + <0xe000c014 0x4>, + <0xe000c018 0x4>, + <0xe000c01c 0x4>, + <0xe000c020 0x4>, + <0x60000000 0x1000000>; + reg-names = "phy_clk_divisor", + "mmap_dummy_bits", + "master_cs", + "master_phyconfig", + "master_rxtx", + "master_status", + "master_ev_status", + "master_ev_pending", + "master_ev_enable", + "flash_mmap"; + interrupts = <9 0>; + #address-cells = <1>; + #size-cells = <0>; -&i2c0 { - status = "okay"; -}; + spiflash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + }; + }; -&i2c1 { - status = "okay"; -}; + prbs0: prbs@e0006800 { + compatible = "litex,prbs"; + reg = <0xe0006800 0x4>; + reg-names = "status"; + status = "okay"; + }; -&pwm0 { - status = "okay"; -}; + i2c0: i2c@e0005000 { + compatible = "litex,i2c"; + reg = <0xe0005000 0x4 0xe0005004 0x4>; + reg-names = "write", "read"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + }; -&gpio_out { - status = "okay"; -}; + i2c1: i2c@e000d800 { + compatible = "litex,litei2c"; + interrupt-parent = <&intc0>; + reg = <0xe000d800 0x4>, + <0xe000d804 0x4>, + <0xe000d808 0x4>, + <0xe000d80c 0x4>, + <0xe000d810 0x4>, + <0xe000d814 0x4>, + <0xe000d818 0x4>, + <0xe000d81c 0x4>, + <0xe000d820 0x4>; + reg-names = "phy_speed_mode", + "master_active", + "master_settings", + "master_addr", + "master_rxtx", + "master_status", + "master_ev_status", + "master_ev_pending", + "master_ev_enable"; + interrupts = <10 0>; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + }; -&gpio_in { - status = "okay"; -}; + pwm0: pwm@e0007000 { + compatible = "litex,pwm"; + reg = <0xe0007000 0x4 0xe0007004 0x10 0xe0007014 0x10>; + reg-names = "enable", "width", "period"; + status = "okay"; + #pwm-cells = <2>; + }; -&i2s_rx { - status = "okay"; -}; + gpio_out: gpio@e0005800 { + compatible = "litex,gpio"; + reg = <0xe0005800 0x4>; + reg-names = "control"; + ngpios = <4>; + port-is-output; + status = "okay"; + gpio-controller; + #gpio-cells = <2>; + }; -&i2s_tx { - status = "okay"; -}; + gpio_in: gpio@e0006000 { + compatible = "litex,gpio"; + reg = <0xe0006000 0x4 + 0xe0006004 0x4 + 0xe0006008 0x4 + 0xe0006010 0x4 + 0xe0006014 0x4>; + interrupt-parent = <&intc0>; + interrupts = <4 2>; + reg-names = "base", + "irq_mode", + "irq_edge", + "irq_pend", + "irq_en"; + ngpios = <4>; + status = "okay"; + gpio-controller; + #gpio-cells = <2>; + }; -&clk0 { - status = "okay"; -}; + i2s_rx: i2s_rx@e000a800 { + compatible = "litex,i2s"; + reg = <0xe000a800 0x4 + 0xe000a804 0x4 + 0xe000a808 0x4 + 0xe000a80c 0x4 + 0xe000a810 0x4 + 0xe000a814 0x4 + 0xb1000000 0x40000>; + interrupt-parent = <&intc0>; + interrupts = <6 2>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "ev_status", + "ev_pending", + "ev_enable", + "rx_ctl", + "rx_stat", + "rx_conf", + "fifo"; + fifo-depth = <256>; + status = "okay"; + }; -&clk1 { - status = "okay"; -}; + i2s_tx: i2s_tx@e000b000 { + compatible = "litex,i2s"; + reg = <0xe000b000 0x4 + 0xe000b004 0x4 + 0xe000b008 0x4 + 0xe000b00c 0x4 + 0xe000b010 0x4 + 0xe000b014 0x4 + 0xb2000000 0x40000>; + interrupt-parent = <&intc0>; + interrupts = <7 2>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "ev_status", + "ev_pending", + "ev_enable", + "tx_ctl", + "tx_stat", + "tx_conf", + "fifo"; + fifo-depth = <256>; + status = "okay"; + }; + + clock-outputs { + #address-cells = <1>; + #size-cells = <0>; -&clock0 { - status = "okay"; + clk0: clock-controller@0 { + #clock-cells = <1>; + reg = <0>; + compatible = "litex,clkout"; + clock-output-names = "CLK_0"; + litex,clock-frequency = <11289600>; + litex,clock-phase = <0>; + litex,clock-duty-num = <1>; + litex,clock-duty-den = <2>; + litex,clock-margin = <1>; + litex,clock-margin-exp = <2>; + status = "okay"; + }; + + clk1: clock-controller@1 { + #clock-cells = <1>; + reg = <1>; + compatible = "litex,clkout"; + clock-output-names = "CLK_1"; + litex,clock-frequency = <22579200>; + litex,clock-phase = <0>; + litex,clock-duty-num = <1>; + litex,clock-duty-den = <2>; + litex,clock-margin = <1>; + litex,clock-margin-exp = <2>; + status = "okay"; + }; + }; + + clock0: clock@e0004800 { + compatible = "litex,clk"; + reg = <0xe0004800 0x4 + 0xe0004804 0x4 + 0xe0004808 0x4 + 0xe000480c 0x4 + 0xe0004810 0x4 + 0xe0004814 0x4 + 0xe0004818 0x4 + 0xe000481c 0x4>; + reg-names = "drp_reset", + "drp_locked", + "drp_read", + "drp_write", + "drp_drdy", + "drp_adr", + "drp_dat_w", + "drp_dat_r"; + #clock-cells = <1>; + clocks = <&clk0 0>, <&clk1 1>; + clock-output-names = "CLK_0", "CLK_1"; + litex,lock-timeout = <10>; + litex,drdy-timeout = <10>; + litex,divclk-divide-min = <1>; + litex,divclk-divide-max = <107>; + litex,clkfbout-mult-min = <2>; + litex,clkfbout-mult-max = <65>; + litex,vco-freq-min = <600000000>; + litex,vco-freq-max = <1200000000>; + litex,clkout-divide-min = <1>; + litex,clkout-divide-max = <126>; + litex,vco-margin = <0>; + status = "okay"; + }; + }; }; diff --git a/boards/espressif/common/board-variants.rst b/boards/espressif/common/board-variants.rst index b04cdc57b5f0a..0fffde9c64602 100644 --- a/boards/espressif/common/board-variants.rst +++ b/boards/espressif/common/board-variants.rst @@ -42,4 +42,9 @@ To apply a board variant, use the ``-S`` flag with west build: :snippets: flash-32M,psram-4M :compact: -**Note:** These snippets are applicable to boards with compatible hardware support for the selected flash/PSRAM configuration. +.. note:: + + These snippets are applicable to boards with compatible hardware support for the selected flash/PSRAM configuration. + + - If no FLASH snippet is used, the board default flash size will be used. + - If no PSRAM snippet is used, the board default psram size will be used. diff --git a/boards/espressif/common/building-flashing.rst b/boards/espressif/common/building-flashing.rst index 4cf1df30f8bae..f924043211951 100644 --- a/boards/espressif/common/building-flashing.rst +++ b/boards/espressif/common/building-flashing.rst @@ -2,7 +2,7 @@ .. espressif-building-flashing -Simple boot +Simple Boot =========== The board could be loaded using the single binary image, without 2nd stage bootloader. @@ -12,7 +12,7 @@ It is the default option when building the application without additional config Simple boot does not provide any security features nor OTA updates. -MCUboot bootloader +MCUboot Bootloader ================== User may choose to use MCUboot bootloader instead. In that case the bootloader @@ -74,7 +74,7 @@ Zephyr build. Output is structured by the domain subdirectories: For more information about the system build please read the :ref:`sysbuild` documentation. -Manual build +Manual Build ============ During the development cycle, it is intended to build & flash as quickly possible. @@ -117,3 +117,5 @@ message in the monitor: ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** Hello World! + +.. _`Zephyr Support Status`: https://developer.espressif.com/software/zephyr-support-status/ diff --git a/boards/espressif/common/openocd-debugging.rst b/boards/espressif/common/openocd-debugging.rst index 7e6fccd4d7746..71d75389eb793 100644 --- a/boards/espressif/common/openocd-debugging.rst +++ b/boards/espressif/common/openocd-debugging.rst @@ -7,12 +7,14 @@ OpenOCD 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 `_. +the project. The custom OpenOCD can be obtained at `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. +Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32`_. + Here is an example for building the :zephyr:code-sample:`hello_world` application. .. zephyr-app-commands:: @@ -27,3 +29,7 @@ You can debug an application in the usual way. Here is an example for the :zephy :zephyr-app: samples/hello_world :board: :goals: debug + + +.. _`OpenOCD for ESP32`: https://github.com/espressif/openocd-esp32/releases +.. _`JTAG debugging for ESP32`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html diff --git a/boards/espressif/common/soc-esp32-features.rst b/boards/espressif/common/soc-esp32-features.rst new file mode 100644 index 0000000000000..f82274e7317b0 --- /dev/null +++ b/boards/espressif/common/soc-esp32-features.rst @@ -0,0 +1,43 @@ +:orphan: + +.. espressif-soc-esp32-features + +ESP32 Features +============== + +- Dual core Xtensa microprocessor (LX6), running at 160 or 240MHz +- 520KB of SRAM +- 802.11b/g/n/e/i +- Bluetooth v4.2 BR/EDR and BLE +- Various peripherals: + + - 12-bit ADC with up to 18 channels + - 2x 8-bit DACs + - 10x touch sensors + - 4x SPI + - 2x I2S + - 2x I2C + - 3x UART + - SD/SDIO/MMC host + - Slave (SDIO/SPI) + - Ethernet MAC + - CAN bus 2.0 + - IR (RX/TX) + - Motor PWM + - LED PWM with up to 16 channels + - Hall effect sensor + - Temperature sensor + +- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) +- 5uA deep sleep current + +Asymmetric Multiprocessing (AMP) +================================ + +ESP32 allows 2 different applications to be executed in ESP32 SoC. Due to its dual-core architecture, each core can be enabled to execute customized tasks in stand-alone mode +and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. + +For more information, check the `ESP32 Datasheet`_ or the `ESP32 Technical Reference Manual`_. + +.. _`ESP32 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf +.. _`ESP32 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32c2-features.rst b/boards/espressif/common/soc-esp32c2-features.rst new file mode 100644 index 0000000000000..17c713e540586 --- /dev/null +++ b/boards/espressif/common/soc-esp32c2-features.rst @@ -0,0 +1,42 @@ +:orphan: + +.. espressif-soc-esp32c2-features + +ESP32-C2 Features +================= + +ESP32-C2 (ESP8684 core) is a low-cost, Wi-Fi 4 & Bluetooth 5 (LE) chip. Its unique design +makes the chip smaller and yet more powerful than ESP8266. ESP32-C2 is built around a RISC-V +32-bit, single-core processor, with 272 KB of SRAM (16 KB dedicated to cache) and 576 KB of ROM. +ESP32-C2 has been designed to target simple, high-volume, and low-data-rate IoT applications, +such as smart plugs and smart light bulbs. ESP32-C2 offers easy and robust wireless connectivity, +which makes it the go-to solution for developing simple, user-friendly and reliable +smart-home devices. + +Features include the following: + +- 32-bit core RISC-V microcontroller with a maximum clock speed of 120 MHz +- 2 MB or 4 MB in chip (ESP8684) or in package (ESP32-C2) flash +- 272 KB of internal RAM +- 802.11b/g/n +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh +- Various peripherals: + + - General DMA controller (GDMA) + - LED PWM controller, with up to 6 channels + - 14 programmable GPIOs + - 3 SPI + - 2 UART + - 1 I2C Master + - 1 12-bit SAR ADC, up to 5 channels + - 1 temperature sensor + - 1 54-bit general-purpose timer + - 2 watchdog timers + - 1 52-bit system timer + +- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) + +For detailed information check the `ESP8684 Datasheet`_ or the `ESP8684 Technical Reference Manual`_. + +.. _`ESP8684 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp8684_datasheet_en.pdf +.. _`ESP8684 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp8684_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32c3-features.rst b/boards/espressif/common/soc-esp32c3-features.rst new file mode 100644 index 0000000000000..fb48b9319bbe9 --- /dev/null +++ b/boards/espressif/common/soc-esp32c3-features.rst @@ -0,0 +1,46 @@ +:orphan: + +.. espressif-soc-esp32c3-features + +ESP32-C3 Features +================= + +ESP32-C3 is a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, +based on the open-source RISC-V architecture. It strikes the right balance of power, +I/O capabilities and security, thus offering the optimal cost-effective +solution for connected devices. +The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, +but it also facilitates a variety of use-cases based on dual connectivity. + +The features include the following: + +- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz +- 802.11b/g/n/ +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh +- 384 KB ROM +- 400 KB SRAM (16 KB for cache) +- 8 KB SRAM in RTC +- 22 x programmable GPIOs +- Various peripherals: + + - Full-speed USB Serial/JTAG controller + - TWAI® compatible with CAN bus 2.0 + - General DMA controller (GDMA) + - 2x 12-bit SAR ADC with up to 6 channels + - 3x SPI + - 2x UART + - 1x I2S + - 1x I2C + - 2 x 54-bit general-purpose timers + - 3 x watchdog timers + - 1 x 52-bit system timer + - Remote Control Peripheral (RMT) + - LED PWM controller (LEDC) with up to 6 channels + - Temperature sensor + +- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) + +For more information, check the `ESP32-C3 Datasheet`_ or the `ESP32-C3 Technical Reference Manual`_. + +.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf +.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32c6-features.rst b/boards/espressif/common/soc-esp32c6-features.rst new file mode 100644 index 0000000000000..886685815c878 --- /dev/null +++ b/boards/espressif/common/soc-esp32c6-features.rst @@ -0,0 +1,93 @@ +:orphan: + +.. espressif-soc-esp32c6-features + +ESP32-C6 Features +================= + +ESP32-C6 is Espressif's first Wi-Fi 6 SoC integrating 2.4 GHz Wi-Fi 6, Bluetooth 5.3 (LE) and the +802.15.4 protocol. ESP32-C6 achieves an industry-leading RF performance, with reliable security +features and multiple memory resources for IoT products. +It consists of a high-performance (HP) 32-bit RISC-V processor, which can be clocked up to 160 MHz, +and a low-power (LP) 32-bit RISC-V processor, which can be clocked up to 20 MHz. +It has a 320KB ROM, a 512KB SRAM, and works with external flash. + +ESP32-C6 includes the following features: + +- 32-bit core RISC-V microcontroller with a clock speed of up to 160 MHz +- 400 KB of internal RAM +- WiFi 802.11 ax 2.4GHz +- Fully compatible with IEEE 802.11b/g/n protocol +- Bluetooth LE: Bluetooth 5.3 certified +- Internal co-existence mechanism between Wi-Fi and Bluetooth to share the same antenna +- IEEE 802.15.4 (Zigbee and Thread) + +Digital interfaces: + +- 30x GPIOs (QFN40), or 22x GPIOs (QFN32) +- 2x UART +- 1x Low-power (LP) UART +- 1x General purpose SPI +- 1x I2C +- 1x Low-power (LP) I2C +- 1x I2S +- 1x Pulse counter +- 1x USB Serial/JTAG controller +- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) +- 1x SDIO 2.0 slave controller +- LED PWM controller, up to 6 channels +- 1x Motor control PWM (MCPWM) +- 1x Remote control peripehral +- 1x Parallel IO interface (PARLIO) +- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels +- Event task matrix (ETM) + +Analog interfaces: + +- 1x 12-bit SAR ADCs, up to 7 channels +- 1x temperature sensor + +Timers: + +- 1x 52-bit system timer +- 1x 54-bit general-purpose timers +- 3x Watchdog timers +- 1x Analog watchdog timer + +Low Power: + +- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep + +Security: + +- Secure boot +- Flash encryption +- 4-Kbit OTP, up to 1792 bits for users +- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) +- Random number generator (RNG) + +Low-Power CPU (LP CORE) +======================= + +The ESP32-C6 SoC has two RISC-V cores: the High-Performance Core (HP CORE) and the Low-Power Core (LP CORE). +The LP Core features ultra low power consumption, an interrupt controller, a debug module and a system bus +interface for memory and peripheral access. + +The LP Core is in sleep mode by default. It has two application scenarios: + +- Power insensitive scenario: When the High-Performance CPU (HP Core) is active, the LP Core can assist the HP CPU with some speed and efficiency-insensitive controls and computations. +- Power sensitive scenario: When the HP CPU is in the power-down state to save power, the LP Core can be woken up to handle some external wake-up events. + +The LP Core support is fully integrated with :ref:`sysbuild`. The user can enable the LP Core by adding +the following configuration to the project: + +.. code:: cfg + + CONFIG_ULP_COPROC_ENABLED=y + +See :zephyr:code-sample-category:`lp-core` folder as code reference. + +For more information, check the `ESP32-C6 Datasheet`_ or the `ESP32-C6 Technical Reference Manual`_. + +.. _`ESP32-C6 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf +.. _`ESP32-C6 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32h2-features.rst b/boards/espressif/common/soc-esp32h2-features.rst new file mode 100644 index 0000000000000..f237a8ecfbd2f --- /dev/null +++ b/boards/espressif/common/soc-esp32h2-features.rst @@ -0,0 +1,68 @@ +:orphan: + +.. espressif-soc-esp32h2-features + +ESP32-H2 Features +================= + +ESP32-H2 combines IEEE 802.15.4 connectivity with Bluetooth 5 (LE). The SoC is powered by +a single-core, 32-bit RISC-V microcontroller that can be clocked up to 96 MHz. The ESP32-H2 has +been designed to ensure low power consumption and security for connected devices. ESP32-H2 has +320 KB of SRAM with 16 KB of Cache, 128 KB of ROM, 4 KB LP of memory, and a built-in 2 MB or 4 MB +SiP flash. It has 19 programmable GPIOs with support for ADC, SPI, UART, I2C, I2S, RMT, GDMA +and LED PWM. + +ESP32-H2 main features: + +- RISC-V 32-bit single-core microprocessor +- 320 KB of internal RAM +- 4 KB LP Memory +- Bluetooth LE: Bluetooth 5.3 certified +- IEEE 802.15.4 (Zigbee and Thread) +- 19 programmable GPIOs +- Numerous peripherals (details below) + +Digital interfaces: + +- 19x GPIOs +- 2x UART +- 2x I2C +- 1x General-purpose SPI +- 1x I2S +- 1x Pulse counter +- 1x USB Serial/JTAG controller +- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) +- 1x LED PWM controller, up to 6 channels +- 1x Motor Control PWM (MCPWM) +- 1x Remote Control peripheral (RMT), with up to 2 TX and 2 RX channels +- 1x Parallel IO interface (PARLIO) +- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels +- Event Task Matrix (ETM) + +Analog interfaces: + +- 1x 12-bit SAR ADCs, up to 5 channels +- 1x Temperature sensor (die) + +Timers: + +- 1x 52-bit system timer +- 2x 54-bit general-purpose timers +- 3x Watchdog timers + +Low Power: + +- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep + +Security: + +- Secure boot +- Flash encryption +- 4-Kbit OTP, up to 1792 bits for users +- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) +- Random number generator (RNG) + +For detailed information, check the `ESP32-H2 Datasheet`_ or the `ESP32-H2 Technical Reference Manual`_. + +.. _`ESP32-H2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf +.. _`ESP32-H2 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32s2-features.rst b/boards/espressif/common/soc-esp32s2-features.rst new file mode 100644 index 0000000000000..44fa59fb5ed62 --- /dev/null +++ b/boards/espressif/common/soc-esp32s2-features.rst @@ -0,0 +1,35 @@ +:orphan: + +.. espressif-soc-esp32s2-features + +ESP32-S2 Features +================= + +ESP32-S2 is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, designed to be secure and +cost-effective, with a high performance and a rich set of IO capabilities. + +The features include the following: + +- RSA-3072-based secure boot +- AES-XTS-256-based flash encryption +- Protected private key and device secrets from software access +- Cryptographic accelerators for enhanced performance +- Protection against physical fault injection attacks +- Various peripherals: + + - 43x programmable GPIOs + - 14x configurable capacitive touch GPIOs + - USB OTG + - LCD interface + - camera interface + - SPI + - I2S + - UART + - ADC + - DAC + - LED PWM with up to 8 channels + +For more information, check the `ESP32-S2 Datasheet`_ or the `ESP32-S2 Technical Reference Manual`_. + +.. _`ESP32-S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf +.. _`ESP32-S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/soc-esp32s3-features.rst b/boards/espressif/common/soc-esp32s3-features.rst new file mode 100644 index 0000000000000..c0a338ec14c15 --- /dev/null +++ b/boards/espressif/common/soc-esp32s3-features.rst @@ -0,0 +1,76 @@ +:orphan: + +.. espressif-soc-esp32s3-features + +ESP32-S3 Features +================= + +ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi +and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor +(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, +RF module, and numerous peripherals. + +ESP32-S3 SoC includes the following features: + +- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz +- Additional vector instructions support for AI acceleration +- 512KB of SRAM +- 384KB of ROM +- Wi-Fi 802.11b/g/n +- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate + +Digital interfaces: + +- 45 programmable GPIOs +- 4x SPI +- 1x LCD interface (8-bit ~16-bit parallel RGB, I8080 and MOTO6800), supporting conversion between RGB565, YUV422, YUV420 and YUV411 +- 1x DVP 8-bit ~16-bit camera interface +- 3x UART +- 2x I2C +- 2x I2S +- 1x RMT (TX/RX) +- 1x pulse counter +- LED PWM controller, up to 8 channels +- 1x full-speed USB OTG +- 1x USB Serial/JTAG controller +- 2x MCPWM +- 1x SDIO host controller with 2 slots +- General DMA controller (GDMA), with 5 transmit channels and 5 receive channels +- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) +- Addressable RGB LED, driven by GPIO38. + +Analog interfaces: + +- 2x 12-bit SAR ADCs, up to 20 channels +- 1x temperature sensor +- 14x touch sensing IOs + +Timers: + +- 4x 54-bit general-purpose timers +- 1x 52-bit system timer +- 3x watchdog timers + +Low Power: + +- Power Management Unit with five power modes +- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM + +Security: + +- Secure boot +- Flash encryption +- 4-Kbit OTP, up to 1792 bits for users +- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) + +Asymmetric Multiprocessing (AMP) +================================ + +Boards featuring the ESP32-S3 SoC allows 2 different applications to be executed. Due to its dual-core +architecture, each core can be enabled to execute customized tasks in stand-alone mode +and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. + +For more information, check the `ESP32-S3 Datasheet`_ or the `ESP32-S3 Technical Reference Manual`_. + +.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf +.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf diff --git a/boards/espressif/common/system-requirements.rst b/boards/espressif/common/system-requirements.rst new file mode 100644 index 0000000000000..b0fd19d139031 --- /dev/null +++ b/boards/espressif/common/system-requirements.rst @@ -0,0 +1,17 @@ +:orphan: + +.. espressif-system-requirements + +Binary Blobs +============ + +Espressif HAL requires RF binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. diff --git a/boards/espressif/esp32_devkitc/doc/index.rst b/boards/espressif/esp32_devkitc/doc/index.rst index 48c1a4496a8cc..ddfd1d2041257 100644 --- a/boards/espressif/esp32_devkitc/doc/index.rst +++ b/boards/espressif/esp32_devkitc/doc/index.rst @@ -10,61 +10,22 @@ variations. ESP32 is created and developed by Espressif Systems, a Shanghai-based Chinese company, and is manufactured by TSMC using their 40nm process. For more information, check `ESP32-DevKitC`_. -The features include the following: - -- Dual core Xtensa microprocessor (LX6), running at 160 or 240MHz -- 520KB of SRAM -- 802.11b/g/n/e/i -- Bluetooth v4.2 BR/EDR and BLE -- Various peripherals: - - - 12-bit ADC with up to 18 channels - - 2x 8-bit DACs - - 10x touch sensors - - Temperature sensor - - 4x SPI - - 2x I2S - - 2x I2C - - 3x UART - - SD/SDIO/MMC host - - Slave (SDIO/SPI) - - Ethernet MAC - - CAN bus 2.0 - - IR (RX/TX) - - Motor PWM - - LED PWM with up to 16 channels - - Hall effect sensor - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) -- 5uA deep sleep current - -For more information, check the datasheet at `ESP32 Datasheet`_ or the technical reference -manual at `ESP32 Technical Reference Manual`_. - -Asymmetric Multiprocessing (AMP) -******************************** - -ESP32-DevKitC-WROVER allows 2 different applications to be executed in ESP32 SoC. Due to its dual-core architecture, each core can be enabled to execute customized tasks in stand-alone mode -and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. +Hardware +******** + +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features Supported Features -****************** +================== .. zephyr:board-supported-hw:: System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -80,7 +41,8 @@ Programming and Debugging Debugging ========= -ESP32 support on OpenOCD is available at `OpenOCD ESP32`_. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging On the ESP32-DevKitC board, the JTAG pins are not run to a standard connector (e.g. ARM 20-pin) and need to be manually connected @@ -104,40 +66,9 @@ to the external programmer (e.g. a Flyswatter2): | IO15 | TDO | +------------+-----------+ -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32_devkitc/esp32/procpu - :goals: build flash - -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: esp32_devkitc/esp32/procpu - :goals: debug - -Note on Debugging with GDB Stub -=============================== - -GDB stub is enabled on ESP32. - -* When adding breakpoints, please use hardware breakpoints with command - ``hbreak``. Command ``break`` uses software breakpoints which requires - modifying memory content to insert break/trap instructions. - This does not work as the code is on flash which cannot be randomly - accessed for modification. - References ********** .. target-notes:: .. _`ESP32-DevKitC`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32/esp32-devkitc/index.html -.. _`ESP32 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf -.. _`ESP32 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32_ethernet_kit/doc/index.rst b/boards/espressif/esp32_ethernet_kit/doc/index.rst index 5c58a64e06822..17c5104d54fa5 100644 --- a/boards/espressif/esp32_ethernet_kit/doc/index.rst +++ b/boards/espressif/esp32_ethernet_kit/doc/index.rst @@ -37,13 +37,16 @@ USB interface without a separate JTAG debugger. Hardware ******** +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features -****************** +================== .. zephyr:board-supported-hw:: Functionality Overview -********************** +====================== The block diagram below shows the main components of ESP32-Ethernet-Kit and their interconnections. @@ -55,7 +58,6 @@ and their interconnections. ESP32-Ethernet-Kit block diagram - Functional Description ====================== @@ -64,7 +66,6 @@ and controls of the ESP32-Ethernet-Kit. .. _get-started-esp32-ethernet-kit-a-v1.2-layout: - Ethernet Board (A) ------------------ @@ -187,9 +188,8 @@ PoE. When the Ethernet Board (A) detects 5 V power output from the PoE Board .. _get-started-esp32-ethernet-kit-v1.2-setup-options: - Setup Options -************* +============= This section describes options to configure the ESP32-Ethernet-Kit hardware. @@ -211,7 +211,6 @@ DIP SW GPIO Pin 4 GPIO14 ======= ================ - RMII Clock Selection ==================== @@ -267,14 +266,12 @@ sheet 2, location D2. Please note that if the APLL is already used for other purposes (e.g. I2S peripheral), then you have no choice but use an external RMII clock. - GPIO Allocation -*************** +=============== This section describes allocation of ESP32 GPIOs to specific interfaces or functions of the ESP32-Ethernet-Kit. - IP101GRI (PHY) Interface ======================== @@ -312,7 +309,6 @@ No. ESP32 Pin (MAC) IP101GRI (PHY) be selected from GPIO0, GPIO16 or GPIO17 and it can not be changed through GPIO Matrix. - GPIO Header 1 ============= @@ -330,7 +326,6 @@ No. ESP32 Pin 6 GPIO39 ==== ================ - GPIO Header 2 ============= @@ -413,22 +408,8 @@ GPIO Allocation Summary to use these pins, please solder a module without PSRAM memory inside, e.g. the ESP32-WROOM-32D or ESP32-SOLO-1. -System Requirements -******************* - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - Enabling Ethernet -***************** +================= Enable Ethernet MAC, PHY and MDIO; add these to your device tree overlay: @@ -455,11 +436,17 @@ Enable Ethernet in KConfig: CONFIG_NET_L2_ETHERNET=y Board Init -********** +========== RESET_N (GPIO5) is automatically set high to enable the Ethernet PHY during board initialization (board_init.c) +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + Programming and Debugging ************************* @@ -484,4 +471,3 @@ References .. _`ESP32-Ethernet-Kit V1.2 Ethernet Board (A) Schematic`: https://dl.espressif.com/dl/schematics/SCH_ESP32-Ethernet-Kit_A_V1.2_20200528.pdf .. _`ESP32-WROVER-E Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-wrover-e_esp32-wrover-ie_datasheet_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32c3_devkitc/doc/index.rst b/boards/espressif/esp32c3_devkitc/doc/index.rst index 6ba73a120c847..5c00c7e41bafa 100644 --- a/boards/espressif/esp32c3_devkitc/doc/index.rst +++ b/boards/espressif/esp32c3_devkitc/doc/index.rst @@ -10,34 +10,8 @@ For more information, check `ESP32-C3-DevKitC`_. Hardware ******** -ESP32-C3 is a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, -based on the open-source RISC-V architecture. It strikes the right balance of power, -I/O capabilities and security, thus offering the optimal cost-effective -solution for connected devices. -The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, -but it also facilitates a variety of use-cases based on dual connectivity. - -The features include the following: - -- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz -- 400 KB of internal RAM -- 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh -- Various peripherals: - - - 12-bit ADC with up to 6 channels - - TWAI compatible with CAN bus 2.0 - - Temperature sensor - - 3x SPI - - 1x I2S - - 1x I2C - - 2x UART - - LED PWM with up to 6 channels - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) - -For more information, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference -manual at `ESP32-C3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Supported Features ================== @@ -47,16 +21,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -81,6 +47,3 @@ References .. target-notes:: .. _`ESP32-C3-DevKitC`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c3/esp32-c3-devkitc-02/index.html -.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32c3_devkitm/doc/index.rst b/boards/espressif/esp32c3_devkitm/doc/index.rst index c1319966e44b8..a46f754694482 100644 --- a/boards/espressif/esp32c3_devkitm/doc/index.rst +++ b/boards/espressif/esp32c3_devkitm/doc/index.rst @@ -10,34 +10,8 @@ For more information, check `ESP32-C3-DevKitM`_. Hardware ******** -ESP32-C3 is a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, -based on the open-source RISC-V architecture. It strikes the right balance of power, -I/O capabilities and security, thus offering the optimal cost-effective -solution for connected devices. -The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, -but it also facilitates a variety of use-cases based on dual connectivity. - -The features include the following: - -- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz -- 400 KB of internal RAM -- 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh -- Various peripherals: - - - 12-bit ADC with up to 6 channels - - TWAI compatible with CAN bus 2.0 - - Temperature sensor - - 3x SPI - - 1x I2S - - 1x I2C - - 2x UART - - LED PWM with up to 6 channels - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) - -For more information, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference -manual at `ESP32-C3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Supported Features ================== @@ -47,16 +21,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -81,6 +47,3 @@ References .. target-notes:: .. _`ESP32-C3-DevKitM`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html -.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32c3_rust/doc/index.rst b/boards/espressif/esp32c3_rust/doc/index.rst index 2ab911aab84b0..8412e18952dfd 100644 --- a/boards/espressif/esp32c3_rust/doc/index.rst +++ b/boards/espressif/esp32c3_rust/doc/index.rst @@ -12,32 +12,8 @@ For more information, check `ESP32-C3-DevKit-RUST`_. Hardware ******** -SoC Features: - -- IEEE 802.11 b/g/n-compliant -- Bluetooth 5, Bluetooth mesh -- 32-bit RISC-V single-core processor, up to 160MHz -- 384 KB ROM -- 400 KB SRAM (16 KB for cache) -- 8 KB SRAM in RTC -- 22 x programmable GPIOs -- 3 x SPI -- 2 x UART -- 1 x I2C -- 1 x I2S -- 2 x 54-bit general-purpose timers -- 3 x watchdog timers -- 1 x 52-bit system timer -- Remote Control Peripheral (RMT) -- LED PWM controller (LEDC) -- Full-speed USB Serial/JTAG controller -- General DMA controller (GDMA) -- 1 x TWAI® -- 2 x 12-bit SAR ADCs, up to 6 channels -- 1 x temperature sensor - -For more information, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference -manual at `ESP32-C3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Supported Features ================== @@ -92,16 +68,8 @@ Power System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -126,6 +94,3 @@ References .. target-notes:: .. _`ESP32-C3-DevKit-RUST`: https://github.com/esp-rs/esp-rust-board/tree/v1.2 -.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32c6_devkitc/doc/index.rst b/boards/espressif/esp32c6_devkitc/doc/index.rst index 3477165463f24..79b4703c07227 100644 --- a/boards/espressif/esp32c6_devkitc/doc/index.rst +++ b/boards/espressif/esp32c6_devkitc/doc/index.rst @@ -10,13 +10,6 @@ Bluetooth LE, Zigbee, and Thread functions. For more information, check `ESP32-C Hardware ******** -ESP32-C6 is Espressif's first Wi-Fi 6 SoC integrating 2.4 GHz Wi-Fi 6, Bluetooth 5.3 (LE) and the -802.15.4 protocol. ESP32-C6 achieves an industry-leading RF performance, with reliable security -features and multiple memory resources for IoT products. -It consists of a high-performance (HP) 32-bit RISC-V processor, which can be clocked up to 160 MHz, -and a low-power (LP) 32-bit RISC-V processor, which can be clocked up to 20 MHz. -It has a 320KB ROM, a 512KB SRAM, and works with external flash. - ESP32-C6-DevKitC is an entry-level development board based on ESP32-C6-WROOM-1(U), a general-purpose module with a 8 MB SPI flash. @@ -24,62 +17,8 @@ Most of the I/O pins are broken out to the pin headers on both sides for easy in Developers can either connect peripherals with jumper wires or mount ESP32-C6-DevKitC on a breadboard. -ESP32-C6 includes the following features: - -- 32-bit core RISC-V microcontroller with a clock speed of up to 160 MHz -- 400 KB of internal RAM -- WiFi 802.11 ax 2.4GHz -- Fully compatible with IEEE 802.11b/g/n protocol -- Bluetooth LE: Bluetooth 5.3 certified -- Internal co-existence mechanism between Wi-Fi and Bluetooth to share the same antenna -- IEEE 802.15.4 (Zigbee and Thread) - -Digital interfaces: - -- 30x GPIOs (QFN40), or 22x GPIOs (QFN32) -- 2x UART -- 1x Low-power (LP) UART -- 1x General purpose SPI -- 1x I2C -- 1x Low-power (LP) I2C -- 1x I2S -- 1x Pulse counter -- 1x USB Serial/JTAG controller -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) -- 1x SDIO 2.0 slave controller -- LED PWM controller, up to 6 channels -- 1x Motor control PWM (MCPWM) -- 1x Remote control peripehral -- 1x Parallel IO interface (PARLIO) -- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels -- Event task matrix (ETM) - -Analog interfaces: - -- 1x 12-bit SAR ADCs, up to 7 channels -- 1x temperature sensor - -Timers: - -- 1x 52-bit system timer -- 1x 54-bit general-purpose timers -- 3x Watchdog timers -- 1x Analog watchdog timer - -Low Power: - -- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) -- Random number generator (RNG) - -For more information, check the datasheet at `ESP32-C6 Datasheet`_ or the technical reference -manual at `ESP32-C6 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c6-features.rst + :start-after: espressif-soc-esp32c6-features Supported Features ================== @@ -89,16 +28,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -117,36 +48,9 @@ Debugging .. include:: ../../../espressif/common/openocd-debugging.rst :start-after: espressif-openocd-debugging -Low-Power CPU (LP CORE) -*********************** - -The ESP32-C6 SoC has two RISC-V cores: the High-Performance Core (HP CORE) and the Low-Power Core (LP CORE). -The LP Core features ultra low power consumption, an interrupt controller, a debug module and a system bus -interface for memory and peripheral access. - -The LP Core is in sleep mode by default. It has two application scenarios: - -- Power insensitive scenario: When the High-Performance CPU (HP Core) is active, the LP Core can assist the HP CPU with some speed and efficiency-insensitive controls and computations. -- Power sensitive scenario: When the HP CPU is in the power-down state to save power, the LP Core can be woken up to handle some external wake-up events. - -For more information, check the datasheet at `ESP32-C6 Datasheet`_ or the technical reference -manual at `ESP32-C6 Technical Reference Manual`_. - -The LP Core support is fully integrated with :ref:`sysbuild`. The user can enable the LP Core by adding -the following configuration to the project: - -.. code:: cfg - - CONFIG_ULP_COPROC_ENABLED=y - -See :zephyr:code-sample-category:`lp-core` folder as code reference. - References ********** .. target-notes:: .. _`ESP32-C6-DevKitC`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/user_guide.html -.. _`ESP32-C6 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf -.. _`ESP32-C6 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32h2_devkitm/doc/index.rst b/boards/espressif/esp32h2_devkitm/doc/index.rst index f1f64f7cd2c48..d7b10d72fd9d2 100644 --- a/boards/espressif/esp32h2_devkitm/doc/index.rst +++ b/boards/espressif/esp32h2_devkitm/doc/index.rst @@ -14,69 +14,8 @@ For details on getting started, check `ESP32-H2-DevKitM-1`_. Hardware ******** -ESP32-H2 combines IEEE 802.15.4 connectivity with Bluetooth 5 (LE). The SoC is powered by -a single-core, 32-bit RISC-V microcontroller that can be clocked up to 96 MHz. The ESP32-H2 has -been designed to ensure low power consumption and security for connected devices. ESP32-H2 has -320 KB of SRAM with 16 KB of Cache, 128 KB of ROM, 4 KB LP of memory, and a built-in 2 MB or 4 MB -SiP flash. It has 19 programmable GPIOs with support for ADC, SPI, UART, I2C, I2S, RMT, GDMA -and LED PWM. - -Most of ESP32-H2-DevKitM-1's I/O pins are broken out to the pin headers on both sides for easy -interfacing. Developers can either connect peripherals with jumper wires or mount the board -on a breadboard. - -ESP32-H2 main features: - -- RISC-V 32-bit single-core microprocessor -- 320 KB of internal RAM -- 4 KB LP Memory -- Bluetooth LE: Bluetooth 5.3 certified -- IEEE 802.15.4 (Zigbee and Thread) -- 19 programmable GPIOs -- Numerous peripherals (details below) - -Digital interfaces: - -- 19x GPIOs -- 2x UART -- 2x I2C -- 1x General-purpose SPI -- 1x I2S -- 1x Pulse counter -- 1x USB Serial/JTAG controller -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) -- 1x LED PWM controller, up to 6 channels -- 1x Motor Control PWM (MCPWM) -- 1x Remote Control peripheral (RMT), with up to 2 TX and 2 RX channels -- 1x Parallel IO interface (PARLIO) -- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels -- Event Task Matrix (ETM) - -Analog interfaces: - -- 1x 12-bit SAR ADCs, up to 5 channels -- 1x Temperature sensor (die) - -Timers: - -- 1x 52-bit system timer -- 2x 54-bit general-purpose timers -- 3x Watchdog timers - -Low Power: - -- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) -- Random number generator (RNG) - -For detailed information, check the datasheet at `ESP32-H2 Datasheet`_ or the Technical Reference -Manual at `ESP32-H2 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32h2-features.rst + :start-after: espressif-soc-esp32h2-features Supported Features ================== @@ -86,16 +25,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -120,5 +51,3 @@ References .. target-notes:: .. _`ESP32-H2-DevKitM-1`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32h2/esp32-h2-devkitm-1/user_guide.html -.. _`ESP32-H2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf -.. _`ESP32-H2 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf diff --git a/boards/espressif/esp32s2_devkitc/doc/index.rst b/boards/espressif/esp32s2_devkitc/doc/index.rst index b3bef993a45f7..c269d657691ce 100644 --- a/boards/espressif/esp32s2_devkitc/doc/index.rst +++ b/boards/espressif/esp32s2_devkitc/doc/index.rst @@ -11,32 +11,8 @@ For more information, check `ESP32-S2-DevKitC`_. Hardware ******** -ESP32-S2 is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, designed to be secure and -cost-effective, with a high performance and a rich set of IO capabilities. - -The features include the following: - -- RSA-3072-based secure boot -- AES-XTS-256-based flash encryption -- Protected private key and device secrets from software access -- Cryptographic accelerators for enhanced performance -- Protection against physical fault injection attacks -- Various peripherals: - - - 43x programmable GPIOs - - 14x configurable capacitive touch GPIOs - - USB OTG - - LCD interface - - camera interface - - SPI - - I2S - - UART - - ADC - - DAC - - LED PWM with up to 8 channels - -For more information, check the datasheet at `ESP32-S2 Datasheet`_ or the technical reference -manual at `ESP32-S2 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32s2-features.rst + :start-after: espressif-soc-esp32s2-features Supported Features ================== @@ -46,16 +22,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -94,7 +62,3 @@ References .. target-notes:: .. _`ESP32-S2-DevKitC`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html -.. _`ESP32-S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf -.. _`ESP32-S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32-S2`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/jtag-debugging/index.html -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32s2_saola/doc/index.rst b/boards/espressif/esp32s2_saola/doc/index.rst index 418fde8cba778..756ad038e805b 100644 --- a/boards/espressif/esp32s2_saola/doc/index.rst +++ b/boards/espressif/esp32s2_saola/doc/index.rst @@ -11,32 +11,8 @@ For more information, check `ESP32-S3-DevKitC`_. Hardware ******** -ESP32-S2 is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, designed to be secure and -cost-effective, with a high performance and a rich set of IO capabilities. - -The features include the following: - -- RSA-3072-based secure boot -- AES-XTS-256-based flash encryption -- Protected private key and device secrets from software access -- Cryptographic accelerators for enhanced performance -- Protection against physical fault injection attacks -- Various peripherals: - - - 43x programmable GPIOs - - 14x configurable capacitive touch GPIOs - - USB OTG - - LCD interface - - camera interface - - SPI - - I2S - - UART - - ADC - - DAC - - LED PWM with up to 8 channels - -For more information, check the datasheet at `ESP32-S2 Datasheet`_ or the technical reference -manual at `ESP32-S2 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32s2-features.rst + :start-after: espressif-soc-esp32s2-features Supported Features ================== @@ -46,16 +22,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -94,7 +62,3 @@ References .. target-notes:: .. _`ESP32-S3-DevKitC`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html -.. _`ESP32-S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf -.. _`ESP32-S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32-S2`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/jtag-debugging/index.html -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32s3_devkitc/doc/index.rst b/boards/espressif/esp32s3_devkitc/doc/index.rst index 6fce1233a6894..a082b9569d42e 100644 --- a/boards/espressif/esp32s3_devkitc/doc/index.rst +++ b/boards/espressif/esp32s3_devkitc/doc/index.rst @@ -10,73 +10,8 @@ and Bluetooth Low Energy functions. For more information, check `ESP32-S3-DevKit Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. - -ESP32-S3-DevKitC includes the following features: - -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 512KB of SRAM -- 384KB of ROM -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate - -Digital interfaces: - -- 45 programmable GPIOs -- 4x SPI -- 1x LCD interface (8-bit ~16-bit parallel RGB, I8080 and MOTO6800), supporting conversion between RGB565, YUV422, YUV420 and YUV411 -- 1x DVP 8-bit ~16-bit camera interface -- 3x UART -- 2x I2C -- 2x I2S -- 1x RMT (TX/RX) -- 1x pulse counter -- LED PWM controller, up to 8 channels -- 1x full-speed USB OTG -- 1x USB Serial/JTAG controller -- 2x MCPWM -- 1x SDIO host controller with 2 slots -- General DMA controller (GDMA), with 5 transmit channels and 5 receive channels -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) -- Addressable RGB LED, driven by GPIO38. - -Analog interfaces: - -- 2x 12-bit SAR ADCs, up to 20 channels -- 1x temperature sensor -- 14x touch sensing IOs - -Timers: - -- 4x 54-bit general-purpose timers -- 1x 52-bit system timer -- 3x watchdog timers - -Low Power: - -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) - -Asymmetric Multiprocessing (AMP) -******************************** - -ESP32S3-DevKitC allows 2 different applications to be executed in ESP32-S3 SoC. Due to its dual-core -architecture, each core can be enabled to execute customized tasks in stand-alone mode -and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_ or the technical reference -manual at `ESP32-S3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== @@ -86,16 +21,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -120,7 +47,3 @@ References .. target-notes:: .. _`ESP32-S3-DevKitC`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp32s3_devkitm/doc/index.rst b/boards/espressif/esp32s3_devkitm/doc/index.rst index bb403fb5ab0c8..ccd6d363ce296 100644 --- a/boards/espressif/esp32s3_devkitm/doc/index.rst +++ b/boards/espressif/esp32s3_devkitm/doc/index.rst @@ -10,92 +10,19 @@ and Bluetooth Low Energy functions. For more information, check `ESP32-S3-DevKit Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. - -ESP32-S3-DevKitM includes the following features: - -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 512KB of SRAM -- 384KB of ROM -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate - -Digital interfaces: - -- 45 programmable GPIOs -- 4x SPI -- 1x LCD interface (8-bit ~16-bit parallel RGB, I8080 and MOTO6800), supporting conversion between RGB565, YUV422, YUV420 and YUV411 -- 1x DVP 8-bit ~16-bit camera interface -- 3x UART -- 2x I2C -- 2x I2S -- 1x RMT (TX/RX) -- 1x pulse counter -- LED PWM controller, up to 8 channels -- 1x full-speed USB OTG -- 1x USB Serial/JTAG controller -- 2x MCPWM -- 1x SDIO host controller with 2 slots -- General DMA controller (GDMA), with 5 transmit channels and 5 receive channels -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) -- Addressable RGB LED, driven by GPIO48. - -Analog interfaces: - -- 2x 12-bit SAR ADCs, up to 20 channels -- 1x temperature sensor -- 14x touch sensing IOs - -Timers: - -- 4x 54-bit general-purpose timers -- 1x 52-bit system timer -- 3x watchdog timers - -Low Power: - -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== .. zephyr:board-supported-hw:: -Asymmetric Multiprocessing (AMP) -******************************** - -ESP32S3-DevKitM allows 2 different applications to be executed in ESP32-S3 SoC. Due to its dual-core -architecture, each core can be enabled to execute customized tasks in stand-alone mode -and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_ or the technical reference -manual at `ESP32-S3 Technical Reference Manual`_. - System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -120,7 +47,3 @@ References .. target-notes:: .. _`ESP32-S3-DevKitM User Guide`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitm-1.html -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-mini-1_mini-1u_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ diff --git a/boards/espressif/esp32s3_eye/doc/index.rst b/boards/espressif/esp32s3_eye/doc/index.rst index 7180ff7d81700..04e1ae7799b8a 100644 --- a/boards/espressif/esp32s3_eye/doc/index.rst +++ b/boards/espressif/esp32s3_eye/doc/index.rst @@ -3,8 +3,8 @@ Overview ******** -The ESP32-S3-EYE is a small-sized AI development board produced by `Espressif`_. -It is based on the `ESP32-S3`_ SoC. +The ESP32-S3-EYE is a small-sized AI development board produced by Espressif and based on the +ESP32-S3 SoC. It features a 2-Megapixel camera, an LCD display, and a microphone, which are used for image recognition and audio processing. ESP32-S3-EYE offers plenty of storage, with an 8 MB Octal PSRAM and a 8 MB flash. @@ -17,6 +17,9 @@ ESP32-S3-WROOM-1 module, camera, SD card slot, digital microphone, USB port, and and the sub board (ESP32-S3-EYE-SUB) that contains an LCD display. The main board and sub board are connected through pin headers. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== @@ -121,16 +124,8 @@ Components on the ESP32-S3-EYE-SUB Sub Board System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -152,8 +147,4 @@ Debugging References ********** -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases - -.. _`Espressif`: https://espressif.com - -.. _`ESP32-S3`: https://www.espressif.com/en/products/socs/esp32-s3 +.. target-notes:: diff --git a/boards/espressif/esp8684_devkitm/doc/index.rst b/boards/espressif/esp8684_devkitm/doc/index.rst index 22b0aef4f4893..a69a65701f891 100644 --- a/boards/espressif/esp8684_devkitm/doc/index.rst +++ b/boards/espressif/esp8684_devkitm/doc/index.rst @@ -10,38 +10,8 @@ For more information, check `ESP8684-DevKitM User Guide`_ Hardware ******** -ESP32-C2 (ESP8684 core) is a low-cost, Wi-Fi 4 & Bluetooth 5 (LE) chip. Its unique design -makes the chip smaller and yet more powerful than ESP8266. ESP32-C2 is built around a RISC-V -32-bit, single-core processor, with 272 KB of SRAM (16 KB dedicated to cache) and 576 KB of ROM. -ESP32-C2 has been designed to target simple, high-volume, and low-data-rate IoT applications, -such as smart plugs and smart light bulbs. ESP32-C2 offers easy and robust wireless connectivity, -which makes it the go-to solution for developing simple, user-friendly and reliable -smart-home devices. For more information, check `ESP8684 Datasheet`_. - -Features include the following: - -- 32-bit core RISC-V microcontroller with a maximum clock speed of 120 MHz -- 2 MB or 4 MB in chip (ESP8684) or in package (ESP32-C2) flash -- 272 KB of internal RAM -- 802.11b/g/n -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh -- Various peripherals: - - - 14 programmable GPIOs - - 3 SPI - - 2 UART - - 1 I2C Master - - LED PWM controller, with up to 6 channels - - General DMA controller (GDMA) - - 1 12-bit SAR ADC, up to 5 channels - - 1 temperature sensor - - 1 54-bit general-purpose timer - - 2 watchdog timers - - 1 52-bit system timer - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) - -For detailed information check `ESP8684 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c2-features.rst + :start-after: espressif-soc-esp32c2-features Supported Features ================== @@ -53,16 +23,8 @@ For a getting started user guide, please check `ESP8684-DevKitM User Guide`_. System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -87,6 +49,3 @@ References .. target-notes:: .. _`ESP8684-DevKitM User Guide`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp8684/esp8684-devkitm-1/user_guide.html -.. _`ESP8684 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp8684_datasheet_en.pdf -.. _`ESP8684 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp8684_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/espressif/esp_wrover_kit/doc/index.rst b/boards/espressif/esp_wrover_kit/doc/index.rst index 208550ee0ec5c..411f6eadf5b53 100644 --- a/boards/espressif/esp_wrover_kit/doc/index.rst +++ b/boards/espressif/esp_wrover_kit/doc/index.rst @@ -3,8 +3,6 @@ Overview ******** -ESP-WROVER-KIT is an ESP32-based development board produced by `Espressif `_. - ESP-WROVER-KIT features the following integrated components: - ESP32-WROVER-E module @@ -25,12 +23,17 @@ Most of the ESP32 I/O pins are broken out to the board's pin headers for easy ac For more information, check `ESP32-WROVER-E Datasheet`_ and `ESP32 Datasheet`_. +Hardware +******** + +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: - Functionality Overview ====================== @@ -160,7 +163,7 @@ The table below provides description in the following manner: .. _setup options: Setup Options -************* +============= There are three jumper blocks available to set up the board functionality. The most frequently required options are listed in the table below. @@ -190,7 +193,7 @@ required options are listed in the table below. +--------+----------------+-------------------------------------------------------+ Allocation of ESP32 Pins -************************ +======================== Some pins / terminals of ESP32 are allocated for use with the onboard or external hardware. If that hardware is not used, e.g., nothing is plugged into the Camera (JP4) header, then these @@ -211,7 +214,7 @@ For more details on which pins are shared among which peripherals, please refer the next section. Main I/O Connector / JP1 -************************ +======================== The JP1 connector consists of 14x2 male pins whose functions are shown in the middle two “I/O” columns of the table below. The two “Shared With” columns on both sides describe where else on @@ -261,7 +264,7 @@ Legend: - PSRAM - ESP32-WROVER-E's PSRAM 32.768 kHz Oscillator -********************* +===================== +---+-----------+ | . | ESP32 Pin | @@ -279,7 +282,7 @@ Legend: them to positions R12 / R24. SPI Flash / JP2 -*************** +=============== +---+--------------+ | . | ESP32 Pin | @@ -304,7 +307,7 @@ SPI Flash / JP2 module's flash bus from the pin header JP2. JTAG / JP2 -********** +========== +---+---------------+-------------+ | . | ESP32 Pin | JTAG Signal | @@ -321,7 +324,7 @@ JTAG / JP2 +---+---------------+-------------+ Camera / JP4 -************ +============ +----+-----------+-----------------------------+ | . | ESP32 Pin | Camera Signal | @@ -366,7 +369,7 @@ Camera / JP4 - Signals D0 .. D7 denote camera data bus RGB LED -******* +======= +----+-----------+---------+ | . | ESP32 Pin | RGB LED | @@ -379,7 +382,7 @@ RGB LED +----+-----------+---------+ MicroSD Card -************ +============ +---+---------------+----------------+ | . | ESP32 Pin | MicroSD Signal | @@ -400,7 +403,7 @@ MicroSD Card +---+---------------+----------------+ LCD / U5 -******** +======== +---+-----------+------------+ | . | ESP32 Pin | LCD Signal | @@ -420,14 +423,8 @@ LCD / U5 | 7 | GPIO5 | Backlight | +---+-----------+------------+ -Start Application Development -***************************** - -Before powering up your ESP-WROVER-KIT, please make sure that the board is in good -condition with no obvious signs of damage. - Initial Setup -************* +============= Please set only the following jumpers shown in the pictures below: @@ -447,16 +444,8 @@ Turn the Power Switch to ON, the 5V Power On LED should light up. System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -472,7 +461,8 @@ Programming and Debugging Debugging ========= -ESP32 support on OpenOCD is available at `OpenOCD ESP32`_. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging On the ESP-WROVER-KIT board, the JTAG pins are connected internally to a USB serial port on the same device as the console. These boards @@ -483,27 +473,10 @@ headers are on the right side of the board as viewed from the power switch, next to similar headers for SPI and UART. See `ESP-WROVER-32 V3 Getting Started Guide`_ for details. -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp_wrover_kit/esp32/procpu - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp_wrover_kit/esp32/procpu - :goals: debug - References ********** .. target-notes:: -.. _`ESP32 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf (PDF) .. _`ESP32-WROVER-E Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-wrover-e_esp32-wrover-ie_datasheet_en.pdf (PDF) -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases .. _`ESP-WROVER-32 V3 Getting Started Guide`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-wrover-kit.html diff --git a/boards/espressif/index.rst b/boards/espressif/index.rst index b1b7dfbeede26..d488266df3d1b 100644 --- a/boards/espressif/index.rst +++ b/boards/espressif/index.rst @@ -7,4 +7,4 @@ Espressif :maxdepth: 1 :glob: - **/* + */**/index diff --git a/boards/franzininho/esp32s2_franzininho/doc/index.rst b/boards/franzininho/esp32s2_franzininho/doc/index.rst index bdbc20574ecdb..97de6f586db2c 100644 --- a/boards/franzininho/esp32s2_franzininho/doc/index.rst +++ b/boards/franzininho/esp32s2_franzininho/doc/index.rst @@ -4,172 +4,40 @@ Overview ******** Franzininho is an educational development board based on ESP32-S2 which is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, -designed to be secure and cost-effective, with a high performance and a rich set of IO capabilities. [1]_ +designed to be secure and cost-effective, with a high performance and a rich set of IO capabilities. -The features include the following: - -- RSA-3072-based secure boot -- AES-XTS-256-based flash encryption -- Protected private key and device secrets from software access -- Cryptographic accelerators for enhanced performance -- Protection against physical fault injection attacks -- Various peripherals: - - - 43x programmable GPIOs - - 14x configurable capacitive touch GPIOs - - USB OTG - - LCD interface - - camera interface - - SPI - - I2S - - UART - - ADC - - DAC - - LED PWM with up to 8 channels - -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +Hardware +******** - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/soc-esp32s2-features.rst + :start-after: espressif-soc-esp32s2-features -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Sysbuild -======== +Programming and Debugging +************************* -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32s2_franzininho - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s2_franzininho - :goals: build - -The usual ``flash`` target will work with the ``esp32s2_franzininho`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s2_franzininho - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell +.. zephyr:board-supported-runners:: - west espressif monitor +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32s2_franzininho +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. [1] https://www.espressif.com/en/products/socs/esp32-s2 -.. _`ESP32S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf -.. _`ESP32S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf +.. _`ESP32-S2 Product page`: https://www.espressif.com/en/products/socs/esp32-s2 diff --git a/boards/hardkernel/odroid_go/doc/index.rst b/boards/hardkernel/odroid_go/doc/index.rst index 3c14c9c23b0f8..23d44955404f7 100644 --- a/boards/hardkernel/odroid_go/doc/index.rst +++ b/boards/hardkernel/odroid_go/doc/index.rst @@ -5,21 +5,27 @@ Overview ODROID-GO Game Kit is a "Do it yourself" ("DIY") portable game console by HardKernel. It features a custom ESP32-WROVER with 16 MB flash and it operates -from 80 MHz - 240 MHz [1]_. +from 80 MHz - 240 MHz. More details can be found in `ODROID-GO pages`_. -The features include the following: +Hardware +******** + +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + +The board peripherals: -- Dual core Xtensa microprocessor (LX6), running at 80 - 240MHz -- 4 MB of PSRAM -- 802.11b/g/n/e/i -- Bluetooth v4.2 BR/EDR and BLE - 2.4 inch 320x240 TFT LCD - Speaker - Micro SD card slot - Micro USB port (battery charging and USB_UART data communication - Input Buttons (Menu, Volume, Select, Start, A, B, Direction Pad) - Expansion port (I2C, GPIO, SPI) -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) + +Supported Features +================== + +.. zephyr:board-supported-hw:: External Connector ================== @@ -48,179 +54,32 @@ External Connector | 10 | VBUS | USB VBUS (5V) | +-------+------------------+-------------------------+ -Supported Features -================== - -.. zephyr:board-supported-hw:: - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: odroid_go - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: odroid_go/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``odroid_go`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: odroid_go/esp32/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! odroid_go +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants 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 ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: odroid_go/esp32/procpu - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: odroid_go/esp32/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. [1] https://wiki.odroid.com/odroid_go/odroid_go -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases +.. _`ODROID-GO pages`: https://wiki.odroid.com/odroid_go/odroid_go diff --git a/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst b/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst index abe91f4ca90d2..397b1dbc5edac 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst +++ b/boards/heltec/heltec_wifi_lora32_v2/doc/index.rst @@ -5,7 +5,7 @@ Overview Heltec WiFi LoRa 32 is a classic IoT dev-board designed & produced by Heltec Automation(TM), it's a highly integrated product based on ESP32 + SX127x, it has Wi-Fi, BLE, LoRa functions, also Li-Po battery management -system, 0.96" OLED are also included. [1]_ +system, 0.96" OLED are also included. See the `Heltec WiFi LoRa (V2) pages`_ for more details. The features include the following: @@ -19,169 +19,34 @@ The features include the following: - Onboard 0.96-inch 128*64 dot matrix OLED display - Integrated CP2102 USB to serial port chip -System requirements -******************* - -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +Hardware +******** - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: heltec_wifi_lora32_v2 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: +Programming and Debugging +************************* - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wifi_lora32_v2/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``heltec_wifi_lora32_v2`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wifi_lora32_v2/esp32/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! heltec_wifi_lora32_v2 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants 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 ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. +========= -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wifi_lora32_v2/esp32/procpu - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wifi_lora32_v2/esp32/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging Utilizing Hardware Features *************************** @@ -202,10 +67,8 @@ connected via I2C. It can therefore be used by enabling the References ********** -- `Heltec WiFi LoRa (v2) Pinout Diagram `_ -- `Heltec WiFi LoRa (v2) Schematic Diagrams `_ -- `ESP32 Toolchain `_ -- `esptool documentation `_ -- `OpenOCD ESP32 `_ +.. target-notes:: -.. [1] https://heltec.org/project/wifi-lora-32/ +.. _`Heltec WiFi LoRa (V2) pages`: https://heltec.org/project/wifi-lora-32/ +.. _`Heltec WiFi LoRa (v2) Pinout Diagram`: https://resource.heltec.cn/download/WiFi_LoRa_32/WIFI_LoRa_32_V2.pdf +.. _`Heltec WiFi LoRa (v2) Schematic Diagrams`: https://resource.heltec.cn/download/WiFi_LoRa_32/V2 diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst b/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst index 431f83d41ebeb..02a846d47fa67 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst +++ b/boards/heltec/heltec_wireless_stick_lite_v3/doc/index.rst @@ -3,7 +3,8 @@ Overview ******** -HelTec Wireless Stick Lite (V3) is a development board with Wi-Fi, Bluetooth and LoRa support. It is designed and produced by HelTec Automation(TM). [1]_ +HelTec Wireless Stick Lite (V3) is a development board with Wi-Fi, Bluetooth and LoRa support. +It is designed and produced by HelTec Automation(TM). See the `Heltec Wireless Stick Lite (v3) pages`_ for more details. Hardware ******** @@ -18,6 +19,9 @@ The main hardware features are: - Integrated CP2102 USB to serial port chip, convenient for program downloading, debugging information printing. - Good RF circuit design and low-power design. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== @@ -120,178 +124,35 @@ Connections and IOs | J3.20 | TWAI_RX | CAN (optional) | +--------+---------+-----------------------------+ - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32-S3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: heltec_wireless_stick_lite_v3 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32S3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wireless_stick_lite_v3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``heltec_wireless_stick_lite_v3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wireless_stick_lite_v3/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! heltec_wireless_stick_lite_v3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ========= -As with much custom hardware, the ESP32S3 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wireless_stick_lite_v3/esp32s3/procpu - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: heltec_wireless_stick_lite_v3/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** -- `Heltec Wireless Stick Lite (v3) Pinout Diagram `_ -- `Heltec Wireless Stick Lite (v3) Schematic Diagrams `_ -- `ESP-IDF Programming Guide `_ -- `esptool documentation `_ -- `OpenOCD ESP32 `_ +.. target-notes:: -.. [1] https://heltec.org/project/wireless-stick-lite-v2/ +.. _`Heltec Wireless Stick Lite (v3) pages`: https://heltec.org/project/wireless-stick-lite-v2/ +.. _`Heltec Wireless Stick Lite (v3) Pinout Diagram`: https://resource.heltec.cn/download/Wireless_Stick_Lite_V3/HTIT-WSL_V3.png +.. _`Heltec Wireless Stick Lite (v3) Schematic Diagrams`: https://resource.heltec.cn/download/Wireless_Stick_Lite_V3/HTIT-WSL_V3_Schematic_Diagram.pdf +.. _`ESP-IDF Programming Guide`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/index.html diff --git a/boards/infineon/kit_pse84_eval/board.yml b/boards/infineon/kit_pse84_eval/board.yml index 821aeea313213..1e6733003ee1c 100644 --- a/boards/infineon/kit_pse84_eval/board.yml +++ b/boards/infineon/kit_pse84_eval/board.yml @@ -5,7 +5,7 @@ board: name: kit_pse84_eval - full_name: kit_pse84_eval + full_name: PSOC Edge E84 Evaluation Kit vendor: infineon socs: - name: pse846gps2dbzc4a diff --git a/boards/intel/adsp/intel_adsp_ace15_mtpm_sim_defconfig b/boards/intel/adsp/intel_adsp_ace15_mtpm_sim_defconfig index 8c36c0e39dda9..17279c64c5be1 100644 --- a/boards/intel/adsp/intel_adsp_ace15_mtpm_sim_defconfig +++ b/boards/intel/adsp/intel_adsp_ace15_mtpm_sim_defconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_INTEL_ADSP_SIM=y -CONFIG_INTEL_ADSP_SIM_NO_SECONDARY_CORE_FLOW=y CONFIG_GEN_ISR_TABLES=y CONFIG_GEN_IRQ_VECTOR_TABLE=n diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl_sim_defconfig b/boards/intel/adsp/intel_adsp_ace30_ptl_sim_defconfig index 5373f0c0bf841..03a0eff15fcc9 100644 --- a/boards/intel/adsp/intel_adsp_ace30_ptl_sim_defconfig +++ b/boards/intel/adsp/intel_adsp_ace30_ptl_sim_defconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_INTEL_ADSP_SIM=y -CONFIG_INTEL_ADSP_SIM_NO_SECONDARY_CORE_FLOW=y CONFIG_GEN_ISR_TABLES=y CONFIG_GEN_IRQ_VECTOR_TABLE=n diff --git a/boards/intel/adsp/intel_adsp_ace40_nvl_sim.dts b/boards/intel/adsp/intel_adsp_ace40_nvl_sim.dts new file mode 100644 index 0000000000000..312f4b3f8ba97 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace40_nvl_sim.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_ace40_nvl_sim"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &mem_window3; + }; +}; diff --git a/boards/kincony/kincony_kc868_a32/doc/index.rst b/boards/kincony/kincony_kc868_a32/doc/index.rst index 6a001bbfdd8e4..5ebeed6af4c48 100644 --- a/boards/kincony/kincony_kc868_a32/doc/index.rst +++ b/boards/kincony/kincony_kc868_a32/doc/index.rst @@ -4,9 +4,12 @@ Overview ******** Kincony KC868-A32 is a home automation relay module based on the -Espressif ESP-WROOM-32 module with all its inherent capabilities +Espressif ESP32 ESP-WROOM-32 module with all its inherent capabilities (Wi-Fi, Bluetooth, etc.) +Hardware +******** + The features include the following: - 32 digital optoisolated inputs “dry contact” @@ -20,58 +23,25 @@ The features include the following: - RESET and DOWNLOAD buttons - Powered by 12V DC -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features -.. code-block:: console +System Requirements +******************* - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -------------------- +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: kincony_kc868_a32/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``kincony_kc868_a32`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: kincony_kc868_a32/esp32/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! kincony_kc868_a32 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Enabling Ethernet ***************** diff --git a/boards/lilygo/tdongle_s3/doc/index.rst b/boards/lilygo/tdongle_s3/doc/index.rst index b90f5a214172c..01d0e17f60073 100644 --- a/boards/lilygo/tdongle_s3/doc/index.rst +++ b/boards/lilygo/tdongle_s3/doc/index.rst @@ -16,165 +16,44 @@ It features the following integrated components: - JST SH 1.0mm 4-pin UART connector - Transparent plastic case -Functional Description -********************** +Hardware +******** + This board is based on the ESP32-S3 with 16MB of flash, WiFi and BLE support. It has an USB-A port for programming and debugging, integrated battery charging and an on-board antenna. The fitted U.FL external antenna connector can be enabled by moving a 0-ohm resistor. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your Lilygo T-Dongle T8-S3, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: tdongle_s3/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flashed at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: tdongle_s3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``tdongle_s3`` board target. -Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: tdongle_s3/esp32s3/procpu - :goals: flash - -The default baud rate for the Lilygo T-Dongle S3 is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! tdongle_s3/esp32s3/procpu +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -183,7 +62,3 @@ References .. _`Lilygo T-Dongle S3 schematic`: https://github.com/Xinyuan-LilyGO/T-Dongle-S3/blob/main/shcematic/T-Dongle-S3.pdf .. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGO/T-Dongle-S3.git -.. _`ESP32-S3 Datasheet`: https://github.com/Xinyuan-LilyGO/T-Dongle-S3/blob/main/doc/esp32-s3_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://github.com/Xinyuan-LilyGO/T-Dongle-S3/blob/main/doc/esp32-s3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ diff --git a/boards/lilygo/ttgo_lora32/doc/index.rst b/boards/lilygo/ttgo_lora32/doc/index.rst index 1b662bb030c32..dd69751f144dd 100644 --- a/boards/lilygo/ttgo_lora32/doc/index.rst +++ b/boards/lilygo/ttgo_lora32/doc/index.rst @@ -18,161 +18,38 @@ Some of the ESP32 I/O pins are accessible on the board's pin headers. Hardware ******** +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your Lilygo TTGO LoRa32, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-PICO-D4 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: ttgo_lora32/esp32/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-PICO-D4 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. code-block:: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_lora32/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``ttgo_lora32`` board target. -Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_lora32/esp32/procpu - :goals: flash - -The default baud rate for the Lilygo TTGO LoRa32 is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_lora32/esp32/procpu +Lilygo TTGO LoRa32 debugging is not supported due to pinout limitations. -Code samples -============ +Sample Applications +******************* The following sample applications will work out of the box with this board: @@ -181,18 +58,15 @@ The following sample applications will work out of the box with this board: * :zephyr:code-sample:`fs` * :zephyr:code-sample:`character-frame-buffer` -Debugging -********* - -Lilygo TTGO LoRa32 debugging is not supported due to pinout limitations. - Related Documents ***************** -- `Lilygo TTGO LoRa32 schematic `_ (PDF) -- `Lilygo TTGO LoRa32 documentation `_ -- `Lilygo github repo `_ -- `ESP32-PICO-D4 Datasheet `_ (PDF) -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ -- `SX127x Datasheet `_ -- `SSD1306 Datasheet `_ (PDF) + +.. target-notes:: + +.. _`Lilygo TTGO LoRa32 schematic`: https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/blob/master/schematic/T3_V1.6.1.pdf +.. _`Lilygo TTGO LoRa32 documentation`: https://www.lilygo.cc/products/lora3 +.. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGo +.. _`ESP32-PICO-D4 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html +.. _`SX127x Datasheet`: https://www.semtech.com/products/wireless-rf/lora-connect/sx1276#documentation +.. _`SSD1306 Datasheet`: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf diff --git a/boards/lilygo/ttgo_t7v1_5/doc/index.rst b/boards/lilygo/ttgo_t7v1_5/doc/index.rst index 57d12645c9aed..958f73d418d4a 100644 --- a/boards/lilygo/ttgo_t7v1_5/doc/index.rst +++ b/boards/lilygo/ttgo_t7v1_5/doc/index.rst @@ -20,155 +20,39 @@ This board is based on the ESP32-WROVER-E module with 4MB of flash (there are models 16MB as well), WiFi and BLE support. It has a Micro-USB port for programming and debugging, integrated battery charging and an on-board antenna. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :app: samples/hello_world - :board: ttgo_t7v1_5/esp32/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: +Debugging +========= - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t7v1_5/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``ttgo_t7v1_5`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t7v1_5/esp32/procpu - :goals: flash - -The default baud rate for the Lilygo TTGO T7 V1.5 is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_t7v1_5 - -Sample applications -=================== +Sample Applications +******************* The following samples will run out of the box on the TTGO T7 V1.5 board. @@ -189,9 +73,11 @@ To build the bluetooth beacon sample: :goals: build -Related Documents -***************** +References +********** + +.. target-notes:: + .. _`Lilygo TTGO T7-V1.5 schematic`: https://github.com/LilyGO/TTGO-T7-Demo/blob/master/t7_v1.5.pdf .. _`Lilygo github repo`: https://github.com/LilyGO/TTGO-T7-Demo/tree/master .. _`Espressif ESP32-WROVER-E datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-wrover-e_esp32-wrover-ie_datasheet_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/lilygo/ttgo_t8c3/doc/index.rst b/boards/lilygo/ttgo_t8c3/doc/index.rst index 33cab6415243e..f7d502b39b03c 100644 --- a/boards/lilygo/ttgo_t8c3/doc/index.rst +++ b/boards/lilygo/ttgo_t8c3/doc/index.rst @@ -22,184 +22,41 @@ has an USB-C port for programming and debugging, integrated battery charging and an on-board antenna. The fitted U.FL external antenna connector can be enabled by moving a 0-ohm resistor. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your Lilygo TTGO T8-C3, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-C3 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: ttgo_t8c3 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-C3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t8c3 - :goals: build - -The usual ``flash`` target will work with the ``ttgo_t8c3`` board target. -Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t8c3 - :goals: flash - -The default baud rate for the Lilygo TTGO T8-C3 is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_t8c3 - -Sample applications -=================== - -The following samples will run out of the box on the TTGO T8-C3 board. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -To build the blinky sample: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/basic/blinky - :board: ttgo_t8c3 - :goals: build +Debugging +========= -To build the bluetooth beacon sample: +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/bluetooth/beacon - :board: ttgo_t8c3 - :goals: build +References +********** +.. target-notes:: -Related Documents -***************** .. _`Lilygo TTGO T8-C3 schematic`: https://github.com/Xinyuan-LilyGO/T8-C3/blob/main/Schematic/T8-C3_V1.1.pdf .. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGo -.. _`Espressif ESP32-C3 datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`Espressif ESP32-C3 technical reference manual`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/lilygo/ttgo_t8s3/doc/index.rst b/boards/lilygo/ttgo_t8s3/doc/index.rst index fb29b2e5f7b60..3cb2384e5cc3f 100644 --- a/boards/lilygo/ttgo_t8s3/doc/index.rst +++ b/boards/lilygo/ttgo_t8s3/doc/index.rst @@ -23,168 +23,45 @@ has an USB-C port for programming and debugging, integrated battery charging and an on-board antenna. The fitted U.FL external antenna connector can be enabled by moving a 0-ohm resistor. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your Lilygo TTGO T8-S3, please make sure that the board is in good -condition with no obvious signs of damage. - System requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: ttgo_t8s3/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. +Debugging +========= -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t8s3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``ttgo_t8s3`` board target -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_t8s3/esp32s3/procpu - :goals: flash - -The default baud rate for the Lilygo TTGO T8-S3 is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_t8s3 - -Code samples -============ +Sample Applications +******************* The following code samples will run out of the box on the TTGO T8-S3 board: * :zephyr:code-sample:`wifi-shell` * :zephyr:code-sample:`fs` - References ********** @@ -192,7 +69,3 @@ References .. _`Lilygo TTGO T8-S3 schematic`: https://github.com/Xinyuan-LilyGO/T8-S3/blob/main/schematic/T8_S3_V1.0.pdf .. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGo -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-mini-1_mini-1u_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ diff --git a/boards/lilygo/ttgo_tbeam/doc/index.rst b/boards/lilygo/ttgo_tbeam/doc/index.rst index fa6082abaa29d..64e44c0250c70 100644 --- a/boards/lilygo/ttgo_tbeam/doc/index.rst +++ b/boards/lilygo/ttgo_tbeam/doc/index.rst @@ -20,161 +20,38 @@ Some of the ESP32 I/O pins are accessible on the board's pin headers. Hardware ******** +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your Lilygo TTGO TBeam, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-PICO-D4 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: ttgo_tbeam/esp32/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-PICO-D4 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. code-block:: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_tbeam/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``ttgo_tbeam`` board target. -Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_tbeam/esp32/procpu - :goals: flash - -The default baud rate for the Lilygo TTGO TBeam is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_tbeam/esp32/procpu +Lilygo TTGO TBeam debugging is not supported due to pinout limitations. -Code samples -============ +Sample Applications +******************* The following sample applications will work out of the box with this board: @@ -185,20 +62,17 @@ The following sample applications will work out of the box with this board: * :zephyr:code-sample:`character-frame-buffer` * :zephyr:code-sample:`blinky` -Debugging -********* - -Lilygo TTGO TBeam debugging is not supported due to pinout limitations. - Related Documents ***************** -- `Lilygo TTGO TBeam schematic `_ (PDF) -- `Lilygo TTGO TBeam documentation `_ -- `Lilygo github repo `_ -- `ESP32-PICO-D4 Datasheet `_ (PDF) -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ -- `SX127x Datasheet `_ -- `SSD1306 Datasheet `_ (PDF) -- `NEO-6M Datasheet `_ (PDF) -- `NEO-N8M Datasheet `_ (PDF) + +.. target-notes:: + +.. _`Lilygo TTGO TBeam schematic`: https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/blob/master/schematic/LilyGo_TBeam_V1.2.pdf +.. _`Lilygo TTGO TBeam documentation`: https://www.lilygo.cc/products/t-beam-v1-1-esp32-lora-module +.. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGo +.. _`ESP32-PICO-D4 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html +.. _`SX127x Datasheet`: https://www.semtech.com/products/wireless-rf/lora-connect/sx1276#documentation +.. _`SSD1306 Datasheet`: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf +.. _`NEO-6M Datasheet`: https://content.u-blox.com/sites/default/files/products/documents/NEO-6_DataSheet_%28GPS.G6-HW-09005%29.pdf +.. _`NEO-N8M Datasheet`: https://content.u-blox.com/sites/default/files/NEO-M8-FW3_DataSheet_UBX-15031086.pdf diff --git a/boards/lilygo/ttgo_toiplus/doc/index.rst b/boards/lilygo/ttgo_toiplus/doc/index.rst index 3ea6b50446fa3..62d560a8f5ac8 100644 --- a/boards/lilygo/ttgo_toiplus/doc/index.rst +++ b/boards/lilygo/ttgo_toiplus/doc/index.rst @@ -14,12 +14,21 @@ It features the following integrated components: - optional 18340 Li-ion battery holder - LED -Functional Description -********************** +Hardware +******** + This board is based on the ESP32-C3 with 4MB of flash, WiFi and BLE support. It has an USB-C port for programming and debugging, integrated battery charging and an Grove connector. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + Connections and IOs =================== @@ -27,149 +36,31 @@ Connections and IOs (Note: the above UART interface also supports connecting through USB.) -Start Application Development -***************************** - -Before powering up your Lilygo TTGO T-OI-PLUS, please make sure that the board is in good -condition with no obvious signs of damage. - System requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-C3 SoC. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -To build the sample application using sysbuild use the command: +Programming and Debugging +************************* -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: ttgo_toiplus - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-C3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml +.. zephyr:board-supported-runners:: -.. note:: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -For more information about the system build please read the :ref:`sysbuild` documentation. +Debugging +========= -Manual build -============ +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_toiplus - :goals: build - -The usual ``flash`` target will work with the ``ttgo_toiplus`` board target. -Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: ttgo_toiplus - :goals: flash - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! ttgo_toiplus - -Sample applications -=================== +Sample Applications +******************* The following samples will run out of the box on the TTGO T-OI-PLUS board. @@ -190,10 +81,10 @@ To build the bluetooth beacon sample: :goals: build -Related Documents -***************** +References +********** + +.. target-notes:: + .. _`Lilygo TTGO T-OI-PLUS schematic`: https://github.com/Xinyuan-LilyGO/LilyGo-T-OI-PLUS/blob/main/schematic/T-OI_PLUS_Schematic.pdf .. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGO -.. _`Espressif ESP32-C3 datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`Espressif ESP32-C3 technical reference manual`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/lilygo/twatch_s3/doc/index.rst b/boards/lilygo/twatch_s3/doc/index.rst index 3dc07e37673ea..215b64add1e7c 100644 --- a/boards/lilygo/twatch_s3/doc/index.rst +++ b/boards/lilygo/twatch_s3/doc/index.rst @@ -3,7 +3,11 @@ Overview ******** -LILYGO T-Watch S3 is an ESP32-S3 based smartwatch with the following features: +LILYGO T-Watch S3 is an ESP32-S3 based smartwatch. + + +Hardware +******** - ESP32-S3-R8 chip @@ -40,149 +44,36 @@ It does not have any GPIO that can easily be connected to something external. There is only 1 physical button which is connected to the PMU and it's used to turn on/off the device. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order to work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Simple boot -=========== - -The board could be loaded using a single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code-block:: cfg +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - CONFIG_BOOTLOADER_MCUBOOT=y +Programming and Debugging +************************* -Sysbuild --------- - -The sysbuild makes it possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild, use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: twatch_s3/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-S3 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-built and re-flashed - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build ------------- - -During the development cycle, it is intended to build & flash as quickly as possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flashed at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: twatch_s3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``twatch_s3`` board target -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: twatch_s3/esp32s3/procpu - :goals: flash - -The default baud rate is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell +.. zephyr:board-supported-runners:: - west espressif monitor +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! twatch_s3/esp32s3/procpu +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -192,7 +83,3 @@ References .. _`Lilygo Twatch S3 schematic`: https://github.com/Xinyuan-LilyGO/TTGO_TWatch_Library/blob/t-watch-s3/schematic/T_WATCH_S3.pdf .. _`Lilygo T-Watch S3 repo`: https://github.com/Xinyuan-LilyGO/TTGO_TWatch_Library/tree/t-watch-s3 .. _`Lilygo T-Watch Deps repo`: https://github.com/Xinyuan-LilyGO/T-Watch-Deps -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ diff --git a/boards/luatos/esp32c3_luatos_core/doc/index.rst b/boards/luatos/esp32c3_luatos_core/doc/index.rst index 02df6687cb3c1..547b67b862bc0 100644 --- a/boards/luatos/esp32c3_luatos_core/doc/index.rst +++ b/boards/luatos/esp32c3_luatos_core/doc/index.rst @@ -1,7 +1,4 @@ -.. _esp32c3_luatos_core: - -ESP32C3_LUATOS_CORE -################### +.. zephyr:board:: esp32c3_luatos_core Overview ******** @@ -11,26 +8,14 @@ based on the open-source RISC-V architecture. It strikes the right balance of po I/O capabilities and security, thus offering the optimal cost-effective solution for connected devices. The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, -but it also facilitates a variety of use-cases based on dual connectivity. [1]_ - -The features include the following: +but it also facilitates a variety of use-cases based on dual connectivity. +See the `ESP32C3 Luatos Core Website`_ for more details. -- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz -- 400 KB of internal RAM -- 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh -- Various peripherals: - - - 12-bit ADC with up to 6 channels - - TWAI compatible with CAN bus 2.0 - - Temperature sensor - - 3x SPI - - 1x I2S - - 1x I2C - - 2x UART - - LED PWM with up to 6 channels +Hardware +******** -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features There are two version hardware of this board. The difference between them is the ch343 chip. @@ -49,216 +34,41 @@ There are two version hardware of this board. The difference between them is the Supported Features ================== -Current Zephyr's ESP32C3_LUATOS_CORE board supports the following features: +.. zephyr:board-supported-hw:: -+------------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+============+============+=====================================+ -| UART | on-chip | serial port | -+------------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+------------+------------+-------------------------------------+ -| PINMUX | on-chip | pinmux | -+------------+------------+-------------------------------------+ -| USB-JTAG | on-chip | hardware interface | -+------------+------------+-------------------------------------+ -| SPI Master | on-chip | spi | -+------------+------------+-------------------------------------+ -| Timers | on-chip | counter | -+------------+------------+-------------------------------------+ -| Watchdog | on-chip | watchdog | -+------------+------------+-------------------------------------+ -| TRNG | on-chip | entropy | -+------------+------------+-------------------------------------+ -| LEDC | on-chip | pwm | -+------------+------------+-------------------------------------+ -| SPI DMA | on-chip | spi | -+------------+------------+-------------------------------------+ -| TWAI | on-chip | can | -+------------+------------+-------------------------------------+ -| USB-CDC | on-chip | serial | -+------------+------------+-------------------------------------+ -| ADC | on-chip | adc | -+------------+------------+-------------------------------------+ -| Wi-Fi | on-chip | | -+------------+------------+-------------------------------------+ -| Bluetooth | on-chip | | -+------------+------------+-------------------------------------+ +Connection and IO +================= .. image:: img/esp32c3_luatos_core_pinfunc.jpg :align: center :alt: esp32c3_luatos_core_pinfunc -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -To build the sample application using sysbuild use the command: +Programming and Debugging +************************* -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32c3_luatos_core - :goals: build - :west-args: --sysbuild - :compact: +.. zephyr:board-supported-runners:: -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_luatos_core - :goals: build - -The usual ``flash`` target will work with the ``esp32c3_luatos_core`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_luatos_core - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32c3_luatos_core +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -As with much custom hardware, the ESP32-C3 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_luatos_core - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_luatos_core - :goals: debug +========= -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. [1] https://www.espressif.com/en/products/socs/esp32-c3 -.. _ESP32C3 Core Website: https://wiki.luatos.com/chips/esp32c3/board.html -.. _ESP32C3 Technical Reference Manual: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _ESP32C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf +.. _`ESP32C3 Luatos Core Website`: https://wiki.luatos.com/chips/esp32c3/board.html diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi index 259b05379f3d7..816168c6011f6 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core-pinctrl.dtsi @@ -23,21 +23,21 @@ spim2_default: spim2_default { group1 { - pinmux = , - , - ; + pinmux = , + , + ; }; group2 { - pinmux = ; + pinmux = ; output-low; }; }; i2c0_default: i2c0_default { group1 { - pinmux = , - ; + pinmux = , + ; bias-pull-up; drive-open-drain; output-high; @@ -46,8 +46,8 @@ twai_default: twai_default { group1 { - pinmux = , - ; + pinmux = , + ; }; }; }; diff --git a/boards/luatos/esp32s3_luatos_core/doc/index.rst b/boards/luatos/esp32s3_luatos_core/doc/index.rst index c8e3f74375f75..88892e3c2a96c 100644 --- a/boards/luatos/esp32s3_luatos_core/doc/index.rst +++ b/boards/luatos/esp32s3_luatos_core/doc/index.rst @@ -1,7 +1,4 @@ -.. _esp32s3_luatos_core: - -ESP32S3-Luatos-Core -################### +.. zephyr:board:: esp32s3_luatos_core Overview ******** @@ -17,66 +14,8 @@ For more information, check `ESP32S3-Luatos-Core`_ (chinese) Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. - -ESP32S3-Luatos-Core includes the following features: - -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 512KB of SRAM -- 384KB of ROM -- 8MB of PSRAM -- 16MB of FLASH -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate - -Digital interfaces: - -- 4x SPI -- 1x LCD interface (8-bit ~16-bit parallel RGB, I8080 and MOTO6800), supporting conversion between RGB565, YUV422, YUV420 and YUV411 -- 1x DVP 8-bit ~16-bit camera interface -- 3x UART -- 2x I2C -- 2x I2S -- 1x RMT (TX/RX) -- 1x pulse counter -- LED PWM controller, up to 8 channels -- 1x USB Port with USB switcher, supporting following modes: - - 1x full-speed USB OTG or 1x USB Serial/JTAG controller - - USB to serial chip CH343 -- 2x MCPWM -- 1x SDIO host controller with 2 slots -- General DMA controller (GDMA), with 5 transmit channels and 5 receive channels -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) -- 2x Blue LED - -Analog interfaces: - -- 2x 12-bit SAR ADCs, up to 20 channels - -Timers: - -- 4x 54-bit general-purpose timers -- 1x 52-bit system timer -- 3x watchdog timers - -Low Power: - -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) - -For more information, check the datasheet at `ESP32-S3 Datasheet`_ or the technical reference -manual at `ESP32-S3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features .. image:: img/esp32s3_luatos_core_pinout.jpg :align: center @@ -85,203 +24,30 @@ manual at `ESP32-S3 Technical Reference Manual`_. Supported Features ================== -Current Zephyr's ESP32S3-Luatos-Core board supports the following features: - -+------------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+============+============+=====================================+ -| UART | on-chip | serial port | -+------------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+------------+------------+-------------------------------------+ -| PINMUX | on-chip | pinmux | -+------------+------------+-------------------------------------+ -| USB-JTAG | on-chip | hardware interface | -+------------+------------+-------------------------------------+ -| SPI Master | on-chip | spi | -+------------+------------+-------------------------------------+ -| TWAI/CAN | on-chip | can | -+------------+------------+-------------------------------------+ -| Timers | on-chip | counter | -+------------+------------+-------------------------------------+ -| Watchdog | on-chip | watchdog | -+------------+------------+-------------------------------------+ -| TRNG | on-chip | entropy | -+------------+------------+-------------------------------------+ -| LEDC | on-chip | pwm | -+------------+------------+-------------------------------------+ -| MCPWM | on-chip | pwm | -+------------+------------+-------------------------------------+ -| PCNT | on-chip | qdec | -+------------+------------+-------------------------------------+ -| GDMA | on-chip | dma | -+------------+------------+-------------------------------------+ -| USB-CDC | on-chip | serial | -+------------+------------+-------------------------------------+ - -Prerequisites -------------- +.. zephyr:board-supported-hw:: -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - CONFIG_BOOTLOADER_MCUBOOT=y +Programming and Debugging +************************* -Sysbuild -======== +.. zephyr:board-supported-runners:: -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core/esp32s3/procpu - :goals: build - -If CH343 chip is disabled, You need use the following command to build: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core/esp32s3/procpu/usb - :goals: build - -The usual ``flash`` target will work with the ``esp32s3_luatos_core`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32s3_luatos_core +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core/esp32s3/procpu - :goals: build flash - -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: esp32s3_luatos_core/esp32s3/procpu - :goals: debug +========= +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -289,7 +55,3 @@ References .. target-notes:: .. _`ESP32S3-Luatos-Core`: https://wiki.luatos.com/chips/esp32s3/board.html -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-mini-1_mini-1u_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/m5stack/m5stack_atom_lite/doc/index.rst b/boards/m5stack/m5stack_atom_lite/doc/index.rst index 9b84f801fd6f7..121fb55bedbac 100644 --- a/boards/m5stack/m5stack_atom_lite/doc/index.rst +++ b/boards/m5stack/m5stack_atom_lite/doc/index.rst @@ -5,6 +5,9 @@ Overview M5Stack ATOM Lite is an ESP32-based development board from M5Stack. +Hardware +******** + It features the following integrated components: - ESP32-PICO-D4 chip (240MHz dual core, Wi-Fi/BLE 5.0) @@ -13,81 +16,41 @@ It features the following integrated components: - Infrared LED - 1x Grove extension port +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your M5Stack ATOM Lite, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements -=================== - -Prerequisites -------------- +System Requirements +******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. code-block:: shell - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -------------------- +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atom_lite/esp32/procpu - :goals: build +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -The usual ``flash`` target will work with the ``m5stack_atom_lite`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atom_lite/esp32/procpu - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_atom_lite +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= M5Stack ATOM Lite debugging is not supported due to pinout limitations. Related Documents ***************** -- `M5Stack ATOM Lite docs `_ -- `M5Stack ATOM Lite schematic `_ -- `ESP32-PICO-D4 Datasheet `_ (PDF) + +.. target-notes:: + +.. _`M5Stack ATOM Lite docs`: https://docs.m5stack.com/en/core/ATOM%20Lite +.. _`M5Stack ATOM Lite schematic`: https://static-cdn.m5stack.com/resource/docs/products/core/atom_lite/atom_lite_map_01.webp +.. _`ESP32-PICO-D4 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf diff --git a/boards/m5stack/m5stack_atoms3/doc/index.rst b/boards/m5stack/m5stack_atoms3/doc/index.rst index 9cedbfb51805a..fcc0b28f987c5 100644 --- a/boards/m5stack/m5stack_atoms3/doc/index.rst +++ b/boards/m5stack/m5stack_atoms3/doc/index.rst @@ -5,91 +5,49 @@ Overview M5Stack AtomS3 is an ESP32-based development board from M5Stack. -It features the following integrated components: +Hardware +******** + +The board peripherals: -- ESP32-S3FN8 chip (240MHz dual core, Wi-Fi/BLE 5.0) -- 512KB of SRAM -- 384KB of ROM - 8MB of Flash - LCD IPS TFT 0.85", 128x128 px screen (ST7789 compatible) - 6-axis IMU MPU6886 - Infrared emitter +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your M5Stack AtomS3, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: shell - - west blobs fetch hal_espressif - -.. note:: +System Requirements +******************* - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Building & Flashing -------------------- +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). +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atoms3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stack_atoms3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atoms3/esp32s3/procpu - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_atoms3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= M5Stack AtomS3 debugging is not supported due to pinout limitations. Related Documents ***************** -- `M5Stack AtomS3 schematic `_ -- `ESP32S3 Datasheet `_ +.. target-notes:: + +.. _`M5Stack AtomS3 schematic`: https://static-cdn.m5stack.com/resource/docs/products/core/AtomS3/img-b85e925c-adff-445d-994c-45987dc97a44.jpg diff --git a/boards/m5stack/m5stack_atoms3_lite/doc/index.rst b/boards/m5stack/m5stack_atoms3_lite/doc/index.rst index 8403358be1e4f..17a5361f79467 100644 --- a/boards/m5stack/m5stack_atoms3_lite/doc/index.rst +++ b/boards/m5stack/m5stack_atoms3_lite/doc/index.rst @@ -5,6 +5,9 @@ Overview M5Stack AtomS3 Lite is an ESP32-based development board from M5Stack. +Hardware +******** + It features the following integrated components: - ESP32-S3FN8 chip (240MHz dual core, Wi-Fi/BLE 5.0) @@ -13,81 +16,39 @@ It features the following integrated components: - 8MB of Flash - RGB Status-LED +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Start Application Development -***************************** - -Before powering up your M5Stack AtomS3 Lite, please make sure that the board is in good -condition with no obvious signs of damage. - System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: shell - - west blobs fetch hal_espressif - -.. note:: +******************* - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Building & Flashing -------------------- +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). +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atoms3_lite/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stack_atoms3_lite`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_atoms3_lite/esp32s3/procpu - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_atoms3_lite +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= M5Stack AtomS3 Lite debugging is not supported due to pinout limitations. -Related Documents -***************** +References +********** + +.. target-notes:: -- `M5Stack AtomS3 Lite schematic `_ -- `ESP32S3 Datasheet `_ +.. _`M5Stack AtomS3 Lite schematic`: https://static-cdn.m5stack.com/resource/docs/products/core/AtomS3%20Lite/img-4061fdd4-6954-4709-a7e7-b0f50e5ba52e.webp diff --git a/boards/m5stack/m5stack_core2/doc/index.rst b/boards/m5stack/m5stack_core2/doc/index.rst index fb21227767c44..e0047a3c6dcd6 100644 --- a/boards/m5stack/m5stack_core2/doc/index.rst +++ b/boards/m5stack/m5stack_core2/doc/index.rst @@ -5,6 +5,9 @@ Overview M5Stack Core2 is an ESP32-based development board from M5Stack. It is the successor for the Core module. +Hardware +******** + M5Stack Core2 features the following integrated components: - ESP32-D0WDQ6-V3 chip (240MHz dual core, 600 DMIPS, 520KB SRAM, Wi-Fi) @@ -23,8 +26,16 @@ M5Stack Core2 features the following integrated components: - MIC SPM1423 - Battery 390mAh 3,7V +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + Functional Description -********************** +====================== The following table below describes the key components, interfaces, and controls of the M5Stack Core2 board. @@ -82,6 +93,7 @@ of the M5Stack Core2 board. Power supply ============ + M5Stack Core2 module is equipped with the feature-rich power management IC (:dtcompatible:`x-powers,axp192-regulator`). Following regulators are utilized on this module: @@ -98,87 +110,34 @@ Following regulators are utilized on this module: BUS_5V supply for Grove port. Note: This fixed regulator supply is disabled by default. - These voltages can be controlled via regulator api. -Supported Features -================== - -.. zephyr:board-supported-hw:: - -Start Application Development -***************************** - -Before powering up your M5Stack Core2, please make sure that the board is in good -condition with no obvious signs of damage. +System Requirements +******************* -System requirements -=================== +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -------------------- +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_core2/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stack_core2`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_core2/esp32/procpu - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_core2 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= M5Stack Core2 debugging is not supported due to pinout limitations. Related Documents ***************** -- `M5Stack-Core2 schematic `_ (PDF) -- `ESP32-PICO-D4 Datasheet `_ (PDF) -- `M5Stack-Core2 docs `_ -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ +.. _`M5Stack-Core2 schematic`: https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/CORE2_V1.0_SCH.pdf +.. _`ESP32-PICO-D4 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf +.. _`M5Stack-Core2 docs`: https://docs.m5stack.com/en/core/core2 +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html diff --git a/boards/m5stack/m5stack_cores3/doc/index.rst b/boards/m5stack/m5stack_cores3/doc/index.rst index 2fdd042c38e67..e6e6da6136a05 100644 --- a/boards/m5stack/m5stack_cores3/doc/index.rst +++ b/boards/m5stack/m5stack_cores3/doc/index.rst @@ -7,6 +7,9 @@ M5Stack CoreS3 is an ESP32-based development board from M5Stack. It is the third M5Stack CoreS3 SE is the compact version of CoreS3. It has the same form factor as the original M5Stack, and some features were reduced from CoreS3. +Hardware +******** + M5Stack CoreS3/CoreS3 SE features consist of: - ESP32-S3 chip (dual-core Xtensa LX7 processor @240MHz, WIFI, OTG and CDC functions) @@ -26,234 +29,36 @@ M5Stack CoreS3/CoreS3 SE features consist of: - Proximity sensor LTR-553ALS-WA (Not available for CoreS3 SE) - 6-Axis IMU BMI270 (Not available for CoreS3 SE) -Start Application Development -***************************** - -Before powering up your M5Stack CoreS3, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features -Building & Flashing -******************* - -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader +Supported Features ================== -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. tabs:: - - .. group-tab:: M5Stack CoreS3 - - .. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - - .. group-tab:: M5Stack CoreS3 SE - - .. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu/se - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: +.. zephyr:board-supported-hw:: - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. tabs:: - - .. group-tab:: M5Stack CoreS3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu - :goals: build - - .. group-tab:: M5Stack CoreS3 SE - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu/se - :goals: build - -The usual ``flash`` target will work with the ``m5stack_cores3/esp32s3/procpu`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. tabs:: - - .. group-tab:: M5Stack CoreS3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu - :goals: flash - - .. group-tab:: M5Stack CoreS3 SE - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu/se - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: +System Requirements +******************* -.. code-block:: shell +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - west espressif monitor +Programming and Debugging +************************* -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - *** Booting Zephyr OS build vx.x.x-xxx-gxxxxxxxxxxxx *** - Hello World! m5stack_cores3/esp32s3/procpu +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. tabs:: - - .. group-tab:: M5Stack CoreS3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu - :goals: debug - - .. group-tab:: M5Stack CoreS3 SE - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu/se - :goals: debug - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. tabs:: - - .. group-tab:: M5Stack CoreS3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu - :goals: debug - - .. group-tab:: M5Stack CoreS3 SE +========= - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_cores3/esp32s3/procpu/se - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -264,5 +69,3 @@ References .. _`M5Stack CoreS3 Schematic`: https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/core/K128%20CoreS3/Sch_M5_CoreS3_v1.0.pdf .. _`M5Stack CoreS3 SE Documentation`: https://docs.m5stack.com/en/core/M5CoreS3%20SE .. _`M5Stack CoreS3 SE Schematic`: https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/core/M5CORES3%20SE/M5_CoreS3SE.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ diff --git a/boards/m5stack/m5stack_fire/doc/index.rst b/boards/m5stack/m5stack_fire/doc/index.rst index 0a5f940cc2fe7..f6c19960b3c85 100644 --- a/boards/m5stack/m5stack_fire/doc/index.rst +++ b/boards/m5stack/m5stack_fire/doc/index.rst @@ -5,6 +5,9 @@ Overview M5Stack Fire is an ESP32-based development board from M5Stack. +Hardware +******** + M5Stack Fire features the following integrated components: - ESP32-D0WDQ6 chip (240MHz dual core, 600 DMIPS, 520KB SRAM, Wi-Fi) @@ -22,8 +25,16 @@ M5Stack Fire features the following integrated components: - Three physical buttons - LED strips +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + Functional Description -********************** +====================== The following table below describes the key components, interfaces, and controls of the M5Stack Core2 board. @@ -69,83 +80,33 @@ of the M5Stack Core2 board. | | possibility to query current battery status. | | +------------------+------------------------------------------------------------------------+-----------+ -Supported Features -================== - -.. zephyr:board-supported-hw:: - -Start Application Development -***************************** - -Before powering up your M5Stack Fire, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements -=================== +System Requirements +******************* -Prerequisites -------------- +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -------------------- +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_fire/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stack_fire`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_fire/esp32/procpu - :goals: flash +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_fire +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= M5Stack Fire debugging is not supported due to pinout limitations. Related Documents ***************** -- `M5Stack-Fire schematic `_ (PDF) -- `M5Stack-Fire docs `_ -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ +.. target-notes:: + +.. _`M5Stack-Fire schematic`: https://m5stack-doc.oss-cn-shenzhen.aliyuncs.com/480/M5-Core-Schematic_20171206.pdf +.. _`M5Stack-Fire docs`: https://docs.m5stack.com/en/core/fire_v2.7 +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html diff --git a/boards/m5stack/m5stack_stamps3/doc/index.rst b/boards/m5stack/m5stack_stamps3/doc/index.rst index 4e006eca8a397..fd35a04ee41df 100644 --- a/boards/m5stack/m5stack_stamps3/doc/index.rst +++ b/boards/m5stack/m5stack_stamps3/doc/index.rst @@ -4,6 +4,10 @@ Overview ******** M5Stack StampS3 is an ESP32-based development board from M5Stack. + +Hardware +******** + It features the following integrated components: - ESP32-S3FN8 chip (240MHz dual core) @@ -14,8 +18,16 @@ It features the following integrated components: - Bluetooth - User-Button +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + Functional Description -********************** +====================== The following table below describes the key components, interfaces, and controls of the M5Stack StampS3 module. @@ -108,71 +120,28 @@ supply. If this pin is pulled low this main 3.3V power supply for the MCU will b deactivated. It is internally equipped with a pull-up and can hence be left open if unused. -Start Application Development -***************************** - -Before powering up your M5Stack StampS3, please make sure that the board is in good -condition with no obvious signs of damage. +System Requirements +******************* -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - It is recommended running the command above after :file:`west update`. - -Building & Flashing -------------------- +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_stamps3/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stack_stamps3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stack_stamps3/esp32s3/procpu - :goals: flash - -The baud rate of 921600bps is set by default. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stack_stamps3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging ---------- +========= + +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging M5Stack StampS3 exports a JTAG-interface via Pins 19 (MTCK), 21 (MTDO), 23 (MTDI), 25 (MTMS). @@ -185,7 +154,8 @@ M5Stack StampS3 exports a JTAG-interface via Pins 19 (MTCK), 21 (MTDO), 23 Related Documents ***************** -- `M5Stack StampS3 schematic `_ -- `M5Stack StampS3 `_ -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ +.. target-notes:: + +.. _`M5Stack StampS3 schematic`: https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/Stamp/S007%20StampS3/Sch_M5StampS3_v0.2.pdf +.. _`M5Stack StampS3`: https://docs.m5stack.com/en/core/StampS3 +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html diff --git a/boards/m5stack/m5stickc_plus/doc/index.rst b/boards/m5stack/m5stickc_plus/doc/index.rst index e6e65a3e1d8f1..56eabee9e9452 100644 --- a/boards/m5stack/m5stickc_plus/doc/index.rst +++ b/boards/m5stack/m5stickc_plus/doc/index.rst @@ -5,6 +5,9 @@ Overview M5StickC PLUS, one of the core devices in M5Stacks product series, is an ESP32-based development board. +Hardware +******** + M5StickC PLUS features the following integrated components: - ESP32-PICO-D4 chip (240MHz dual core, 600 DMIPS, 520KB SRAM, Wi-Fi) @@ -17,8 +20,16 @@ M5StickC PLUS features the following integrated components: Some of the ESP32 I/O pins are broken out to the board's pin headers for easy access. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + Functional Description -********************** +====================== The following table below describes the key components, interfaces, and controls of the M5StickC PLUS board. @@ -57,165 +68,34 @@ of the M5StickC PLUS board. | microphone | | +------------------+-------------------------------------------------------------------------+ - -Start Application Development -***************************** - -Before powering up your M5StickC PLUS, please make sure that the board is in good -condition with no obvious signs of damage. - -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - .. code:: cfg +Programming and Debugging +************************* - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: m5stickc_plus - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stickc_plus/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``m5stickc_plus`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: m5stickc_plus/esp32/procpu - :goals: flash - -The default baud rate for the M5StickC PLUS is set to 1500000bps. If experiencing issues when flashing, -try using different values by using ``--esp-baud-rate `` option during -``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). - -You can also open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! m5stickc_plus +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* +========= M5StickC PLUS debugging is not supported due to pinout limitations. -Related Documents -***************** +References +********** + +.. target-notes:: -- `M5StickC PLUS schematic `_ (WEBP) -- `ESP32-PICO-D4 Datasheet `_ (PDF) -- `M5StickC PLUS docs `_ -- `ESP32 Datasheet `_ (PDF) -- `ESP32 Hardware Reference `_ +.. _`M5StickC PLUS schematic`: https://static-cdn.m5stack.com/resource/docs/products/core/m5stickc_plus/m5stickc_plus_sch_03.webp +.. _`ESP32-PICO-D4 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf +.. _`M5StickC PLUS docs`: https://docs.m5stack.com/en/core/m5stickc_plus +.. _`ESP32 Hardware Reference`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/index.html diff --git a/boards/m5stack/stamp_c3/doc/index.rst b/boards/m5stack/stamp_c3/doc/index.rst index 704bacc6cad90..9b2d729132513 100644 --- a/boards/m5stack/stamp_c3/doc/index.rst +++ b/boards/m5stack/stamp_c3/doc/index.rst @@ -8,171 +8,39 @@ for IoT edge devices such as home appliances and Industrial Automation. For more details see the `M5Stack STAMP-C3`_ page. +Hardware +******** + +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + Supported Features ================== .. zephyr:board-supported-hw:: -Prerequisites -************* - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: stamp_c3 - :goals: build - :west-args: --sysbuild - :compact: +Programming and Debugging +************************* -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: stamp_c3 - :goals: build - -The usual ``flash`` target will work with the ``stamp_c3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: stamp_c3 - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! stamp_c3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants 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 ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: stamp_c3 - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: stamp_c3 - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -180,6 +48,3 @@ References .. target-notes:: .. _`M5Stack STAMP-C3`: https://docs.m5stack.com/en/core/stamp_c3 -.. _`ESP32C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`ESP32C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/Kconfig.pic32cz_ca80_cult b/boards/microchip/pic32c/pic32cz_ca80_cult/Kconfig.pic32cz_ca80_cult new file mode 100644 index 0000000000000..a8df482431f52 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/Kconfig.pic32cz_ca80_cult @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PIC32CZ_CA80_CULT + select SOC_PIC32CZ8110CA80208 diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/board.cmake b/boards/microchip/pic32c/pic32cz_ca80_cult/board.cmake new file mode 100644 index 0000000000000..d76c72d4806b5 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=PIC32CZ8110CA80" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/board.yml b/boards/microchip/pic32c/pic32cz_ca80_cult/board.yml new file mode 100644 index 0000000000000..d26381cc32115 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: pic32cz_ca80_cult + full_name: PIC32CZ CA80 Curiosity Ultra + vendor: microchip + socs: + - name: pic32cz8110ca80208 diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/doc/img/pic32cz_ca80_cult.webp b/boards/microchip/pic32c/pic32cz_ca80_cult/doc/img/pic32cz_ca80_cult.webp new file mode 100644 index 0000000000000..a090e451328b1 Binary files /dev/null and b/boards/microchip/pic32c/pic32cz_ca80_cult/doc/img/pic32cz_ca80_cult.webp differ diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/doc/index.rst b/boards/microchip/pic32c/pic32cz_ca80_cult/doc/index.rst new file mode 100644 index 0000000000000..171bbe01ae347 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/doc/index.rst @@ -0,0 +1,97 @@ +.. zephyr:board:: pic32cz_ca80_cult + +Overview +******** + +The PIC32CZ CA80 Curiosity Ultra development board is a hardware platform +to evaluate the Microchip PIC32CZ CA80 microcontroller, and the +development board part number is EV51S73A. The development board offers a +set of features that enables the PIC32CZ CA80 users to get started with +the PIC32CZ CA80 peripherals, and to obtain an understanding of how to +integrate the device in their own design. + +Hardware +******** + +- 208-Pin TFBGA PIC32CZ8110 CA80 microcontroller +- 32.768 kHz crystal oscillator +- 8M flash memory and 1M of RAM +- Xplained pro extension compatible interface +- Two yellow user LEDs +- Two mechanical user push button +- One reset button +- Virtual COM port (VCOM) +- Programming and debugging of on-board PIC32CZ CA80 through Serial Wire Debug (SWD) +- Arduino uno R3 compatible interface +- MikroBus Socket +- On-board temperature sensor +- Graphics interface +- G-bit Ethernet +- 2 high-speed USB (Type-C and Micro A/B) + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The `PIC32CZ CA80 Curiosity Ultra User Guide`_ has detailed information about board connections. + +Programming & Debugging +*********************** + +.. zephyr:board-supported-runners:: + +Flash Using J-Link +================== + +To flash the board using the J-Link debugger, follow the steps below: + +1. Install J-Link Software + + - Download and install the `J-Link software `_ tools from Segger. + - Make sure the installed J-Link executables (e.g., ``JLink``, ``JLinkGDBServer``) are available in your system's PATH. + +2. Connect the Board + + - Connect the `J32 Debug Probe `_ to the board's **CORTEX DEBUG** header. + - Connect the other end of the J32 Debug Probe to your **host machine (PC)** via USB. + - Connect the DEBUG USB port on the board to your host machine to **power up the board**. + +3. Build the Application + + You can build a sample Zephyr application, such as **Blinky**, using the ``west`` tool. Run the following commands from your Zephyr workspace: + + .. code-block:: console + + west build -b pic32cz_ca80_cult -p -s samples/basic/blinky + + This will build the Blinky application for the ``pic32cz_ca80_cult`` board. + +4. Flash the Device + + Once the build completes, flash the firmware using: + + .. code-block:: console + + west flash + + This uses the default ``jlink`` runner to flash the application to the board. + +5. Observe the Result + + After flashing, **LED0** on the board should start **blinking**, indicating that the application is running successfully. + +References +********** + +PIC32CZ CA80 Product Page: + https://www.microchip.com/en-us/product/PIC32CZ8110CA80208 + +PIC32CZ CA80 Curiosity Ultra Development Board Page: + https://www.microchip.com/en-us/development-tool/ev51s73a + +.. _PIC32CZ CA80 Curiosity Ultra User Guide: + https://ww1.microchip.com/downloads/aemDocuments/documents/MCU32/ProductDocuments/UserGuides/PIC32CZ-CA80-CA90-Curiosity-Ultra-User-Guide-DS70005522.pdf diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.dts b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.dts new file mode 100644 index 0000000000000..e9c286460625d --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.dts @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "PIC32CZ CA80 Curiosity Ultra"; + compatible = "pic32cz_ca80,cult", "microchip,pic32cz8110ca80208", "microchip,pic32cz"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&portb 21 GPIO_ACTIVE_LOW>; + label = "User LED 0"; + }; + + led1: led_1 { + gpios = <&portb 22 GPIO_ACTIVE_LOW>; + label = "User LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&portb 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW0"; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&portc 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1"; + zephyr,code = ; + }; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@7fc000 { + label = "storage"; + reg = <0x0007fc000 0x4000>; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&portb { + status = "okay"; +}; + +&portc { + status = "okay"; +}; diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.yaml b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.yaml new file mode 100644 index 0000000000000..e1e62f62ee721 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +identifier: pic32cz_ca80_cult +name: PIC32CZ CA80 Curiosity Ultra +type: mcu +arch: arm +toolchain: + - zephyr +flash: 8192 +ram: 1024 +supported: + - gpio +vendor: microchip diff --git a/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult_defconfig b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult_defconfig new file mode 100644 index 0000000000000..912a8e1042370 --- /dev/null +++ b/boards/microchip/pic32c/pic32cz_ca80_cult/pic32cz_ca80_cult_defconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_ARM_MPU=y 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 05798b46d3ecd..dcd24d59b034d 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 @@ -13,4 +13,10 @@ ; }; }; + + tcc0_pwm_default: tcc0_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 025d49b64e98a..5f8ac877f8e8d 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -19,6 +19,19 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; }; + + aliases { + pwm-led0 = &pwm_led0; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + status = "okay"; + pwms = <&tcc0 2 PWM_MSEC(20) 0>; + }; + }; }; &flash0 { @@ -60,3 +73,14 @@ pinctrl-0 = <&sercom2_uart_default>; pinctrl-names = "default"; }; + +&tcc0 { + compatible = "microchip,tcc-g1-pwm"; + status = "okay"; + #pwm-cells = <3>; + pinctrl-0 = <&tcc0_pwm_default>; + pinctrl-names = "default"; + max-bit-width = <24>; + prescaler = <8>; + channels = <6>; +}; 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 d349dbd338489..06b83ffc0fc55 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml @@ -11,6 +11,8 @@ flash: 1024 ram: 256 supported: - pinctrl + - pwm + - reset - shell - uart vendor: microchip diff --git a/boards/microchip/sam/sama7d65_curiosity/Kconfig.sama7d65_curiosity b/boards/microchip/sam/sama7d65_curiosity/Kconfig.sama7d65_curiosity new file mode 100644 index 0000000000000..5556c4d81b09f --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/Kconfig.sama7d65_curiosity @@ -0,0 +1,7 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +config BOARD_SAMA7D65_CURIOSITY + select SOC_SAMA7D65 diff --git a/boards/microchip/sam/sama7d65_curiosity/board.yml b/boards/microchip/sam/sama7d65_curiosity/board.yml new file mode 100644 index 0000000000000..324e86c23c1c3 --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/board.yml @@ -0,0 +1,6 @@ +board: + name: sama7d65_curiosity + full_name: SAMA7D65 Curiosity Kit + vendor: microchip + socs: + - name: sama7d65 diff --git a/boards/microchip/sam/sama7d65_curiosity/doc/img/sama7d65_curiosity.webp b/boards/microchip/sam/sama7d65_curiosity/doc/img/sama7d65_curiosity.webp new file mode 100644 index 0000000000000..a0d44e8e3a850 Binary files /dev/null and b/boards/microchip/sam/sama7d65_curiosity/doc/img/sama7d65_curiosity.webp differ diff --git a/boards/microchip/sam/sama7d65_curiosity/doc/index.rst b/boards/microchip/sam/sama7d65_curiosity/doc/index.rst new file mode 100644 index 0000000000000..f374b1f2fdd99 --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/doc/index.rst @@ -0,0 +1,109 @@ +.. zephyr:board:: sama7d65_curiosity + +Overview +******** + +The EV63J76A (SAMA7D65 Curiosity Kit) is a development kit for evaluating and +prototyping with Microchip SAMA7D65 microprocessor (MPU). The SAMA7D65 MPU is a +high-performance ARM Cortex-A7 CPU-based embedded MPU running up to 1GHz. + +The board allows evaluation of powerful peripherals for connectivity, audio and +user interface applications, including MIPI-DSI and LVDS w/ 2D graphics, dual +Gigabit Ethernet w/ TSN and CAN-FD. The MPUs offer advanced security functions, +like tamper detection, secure boot, secure key stoarge, TRNG, PUF as well as +higher-performance crypto accelerators for AES and SHA. + +The SAMA7D65 series is supported by Microchip MPLAB-X development tools, Harmony +V3, Linux distributions and Microchip Graphic Suite (MGS) for Linux. The +SAMA7D65 is well-suited for industrial and automotive applications with +graphical displays support up to WXGA/720p. + +Hardware +******** +EV63J76A provides the following hardware components: + +- Processor + + - Microchip SAMA7D65-V/4HB (SoC 343-ball TFBGA, 14x14 mm, 0.65 mm pitch) + +- Memory + + - 8 Gb DDR3L (AS4C512M16D3LA-10BIN) + - 64 Mb QSPI NOR Flash with EUI-48 (Microchip SST26VF064BEUI-104I/MF) + - 4Gbit SLC NAND Flash (MX30LF4G28AD-XKI) + - 2Kb EEPROM with EUI-48 (Microchip 24AA025E48) + +- SD/MMC + + - One SD card socket, 4 bit + - One M.2 Radio Module interface, SDIO I/F + +- USB + + - One device USB Type-C connector + - Two host USB Type-A connectors (Microchip MIC2026-1YM) + +- Ethernet + + - One 10/100/1000 RGMII on board + - One 10/100/1000 RGMII SODIMM add-on slot (Microchip LAN8840-V/PSA) + +- Display + + - One MIPI-DSI 34-pin FPC connector + - One LVDS 30-pin FPC connector + +- Debug port + + - One UART Debug connector + - One JTAG interface + +- User interaction + + - One RGB (Red, Green, Blue) LED + - Four push button switches + +- CAN-FD + + - Three onboard CAN-FD transceivers + - Two interfaces available on mikroBUS slots + +- Expansion + + - Raspberry Pi 40-pin GPIO connector + - Two mikroBUS™ connectors + - Two PIOBU/System headers + +- Power management + + - Power Supply Unit (Microchip MCP16502TAB-E/S8B) + - Power Monitoring (Microchip PAC1934) + - Daughter cards power supply (Microchip MIC23450-AAAYML-TR) + - Backup power supply (CR1220 battery holder) + +- Board supply + + - System 5 VDC from USB Type-C + - System 5 VDC from DC Jack + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The `SAMA7D65-Curiosity Kit User Guide`_ has detailed information about board connections. + +References +********** + +SAMA7D65 Product Page: + https://www.microchip.com/en-us/product/sama7d65 + +SAMA7D65 Curiosity Kit Page: + https://www.microchip.com/en-us/development-tool/EV63J76A + +.. _SAMA7D65-Curiosity Kit User Guide: + https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/UserGuides/SAMA7D65-Curiosity-Kit-User-Guide-DS50003806.pdf diff --git a/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts new file mode 100644 index 0000000000000..8761d5037ddf1 --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/dts-v1/; +#include +#include +#include +#include + +/ { + model = "SAMA7D65-Curiosity board"; + compatible = "microchip,sama7d65curiosity", "microchip,sama7d6", "microchip,sama7"; + + chosen { + zephyr,sram = &ddram; + zephyr,console = &uart6; + zephyr,shell-uart = &uart6; + }; + + clocks { + main_xtal { + clock-frequency = ; + }; + + slow_xtal { + clock-frequency = <32768>; + }; + }; + + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(1024)>; + }; +}; + +&flx6 { + mchp,flexcom-mode = ; + status = "okay"; + + uart6: serial@200 { + current-speed = <115200>; + pinctrl-0 = <&pinctrl_uart6_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&pinctrl { + pinctrl_uart6_default: uart6-default { + group1 { + pinmux = , + ; + bias-disable; + }; + }; +}; + +&pit64b0 { + clock-frequency = ; +}; diff --git a/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.yaml b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.yaml new file mode 100644 index 0000000000000..312766bb65dd1 --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.yaml @@ -0,0 +1,16 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# SPDX-License-Identifier: Apache-2.0 + +identifier: sama7d65_curiosity +name: SAMA7D65 Curiosity Kit +type: mcu +arch: arm +toolchain: + - zephyr +ram: 128 +supported: + - i2c + - pinctrl + - shell + - uart +vendor: microchip diff --git a/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity_defconfig b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity_defconfig new file mode 100644 index 0000000000000..10b06d0f7f423 --- /dev/null +++ b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity_defconfig @@ -0,0 +1,9 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CLOCK_CONTROL_FIXED_RATE_CLOCK=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y diff --git a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts index e6a3879bf2112..c918f4c03a193 100644 --- a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts +++ b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts @@ -94,6 +94,18 @@ }; }; +&dma0 { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&dma2 { + status = "okay"; +}; + &flx3 { mchp,flexcom-mode = ; status = "okay"; diff --git a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml index 4174a0606b3ba..7b463c5a7fe10 100644 --- a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml +++ b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml @@ -9,6 +9,7 @@ toolchain: - zephyr ram: 128 supported: + - dma - entropy - pwm - sdhc diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr_0_9_0.yaml index 60f22350504dc..87fe8c68ba91b 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr_0_9_0.yaml @@ -11,6 +11,7 @@ sysbuild: true ram: 62 flash: 62 supported: + - adc - counter - gpio - i2c diff --git a/boards/nordic/nrf54lm20dk/Kconfig b/boards/nordic/nrf54lm20dk/Kconfig new file mode 100644 index 0000000000000..0b1905a0d8ef1 --- /dev/null +++ b/boards/nordic/nrf54lm20dk/Kconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +DT_NRF_MPC := $(dt_nodelabel_path,nrf_mpc) + +if BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS + +config NRF_TRUSTZONE_FLASH_REGION_SIZE + hex + default $(dt_node_int_prop_hex,$(DT_NRF_MPC),override-granularity) + help + This defines the flash region size from the TrustZone perspective. + It is used when configuring the TrustZone and when setting alignments + requirements for the partitions. + This abstraction allows us to configure TrustZone without depending + on peripheral-specific symbols. + +config NRF_TRUSTZONE_RAM_REGION_SIZE + hex + default $(dt_node_int_prop_hex,$(DT_NRF_MPC),override-granularity) + help + This defines the RAM region size from the TrustZone perspective. + It is used when configuring the TrustZone and when setting alignments + requirements for the partitions. + This abstraction allows us to configure TrustZone without depending + on peripheral specific symbols. + +endif # BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS diff --git a/boards/nordic/nrf54lm20dk/Kconfig.defconfig b/boards/nordic/nrf54lm20dk/Kconfig.defconfig index 67410cd4d653f..c77e844b822cf 100644 --- a/boards/nordic/nrf54lm20dk/Kconfig.defconfig +++ b/boards/nordic/nrf54lm20dk/Kconfig.defconfig @@ -7,3 +7,12 @@ config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION endif # BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP + +if BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS + +# 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 + +endif # BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS diff --git a/boards/nordic/nrf54lm20dk/Kconfig.nrf54lm20dk b/boards/nordic/nrf54lm20dk/Kconfig.nrf54lm20dk index 83b3842211f31..b311fd9ae87e1 100644 --- a/boards/nordic/nrf54lm20dk/Kconfig.nrf54lm20dk +++ b/boards/nordic/nrf54lm20dk/Kconfig.nrf54lm20dk @@ -2,5 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_NRF54LM20DK - select SOC_NRF54LM20A_ENGA_CPUAPP if BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP + select SOC_NRF54LM20A_ENGA_CPUAPP if BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP || BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS select SOC_NRF54LM20A_ENGA_CPUFLPR if BOARD_NRF54LM20DK_NRF54LM20A_CPUFLPR diff --git a/boards/nordic/nrf54lm20dk/board.cmake b/boards/nordic/nrf54lm20dk/board.cmake index e487ecfb476fe..6aaf6196d5729 100644 --- a/boards/nordic/nrf54lm20dk/board.cmake +++ b/boards/nordic/nrf54lm20dk/board.cmake @@ -7,5 +7,13 @@ elseif(CONFIG_SOC_NRF54LM20A_ENGA_CPUFLPR) board_runner_args(jlink "--speed=4000") endif() +if(CONFIG_BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP_NS) + set(TFM_PUBLIC_KEY_FORMAT "full") +endif() + +if(CONFIG_TFM_FLASH_MERGED_BINARY) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) +endif() + include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf54lm20dk/board.yml b/boards/nordic/nrf54lm20dk/board.yml index 2930f9d3dfbdc..86decbf7c7cd0 100644 --- a/boards/nordic/nrf54lm20dk/board.yml +++ b/boards/nordic/nrf54lm20dk/board.yml @@ -5,6 +5,8 @@ board: socs: - name: nrf54lm20a variants: + - name: ns + cpucluster: cpuapp - name: xip cpucluster: cpuflpr runners: @@ -17,6 +19,7 @@ runners: groups: - boards: - nrf54lm20dk/nrf54lm20a/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuflpr - nrf54lm20dk/nrf54lm20a/cpuflpr/xip '--erase': @@ -28,6 +31,7 @@ runners: groups: - boards: - nrf54lm20dk/nrf54lm20a/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuflpr - nrf54lm20dk/nrf54lm20a/cpuflpr/xip '--reset': @@ -39,5 +43,6 @@ runners: groups: - boards: - nrf54lm20dk/nrf54lm20a/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuflpr - nrf54lm20dk/nrf54lm20a/cpuflpr/xip diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20a_cpuapp_common.dtsi b/boards/nordic/nrf54lm20dk/nrf54lm20a_cpuapp_common.dtsi index b096e0e9ebcfd..f0946efb543f2 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20a_cpuapp_common.dtsi +++ b/boards/nordic/nrf54lm20dk/nrf54lm20a_cpuapp_common.dtsi @@ -58,44 +58,6 @@ status = "okay"; }; -&cpuapp_rram { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; - }; - - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x10000 DT_SIZE_K(449)>; - }; - - slot0_ns_partition: partition@80400 { - label = "image-0-nonsecure"; - reg = <0x80400 DT_SIZE_K(449)>; - }; - - slot1_partition: partition@f0800 { - label = "image-1"; - reg = <0xf0800 DT_SIZE_K(449)>; - }; - - slot1_ns_partition: partition@160c00 { - label = "image-1-nonsecure"; - reg = <0x160c00 DT_SIZE_K(449)>; - }; - - storage_partition: partition@1d1000 { - label = "storage"; - reg = <0x1d1000 DT_SIZE_K(36)>; - }; - }; -}; - &uart20 { status = "okay"; }; diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts index 6dd2c5b2e850a..2e79bbb98215c 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts @@ -7,6 +7,7 @@ /dts-v1/; #include "nrf54lm20a_cpuapp_common.dtsi" +#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 new file mode 100644 index 0000000000000..04cb9d04a60ca --- /dev/null +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#define USE_NON_SECURE_ADDRESS_MAP 1 + +#include "nrf54lm20a_cpuapp_common.dtsi" + +/ { + compatible = "nordic,nrf54lm20dk_nrf54lm20a-cpuapp-ns"; + model = "Nordic nRF54LM20 DK nRF54LM20A Application MCU Non-Secure"; + + chosen { + zephyr,code-partition = &slot0_ns_partition; + zephyr,sram = &sram0_ns; + zephyr,entropy = &psa_rng; + }; + + /delete-node/ rng; + + psa_rng: psa-rng { + status = "okay"; + }; +}; + +/ { + /* + * 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"; +}; + +&uart30 { + /* Disable so that TF-M can use this UART */ + status = "disabled"; +}; + +/* Include default memory partition configuration file */ +#include diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.yaml b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.yaml new file mode 100644 index 0000000000000..3f10201892fb5 --- /dev/null +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.yaml @@ -0,0 +1,22 @@ +identifier: nrf54lm20dk/nrf54lm20a/cpuapp/ns +name: nRF54lm20-DK-nRF54lm20a-Application-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - zephyr +ram: 208 +flash: 1356 +supported: + - adc + - counter + - dmic + - gpio + - i2c + - i2s + - pwm + - spi + - usbd + - watchdog +vendor: nordic +sysbuild: true diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns_defconfig b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns_defconfig new file mode 100644 index 0000000000000..d360ef89bac48 --- /dev/null +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns_defconfig @@ -0,0 +1,45 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=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 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Don't enable the cache in the non-secure image as it is a +# secure-only peripheral on 54l +CONFIG_CACHE_MANAGEMENT=n +CONFIG_EXTERNAL_CACHE=n + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y + +# Disable TFM BL2 since it is not supported +CONFIG_TFM_BL2=n +# Support for silence logging is not supported at the moment +# Tracked by: NCSDK-31930 +CONFIG_TFM_LOG_LEVEL_SILENCE=n + +# The oscillators are configured as secure and cannot be configured +# from the non secure application directly. This needs to be set +# otherwise nrfx will try to configure them, resulting in a bus +# fault. +CONFIG_NRF_SKIP_CLOCK_CONFIG=y diff --git a/boards/nxp/frdm_imx91/Kconfig.defconfig b/boards/nxp/frdm_imx91/Kconfig.defconfig new file mode 100644 index 0000000000000..bc9db5069fcd4 --- /dev/null +++ b/boards/nxp/frdm_imx91/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FRDM_IMX91 + +config GPIO + default y if IMX_USDHC + +endif # BOARD_FRDM_IMX93 diff --git a/boards/nxp/frdm_imx91/doc/index.rst b/boards/nxp/frdm_imx91/doc/index.rst index 9c2a956951ec8..a4c628cd81ce5 100644 --- a/boards/nxp/frdm_imx91/doc/index.rst +++ b/boards/nxp/frdm_imx91/doc/index.rst @@ -70,6 +70,37 @@ Serial Port This board configuration uses a single serial communication channel with the CPU's UART1 for A55 core. +uSDHC (SD or eMMC Interface on A55) +----------------------------------- + +i.MX 91 processor has three ultra secured digital host controller (uSDHC) modules +for SD/eMMC interface support. On the FRDM-IMX91 board, the uSDHC2 interface of +the processor connects to the MicroSD card slot (P13), and uSDHC1 interface connects +to the eMMC memory (located at the SOM board). DTS overlay file "usdhc1.overlay" and +"usdhc2.overlay" are provided to enable specified the uSDHC controller. + +Currently it rely on U-boot or Linux to boot Zephyr, so Zephyr need to use different +uSDHC controller from U-boot or Linux to avoid resource conflict. For example, if +FRDM-IMX91 board boots from SD Card which uses uSDHC2, Zephyr can use MMC +which uses uSDHC1 for testing: + +.. zephyr-app-commands:: + :zephyr-app: tests/subsys/sd/mmc + :host-os: unix + :board: frdm_imx91/mimx9131 + :goals: build + :gen-args: -DEXTRA_DTC_OVERLAY_FILE=usdhc1.overlay + +And if FRDM-IMX91 board boots from MMC which uses uSDHC1, Zephyr can use SD Card which uses +uSDHC2 for testing: + +.. zephyr-app-commands:: + :zephyr-app: tests/subsys/sd/sdmmc + :host-os: unix + :board: frdm_imx91/mimx9131 + :goals: build + :gen-args: -DEXTRA_DTC_OVERLAY_FILE=usdhc2.overlay + Programming and Debugging ************************* diff --git a/boards/nxp/frdm_imx91/dts/usdhc1.overlay b/boards/nxp/frdm_imx91/dts/usdhc1.overlay new file mode 100644 index 0000000000000..d020f5e31e5f4 --- /dev/null +++ b/boards/nxp/frdm_imx91/dts/usdhc1.overlay @@ -0,0 +1,18 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &usdhc1; + }; +}; + +&usdhc1 { + status = "okay"; + sdmmc { + status = "okay"; + }; +}; diff --git a/boards/nxp/frdm_imx91/dts/usdhc2.overlay b/boards/nxp/frdm_imx91/dts/usdhc2.overlay new file mode 100644 index 0000000000000..8e32620412de5 --- /dev/null +++ b/boards/nxp/frdm_imx91/dts/usdhc2.overlay @@ -0,0 +1,18 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &usdhc2; + }; +}; + +&usdhc2 { + status = "okay"; + sdmmc { + status = "okay"; + }; +}; diff --git a/boards/nxp/frdm_imx91/frdm_imx91-pinctrl.dtsi b/boards/nxp/frdm_imx91/frdm_imx91-pinctrl.dtsi index c5b02e6771a0e..b17f345ad53d5 100644 --- a/boards/nxp/frdm_imx91/frdm_imx91-pinctrl.dtsi +++ b/boards/nxp/frdm_imx91/frdm_imx91-pinctrl.dtsi @@ -26,4 +26,199 @@ drive-strength = "x5"; }; }; + + pinmux_usdhc1: pinmux_usdhc1 { + group0 { + pinmux = <&iomuxc1_sd1_clk_usdhc_clk_usdhc1_clk>, + <&iomuxc1_sd1_strobe_usdhc_strobe_usdhc1_strobe>; + drive-strength = "x1"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd1_cmd_usdhc_cmd_usdhc1_cmd>, + <&iomuxc1_sd1_data0_usdhc_data_usdhc1_data0>, + <&iomuxc1_sd1_data1_usdhc_data_usdhc1_data1>, + <&iomuxc1_sd1_data2_usdhc_data_usdhc1_data2>, + <&iomuxc1_sd1_data3_usdhc_data_usdhc1_data3>, + <&iomuxc1_sd1_data4_usdhc_data_usdhc1_data4>, + <&iomuxc1_sd1_data5_usdhc_data_usdhc1_data5>, + <&iomuxc1_sd1_data6_usdhc_data_usdhc1_data6>, + <&iomuxc1_sd1_data7_usdhc_data_usdhc1_data7>; + drive-strength = "x1"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + }; + + pinmux_usdhc1_100mhz: pinmux_usdhc1_100mhz { + group0 { + pinmux = <&iomuxc1_sd1_clk_usdhc_clk_usdhc1_clk>, + <&iomuxc1_sd1_strobe_usdhc_strobe_usdhc1_strobe>; + drive-strength = "x3"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd1_cmd_usdhc_cmd_usdhc1_cmd>, + <&iomuxc1_sd1_data0_usdhc_data_usdhc1_data0>, + <&iomuxc1_sd1_data1_usdhc_data_usdhc1_data1>, + <&iomuxc1_sd1_data2_usdhc_data_usdhc1_data2>, + <&iomuxc1_sd1_data3_usdhc_data_usdhc1_data3>, + <&iomuxc1_sd1_data4_usdhc_data_usdhc1_data4>, + <&iomuxc1_sd1_data5_usdhc_data_usdhc1_data5>, + <&iomuxc1_sd1_data6_usdhc_data_usdhc1_data6>, + <&iomuxc1_sd1_data7_usdhc_data_usdhc1_data7>; + drive-strength = "x3"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + }; + + pinmux_usdhc1_200mhz: pinmux_usdhc1_200mhz { + group0 { + pinmux = <&iomuxc1_sd1_clk_usdhc_clk_usdhc1_clk>, + <&iomuxc1_sd1_strobe_usdhc_strobe_usdhc1_strobe>; + drive-strength = "x6"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd1_cmd_usdhc_cmd_usdhc1_cmd>, + <&iomuxc1_sd1_data0_usdhc_data_usdhc1_data0>, + <&iomuxc1_sd1_data1_usdhc_data_usdhc1_data1>, + <&iomuxc1_sd1_data2_usdhc_data_usdhc1_data2>, + <&iomuxc1_sd1_data3_usdhc_data_usdhc1_data3>, + <&iomuxc1_sd1_data4_usdhc_data_usdhc1_data4>, + <&iomuxc1_sd1_data5_usdhc_data_usdhc1_data5>, + <&iomuxc1_sd1_data6_usdhc_data_usdhc1_data6>, + <&iomuxc1_sd1_data7_usdhc_data_usdhc1_data7>; + drive-strength = "x6"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + }; + + pinmux_usdhc2: pinmux_usdhc2 { + group0 { + pinmux = <&iomuxc1_sd2_clk_usdhc_clk_usdhc2_clk>; + drive-strength = "x1"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd2_cmd_usdhc_cmd_usdhc2_cmd>, + <&iomuxc1_sd2_data0_usdhc_data_usdhc2_data0>, + <&iomuxc1_sd2_data1_usdhc_data_usdhc2_data1>, + <&iomuxc1_sd2_data2_usdhc_data_usdhc2_data2>, + <&iomuxc1_sd2_data3_usdhc_data_usdhc2_data3>; + drive-strength = "x1"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + + group2 { + pinmux = <&iomuxc1_sd2_vselect_usdhc_vselect_usdhc2_vselect>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + }; + + group3 { + pinmux = <&iomuxc1_sd2_cd_b_gpio_io_gpio3_io0>, + <&iomuxc1_sd2_reset_b_gpio_io_gpio3_io7>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + bias-pull-up; + }; + }; + + pinmux_usdhc2_100mhz: pinmux_usdhc2_100mhz { + group0 { + pinmux = <&iomuxc1_sd2_clk_usdhc_clk_usdhc2_clk>; + drive-strength = "x3"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd2_cmd_usdhc_cmd_usdhc2_cmd>, + <&iomuxc1_sd2_data0_usdhc_data_usdhc2_data0>, + <&iomuxc1_sd2_data1_usdhc_data_usdhc2_data1>, + <&iomuxc1_sd2_data2_usdhc_data_usdhc2_data2>, + <&iomuxc1_sd2_data3_usdhc_data_usdhc2_data3>; + drive-strength = "x3"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + + group2 { + pinmux = <&iomuxc1_sd2_vselect_usdhc_vselect_usdhc2_vselect>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + }; + + group3 { + pinmux = <&iomuxc1_sd2_cd_b_gpio_io_gpio3_io0>, + <&iomuxc1_sd2_reset_b_gpio_io_gpio3_io7>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + bias-pull-up; + }; + }; + + pinmux_usdhc2_200mhz: pinmux_usdhc2_200mhz { + group0 { + pinmux = <&iomuxc1_sd2_clk_usdhc_clk_usdhc2_clk>; + drive-strength = "x6"; + bias-pull-down; + slew-rate = "fast"; + input-schmitt-enable; + }; + + group1 { + pinmux = <&iomuxc1_sd2_cmd_usdhc_cmd_usdhc2_cmd>, + <&iomuxc1_sd2_data0_usdhc_data_usdhc2_data0>, + <&iomuxc1_sd2_data1_usdhc_data_usdhc2_data1>, + <&iomuxc1_sd2_data2_usdhc_data_usdhc2_data2>, + <&iomuxc1_sd2_data3_usdhc_data_usdhc2_data3>; + drive-strength = "x6"; + slew-rate = "fast"; + input-schmitt-enable; + bias-pull-up; + input-enable; + }; + + group2 { + pinmux = <&iomuxc1_sd2_vselect_usdhc_vselect_usdhc2_vselect>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + }; + + group3 { + pinmux = <&iomuxc1_sd2_cd_b_gpio_io_gpio3_io0>, + <&iomuxc1_sd2_reset_b_gpio_io_gpio3_io7>; + drive-strength = "x4"; + slew-rate = "slightly_fast"; + bias-pull-up; + }; + }; }; diff --git a/boards/nxp/frdm_imx91/frdm_imx91_mimx9131.dts b/boards/nxp/frdm_imx91/frdm_imx91_mimx9131.dts index 329ba3e83b73c..b36f451daf8f6 100644 --- a/boards/nxp/frdm_imx91/frdm_imx91_mimx9131.dts +++ b/boards/nxp/frdm_imx91/frdm_imx91_mimx9131.dts @@ -25,6 +25,10 @@ }; +&gpio3{ + status = "okay"; +}; + &lpuart1 { status = "okay"; current-speed = <115200>; @@ -35,3 +39,40 @@ &tpm2 { status = "okay"; }; + +&usdhc1 { + pinctrl-0 = <&pinmux_usdhc1>; + pinctrl-1 = <&pinmux_usdhc1_100mhz>; + pinctrl-2 = <&pinmux_usdhc1_200mhz>; + pinctrl-names = "default", "med", "fast"; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + read-watermark = <0x10>; + write-watermark = <0x80>; + status = "disabled"; + mmc { + compatible = "zephyr,mmc-disk"; + disk-name = "SD2"; + status = "disabled"; + }; +}; + +&usdhc2 { + pinctrl-0 = <&pinmux_usdhc2>; + pinctrl-1 = <&pinmux_usdhc2_100mhz>; + pinctrl-2 = <&pinmux_usdhc2_200mhz>; + pinctrl-names = "default", "med", "fast"; + pwr-gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + power-delay-ms = <20>; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + read-watermark = <0x10>; + write-watermark = <0x80>; + status = "disabled"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "disabled"; + }; +}; diff --git a/boards/nxp/frdm_mcxa153/frdm_mcxa153-pinctrl.dtsi b/boards/nxp/frdm_mcxa153/frdm_mcxa153-pinctrl.dtsi index b92a00352cc75..3522372e6b504 100644 --- a/boards/nxp/frdm_mcxa153/frdm_mcxa153-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxa153/frdm_mcxa153-pinctrl.dtsi @@ -75,6 +75,18 @@ }; }; + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_lpuart0: pinmux_lpuart0 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts b/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts index e257a5e0bd986..2c626ef183d5a 100644 --- a/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts +++ b/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts @@ -9,6 +9,7 @@ #include #include "frdm_mcxa153-pinctrl.dtsi" #include +#include #include / { @@ -70,6 +71,54 @@ zephyr,code = ; }; }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio3 30 0>, /* AN */ + <1 0 &gpio3 1 0>, /* RST */ + <2 0 &gpio1 3 0>, /* CS */ + <3 0 &gpio1 1 0>, /* SCK */ + <4 0 &gpio1 2 0>, /* MISO */ + <5 0 &gpio1 0 0>, /* MOSI */ + <6 0 &gpio3 12 0>, /* PWM */ + <7 0 &gpio2 5 0>, /* INT */ + <8 0 &gpio3 14 0>, /* RX */ + <9 0 &gpio3 15 0>, /* TX */ + <10 0 &gpio3 27 0>, /* GPIO, Not a SCL */ + <11 0 &gpio3 28 0>; /* GPIO, Not a SDA */ + }; + + 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 */ + }; }; &cpu0 { @@ -169,12 +218,24 @@ pinctrl-names = "default"; }; +arduino_i2c: &lpi2c0 {}; + &lpspi0 { status = "okay"; pinctrl-0 = <&pinmux_lpspi0>; pinctrl-names = "default"; }; +mikrobus_spi: &lpspi0 {}; + +&lpspi1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + +arduino_spi: &lpspi1 {}; + &lptmr0 { status = "okay"; }; @@ -193,6 +254,8 @@ pinctrl-names = "default"; }; +mikrobus_serial: &lpuart2 {}; + /* * Uses OS timer as the kernel timer */ diff --git a/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml b/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml index 63cb510600f42..252b7233cc6f7 100644 --- a/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml +++ b/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml @@ -15,6 +15,9 @@ toolchain: - gnuarmemb supported: - adc + - arduino_gpio + - arduino_i2c + - arduino_spi - counter - dma - flash diff --git a/boards/nxp/frdm_mcxa344/CMakeLists.txt b/boards/nxp/frdm_mcxa344/CMakeLists.txt new file mode 100644 index 0000000000000..c06b9273965c0 --- /dev/null +++ b/boards/nxp/frdm_mcxa344/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_mcxa344/Kconfig b/boards/nxp/frdm_mcxa344/Kconfig new file mode 100644 index 0000000000000..9e41ea4cc16a3 --- /dev/null +++ b/boards/nxp/frdm_mcxa344/Kconfig @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXA344 + select BOARD_EARLY_INIT_HOOK diff --git a/boards/nxp/frdm_mcxa344/Kconfig.frdm_mcxa344 b/boards/nxp/frdm_mcxa344/Kconfig.frdm_mcxa344 new file mode 100644 index 0000000000000..4d895ff6d8efa --- /dev/null +++ b/boards/nxp/frdm_mcxa344/Kconfig.frdm_mcxa344 @@ -0,0 +1,6 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXA344 + select SOC_MCXA344 + select SOC_PART_NUMBER_MCXA344VLL diff --git a/boards/nxp/frdm_mcxa344/board.c b/boards/nxp/frdm_mcxa344/board.c new file mode 100644 index 0000000000000..aeef915ad35ad --- /dev/null +++ b/boards/nxp/frdm_mcxa344/board.c @@ -0,0 +1,148 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +/* Core clock frequency: 180MHz */ +#define CLOCK_INIT_CORE_CLOCK 180000000U +#define BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK 180000000U +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +void board_early_init_hook(void) +{ + uint32_t core_freq; + spc_active_mode_core_ldo_option_t ldo_option; + spc_sram_voltage_config_t sram_option; + + /* Get the CPU Core frequency */ + core_freq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (core_freq <= BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldo_option.CoreLDOVoltage = kSPC_CoreLDO_OverDriveVoltage; + ldo_option.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldo_option); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = + (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x4U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sram_option.operateVoltage = kSPC_sramOperateAt1P2V; + sram_option.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sram_option); + } + + /*!< Set up system dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set SYSCON.AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF, 1U); /* !< Set SYSCON.FROHFDIV divider to value 1 */ + CLOCK_SetupFROHFClocking(BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK); /*!< Enable FRO HF */ + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to kFRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (core_freq > BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = + (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x4U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sram_option.operateVoltage = kSPC_sramOperateAt1P2V; + sram_option.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sram_option); + /* Set the LDO_CORE VDD regulator level */ + ldo_option.CoreLDOVoltage = kSPC_CoreLDO_OverDriveVoltage; + ldo_option.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldo_option); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_LF, 1U); /* !< Set SYSCON.FROLFDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivTRACE, 2U); /* !< Set MRCC.TRACE_CLKDIV divider to value 2 */ + +#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(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(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 + + /* Set SystemCoreClock variable. */ + SystemCoreClock = CLOCK_INIT_CORE_CLOCK; +} diff --git a/boards/nxp/frdm_mcxa344/board.cmake b/boards/nxp/frdm_mcxa344/board.cmake new file mode 100644 index 0000000000000..d111b15af049a --- /dev/null +++ b/boards/nxp/frdm_mcxa344/board.cmake @@ -0,0 +1,13 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(jlink "--device=MCXA344") +board_runner_args(linkserver "--device=MCXA344:FRDM-MCXA344") +board_runner_args(pyocd "--target=MCXA344") + +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_mcxa344/board.yml b/boards/nxp/frdm_mcxa344/board.yml new file mode 100644 index 0000000000000..20a587665eacc --- /dev/null +++ b/boards/nxp/frdm_mcxa344/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_mcxa344 + full_name: FRDM-MCXA344 + vendor: nxp + socs: + - name: mcxa344 diff --git a/boards/nxp/frdm_mcxa344/doc/frdm_mcxa344.webp b/boards/nxp/frdm_mcxa344/doc/frdm_mcxa344.webp new file mode 100644 index 0000000000000..7412adb76ac8a Binary files /dev/null and b/boards/nxp/frdm_mcxa344/doc/frdm_mcxa344.webp differ diff --git a/boards/nxp/frdm_mcxa344/doc/index.rst b/boards/nxp/frdm_mcxa344/doc/index.rst new file mode 100644 index 0000000000000..729c69c8a80e8 --- /dev/null +++ b/boards/nxp/frdm_mcxa344/doc/index.rst @@ -0,0 +1,160 @@ +.. zephyr:board:: frdm_mcxa344 + +Overview +******** + +FRDM-MCXA344 is a compact and scalable development board for rapid prototyping of MCX A344 +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-A344 Arm Cortex-M33 microcontroller running at 180 MHz +- 256KB dual-bank on chip Flash +- 64 KB RAM +- 1x 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-A344 SoC and FRDM-MCXA344 board, see: + +- `MCX-A344 SoC Website`_ +- `FRDM-MCXA344 Website`_ +- `FRDM-MCXA344 User Guide`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The MCX-A344 SoC has 5 gpio controllers and has pinmux registers which +can be used to configure the functionality of a pin. + ++------------+-----------------+----------------------------+ +| Name | Function | Usage | ++============+=================+============================+ +| PIO2_3 | UART | UART RX | ++------------+-----------------+----------------------------+ +| PIO2_2 | UART | UART TX | ++------------+-----------------+----------------------------+ + +System Clock +============ + +The MCX-A344 SoC is configured to use FRO running at 180MHz as a source for +the system clock. + +Serial Port +=========== + +The FRDM-MCXA344 SoC has 4 LPUART interfaces for serial communication. +LPUART 2 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_mcxa344 + :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_mcxa344/mcxa344 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxa344/mcxa344 + :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_mcxa344/mcxa344 + +Troubleshooting +=============== + +.. include:: ../../common/segger-ecc-systemview.rst.inc + +.. include:: ../../common/board-footer.rst.inc + +.. _MCX-A344 SoC Website: + https://www.nxp.com/products/MCX-A34X + +.. _FRDM-MCXA344 Website: + https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA344 + +.. _FRDM-MCXA344 User Guide: + https://www.nxp.com/document/guide/getting-started-with-frdm-mcxa344:GS-FRDM-MCXA344 diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi new file mode 100644 index 0000000000000..0179bb4093d2e --- /dev/null +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +&pinctrl { + pinmux_lpuart2: pinmux_lpuart2 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + input-enable; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts new file mode 100644 index 0000000000000..8028d7df658b9 --- /dev/null +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts @@ -0,0 +1,162 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxa344-pinctrl.dtsi" +#include +#include + +/ { + model = "NXP FRDM_MCXA344 board"; + compatible = "nxp,mcxa344", "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 = &lpuart2; + zephyr,shell-uart = &lpuart2; + }; + + leds { + compatible = "gpio-leds"; + + red_led: led_0 { + gpios = <&gpio3 18 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + + green_led: led_1 { + gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + + blue_led: led_2 { + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button_2: button_2 { + label = "User SW2"; + gpios = <&gpio1 7 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 = <180000000>; +}; + +&edma0 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&lpuart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart2>; + 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(16)>; + read-only; + }; + + slot0_partition: partition@4000 { + label = "image-0"; + reg = <0x00004000 DT_SIZE_K(100)>; + }; + + slot1_partition: partition@1D000 { + label = "image-1"; + reg = <0x0001D000 DT_SIZE_K(100)>; + }; + + storage_partition: partition@36000 { + label = "storage"; + reg = <0x00036000 DT_SIZE_K(28)>; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml new file mode 100644 index 0000000000000..5adc5c835cb40 --- /dev/null +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml @@ -0,0 +1,21 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_mcxa344 +name: NXP FRDM MCXA344 +type: mcu +arch: arm +ram: 48 +flash: 244 +toolchain: + - zephyr + - gnuarmemb +supported: + - arduino_gpio + - flash + - gpio + - uart +vendor: nxp diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344_defconfig b/boards/nxp/frdm_mcxa344/frdm_mcxa344_defconfig new file mode 100644 index 0000000000000..e006f6525038c --- /dev/null +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344_defconfig @@ -0,0 +1,12 @@ +# +# 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 diff --git a/boards/nxp/frdm_mcxe247/CMakeLists.txt b/boards/nxp/frdm_mcxe247/CMakeLists.txt new file mode 100644 index 0000000000000..c06b9273965c0 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/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_mcxe247/Kconfig b/boards/nxp/frdm_mcxe247/Kconfig new file mode 100644 index 0000000000000..b3a99a089cd22 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/Kconfig @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXE247 + select BOARD_EARLY_INIT_HOOK diff --git a/boards/nxp/frdm_mcxe247/Kconfig.frdm_mcxe247 b/boards/nxp/frdm_mcxe247/Kconfig.frdm_mcxe247 new file mode 100644 index 0000000000000..57182b0ef1432 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/Kconfig.frdm_mcxe247 @@ -0,0 +1,6 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXE247 + select SOC_MCXE247 + select SOC_PART_NUMBER_MCXE247VLQ diff --git a/boards/nxp/frdm_mcxe247/board.c b/boards/nxp/frdm_mcxe247/board.c new file mode 100644 index 0000000000000..845925a3c32c2 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/board.c @@ -0,0 +1,280 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define ASSERT_WITHIN_RANGE(val, min, max, str) \ + BUILD_ASSERT(val >= min && val <= max, str) + +#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) + +#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable + +#define TO_SYS_CLK_DIV(val) _DO_CONCAT(kSCG_SysClkDivBy, val) +#define TO_ASYNC_CLK_DIV(val) _DO_CONCAT(kSCG_AsyncClkDivBy, val) + +#define SCG_CLOCK_NODE(name) DT_CHILD(DT_INST(0, nxp_kinetis_scg), name) +#define SCG_CLOCK_DIV(name) DT_PROP(SCG_CLOCK_NODE(name), clock_div) +#define SCG_CLOCK_MULT(name) DT_PROP(SCG_CLOCK_NODE(name), clock_mult) + +/* System Clock configuration */ +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(slow_clk), 2, 8, + "Invalid SCG slow clock divider value"); +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(bus_clk), 1, 16, + "Invalid SCG bus clock divider value"); +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(core_clk), 1, 16, + "Invalid SCG core clock divider value"); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +static const scg_sys_clk_config_t scg_sys_clk_config = { + .divSlow = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(slow_clk)), + .divBus = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(bus_clk)), + .divCore = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(core_clk)), +#if DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(sosc_clk)) + .src = kSCG_SysClkSrcSysOsc, +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(sirc_clk)) + .src = kSCG_SysClkSrcSirc, +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(firc_clk)) + .src = kSCG_SysClkSrcFirc, +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(spll_clk)) + .src = kSCG_SysClkSrcSysPll, +#else +#error Invalid SCG core clock source +#endif +}; + +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) +/* System Oscillator (SOSC) configuration */ +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(soscdiv1_clk), + "Invalid SCG SOSC divider 1 value"); +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(soscdiv2_clk), + "Invalid SCG SOSC divider 2 value"); +static const scg_sosc_config_t scg_sosc_config = { + .freq = DT_PROP(SCG_CLOCK_NODE(sosc_clk), clock_frequency), + .monitorMode = kSCG_SysOscMonitorDisable, + .enableMode = kSCG_SysOscEnable, + .div1 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(soscdiv1_clk)), + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(soscdiv2_clk)), + .workMode = DT_PROP(DT_INST(0, nxp_kinetis_scg), sosc_mode) +}; +#endif /* DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) */ + +/* Slow Internal Reference Clock (SIRC) configuration */ +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(sircdiv1_clk), + "Invalid SCG SIRC divider 1 value"); +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(sircdiv2_clk), + "Invalid SCG SIRC divider 2 value"); +static const scg_sirc_config_t scg_sirc_config = { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower, + .div1 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(sircdiv1_clk)), + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(sircdiv2_clk)), +#if MHZ(8) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency) + .range = kSCG_SircRangeHigh +#else +#error Invalid SCG SIRC clock frequency +#endif +}; + +/* Fast Internal Reference Clock (FIRC) configuration */ +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv1_clk), + "Invalid SCG FIRC divider 1 value"); +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv2_clk), + "Invalid SCG FIRC divider 2 value"); +static const scg_firc_config_t scg_firc_config = { + .enableMode = kSCG_FircEnable, + .div1 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv1_clk)), + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), +#if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) + .range = kSCG_FircRange48M, +#else +#error Invalid SCG FIRC clock frequency +#endif + .trimConfig = NULL +}; + +/* System Phase-Locked Loop (SPLL) configuration */ +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(spll_clk), 2, 2, + "Invalid SCG SPLL fixed divider value"); +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(splldiv1_clk), + "Invalid SCG SPLL divider 1 value"); +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(splldiv2_clk), + "Invalid SCG SPLL divider 2 value"); +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(pll), 1, 8, + "Invalid SCG PLL pre divider value"); +ASSERT_WITHIN_RANGE(SCG_CLOCK_MULT(pll), 16, 47, + "Invalid SCG PLL multiplier value"); +#if (DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) && \ + DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(spll_clk))) +static const scg_spll_config_t scg_spll_config = { + .enableMode = kSCG_SysPllEnable, + .monitorMode = kSCG_SysPllMonitorDisable, + .div1 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(splldiv1_clk)), + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(splldiv2_clk)), +#if !DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(pll)), SCG_CLOCK_NODE(sosc_clk)) +#error Invalid SCG PLL clock source +#endif + .prediv = (SCG_CLOCK_DIV(pll) - 1U), + .mult = (SCG_CLOCK_MULT(pll) - 16U) +}; +#endif + +__weak void clock_init(void) +{ + scg_sys_clk_config_t current; + + const scg_sys_clk_config_t scg_sys_clk_config_safe = { + .divSlow = kSCG_SysClkDivBy4, + .divBus = kSCG_SysClkDivBy1, + .divCore = kSCG_SysClkDivBy1, + .src = kSCG_SysClkSrcSirc + }; + +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) + /* Optionally initialize system oscillator */ + CLOCK_InitSysOsc(&scg_sosc_config); + CLOCK_SetXtal0Freq(scg_sosc_config.freq); +#endif + + /* Configure SIRC */ + CLOCK_InitSirc(&scg_sirc_config); + + /* Temporary switch to safe SIRC in order to configure FIRC */ + CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config_safe); + do { + CLOCK_GetCurSysClkConfig(¤t); + } while (current.src != scg_sys_clk_config_safe.src); + CLOCK_InitFirc(&scg_firc_config); + + #if (DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) && \ + DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(spll_clk))) + /* Configure System PLL only if system oscilator is initialized */ + /* as the oscillator is the only SPLL clock source.*/ + CLOCK_InitSysPll(&scg_spll_config); + #endif + + /* Only RUN mode supported for now */ + CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config); + do { + CLOCK_GetCurSysClkConfig(¤t); + } while (current.src != scg_sys_clk_config.src); + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) + CLOCK_SetIpSrc(kCLOCK_Lpuart0, + DT_CLOCKS_CELL(DT_NODELABEL(lpuart0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) + CLOCK_SetIpSrc(kCLOCK_Lpuart1, + DT_CLOCKS_CELL(DT_NODELABEL(lpuart1), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart2)) + CLOCK_SetIpSrc(kCLOCK_Lpuart2, + DT_CLOCKS_CELL(DT_NODELABEL(lpuart2), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c0)) + CLOCK_SetIpSrc(kCLOCK_Lpi2c0, + DT_CLOCKS_CELL(DT_NODELABEL(lpi2c0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) + CLOCK_SetIpSrc(kCLOCK_Lpi2c1, + DT_CLOCKS_CELL(DT_NODELABEL(lpi2c1), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi0)) + CLOCK_SetIpSrc(kCLOCK_Lpspi0, + DT_CLOCKS_CELL(DT_NODELABEL(lpspi0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi1)) + CLOCK_SetIpSrc(kCLOCK_Lpspi1, + DT_CLOCKS_CELL(DT_NODELABEL(lpspi1), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi2)) + CLOCK_SetIpSrc(kCLOCK_Lpspi2, + DT_CLOCKS_CELL(DT_NODELABEL(lpspi2), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(adc0)) + CLOCK_SetIpSrc(kCLOCK_Adc0 + DT_CLOCKS_CELL(DT_NODELABEL(adc0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(adc1)) + CLOCK_SetIpSrc(kCLOCK_Adc1, + DT_CLOCKS_CELL(DT_NODELABEL(adc1), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm0)) + CLOCK_SetIpSrc(kCLOCK_Ftm0, + DT_CLOCKS_CELL(DT_NODELABEL(ftm0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm1)) + CLOCK_SetIpSrc(kCLOCK_Ftm1, + DT_CLOCKS_CELL(DT_NODELABEL(ftm1), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm2)) + CLOCK_SetIpSrc(kCLOCK_Ftm2, + DT_CLOCKS_CELL(DT_NODELABEL(ftm2), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm3)) + CLOCK_SetIpSrc(kCLOCK_Ftm3, + DT_CLOCKS_CELL(DT_NODELABEL(ftm3), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm4)) + CLOCK_SetIpSrc(kCLOCK_Ftm4, + DT_CLOCKS_CELL(DT_NODELABEL(ftm4), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm5)) + CLOCK_SetIpSrc(kCLOCK_Ftm5, + DT_CLOCKS_CELL(DT_NODELABEL(ftm5), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm6)) + CLOCK_SetIpSrc(kCLOCK_Ftm6, + DT_CLOCKS_CELL(DT_NODELABEL(ftm6), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ftm7)) + CLOCK_SetIpSrc(kCLOCK_Ftm7, + 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)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexio0)) + CLOCK_SetIpSrc(kCLOCK_Flexio0, + DT_CLOCKS_CELL(DT_NODELABEL(flexio0), ip_source)); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(enet_ptp_clock)) + CLOCK_SetIpSrc(kCLOCK_Enet, + DT_CLOCKS_CELL(DT_NODELABEL(enet_ptp_clock), ip_source)); +#endif +} + +void board_early_init_hook(void) +{ +#if !defined(CONFIG_ARM_MPU) + uint32_t temp_reg; +#endif /* !CONFIG_ARM_MPU */ + +#if !defined(CONFIG_ARM_MPU) + /* + * Disable memory protection and clear slave port errors. + * MCXE24x does not implement the optional ARMv7-M memory + * protection unit (MPU), specified by the architecture (PMSAv7), in the + * Cortex-M4 core. Instead, the processor includes its own MPU module. + */ + temp_reg = SYSMPU->CESR; + temp_reg &= ~SYSMPU_CESR_VLD_MASK; + temp_reg |= SYSMPU_CESR_SPERR_MASK; + SYSMPU->CESR = temp_reg; +#endif /* !CONFIG_ARM_MPU */ + + clock_init(); +} diff --git a/boards/nxp/frdm_mcxe247/board.cmake b/boards/nxp/frdm_mcxe247/board.cmake new file mode 100644 index 0000000000000..948436a6df9f6 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(linkserver "--device=MCXE247:FRDM-MCXE247") +board_runner_args(jlink "--device=MCXE247") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_mcxe247/board.yml b/boards/nxp/frdm_mcxe247/board.yml new file mode 100644 index 0000000000000..91abc6945b247 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_mcxe247 + full_name: FRDM-MCXE247 + vendor: nxp + socs: + - name: mcxe247 diff --git a/boards/nxp/frdm_mcxe247/doc/frdm_mcxe247.webp b/boards/nxp/frdm_mcxe247/doc/frdm_mcxe247.webp new file mode 100644 index 0000000000000..9e3df04f39d07 Binary files /dev/null and b/boards/nxp/frdm_mcxe247/doc/frdm_mcxe247.webp differ diff --git a/boards/nxp/frdm_mcxe247/doc/index.rst b/boards/nxp/frdm_mcxe247/doc/index.rst new file mode 100644 index 0000000000000..11cd6e608c936 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/doc/index.rst @@ -0,0 +1,184 @@ +.. zephyr:board:: frdm_mcxe247 + +Overview +******** + +FRDM-MCXE247 is compact and scalable development board for rapid +prototyping of MCX E245/246/247 MCUs. It offers industry standard +headers for easy access to the MCU's I/Os, integrated +open-standard serial interfaces, external flash memory and +an on-board MCU-Link debugger. + +Hardware +******** + +- MCXE247VLQ Arm Cortex-M4F 32-bit CPU +- Supports up to 112 MHz frequency (HSRUN mode) +- LQFP144 package +- 2 MB on chip flash memory +- 64 kB FlexNVM for data flash memory and EEPROM emulation +- 256 kB SRAM +- 4 kB of FlexRAM for use as SRAM or EEPROM emulation +- 2x ADC, 1x CMP, TRGMUX +- 2x LPI2C, 3xLPSPI, 1x FlexIO, 3x LPUART, 2x SAI, QSPI, 3xFlexCAN, IEEE1588 100 Mbps ETH MAC +- 8x FlexTimer, Internal and external WDOG, 1x LPIT, 1x LPTMR, 2x PDB, RTC +- NMH1000 magnetic switch +- FXLS8974CF accelerometer +- RGB user LED +- On-board MCU-Link debugger with CMSIS-DAP +- Arduino Header, mikroBUS, Pmod + +For more information about the MCXE247 SoC and FRDM-MCXE247 board, see +these references: + +- `MCX E24x Series Microcontrollers Website`_ +- `FRDM-MCXE247 Website`_ +- `FRDM-MCXE247 Quick Reference Guide`_ +- `FRDM-MCXE247 Getting Started`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The MCX E247 SoC has five pairs of pinmux/gpio controllers (PORTA/GPIOA, +PORTB/GPIOB, PORTC/GPIOC, PORTD/GPIOD, and PORTE/GPIOE). + ++-------+-------------+---------------------------+ +| Name | Function | Usage | ++=======+=============+===========================+ +| PTC13 | GPIO | Red LED | ++-------+-------------+---------------------------+ +| PTB11 | GPIO | Green LED | ++-------+-------------+---------------------------+ +| PTC12 | GPIO | Blue LED | ++-------+-------------+---------------------------+ +| PTD17 | LPUART2_RX | UART Console | ++-------+-------------+---------------------------+ +| PTE12 | LPUART2_TX | UART Console | ++-------+-------------+---------------------------+ +| PTA5 | RESET | RESET Button SW1 | ++-------+-------------+---------------------------+ +| PTA9 | GPIO | User button SW2 | ++-------+-------------+---------------------------+ +| PTC10 | GPIO | User button SW3 | ++-------+-------------+---------------------------+ +| PTA2 | I2C0_SDA | I2C sensor | ++-------+-------------+---------------------------+ +| PTA3 | I2C0_SCL | I2C sensor | ++-------+-------------+---------------------------+ + +System Clock +============ + +The MCXE247 SoC is configured to use SPLL running at 80 MHz (RUN mode) as +a system clock source. + +Serial Port +=========== + +The MCX E247 LPUART2 is used 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 ``DFU mode`` to program the firmware, +short jumper JP2. + +Using J-Link +------------ + +There are two options. The onboard debug circuit can be updated with Segger +J-Link firmware by following the instructions in +:ref:`mcu-link-jlink-onboard-debug-probe`. +To be able to program the firmware, you need to put the board in ``DFU mode`` +by shortening the jumper JP2. +The second option is to attach a :ref:`jlink-external-debug-probe` to the +10-pin SWD connector (J10) of the board. +For both options use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Connect a USB cable from your PC to 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_mcxe247 + :goals: flash + +Open a serial terminal, reset the board (press the SW1 button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v4.1.0-5194-ge7d44ce91cb3 *** + Hello World! frdm_mcxe247/mcxe247 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxe247 + :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 v4.1.0-5194-ge7d44ce91cb3 *** + Hello World! frdm_mcxe247/mcxe247 + +.. include:: ../../common/board-footer.rst.inc + +.. _MCX E24x Series Microcontrollers Website: + https://www.nxp.com/products/MCX-E24X + +.. _FRDM-MCXE247 Website: + https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXE247 + +.. _FRDM-MCXE247 Quick Reference Guide: + https://www.nxp.com/docs/en/quick-reference-guide/MCXE247QSG.pdf + +.. _FRDM-MCXE247 Getting Started: + https://www.nxp.com/document/guide/getting-started-with-the-frdm-mcxe247-board:GS-FRDM-MCXE247 diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi new file mode 100644 index 0000000000000..6f933ab8bce04 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +&pinctrl { + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_lpuart2: pinmux_lpuart2 { + 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 new file mode 100644 index 0000000000000..e7ae5b968abb7 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -0,0 +1,164 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxe247-pinctrl.dtsi" +#include +#include + +/ { + model = "NXP FRDM-MCXE247 board"; + compatible = "nxp,mcxe247", "nxp,mcx"; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &user_button_2; + sw1 = &user_button_3; + }; + + chosen { + zephyr,sram = &sram_l; + zephyr,flash = &flash0; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + zephyr,canbus = &flexcan0; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + green_led: led_1 { + gpios = <&gpiob 11 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + blue_led: led_2 { + gpios = <&gpioc 12 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_2: button_2 { + label = "User SW2"; + gpios = <&gpioa 9 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + user_button_3: button_3 { + label = "User SW3"; + gpios = <&gpioc 10 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; +}; + +&cpu0 { + clock-frequency = <80000000>; +}; + +&sosc_clk { + clock-frequency = <8000000>; + status = "okay"; +}; + +&spll_clk { + status = "okay"; +}; + +&core_clk { + clocks = <&spll_clk>; + clock-div = <2>; +}; + +&bus_clk { + clock-div = <2>; +}; + +&slow_clk { + clock-div = <4>; +}; + +&fircdiv2_clk { + clock-div = <1>; +}; + +&soscdiv2_clk { + clock-div = <1>; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&gpioe { + status = "okay"; +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-names = "default"; +}; + +&lpuart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart2>; + pinctrl-names = "default"; +}; + +&edma { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml new file mode 100644 index 0000000000000..1946cb7b28012 --- /dev/null +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -0,0 +1,20 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_mcxe247 +name: NXP FRDM-MCXE247 +type: mcu +arch: arm +ram: 128 +flash: 1536 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - gpio + - arduino_gpio +vendor: nxp diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247_defconfig b/boards/nxp/frdm_mcxe247/frdm_mcxe247_defconfig new file mode 100644 index 0000000000000..a13393c8e5dcd --- /dev/null +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247_defconfig @@ -0,0 +1,10 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y diff --git a/boards/nxp/frdm_mcxe31b/CMakeLists.txt b/boards/nxp/frdm_mcxe31b/CMakeLists.txt new file mode 100644 index 0000000000000..161914f1a01bb --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_NXP_MCXE31X_BOOT_HEADER) + zephyr_library_sources(boot_header/boot_header.c) + zephyr_library_include_directories(boot_header) +endif() diff --git a/boards/nxp/frdm_mcxe31b/Kconfig b/boards/nxp/frdm_mcxe31b/Kconfig new file mode 100644 index 0000000000000..5373c9c7f9f3b --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/Kconfig @@ -0,0 +1,12 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NXP_MCXE31X_BOOT_HEADER + bool "MCXE31x boot header support" + select SOC_NXP_MCXE31X_BOOT_HEADER + default y + help + Enable this option to include the MCXE31x boot header in the final + image. The boot header is required for proper operation of the + on-chip bootloader. + See the MCXE31x reference manual for more details. diff --git a/boards/nxp/frdm_mcxe31b/Kconfig.frdm_mcxe31b b/boards/nxp/frdm_mcxe31b/Kconfig.frdm_mcxe31b new file mode 100644 index 0000000000000..0a5bb955a9b88 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/Kconfig.frdm_mcxe31b @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXE31B + select SOC_PART_NUMBER_MCXE31BMPB diff --git a/boards/nxp/frdm_mcxe31b/board.cmake b/boards/nxp/frdm_mcxe31b/board.cmake new file mode 100644 index 0000000000000..7c3a7470cf770 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/board.cmake @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MCXE31B") +board_runner_args(linkserver "--device=MCXE31B:FRDM-MCXE31B") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_mcxe31b/board.yml b/boards/nxp/frdm_mcxe31b/board.yml new file mode 100644 index 0000000000000..f4030712e3c2b --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_mcxe31b + full_name: FRDM-MCXE31B + vendor: nxp + socs: + - name: mcxe31b diff --git a/boards/nxp/frdm_mcxe31b/boot_header/boot_header.c b/boards/nxp/frdm_mcxe31b/boot_header/boot_header.c new file mode 100644 index 0000000000000..da11b11e521c0 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/boot_header/boot_header.c @@ -0,0 +1,91 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "boot_header.h" +#include "fsl_common.h" + +/****************************************************************************** + * External references + ******************************************************************************/ +#if defined(CONFIG_BOARD_NXP_MCXE31X_BOOT_HEADER) && (CONFIG_BOARD_NXP_MCXE31X_BOOT_HEADER != 0U) + +extern void *const _vector_start; + +/****************************************************************************** + * Boot Header + ******************************************************************************/ +typedef struct image_vector_table { + uint32_t header; /* header */ + uint32_t boot_config; /* Boot configuration Word */ + const uint32_t reserved1; /* Reserved */ + const uint32_t *cm7_0_start_address; /* Start address of CM7_0 Core */ + const uint32_t reserved2; /* Reserved */ + const uint32_t *reserved3; /* Reserved */ + const uint32_t reserved4; /* Reserved */ + const uint32_t *reserved5; /* Reserved */ + const uint32_t *reserved6; /* Reserved */ + const uint32_t *lcc_config; /* Address of LC config */ + uint8_t reserved7[216]; /* Reserved for future use */ +} ivt_t; + +/****************************************************************************** + * SBAF definitions + ******************************************************************************/ +/* CM7_0_ENABLE: */ +/* 0- Cortex-M7_0 application core clock gated after boot */ +/* 1- Cortex-M7_0 application core clock un-gated after boot */ +#define CM7_0_ENABLE_MASK 1U + +/* Control the boot flow of the application: */ +/* 0- Non-Secure Boot- Application image is started by SBAF without any */ +/* authentication in parallel to HSE firmware. */ +/* 1- Secure Boot- Application image is executed by HSE firmware after the */ +/* authentication. SBAF only starts the HSE firmware after successful */ +/* authentication. */ +#define BOOT_SEQ_MASK 8U + +/* APP_SWT_INIT: Control SWT0 before starting application core(s): */ +/* 0- Disable. */ +/* 1- Enable. SBAF initializes SWT0 before enabling application cores. */ +/* SBAF scans this bit only when BOOT_SEQ bit is 0. */ +#define APP_SWT_INIT_MASK 32U + +/*! + * @brief Sets register field in peripheral configuration structure. + * @details This macro sets register field mask in the peripheral + * configuration structure. + * @param mask Register field to be set. + * @note Implemented as a macro. + */ +#define SET(mask) (mask) + +/*! + * @brief Clears register field in peripheral configuration structure. + * @details This macro clears register field mask in the peripheral + * configuration structure. + * @param mask Register field to be cleared. + * @note Implemented as a macro. + */ +#define CLR(mask) 0 + +const ivt_t _boot_header __attribute__((used, section(".boot_header"))) = { + .header = 0x5AA55AA5, + .boot_config = SET(CM7_0_ENABLE_MASK) | /* booting core is core0 */ + CLR(BOOT_SEQ_MASK) | /* unsecure boot is only supported */ + CLR(APP_SWT_INIT_MASK), /* SWT0 is not setup by BAF */ + .cm7_0_start_address = (const uint32_t *)&_vector_start, + .lcc_config = (const uint32_t *)&lc_config}; + +/****************************************************************************** + * Default configurations that can be overridden by strong definitions + ******************************************************************************/ + +__WEAK const boot_lc_config_t lc_config = 0xffffffff; + +#endif /* CONFIG_BOARD_NXP_MCXE31X_BOOT_HEADER */ +/****************************************************************************** + * End of module + ******************************************************************************/ diff --git a/boards/nxp/frdm_mcxe31b/boot_header/boot_header.h b/boards/nxp/frdm_mcxe31b/boot_header/boot_header.h new file mode 100644 index 0000000000000..5cd390d196a1c --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/boot_header/boot_header.h @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BOOT_HEADER_H_ +#define ZEPHYR_INCLUDE_BOOT_HEADER_H_ + +#include "fsl_common.h" + +/****************************************************************************** + * Configuration structure definition * + ******************************************************************************/ + +typedef uint32_t boot_lc_config_t; +extern const boot_lc_config_t lc_config; + +#endif /* ZEPHYR_INCLUDE_BOOT_HEADER_H_ */ diff --git a/boards/nxp/frdm_mcxe31b/doc/frdm_mcxe31b.webp b/boards/nxp/frdm_mcxe31b/doc/frdm_mcxe31b.webp new file mode 100644 index 0000000000000..e95771fcd0ec3 Binary files /dev/null and b/boards/nxp/frdm_mcxe31b/doc/frdm_mcxe31b.webp differ diff --git a/boards/nxp/frdm_mcxe31b/doc/index.rst b/boards/nxp/frdm_mcxe31b/doc/index.rst new file mode 100644 index 0000000000000..983390bbea5f5 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/doc/index.rst @@ -0,0 +1,174 @@ +.. zephyr:board:: frdm_mcxe31b + +Overview +******** +The FRDM-MCXE31B board is a design and evaluation platform based on the NXP MCXE31B +microcontroller (MCU). NXP MCXE31B MCU based on an Arm Cortex-M7 core, running at +speeds of up to 160 MHz with a 2.97 to 5.5V supply. + +Hardware +******** + +- MCXE31B Arm Cortex-M7 microcontroller running up to 160 MHz +- 4MB dual-bank on chip Flash +- 320KB SRAM + 192KB TCM +- 2x I2C +- 6x SPI +- 16x UART +- On-board MCU-Link debugger with CMSIS-DAP +- Arduino Header, mikroBUS + +For more information about the MCXE31B SoC and FRDM-MCXE31B board, see: + +- `MCXE31X Datasheet`_ +- `MCXE31X Reference Manual`_ +- `FRDM-MCXE31B Board User Manual`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +Each GPIO port is divided into two banks: low bank, from pin 0 to 15, and high +bank, from pin 16 to 31. For example, ``PTA2`` is the pin 2 of ``gpioa_l`` (low +bank), and ``PTA20`` is the pin 4 of ``gpioa_h`` (high bank). + +The GPIO controller provides the option to route external input pad interrupts +to either the SIUL2 EIRQ or WKPU interrupt controllers, as supported by the SoC. +By default, GPIO interrupts are routed to SIUL2 EIRQ interrupt controller, +unless they are explicity configured to be directed to the WKPU interrupt +controller, as outlined in :zephyr_file:`dts/bindings/gpio/nxp,siul2-gpio.yaml`. + +To find information about which GPIOs are compatible with each interrupt +controller, refer to the device reference manual. + ++-------+-------------+---------------------------+ +| Name | Function | Usage | ++=======+=============+===========================+ +| PTC16 | GPIO | Red LED | ++-------+-------------+---------------------------+ +| PTB22 | GPIO | Green LED | ++-------+-------------+---------------------------+ +| PTC14 | GPIO | Blue LED | ++-------+-------------+---------------------------+ +| PTE3 | LPUART5_RX | UART Console | ++-------+-------------+---------------------------+ +| PTE14 | LPUART5_TX | UART Console | ++-------+-------------+---------------------------+ + +System Clock +============ + +The MCXE31B SoC is configured to use PLL running at 160MHz as a source for +the system clock. + +Serial Port +=========== + +The MCXE31B LPUART5 is used 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 JP3. + +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 shorting the jumper JP3. +The second option is to attach a :ref:`jlink-external-debug-probe` to the +10-pin SWD connector (J14) of the board. +For both options use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Connect a USB cable from your PC to 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_mcxe31b + :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 v4.2.0-2092-g17e93a718422 *** + Hello World! frdm_mcxe31b/mcxe31b + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxe31b + :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 v4.2.0-2092-g17e93a718422 *** + Hello World! frdm_mcxe31b/mcxe31b + +Troubleshooting +=============== + +.. include:: ../../common/segger-ecc-systemview.rst.inc + +.. include:: ../../common/board-footer.rst.inc + +.. _MCXE31X Datasheet: + https://www.nxp.com/docs/en/data-sheet/MCXEP172M160FB0.pdf + +.. _MCXE31X Reference Manual: + https://www.nxp.com/webapp/Download?colCode=MCXE31XRM&location=null + +.. _FRDM-MCXE31B Board User Manual: + https://www.nxp.com/webapp/Download?colCode=UM12330&location=null&isHTMLorPDF=HTML diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi new file mode 100644 index 0000000000000..965205033ec69 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi @@ -0,0 +1,28 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +&pinctrl { + eirq0_default: eirq0_default { + group1 { + pinmux = ; + input-enable; + }; + }; + + pinmux_lpuart_5: pinmux_lpuart_5 { + group1 { + pinmux = ; + output-enable; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts new file mode 100644 index 0000000000000..d56bd97263b72 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts @@ -0,0 +1,167 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxe31b-pinctrl.dtsi" +#include +#include +#include + +/ { + model = "NXP FRDM_MCXE31B board"; + compatible = "nxp,mcxe31b"; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &user_button; + }; + + chosen { + zephyr,sram = &sram; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,flash = &program_flash; + zephyr,flash-controller = &flash; + zephyr,console = &lpuart_5; + }; + + leds { + compatible = "gpio-leds"; + + red_led: led_0 { + gpios = <&gpioc_h 0 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + + green_led: led_1 { + gpios = <&gpiob_h 6 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + + blue_led: led_2 { + gpios = <&gpioc_l 14 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button: button_0 { + label = "User SW3"; + gpios = <&gpiod_l 5 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; +}; + +&core0 { + clock-frequency = ; +}; + +&gpiob_h { + status = "okay"; +}; + +&lpuart_5 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart_5>; + pinctrl-names = "default"; + dmas = <&edma 1 44>, <&edma 2 45>; + dma-names = "tx", "rx"; +}; + +&gpioc_l { + status = "okay"; +}; + +&gpioc_h { + status = "okay"; +}; + +&gpiod_l { + status = "okay"; +}; + +&eirq0 { + pinctrl-0 = <&eirq0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&firc { + status = "okay"; + firc-div = "UnDiv"; +}; + +&fxosc { + status = "okay"; + freq = <16000000>; + workmode = "crystal"; + delay = <49>; + overdrive = <12>; +}; + +&pll { + status = "okay"; + workmode = "Integer"; + prediv = <2>; + postdiv = <2>; + multiplier = <120>; + fracloopdiv = <0>; + stepsize = <0>; + stepnum = <0>; + accuracy = "Accuracy9"; + outdiv = <3 3>; +}; + +&mc_cgm { + status = "okay"; + max-ido-change = <50>; + step-duration = <1>; + clk-src-freq = <160000000>; + mux-0-dc-0-div = <1>; + mux-0-dc-1-div = <2>; + mux-0-dc-2-div = <4>; + mux-0-dc-3-div = <2>; + mux-0-dc-4-div = <4>; + mux-0-dc-5-div = <4>; + mux-0-dc-6-div = <1>; +}; diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml new file mode 100644 index 0000000000000..7a1dafbd58828 --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml @@ -0,0 +1,16 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +identifier: frdm_mcxe31b +name: NXP FRDM MCXE31B +type: mcu +arch: arm +ram: 288 +flash: 4096 +toolchain: + - zephyr + - gnuarmemb +supported: + - arduino_gpio + - gpio +vendor: nxp diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b_defconfig b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b_defconfig new file mode 100644 index 0000000000000..7c9b1108f66aa --- /dev/null +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b_defconfig @@ -0,0 +1,7 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/nxp/frdm_mcxn236/board.c b/boards/nxp/frdm_mcxn236/board.c index 53d2052a78331..f4034aebbc3c2 100644 --- a/boards/nxp/frdm_mcxn236/board.c +++ b/boards/nxp/frdm_mcxn236/board.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * SPDX-License-Identifier: Apache-2.0 */ #include @@ -103,7 +103,9 @@ void board_early_init_hook(void) CLOCK_SetupExtClocking(BOARD_XTAL0_CLK_HZ); -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai0)) || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai1)) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai0)) || \ + DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai1)) || \ + DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(micfil)) /* < Set up PLL1 */ const pll_setup_t pll1_Setup = { .pllctrl = SCG_SPLLCTRL_SOURCE(1U) | SCG_SPLLCTRL_SELI(3U) | @@ -111,12 +113,13 @@ void board_early_init_hook(void) .pllndiv = SCG_SPLLNDIV_NDIV(25U), .pllpdiv = SCG_SPLLPDIV_PDIV(10U), .pllmdiv = SCG_SPLLMDIV_MDIV(256U), - .pllRate = 24576000U}; + .pllRate = 24576000U + }; /* Configure PLL1 to the desired values */ CLOCK_SetPLL1Freq(&pll1_Setup); - /* Set PLL1 CLK0 divider to value 1 */ - CLOCK_SetClkDiv(kCLOCK_DivPLL1Clk0, 1U); + /* Set PLL1 CLK0 divider to value 2, then the clock is 12288000Hz. */ + CLOCK_SetClkDiv(kCLOCK_DivPLL1Clk0, 2U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm0)) @@ -339,6 +342,12 @@ void board_early_init_hook(void) CLOCK_EnableClock(kCLOCK_Sai1); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(micfil)) + CLOCK_SetClkDiv(kCLOCK_DivMicfilFClk, 1U); + CLOCK_AttachClk(kPLL1_CLK0_to_MICFILF); + CLOCK_EnableClock(kCLOCK_Micfil); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; } diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi b/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi index d03950c097718..5b8aaf77b9831 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi @@ -8,8 +8,8 @@ &pinctrl { pinmux_flexcomm0_lpuart: pinmux_flexcomm0_lpuart { group0 { - pinmux = , - ; + pinmux = , + ; slew-rate = "fast"; drive-strength = "low"; input-enable; @@ -248,4 +248,14 @@ drive-open-drain; }; }; + + pinmux_micfil: pinmux_micfil { + group0 { + pinmux = , + ; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts index 35bb46e9ee7bd..a22cac77b6aaf 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts @@ -443,3 +443,9 @@ dvp_20pin_interface: &video_sdma {}; pinctrl-0 = <&pinmux_sai1>; pinctrl-names = "default"; }; + +&micfil { + status = "okay"; + pinctrl-0 = <&pinmux_micfil>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/frdm_mcxn947/board.c b/boards/nxp/frdm_mcxn947/board.c index 321941863d03f..2ac3f1696774d 100644 --- a/boards/nxp/frdm_mcxn947/board.c +++ b/boards/nxp/frdm_mcxn947/board.c @@ -422,7 +422,7 @@ void board_early_init_hook(void) CLOCK_AttachClk(kPLL0_to_FLEXIO); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i3c1)) /* Enable 1MHz clock. */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK; @@ -436,7 +436,7 @@ void board_early_init_hook(void) CLOCK_AttachClk(kI3C1FCLK_to_I3C1FCLKSTC); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sc_timer), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sc_timer)) /* attach FRO HF to SCT */ CLOCK_SetClkDiv(kCLOCK_DivSctClk, 1u); CLOCK_AttachClk(kFRO_HF_to_SCT); diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi index 8df1c3d4df029..36101b40a6358 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi @@ -18,6 +18,18 @@ }; }; + pinmux_flexcomm6_lpspi: pinmux_flexcomm6_lpspi { + group0 { + pinmux = , /* SAI1_TXD0 */ + , /* SAI1_RXD0 */ + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_flexcomm2_lpi2c: pinmux_flexcomm2_lpi2c { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi index 6fd415f581c75..e4018e362a40e 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi @@ -61,6 +61,25 @@ }; }; + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = /* ANA_4/ADC1_A0 AN */ + <1 0 &gpio1 3 0>, /* RST */ + <2 0 &gpio3 23 0>, /* CS */ + <3 0 &gpio3 21 0>, /* SCK */ + <4 0 &gpio3 22 0>, /* MISO */ + <5 0 &gpio3 20 0>, /* MOSI */ + <6 0 &gpio3 19 0>, /* PWM */ + <7 0 &gpio5 7 0>, /* INT */ + <8 0 &gpio1 16 0>, /* GPIO, Not a RX */ + <9 0 &gpio1 17 0>, /* GPIO, Not a TX */ + <10 0 &gpio1 1 0>, /* SCL */ + <11 0 &gpio1 0 0>; /* SDA */ + }; + arduino_header: arduino-connector { compatible = "arduino-header-r3"; #gpio-cells = <2>; @@ -70,8 +89,8 @@ , , , - , - , + , /* RX */ + , /* TX */ , , , @@ -80,12 +99,12 @@ , , , - , - , - , - , - , - ; + , /* CS */ + , /* MOSI */ + , /* MISO */ + , /* SCK */ + , /* SDA */ + ; /* SCL */ }; /* @@ -116,18 +135,39 @@ pinctrl-names = "default"; }; +arduino_spi: &flexcomm1_lpspi1 {}; + +&flexcomm6_lpspi6 { + pinctrl-0 = <&pinmux_flexcomm6_lpspi>; + pinctrl-names = "default"; +}; + +mikrobus_spi: &flexcomm6_lpspi6 {}; + nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { pinctrl-0 = <&pinmux_flexcomm2_lpi2c>; pinctrl-names = "default"; clock-frequency = ; }; +arduino_i2c: &flexcomm2_lpi2c2 {}; + +&flexcomm3_lpi2c3 { + pinctrl-0 = <&pinmux_flexcomm3_lpi2c>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +mikrobus_i2c: &flexcomm3_lpi2c3 {}; + &flexcomm2_lpuart2 { current-speed = <115200>; pinctrl-0 = <&pinmux_flexcomm2_lpuart>; pinctrl-names = "default"; }; +arduino_serial: &flexcomm2_lpuart2 {}; + &flexcomm4_lpuart4 { current-speed = <115200>; pinctrl-0 = <&pinmux_flexcomm4_lpuart>; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi index 00666335086d1..cd40cd6e56e6d 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi @@ -56,22 +56,36 @@ status = "okay"; }; -&gpio4 { +/* Required on MikroBus connector. */ +&gpio5 { status = "okay"; }; -&gpio1 { +/* Required on Arduino connector. */ +&gpio4 { status = "okay"; }; -&gpio0 { +/* Required on MikroBus connector. */ +&gpio3 { status = "okay"; }; +/* Required on SD card. */ &gpio2 { status = "okay"; }; +/* Required on Arduino and MikroBus connector. */ +&gpio1 { + status = "okay"; +}; + +/* Required on Arduino connector. */ +&gpio0 { + status = "okay"; +}; + &green_led { status = "okay"; }; @@ -92,38 +106,63 @@ status = "okay"; }; +/* Required on Arduino connector. */ &flexcomm1_lpspi1 { status = "okay"; }; +/* + * LPFLEXCOMM supports UART and I2C on the same instance, enable this for + * LPLEXCOMM2 with LPUART2 and LPI2C2. + */ &flexcomm2 { status = "okay"; }; +/* Required on Arduino and FlexIO LCD (touch panel) connector. */ &flexcomm2_lpi2c2 { status = "okay"; }; -/* - *LPFLEXCOMM supports UART and I2C on the same instance, enable this for - * LFLEXCOMM2 - */ +/* Required on Arduino connector. */ &flexcomm2_lpuart2 { status = "okay"; }; +&flexcomm3 { + status = "okay"; +}; + +/* Required on MikroBus connector. */ +&flexcomm3_lpi2c3 { + status = "okay"; +}; + &flexcomm4 { status = "okay"; }; +/* Required for serial console and on Camera connector. */ &flexcomm4_lpuart4 { status = "okay"; }; +/* + * LPFLEXCOMM6 supports SPI for MikroBus. Enable this for LPSPI6 but let + * LPSPI6 disabled as long as it is not needed because of two shared signals + * with SAI1 (P3_20 for SAI1_TXD0 and FC6_SPI_MOSI and P3_21 for SAI1_RXD0 + * and FC6_SPI_SCK). There is also an additional MikroBus signal shared + * with SAI1 (P3_19 for SAI1_RX_FS and MikroBus:PWM). + */ +&flexcomm6 { + status = "okay"; +}; + &flexcomm7 { status = "okay"; }; +/* Required on Camera connector. */ &flexcomm7_lpi2c7 { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index 462e1eb809fd5..0fd1ac9dbb0a8 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -15,6 +15,10 @@ toolchain: - gnuarmemb supported: - adc + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi - can - counter - dac 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 438ed72869304..ca5461e8df4c3 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -15,6 +15,10 @@ toolchain: - gnuarmemb supported: - adc + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi - can - counter - dac diff --git a/boards/nxp/frdm_mcxw23/frdm_mcxw23-pinctrl.dtsi b/boards/nxp/frdm_mcxw23/frdm_mcxw23-pinctrl.dtsi index 4b1467fba11d2..d0a0ecd98c862 100644 --- a/boards/nxp/frdm_mcxw23/frdm_mcxw23-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxw23/frdm_mcxw23-pinctrl.dtsi @@ -26,6 +26,16 @@ }; }; + pinmux_flexcomm2_spi: pinmux_flexcomm2_spi { + group0 { + pinmux = , + , + , + ; + slew-rate = "standard"; + }; + }; + pinmux_sctimer_default: pinmux_sctimer_default { group0 { pinmux = ; diff --git a/boards/nxp/frdm_mcxw23/frdm_mcxw23.yaml b/boards/nxp/frdm_mcxw23/frdm_mcxw23.yaml index c7154b8d88732..b979d8ff8cff9 100644 --- a/boards/nxp/frdm_mcxw23/frdm_mcxw23.yaml +++ b/boards/nxp/frdm_mcxw23/frdm_mcxw23.yaml @@ -22,4 +22,6 @@ supported: - i2c - watchdog - pwm + - spi + - dma vendor: nxp diff --git a/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi b/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi index 640a888650207..e7065d363b254 100644 --- a/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi +++ b/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi @@ -176,6 +176,15 @@ pinctrl-names = "default"; }; +/* + * MCXW23 FRDM board uses OS timer as the kernel timer + * In case we need to switch to SYSTICK timer, then + * replace &os_timer with &systick + */ +&os_timer { + status = "okay"; +}; + &wwdt0 { status = "okay"; }; @@ -188,6 +197,14 @@ status = "okay"; }; +&dma0 { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; @@ -218,7 +235,14 @@ arduino_i2c: &flexcomm1 {}; -arduino_spi: &flexcomm2 {}; +arduino_spi: &flexcomm2 { + status = "okay"; + compatible = "nxp,lpc-spi"; + pinctrl-0 = <&pinmux_flexcomm2_spi>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; +}; mikrobus_i2c: &flexcomm1 {}; diff --git a/boards/nxp/frdm_mcxw23/pre_dt_board.cmake b/boards/nxp/frdm_mcxw23/pre_dt_board.cmake new file mode 100644 index 0000000000000..29bf157c1b597 --- /dev/null +++ b/boards/nxp/frdm_mcxw23/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "spi_bus_bridge" as flexcomm node can be used as a SPI device. +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts index d67033c8b5db3..b1cbec74e7e13 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts @@ -142,9 +142,6 @@ status = "okay"; pinctrl-0 = <&pinmux_lpspi1>; pinctrl-names = "default"; - pcs-sck-delay = <5>; - sck-pcs-delay = <5>; - transfer-delay = <125>; mx25r6435fm2il0: flash@0 { compatible = "jedec,spi-nor"; @@ -163,6 +160,9 @@ mxicy,mx25r-power-mode = "low-power"; /* 8 MHz for low power mode */ spi-max-frequency = ; + spi-cs-setup-delay-ns = <5>; + spi-cs-hold-delay-ns = <5>; + spi-interframe-delay-ns = <125>; }; }; diff --git a/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi b/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi index 4e1e4af80523a..c960ba7c6f272 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi +++ b/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi @@ -47,11 +47,16 @@ }; }; + /* support CS0 (Arduino connector) and CS1 (MicroBus connector). */ pinmux_flexcomm1_spi: pinmux_flexcomm1_spi { group0 { pinmux = ; slew-rate = "ultra"; }; + group1 { + pinmux = ; + slew-rate = "ultra"; + }; }; pinmux_pwm0: pinmux_pwm0 { diff --git a/boards/nxp/frdm_rw612/frdm_rw612.yaml b/boards/nxp/frdm_rw612/frdm_rw612.yaml index 659229a89c6f9..7ad0b8d1f93fb 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.yaml +++ b/boards/nxp/frdm_rw612/frdm_rw612.yaml @@ -16,6 +16,9 @@ flash: 65536 supported: - arduino_gpio - gpio + - arduino_gpio + - arduino_i2c + - arduino_spi - dma - spi - i2c diff --git a/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi index e649d3d04167b..1d4e20a9ff70b 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi +++ b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi @@ -59,6 +59,25 @@ <12 0 &hsgpio0 18 0>; /* Pin 11, LCD touch INT */ }; + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &hsgpio1 29 0>, /* AN */ + <1 0 &hsgpio0 19 0>, /* RST */ + <2 0 &hsgpio0 10 0>, /* CS */ + <3 0 &hsgpio0 7 0>, /* SCK */ + <4 0 &hsgpio0 8 0>, /* MISO */ + <5 0 &hsgpio0 9 0>, /* MOSI */ + <6 0 &hsgpio0 1 0>, /* PWM */ + <7 0 &hsgpio1 22 0>, /* INT */ + <8 0 &hsgpio0 2 0>, /* RX */ + <9 0 &hsgpio0 3 0>, /* TX */ + <10 0 &hsgpio0 17 0>, /* SCL */ + <11 0 &hsgpio0 16 0>; /* SDA */ + }; + arduino_header: arduino-connector { compatible = "arduino-header-r3"; #gpio-cells = <2>; @@ -67,8 +86,8 @@ gpio-map = , , , - , - , + , /* GPIO(D11), Not a RX */ + , /* GPIO(D12), Not a TX */ , , , @@ -77,12 +96,12 @@ , , , - , - , - , - , - , - ; + , /* CS */ + , /* MOSI */ + , /* MISO */ + , /* SCK */ + , /* SDA */ + ; /* SCL */ }; }; @@ -103,6 +122,8 @@ pinctrl-names = "default"; }; +mikrobus_serial: &flexcomm0 {}; + &hsgpio0 { status = "okay"; pinctrl-0 = <&pinmux_hsgpio0>; @@ -299,7 +320,11 @@ zephyr_udc0: &usb_otg { #size-cells = <0>; }; -arduino_i2c: &flexcomm2 { +arduino_spi: &flexcomm1 {}; + +mikrobus_spi: &flexcomm1 {}; + +&flexcomm2 { compatible = "nxp,lpc-i2c"; status = "okay"; clock-frequency = ; @@ -315,6 +340,10 @@ arduino_i2c: &flexcomm2 { }; }; +arduino_i2c: &flexcomm2 {}; + +mikrobus_i2c: &flexcomm2 {}; + zephyr_mipi_dbi_spi: &lcdic { status = "okay"; pinctrl-0 = <&pinmux_lcdic>; diff --git a/boards/nxp/mcx_nx4x_evk/board.c b/boards/nxp/mcx_nx4x_evk/board.c index 760812971a3ad..27557d88546ac 100644 --- a/boards/nxp/mcx_nx4x_evk/board.c +++ b/boards/nxp/mcx_nx4x_evk/board.c @@ -418,7 +418,7 @@ void board_early_init_hook(void) CLOCK_AttachClk(kPLL0_to_FLEXIO); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i3c1)) /* Enable 1MHz clock. */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK; @@ -432,7 +432,7 @@ void board_early_init_hook(void) CLOCK_AttachClk(kI3C1FCLK_to_I3C1FCLKSTC); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sc_timer), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sc_timer)) /* attach FRO HF to SCT */ CLOCK_SetClkDiv(kCLOCK_DivSctClk, 1u); CLOCK_AttachClk(kFRO_HF_to_SCT); diff --git a/boards/nxp/mcx_nx4x_evk/board.cmake b/boards/nxp/mcx_nx4x_evk/board.cmake index e31e7eacb36be..4abf13fd95a84 100644 --- a/boards/nxp/mcx_nx4x_evk/board.cmake +++ b/boards/nxp/mcx_nx4x_evk/board.cmake @@ -28,6 +28,7 @@ elseif(CONFIG_SOC_MCXN947_CPU1) board_runner_args(linkserver "--device=MCXN947:MCX-N9XX-EVK") board_runner_args(linkserver "--core=cm33_core1") elseif(CONFIG_SOC_MCXN547_CPU0) + board_runner_args(jlink "--device=MCXN547_M33_0" "--reset-after-load") board_runner_args(linkserver "--device=MCXN547:MCX-N5XX-EVK") endif() diff --git a/boards/nxp/mcxw23_evk/mcxw23_evk-pinctrl.dtsi b/boards/nxp/mcxw23_evk/mcxw23_evk-pinctrl.dtsi index 4b1467fba11d2..d0a0ecd98c862 100644 --- a/boards/nxp/mcxw23_evk/mcxw23_evk-pinctrl.dtsi +++ b/boards/nxp/mcxw23_evk/mcxw23_evk-pinctrl.dtsi @@ -26,6 +26,16 @@ }; }; + pinmux_flexcomm2_spi: pinmux_flexcomm2_spi { + group0 { + pinmux = , + , + , + ; + slew-rate = "standard"; + }; + }; + pinmux_sctimer_default: pinmux_sctimer_default { group0 { pinmux = ; diff --git a/boards/nxp/mcxw23_evk/mcxw23_evk.yaml b/boards/nxp/mcxw23_evk/mcxw23_evk.yaml index a137a9558c7d1..d3c5f6ffac817 100644 --- a/boards/nxp/mcxw23_evk/mcxw23_evk.yaml +++ b/boards/nxp/mcxw23_evk/mcxw23_evk.yaml @@ -22,4 +22,6 @@ supported: - i2c - watchdog - pwm + - spi + - dma vendor: nxp diff --git a/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi b/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi index 09c1ac9d29e0d..7cdc1103826a0 100644 --- a/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi +++ b/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi @@ -156,6 +156,15 @@ pinctrl-names = "default"; }; +/* + * MCXW23 EVK board uses OS timer as the kernel timer + * In case we need to switch to SYSTICK timer, then + * replace &os_timer with &systick + */ +&os_timer { + status = "okay"; +}; + &wwdt0 { status = "okay"; }; @@ -168,6 +177,14 @@ status = "okay"; }; +&dma0 { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; @@ -198,8 +215,13 @@ arduino_i2c: &flexcomm0 {}; -arduino_spi: &flexcomm0 {}; - mikrobus_i2c: &flexcomm0 {}; -mikrobus_spi: &flexcomm0 {}; +mikrobus_spi: &flexcomm2 { + status = "okay"; + compatible = "nxp,lpc-spi"; + pinctrl-0 = <&pinmux_flexcomm2_spi>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; +}; diff --git a/boards/nxp/mcxw23_evk/pre_dt_board.cmake b/boards/nxp/mcxw23_evk/pre_dt_board.cmake new file mode 100644 index 0000000000000..29bf157c1b597 --- /dev/null +++ b/boards/nxp/mcxw23_evk/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "spi_bus_bridge" as flexcomm node can be used as a SPI device. +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c b/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c index 0671843514ddb..cd444ea4ec673 100644 --- a/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c +++ b/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define MEMORY_REGION_SIZE_KB(SIZE) (SIZE / 1024) @@ -48,32 +48,32 @@ static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("UNMAPPED", 0, {REGION_4G | MPU_RASR_XN_Msk | P_NA_U_NA_Msk}), -#if DT_NODE_HAS_STATUS(DT_NODELABEL(itcm), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(itcm)) MPU_REGION_ENTRY("ITCM", REGION_ITCM_BASE_ADDRESS, REGION_FLASH_ATTR(REGION_ITCM_SIZE)), #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(dtcm), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dtcm)) MPU_REGION_ENTRY("DTCM", REGION_DTCM_BASE_ADDRESS, REGION_RAM_NOCACHE_ATTR(REGION_DTCM_SIZE)), #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ocram1), okay) +#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)), #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ocram2), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ocram2)) MPU_REGION_ENTRY("OCRAM2", REGION_OCRAM2_SHM_BASE_ADDRESS, REGION_RAM_NOCACHE_ATTR(REGION_OCRAM2_SHM_SIZE)), #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(hyperram0), okay) +#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)), #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(w25q128jw), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(w25q128jw)) MPU_REGION_ENTRY("QSPI_FLASH", REGION_QSPI_FLASH_BASE_ADDRESS, REGION_FLASH_ATTR(REGION_QSPI_FLASH_SIZE)), #endif diff --git a/boards/nxp/mimxrt700_evk/board.c b/boards/nxp/mimxrt700_evk/board.c index 07b66dbaf6057..85b6fc8166687 100644 --- a/boards/nxp/mimxrt700_evk/board.c +++ b/boards/nxp/mimxrt700_evk/board.c @@ -189,29 +189,29 @@ void board_early_init_hook(void) POWER_ApplyPD(); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(edma0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(edma0)) CLOCK_EnableClock(kCLOCK_Dma0); RESET_ClearPeripheralReset(kDMA0_RST_SHIFT_RSTn); edma_enable_all_request(0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(edma1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(edma1)) CLOCK_EnableClock(kCLOCK_Dma1); RESET_ClearPeripheralReset(kDMA1_RST_SHIFT_RSTn); edma_enable_all_request(1); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon)) RESET_ClearPeripheralReset(kIOPCTL0_RST_SHIFT_RSTn); CLOCK_EnableClock(kCLOCK_Iopctl0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon1)) RESET_ClearPeripheralReset(kIOPCTL1_RST_SHIFT_RSTn); CLOCK_EnableClock(kCLOCK_Iopctl1); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon2), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon2)) RESET_ClearPeripheralReset(kIOPCTL2_RST_SHIFT_RSTn); CLOCK_EnableClock(kCLOCK_Iopctl2); #endif @@ -221,203 +221,203 @@ void board_early_init_hook(void) CLOCK_SetClkDiv(kCLOCK_DivFcclk0Clk, 1U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm0)) SET_UP_FLEXCOMM_CLOCK(0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm1)) SET_UP_FLEXCOMM_CLOCK(1); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm2), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm2)) SET_UP_FLEXCOMM_CLOCK(2); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm3), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm3)) SET_UP_FLEXCOMM_CLOCK(3); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm4), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm4)) SET_UP_FLEXCOMM_CLOCK(4); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm5), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm5)) SET_UP_FLEXCOMM_CLOCK(5); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm6), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm6)) SET_UP_FLEXCOMM_CLOCK(6); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm7), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm7)) SET_UP_FLEXCOMM_CLOCK(7); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm8), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm8)) SET_UP_FLEXCOMM_CLOCK(8); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm9), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm9)) SET_UP_FLEXCOMM_CLOCK(9); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm10), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm10)) SET_UP_FLEXCOMM_CLOCK(10); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm11), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm11)) SET_UP_FLEXCOMM_CLOCK(11); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm12), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm12)) SET_UP_FLEXCOMM_CLOCK(12); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm13), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm13)) SET_UP_FLEXCOMM_CLOCK(13); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi14), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi14)) CLOCK_AttachClk(kFRO1_DIV1_to_LPSPI14); CLOCK_SetClkDiv(kCLOCK_DivLpspi14Clk, 3U); CLOCK_EnableClock(kCLOCK_LPSpi14); RESET_ClearPeripheralReset(kLPSPI14_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpi2c15), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c15)) CLOCK_AttachClk(kSENSE_BASE_to_LPI2C15); CLOCK_SetClkDiv(kCLOCK_DivLpi2c15Clk, 2U); CLOCK_EnableClock(kCLOCK_LPI2c15); RESET_ClearPeripheralReset(kLPI2C15_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi16), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi16)) CLOCK_AttachClk(kFRO0_DIV1_to_LPSPI16); CLOCK_SetClkDiv(kCLOCK_DivLpspi16Clk, 1U); CLOCK_EnableClock(kCLOCK_LPSpi16); RESET_ClearPeripheralReset(kLPSPI16_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm17), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm17)) CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM17); CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm17Clk, 4U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm18), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm18)) CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM18); CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm18Clk, 4U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm19), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm19)) CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM19); CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm19Clk, 4U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm20), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcomm20)) CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM20); CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm20Clk, 4U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexio), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexio)) CLOCK_AttachClk(kFRO0_DIV1_to_FLEXIO); CLOCK_SetClkDiv(kCLOCK_DivFlexioClk, 1U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio0)) CLOCK_EnableClock(kCLOCK_Gpio0); RESET_ClearPeripheralReset(kGPIO0_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio1)) CLOCK_EnableClock(kCLOCK_Gpio1); RESET_ClearPeripheralReset(kGPIO1_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio2), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio2)) CLOCK_EnableClock(kCLOCK_Gpio2); RESET_ClearPeripheralReset(kGPIO2_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio3), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio3)) CLOCK_EnableClock(kCLOCK_Gpio3); RESET_ClearPeripheralReset(kGPIO3_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio4), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio4)) CLOCK_EnableClock(kCLOCK_Gpio4); RESET_ClearPeripheralReset(kGPIO4_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio5), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio5)) CLOCK_EnableClock(kCLOCK_Gpio5); RESET_ClearPeripheralReset(kGPIO5_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio6), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio6)) CLOCK_EnableClock(kCLOCK_Gpio6); RESET_ClearPeripheralReset(kGPIO6_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio7), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio7)) CLOCK_EnableClock(kCLOCK_Gpio7); RESET_ClearPeripheralReset(kGPIO7_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio8), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio8)) CLOCK_EnableClock(kCLOCK_Gpio8); RESET_ClearPeripheralReset(kGPIO8_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio9), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio9)) CLOCK_EnableClock(kCLOCK_Gpio9); RESET_ClearPeripheralReset(kGPIO9_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio10), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio10)) CLOCK_EnableClock(kCLOCK_Gpio10); RESET_ClearPeripheralReset(kGPIO10_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer0)) SET_UP_CTIMER_CLOCK(0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer1), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer1)) SET_UP_CTIMER_CLOCK(1); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer2), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer2)) SET_UP_CTIMER_CLOCK(2); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer3), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer3)) SET_UP_CTIMER_CLOCK(3); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer4), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer4)) SET_UP_CTIMER_CLOCK(4); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer5), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer5)) SET_UP_CTIMER_CLOCK(5); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer6), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer6)) SET_UP_CTIMER_CLOCK(6); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer7), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer7)) SET_UP_CTIMER_CLOCK(7); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpadc0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpadc0)) CLOCK_AttachClk(kFRO1_DIV1_to_SENSE_MAIN); CLOCK_AttachClk(kSENSE_BASE_to_ADC); CLOCK_SetClkDiv(kCLOCK_DivAdcClk, 1U); #endif -#if (DT_NODE_HAS_STATUS(DT_NODELABEL(os_timer_cpu0), okay) || \ - DT_NODE_HAS_STATUS(DT_NODELABEL(os_timer_cpu1), okay)) +#if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(os_timer_cpu0)) || \ + DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(os_timer_cpu1))) CLOCK_AttachClk(kLPOSC_to_OSTIMER); CLOCK_SetClkDiv(kCLOCK_DivOstimerClk, 1U); #endif @@ -449,7 +449,7 @@ void board_early_init_hook(void) DT_PROP_BY_PHANDLE(DT_NODELABEL(usb0), clocks, clock_frequency)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc0), okay) && CONFIG_IMX_USDHC +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usdhc0)) && CONFIG_IMX_USDHC /*Make sure USDHC ram buffer has power up*/ POWER_DisablePD(kPDRUNCFG_APD_SDHC0_SRAM); POWER_DisablePD(kPDRUNCFG_PPD_SDHC0_SRAM); @@ -469,7 +469,7 @@ void board_early_init_hook(void) CLOCK_AttachClk(kLPOSC_to_WWDT0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sai0), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai0)) /* SAI clock 368.64 / 15 = 24.576MHz */ CLOCK_AttachClk(kAUDIO_PLL_PFD3_to_AUDIO_VDD2); CLOCK_AttachClk(kAUDIO_VDD2_to_SAI012); @@ -477,7 +477,7 @@ void board_early_init_hook(void) RESET_ClearPeripheralReset(kSAI0_RST_SHIFT_RSTn); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sc_timer), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sc_timer)) CLOCK_AttachClk(kFRO0_DIV6_to_SCT); #endif @@ -537,13 +537,13 @@ void board_early_init_hook(void) RESET_ClearPeripheralReset(kLCDIF_RST_SHIFT_RSTn); #endif -#if (DT_NODE_HAS_STATUS(DT_NODELABEL(i3c2), okay) || \ - DT_NODE_HAS_STATUS(DT_NODELABEL(i3c3), okay)) +#if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i3c2)) || \ + DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i3c3))) CLOCK_AttachClk(kSENSE_BASE_to_I3C23); CLOCK_SetClkDiv(kCLOCK_DivI3c23Clk, 4U); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(acmp), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(acmp)) CLOCK_EnableClock(kCLOCK_Acmp0); RESET_ClearPeripheralReset(kACMP0_RST_SHIFT_RSTn); #endif diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts index e4fd420abd2c5..623ca7c278ba9 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts +++ b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts @@ -255,15 +255,15 @@ &lpspi1 { status = "okay"; - pcs-sck-delay = <50>; - sck-pcs-delay = <50>; - transfer-delay = <50>; icm42686_0: icm42686p0@0 { compatible = "invensense,icm42686", "invensense,icm4268x"; reg = <0>; int-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; spi-max-frequency = ; + spi-cs-setup-delay-ns = <50>; + spi-cs-hold-delay-ns = <50>; + spi-interframe-delay-ns = <50>; accel-pwr-mode = ; accel-odr = ; accel-fs = ; @@ -283,15 +283,15 @@ &lpspi2 { status = "okay"; - pcs-sck-delay = <50>; - sck-pcs-delay = <50>; - transfer-delay = <50>; icm42688_0: icm42688p0@0 { compatible = "invensense,icm42688", "invensense,icm4268x"; reg = <0>; int-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; spi-max-frequency = ; + spi-cs-setup-delay-ns = <50>; + spi-cs-hold-delay-ns = <50>; + spi-interframe-delay-ns = <50>; accel-pwr-mode = ; accel-odr = ; accel-fs = ; diff --git a/boards/olimex/olimex_esp32_evb/doc/index.rst b/boards/olimex/olimex_esp32_evb/doc/index.rst index 1f5ca0033fb30..6bb5e6b810dfc 100644 --- a/boards/olimex/olimex_esp32_evb/doc/index.rst +++ b/boards/olimex/olimex_esp32_evb/doc/index.rst @@ -38,191 +38,43 @@ these reference documents: - `ESP32-EVB GitHub Repository`_ - `ESP32-WROOM32-E/UE Datasheet`_ +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features + Supported Features -****************** +================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: olimex_esp32_evb - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: olimex_esp32_evb/esp32/procpu - :goals: build - -The usual ``flash`` target will work with the ``olimex_esp32_evb`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: olimex_esp32_evb/esp32/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! olimex_esp32_evb +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants 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 ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: olimex_esp32_evb/esp32/procpu - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: olimex_esp32_evb/esp32/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _ESP32-EVB Website: - https://www.olimex.com/Products/IoT/ESP32/ESP32-EVB/open-source-hardware - -.. _ESP32-EVB Schematic: - https://github.com/OLIMEX/ESP32-EVB/raw/master/HARDWARE/REV-I/ESP32-EVB_Rev_I.pdf - -.. _ESP32-EVB GitHub Repository: - https://github.com/OLIMEX/ESP32-EVB - -.. _ESP32-WROOM32-E/UE Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf - -.. _OpenOCD ESP32: - https://github.com/espressif/openocd-esp32/releases +.. _`ESP32-EVB Website`: https://www.olimex.com/Products/IoT/ESP32/ESP32-EVB/open-source-hardware +.. _`ESP32-EVB Schematic`: https://github.com/OLIMEX/ESP32-EVB/raw/master/HARDWARE/REV-I/ESP32-EVB_Rev_I.pdf +.. _`ESP32-EVB GitHub Repository`: https://github.com/OLIMEX/ESP32-EVB +.. _`ESP32-WROOM32-E/UE Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf diff --git a/boards/others/esp32c3_supermini/doc/index.rst b/boards/others/esp32c3_supermini/doc/index.rst index cf7e1841e05dd..bcd6856c04011 100644 --- a/boards/others/esp32c3_supermini/doc/index.rst +++ b/boards/others/esp32c3_supermini/doc/index.rst @@ -5,206 +5,42 @@ Overview ESP32-C3-SUPERMINI is based on the ESP32-C3, a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, based on the open-source RISC-V architecture. This board also includes a Type-C USB Serial/JTAG port. -There may be multiple variations depending on the specific vendor. For more information a reasonably well documented version of this board can be found at `ESP32-C3-SUPERMINI`_ +There may be multiple variations depending on the specific vendor. +For more information a reasonably well documented version of this board can be found at `ESP32-C3-SUPERMINI`_ Hardware ******** -SoC Features: - -- IEEE 802.11 b/g/n-compliant -- Bluetooth 5, Bluetooth mesh -- 32-bit RISC-V single-core processor, up to 160MHz -- 384 KB ROM -- 400 KB SRAM (16 KB for cache) -- 8 KB SRAM in RTC -- 22 x programmable GPIOs -- 3 x SPI -- 2 x UART -- 1 x I2C -- 1 x I2S -- 2 x 54-bit general-purpose timers -- 3 x watchdog timers -- 1 x 52-bit system timer -- Remote Control Peripheral (RMT) -- LED PWM controller (LEDC) -- Full-speed USB Serial/JTAG controller -- General DMA controller (GDMA) -- 1 x TWAI® -- 2 x 12-bit SAR ADCs, up to 6 channels -- 1 x soc core temperature sensor - -For more information on the ESP32-C3 SOC, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference -manual at `ESP32-C3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Supported Features ================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Prerequisites -============= +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32c3_supermini - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_supermini - :goals: build - -The usual ``flash`` target will work with the ``esp32c3_supermini`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_supermini - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32c3_supermini +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -As with much custom hardware, the ESP32-C3 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_supermini - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32c3_supermini - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -212,6 +48,3 @@ References .. target-notes:: .. _`ESP32-C3-SUPERMINI`: https://www.nologo.tech/product/esp32/esp32c3SuperMini/esp32C3SuperMini.html -.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/others/icev_wireless/doc/index.rst b/boards/others/icev_wireless/doc/index.rst index f9168a1489013..e706428d1ca14 100644 --- a/boards/others/icev_wireless/doc/index.rst +++ b/boards/others/icev_wireless/doc/index.rst @@ -3,7 +3,7 @@ Overview ******** -The ICE-V Wireless is a combined ESP32C3 and iCE40 FPGA board. +The ICE-V Wireless is a combined ESP32-C3 and iCE40 FPGA board. See the `ICE-V Wireless Github Project`_ for details. @@ -25,6 +25,9 @@ For details on iCE40 hardware please refer to the following resources: * `iCE40 UltraPlus Family Datasheet`_ +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + Supported Features ================== @@ -55,179 +58,35 @@ below. :align: center :alt: ICE-V Wireless Pinout +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Programming and debugging for the ICE-V Wireless ESP32-C3 target is -incredibly easy 🎉 following the steps below. - -Building and Flashing -********************* - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: icev_wireless - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -For the :code:`Hello, world!` application, follow the instructions below. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: icev_wireless - :goals: build flash - -Open the serial monitor using the following command: - -.. code-block:: console - - $ west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! icev_wireless +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -As with much custom hardware, the ESP32C3 modules require patches to -OpenOCD that are not upstreamed. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained by running the following extension: +========= -.. code-block:: console - - west espressif install - -.. note:: - - By default, the OpenOCD will be downloaded and installed under $HOME/.espressif/tools/zephyr directory - (%USERPROFILE%/.espressif/tools/zephyr on Windows). - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: icev_wireless - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the -:zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: icev_wireless - :maybe-skip-config: - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _ICE-V Wireless Github Project: - https://github.com/ICE-V-Wireless/ICE-V-Wireless - -.. _ESP32-C3-MINI-1 Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf - -.. _ESP32-C3 Datasheet: - https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf - -.. _ESP32-C3 Technical Reference Manual: - https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf - -.. _iCE40 UltraPlus Family Datasheet: - https://www.latticesemi.com/-/media/LatticeSemi/Documents/DataSheets/iCE/iCE40-UltraPlus-Family-Data-Sheet.ashx - -.. _PMOD Specification: - https://digilent.com/reference/_media/reference/pmod/pmod-interface-specification-1_2_0.pdf +.. _`ICE-V Wireless Github Project`: https://github.com/ICE-V-Wireless/ICE-V-Wireless +.. _`ESP32-C3-MINI-1 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf +.. _`iCE40 UltraPlus Family Datasheet`: https://www.latticesemi.com/-/media/LatticeSemi/Documents/DataSheets/iCE/iCE40-UltraPlus-Family-Data-Sheet.ashx +.. _`PMOD Specification`: https://digilent.com/reference/_media/reference/pmod/pmod-interface-specification-1_2_0.pdf diff --git a/boards/raytac/an54l15q_db/Kconfig.defconfig b/boards/raytac/an54l15q_db/Kconfig.defconfig deleted file mode 100644 index 0d903ea091d05..0000000000000 --- a/boards/raytac/an54l15q_db/Kconfig.defconfig +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# Copyright (c) 2025 Raytac Corporation. -# SPDX-License-Identifier: Apache-2.0 - -# Workaround for not being able to have commas in macro arguments -DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition -DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition - -if BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS - -config HAS_BT_CTLR - default BT - -config FLASH_LOAD_OFFSET - default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -config FLASH_LOAD_SIZE - default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -# 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 - -endif # BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS diff --git a/boards/raytac/an54l15q_db/Kconfig.raytac_an54l15q_db b/boards/raytac/an54l15q_db/Kconfig.raytac_an54l15q_db deleted file mode 100644 index 58f42ef31d9d9..0000000000000 --- a/boards/raytac/an54l15q_db/Kconfig.raytac_an54l15q_db +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# Copyright (c) 2025 Raytac Corporation. -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_RAYTAC_AN54L15Q_DB - select SOC_NRF54L15_CPUAPP if BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP || BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS - select SOC_NRF54L15_CPUFLPR if BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUFLPR || \ - BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUFLPR_XIP diff --git a/boards/raytac/an54l15q_db/board.yml b/boards/raytac/an54l15q_db/board.yml deleted file mode 100644 index 08d0e2398e7bc..0000000000000 --- a/boards/raytac/an54l15q_db/board.yml +++ /dev/null @@ -1,45 +0,0 @@ -board: - name: raytac_an54l15q_db - full_name: AN54L15Q-DB - vendor: raytac - socs: - - name: nrf54l15 - variants: - - name: xip - cpucluster: cpuflpr - - name: ns - cpucluster: cpuapp -runners: - run_once: - '--recover': - - runners: - - nrfjprog - - nrfutil - run: first - groups: - - boards: - - raytac_an54l15q_db/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuflpr - - raytac_an54l15q_db/nrf54l15/cpuflpr/xip - '--erase': - - runners: - - nrfjprog - - jlink - - nrfutil - run: first - groups: - - boards: - - raytac_an54l15q_db/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuflpr - - raytac_an54l15q_db/nrf54l15/cpuflpr/xip - '--reset': - - runners: - - nrfjprog - - jlink - - nrfutil - run: last - groups: - - boards: - - raytac_an54l15q_db/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuflpr - - raytac_an54l15q_db/nrf54l15/cpuflpr/xip diff --git a/boards/raytac/an54l15q_db/doc/img/raytac_an54l15q_db.webp b/boards/raytac/an54l15q_db/doc/img/raytac_an54l15q_db.webp deleted file mode 100644 index 35ecd0b4e90da..0000000000000 Binary files a/boards/raytac/an54l15q_db/doc/img/raytac_an54l15q_db.webp and /dev/null differ diff --git a/boards/raytac/an54l15q_db/Kconfig b/boards/raytac/an54lq_db_15/Kconfig similarity index 87% rename from boards/raytac/an54l15q_db/Kconfig rename to boards/raytac/an54lq_db_15/Kconfig index 69aa54f32207a..091071d266a1e 100644 --- a/boards/raytac/an54l15q_db/Kconfig +++ b/boards/raytac/an54lq_db_15/Kconfig @@ -2,9 +2,9 @@ # Copyright (c) 2025 Raytac Corporation. # SPDX-License-Identifier: Apache-2.0 -# Raytac AN54L15Q-DB board configuration +# Raytac AN54LQ-DB-15 board configuration -if BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS +if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS DT_NRF_MPC := $(dt_nodelabel_path,nrf_mpc) @@ -28,4 +28,4 @@ config NRF_TRUSTZONE_RAM_REGION_SIZE This abstraction allows us to configure TrustZone without depending on peripheral specific symbols. -endif #BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS +endif # BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS diff --git a/boards/raytac/an54lq_db_15/Kconfig.defconfig b/boards/raytac/an54lq_db_15/Kconfig.defconfig new file mode 100644 index 0000000000000..ca2937b18b044 --- /dev/null +++ b/boards/raytac/an54lq_db_15/Kconfig.defconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# Copyright (c) 2025 Raytac Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config HW_STACK_PROTECTION + default ARCH_HAS_STACK_PROTECTION + +if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP + +config ROM_START_OFFSET + default 0x800 if BOOTLOADER_MCUBOOT + +endif # BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP + +if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS + +config BOARD_RAYTAC_AN54LQ_DB_15 + select USE_DT_CODE_PARTITION if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS + +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 + +endif # BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS diff --git a/boards/raytac/an54lq_db_15/Kconfig.raytac_an54lq_db_15 b/boards/raytac/an54lq_db_15/Kconfig.raytac_an54lq_db_15 new file mode 100644 index 0000000000000..6a590ffc75b11 --- /dev/null +++ b/boards/raytac/an54lq_db_15/Kconfig.raytac_an54lq_db_15 @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# Copyright (c) 2025 Raytac Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RAYTAC_AN54LQ_DB_15 + select SOC_NRF54L15_CPUAPP if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP || BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS + select SOC_NRF54L15_CPUFLPR if BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUFLPR || \ + BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUFLPR_XIP diff --git a/boards/raytac/an54l15q_db/board.cmake b/boards/raytac/an54lq_db_15/board.cmake similarity index 82% rename from boards/raytac/an54l15q_db/board.cmake rename to boards/raytac/an54lq_db_15/board.cmake index 368bcc9d2fee1..522a505cf5c39 100644 --- a/boards/raytac/an54l15q_db/board.cmake +++ b/boards/raytac/an54lq_db_15/board.cmake @@ -3,12 +3,12 @@ # SPDX-License-Identifier: Apache-2.0 if(CONFIG_SOC_NRF54L15_CPUAPP) - board_runner_args(jlink "--device=nRF54L15_M33" "--speed=4000") + board_runner_args(jlink "--device=nRF54L15_M33" "--speed=4000") elseif (CONFIG_SOC_NRF54L15_CPUFLPR) board_runner_args(jlink "--device=nRF54L15_RV32") endif() -if(BOARD_RAYTAC_AN54L15Q_DB_NRF54L15_CPUAPP_NS) +if(BOARD_RAYTAC_AN54LQ_DB_15_NRF54L15_CPUAPP_NS) set(TFM_PUBLIC_KEY_FORMAT "full") endif() diff --git a/boards/raytac/an54lq_db_15/board.yml b/boards/raytac/an54lq_db_15/board.yml new file mode 100644 index 0000000000000..e9d165d9b7cf9 --- /dev/null +++ b/boards/raytac/an54lq_db_15/board.yml @@ -0,0 +1,48 @@ +board: + name: raytac_an54lq_db_15 + full_name: AN54LQ-DB-15 + vendor: raytac + socs: + - name: nrf54l15 + variants: + - name: xip + cpucluster: cpuflpr + - name: ns + cpucluster: cpuapp +runners: + run_once: + '--recover': + - runners: + - nrfjprog + - nrfutil + run: first + groups: + - boards: + - raytac_an54lq_db_15/nrf54l15/cpuapp + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns + - raytac_an54lq_db_15/nrf54l15/cpuflpr + - raytac_an54lq_db_15/nrf54l15/cpuflpr/xip + '--erase': + - runners: + - nrfjprog + - jlink + - nrfutil + run: first + groups: + - boards: + - raytac_an54lq_db_15/nrf54l15/cpuapp + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns + - raytac_an54lq_db_15/nrf54l15/cpuflpr + - raytac_an54lq_db_15/nrf54l15/cpuflpr/xip + '--reset': + - runners: + - nrfjprog + - jlink + - nrfutil + run: last + groups: + - boards: + - raytac_an54lq_db_15/nrf54l15/cpuapp + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns + - raytac_an54lq_db_15/nrf54l15/cpuflpr + - raytac_an54lq_db_15/nrf54l15/cpuflpr/xip diff --git a/boards/raytac/an54lq_db_15/doc/img/raytac_an54lq_db_15.webp b/boards/raytac/an54lq_db_15/doc/img/raytac_an54lq_db_15.webp new file mode 100644 index 0000000000000..a31e8cd06341c Binary files /dev/null and b/boards/raytac/an54lq_db_15/doc/img/raytac_an54lq_db_15.webp differ diff --git a/boards/raytac/an54l15q_db/doc/index.rst b/boards/raytac/an54lq_db_15/doc/index.rst similarity index 81% rename from boards/raytac/an54l15q_db/doc/index.rst rename to boards/raytac/an54lq_db_15/doc/index.rst index 415b8ef51df39..8de880acc4f90 100644 --- a/boards/raytac/an54l15q_db/doc/index.rst +++ b/boards/raytac/an54lq_db_15/doc/index.rst @@ -1,9 +1,9 @@ -.. zephyr:board:: raytac_an54l15q_db +.. zephyr:board:: raytac_an54lq_db_15 Overview ******** -The Raytac AN54L15Q-DB demonstration board is a development board based on the Raytac AN54L15Q module. +The Raytac AN54LQ-DB-15 demonstration board is a development board based on the Raytac AN54LQ-15 module. It uses the Nordic Semiconductor nRF54L15 SoC solution. The idea is to connect all the module's pins to a 2.54mm pin header. It can easily open the verification module functions and connect with other peripheral devices and sensor pins, making it a useful tool for early software development. @@ -16,7 +16,7 @@ peripheral devices and sensor pins, making it a useful tool for early software d Hardware ******** -The Raytac AN54L15Q-DB has two crystal oscillators: +The Raytac AN54LQ-DB-15 has two crystal oscillators: * High-frequency 32 MHz crystal oscillator (HFXO) * Low-frequency 32.768 kHz crystal oscillator (LFXO) @@ -24,7 +24,7 @@ The Raytac AN54L15Q-DB has two crystal oscillators: The crystal oscillators can be configured to use either internal or external capacitors. -- Module Demo Board built by AN54L15Q +- Module Demo Board built by AN54LQ-15 - Nordic nRF54L15 SoC Solution - A recommended 3rd-party module by Nordic Semiconductor. - Intended for Bluetooth specification BT6 @@ -75,13 +75,13 @@ Programming and Debugging .. zephyr:board-supported-runners:: -Applications for the ``raytac_an54l15q_db/nrf54l15/cpuapp`` board can be +Applications for the ``raytac_an54lq_db_15/nrf54l15/cpuapp`` board can be built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. .. note:: - The ``raytac_an54l15q_db`` board does not have an on-board J-Link debug IC; + The ``raytac_an54lq_db_15`` board does not have an on-board J-Link debug IC; Use the Debug out connector of the nRF5340-DK or nRF54L15-DK to connect to the J1 or J9 SWD connector, and use SEGGER J-Link OB IF to debug. @@ -114,9 +114,9 @@ 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 Raytac AN54L15Q-DB, complete the following steps: +To build and program the sample to the Raytac AN54LQ-DB-15, complete the following steps: -First, connect the Raytac AN54L15Q-DB's J10 connector to you computer using a USB to TTL +First, connect the Raytac AN54LQ-DB-15's J10 connector to you computer using a USB to TTL converter. Then run your favorite terminal program to listen for output. .. code-block:: console @@ -130,7 +130,7 @@ Next, build the sample by running the following command: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: raytac_an54l15q_db/nrf54l15/cpuapp + :board: raytac_an54lq_db_15/nrf54l15/cpuapp :goals: build flash References @@ -138,12 +138,6 @@ References .. target-notes:: -.. _Raytac AN54L15Q-DB website: - https://www.raytac.com/product/ins.php?index_id=139 -.. _Raytac AN54L15Q-DB Specification: - https://www.raytac.com/download/index.php?index_id=60 -.. _Raytac AN54L15Q-DB Schematic: - https://www.raytac.com/upload/catalog_b/8b5e364600a9cc8c53a869733e97f07e.jpg .. _nRF54L15 website: https://www.nordicsemi.com/Products/nRF54L15 .. _nRF54L15 documentation: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/index.html .. _J-Link Software and documentation pack: diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_pinctrl.dtsi b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15-pinctrl.dtsi similarity index 100% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_pinctrl.dtsi rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15-pinctrl.dtsi diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_common.dtsi b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_common.dtsi similarity index 96% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_common.dtsi rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_common.dtsi index 98eec9d2fe7f4..cbc24af075d62 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_common.dtsi +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_common.dtsi @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "raytac_an54l15q_db_pinctrl.dtsi" +#include "raytac_an54lq_db_15-pinctrl.dtsi" / { leds { @@ -110,5 +110,9 @@ pinctrl-names = "default", "sleep"; }; +&hfxo { + startup-time-us = <854>; +}; + /* Get a node label for wi-fi spi to use in shield files */ wifi_spi: &spi22 {}; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_cpuapp_common.dtsi b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_cpuapp_common.dtsi similarity index 84% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_cpuapp_common.dtsi rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_cpuapp_common.dtsi index 2029662e892ff..328397d3157e8 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_cpuapp_common.dtsi +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_cpuapp_common.dtsi @@ -7,7 +7,7 @@ /* This file is common to the secure and non-secure domain */ -#include "raytac_an54l15q_db_common.dtsi" +#include "raytac_an54lq_db_15_common.dtsi" / { chosen { @@ -19,6 +19,12 @@ zephyr,flash-controller = &rram_controller; zephyr,flash = &cpuapp_rram; zephyr,ieee802154 = &ieee802154; + zephyr,boot-mode = &boot_mode0; + }; + + aliases { + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; }; }; @@ -28,7 +34,7 @@ &lfxo { load-capacitors = "internal"; - load-capacitance-femtofarad = <15500>; + load-capacitance-femtofarad = <17000>; }; &hfxo { @@ -56,6 +62,10 @@ status = "okay"; }; +&nfct { + status = "okay"; +}; + &gpio0 { status = "okay"; }; @@ -92,6 +102,16 @@ status = "okay"; }; +&gpregret1 { + status = "okay"; + + boot_mode0: boot_mode@0 { + compatible = "zephyr,retention"; + status = "okay"; + reg = <0x0 0x1>; + }; +}; + &spi00 { status = "okay"; cs-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts similarity index 70% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.dts rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts index d347ef16ac14b..7fa21fafd0216 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts @@ -8,12 +8,11 @@ /dts-v1/; #include -#include "raytac_an54l15q_db_cpuapp_common.dtsi" +#include "raytac_an54lq_db_15_cpuapp_common.dtsi" / { - compatible = "raytac,an54l15q_db_nrf54l15-cpuapp"; - - model = "Raytac AN54L15Q-DB nRF54L15 Application MCU"; + compatible = "raytac,an54lq_db_15_nrf54l15-cpuapp"; + model = "Raytac AN54LQ-DB-15 nRF54L15 Application MCU"; chosen { zephyr,code-partition = &slot0_partition; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.yaml b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.yaml similarity index 75% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.yaml rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.yaml index 7a5e9a84f960c..6676ea96a29e1 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp.yaml +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.yaml @@ -2,13 +2,12 @@ # Copyright (c) 2024 Raytac Corporation. # SPDX-License-Identifier: Apache-2.0 -identifier: raytac_an54l15q_db/nrf54l15/cpuapp -name: Raytac-AN54L15Q-DB-nRF54l15-Application +identifier: raytac_an54lq_db_15/nrf54l15/cpuapp +name: Raytac-AN54LQ-DB-15-nRF54l15-Application type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 188 @@ -16,6 +15,7 @@ flash: 1428 supported: - adc - counter + - dmic - gpio - i2c - pwm diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_defconfig b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_defconfig similarity index 81% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_defconfig rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_defconfig index 299496280d227..d8efa7c1be2b9 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_defconfig +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_defconfig @@ -14,6 +14,3 @@ CONFIG_GPIO=y # Enable MPU CONFIG_ARM_MPU=y - -# Enable hardware stack protection -CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts similarity index 90% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.dts rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts index d6395d7fd71a3..8582e62d2f238 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts @@ -10,11 +10,11 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 #include -#include "raytac_an54l15q_db_cpuapp_common.dtsi" +#include "raytac_an54lq_db_15_cpuapp_common.dtsi" / { - compatible = "raytac,raytac_an54l15q_db_nrf54l15-cpuapp"; - model = "Raytac AN54L15Q-DB nRF54L15 Application MCU"; + compatible = "raytac,raytac_an54lq_db_15_nrf54l15-cpuapp"; + model = "Raytac AN54LQ-DB-15 nRF54L15 Application MCU"; chosen { zephyr,code-partition = &slot0_ns_partition; @@ -61,6 +61,7 @@ &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; + current-speed = <115200>; pinctrl-0 = <&uart30_default>; pinctrl-1 = <&uart30_sleep>; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.yaml b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.yaml similarity index 74% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.yaml rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.yaml index 8662a82fad603..2f26145805c75 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns.yaml +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.yaml @@ -2,8 +2,8 @@ # Copyright (c) 2025 Raytac Corporation. # SPDX-License-Identifier: Apache-2.0 -identifier: raytac_an54l15q_db/nrf54l15/cpuapp/ns -name: Raytac-AN54L15Q-DB-nRF54l15-Application-Non-Secure +identifier: raytac_an54lq_db_15/nrf54l15/cpuapp/ns +name: Raytac-AN54LQ-DB-15-nRF54l15-Application-Non-Secure type: mcu arch: arm toolchain: diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns_defconfig b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns_defconfig similarity index 97% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns_defconfig rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns_defconfig index 0df2316b45024..c364a395a2479 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuapp_ns_defconfig +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns_defconfig @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_ARM_MPU=y -CONFIG_HW_STACK_PROTECTION=y CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.dts similarity index 86% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.dts rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.dts index d7c1a0cbbe007..582bbf6d7c3a1 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.dts @@ -7,11 +7,11 @@ /dts-v1/; #include -#include "raytac_an54l15q_db_common.dtsi" +#include "raytac_an54lq_db_15_common.dtsi" / { - model = "Raytac AN54L15Q-DB nRF54L15 FLPR MCU"; - compatible = "raytac,raytac_an54l15q_db_nrf54l15-cpuflpr"; + model = "Raytac AN54LQ-DB-15 nRF54L15 FLPR MCU"; + compatible = "raytac,raytac_an54lq_db_15_nrf54l15-cpuflpr"; chosen { zephyr,console = &uart30; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.yaml b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.yaml similarity index 68% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.yaml rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.yaml index 3a4f07f907e84..02bbe34aaaf52 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr.yaml +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr.yaml @@ -2,8 +2,8 @@ # Copyright (c) 2025 Raytac Corporation. # SPDX-License-Identifier: Apache-2.0 -identifier: raytac_an54l15q_db/nrf54l15/cpuflpr -name: Raytac-AN54L15Q-DB-nRF54L15-Fast-Lightweight-Peripheral-Processor +identifier: raytac_an54lq_db_15/nrf54l15/cpuflpr +name: Raytac-AN54LQ-DB-15-nRF54L15-Fast-Lightweight-Peripheral-Processor type: mcu arch: riscv toolchain: diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_defconfig b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_defconfig similarity index 100% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_defconfig rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_defconfig diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.dts similarity index 81% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.dts rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.dts index 3e700be42dae4..7509267b8262c 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.dts @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "raytac_an54l15q_db_nrf54l15_cpuflpr.dts" +#include "raytac_an54lq_db_15_nrf54l15_cpuflpr.dts" &cpuflpr_sram { reg = <0x2002f000 DT_SIZE_K(68)>; diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.yaml b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.yaml similarity index 65% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.yaml rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.yaml index ee996f4a9a1db..5f2bf3fe9ac27 100644 --- a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.yaml +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.yaml @@ -2,8 +2,8 @@ # Copyright (c) 2025 Raytac Corporation. # SPDX-License-Identifier: Apache-2.0 -identifier: raytac_an54l15q_db/nrf54l15/cpuflpr/xip -name: Raytac-AN54L15Q-DB-nRF54L15-Fast-Lightweight-Peripheral-Processor (RRAM XIP) +identifier: raytac_an54lq_db_15/nrf54l15/cpuflpr/xip +name: Raytac-AN54LQ-DB-15-nRF54L15-Fast-Lightweight-Peripheral-Processor (RRAM XIP) type: mcu arch: riscv toolchain: diff --git a/boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip_defconfig b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip_defconfig similarity index 100% rename from boards/raytac/an54l15q_db/raytac_an54l15q_db_nrf54l15_cpuflpr_xip_defconfig rename to boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip_defconfig diff --git a/boards/renesas/rza3ul_smarc/Kconfig.defconfig b/boards/renesas/rza3ul_smarc/Kconfig.defconfig new file mode 100644 index 0000000000000..8df5fc7719245 --- /dev/null +++ b/boards/renesas/rza3ul_smarc/Kconfig.defconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config FLASH_LOAD_OFFSET + default $(dt_nodelabel_reg_addr_hex,header) diff --git a/boards/renesas/rza3ul_smarc/rza3ul_smarc-pinctrl.dtsi b/boards/renesas/rza3ul_smarc/rza3ul_smarc-pinctrl.dtsi index 073e7ebb17181..61db6fc06b1a5 100644 --- a/boards/renesas/rza3ul_smarc/rza3ul_smarc-pinctrl.dtsi +++ b/boards/renesas/rza3ul_smarc/rza3ul_smarc-pinctrl.dtsi @@ -34,4 +34,13 @@ input-enable; }; }; + + /omit-if-no-ref/ spi0_pins: spi0 { + spi0-pinmux { + pinmux = , /* CK */ + , /* MOSI */ + , /* MISO */ + ; /* SSL */ + }; + }; }; diff --git a/boards/renesas/rza3ul_smarc/rza3ul_smarc.dts b/boards/renesas/rza3ul_smarc/rza3ul_smarc.dts index 1517949346cd3..e4901c6a24f46 100644 --- a/boards/renesas/rza3ul_smarc/rza3ul_smarc.dts +++ b/boards/renesas/rza3ul_smarc/rza3ul_smarc.dts @@ -18,7 +18,7 @@ chosen { zephyr,sram = &ddr; - zephyr,flash = &spi_flash; + zephyr,flash = &at25ql128a; zephyr,console = &scif0; zephyr,shell-uart = &scif0; zephyr,code-partition = &slot0_partition; @@ -40,28 +40,6 @@ zephyr,memory-region = "SRAM"; }; - spi_flash: memory@20020000 { - compatible = "mmio-sram"; - reg = <0x20020000 (DT_SIZE_M(16) - 0x20000)>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - header: partition@0 { - label = "header"; - reg = <0x00000000 0x200>; - read-only; - }; - - slot0_partition: partition@200 { - label = "image-0"; - reg = <0x00000200 (DT_SIZE_M(16) - 0x20200)>; - read-only; - }; - }; - }; }; &scif0 { @@ -81,6 +59,47 @@ status = "okay"; }; +&spi0 { + pinctrl-0 = <&spi0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + &wdt0 { status = "okay"; }; + +&spibsc { + status = "okay"; + + at25ql128a: qspi-nor-flash@20000000 { + compatible = "renesas,rz-qspi-spibsc"; + reg = <0x20000000 DT_SIZE_M(16)>; /* 128 Mbits */ + write-block-size = <1>; + erase-block-size = <4096>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + reserved: partition@0 { + reg = <0x00000000 0x20000>; + read-only; + }; + + header: partition@20000 { + label = "header"; + reg = <0x00020000 0x200>; + read-only; + }; + + slot0_partition: partition@20200 { + label = "image-0"; + reg = <0x00020200 (DT_SIZE_M(16) - 0x20200)>; + read-only; + }; + }; + }; +}; diff --git a/boards/renesas/rza3ul_smarc/rza3ul_smarc.yaml b/boards/renesas/rza3ul_smarc/rza3ul_smarc.yaml index 13c9e23ca371e..2fe827e979617 100644 --- a/boards/renesas/rza3ul_smarc/rza3ul_smarc.yaml +++ b/boards/renesas/rza3ul_smarc/rza3ul_smarc.yaml @@ -11,6 +11,7 @@ supported: - pwm - adc - i2c + - spi - counter - watchdog testing: diff --git a/boards/renesas/rzn2l_rsk/rzn2l_rsk-pinctrl.dtsi b/boards/renesas/rzn2l_rsk/rzn2l_rsk-pinctrl.dtsi index 2b338491a4bb3..9d0515ec0604f 100644 --- a/boards/renesas/rzn2l_rsk/rzn2l_rsk-pinctrl.dtsi +++ b/boards/renesas/rzn2l_rsk/rzn2l_rsk-pinctrl.dtsi @@ -48,4 +48,27 @@ ; /* SDA */ }; }; + + /omit-if-no-ref/ spi2_pins: spi2 { + spi2-pinmux { + pinmux = , /* CK2 */ + , /* MOSI2 */ + , /* MISO2 */ + ; /* SSL20 */ + }; + }; + + /omit-if-no-ref/ xspi0_default: xspi0_default { + xspi0-pinmux { + pinmux = , /* XSPI0_CKP */ + , /* XSPI0_CKN */ + , /* XSPI0_CS0 */ + , /* XSPI0_IO0 */ + , /* XSPI0_IO1 */ + , /* XSPI0_IO2 */ + , /* XSPI0_IO3 */ + , /* XSPI0_RESET0 */ + ; /* XSPI0_RSTO0 */ + }; + }; }; diff --git a/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts b/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts index da0e1eec63c8b..c08c80df0903f 100644 --- a/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts +++ b/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts @@ -14,7 +14,7 @@ chosen { zephyr,sram = &atcm; - zephyr,flash = &xspi0_cs0; + zephyr,flash = &mx25u51245g; zephyr,code-partition = &slot0_partition; zephyr,console = &uart0; zephyr,shell-uart = &uart0; @@ -125,6 +125,26 @@ status = "okay"; }; +&spi2 { + pinctrl-0 = <&spi2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + &wdt0 { status = "okay"; }; + +&xspi0 { + pinctrl-0 = <&xspi0_default>; + pinctrl-names = "default"; + status = "okay"; + + mx25u51245g: qspi-nor-flash@60000000 { + compatible = "renesas,rz-qspi-xspi"; + reg = <0x60000000 DT_SIZE_M(64)>; /* 512 Mbits */ + write-block-size = <1>; + erase-block-size = <4096>; + status = "okay"; + }; +}; diff --git a/boards/renesas/rzn2l_rsk/rzn2l_rsk.yaml b/boards/renesas/rzn2l_rsk/rzn2l_rsk.yaml index 86a27b0da0985..22e2fc3213b6f 100644 --- a/boards/renesas/rzn2l_rsk/rzn2l_rsk.yaml +++ b/boards/renesas/rzn2l_rsk/rzn2l_rsk.yaml @@ -11,5 +11,6 @@ supported: - adc - i2c - counter + - spi - watchdog vendor: renesas diff --git a/boards/renesas/rzt2m_rsk/rzt2m_rsk-pinctrl.dtsi b/boards/renesas/rzt2m_rsk/rzt2m_rsk-pinctrl.dtsi index 9b48e978a3cce..63a971e8989d7 100644 --- a/boards/renesas/rzt2m_rsk/rzt2m_rsk-pinctrl.dtsi +++ b/boards/renesas/rzt2m_rsk/rzt2m_rsk-pinctrl.dtsi @@ -40,4 +40,28 @@ ; /* SDA */ }; }; + + /omit-if-no-ref/ spi2_pins: spi2 { + spi2-pinmux { + pinmux = , /* CK2 */ + , /* MOSI2 */ + , /* MISO2 */ + ; /* SSL20 */ + }; + }; + + /omit-if-no-ref/ xspi0_default: xspi0_default { + xspi0-pinmux { + pinmux = , /* XSPI0_CKP */ + , /* XSPI0_CKN */ + , /* XSPI0_CS0 */ + , /* XSPI0_IO0 */ + , /* XSPI0_IO1 */ + , /* XSPI0_IO2 */ + , /* XSPI0_IO3 */ + , /* XSPI0_RESET0 */ + ; /* XSPI0_RSTO0 */ + }; + }; + }; diff --git a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts index c64faaaa656d9..6606eb1995083 100644 --- a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts +++ b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts @@ -16,7 +16,7 @@ chosen { zephyr,sram = &cpu0_atcm; - zephyr,flash = &xspi0_cs0; + zephyr,flash = &mx25u51245g; zephyr,code-partition = &slot0_partition; zephyr,console = &uart0; zephyr,shell-uart = &uart0; @@ -122,6 +122,26 @@ status = "okay"; }; +&spi2 { + pinctrl-0 = <&spi2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + &wdt0 { status = "okay"; }; + +&xspi0 { + pinctrl-0 = <&xspi0_default>; + pinctrl-names = "default"; + status = "okay"; + + mx25u51245g: qspi-nor-flash@60000000 { + compatible = "renesas,rz-qspi-xspi"; + reg = <0x60000000 DT_SIZE_M(64)>; /* 512 Mbits */ + write-block-size = <1>; + erase-block-size = <4096>; + status = "okay"; + }; +}; diff --git a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.yaml b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.yaml index 8f5ff3ea5a9fb..9ad2cc1ba7cff 100644 --- a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.yaml +++ b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.yaml @@ -16,5 +16,6 @@ supported: - adc - i2c - counter + - spi - watchdog vendor: renesas diff --git a/boards/renesas/rzv2l_smarc/rzv2l_smarc-pinctrl.dtsi b/boards/renesas/rzv2l_smarc/rzv2l_smarc-pinctrl.dtsi index 0e0b91c4738f1..ed7e4d66695e4 100644 --- a/boards/renesas/rzv2l_smarc/rzv2l_smarc-pinctrl.dtsi +++ b/boards/renesas/rzv2l_smarc/rzv2l_smarc-pinctrl.dtsi @@ -32,4 +32,13 @@ ; /* SCL */ }; }; + + /omit-if-no-ref/ spi1_pins: spi1 { + spi1-pinmux { + pinmux = , /* CK */ + , /* MOSI */ + , /* MISO */ + ; /* SSL */ + }; + }; }; diff --git a/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.dts b/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.dts index 06534843bab28..b71ef82061dc9 100644 --- a/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.dts +++ b/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.dts @@ -43,3 +43,9 @@ pinctrl-names = "default"; status = "okay"; }; + +&spi1 { + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.yaml b/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.yaml index b69c99cd18550..cf8105de9cc45 100644 --- a/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.yaml +++ b/boards/renesas/rzv2l_smarc/rzv2l_smarc_r9a07g054l23gbg_cm33.yaml @@ -11,6 +11,7 @@ supported: - pwm - adc - i2c + - spi - counter - mbox vendor: renesas diff --git a/boards/seeed/seeeduino_xiao/doc/index.rst b/boards/seeed/seeeduino_xiao/doc/index.rst index 64289cebf1d65..a216a4748af5e 100644 --- a/boards/seeed/seeeduino_xiao/doc/index.rst +++ b/boards/seeed/seeeduino_xiao/doc/index.rst @@ -127,11 +127,6 @@ References .. target-notes:: -.. _Seeeduino XIAO wiki: - https://wiki.seeedstudio.com/Seeeduino-XIAO/ - -.. _pinouts: - https://wiki.seeedstudio.com/Seeeduino-XIAO/#hardware-overview - -.. _schematic: - https://wiki.seeedstudio.com/Seeeduino-XIAO/#resources +.. _`Seeeduino XIAO wiki`: https://wiki.seeedstudio.com/Seeeduino-XIAO/ +.. _`pinouts`: https://wiki.seeedstudio.com/Seeeduino-XIAO/#hardware-overview +.. _`schematic`: https://wiki.seeedstudio.com/Seeeduino-XIAO/#resources diff --git a/boards/seeed/xiao_esp32c3/doc/index.rst b/boards/seeed/xiao_esp32c3/doc/index.rst index ef8bdb5a86e11..84ea2d13a7bb3 100644 --- a/boards/seeed/xiao_esp32c3/doc/index.rst +++ b/boards/seeed/xiao_esp32c3/doc/index.rst @@ -3,7 +3,7 @@ Overview ******** -Seeed Studio XIAO ESP32C3 is an IoT mini development board based on the +Seeed Studio XIAO ESP32-C3 is an IoT mini development board based on the Espressif ESP32-C3 WiFi/Bluetooth dual-mode chip. For more details see the `Seeed Studio XIAO ESP32C3`_ wiki page. @@ -16,6 +16,9 @@ has an USB-C port for programming and debugging, integrated battery charging and an U.FL external antenna connector. It is based on a standard XIAO 14 pin pinout. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + Supported Features ================== @@ -32,157 +35,28 @@ The board uses a standard XIAO pinout, the default pin mapping is the following: XIAO ESP32C3 Pinout -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: xiao_esp32c3 - :goals: build - :west-args: --sysbuild - :compact: +Programming and Debugging +************************* -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by Sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -For the :code:`Hello, world!` application, follow the instructions below. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c3 - :goals: build flash - -Since the Zephyr console is by default on the ``usb_serial`` device, we use -the espressif monitor to view. - -.. code-block:: console - - $ west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! xiao_esp32c3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants 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 ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c3 - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c3 - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -190,4 +64,3 @@ References .. target-notes:: .. _`Seeed Studio XIAO ESP32C3`: https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/seeed/xiao_esp32c6/doc/index.rst b/boards/seeed/xiao_esp32c6/doc/index.rst index a1b93cc9c42dc..06aeaf8ed9b45 100644 --- a/boards/seeed/xiao_esp32c6/doc/index.rst +++ b/boards/seeed/xiao_esp32c6/doc/index.rst @@ -18,11 +18,17 @@ Bluetooth 5.3 (LE) and the 802.15.4 protocol. It has an USB-C port for programmi and debugging, integrated battery charging and an U.FL external antenna connector. It is based on a standard XIAO 14 pin pinout. +.. include:: ../../../espressif/common/soc-esp32c6-features.rst + :start-after: espressif-soc-esp32c6-features + Supported Features ================== .. zephyr:board-supported-hw:: +Connections and IOs +=================== + The board uses a standard XIAO pinout, the default pin mapping is the following: .. figure:: img/xiao_esp32c6_pinout.webp @@ -31,170 +37,28 @@ The board uses a standard XIAO pinout, the default pin mapping is the following: XIAO ESP32C6 Pinout -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the EPS32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: xiao_esp32c6/esp32c6/hpcore - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32-C6 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c6/esp32c6/hpcore - :goals: build - -The usual ``flash`` target will work with the ``xiao_esp32c6`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c6/esp32c6/hpcore - :goals: flash - -Since the Zephyr console is by default on the ``usb_serial`` device, we use -the espressif monitor to view. - -.. code-block:: console - - $ west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! xiao_esp32c6/esp32c6/hpcore +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -As with much custom hardware, the ESP32-C6 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c6/esp32c6/hpcore - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32c6/esp32c6/hpcore - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -202,6 +66,3 @@ References .. target-notes:: .. _`Seeed Studio XIAO ESP32C6`: https://wiki.seeedstudio.com/xiao_esp32c6_getting_started/ -.. _`ESP32-C6 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf -.. _`ESP32-C6 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/seeed/xiao_esp32s3/doc/index.rst b/boards/seeed/xiao_esp32s3/doc/index.rst index 1aacfe17bc44e..8a6976ea7f17f 100644 --- a/boards/seeed/xiao_esp32s3/doc/index.rst +++ b/boards/seeed/xiao_esp32s3/doc/index.rst @@ -35,6 +35,9 @@ RF module, and numerous peripherals. Additionally, Sense variant integrates a OV2640 camera sensor, microphone and sdcard slot. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features + Supported Features ================== @@ -51,173 +54,31 @@ The board uses a standard XIAO pinout, the default pin mapping is the following: XIAO ESP32S3 and XIAO ESP32S3 Sense Pinout -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: xiao_esp32s3 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). +Programming and Debugging +************************* -.. tabs:: - - .. group-tab:: XIAO ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32s3/esp32s3/procpu - :goals: build - - .. group-tab:: XIAO ESP32S3 Sense - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32s3/esp32s3/procpu/sense - :goals: build - -The usual ``flash`` target will work with the ``xiao_esp32s3`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. tabs:: - - .. group-tab:: XIAO ESP32S3 - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32s3/esp32s3/procpu - :goals: flash - - .. group-tab:: XIAO ESP32S3 Sense - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: xiao_esp32s3/esp32s3/procpu/sense - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! xiao_esp32s3 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. +========= -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any additional chip. Only an USB cable connected to the D+/D- pins is necessary. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. +Sample applications +******************* .. tabs:: @@ -259,5 +120,3 @@ References .. target-notes:: .. _`Seeed Studio XIAO ESP32S3`: https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/ -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_common.dtsi b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_common.dtsi index 595cc808c6394..93c9979a3628f 100644 --- a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_common.dtsi +++ b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_common.dtsi @@ -10,7 +10,7 @@ compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; label = "LED 0"; }; }; diff --git a/boards/shields/adafruit_lps22/Kconfig.shield b/boards/shields/adafruit_lps22/Kconfig.shield new file mode 100644 index 0000000000000..f89d32183b34e --- /dev/null +++ b/boards/shields/adafruit_lps22/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ADAFRUIT_LPS22 + def_bool $(shields_list_contains,adafruit_lps22) diff --git a/boards/shields/adafruit_lps22/adafruit_lps22.overlay b/boards/shields/adafruit_lps22/adafruit_lps22.overlay new file mode 100644 index 0000000000000..500ac3a819e97 --- /dev/null +++ b/boards/shields/adafruit_lps22/adafruit_lps22.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pressure-sensor = &adafruit_lps22; + }; +}; + +&zephyr_i2c { + status = "okay"; + + adafruit_lps22: lps22@5d { + compatible = "st,lps22hb-press"; + status = "okay"; + reg = <0x5d>; + }; +}; diff --git a/boards/shields/adafruit_lps22/doc/adafruit_lps22.webp b/boards/shields/adafruit_lps22/doc/adafruit_lps22.webp new file mode 100644 index 0000000000000..928a8d793c77b Binary files /dev/null and b/boards/shields/adafruit_lps22/doc/adafruit_lps22.webp differ diff --git a/boards/shields/adafruit_lps22/doc/index.rst b/boards/shields/adafruit_lps22/doc/index.rst new file mode 100644 index 0000000000000..f52b5d0540d82 --- /dev/null +++ b/boards/shields/adafruit_lps22/doc/index.rst @@ -0,0 +1,66 @@ +.. _adafruit_lps22: + +Adafruit LPS22 Shield +##################### + +Overview +******** + +The `Adafruit LPS22 Pressure Sensor Shield`_ features +a `ST Microelectronics LPS22HB Pressure Sensor`_ and two STEMMA QT connectors. +It measures air pressure and temperature. + +.. figure:: adafruit_lps22.webp + :align: center + :alt: Adafruit LPS22 Shield + + Adafruit LPS22 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 | ++==============+=====================================+ +| SCK | LPS22 I2C SCL | ++--------------+-------------------------------------+ +| SDI | LPS22 I2C SDA | ++--------------+-------------------------------------+ +| SDO | LPS22 I2C address adjust | ++--------------+-------------------------------------+ +| CS | LPS22 mode. Pulled high to use I2C. | ++--------------+-------------------------------------+ +| INT | LPS22 interrupt out | ++--------------+-------------------------------------+ + +See :dtcompatible:`st,lps22hb-press` for documentation on how to adjust the +devicetree file. + + +Programming +*********** + +Set ``--shield adafruit_lps22`` when you invoke ``west build``. For example +when running the :zephyr:code-sample:`pressure_polling` pressure and temperature sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/pressure_polling + :board: adafruit_feather_rp2040 + :shield: adafruit_lps22 + :goals: build flash + +.. _Adafruit LPS22 Pressure Sensor Shield: + https://learn.adafruit.com/adafruit-lps25-pressure-sensor + +.. _ST Microelectronics LPS22HB Pressure Sensor: + https://www.st.com/en/mems-and-sensors/lps22hb.html diff --git a/boards/shields/adafruit_lps22/shield.yml b/boards/shields/adafruit_lps22/shield.yml new file mode 100644 index 0000000000000..4655afd3cc838 --- /dev/null +++ b/boards/shields/adafruit_lps22/shield.yml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2025, Jonas Berg + +shield: + name: adafruit_lps22 + full_name: Adafruit LPS22 Pressure Sensor Shield + vendor: adafruit + supported_features: + - sensor diff --git a/boards/shields/canis_canpico/Kconfig.shield b/boards/shields/canis_canpico/Kconfig.shield new file mode 100644 index 0000000000000..45f2cd41f29e2 --- /dev/null +++ b/boards/shields/canis_canpico/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Steve Boylan +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_CANIS_CANPICO + def_bool $(shields_list_contains,canis_canpico) diff --git a/boards/shields/canis_canpico/canis_canpico.overlay b/boards/shields/canis_canpico/canis_canpico.overlay new file mode 100644 index 0000000000000..8a5d069f3255b --- /dev/null +++ b/boards/shields/canis_canpico/canis_canpico.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Steve Boylan + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pico_spi { + status = "okay"; + cs-gpios = <&pico_header 6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi1_canpico>; + pinctrl-names = "default"; + + mcp251xfd_canis_canpico: can@0 { + compatible = "microchip,mcp251xfd"; + spi-max-frequency = <1000000>; + int-gpios = <&pico_header 5 GPIO_ACTIVE_LOW>; + status = "okay"; + reg = <0x0>; + osc-freq = <16000000>; + + can-transceiver { + max-bitrate = <1000000>; + }; + }; +}; + +&pinctrl { + spi1_canpico: spi1_canpico { + group1 { + pinmux = , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; +}; + +/ { + chosen { + zephyr,canbus = &mcp251xfd_canis_canpico; + }; +}; diff --git a/boards/shields/canis_canpico/doc/canis_canpico.webp b/boards/shields/canis_canpico/doc/canis_canpico.webp new file mode 100644 index 0000000000000..f3fb8e0408f59 Binary files /dev/null and b/boards/shields/canis_canpico/doc/canis_canpico.webp differ diff --git a/boards/shields/canis_canpico/doc/index.rst b/boards/shields/canis_canpico/doc/index.rst new file mode 100644 index 0000000000000..7461e38861c2d --- /dev/null +++ b/boards/shields/canis_canpico/doc/index.rst @@ -0,0 +1,165 @@ +.. _canis_canpico: + +Canis Labs CANPico Shield +######################### + +Overview +******** + +The Canis Labs CANPico shield supports the Microchip MCP2517FD or MCP2518FD +stand-alone CAN controller and Microchip MCP2562FD high-speed CAN FD +transceiver. The CANPico is a carrier board in a ‘sock’ format for a +Raspberry Pi Pico family. + +.. figure:: canis_canpico.webp + :align: center + :alt: Canis_Labs_CANPico_SHIELD + +Hardware +******** + +- MCP2517/2518FD + + - External CAN FD Controller with Serial Peripheral Interface (SPI) + - Arbitration Bit Rate up to 1 Mbps + - Data Bit Rate up to 8 Mbps + - CAN FD Controller modes: CAN 2.0B Mode or Mixed CAN 2.0B and CAN FD Mode + - Conforms to ISO 11898-1:2015 + +- MCP2562FD + + - Optimized for CAN FD (Flexible Data rate) at 2, 5 and 8 Mbps Operation + - Maximum Propagation Delay: 120 ns + - Implements ISO-11898-2 and ISO-11898-5 Standard Physical Layer Requirements + - Very Low Standby Current (5 µA, typical) + - VIO Supply Pin to Interface Directly to CAN Controllers and Microcontrollers with 1.8V to 5.5V I/O + +- Connectivity + + - Jumper header to enable a 120W CAN bus termination resistor + - Jumper header to enable the CAN TX line to the transceiver + - Screw terminal connector to CAN bus + - CAN controller interrupt and Start-of-Frame inputs to GPIO pins + - Direct access via GPIO pins to the CAN transceiver Tx and Rx pins + - Test instrument header (for an oscilloscope or logic analyzer) + ++-------+-----------------------+---------------------------+ +| Name | Function | Usage | ++=======+=======================+===========================+ +| GP0 | None | | ++-------+-----------------------+---------------------------+ +| GP1 | None | | ++-------+-----------------------+---------------------------+ +| GP2 | TRIG | Programmable trigger | ++-------+-----------------------+---------------------------+ +| GP3 | STBY | Transceiver standby | ++-------+-----------------------+---------------------------+ +| GP4 | SOF | Clock/SOF | ++-------+-----------------------+---------------------------+ +| GP5 | IRQ | Transceiver interrupt | ++-------+-----------------------+---------------------------+ +| GP6 | None | SPI CS | ++-------+-----------------------+---------------------------+ +| GP7 | None | | ++-------+-----------------------+---------------------------+ +| GP8 | SPI1_Rx | SPI Rx | ++-------+-----------------------+---------------------------+ +| GP9 | None | | ++-------+-----------------------+---------------------------+ +| GP10 | SPI1_SCK | SPI clock | ++-------+-----------------------+---------------------------+ +| GP11 | SPI1_Tx | SPI Tx | ++-------+-----------------------+---------------------------+ +| GP12 | None | | ++-------+-----------------------+---------------------------+ +| GP13 | None | | ++-------+-----------------------+---------------------------+ +| GP14 | None | | ++-------+-----------------------+---------------------------+ +| GP15 | None | | ++-------+-----------------------+---------------------------+ +| GP16 | None | | ++-------+-----------------------+---------------------------+ +| GP17 | None | | ++-------+-----------------------+---------------------------+ +| GP18 | None | | ++-------+-----------------------+---------------------------+ +| GP19 | None | | ++-------+-----------------------+---------------------------+ +| GP20 | None | | ++-------+-----------------------+---------------------------+ +| GP21 | Rx | CAN Rx data | ++-------+-----------------------+---------------------------+ +| GP22 | Tx | CAN Tx data | ++-------+-----------------------+---------------------------+ +| GP23 | None | | ++-------+-----------------------+---------------------------+ +| GP24 | None | | ++-------+-----------------------+---------------------------+ +| GP25 | None | | ++-------+-----------------------+---------------------------+ +| GP26 | None | | ++-------+-----------------------+---------------------------+ +| GP27 | None | | ++-------+-----------------------+---------------------------+ +| GP28 | None | | ++-------+-----------------------+---------------------------+ + +- Test header + + - TRIG: Programmable trigger output + - Tx: Logic-level CAN Tx data + - Rx: Logic-level CAN Rx data + - H: Raw CAN-Hi signal + - L: Raw CAN-Low signal + +- Power Supply + + - 3.3V ~ 5V + +- Components + + - Tx Enable jumper + - 120 ohm terminator jumper + +For more information about the Canis Labs CANPico shield: + +- `Canis Labs Website`_ +- `CANPico CAN Bus Shield`_ +- `MCP2517FD Datasheet`_ +- `MCP2518FD Datasheet`_ +- `MCP2562FD Datasheet`_ + +Programming +*********** + +Set ``--shield canis-canpico`` when you invoke ``west build`` or ``cmake`` +in your Zephyr application. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/can/counter + :tool: all + :board: rpi_pico + :shield: canpico + :goals: build flash + +.. _Canis Labs Website: + https://canislabs.com/ + +.. _CANPico CAN Bus Shield: + https://canislabs.com/canpico/ + +.. _MCP2517FD: + https://www.microchip.com/en-us/product/MCP2518FD + +.. _MCP2517FD Datasheet: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/MCP2517FD-External-CAN-FD-Controller-with-SPI-Interface-20005688B.pdf + +.. _MCP2518FD: + https://www.microchip.com/en-us/product/MCP2518FD + +.. _MCP2518FD Datasheet: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/External-CAN-FD-Controller-with-SPI-Interface-DS20006027B.pdf + +.. _MCP2562FD Datasheet: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005284A.pdf diff --git a/boards/shields/canis_canpico/shield.yml b/boards/shields/canis_canpico/shield.yml new file mode 100644 index 0000000000000..2b0b30c04aa1d --- /dev/null +++ b/boards/shields/canis_canpico/shield.yml @@ -0,0 +1,6 @@ +shields: + - name: canis_canpico + full_name: Canis Labs CANPico + vendor: canis + supported_features: + - can diff --git a/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig b/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig index ce0297675d285..db13e996f1f41 100644 --- a/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig +++ b/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig @@ -14,4 +14,7 @@ config VIDEO_STM32_DCMIPP_SENSOR_WIDTH config VIDEO_STM32_DCMIPP_SENSOR_HEIGHT default 1944 +config GPIO_HOGS + default y + endif # VIDEO_STM32_DCMIPP diff --git a/boards/shields/st_b_cams_imx_mb1854/st_b_cams_imx_mb1854.overlay b/boards/shields/st_b_cams_imx_mb1854/st_b_cams_imx_mb1854.overlay index 5399867bfc737..0ee986db6af58 100644 --- a/boards/shields/st_b_cams_imx_mb1854/st_b_cams_imx_mb1854.overlay +++ b/boards/shields/st_b_cams_imx_mb1854/st_b_cams_imx_mb1854.overlay @@ -47,11 +47,8 @@ }; }; -&csi_connector { - /* Power the camera module */ - en-module-gpios { - gpio-hog; - gpios = ; - output-high; - }; +/* Power the camera module */ +&csi_gpio1_hog { + status = "okay"; + output-high; }; diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_defconfig b/boards/silabs/dev_kits/sltb010a/sltb010a_defconfig index b7da445368cb1..3f81ba69cff1d 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_defconfig +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_defconfig @@ -5,6 +5,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_GPIO=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig index ea3fbea0c139f..7e2172f28aaeb 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig @@ -8,5 +8,3 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_HW_STACK_PROTECTION=y CONFIG_REGULATOR=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig index ea3fbea0c139f..7e2172f28aaeb 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig @@ -8,5 +8,3 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_HW_STACK_PROTECTION=y CONFIG_REGULATOR=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig index b7da445368cb1..3f81ba69cff1d 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig @@ -5,6 +5,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_GPIO=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig index d937f7c3052ba..e70f8f5c5197d 100644 --- a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig @@ -5,5 +5,3 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_GPIO=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts index 2b76d423cafe6..26dcdf0123be9 100644 --- a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts +++ b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts @@ -183,7 +183,7 @@ zephyr_i2c: &i2c0 { status = "okay"; }; -&stimer0 { +&sysrtc0 { status = "okay"; }; diff --git a/boards/st/b_l072z_lrwan1/support/openocd.cfg b/boards/st/b_l072z_lrwan1/support/openocd.cfg index 94e533f721010..40b192cc4080c 100644 --- a/boards/st/b_l072z_lrwan1/support/openocd.cfg +++ b/boards/st/b_l072z_lrwan1/support/openocd.cfg @@ -1,6 +1,14 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd -transport select hla_swd +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd set WORKAREASIZE 0x2000 diff --git a/boards/st/nucleo_c092rc/doc/index.rst b/boards/st/nucleo_c092rc/doc/index.rst index 3547334d43f47..6cf87da671d4d 100644 --- a/boards/st/nucleo_c092rc/doc/index.rst +++ b/boards/st/nucleo_c092rc/doc/index.rst @@ -6,10 +6,6 @@ The STM32 Nucleo-64 development board, featuring the STM32C092RC MCU, supports both Arduino and ST morpho connectivity, and includes a CAN FD interface with an onboard transceiver. -.. image:: img/st_nucleo_c092rc.webp - :align: center - :alt: Nucleo C092RC development board - More information about the board can be found at the `Nucleo C092RC website`_. Hardware diff --git a/boards/st/nucleo_g070rb/support/openocd.cfg b/boards/st/nucleo_g070rb/support/openocd.cfg index 0001c39855b0d..589ea907059b9 100644 --- a/boards/st/nucleo_g070rb/support/openocd.cfg +++ b/boards/st/nucleo_g070rb/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g0x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g0.cfg] diff --git a/boards/st/nucleo_g071rb/support/openocd.cfg b/boards/st/nucleo_g071rb/support/openocd.cfg index 0001c39855b0d..589ea907059b9 100644 --- a/boards/st/nucleo_g071rb/support/openocd.cfg +++ b/boards/st/nucleo_g071rb/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g0x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g0.cfg] diff --git a/boards/st/nucleo_g0b1re/support/openocd.cfg b/boards/st/nucleo_g0b1re/support/openocd.cfg index 0001c39855b0d..589ea907059b9 100644 --- a/boards/st/nucleo_g0b1re/support/openocd.cfg +++ b/boards/st/nucleo_g0b1re/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g0x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g0.cfg] diff --git a/boards/st/nucleo_g431kb/support/openocd.cfg b/boards/st/nucleo_g431kb/support/openocd.cfg index d936f7d353423..613455dc81838 100644 --- a/boards/st/nucleo_g431kb/support/openocd.cfg +++ b/boards/st/nucleo_g431kb/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g4.cfg] diff --git a/boards/st/nucleo_g431rb/support/openocd.cfg b/boards/st/nucleo_g431rb/support/openocd.cfg index d936f7d353423..613455dc81838 100644 --- a/boards/st/nucleo_g431rb/support/openocd.cfg +++ b/boards/st/nucleo_g431rb/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g4.cfg] diff --git a/boards/st/nucleo_g474re/support/openocd.cfg b/boards/st/nucleo_g474re/support/openocd.cfg index d936f7d353423..613455dc81838 100644 --- a/boards/st/nucleo_g474re/support/openocd.cfg +++ b/boards/st/nucleo_g474re/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32g4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_g4.cfg] diff --git a/boards/st/nucleo_l011k4/support/openocd.cfg b/boards/st/nucleo_l011k4/support/openocd.cfg index a6ca36d73b03f..70aa84294c665 100644 --- a/boards/st/nucleo_l011k4/support/openocd.cfg +++ b/boards/st/nucleo_l011k4/support/openocd.cfg @@ -1,8 +1,17 @@ # This is an ST NUCLEO-L011K4 board with single STM32L011K4 chip. # https://www.st.com/en/evaluation-tools/nucleo-l011k4.html -source [find interface/stlink.cfg] -transport select hla_swd +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd + +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd #set WORKAREASIZE 0x2000 diff --git a/boards/st/nucleo_l031k6/support/openocd.cfg b/boards/st/nucleo_l031k6/support/openocd.cfg index be154d927e4db..e303b7399cecf 100644 --- a/boards/st/nucleo_l031k6/support/openocd.cfg +++ b/boards/st/nucleo_l031k6/support/openocd.cfg @@ -1,8 +1,17 @@ # This is an ST NUCLEO-L031K6 board with single STM32L031K6 chip. # https://www.st.com/en/evaluation-tools/nucleo-l031k6.html -source [find interface/stlink.cfg] -transport select hla_swd +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd + +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd source [find target/stm32l0.cfg] diff --git a/boards/st/nucleo_l053r8/support/openocd.cfg b/boards/st/nucleo_l053r8/support/openocd.cfg index fec9da07d5570..09161f939a4a3 100644 --- a/boards/st/nucleo_l053r8/support/openocd.cfg +++ b/boards/st/nucleo_l053r8/support/openocd.cfg @@ -1,8 +1,17 @@ # This is an ST NUCLEO-L053R8 board with single STM32L053R8 chip. # https://www.st.com/en/evaluation-tools/nucleo-l053r8.html -source [find interface/stlink.cfg] -transport select hla_swd +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd + +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd set WORKAREASIZE 0x2000 diff --git a/boards/st/nucleo_l073rz/support/openocd.cfg b/boards/st/nucleo_l073rz/support/openocd.cfg index b28dd29e5c110..718e20e15e086 100644 --- a/boards/st/nucleo_l073rz/support/openocd.cfg +++ b/boards/st/nucleo_l073rz/support/openocd.cfg @@ -1,19 +1,6 @@ # This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip. # https://www.st.com/en/evaluation-tools/nucleo-l073rz.html -source [find interface/stlink.cfg] - -transport select hla_swd - -set WORKAREASIZE 0x2000 - -source [find target/stm32l0.cfg] - -# Add the second flash bank. -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME - -# There is only system reset line and JTAG/SWD command can be issued when SRST -reset_config srst_only +source [find board/st_nucleo_l073rz.cfg] $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" diff --git a/boards/st/nucleo_l152re/support/openocd.cfg b/boards/st/nucleo_l152re/support/openocd.cfg index 7e76ff5be9cda..214286330e09a 100644 --- a/boards/st/nucleo_l152re/support/openocd.cfg +++ b/boards/st/nucleo_l152re/support/openocd.cfg @@ -1,15 +1,5 @@ -# TODO: Once official openOCD fix merged and available in zephyr: -# http://openocd.zylin.com/#/c/5829/ -# revert to board/st_nucleo_l1.cfg -# source [find board/st_nucleo_l1.cfg] - -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l1x_dual_bank.cfg] - -reset_config srst_only +# http://openocd.zylin.com/#/c/5829/ was merged in 2020 +source [find board/st_nucleo_l1.cfg] $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" diff --git a/boards/st/nucleo_l412rb_p/support/openocd.cfg b/boards/st/nucleo_l412rb_p/support/openocd.cfg index cd566c1fa1c97..c4850019587db 100644 --- a/boards/st/nucleo_l412rb_p/support/openocd.cfg +++ b/boards/st/nucleo_l412rb_p/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_l4.cfg] diff --git a/boards/st/nucleo_l432kc/support/openocd.cfg b/boards/st/nucleo_l432kc/support/openocd.cfg index cd566c1fa1c97..c4850019587db 100644 --- a/boards/st/nucleo_l432kc/support/openocd.cfg +++ b/boards/st/nucleo_l432kc/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_l4.cfg] diff --git a/boards/st/nucleo_l433rc_p/support/openocd.cfg b/boards/st/nucleo_l433rc_p/support/openocd.cfg index cd566c1fa1c97..c4850019587db 100644 --- a/boards/st/nucleo_l433rc_p/support/openocd.cfg +++ b/boards/st/nucleo_l433rc_p/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_l4.cfg] diff --git a/boards/st/nucleo_l452re/support/openocd.cfg b/boards/st/nucleo_l452re/support/openocd.cfg index cd566c1fa1c97..c4850019587db 100644 --- a/boards/st/nucleo_l452re/support/openocd.cfg +++ b/boards/st/nucleo_l452re/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -reset_config srst_only +source [find board/st_nucleo_l4.cfg] diff --git a/boards/st/nucleo_l552ze_q/support/openocd.cfg b/boards/st/nucleo_l552ze_q/support/openocd.cfg index f4ccc5641251a..c7ff4b06e1419 100644 --- a/boards/st/nucleo_l552ze_q/support/openocd.cfg +++ b/boards/st/nucleo_l552ze_q/support/openocd.cfg @@ -1,11 +1,4 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l5x.cfg] - -# use hardware reset -reset_config srst_only srst_nogate +source [find board/st_nucleo_l5.cfg] $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" 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 0660ce0463c08..7bbb69b776935 100644 --- a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "arduino_r3_connector.dtsi" @@ -54,6 +55,31 @@ led2 = &red_led; sw0 = &user_button; }; + + csi_connector: connector_csi { + compatible = "raspberrypi,csi-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + ; + }; +}; + +&gpioo { + csi_gpio0_hog: csi-gpio0-hog { + gpio-hog; + gpios = <5 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; +}; + +&gpioa { + csi_gpio1_hog: csi-gpio1-hog { + gpio-hog; + gpios = <0 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; }; &clk_hse { @@ -109,6 +135,19 @@ status = "okay"; }; +&ic17 { + pll-src = <1>; + ic-div = <4>; + status = "okay"; +}; + +/* IC18 must be enabled for the 27MHz CSIPHY */ +&ic18 { + pll-src = <1>; + ic-div = <60>; + status = "okay"; +}; + &perck { clocks = <&rcc STM32_SRC_HSI PER_SEL(0)>; status = "okay"; @@ -154,6 +193,15 @@ status = "okay"; }; +csi_i2c: &i2c2 { + clocks = <&rcc STM32_CLOCK(APB1, 22)>, + <&rcc STM32_SRC_CKPER I2C2_SEL(1)>; + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + &i2c4 { clocks = <&rcc STM32_CLOCK(APB4, 7)>, <&rcc STM32_SRC_CKPER I2C4_SEL(1)>; @@ -257,3 +305,9 @@ zephyr_udc0: &usbotg_hs1 { }; }; }; + +csi_interface: &dcmipp { + port { + csi_ep_in: endpoint {}; + }; +}; diff --git a/boards/st/nucleo_wb55rg/support/openocd.cfg b/boards/st/nucleo_wb55rg/support/openocd.cfg index 2ad582703684c..a324300d395fa 100644 --- a/boards/st/nucleo_wb55rg/support/openocd.cfg +++ b/boards/st/nucleo_wb55rg/support/openocd.cfg @@ -1,7 +1 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32wbx.cfg] - -reset_config srst_only +source [find board/st_nucleo_wb55rg] diff --git a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts index 0d0742d7e2864..52a6dcd1830d1 100644 --- a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts +++ b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts @@ -174,3 +174,17 @@ stm32_lp_tick_source: &lptim1 { }; }; }; + +zephyr_udc0: &usbotg_hs { + clocks = <&rcc STM32_CLOCK(AHB2, 14)>, + <&rcc STM32_SRC_HSE OTGHS_SEL(0)>; + pinctrl-0 = <&usb_otg_hs_dm_pd7 &usb_otg_hs_dp_pd6>; + pinctrl-names = "default"; + status = "okay"; +}; + +&otghs_phy { + /* OTG HS clock source is 32 MHz HSE */ + clock-reference = "SYSCFG_OTG_HS_PHY_CLK_32MHz"; + status = "okay"; +}; diff --git a/boards/st/nucleo_wba65ri/nucleo_wba65ri.yaml b/boards/st/nucleo_wba65ri/nucleo_wba65ri.yaml index 78617e1b26282..a9f9eaa2a7dc0 100644 --- a/boards/st/nucleo_wba65ri/nucleo_wba65ri.yaml +++ b/boards/st/nucleo_wba65ri/nucleo_wba65ri.yaml @@ -11,6 +11,7 @@ supported: - spi - adc - rng + - usbd - arduino_gpio - arduino_i2c - arduino_spi diff --git a/boards/st/nucleo_wl55jc/support/openocd.cfg b/boards/st/nucleo_wl55jc/support/openocd.cfg index 9d7fe815eba4e..78eadd8d601ad 100644 --- a/boards/st/nucleo_wl55jc/support/openocd.cfg +++ b/boards/st/nucleo_wl55jc/support/openocd.cfg @@ -1,6 +1,6 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd source [find target/stm32wlx.cfg] diff --git a/boards/st/st25dv_mb1283_disco/support/openocd.cfg b/boards/st/st25dv_mb1283_disco/support/openocd.cfg index 5d6a3772c5cf6..6f67ad513a3d8 100644 --- a/boards/st/st25dv_mb1283_disco/support/openocd.cfg +++ b/boards/st/st25dv_mb1283_disco/support/openocd.cfg @@ -1,6 +1,14 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd -transport select hla_swd +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd source [find target/stm32f4x.cfg] diff --git a/boards/st/steval_fcu001v1/support/openocd.cfg b/boards/st/steval_fcu001v1/support/openocd.cfg index 8412eea50e738..7dc7362df5457 100644 --- a/boards/st/steval_fcu001v1/support/openocd.cfg +++ b/boards/st/steval_fcu001v1/support/openocd.cfg @@ -1,6 +1,14 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd -transport select hla_swd +# If you use an OpenOCD version higher than 0.12.0 and your target embeds +# an ST-Link firmware earlier than v2j24, connection will not work. +# It is recommended to upgrade the ST-Link firmware of the target, +# however, if not possible, the 2 lines above can be replaced with the +# following to connect successfully: +# +# source [find interface/stlink-hla.cfg] +# transport select hla_swd set WORKAREASIZE 0x10000 diff --git a/boards/st/stm32g0316_disco/support/openocd.cfg b/boards/st/stm32g0316_disco/support/openocd.cfg index 2d736e0a4089e..101d48c2e0a47 100644 --- a/boards/st/stm32g0316_disco/support/openocd.cfg +++ b/boards/st/stm32g0316_disco/support/openocd.cfg @@ -1,5 +1,5 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd source [find target/stm32g0x.cfg] diff --git a/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg b/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg index ddceef92cb191..e090c2462d245 100644 --- a/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg +++ b/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg @@ -1,7 +1,7 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd set DUAL_BANK 1 diff --git a/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg b/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg index 75d441d180926..3ec0a46f323b9 100644 --- a/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg +++ b/boards/st/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg @@ -1,7 +1,7 @@ -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd source [find target/stm32h7x.cfg] diff --git a/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m4.cfg b/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m4.cfg index 9958067dfb389..4acfabf2e4175 100644 --- a/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m4.cfg +++ b/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m4.cfg @@ -1,9 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2025 Foss Analytical A/S -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd set DUAL_BANK 1 diff --git a/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m7.cfg b/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m7.cfg index 172b4eb785142..543c160819261 100644 --- a/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m7.cfg +++ b/boards/st/stm32h757i_eval/support/openocd_stm32h757i_eval_m7.cfg @@ -1,9 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2025 Foss Analytical A/S -source [find interface/stlink.cfg] +source [find interface/stlink-dap.cfg] -transport select hla_swd +transport select dapdirect_swd source [find target/stm32h7x.cfg] diff --git a/boards/st/stm32l562e_dk/support/openocd.cfg b/boards/st/stm32l562e_dk/support/openocd.cfg index f4ccc5641251a..c7ff4b06e1419 100644 --- a/boards/st/stm32l562e_dk/support/openocd.cfg +++ b/boards/st/stm32l562e_dk/support/openocd.cfg @@ -1,11 +1,4 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32l5x.cfg] - -# use hardware reset -reset_config srst_only srst_nogate +source [find board/st_nucleo_l5.cfg] $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index 0f1096116a1bd..e93f6ffa86f14 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -86,6 +86,22 @@ }; }; +&gpioc { + csi_gpio0_hog: csi-gpio0-hog { + gpio-hog; + gpios = <8 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; +}; + +&gpiod { + csi_gpio1_hog: csi-gpio1-hog { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; +}; + &i2c2 { status = "okay"; clocks = <&rcc STM32_CLOCK(APB1, 22)>, diff --git a/boards/st/stm32wb5mm_dk/support/openocd.cfg b/boards/st/stm32wb5mm_dk/support/openocd.cfg index 2ad582703684c..7e5a53e660568 100644 --- a/boards/st/stm32wb5mm_dk/support/openocd.cfg +++ b/boards/st/stm32wb5mm_dk/support/openocd.cfg @@ -1,7 +1,2 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32wbx.cfg] - -reset_config srst_only +# OpenOCD st_nucleo_wb55rg.cfg matches stm32wb55mm_dk support +source [find board/st_nucleo_wb55rg.cfg] diff --git a/boards/st/stm32wb5mmg/support/openocd.cfg b/boards/st/stm32wb5mmg/support/openocd.cfg index 2ad582703684c..7e346846af125 100644 --- a/boards/st/stm32wb5mmg/support/openocd.cfg +++ b/boards/st/stm32wb5mmg/support/openocd.cfg @@ -1,7 +1,2 @@ -source [find interface/stlink.cfg] - -transport select hla_swd - -source [find target/stm32wbx.cfg] - -reset_config srst_only +# OpenOCD st_nucleo_wb55rg.cfg matches stm32wb55mmg support +source [find board/st_nucleo_wb55k.cfg] diff --git a/boards/technexion/pico_pi/doc/index.rst b/boards/technexion/pico_pi/doc/index.rst index 530bc3a86afa1..b0b5f8c11d1f6 100644 --- a/boards/technexion/pico_pi/doc/index.rst +++ b/boards/technexion/pico_pi/doc/index.rst @@ -44,28 +44,7 @@ For more information about the i.MX7 SoC and Pico-Pi i.MX7D, see these reference Supported Features ================== -The Pico-Pi i.MX7D configuration supports the following hardware features on the -Cortex M4 Core: - -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| I2C | on-chip | i2c | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ - -The default configuration can be found in the defconfig file: -:zephyr_file:`boards/technexion/pico_pi/pico_pi_mcimx7d_m4_defconfig` - -Other hardware features are not currently supported by the port. +.. zephyr:board-supported-hw:: Connections and IOs =================== diff --git a/boards/toradex/colibri_imx7d/doc/index.rst b/boards/toradex/colibri_imx7d/doc/index.rst index c381a39a49657..c05d61e0110e5 100644 --- a/boards/toradex/colibri_imx7d/doc/index.rst +++ b/boards/toradex/colibri_imx7d/doc/index.rst @@ -61,31 +61,7 @@ and Colibri Evaluation Board, see these references: Supported Features ================== -The Colibri iMX7D Computer on Module with Colibri Evaluation Board configuration -supports the following hardware features on the Cortex M4 Core: - -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| I2C | on-chip | i2c | -+-----------+------------+-------------------------------------+ -| PWM | on-chip | pwm | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ - -The default configuration can be found in the defconfig file: - - :zephyr_file:`boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4_defconfig` - -Other hardware features are not currently supported by the port. +.. zephyr:board-supported-hw:: Connections and IOs =================== diff --git a/boards/vcc-gnd/yd_esp32/doc/index.rst b/boards/vcc-gnd/yd_esp32/doc/index.rst index af9e54c5a65fd..9885330db4247 100644 --- a/boards/vcc-gnd/yd_esp32/doc/index.rst +++ b/boards/vcc-gnd/yd_esp32/doc/index.rst @@ -6,208 +6,39 @@ Overview The YD-ESP32 development board is one of VCC-GND® Studio's official boards. This board is based on the ESP32-WROOM-32E module, with the ESP32 as the core. -ESP32 -===== - -ESP32 is a series of low cost, low power system on a chip microcontrollers -with integrated Wi-Fi & dual-mode Bluetooth. The ESP32 series employs a -Tensilica Xtensa LX6 microprocessor in both dual-core and single-core -variations. ESP32 is created and developed by Espressif Systems, a -Shanghai-based Chinese company, and is manufactured by TSMC using their 40nm -process. - -The features include the following: - -- Dual core Xtensa microprocessor (LX6), running at 160 or 240MHz -- 520KB of SRAM -- 802.11b/g/n/e/i -- Bluetooth v4.2 BR/EDR and BLE -- Various peripherals: - - - 12-bit ADC with up to 18 channels - - 2x 8-bit DACs - - 10x touch sensors - - Temperature sensor - - 4x SPI - - 2x I2S - - 2x I2C - - 3x UART - - SD/SDIO/MMC host - - Slave (SDIO/SPI) - - Ethernet MAC - - CAN bus 2.0 - - IR (RX/TX) - - Motor PWM - - LED PWM with up to 16 channels - - Hall effect sensor - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) -- 5uA deep sleep current +Hardware +******** -For more information, check the datasheet at `ESP32 Datasheet`_ or the technical reference -manual at `ESP32 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32-features.rst + :start-after: espressif-soc-esp32-features Supported Features ================== .. zephyr:board-supported-hw:: -System requirements -=================== - -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: yd_esp32 - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: yd_esp32/esp32/procpu - :goals: build +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -The usual ``flash`` target will work with the ``yd_esp32`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. +Programming and Debugging +************************* -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: yd_esp32/esp32/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! yd_esp32 - -RGB LED -======= - -The board contains an addressable RGB LED (`XL-5050RGBC-WS2812B`_), driven by GPIO16. -Here is an example of how to test it using the :zephyr:code-sample:`led-strip` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/drivers/led/led_strip - :board: yd_esp32/esp32/procpu - :goals: flash +.. zephyr:board-supported-runners:: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -.. _`XL-5050RGBC-WS2812B`: http://www.xinglight.cn/index.php?c=show&id=947 +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* +========= -ESP32 support on OpenOCD is available at `OpenOCD ESP32`_. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging On the YD-ESP32 board, the JTAG pins are not run to a standard connector (e.g. ARM 20-pin) and need to be manually connected @@ -231,22 +62,6 @@ to the external programmer (e.g. a Flyswatter2): | IO15 | TDO | +------------+-----------+ -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: yd_esp32/esp32/procpu - :goals: build flash - -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: yd_esp32/esp32/procpu - :goals: debug - Note on Debugging with GDB Stub =============================== @@ -258,13 +73,26 @@ GDB stub is enabled on ESP32. This does not work as the code is on flash which cannot be randomly accessed for modification. + +Sample applications +******************* + +RGB LED +======= + +The board contains an addressable RGB LED (`XL-5050RGBC-WS2812B`_), driven by GPIO16. +Here is an example of how to test it using the :zephyr:code-sample:`led-strip` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/led/led_strip + :board: yd_esp32/esp32/procpu + :goals: flash + +.. _`XL-5050RGBC-WS2812B`: http://www.xinglight.cn/index.php?c=show&id=947 + References ********** .. target-notes:: .. _`ESP32-DevKitC-WROVER`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/hw-reference/esp32/get-started-devkitc.html# -.. _`ESP32 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf -.. _`ESP32 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/waveshare/esp32s3_matrix/doc/index.rst b/boards/waveshare/esp32s3_matrix/doc/index.rst index 4090485a84d66..71d8e7eebf7a1 100644 --- a/boards/waveshare/esp32s3_matrix/doc/index.rst +++ b/boards/waveshare/esp32s3_matrix/doc/index.rst @@ -11,38 +11,13 @@ port. Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. - -ESP32-S3-Matrix includes the following features: - -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 512KB of SRAM -- 2MB of PSRAM -- 4MB of FLASH -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate -- 8x8 RGB LED matrix -- Accelerometer/gyroscope - -Digital interfaces: - -- 15 programmable GPIOs +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features -Low Power: +The board included peripherals: -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) +- 8x8 RGB LED matrix +- Accelerometer/gyroscope Asymmetric Multiprocessing (AMP) ******************************** @@ -59,163 +34,28 @@ Supported Features .. zephyr:board-supported-hw:: -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing +System Requirements ******************* -.. zephyr:board-supported-runners:: - -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32-S3 SoC. +Programming and Debugging +************************* -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: esp32s3_matrix/esp32s3/procpu - :goals: build - :west-args: --sysbuild - :compact: - -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │   └── zephyr - │   ├── zephyr.elf - │   └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_matrix/esp32s3/procpu - :goals: build - -The usual ``flash`` target will work with the ``esp32s3_matrix`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_matrix/esp32s3/procpu - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: +.. zephyr:board-supported-runners:: -.. code-block:: console +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32s3_matrix +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. - -ESP32-S3 has a built-in JTAG circuitry and can be debugged without any additional chip. Only an USB cable connected to the D+/D- pins is necessary. - -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32-S3`_. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s3_matrix/esp32s3/procpu - :goals: build flash - -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: esp32s3_matrix/esp32s3/procpu - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -223,7 +63,3 @@ References .. target-notes:: .. _ESP32-S3-Matrix Waveshare Wiki: https://www.waveshare.com/wiki/ESP32-S3-Matrix -.. _ESP32-S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf -.. _ESP32-S3 Technical Reference Manual: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf -.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/doc/index.rst b/boards/waveshare/esp32s3_touch_lcd_1_28/doc/index.rst index b9cab2da1d141..1a4ce7dde60e5 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/doc/index.rst +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/doc/index.rst @@ -10,89 +10,40 @@ Low Energy functions, an accelerometer and gyroscope, a battery charger and GPIO Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. - -ESP32-S3-Touch-LCD-1.28 includes the following features: - -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 2MB of SRAM -- 16MB of FLASH -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate -- Round 1.28" LCD with touchscreen controller -- Accelerometer/gyroscope -- Battery charger - -Digital interfaces: - -- 6 programmable GPIOs -- 2 open-drain outputs - -Low Power: - -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) - -Asymmetric Multiprocessing (AMP) -******************************** - -ESP32-S3 allows 2 different applications to be executed in ESP32-S3 SoC. Due to its dual-core -architecture, each core can be enabled to execute customized tasks in stand-alone mode -and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_ or the technical reference -manual at `ESP32-S3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features Supported Features ================== .. zephyr:board-supported-hw:: -Prerequisites -------------- - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: +System Requirements +******************* - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. note:: +Debugging +========= - Simple boot does not provide any security features nor OTA updates. +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. _ESP32-S3-Touch-LCD-1.28 Waveshare Wiki: https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.28 -.. _ESP32-S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3-mini-1_mini-1u_datasheet_en.pdf -.. _ESP32-S3 Technical Reference Manual: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf +.. _`ESP32-S3-Touch-LCD-1.28 Waveshare Wiki`: https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.28 diff --git a/boards/we/orthosie1ev/doc/index.rst b/boards/we/orthosie1ev/doc/index.rst index 55f0afdb168a5..3df31a4a19fbc 100644 --- a/boards/we/orthosie1ev/doc/index.rst +++ b/boards/we/orthosie1ev/doc/index.rst @@ -4,209 +4,42 @@ Overview ******** Orthosie-I-EV is an entry-level development board based on Orthosie-I, -a module named for its small size. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions. +a module named for its small size. This board integrates ESP32-C3 - complete Wi-Fi and Bluetooth® Low Energy functions. For more information, check `Orthosie-I Website`_. Hardware ******** -ESP32-C3 is a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, -based on the open-source RISC-V architecture. It strikes the right balance of power, -I/O capabilities and security, thus offering the optimal cost-effective -solution for connected devices. -The availability of Wi-Fi and Bluetooth 5 (LE) connectivity not only makes the device configuration easy, -but it also facilitates a variety of use-cases based on dual connectivity. - -The features include the following: - -- 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz -- 400 KB of internal RAM -- 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh -- Various peripherals: - - - 12-bit ADC with up to 6 channels - - TWAI compatible with CAN bus 2.0 - - Temperature sensor - - 3x SPI - - 1x I2S - - 1x I2C - - 2x UART - - LED PWM with up to 6 channels - -- Cryptographic hardware acceleration (RNG, ECC, RSA, SHA-2, AES) - -For more information, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference -manual at `ESP32-C3 Technical Reference Manual`_. +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features Supported Features ================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -******************* +Programming and Debugging +************************* .. zephyr:board-supported-runners:: -Simple boot -=========== - -The board could be loaded using the single binary image, without 2nd stage bootloader. -It is the default option when building the application without additional configuration. - -.. note:: - - Simple boot does not provide any security features nor OTA updates. - -MCUboot bootloader -================== - -User may choose to use MCUboot bootloader instead. In that case the bootloader -must be built (and flashed) at least once. - -There are two options to be used when building an application: - -1. Sysbuild -2. Manual build - -.. note:: - - User can select the MCUboot bootloader by adding the following line - to the board default configuration file. - - .. code:: cfg - - CONFIG_BOOTLOADER_MCUBOOT=y - -Sysbuild -======== - -The sysbuild makes possible to build and flash all necessary images needed to -bootstrap the board with the ESP32 SoC. - -To build the sample application using sysbuild use the command: - -.. zephyr-app-commands:: - :tool: west - :zephyr-app: samples/hello_world - :board: we_orthosie1ev - :goals: build - :west-args: --sysbuild - :compact: +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -By default, the ESP32 sysbuild creates bootloader (MCUboot) and application -images. But it can be configured to create other kind of images. - -Build directory structure created by sysbuild is different from traditional -Zephyr build. Output is structured by the domain subdirectories: - -.. code-block:: - - build/ - ├── hello_world - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - ├── mcuboot - │ └── zephyr - │ ├── zephyr.elf - │ └── zephyr.bin - └── domains.yaml - -.. note:: - - With ``--sysbuild`` option the bootloader will be re-build and re-flash - every time the pristine build is used. - -For more information about the system build please read the :ref:`sysbuild` documentation. - -Manual build -============ - -During the development cycle, it is intended to build & flash as quickly possible. -For that reason, images can be built one at a time using traditional build. - -The instructions following are relevant for both manual build and sysbuild. -The only difference is the structure of the build directory. - -.. note:: - - Remember that bootloader (MCUboot) needs to be flash at least once. - -Build and flash applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: we_orthosie1ev - :goals: build - -The usual ``flash`` target will work with the ``we_orthosie1ev`` board -configuration. Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: we_orthosie1ev - :goals: flash - -Open the serial monitor using the following command: - -.. code-block:: shell - - west espressif monitor - -After the board has automatically reset and booted, you should see the following -message in the monitor: - -.. code-block:: console - - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! we_orthosie1ev +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants Debugging -********* - -As with much custom hardware, the ESP32-C3 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. - -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. - -Here is an example for building the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: we_orthosie1ev - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= - -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +========= -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: we_orthosie1ev - :goals: debug +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** @@ -214,6 +47,3 @@ References .. target-notes:: .. _`Orthosie-I Website`: https://www.we-online.com/en/components/products/ORTHOSIE-I -.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf -.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/weact/blackpill_u585ci/board.yml b/boards/weact/blackpill_u585ci/board.yml index 4abf4758c34bb..47697f740013c 100644 --- a/boards/weact/blackpill_u585ci/board.yml +++ b/boards/weact/blackpill_u585ci/board.yml @@ -1,6 +1,6 @@ board: name: blackpill_u585ci - full_name: WeAct Studio Black Pill STM32U585 Core Board + full_name: Black Pill STM32U585 vendor: weact socs: - name: stm32u585xx diff --git a/boards/weact/weact_esp32s3_b/doc/index.rst b/boards/weact/weact_esp32s3_b/doc/index.rst index a4993ca310e46..9688303d5fb70 100644 --- a/boards/weact/weact_esp32s3_b/doc/index.rst +++ b/boards/weact/weact_esp32s3_b/doc/index.rst @@ -11,78 +11,15 @@ and user button. For more information, check `WeAct Studio ESP32-S3-B`_. Hardware ******** -ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated 2.4 GHz Wi-Fi -and Bluetooth® Low Energy (Bluetooth LE). It consists of high-performance dual-core microprocessor -(Xtensa® 32-bit LX7), a low power coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, -RF module, and numerous peripherals. +.. include:: ../../../espressif/common/soc-esp32s3-features.rst + :start-after: espressif-soc-esp32s3-features WeAct Studio ESP32-S3-B includes the following features: -- Dual core 32-bit Xtensa Microprocessor (Tensilica LX7), running up to 240MHz -- Additional vector instructions support for AI acceleration -- 16MB external Flash memory (separate chip) -- 8MB integrated PSRAM (ESP32-S3R8 chip) -- 512KB of SRAM -- 384KB of ROM -- Wi-Fi 802.11b/g/n -- Bluetooth LE 5.0 with long-range support and up to 2Mbps data rate - Onboard RGB WS2812 LED (GPIO48) - User button (GPIO45) - BOOT button (GPIO0) -Digital interfaces: - -- 45 programmable GPIOs -- 4x SPI -- 1x LCD interface (8-bit ~16-bit parallel RGB, I8080 and MOTO6800), supporting conversion between RGB565, YUV422, YUV420 and YUV411 -- 1x DVP 8-bit ~16-bit camera interface -- 3x UART -- 2x I2C -- 2x I2S -- 1x RMT (TX/RX) -- 1x pulse counter -- LED PWM controller, up to 8 channels -- 1x full-speed USB OTG -- 1x USB Serial/JTAG controller -- 2x MCPWM -- 1x SDIO host controller with 2 slots -- General DMA controller (GDMA), with 5 transmit channels and 5 receive channels -- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) - -Analog interfaces: - -- 2x 12-bit SAR ADCs, up to 20 channels -- 1x temperature sensor -- 14x touch sensing IOs - -Timers: - -- 4x 54-bit general-purpose timers -- 1x 52-bit system timer -- 3x watchdog timers - -Low Power: - -- Power Management Unit with five power modes -- Ultra-Low-Power (ULP) coprocessors: ULP-RISC-V and ULP-FSM - -Security: - -- Secure boot -- Flash encryption -- 4-Kbit OTP, up to 1792 bits for users -- Cryptographic hardware acceleration: (AES-128/256, Hash, RSA, RNG, HMAC, Digital signature) - -Asymmetric Multiprocessing (AMP) -******************************** - -WeAct Studio ESP32-S3-B allows 2 different applications to be executed in ESP32-S3 SoC. Due to its dual-core -architecture, each core can be enabled to execute customized tasks in stand-alone mode -and/or exchanging data over OpenAMP framework. See :zephyr:code-sample-category:`ipc` folder as code reference. - -For more information, check the datasheet at `ESP32-S3 Datasheet`_ or the technical reference -manual at `ESP32-S3 Technical Reference Manual`_. - Supported Features ================== @@ -91,16 +28,8 @@ Supported Features System Requirements ******************* -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif - -.. note:: - - It is recommended running the command above after :file:`west update`. +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements Programming and Debugging ************************* @@ -110,6 +39,9 @@ Programming and Debugging .. include:: ../../../espressif/common/building-flashing.rst :start-after: espressif-building-flashing +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants + Debugging ========= @@ -122,5 +54,3 @@ References .. target-notes:: .. _`WeAct Studio ESP32-S3-B`: https://github.com/WeActStudio/WeActStudio.ESP32S3-AorB -.. _`ESP32-S3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf -.. _`ESP32-S3 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf diff --git a/boards/wemos/esp32s2_lolin_mini/doc/index.rst b/boards/wemos/esp32s2_lolin_mini/doc/index.rst index 9fadc278205e2..eef927b2ca10a 100644 --- a/boards/wemos/esp32s2_lolin_mini/doc/index.rst +++ b/boards/wemos/esp32s2_lolin_mini/doc/index.rst @@ -3,99 +3,45 @@ Overview ******** -ESP32-S2 is a highly integrated, low-power, single-core Wi-Fi Microcontroller SoC, designed to be secure and -cost-effective, with a high performance and a rich set of IO capabilities. [1]_ - -The features include the following: - -- RSA-3072-based secure boot -- AES-XTS-256-based flash encryption -- Protected private key and device secrets from software access -- Cryptographic accelerators for enhanced performance -- Protection against physical fault injection attacks -- Various peripherals: - - - 43x programmable GPIOs - - 14x configurable capacitive touch GPIOs - - USB OTG - - LCD interface - - camera interface - - SPI - - I2S - - UART - - ADC - - DAC - - LED PWM with up to 8 channels +A mini wifi boards based ESP32-S2FN4R2. Hardware ******** +.. include:: ../../../espressif/common/soc-esp32s2-features.rst + :start-after: espressif-soc-esp32s2-features + Supported Features ================== .. zephyr:board-supported-hw:: -System requirements +System Requirements ******************* -Prerequisites -============= - -Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command -below to retrieve those files. - -.. code-block:: console - - west blobs fetch hal_espressif +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements -.. note:: - - It is recommended running the command above after :file:`west update`. - -Building & Flashing -=================== +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). - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s2_lolin_mini - :goals: build - -The usual ``flash`` target will work with the ``esp32s2_lolin_mini`` board -configuration after putting the board into bootloader mode by holding the '0' -button then pressing 'RST' and releasing the 'RST' button. - -Here is an example for the :zephyr:code-sample:`hello_world` -application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: esp32s2_lolin_mini - :goals: flash - -Open a serial port using e.g. screen - -.. code-block:: shell - - screen /dev/ttyUSB0 115200 +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing -After the board has been manually reset and booted, you should see the following -message in the monitor: +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants -.. code-block:: console +Debugging +========= - ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** - Hello World! esp32s2_lolin_mini +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging References ********** .. target-notes:: -.. [1] https://www.espressif.com/en/products/socs/esp32-s2 -.. _`ESP32S2 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf -.. _`ESP32S2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf +.. _`ESP32-S2 Product pages`: https://www.espressif.com/en/products/socs/esp32-s2 diff --git a/cmake/mcuboot.cmake b/cmake/mcuboot.cmake index d22a068023e3e..43d265c419d5f 100644 --- a/cmake/mcuboot.cmake +++ b/cmake/mcuboot.cmake @@ -222,7 +222,7 @@ function(zephyr_mcuboot_tasks) endif() if(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD OR CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT) - list(APPEND byproducts ${output}.slot1.signed.encrypted.bin) + list(APPEND byproducts ${output}.slot1.signed.bin) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${imgtool_sign} ${imgtool_args_alt_slot} ${output}.bin ${output}.slot1.signed.bin) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 60667eb6444bd..1a6332298ba64 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -191,7 +191,13 @@ set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_hardenconfig ${ZEPHYR_BASE}/scripts/kconfig/hardenconfig.py ) -set_ifndef(KCONFIG_TARGETS menuconfig guiconfig hardenconfig) +set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_traceconfig + ${ZEPHYR_BASE}/scripts/kconfig/traceconfig.py + ${DOTCONFIG} + ${PROJECT_BINARY_DIR}/kconfig-trace.md + ) + +set_ifndef(KCONFIG_TARGETS menuconfig guiconfig hardenconfig traceconfig) foreach(kconfig_target ${KCONFIG_TARGETS} diff --git a/cmake/reports/CMakeLists.txt b/cmake/reports/CMakeLists.txt index a65482ac10ac8..7f282b6029e9c 100644 --- a/cmake/reports/CMakeLists.txt +++ b/cmake/reports/CMakeLists.txt @@ -128,7 +128,7 @@ if(NOT ${PUNCOVER} STREQUAL PUNCOVER-NOTFOUND) puncover ${PUNCOVER} --elf_file ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} - --gcc_tools_base ${CROSS_COMPILE} + --gcc-tools-base ${CROSS_COMPILE} --src_root ${ZEPHYR_BASE} --build_dir ${CMAKE_BINARY_DIR} ${PUNCOVER_ARGS} diff --git a/doc/_extensions/zephyr/domain/static/css/board-catalog.css b/doc/_extensions/zephyr/domain/static/css/board-catalog.css index e37c78537d137..8a13b3b183ebd 100644 --- a/doc/_extensions/zephyr/domain/static/css/board-catalog.css +++ b/doc/_extensions/zephyr/domain/static/css/board-catalog.css @@ -106,6 +106,10 @@ margin-right: 8px; } +#compatibles-tags .tag { + font-family: var(--monospace-font-family); +} + .tag:hover { background-color: #0056b3; } diff --git a/doc/_extensions/zephyr/domain/static/js/board-catalog.js b/doc/_extensions/zephyr/domain/static/js/board-catalog.js index 3d433d237e220..94312793bafaa 100644 --- a/doc/_extensions/zephyr/domain/static/js/board-catalog.js +++ b/doc/_extensions/zephyr/domain/static/js/board-catalog.js @@ -41,15 +41,34 @@ function populateFormFromURL() { const features = hashParams.get("features").split(","); setTimeout(() => { features.forEach(feature => { - const tagContainer = document.getElementById('tag-container'); - const tagInput = document.getElementById('tag-input'); + const tagContainer = document.getElementById('hwcaps-tags'); + const tagInput = document.getElementById('hwcaps-input'); const tagElement = document.createElement('span'); tagElement.classList.add('tag'); tagElement.textContent = feature; tagElement.onclick = () => { - const selectedTags = [...document.querySelectorAll('.tag')].map(tag => tag.textContent); - selectedTags.splice(selectedTags.indexOf(feature), 1); + tagElement.remove(); + filterBoards(); + }; + tagContainer.insertBefore(tagElement, tagInput); + }); + filterBoards(); + }, 0); + } + + // Restore compatibles from URL + if (hashParams.has("compatibles")) { + const compatibles = hashParams.get("compatibles").split("|"); + setTimeout(() => { + compatibles.forEach(compatible => { + const tagContainer = document.getElementById('compatibles-tags'); + const tagInput = document.getElementById('compatibles-input'); + + const tagElement = document.createElement('span'); + tagElement.classList.add('tag'); + tagElement.textContent = compatible; + tagElement.onclick = () => { tagElement.remove(); filterBoards(); }; @@ -83,8 +102,12 @@ function updateURL() { }); // Add supported features to URL - const selectedTags = [...document.querySelectorAll('.tag')].map(tag => tag.textContent); - selectedTags.length ? hashParams.set("features", selectedTags.join(",")) : hashParams.delete("features"); + const selectedHWTags = [...document.querySelectorAll('#hwcaps-tags .tag')].map(tag => tag.textContent); + selectedHWTags.length ? hashParams.set("features", selectedHWTags.join(",")) : hashParams.delete("features"); + + // Add compatibles to URL + const selectedCompatibles = [...document.querySelectorAll('#compatibles-tags .tag')].map(tag => tag.textContent); + selectedCompatibles.length ? hashParams.set("compatibles", selectedCompatibles.join("|")) : hashParams.delete("compatibles"); window.history.replaceState({}, "", `#${hashParams.toString()}`); } @@ -126,8 +149,8 @@ function fillSocSocSelect(families, series = undefined, selectOnFill = false) { function setupHWCapabilitiesField() { let selectedTags = []; - const tagContainer = document.getElementById('tag-container'); - const tagInput = document.getElementById('tag-input'); + const tagContainer = document.getElementById('hwcaps-tags'); + const tagInput = document.getElementById('hwcaps-input'); const datalist = document.getElementById('tag-list'); const tagCounts = Array.from(document.querySelectorAll('.board-card')).reduce((acc, board) => { @@ -198,6 +221,80 @@ function setupHWCapabilitiesField() { updateDatalist(); } +function setupCompatiblesField() { + let selectedCompatibles = []; + + const tagContainer = document.getElementById('compatibles-tags'); + const tagInput = document.getElementById('compatibles-input'); + const datalist = document.getElementById('compatibles-list'); + + // Collect all unique compatibles from boards + const allCompatibles = Array.from(document.querySelectorAll('.board-card')).reduce((acc, board) => { + (board.getAttribute('data-compatibles') || '').split(' ').forEach(compat => { + if (compat && !acc.includes(compat)) { + acc.push(compat); + } + }); + return acc; + }, []); + + allCompatibles.sort(); + + function addCompatible(compatible) { + if (selectedCompatibles.includes(compatible) || compatible === "") return; + selectedCompatibles.push(compatible); + + const tagElement = document.createElement('span'); + tagElement.classList.add('tag'); + tagElement.textContent = compatible; + tagElement.onclick = () => removeCompatible(compatible); + tagContainer.insertBefore(tagElement, tagInput); + + tagInput.value = ''; + updateDatalist(); + } + + function removeCompatible(compatible) { + selectedCompatibles = selectedCompatibles.filter(c => c !== compatible); + document.querySelectorAll('.tag').forEach(el => { + if (el.textContent === compatible && el.parentElement === tagContainer) { + el.remove(); + } + }); + updateDatalist(); + } + + function updateDatalist() { + datalist.innerHTML = ''; + const filteredCompatibles = allCompatibles.filter(c => !selectedCompatibles.includes(c)); + + filteredCompatibles.forEach(compatible => { + const option = document.createElement('option'); + option.value = compatible; + datalist.appendChild(option); + }); + + filterBoards(); + } + + tagInput.addEventListener('input', () => { + if (allCompatibles.includes(tagInput.value)) { + addCompatible(tagInput.value); + } + }); + + tagInput.addEventListener('keydown', (e) => { + if (e.key === 'Enter' && tagInput.value) { + addCompatible(tagInput.value); + e.preventDefault(); + } else if (e.key === 'Backspace' && tagInput.value === '' && selectedCompatibles.length > 0) { + removeCompatible(selectedCompatibles[selectedCompatibles.length - 1]); + } + }); + + updateDatalist(); +} + document.addEventListener("DOMContentLoaded", function () { const form = document.querySelector(".filter-form"); @@ -218,6 +315,7 @@ document.addEventListener("DOMContentLoaded", function () { populateFormFromURL(); setupHWCapabilitiesField(); + setupCompatiblesField(); socFamilySelect = document.getElementById("family"); socFamilySelect.addEventListener("change", () => { @@ -272,8 +370,12 @@ function resetForm() { document.getElementById("show-shields").checked = true; // Clear supported features - document.querySelectorAll('.tag').forEach(tag => tag.remove()); - document.getElementById('tag-input').value = ''; + document.querySelectorAll('#hwcaps-tags .tag').forEach(tag => tag.remove()); + document.getElementById('hwcaps-input').value = ''; + + // Clear compatibles + document.querySelectorAll('#compatibles-tags .tag').forEach(tag => tag.remove()); + document.getElementById('compatibles-input').value = ''; filterBoards(); } @@ -289,6 +391,16 @@ function updateBoardCount() { + ` ${visibleShields.length} of ${shields.length} shields`; } +function wildcardMatch(pattern, str) { + // Convert wildcard pattern to regex + // Escape special regex characters except * + const regexPattern = pattern + .replace(/[.+?^${}()|[\]\\]/g, '\\$&') + .replace(/\*/g, '.*'); + const regex = new RegExp(`^${regexPattern}$`, "i"); + return regex.test(str); +} + function filterBoards() { const nameInput = document.getElementById("name").value.toLowerCase(); const archSelect = document.getElementById("arch").value; @@ -297,10 +409,14 @@ function filterBoards() { const showBoards = document.getElementById("show-boards").checked; const showShields = document.getElementById("show-shields").checked; - const selectedTags = [...document.querySelectorAll('.tag')].map(tag => tag.textContent); + // Get selected hardware capability tags + const selectedHWTags = [...document.querySelectorAll('#hwcaps-tags .tag')].map(tag => tag.textContent); + + // Get selected compatible tags + const selectedCompatibles = [...document.querySelectorAll('#compatibles-tags .tag')].map(tag => tag.textContent); const resetFiltersBtn = document.getElementById("reset-filters"); - if (nameInput || archSelect || vendorSelect || socSocSelect.selectedOptions.length || selectedTags.length || !showBoards || !showShields) { + if (nameInput || archSelect || vendorSelect || socSocSelect.selectedOptions.length || selectedHWTags.length || selectedCompatibles.length || !showBoards || !showShields) { resetFiltersBtn.classList.remove("btn-disabled"); } else { resetFiltersBtn.classList.add("btn-disabled"); @@ -314,6 +430,7 @@ function filterBoards() { const boardVendor = board.getAttribute("data-vendor") || ""; const boardSocs = (board.getAttribute("data-socs") || "").split(" ").filter(Boolean); const boardSupportedFeatures = (board.getAttribute("data-supported-features") || "").split(" ").filter(Boolean); + const boardCompatibles = (board.getAttribute("data-compatibles") || "").split(" ").filter(Boolean); const isShield = board.classList.contains("shield"); let matches = true; @@ -323,12 +440,19 @@ function filterBoards() { if ((isShield && !showShields) || (!isShield && !showBoards)) { matches = false; } else { + // Check if board matches all selected compatibles (with wildcard support) + const compatiblesMatch = selectedCompatibles.length === 0 || + selectedCompatibles.every((pattern) => + boardCompatibles.some((compatible) => wildcardMatch(pattern, compatible)) + ); + matches = !(nameInput && !boardName.includes(nameInput)) && !(archSelect && !boardArchs.includes(archSelect)) && !(vendorSelect && boardVendor !== vendorSelect) && (selectedSocs.length === 0 || selectedSocs.some((soc) => boardSocs.includes(soc))) && - (selectedTags.length === 0 || selectedTags.every((tag) => boardSupportedFeatures.includes(tag))); + (selectedHWTags.length === 0 || selectedHWTags.every((tag) => boardSupportedFeatures.includes(tag))) && + compatiblesMatch; } board.classList.toggle("hidden", !matches); diff --git a/doc/_extensions/zephyr/domain/templates/board-card.html b/doc/_extensions/zephyr/domain/templates/board-card.html index 0e4808b85a74f..961048e2e9285 100644 --- a/doc/_extensions/zephyr/domain/templates/board-card.html +++ b/doc/_extensions/zephyr/domain/templates/board-card.html @@ -25,7 +25,19 @@ {%- endfor -%} {%- endfor -%} {{- feature_types|join(' ') -}} - " tabindex="0"> + " + data-compatibles=" + {%- set all_compatibles = [] -%} + {%- for target_compatibles in board.compatibles.values() -%} + {%- for compatible in target_compatibles -%} + {%- if compatible not in all_compatibles -%} + {%- set _ = all_compatibles.append(compatible) -%} + {%- endif -%} + {%- endfor -%} + {%- endfor -%} + {{- all_compatibles|join(' ') -}} + " + tabindex="0">
{{ vendors[board.vendor] }}
{% if board.image -%} A picture of the {{ board.full_name }} board
- -
- Supported Hardware Capabilities +
+
+
+ +
+ + +
+
+
diff --git a/doc/_scripts/gen_boards_catalog.py b/doc/_scripts/gen_boards_catalog.py index 548576fbbb81f..5fcddddbc176f 100755 --- a/doc/_scripts/gen_boards_catalog.py +++ b/doc/_scripts/gen_boards_catalog.py @@ -290,11 +290,13 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None): doc_page = guess_doc_page(board) supported_features = {} + compatibles = {} # Use pre-gathered build info and DTS files if board.name in board_devicetrees: for board_target, edt in board_devicetrees[board.name].items(): features = {} + target_compatibles = set() for node in edt.nodes: if node.binding_path is None: continue @@ -328,6 +330,7 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None): locations.add("soc") existing_feature = features.get(binding_type, {}).get(node.matching_compat) + target_compatibles.add(node.matching_compat) node_info = { "filename": str(filename), @@ -354,8 +357,9 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None): features.setdefault(binding_type, {})[node.matching_compat] = feature_data - # Store features for this specific target + # Store features and compatibles for this specific target supported_features[board_target] = features + compatibles[board_target] = list(target_compatibles) board_runner_info = {} if board.name in board_runners: @@ -392,6 +396,7 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None): "socs": list(socs), "revision_default": board.revision_default, "supported_features": supported_features, + "compatibles": compatibles, "image": guess_image(board), # runners "supported_runners": board_runner_info.get("runners", []), diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index 9287411b72528..2d12a79587184 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -505,6 +505,8 @@ def make_sidebar(compatible, vendor_name, vendor_ref_target, driver_path=None): "", f" :Name: ``{compatible}``", f" :Vendor: :ref:`{vendor_name} <{vendor_ref_target}>`", + f" :Used in: :zephyr:board-catalog:`List of boards <#compatibles={compatible}>` using", + " this compatible", ] if driver_path: lines.append(f" :Driver: :zephyr_file:`{driver_path}`") diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index b7ab9b27ec57f..6cccbb20cb5ac 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -27,6 +27,7 @@ ('boards/rak/rak11720/doc/index', 'boards/rakwireless/rak11720/doc/index'), ('boards/rak/rak4631/doc/index', 'boards/rakwireless/rak4631/doc/index'), ('boards/rak/rak5010/doc/index', 'boards/rakwireless/rak5010/doc/index'), + ('boards/raytac/an54l15q_db/doc/index', 'boards/raytac/an54lq_db_15/doc/index'), ('boards/x86/ehl_crb/doc/index', 'boards/x86/intel_ehl/doc/index'), ('boards/x86/intel_ehl/doc/index', 'boards/intel/ehl/doc/index'), ('boards/x86/intel_rpl/doc/index', 'boards/intel/rpl/doc/index'), diff --git a/doc/build/kconfig/index.rst b/doc/build/kconfig/index.rst index b59213ded02a8..5c09cf7ea9872 100644 --- a/doc/build/kconfig/index.rst +++ b/doc/build/kconfig/index.rst @@ -25,6 +25,7 @@ tips and best practices for writing :file:`Kconfig` files. :maxdepth: 1 menuconfig.rst + tracing.rst setting.rst tips.rst preprocessor-functions.rst diff --git a/doc/build/kconfig/tips.rst b/doc/build/kconfig/tips.rst index 0f4dfe4671212..ab1653424bce1 100644 --- a/doc/build/kconfig/tips.rst +++ b/doc/build/kconfig/tips.rst @@ -375,6 +375,8 @@ error-prone, since it can be hard to spot that the same dependency is added twice. +.. _stuck_symbols: + "Stuck" symbols in menuconfig and guiconfig ******************************************* diff --git a/doc/build/kconfig/tracing.rst b/doc/build/kconfig/tracing.rst new file mode 100644 index 0000000000000..b1b11640818ac --- /dev/null +++ b/doc/build/kconfig/tracing.rst @@ -0,0 +1,59 @@ +Tracing values to their source +############################## + +The merged configuration saved to :file:`zephyr/.config` contains the result of +applying the user configuration file to the whole tree of Kconfig files. This +process can be hard to follow, especially when invisible symbols are being +implicitly selected from anywhere in the tree. To help with this, the +``traceconfig`` target can be used to generate a file in the build directory +that details how each symbol got its final value. + +After building the Zephyr project as usual, the Kconfig trace can be generated +with either of these commands: + + .. code-block:: bash + + west build -t traceconfig + + .. code-block:: bash + + ninja traceconfig + +.. note:: + The generated information is only useful on a clean build, because otherwise + the ``.config`` file "pins" all settings to a specific value (as described + in :ref:`Stuck symbols `). Therefore, it is recommended to + run a :ref:`pristine build ` before generating the + trace. + +The output will be in the :file:`zephyr/kconfig-trace.md` file in the build +directory. This file is best viewed within IDEs to take advantage of Markdown +elements (tables, highlighting, clickable links), but can easily be understood +even when opened directly with any text editor. + +The report is divided in three sections: + +#. Visible symbols +#. Invisible symbols +#. Unset symbols + +For sections 1 and 2, a table is presented where each symbol is shown with its +type, name, and current value. The fourth column details the kind of statement +that resulted in the value being applied, and can be one of the following: + + - *assigned*, when an explicit assignment, of the form ``CONFIG_xxx=y``, is + read from a config file; + + - *default*, when there was no user assignment, but an applicable default + value was read from Kconfig tree; + + - *selected* or *implied*, when a ``select`` or ``imply`` statement from a + separate symbol caused the symbol to be set. + +The fifth column details the location for the source statement. For the first +two kinds of statements, the exact location (file name and line number) is +provided; in the latter cases, it contains the expressions that resulted in the +symbol being set. + +Finally, section 3 simply lists all undefined symbols. These have no additional +information since they never received a value by any of the above means. diff --git a/doc/connectivity/networking/api/net_pkt_filter.rst b/doc/connectivity/networking/api/net_pkt_filter.rst index 3a859b140ed84..338aaa6843789 100644 --- a/doc/connectivity/networking/api/net_pkt_filter.rst +++ b/doc/connectivity/networking/api/net_pkt_filter.rst @@ -12,8 +12,9 @@ Overview The Network Packet Filtering facility provides the infrastructure to construct custom rules for accepting and/or denying packet transmission -and reception. This can be used to create a basic firewall, control -network traffic, etc. +and reception. It also allows to modify the priority of incoming +network packets. This can be used to create a basic firewall, control network +traffic, etc. The :kconfig:option:`CONFIG_NET_PKT_FILTER` must be set in order to enable the relevant APIs. @@ -25,8 +26,13 @@ for a given rule are true then the packet outcome is immediately determined as specified by the current rule and no more rules are considered. If one condition is false then the next rule in the list is considered. -Packet outcome is either ``NET_OK`` to accept the packet or ``NET_DROP`` to -drop it. +Packet outcome is either ``NET_OK`` to accept the packet, ``NET_DROP`` to +drop it or ``NET_CONTINUE`` to modify its priority on the fly. + +When the outcome is ``NET_CONTINUE`` the priority is updated but the final +outcome is not yet determined and processing continues. If all conditions of +multiple rules are true, then the packet gets the priority of the rule last +considered. 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 @@ -47,7 +53,8 @@ retrieve the outer structure from the provided ``npf_test`` structure pointer. Convenience macros are provided in :zephyr_file:`include/zephyr/net/net_pkt_filter.h` to statically define condition instances for various conditions, and -:c:macro:`NPF_RULE()` to create a rule instance to tie them. +:c:macro:`NPF_RULE()` and :c:macro:`NPF_PRIORITY()` to create a rule instance +with an immediate outcome or a priority change. Examples ******** @@ -86,6 +93,40 @@ Another (less efficient) way to achieve the same result could be: npf_append_recv_rule(&npf_default_ok); } +This example assigns priorities to different network traffic. It gives network +control priority (``NET_PRIORITY_NC``) to the ``ptp`` packets, critical +applications priority (``NET_PRIORITY_CA``) to the internet traffic of version +6, excellent effort (``NET_PRIORITY_EE``) for internet protocol version 4 +traffic, and the lowest background priority (``NET_PRIORITY_BK``) to ``lldp`` +and ``arp``. + +Priority rules are only really useful if multiple traffic class queues are +enabled in the project configuration :kconfig:option:`CONFIG_NET_TC_RX_COUNT`. +The mapping from the priority of the packet to the traffic class queue is in +accordance with the standard 802.1Q and depends on the +:kconfig:option:`CONFIG_NET_TC_RX_COUNT`. + +.. code-block:: c + + static NPF_ETH_TYPE_MATCH(is_arp, NET_ETH_PTYPE_ARP); + static NPF_ETH_TYPE_MATCH(is_lldp, NET_ETH_PTYPE_LLDP); + static NPF_ETH_TYPE_MATCH(is_ptp, NET_ETH_PTYPE_PTP); + static NPF_ETH_TYPE_MATCH(is_ipv4, NET_ETH_PTYPE_IP); + static NPF_ETH_TYPE_MATCH(is_ipv6, NET_ETH_PTYPE_IPV6); + + static NPF_PRIORITY(priority_bk, NET_PRIORITY_BK, is_arp, is_lldp); + static NPF_PRIORITY(priority_ee, NET_PRIORITY_EE, is_ipv4); + static NPF_PRIORITY(priority_ca, NET_PRIORITY_CA, is_ipv6); + static NPF_PRIORITY(priority_nc, NET_PRIORITY_NC, is_ptp); + + void install_my_filter(void) { + npf_append_recv_rule(&priority_bk); + npf_append_recv_rule(&priority_ee); + npf_append_recv_rule(&priority_ca); + npf_append_recv_rule(&priority_nc); + npf_append_recv_rule(&npf_default_ok); + } + API Reference ************* diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index 82588c1c9d67b..9d081061cc04d 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -171,7 +171,7 @@ The current minimum required version for the main dependencies are: .. code-block:: bat - winget install Kitware.CMake Ninja-build.Ninja oss-winget.gperf python Git.Git oss-winget.dtc wget 7zip.7zip + winget install Kitware.CMake Ninja-build.Ninja oss-winget.gperf Python.Python.3.12 Git.Git oss-winget.dtc wget 7zip.7zip #. Close the terminal window. @@ -337,6 +337,15 @@ chosen. You'll also install Zephyr's additional Python dependencies in a #. Activate the virtual environment: + .. note:: + + Python's virtual environment activation in PowerShell requires + running a script itself, which needs to be allowed. + + .. code-block:: powershell + + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + .. tabs:: .. code-tab:: bat diff --git a/doc/kernel/services/interrupts.rst b/doc/kernel/services/interrupts.rst index 621e843895001..25de0ab3e30be 100644 --- a/doc/kernel/services/interrupts.rst +++ b/doc/kernel/services/interrupts.rst @@ -689,16 +689,16 @@ Files generated by the script ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The interrupt tables generator script creates 3 files: -isr_tables.c, isr_tables_swi.ld, and isr_tables_vt.ld. +:file:`isr_tables.c`, :file:`isr_tables_swi.ld`, and :file:`isr_tables_vt.ld`. -The isr_tables.c will contain all the structures for interrupts, direct interrupts and +The :file:`isr_tables.c` will contain all the structures for interrupts, direct interrupts and shared interrupts (if enabled). This file implements only all the structures that are not implemented by the application, leaving a comment where the interrupt not implemented here can be found. -Then two linker files are used. The isr_tables_vt.ld file is included in place +Then two linker files are used. The :file:`isr_tables_vt.ld` file is included in place where the interrupt vectors are required to be placed in the selected architecture. -The isr_tables_swi.ld file describes the placement of the software interrupt table +The :file:`isr_tables_swi.ld` file describes the placement of the software interrupt table elements. The separated file is required as it might be placed in writable on nonwritable section, depending on the current configuration. diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index e4379d44775a3..9cd82fc9c2059 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -51,6 +51,15 @@ Base Libraries may include :zephyr_file:`include/zephyr/posix/posix_limits.h` for Zephyr's definitions. Some runtime-invariant values may need to be queried via :c:func:`sysconf`. +* The number of file descriptor table size and its availability is now determined by + a ``ZVFS_OPEN_SIZE`` define instead of the :kconfig:option:`CONFIG_ZVFS_OPEN_MAX` + Kconfig option. Subsystems can specify their own custom file descriptor table size + requirements by specifying Kconfig options with the prefix ``CONFIG_ZVFS_OPEN_ADD_SIZE_``. + The old Kconfig option still exists, but will be overridden if the custom requirements + are larger. To force the old Kconfig option to be used, even when its value is less + than the indicated custom requirements, a new :kconfig:option:`CONFIG_ZVFS_OPEN_IGNORE_MIN` + option has been introduced (which defaults being disabled). + Boards ****** @@ -66,6 +75,16 @@ Boards * Panasonic ``panb511evb`` is renamed to ``panb611evb``. +* STM32 boards OpenOCD configuration files have been changed to support latest OpenOCD versions + (> v0.12.0) in which the HLA/SWD transport has been deprecated (see + https://review.openocd.org/c/openocd/+/8523 and commit + https://sourceforge.net/p/openocd/code/ci/34ec5536c0ba3315bc5a841244bbf70141ccfbb4/). + Issues may be encountered when connecting to an ST-Link adapter running firmware prior + v2j24 which do not support the new transport. In this case, the ST-Link firmware should + be upgraded or, if not possible, the OpenOCD configuration script should be changed to + source "interface/stlink-hla.cfg" and select the "hla_swd" interface explicitly. + Backward compatibility with OpenOCD v0.12.0 or older is maintained. + Device Drivers and Devicetree ***************************** @@ -215,6 +234,15 @@ Bluetooth Mesh been removed. The selection of the PSA Crypto provider is now automatically controlled by Kconfig :kconfig:option:`CONFIG_PSA_CRYPTO`. +Bluetooth Host +============== + +* :kconfig:option:`CONFIG_BT_FIXED_PASSKEY` has been deprecated. Instead, the application can + provide passkeys for pairing using the :c:member:`bt_conn_auth_cb.app_passkey` callback, which is + available when :kconfig:option:`CONFIG_BT_APP_PASSKEY` is enabled. The application can return the + passkey for pairing, or :c:macro:`BT_PASSKEY_RAND` for the Host to generate a random passkey + instead. + Ethernet ======== @@ -325,6 +353,13 @@ Cellular * :c:enum:`cellular_access_technology` values have been redefined to align with 3GPP TS 27.007. * :c:enum:`cellular_registration_status` values have been extended to align with 3GPP TS 27.007. +Crypto +====== + +* Hashing operations now require a constant input in the :c:struct:`hash_pkt`. + This shouldn't affect any existing code, unless an out-of-tree hashing backend actually + performs that operation in-place (see :github:`94218`) + Flash Map ========= @@ -351,6 +386,10 @@ MCUmgr but can still be used by enabling :kconfig:option:`CONFIG_MCUMGR_GRP_OS_INFO_HARDWARE_INFO_SHORT_HARDWARE_PLATFORM`. +* Support for legacy Mbed TLS hash crypto is removed and only PSA Crypto API is used. + :kconfig:option:`CONFIG_MCUMGR_GRP_FS_HASH_SHA256` automatically enables Mbed TLS and its + PSA Crypto implementation if TF-M is not enabled in the build. + RTIO ==== diff --git a/doc/releases/release-notes-4.2.rst b/doc/releases/release-notes-4.2.rst index 048c32ba9fdc7..b73d345acb01b 100644 --- a/doc/releases/release-notes-4.2.rst +++ b/doc/releases/release-notes-4.2.rst @@ -650,7 +650,7 @@ New Boards * Raytac Corporation - * :zephyr:board:`raytac_an54l15q_db` (``raytac_an54l15q_db``) + * :zephyr:board:`raytac_an54lq_db_15` (``raytac_an54lq_db_15``) * :zephyr:board:`raytac_an7002q_db` (``raytac_an7002q_db``) * :zephyr:board:`raytac_mdbt50q_cx_40_dongle` (``raytac_mdbt50q_cx_40_dongle``) diff --git a/doc/releases/release-notes-4.3.rst b/doc/releases/release-notes-4.3.rst index 72d51e066511e..6d300cfea7a30 100644 --- a/doc/releases/release-notes-4.3.rst +++ b/doc/releases/release-notes-4.3.rst @@ -51,6 +51,10 @@ API Changes .. Only removed, deprecated and new APIs, changes go in migration guide. +* Crypto + + * The input buffer in :c:struct:`hash_pkt` is now constant + Removed APIs and options ======================== @@ -146,6 +150,10 @@ New APIs and options * :kconfig:option:`CONFIG_CPU_FREQ` +* Cellular + + * :c:enumerator:`CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT` + * Crypto * :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS` @@ -213,6 +221,8 @@ New APIs and options * hawkBit * :kconfig:option:`CONFIG_HAWKBIT_REBOOT_NONE` + * :kconfig:option:`CONFIG_HAWKBIT_CONFIRM_IMG_ON_INIT` + * :kconfig:option:`CONFIG_HAWKBIT_ERASE_SECOND_SLOT_ON_CONFIRM` * Modem diff --git a/doc/services/cpu_freq/policies/on_demand.rst b/doc/services/cpu_freq/policies/on_demand.rst index ea1d3e15b093a..63026bc454715 100644 --- a/doc/services/cpu_freq/policies/on_demand.rst +++ b/doc/services/cpu_freq/policies/on_demand.rst @@ -4,7 +4,7 @@ On-Demand CPU Frequency Scaling Policy ###################################### The On-Demand policy evaluates the current CPU load using the -:ref:`CPU Load subsystem `, and compares it to the trigger threshold defined by the +:ref:`CPU Load metric `, and compares it to the trigger threshold defined by the SoC P-state definition. The On-Demand policy will iterate through the defined P-states and select the first P-state of which diff --git a/doc/services/cpu_load/index.rst b/doc/services/cpu_load/index.rst index 68fb257ebba20..5ed96621a05ee 100644 --- a/doc/services/cpu_load/index.rst +++ b/doc/services/cpu_load/index.rst @@ -1,4 +1,4 @@ -.. _cpu_load_subsys: +.. _cpu_load_metric: CPU Load ######## diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index c29b99793e98f..6468638e7057a 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -48,6 +48,7 @@ zephyr_library_sources_ifdef(CONFIG_ADC_GECKO_ADC adc_gecko.c) zephyr_library_sources_ifdef(CONFIG_ADC_SILABS_IADC adc_silabs_iadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_SILABS_SIWX91X adc_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_ADC_INFINEON_CAT1 adc_ifx_cat1.c) +zephyr_library_sources_ifdef(CONFIG_ADC_INFINEON_HPPASS_SAR adc_ifx_hppass_sar.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_GPADC adc_smartbond_gpadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_SDADC adc_smartbond_sdadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_TLA202X adc_tla202x.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 8a4597108c599..e400fcfcb8a96 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -136,6 +136,8 @@ source "drivers/adc/Kconfig.silabs" source "drivers/adc/Kconfig.ifx_cat1" +source "drivers/adc/Kconfig.ifx_hppass_sar" + source "drivers/adc/Kconfig.smartbond" source "drivers/adc/Kconfig.tla202x" diff --git a/drivers/adc/Kconfig.ifx_hppass_sar b/drivers/adc/Kconfig.ifx_hppass_sar new file mode 100644 index 0000000000000..30fc8491db583 --- /dev/null +++ b/drivers/adc/Kconfig.ifx_hppass_sar @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Infineon HPPASS SAR ADC configuration options + +config ADC_INFINEON_HPPASS_SAR + bool "Infineon HPPASS SAR ADC driver" + default y + depends on DT_HAS_INFINEON_HPPASS_SAR_ADC_ENABLED + select USE_INFINEON_HPPASS_SAR_ADC + select ADC_CONFIGURABLE_INPUTS + help + This option enables the ADC driver for Infineon PSOC C3 + HPPASS (High Performance Programmable Analog Sub-System) SAR ADC. + + The HPPASS SAR ADC provides 12-bit analog-to-digital + conversion capabilities + +if ADC_INFINEON_HPPASS_SAR + +config ADC_INFINEON_HPPASS_SAR_INIT_PRIORITY + int "Infineon HPPASS SAR ADC driver init priority" + default 80 + help + Infineon HPPASS SAR ADC driver initialization priority. + This should be higher than the HPPASS_ANALOG_INIT_PRIORITY + to ensure the analog subsystem is initialized first. + +endif # ADC_INFINEON_HPPASS_SAR diff --git a/drivers/adc/adc_ifx_hppass_sar.c b/drivers/adc/adc_ifx_hppass_sar.c new file mode 100644 index 0000000000000..d3dcf3d8dff1b --- /dev/null +++ b/drivers/adc/adc_ifx_hppass_sar.c @@ -0,0 +1,765 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief ADC HPPASS SAR driver + * + * Driver for the HPPASS SAR ADC used in the Infineon PSOC C3 series. + */ + +#define DT_DRV_COMPAT infineon_hppass_sar_adc + +#include +#include +#include +#include +#include +#include +#include + +#include "ifx_hppass_analog.h" +#include "cy_pdl.h" + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +#define IFX_HPPASS_SAR_ADC_RESOLUTION (12u) /* ADC Resolution for this device is fixed at 12-bit*/ + +LOG_MODULE_REGISTER(ifx_hppass_sar_adc, CONFIG_ADC_LOG_LEVEL); + +/** + * @brief HPPASS Configuration Structure + * + * Basic configuration for the HPPASS analog subsystem. By default this structure configures the + * HPPASS AC to enable the ADC. Other functions of the HPPASS system are not enabled by default. + */ +const cy_stc_hppass_sar_t ifx_hppass_sar_pdl_cfg_struct_default = { + .vref = CY_HPPASS_SAR_VREF_EXT, + .lowSupply = false, + .offsetCal = false, + .linearCal = false, + .gainCal = false, + .chanId = false, + .aroute = true, + .dirSampEnMsk = 0, + .muxSampEnMsk = 0, + .holdCount = 29U, + .dirSampGain = { + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + }, + .muxSampGain = { + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + CY_HPPASS_SAR_SAMP_GAIN_1, + }, + .sampTime = { + 32U, + 32U, + 32U, + }, + .chan = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + }, + .grp = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + .limit = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + .muxMode = { + CY_HPPASS_SAR_MUX_SEQ, + CY_HPPASS_SAR_MUX_SEQ, + CY_HPPASS_SAR_MUX_SEQ, + CY_HPPASS_SAR_MUX_SEQ, + }, + .fir = { + NULL, + NULL, + }, + .fifo = NULL, +}; + +/* + * Device supports up to 28 channels. Note that channels 12-15, 16-19, 20-23, and 24-27 are + * multiplexed in hardware and share samplers. + */ +#define HPPASS_SAR_ADC_MAX_CHANNELS CY_HPPASS_SAR_CHAN_NUM +#define DIRECT_CHANNEL_CNT CY_HPPASS_SAR_DIR_SAMP_NUM +#define MUXED_CHANNELS_PER_SAMPLER 4 +#define IFX_HPPASS_SAR_SAMPLER_GAIN_MSK 0x03 +#define IFX_HPPASS_SAR_SAMPLER_GAIN_WIDTH 2 + +/* + * Configuration and data structures + */ +struct ifx_hppass_sar_adc_config { + uint8_t irq_priority; + IRQn_Type irq_num; + void (*irq_func)(void); + uint16_t dir_samp_en_mask; + uint16_t mux_samp_en_mask; + bool vref_internal_source; + bool gain_cal; + bool offset_cal; + bool linear_cal; +}; + +/** + * @brief HPPASS SAR ADC channel configuration + */ +struct ifx_hppass_sar_adc_channel_config { + /** Channel number */ + uint8_t id; + uint8_t input_positive; + /* + * PDL channel configuration structure. The PDL will reapply channel configurations for all + * channels any time a change is made to any channel configuration. Store the PDL + * configuration for this channel so we have a copy to be used for this action. + */ + cy_stc_hppass_sar_chan_t pdl_channel_cfg; +}; + +/** + * @brief HPPASS SAR ADC device data + */ +struct ifx_hppass_sar_adc_data { + /* ADC context for async operations */ + struct adc_context ctx; + const struct device *dev; + /* PDL ADC configuration structure */ + cy_stc_hppass_sar_t hppass_sar_obj; + /* channel configurations for all channels (used or not)*/ + struct ifx_hppass_sar_adc_channel_config hppass_sar_chan_obj[HPPASS_SAR_ADC_MAX_CHANNELS]; + /* Bitmask of enabled channels */ + uint32_t enabled_channels; + /* Conversion buffer */ + uint16_t *buffer; + /* Repeat buffer for continuous sampling */ + uint16_t *repeat_buffer; + /** Conversion result */ + int result; +}; + +/* + * ADC Channels 12-28 are grouped together in hardware using a mux. The grouping is as follows: + * Sampler 12: Channels 12-15, + * Sampler 13: Channels 16-19, + * Sampler 14: Channels 20-23, + * Sampler 15: Channels 24-27 + */ +#define ADC_SAMPLER_12_CHANNEL_GROUP 0x0000F000 +#define ADC_SAMPLER_13_CHANNEL_GROUP 0x000F0000 +#define ADC_SAMPLER_14_CHANNEL_GROUP 0x00F00000 +#define ADC_SAMPLER_15_CHANNEL_GROUP 0x0F000000 +#define ADC_SAMPLER_DIRECT_MASK 0x0FFF + +/** + * @brief Configure HPPASS SAR ADC group + * + * @param channels Bitmask of channels to be enabled in the group + * @param group Group number to configure (0-7) + * + * HPPASS SAR ADC has 8 groups. ADC samplers can be added to a group, and will be sampled + * simultaneously and converted sequentially when the group is triggered. Note that only one MUXed + * channel can be included in a mux group. + */ +static int ifx_hppass_sar_configure_group(uint32_t channels, uint32_t group) +{ + cy_stc_hppass_sar_grp_t group_cfg = {0}; + + /* Check that no more than one channel is selected from each muxed group */ + if (POPCOUNT(channels & ADC_SAMPLER_12_CHANNEL_GROUP) > 1 || + POPCOUNT(channels & ADC_SAMPLER_13_CHANNEL_GROUP) > 1 || + POPCOUNT(channels & ADC_SAMPLER_14_CHANNEL_GROUP) > 1 || + POPCOUNT(channels & ADC_SAMPLER_15_CHANNEL_GROUP) > 1) { + + return -EINVAL; + } + + group_cfg.trig = CY_HPPASS_SAR_TRIG_0; /* TRIG_0 used for SW Trigger */ + group_cfg.sampTime = CY_HPPASS_SAR_SAMP_TIME_DISABLED; + + /* Enable directly sampled channels. */ + group_cfg.dirSampMsk = channels & ADC_SAMPLER_DIRECT_MASK; + + /* Enable Muxed channels. We need to determine if each sampler is enabled and what the mux + * should be set to for the sampler. + */ + group_cfg.muxSampMsk = 0; + for (int channel_num = DIRECT_CHANNEL_CNT; channel_num < HPPASS_SAR_ADC_MAX_CHANNELS; + channel_num++) { + if (channels & (1 << channel_num)) { + int sampler_num = + (channel_num - DIRECT_CHANNEL_CNT) / MUXED_CHANNELS_PER_SAMPLER; + int mux_setting = + (channel_num - DIRECT_CHANNEL_CNT) % MUXED_CHANNELS_PER_SAMPLER; + group_cfg.muxSampMsk |= (1 << sampler_num); + group_cfg.muxChanIdx[sampler_num] = mux_setting; + } + } + + if (Cy_HPPASS_SAR_GroupConfig(group, &group_cfg) != 0) { + LOG_ERR("ADC Group configuration failed"); + return -EINVAL; + } + + /* CrossTalkAdjust must be called any time groups are reconfigured. */ + Cy_HPPASS_SAR_CrossTalkAdjust((uint8_t)1U << group); + return 0; +} + +/** + * @brief Read results of the specified group of channels + * + * @param channels Bitmask of channels to read results for + * @param data Pointer to ADC data structure + * + * Helper function to read all the results for the specified channels into the data buffer. + */ +static void ifx_hppass_get_group_results(uint32_t channels, struct ifx_hppass_sar_adc_data *data) +{ + if (data->buffer == NULL) { + LOG_ERR("ADC data buffer is NULL"); + return; + } + + for (size_t i = 0; i < HPPASS_SAR_ADC_MAX_CHANNELS; i++) { + if (channels & (1 << i)) { + int16_t result = Cy_HPPASS_SAR_Result_ChannelRead(i); + *data->buffer++ = result; + } + } +} + +/** + * @brief Start ADC conversion + * + * @param ctx ADC context + * + * The HPPASS SAR ADC uses a grouping functionality to simultaneously sample then convert multiple + * channels with one trigger input. All channels in the ADC Sequence are added to a group and a + * conversion is triggered. + */ +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct ifx_hppass_sar_adc_data *data = + CONTAINER_OF(ctx, struct ifx_hppass_sar_adc_data, ctx); + const struct adc_sequence *sequence = &ctx->sequence; + uint32_t result_status; + + data->repeat_buffer = data->buffer; + if (data->buffer == NULL || sequence->buffer_size == 0) { + data->result = -ENOMEM; + return; + } + + if (sequence->channels == 0) { + LOG_ERR("No channels specified"); + data->result = -EINVAL; + } else if (ifx_hppass_sar_configure_group(sequence->channels, 0) != 0) { + LOG_ERR("Invalid channel group selection"); + data->result = -EINVAL; + } else { + /* Trigger SAR ADC group 0 conversion */ + Cy_HPPASS_SAR_Result_ClearStatus(sequence->channels); + Cy_HPPASS_SetFwTrigger(CY_HPPASS_TRIG_0_MSK); + +#if defined(CONFIG_ADC_ASYNC) + if (!data->ctx.asynchronous) { +#endif /* CONFIG_ADC_ASYNC */ + /* Wait for channel conversion done */ + do { + result_status = Cy_HPPASS_SAR_Result_GetStatus(); + } while ((result_status & sequence->channels) != sequence->channels); + + ifx_hppass_get_group_results(sequence->channels, data); + adc_context_on_sampling_done(&data->ctx, data->dev); +#if defined(CONFIG_ADC_ASYNC) + } +#endif /* CONFIG_ADC_ASYNC */ + + data->result = 0; + } +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct ifx_hppass_sar_adc_data *data = + CONTAINER_OF(ctx, struct ifx_hppass_sar_adc_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +/** + * @brief Start read operation + * + * @param dev Pointer to the device structure for the driver instance. + * @param sequence Pointer to the adc_sequence structure. + * + * This function validates the read parameters, sets up the buffer, and initiates the read + * operation using the ADC context. + */ +static int start_read(const struct device *dev, const struct adc_sequence *sequence) +{ + struct ifx_hppass_sar_adc_data *data = dev->data; + + if (sequence->buffer_size < (sizeof(int16_t) * POPCOUNT(sequence->channels))) { + LOG_ERR("Buffer too small"); + return -ENOMEM; + } + + if (sequence->resolution != IFX_HPPASS_SAR_ADC_RESOLUTION) { + LOG_ERR("Unsupported resolution: %d", sequence->resolution); + return -EINVAL; + } + + if (sequence->channels == 0) { + LOG_ERR("No channels specified"); + return -EINVAL; + } + + if ((sequence->channels ^ (data->enabled_channels & sequence->channels)) != 0) { + LOG_ERR("Channels not configured"); + return -EINVAL; + } + + if (sequence->oversampling != 0) { + LOG_ERR("Oversampling not supported"); + return -EINVAL; + } + + data->buffer = sequence->buffer; + adc_context_start_read(&data->ctx, sequence); + + return adc_context_wait_for_completion(&data->ctx); +} + +/** + * @brief ADC interrupt handler + * + * @param dev Pointer to the device structure for the driver instance. + * + * Interrupt Handler for the combined group results interrupt. This handler is common all group + * completion interrupts. Individual group completion interrupts are available if needed for more + * advanced ADC control. + */ +static void ifx_hppass_sar_adc_isr(const struct device *dev) +{ +#if defined(CONFIG_ADC_ASYNC) + struct ifx_hppass_sar_adc_data *data = dev->data; +#else + ARG_UNUSED(dev); +#endif /* CONFIG_ADC_ASYNC */ + LOG_DBG("SAR ADC combined results interrupt"); + + /* Check which SAR result groups have completed */ + uint32_t result_intr_status = Cy_HPPASS_SAR_Result_GetInterruptStatusMasked(); + + /* Clear the specific SAR result interrupts that fired */ + Cy_HPPASS_SAR_Result_ClearInterrupt(result_intr_status); + + /* Check if Group 0 completed (which is what we're using) */ + if (result_intr_status & CY_HPPASS_INTR_SAR_RESULT_GROUP_0) { + LOG_DBG("SAR Group 0 conversion complete"); + +#if defined(CONFIG_ADC_ASYNC) + if (data->ctx.asynchronous) { + const struct adc_sequence *sequence = &data->ctx.sequence; + uint32_t result_status = Cy_HPPASS_SAR_Result_GetStatus(); + + /* Make sure all requested channels have completed */ + if ((result_status & sequence->channels) == sequence->channels) { + ifx_hppass_get_group_results(sequence->channels, data); + /* Clear the result status for the channels we read */ + Cy_HPPASS_SAR_Result_ClearStatus(result_status & + sequence->channels); + + adc_context_on_sampling_done(&data->ctx, dev); + } else { + /* + * Not all channels have completed yet. This shouldn't happen, if + * configured correctly all channels in the group will be complete + * when this interrupt occurs. + */ + LOG_ERR("SAR Group 0: Not all channels completed."); + } + } +#endif /* CONFIG_ADC_ASYNC */ + } + + /* + * This implementation only uses Group 0. Any other interrupts indicates a configuration + * error. + */ + if (result_intr_status & ~CY_HPPASS_INTR_SAR_RESULT_GROUP_0) { + LOG_ERR("SAR Results Interrupt for unhandled groups: 0x%08X", + (uint32_t)(result_intr_status & ~CY_HPPASS_INTR_SAR_RESULT_GROUP_0)); + } +} + +/** + * @brief Initialize pdl adc configuration structure + * + * This function initializes the pdl adc configuration with values derived from the device tree and + * other default values. Channel and Group configurations are set to NULL intially. Channels will + * be configured later in the channel setup function. Groups are configured when a conversion is + * started. + */ +static void ifx_init_pdl_struct(struct ifx_hppass_sar_adc_data *data, + const struct ifx_hppass_sar_adc_config *cfg) +{ + data->hppass_sar_obj = ifx_hppass_sar_pdl_cfg_struct_default; + data->hppass_sar_obj.vref = + cfg->vref_internal_source ? CY_HPPASS_SAR_VREF_VDDA : CY_HPPASS_SAR_VREF_EXT; + data->hppass_sar_obj.offsetCal = cfg->offset_cal; + data->hppass_sar_obj.linearCal = cfg->linear_cal; + data->hppass_sar_obj.gainCal = cfg->gain_cal; + data->hppass_sar_obj.dirSampEnMsk = cfg->dir_samp_en_mask; + data->hppass_sar_obj.muxSampEnMsk = cfg->mux_samp_en_mask; +} + +/** + * @brief Initialize channel configuration structures + * + * This function initializes the channel configuration structures with default values. All + * channels are initially disabled. Channels will be enabled and configured in the channel setup + * function. + */ +static void ifx_init_channel_cfg(struct ifx_hppass_sar_adc_data *data) +{ + for (int i = 0; i < HPPASS_SAR_ADC_MAX_CHANNELS; i++) { + data->hppass_sar_chan_obj[i] = (struct ifx_hppass_sar_adc_channel_config){ + .id = (uint8_t)i, + .input_positive = 0, + .pdl_channel_cfg = + (cy_stc_hppass_sar_chan_t){ + .diff = false, + .sign = false, + .avg = CY_HPPASS_SAR_AVG_DISABLED, + .limit = CY_HPPASS_SAR_LIMIT_DISABLED, + .result = false, + .fifo = CY_HPPASS_FIFO_DISABLED, + }, + }; + + data->hppass_sar_obj.chan[i] = NULL; + } +} + +/* + * Zephyr Driver API Functions + */ + +/** + * @brief ADC read implementation + */ +static int ifx_hppass_sar_adc_read(const struct device *dev, const struct adc_sequence *sequence) +{ + struct ifx_hppass_sar_adc_data *data = dev->data; + int ret; + + adc_context_lock(&data->ctx, false, NULL); + ret = start_read(dev, sequence); + adc_context_release(&data->ctx, ret); + + return ret; +} + +/** + * @brief ADC read async implementation + */ +#ifdef CONFIG_ADC_ASYNC +static int ifx_hppass_sar_adc_read_async(const struct device *dev, + const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct ifx_hppass_sar_adc_data *data = dev->data; + int ret; + + adc_context_lock(&data->ctx, true, async); + ret = start_read(dev, sequence); + adc_context_release(&data->ctx, ret); + return ret; +} +#endif + +/** + * @brief Configure ADC channel + * + * Implements the Zephyr ADC channel configuration API. + */ +static int ifx_hppass_sar_adc_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + struct ifx_hppass_sar_adc_data *data = dev->data; + + if (channel_cfg->channel_id >= HPPASS_SAR_ADC_MAX_CHANNELS) { + LOG_ERR("Invalid channel ID: %d", channel_cfg->channel_id); + return -EINVAL; + } + + if (channel_cfg->differential) { + LOG_ERR("Differential channels not supported"); + return -ENOTSUP; + } + + if (channel_cfg->gain != ADC_GAIN_1 && channel_cfg->gain != ADC_GAIN_3 && + channel_cfg->gain != ADC_GAIN_6 && channel_cfg->gain != ADC_GAIN_12) { + LOG_ERR("Gain setting not supported"); + return -EINVAL; + } + + /* + * The HPPASS SAR hardware block does not support setting the reference individually per + * channel. The device can select internal or external reference that will apply to all ADC + * channels. + */ + if (channel_cfg->reference != ADC_REF_INTERNAL && + channel_cfg->reference != ADC_REF_EXTERNAL0) { + LOG_ERR("Reference setting not supported"); + return -EINVAL; + } + + /* + * The HPPASS SAR Hardware block does not support setting acquisition time per channel. The + * device has three sampling time configuration registers. These registers are used to + * configure the sample time for a group rather than individual channels. + */ + if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { + LOG_ERR("Invalid channel acquisition time, expected ADC_ACQ_TIME_DEFAULT"); + return -EINVAL; + } + + data->hppass_sar_chan_obj[channel_cfg->channel_id].id = channel_cfg->channel_id; + data->hppass_sar_chan_obj[channel_cfg->channel_id].pdl_channel_cfg = + (cy_stc_hppass_sar_chan_t){ + .diff = (channel_cfg->differential == 0) ? false : true, + .sign = false, + .avg = CY_HPPASS_SAR_AVG_DISABLED, + .limit = CY_HPPASS_SAR_LIMIT_DISABLED, + .result = true, + .fifo = CY_HPPASS_FIFO_DISABLED, + }; + + data->hppass_sar_obj.chan[channel_cfg->channel_id] = + &data->hppass_sar_chan_obj[channel_cfg->channel_id].pdl_channel_cfg; + + if (Cy_HPPASS_SAR_ChannelConfig( + channel_cfg->channel_id, + &data->hppass_sar_chan_obj[channel_cfg->channel_id].pdl_channel_cfg) != + CY_HPPASS_SUCCESS) { + LOG_ERR("Channel %d configuration failed", channel_cfg->channel_id); + return -EIO; + } + + /* + * PDL doesn't support configuring gain except during device initialization. Initialize the + * gain registers directly here. + */ + uint32_t sampler_gain; + + HPPASS_SAR_SAMP_GAIN(HPPASS_BASE) &= + ~(IFX_HPPASS_SAR_SAMPLER_GAIN_MSK + << (channel_cfg->channel_id * IFX_HPPASS_SAR_SAMPLER_GAIN_WIDTH)); + switch (channel_cfg->gain) { + case ADC_GAIN_1: + sampler_gain = 0; + break; + case ADC_GAIN_3: + sampler_gain = 1; + break; + case ADC_GAIN_6: + sampler_gain = 2; + break; + case ADC_GAIN_12: + sampler_gain = 3; + break; + default: + sampler_gain = 0; + break; + } + + HPPASS_SAR_SAMP_GAIN(HPPASS_BASE) |= + (sampler_gain << (channel_cfg->channel_id * IFX_HPPASS_SAR_SAMPLER_GAIN_WIDTH)); + + data->enabled_channels |= BIT(channel_cfg->channel_id); + + return 0; +} + +/** + * @brief Initialize ADC device + */ +static int ifx_hppass_sar_adc_init(const struct device *dev) +{ + const struct ifx_hppass_sar_adc_config *cfg = dev->config; + struct ifx_hppass_sar_adc_data *data = dev->data; + + data->dev = dev; + + LOG_DBG("Initializing HPPASS SAR ADC"); + + /* + * Initialize the data structure. The data structure contains a pdl device initialization + * object which we store to be able to reinitialize the ADC if needed. + */ + ifx_init_pdl_struct(data, cfg); + ifx_init_channel_cfg(data); + + if (Cy_HPPASS_SAR_Init(&data->hppass_sar_obj) != CY_RSLT_SUCCESS) { + LOG_ERR("Failed to initialize HPPASS SAR ADC"); + return -EIO; + } + + if (ifx_hppass_ac_init_adc() != CY_RSLT_SUCCESS) { + LOG_ERR("HPPASS AC failed to initialize ADC"); + return -EIO; + } + +#if defined(CONFIG_ADC_ASYNC) + Cy_HPPASS_SAR_Result_SetInterruptMask(CY_HPPASS_INTR_SAR_RESULT_GROUP_0); + cfg->irq_func(); +#endif /* CONFIG_ADC_ASYNC */ + + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#ifdef CONFIG_ADC_ASYNC +#define ADC_IFX_HPPASS_SAR_DRIVER_API(n) \ + static DEVICE_API(adc, adc_ifx_hppass_sar_driver_api_##n) = { \ + .channel_setup = ifx_hppass_sar_adc_channel_setup, \ + .read = ifx_hppass_sar_adc_read, \ + .read_async = ifx_hppass_sar_adc_read_async, \ + .ref_internal = DT_INST_PROP(n, vref_mv), \ + }; +#else +#define ADC_IFX_HPPASS_SAR_DRIVER_API(n) \ + static DEVICE_API(adc, adc_ifx_hppass_sar_driver_api_##n) = { \ + .channel_setup = ifx_hppass_sar_adc_channel_setup, \ + .read = ifx_hppass_sar_adc_read, \ + .ref_internal = DT_INST_PROP(n, vref_mv), \ + }; +#endif + +/* + * Devicetree channel mask generation + * + * dir_samp_en_mask: + * One bit per direct sampler channel (0..11) that has a child node. + * + * mux_samp_en_mask: + * One bit per mux sampler group: + * Bit0 -> any of channels 12..15 present + * Bit1 -> any of channels 16..19 present + * Bit2 -> any of channels 20..23 present + * Bit3 -> any of channels 24..27 present + */ + +#define IFX_HPPASS_SAR_CH_EXISTS(inst, ch) DT_NODE_EXISTS(DT_CHILD(DT_DRV_INST(inst), channel_##ch)) + +/* Direct sampler bitmap (0..11) */ +#define IFX_HPPASS_SAR_DIR_MASK(inst) \ + ((IFX_HPPASS_SAR_CH_EXISTS(inst, 0) ? BIT(0) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 1) ? BIT(1) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 2) ? BIT(2) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 3) ? BIT(3) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 4) ? BIT(4) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 5) ? BIT(5) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 6) ? BIT(6) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 7) ? BIT(7) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 8) ? BIT(8) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 9) ? BIT(9) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 10) ? BIT(10) : 0) | \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 11) ? BIT(11) : 0)) + +/* Group presence helpers */ +#define IFX_HPPASS_SAR_GRP0_PRESENT(inst) \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 12) || IFX_HPPASS_SAR_CH_EXISTS(inst, 13) || \ + IFX_HPPASS_SAR_CH_EXISTS(inst, 14) || IFX_HPPASS_SAR_CH_EXISTS(inst, 15)) + +#define IFX_HPPASS_SAR_GRP1_PRESENT(inst) \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 16) || IFX_HPPASS_SAR_CH_EXISTS(inst, 17) || \ + IFX_HPPASS_SAR_CH_EXISTS(inst, 18) || IFX_HPPASS_SAR_CH_EXISTS(inst, 19)) + +#define IFX_HPPASS_SAR_GRP2_PRESENT(inst) \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 20) || IFX_HPPASS_SAR_CH_EXISTS(inst, 21) || \ + IFX_HPPASS_SAR_CH_EXISTS(inst, 22) || IFX_HPPASS_SAR_CH_EXISTS(inst, 23)) + +#define IFX_HPPASS_SAR_GRP3_PRESENT(inst) \ + (IFX_HPPASS_SAR_CH_EXISTS(inst, 24) || IFX_HPPASS_SAR_CH_EXISTS(inst, 25) || \ + IFX_HPPASS_SAR_CH_EXISTS(inst, 26) || IFX_HPPASS_SAR_CH_EXISTS(inst, 27)) + +/* Mux sampler enable mask (bit per group if any channel in that group exists) */ +#define IFX_HPPASS_SAR_MUX_MASK(inst) \ + ((IFX_HPPASS_SAR_GRP0_PRESENT(inst) ? BIT(0) : 0) | \ + (IFX_HPPASS_SAR_GRP1_PRESENT(inst) ? BIT(1) : 0) | \ + (IFX_HPPASS_SAR_GRP2_PRESENT(inst) ? BIT(2) : 0) | \ + (IFX_HPPASS_SAR_GRP3_PRESENT(inst) ? BIT(3) : 0)) + +/* Device instantiation */ +#define IFX_HPPASS_SAR_ADC_INIT(n) \ + ADC_IFX_HPPASS_SAR_DRIVER_API(n); \ + static void ifx_hppass_sar_adc_config_func_##n(void); \ + static const struct ifx_hppass_sar_adc_config ifx_hppass_sar_adc_config_##n = { \ + .irq_priority = DT_INST_IRQ(n, priority), \ + .irq_num = DT_INST_IRQN(n), \ + .irq_func = ifx_hppass_sar_adc_config_func_##n, \ + .dir_samp_en_mask = IFX_HPPASS_SAR_DIR_MASK(n), \ + .mux_samp_en_mask = IFX_HPPASS_SAR_MUX_MASK(n), \ + .vref_internal_source = DT_INST_PROP(n, ref_internal_source), \ + .gain_cal = DT_INST_PROP(n, gain_cal), \ + .offset_cal = DT_INST_PROP(n, offset_cal), \ + .linear_cal = DT_INST_PROP(n, linear_cal)}; \ + static struct ifx_hppass_sar_adc_data ifx_hppass_sar_adc_data_##n = { \ + ADC_CONTEXT_INIT_TIMER(ifx_hppass_sar_adc_data_##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(ifx_hppass_sar_adc_data_##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(ifx_hppass_sar_adc_data_##n, ctx), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &ifx_hppass_sar_adc_init, NULL, &ifx_hppass_sar_adc_data_##n, \ + &ifx_hppass_sar_adc_config_##n, POST_KERNEL, \ + CONFIG_ADC_INFINEON_HPPASS_SAR_INIT_PRIORITY, \ + &adc_ifx_hppass_sar_driver_api_##n); \ + static void ifx_hppass_sar_adc_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), ifx_hppass_sar_adc_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +DT_INST_FOREACH_STATUS_OKAY(IFX_HPPASS_SAR_ADC_INIT) diff --git a/drivers/audio/CMakeLists.txt b/drivers/audio/CMakeLists.txt index 2c98e885468a0..f70c78cbfc114 100644 --- a/drivers/audio/CMakeLists.txt +++ b/drivers/audio/CMakeLists.txt @@ -17,3 +17,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_PCM1681 pcm1681.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_MAX98091 max98091.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_AMBIQ_PDM dmic_ambiq_pdm.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_DA7212 da7212.c) +zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_NXP_MICFIL dmic_nxp_micfil.c) diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index 0f9c5f0fae1fb..396aa2c3e59c6 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -68,6 +68,7 @@ source "drivers/audio/Kconfig.mpxxdtyy" source "drivers/audio/Kconfig.dmic_pdm_nrfx" source "drivers/audio/Kconfig.dmic_mcux" source "drivers/audio/Kconfig.dmic_ambiq_pdm" +source "drivers/audio/Kconfig.dmic_nxp_micfil" endif # AUDIO_DMIC diff --git a/drivers/audio/Kconfig.dmic_nxp_micfil b/drivers/audio/Kconfig.dmic_nxp_micfil new file mode 100644 index 0000000000000..35f56b312e30b --- /dev/null +++ b/drivers/audio/Kconfig.dmic_nxp_micfil @@ -0,0 +1,22 @@ +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +config AUDIO_DMIC_NXP_MICFIL + bool "NXP MICFIL driver" + default y + depends on DT_HAS_NXP_MICFIL_ENABLED + select CLOCK_CONTROL + select PINCTRL + help + Enable NXP MICFIL driver. + +if AUDIO_DMIC_NXP_MICFIL + +config DMIC_NXP_MICFIL_QUEUE_SIZE + int "Message queue depth" + default 4 + help + Depth of the message queue used to pass filled buffers to the app. + +endif # AUDIO_DMIC_NXP_MICFIL diff --git a/drivers/audio/dmic_nrfx_pdm.c b/drivers/audio/dmic_nrfx_pdm.c index c2c80a7414c1e..a2d630f847a98 100644 --- a/drivers/audio/dmic_nrfx_pdm.c +++ b/drivers/audio/dmic_nrfx_pdm.c @@ -24,11 +24,15 @@ LOG_MODULE_REGISTER(dmic_nrfx_pdm, CONFIG_AUDIO_DMIC_LOG_LEVEL); #define DMIC_NRFX_CLOCK_FACTOR 8192 #define DMIC_NRFX_AUDIO_CLOCK_FREQ DT_PROP_OR(NODE_AUDIOPLL, frequency, 0) #elif DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL) -#define DMIC_NRFX_AUDIO_CLOCK_FREQ DT_PROP(NODE_AUDIO_AUXPLL, nordic_frequency) -BUILD_ASSERT((DMIC_NRFX_AUDIO_CLOCK_FREQ == NRF_AUXPLL_FREQ_DIV_AUDIO_48K) || - (DMIC_NRFX_AUDIO_CLOCK_FREQ == NRF_AUXPLL_FREQ_DIV_AUDIO_44K1), +#define AUXPLL_FREQUENCY_SETTING DT_PROP(NODE_AUDIO_AUXPLL, nordic_frequency) +BUILD_ASSERT((AUXPLL_FREQUENCY_SETTING == NRF_AUXPLL_FREQ_DIV_AUDIO_48K) || + (AUXPLL_FREQUENCY_SETTING == NRF_AUXPLL_FREQ_DIV_AUDIO_44K1), "Unsupported Audio AUXPLL frequency selection for PDM"); + +#define DMIC_NRFX_AUDIO_CLOCK_FREQ CLOCK_CONTROL_NRF_AUXPLL_GET_FREQ(NODE_AUDIO_AUXPLL) + #define DMIC_NRFX_CLOCK_FREQ MHZ(32) + #else #define DMIC_NRFX_CLOCK_FREQ MHZ(32) #define DMIC_NRFX_CLOCK_FACTOR 4096 diff --git a/drivers/audio/dmic_nxp_micfil.c b/drivers/audio/dmic_nxp_micfil.c new file mode 100644 index 0000000000000..cecef93c9794f --- /dev/null +++ b/drivers/audio/dmic_nxp_micfil.c @@ -0,0 +1,666 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(dmic_nxp_micfil, CONFIG_AUDIO_DMIC_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_micfil + +struct nxp_micfil_cfg { + PDM_Type *base; + uint8_t quality_mode; + uint8_t fifo_watermark; + uint8_t cic_decimation_rate; + uint8_t chan_dc_cutoff[4]; /* dc remover cutoff frequency. */ + uint8_t chan_gain[4]; /* decimation filter gain. */ + uint8_t ch_enabled_mask; + uint32_t sample_rate; /* MICFIL sample rate */ + const struct device *clock_dev; + clock_control_subsys_t clock_name; + void (*irq_config_func)(const struct device *dev); + const struct pinctrl_dev_config *pcfg; +}; + +struct nxp_micfil_drv_data { + const struct device *dev; + PDM_Type *base; + struct k_msgq *rx_msg_queue; + volatile enum dmic_state state; + uint8_t hw_chan[4]; /* Requested hardware channel order, maximun 4 channels. */ + uint8_t channels; /* Current active channels count */ + uint8_t sample_bytes; /* bytes per sample (4 for 32bits). */ + uint16_t block_size; + struct k_mem_slab *mem_slab; + void *active_buf; /* Current active buffer */ + uint16_t write_off; /* Bytes written into active_buf */ + uint8_t fifo_wm; /* FIFO watermark */ +}; + +static int nxp_micfil_configure(const struct device *dev, struct dmic_cfg *cfg_in) +{ + struct nxp_micfil_drv_data *data = dev->data; + const struct nxp_micfil_cfg *cfg = dev->config; + struct pdm_chan_cfg *chan = &cfg_in->channel; + struct pcm_stream_cfg *stream = &cfg_in->streams[0]; + uint8_t act = 0U; + uint8_t micfil_idx; + enum pdm_lr lr; + + if (data->state == DMIC_STATE_ACTIVE) { + return -EBUSY; + } + + if (stream->pcm_rate == 0U || stream->pcm_width == 0U || + stream->mem_slab == NULL || stream->block_size == 0U) { + return -EINVAL; + } + + /* NXP MICFIL FIFO data width is 32-bit, only the 24 more significant bits + * have information, and the other bits are always 0. We output 32-bit PCM + * to keep alignment and simplify processing. + */ + if (stream->pcm_width != 32U) { + LOG_ERR("Unsupported pcm width %u", stream->pcm_width); + return -EINVAL; + } + + if (chan->req_num_streams != 1U) { + LOG_ERR("Only 1 stream supported"); + return -EINVAL; + } + + /* Basic channel count sanity and support limit */ + if ((chan->req_num_chan == 0U) || (chan->req_num_chan > ARRAY_SIZE(data->hw_chan))) { + LOG_ERR("Unsupported number of channels: %u", chan->req_num_chan); + return -ENOTSUP; + } + + /* Parse the requested logical channels and build HW channel list. */ + for (uint8_t index = 0U; index < chan->req_num_chan; index++) { + dmic_parse_channel_map(chan->req_chan_map_lo, chan->req_chan_map_hi, + index, &micfil_idx, &lr); + + /* New mapping model: + * - The micfil number in the map is used directly as the DMIC channel number, + * which corresponds to the hardware DATACH index. + * - The lr value selects which side (Left/Right) that DMIC channel represents + * within its stereo pair; adjacency/consecutiveness is validated later. + */ + uint8_t hw_chan = micfil_idx; + + if (hw_chan >= ARRAY_SIZE(data->hw_chan)) { + LOG_ERR("Requested hw channel index %u exceeds supported %u", + hw_chan, (uint32_t)ARRAY_SIZE(data->hw_chan)); + return -EINVAL; + } + + if ((cfg->ch_enabled_mask & BIT(hw_chan)) == 0U) { + LOG_ERR("Requested hw channel %u not enabled in DT", hw_chan); + return -EINVAL; + } + + /* Avoid duplicates */ + for (uint8_t i = 0U; i < act; i++) { + if (data->hw_chan[i] == hw_chan) { + LOG_ERR("Duplicate channel request for hw channel %u", hw_chan); + return -EINVAL; + } + } + + data->hw_chan[act++] = hw_chan; + } + + /* Ensure no extra mappings beyond req_num_chan are set */ + for (uint8_t index = chan->req_num_chan; index < 16U; index++) { + uint32_t chan_map; + + if (index < 8U) { + chan_map = (chan->req_chan_map_lo >> (index * 4U)) & 0xFU; + } else { + chan_map = (chan->req_chan_map_hi >> ((index - 8U) * 4U)) & 0xFU; + } + if (chan_map != 0U) { + LOG_ERR("Extra mapping present for logical channel %u", index); + return -EINVAL; + } + } + + /* Validate adjacency for each stereo pair (L/R in any order) + * New model requires paired dmics to use consecutive DMIC channel numbers + * (e.g., 0/1, 2/3, ...), not the same micfil number. This preserves the API + * constraint that L and R are adjacent while allowing explicit control + * over which channel number is Left/Right. + */ + for (uint8_t index = 0U; index + 1U < chan->req_num_chan; index += 2U) { + uint8_t micfil0, micfil1; + enum pdm_lr lr0, lr1; + + dmic_parse_channel_map(chan->req_chan_map_lo, chan->req_chan_map_hi, + index, &micfil0, &lr0); + dmic_parse_channel_map(chan->req_chan_map_lo, chan->req_chan_map_hi, + index + 1U, &micfil1, &lr1); + + if (lr0 == lr1) { + LOG_ERR("Pair %u/%u has same L/R selection", index, index + 1U); + return -EINVAL; + } + /* Require consecutive DMIC channel numbers within a pair (e.g., 0/1, 2/3). + * Enforce that the smaller of the two is even to avoid crossing pairs (e.g., 1/2). + */ + uint8_t minp = MIN(micfil0, micfil1); + uint8_t maxp = MAX(micfil0, micfil1); + + if (!((maxp == (uint8_t)(minp + 1U)) && ((minp & 0x1U) == 0U))) { + LOG_ERR("Pair %u/%u must map to consecutive DMIC channels.", + index, index + 1U); + return -EINVAL; + } + } + + if (act == 0U) { + LOG_ERR("No channels requested"); + return -EINVAL; + } + + data->channels = act; + data->sample_bytes = stream->pcm_width / 8U; + data->block_size = stream->block_size; + data->mem_slab = stream->mem_slab; + + /* Validate block_size alignment to complete frames */ + uint32_t frame_bytes = (uint32_t)data->channels * (uint32_t)data->sample_bytes; + + if ((data->block_size % frame_bytes) != 0U) { + LOG_ERR("block_size %u not aligned to frame size %u (channels=%u)", + data->block_size, (uint32_t)frame_bytes, data->channels); + return -EINVAL; + } + + /* Populate act_* fields according to accepted configuration */ + chan->act_num_streams = 1U; + chan->act_num_chan = chan->req_num_chan; + chan->act_chan_map_lo = chan->req_chan_map_lo; + chan->act_chan_map_hi = chan->req_chan_map_hi; + + data->state = DMIC_STATE_CONFIGURED; + + return 0; +} + +/** + * @brief Start MICFIL capture: + * 1. Allocate first buffer + * 2. Clear pending status + * 3. Configure FIFO interrupt + * 4. Enable requested channels + * 5. Enable MICFIL interface. + */ +static int nxp_micfil_start_capture(struct nxp_micfil_drv_data *data) +{ + void *buf = NULL; + + if (k_mem_slab_alloc(data->mem_slab, &buf, K_NO_WAIT) != 0) { + return -ENOMEM; + } + data->active_buf = buf; + data->write_off = 0; + + /* Clear any pending status before enabling data interrupts */ + uint32_t st = data->base->FIFO_STAT; + + if (st) { + data->base->FIFO_STAT = st; + } + st = data->base->STAT; + if (st) { + data->base->STAT = st; + } + + /* Enable data FIFO watermark interrupts only (DISEL=2). */ + data->base->CTRL_1 = ((data->base->CTRL_1 & ~PDM_CTRL_1_DISEL_MASK) | + PDM_CTRL_1_DISEL(2U)); + + /* Enable the requested channels */ + for (uint8_t index = 0; index < data->channels; index++) { + data->base->CTRL_1 |= BIT(data->hw_chan[index]); + } + + /* Enable MICFIL. */ + data->base->CTRL_1 |= PDM_CTRL_1_PDMIEN_MASK; + + data->state = DMIC_STATE_ACTIVE; + + return 0; +} + +/** + * @brief Stop/Pause/Reset MICFIL capture and clean up buffers/queues. + */ +static void nxp_micfil_stop_or_reset(struct nxp_micfil_drv_data *data, enum dmic_trigger cmd) +{ + /* Check if we are in a state that can be stopped/paused/reset */ + if (data->state == DMIC_STATE_ACTIVE || data->state == DMIC_STATE_PAUSED || + data->state == DMIC_STATE_ERROR) { + /* Disable MICFIL */ + data->base->CTRL_1 &= ~PDM_CTRL_1_PDMIEN_MASK; + + /* Disable the requested channels */ + for (uint8_t index = 0; index < data->channels; index++) { + data->base->CTRL_1 &= ~(BIT(data->hw_chan[index])); + } + + /* Disable fifo interrupts. */ + data->base->CTRL_1 &= ~PDM_CTRL_1_DISEL_MASK; + + /* Set state early so any in-flight ISR bails out */ + data->state = (cmd == DMIC_TRIGGER_RESET) ? DMIC_STATE_UNINIT : + DMIC_STATE_CONFIGURED; + + /* Clear any pending status flags */ + uint32_t st = data->base->FIFO_STAT; + + if (st) { + data->base->FIFO_STAT = st; + } + + st = data->base->STAT; + + if (st) { + data->base->STAT = st; + } + } + + /* Free active buffer if any */ + if (data->active_buf) { + void *tmp = data->active_buf; + + data->active_buf = NULL; + k_mem_slab_free(data->mem_slab, tmp); + } + + /* Drain and free any queued buffers that were filled + * but not yet read to avoid leaks. + */ + if (data->rx_msg_queue) { + void *queued; + + while (k_msgq_get(data->rx_msg_queue, &queued, K_NO_WAIT) == 0) { + k_mem_slab_free(data->mem_slab, queued); + } + } +} + +static int nxp_micfil_trigger(const struct device *dev, enum dmic_trigger cmd) +{ + struct nxp_micfil_drv_data *data = dev->data; + + switch (cmd) { + case DMIC_TRIGGER_START: + case DMIC_TRIGGER_RELEASE: { + /* Check if we are in a state that can be started/released */ + if (data->state != DMIC_STATE_CONFIGURED && + data->state != DMIC_STATE_PAUSED) { + return -EIO; + } + + int ret = nxp_micfil_start_capture(data); + + if (ret) { + LOG_ERR("Failed to start capture: %d", ret); + return ret; + } + + break; + } + + case DMIC_TRIGGER_PAUSE: + case DMIC_TRIGGER_STOP: + case DMIC_TRIGGER_RESET: { + nxp_micfil_stop_or_reset(data, cmd); + + break; + } + + default: + return -EINVAL; + } + + return 0; +} + +static int nxp_micfil_read(const struct device *dev, uint8_t stream, + void **buffer, size_t *size, int32_t timeout) +{ + struct nxp_micfil_drv_data *data = dev->data; + + ARG_UNUSED(stream); + + /* Check if we are in a state that can read */ + if (data->state != DMIC_STATE_ACTIVE && data->state != DMIC_STATE_PAUSED) { + return -EIO; + } + + /* Get the filled buffer from the queue */ + int ret = k_msgq_get(data->rx_msg_queue, buffer, SYS_TIMEOUT_MS(timeout)); + + if (ret == 0) { + *size = data->block_size; + return 0; + } + + /* Fallback: if active but no IRQ-produced data arrived within timeout, + * return a zero-filled block so API semantics (non-timeout) are satisfied. + */ + if (data->state == DMIC_STATE_ACTIVE) { + void *buf = NULL; + static uint32_t last_warn_ms; + + if (k_mem_slab_alloc(data->mem_slab, &buf, K_NO_WAIT) != 0) { + return ret; /* original error */ + } + /* Provide silence */ + (void)memset(buf, 0, data->block_size); + + uint32_t now = k_uptime_get_32(); + + if ((now - last_warn_ms) > 1000U) { + LOG_ERR("DMIC fallback: no IRQ data yet, returning silence\n"); + last_warn_ms = now; + } + + *buffer = buf; + *size = data->block_size; + + return 0; + } + + return ret; +} + +static void nxp_micfil_isr(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct nxp_micfil_drv_data *data = dev->data; + uint32_t state = data->base->FIFO_STAT; + + /* Clear status flags */ + if (state) { + data->base->FIFO_STAT = state; + } + + state = data->base->STAT; + + if (state) { + data->base->STAT = state; + } + + /* Check if we are in a state that can read */ + if (!data->active_buf || data->state != DMIC_STATE_ACTIVE) { + return; + } + + /* Read data from all enabled channels */ + uint8_t *dst = (uint8_t *)data->active_buf; + /* Each frame is channels * sample_bytes. Hardware returns 32-bit samples in DATACH[]. + * We output little-endian 32-bit PCM: LSB first, 4 bytes per sample. + */ + uint16_t frame_bytes = (uint16_t)(data->channels * data->sample_bytes); + /* Calculate how many complete frames are left in the current block that can be + * written. This limits the maximum number of frames that this ISR can take from + * the hardware FIFO to avoid write overflow and maintain frame alignment. + */ + uint16_t frames_remaining = (uint16_t)((data->block_size - data->write_off) / frame_bytes); + /* Read up to fifo_wm frames. */ + uint16_t frames_to_read = (uint16_t)data->fifo_wm; + + /* Adjust if more frames than remaining in buffer */ + if (frames_to_read > frames_remaining) { + frames_to_read = frames_remaining; + } + + /* Read frames from all active channels' FIFO. */ + for (uint16_t frame = 0; frame < frames_to_read; frame++) { + for (uint8_t chan = 0; chan < data->channels; chan++) { + /* Read one 32-bit sample from the selected hardware channel FIFO. */ + uint8_t hw = data->hw_chan[chan]; + volatile uint32_t raw_data = data->base->DATACH[hw]; + + dst[data->write_off + 0] = (uint8_t)(raw_data & 0xFFU); + dst[data->write_off + 1] = (uint8_t)((raw_data >> 8U) & 0xFFU); + dst[data->write_off + 2] = (uint8_t)((raw_data >> 16U) & 0xFFU); + dst[data->write_off + 3] = (uint8_t)((raw_data >> 24U) & 0xFFU); + + data->write_off += 4; + } + } + + /* Check if active buffer is full. Hand off to queue and rotate buffers safely. */ + if (data->write_off >= data->block_size) { + void *completed = data->active_buf; + void *new_buf = NULL; + + /* Allocate next buffer first to avoid using a freed buffer */ + if (k_mem_slab_alloc(data->mem_slab, &new_buf, K_NO_WAIT) != 0) { + /* No memory available: enter error state and stop capturing */ + data->active_buf = NULL; + data->state = DMIC_STATE_ERROR; + + /* Disable MICFIL */ + data->base->CTRL_1 &= ~PDM_CTRL_1_PDMIEN_MASK; + + /* Disable the requested channels */ + for (uint8_t index = 0; index < data->channels; index++) { + data->base->CTRL_1 &= ~(BIT(data->hw_chan[index])); + } + + /* Disable fifo interrupts. */ + data->base->CTRL_1 &= ~PDM_CTRL_1_DISEL_MASK; + return; + } + + /* Try to enqueue the completed buffer. If queue is full, free it. */ + if (k_msgq_put(data->rx_msg_queue, &completed, K_NO_WAIT) != 0) { + k_mem_slab_free(data->mem_slab, completed); + } + + /* Switch to the new active buffer */ + data->active_buf = new_buf; + data->write_off = 0; + } +} + +static int nxp_micfil_init(const struct device *dev) +{ + const struct nxp_micfil_cfg *cfg = dev->config; + struct nxp_micfil_drv_data *data = dev->data; + uint32_t clk_rate = 0U; + int ret; + + data->dev = dev; + data->base = cfg->base; + + if (cfg->clock_dev != NULL) { + ret = clock_control_on(cfg->clock_dev, cfg->clock_name); + if (ret) { + LOG_ERR("Device clock turn on failed"); + return ret; + } + + ret = clock_control_get_rate(cfg->clock_dev, cfg->clock_name, &clk_rate); + if (ret < 0) { + LOG_WRN("Device clock rate not available (%d)", ret); + } + } + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("Failed to configure pins (%d)", ret); + return ret; + } + + if (cfg->irq_config_func) { + cfg->irq_config_func(dev); + } + + /* MICFIL initialization. */ + /* Ensure module is enabled and interface/interrupts/channels + * are disabled before config. + */ + data->base->CTRL_1 &= ~(PDM_CTRL_1_MDIS_MASK | PDM_CTRL_1_PDMIEN_MASK | + PDM_CTRL_1_ERREN_MASK); + /* TODO: Use DT property instead of hardcoding channel numbers. */ + for (uint8_t ch = 0U; ch < 4U; ch++) { + data->base->CTRL_1 &= ~BIT(ch); + } + + /* Wait until all filters stopped if supported. */ + while ((data->base->STAT & PDM_STAT_BSY_FIL_MASK) != 0U) { + } + + /* Do a software reset pulse before configuration. */ + data->base->CTRL_1 |= PDM_CTRL_1_SRES_MASK; + + /* Configure quality mode, CIC decimation rate. */ + data->base->CTRL_2 &= ~(PDM_CTRL_2_QSEL_MASK | PDM_CTRL_2_CICOSR_MASK); + data->base->CTRL_2 |= PDM_CTRL_2_QSEL(cfg->quality_mode) | + PDM_CTRL_2_CICOSR(cfg->cic_decimation_rate); + + /* Configure FIFO watermark. */ + data->base->FIFO_CTRL = (data->base->FIFO_CTRL & ~PDM_FIFO_CTRL_FIFOWMK_MASK) | + PDM_FIFO_CTRL_FIFOWMK(cfg->fifo_watermark); + + /* Cache FIFO watermark for ISR. */ + data->fifo_wm = cfg->fifo_watermark; + + /* MICFIL channels initialization. */ + /* Configure DC remover cutoff per hardware channel. */ + for (uint8_t ch = 0U; ch < ARRAY_SIZE(cfg->chan_dc_cutoff); ch++) { + uint32_t mask = PDM_DC_CTRL_DCCONFIG0_MASK << (ch * 2U); + uint32_t val = (cfg->chan_dc_cutoff[ch] & PDM_DC_CTRL_DCCONFIG0_MASK) << (ch * 2U); + + data->base->DC_OUT_CTRL = ((data->base->DC_OUT_CTRL & ~mask) | val); + } + + /* Configure decimation-filter-gain per hardware channel. */ + for (uint8_t ch = 0U; ch < ARRAY_SIZE(cfg->chan_gain); ch++) { + uint32_t mask = PDM_RANGE_CTRL_RANGEADJ0_MASK << (ch * 4U); + uint32_t val = (cfg->chan_gain[ch] & PDM_RANGE_CTRL_RANGEADJ0_MASK) << (ch * 4U); + + data->base->RANGE_CTRL = ((data->base->RANGE_CTRL & ~mask) | val); + } + + /* Configure clock divider if clock rate and sample rate are known. */ + if (clk_rate != 0U && cfg->sample_rate != 0U) { + uint32_t osr_reg_max = (PDM_CTRL_2_CICOSR_MASK >> PDM_CTRL_2_CICOSR_SHIFT); + + if (cfg->cic_decimation_rate > osr_reg_max) { + LOG_ERR("CIC decimation rate %u exceeds max %u", + cfg->cic_decimation_rate, (uint32_t)osr_reg_max); + return -EINVAL; + } + + /* Real OSR per MCUX SDK: (max + 1 - programmed). */ + uint32_t real_osr = osr_reg_max + 1U - (uint32_t)cfg->cic_decimation_rate; + uint32_t micfil_clock_rate = cfg->sample_rate * real_osr * 8U; + + if (clk_rate < micfil_clock_rate) { + LOG_ERR("Clock rate %u too low for sample rate %u (OSR=%u)", + clk_rate, cfg->sample_rate, real_osr); + return -EINVAL; + } + + uint32_t reg_div = clk_rate / micfil_clock_rate; + + if (reg_div == 0U) { + reg_div = 1U; + } + + uint32_t clkdiv_max = (PDM_CTRL_2_CLKDIV_MASK >> PDM_CTRL_2_CLKDIV_SHIFT); + + if (reg_div > clkdiv_max) { + LOG_WRN("CLKDIV %u exceeds max %u, clamping", reg_div, clkdiv_max); + reg_div = clkdiv_max; + } + + data->base->CTRL_2 = (data->base->CTRL_2 & (~PDM_CTRL_2_CLKDIV_MASK)) | + PDM_CTRL_2_CLKDIV(reg_div); + + LOG_INF("MICFIL clk=%uHz sample=%u OSR=%u div=%u wm=%u", + clk_rate, cfg->sample_rate, real_osr, reg_div, cfg->fifo_watermark); + } else { + LOG_WRN("Clock rate or sample rate is zero, cannot set clock divider"); + } + + data->state = DMIC_STATE_INITIALIZED; + + return 0; +} + +static const struct _dmic_ops dmic_ops = { + .configure = nxp_micfil_configure, + .trigger = nxp_micfil_trigger, + .read = nxp_micfil_read, +}; + +#define NXP_MICFIL_IRQ_CONFIG(inst) \ + static void _CONCAT(irq_config, inst)(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nxp_micfil_isr, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN(inst)); \ + } + +/* Build per-hardware-channel DC cutoff array from DT child nodes. */ +#define DC_CUTOFF_ITEM(node_id) [DT_REG_ADDR(node_id)] = \ + DT_PROP(node_id, dc_remover_cutoff_freq), +/* Build per-hardware-channel OUT gain array from DT child nodes. */ +#define OUT_GAIN_ITEM(node_id) [DT_REG_ADDR(node_id)] = \ + DT_PROP_OR(node_id, decimation_filter_gain, 0), +/* Build bitmask of enabled channels by OR-ing BIT(reg) per child. */ +#define CH_BIT(node_id) | BIT(DT_REG_ADDR(node_id)) + +#define NXP_MICFIL_DEFINE(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + K_MSGQ_DEFINE(nxp_micfil_msgq##inst, sizeof(void *), \ + CONFIG_DMIC_NXP_MICFIL_QUEUE_SIZE, 4); \ + \ + NXP_MICFIL_IRQ_CONFIG(inst) \ + \ + static struct nxp_micfil_drv_data _CONCAT(data, inst) = { \ + .rx_msg_queue = &nxp_micfil_msgq##inst, \ + .state = DMIC_STATE_UNINIT, \ + }; \ + \ + static const struct nxp_micfil_cfg _CONCAT(cfg, inst) = { \ + .base = (PDM_Type *)DT_INST_REG_ADDR(inst), \ + .quality_mode = DT_INST_PROP(inst, quality_mode), \ + .fifo_watermark = DT_INST_PROP(inst, fifo_watermark), \ + .cic_decimation_rate = DT_INST_PROP(inst, cic_decimation_rate), \ + .chan_dc_cutoff = { DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, \ + DC_CUTOFF_ITEM) }, \ + .chan_gain = { DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, OUT_GAIN_ITEM) },\ + .ch_enabled_mask = (0 DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, CH_BIT)), \ + .sample_rate = DT_INST_PROP(inst, sample_rate), \ + .clock_dev = DEVICE_DT_GET_OR_NULL(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_name = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, name), \ + .irq_config_func = _CONCAT(irq_config, inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_micfil_init, NULL, \ + &_CONCAT(data, inst), &_CONCAT(cfg, inst), \ + POST_KERNEL, CONFIG_AUDIO_DMIC_INIT_PRIORITY, &dmic_ops); + +DT_INST_FOREACH_STATUS_OKAY(NXP_MICFIL_DEFINE) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 294a99baa05b9..21aeeb98ee242 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -156,7 +156,6 @@ config BT_SILABS_EFR32 default y depends on DT_HAS_SILABS_BT_HCI_EFR32_ENABLED depends on ZEPHYR_HAL_SILABS_MODULE_BLOBS || BUILD_ONLY_NO_BLOBS - depends on !PM || SOC_GECKO_PM_BACKEND_PMGR depends on SOC_GECKO_HAS_RADIO select SOC_GECKO_USE_RAIL select PSA_CRYPTO diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index 77b8ee64fa039..c60e41bcbd585 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -133,7 +133,7 @@ void register_radio_event(void) /* Getting next radio event time if any */ cmd_status = ll_intf_le_get_remaining_time_for_next_event(&next_radio_event_us); UNUSED(cmd_status); - __ASSERT(cmd_staus, "Unable to retrieve next radio event"); + __ASSERT(cmd_status, "Unable to retrieve next radio event"); if (next_radio_event_us == LL_DP_SLP_NO_WAKEUP) { /* No next radio event scheduled */ diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 13100d651592d..b4ebce89ee00a 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -40,6 +40,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SI32_AHB clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SI32_APB clock_control_si32_apb.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_control_smartbond.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_MC_CGM clock_control_nxp_mc_cgm.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RENESAS_RA_CGC clock_control_renesas_ra_cgc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RENESAS_RA_SUBCLK clock_control_renesas_ra_cgc_subclk.c) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index e2c4a071ab09a..2d5ed6198b840 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -86,6 +86,8 @@ source "drivers/clock_control/Kconfig.smartbond" 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.agilex5" diff --git a/drivers/clock_control/Kconfig.nxp_mc_cgm b/drivers/clock_control/Kconfig.nxp_mc_cgm new file mode 100644 index 0000000000000..aba3c9b54d9a3 --- /dev/null +++ b/drivers/clock_control/Kconfig.nxp_mc_cgm @@ -0,0 +1,9 @@ +# 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.silabs b/drivers/clock_control/Kconfig.silabs index 83926fe465cda..52e8ed7a4b0ed 100644 --- a/drivers/clock_control/Kconfig.silabs +++ b/drivers/clock_control/Kconfig.silabs @@ -5,5 +5,6 @@ config CLOCK_CONTROL_SILABS_SERIES bool "Silicon Labs Series 2+ clock control driver" default y depends on DT_HAS_SILABS_SERIES_CLOCK_ENABLED + select SILABS_SISDK_CLOCK_MANAGER help Enable Silicon Labs Series 2+ Clock Management Unit clock control driver. diff --git a/drivers/clock_control/clock_control_bl60x.c b/drivers/clock_control/clock_control_bl60x.c index 1d51cb663d508..64b905c748837 100644 --- a/drivers/clock_control/clock_control_bl60x.c +++ b/drivers/clock_control/clock_control_bl60x.c @@ -650,10 +650,14 @@ static void clock_control_bl60x_peripheral_clock_init(void) /* enable ADC clock routing */ regval |= (1 << 2); + /* enable SEC clock routing */ + regval |= (1 << 3); /* enable UART0 clock routing */ regval |= (1 << 16); /* enable I2C0 clock routing */ regval |= (1 << 19); + /* enable DMA clock routing */ + regval |= (1 << 12); sys_write32(regval, GLB_BASE + GLB_CGEN_CFG1_OFFSET); diff --git a/drivers/clock_control/clock_control_bl61x.c b/drivers/clock_control/clock_control_bl61x.c index f6e7f0b81b76e..034916b820d96 100644 --- a/drivers/clock_control/clock_control_bl61x.c +++ b/drivers/clock_control/clock_control_bl61x.c @@ -1005,6 +1005,8 @@ static void clock_control_bl61x_peripheral_clock_init(void) /* enable ADC clock routing */ regval |= (1 << 2); + /* enable SEC clock routing */ + regval |= (1 << 3); /* enable UART0 clock routing */ regval |= (1 << 16); /* enable UART1 clock routing */ @@ -1017,6 +1019,8 @@ static void clock_control_bl61x_peripheral_clock_init(void) regval |= (1 << 18); /* enable USB clock routing */ regval |= (1 << 13); + /* enable DMA clock routing */ + regval |= (1 << 12); sys_write32(regval, GLB_BASE + GLB_CGEN_CFG1_OFFSET); diff --git a/drivers/clock_control/clock_control_bl70x.c b/drivers/clock_control/clock_control_bl70x.c index 5568bbe5dfd87..898385d5e9fa2 100644 --- a/drivers/clock_control/clock_control_bl70x.c +++ b/drivers/clock_control/clock_control_bl70x.c @@ -530,10 +530,14 @@ static void clock_control_bl70x_peripheral_clock_init(void) /* enable ADC clock routing */ regval |= (1 << 2); + /* enable SEC clock routing */ + regval |= (1 << 3); /* enable UART0 clock routing */ regval |= (1 << 16); /* enable I2C0 clock routing */ regval |= (1 << 19); + /* enable DMA clock routing */ + regval |= (1 << 12); sys_write32(regval, GLB_BASE + GLB_CGEN_CFG1_OFFSET); diff --git a/drivers/clock_control/clock_control_mcux_scg.c b/drivers/clock_control/clock_control_mcux_scg.c index c1e7470abb9ab..ae04e73b33e70 100644 --- a/drivers/clock_control/clock_control_mcux_scg.c +++ b/drivers/clock_control/clock_control_mcux_scg.c @@ -46,7 +46,8 @@ static int mcux_scg_get_rate(const struct device *dev, case KINETIS_SCG_BUS_CLK: clock_name = kCLOCK_BusClk; break; -#if !(defined(CONFIG_SOC_MKE17Z7) || defined(CONFIG_SOC_MKE17Z9)) +#if !(defined(CONFIG_SOC_MKE17Z7) || defined(CONFIG_SOC_MKE17Z9) \ + || defined(CONFIG_SOC_SERIES_MCXE24X)) case KINETIS_SCG_FLEXBUS_CLK: clock_name = kCLOCK_FlexBusClk; break; diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 62eb489394562..f14aedf6c029a 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -185,6 +185,10 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, #endif #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(micfil)) + CLOCK_EnableClock(kCLOCK_Micfil); +#endif + return 0; } @@ -620,6 +624,12 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de *rate = CLOCK_GetLpspiClkFreq(1); break; #endif /* defined(CONFIG_SPI_NXP_LPSPI) */ + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(micfil)) + case MCUX_MICFIL_CLK: + *rate = CLOCK_GetMicfilClkFreq(); + break; +#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 new file mode 100644 index 0000000000000..6eca1da92c4ce --- /dev/null +++ b/drivers/clock_control/clock_control_nxp_mc_cgm.c @@ -0,0 +1,315 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_mc_cgm + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_CLOCK_CONTROL_LOG_LEVEL +#include +LOG_MODULE_REGISTER(clock_control); + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(fxosc), nxp_fxosc, okay) +const fxosc_config_t fxosc_config = {.freqHz = NXP_FXOSC_FREQ, + .workMode = NXP_FXOSC_WORKMODE, + .startupDelay = NXP_FXOSC_DELAY, + .overdriveProtect = NXP_FXOSC_OVERDRIVE}; +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), nxp_plldig, okay) +const pll_config_t pll_config = {.workMode = NXP_PLL_WORKMODE, + .preDiv = NXP_PLL_PREDIV, /* PLL input clock predivider: 2 */ + .postDiv = NXP_PLL_POSTDIV, + .multiplier = NXP_PLL_MULTIPLIER, + .fracLoopDiv = NXP_PLL_FRACLOOPDIV, + .stepSize = NXP_PLL_STEPSIZE, + .stepNum = NXP_PLL_STEPNUM, + .accuracy = NXP_PLL_ACCURACY, + .outDiv = NXP_PLL_OUTDIV_POINTER}; +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(mc_cgm), nxp_mc_cgm, okay) +const clock_pcfs_config_t pcfs_config = {.maxAllowableIDDchange = NXP_PLL_MAXIDOCHANGE, + .stepDuration = NXP_PLL_STEPDURATION, + .clkSrcFreq = NXP_PLL_CLKSRCFREQ}; +#endif + +static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) +{ +#if defined(CONFIG_CAN_MCUX_FLEXCAN) + switch ((uint32_t)sub_system) { + case MCUX_FLEXCAN0_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan0); + break; + case MCUX_FLEXCAN1_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan1); + break; + case MCUX_FLEXCAN2_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan2); + break; + case MCUX_FLEXCAN3_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan3); + break; + case MCUX_FLEXCAN4_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan4); + break; + 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; + case MCUX_LPUART1_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart1); + break; + case MCUX_LPUART2_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart2); + break; + case MCUX_LPUART3_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart3); + break; + case MCUX_LPUART4_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart4); + break; + case MCUX_LPUART5_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart5); + break; + case MCUX_LPUART6_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart6); + break; + case MCUX_LPUART7_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart7); + break; + case MCUX_LPUART8_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart8); + break; + case MCUX_LPUART9_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart9); + break; + case MCUX_LPUART10_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart10); + break; + case MCUX_LPUART11_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart11); + break; + case MCUX_LPUART12_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart12); + break; + case MCUX_LPUART13_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart13); + break; + case MCUX_LPUART14_CLK: + CLOCK_EnableClock(kCLOCK_Lpuart14); + break; + 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; + case MCUX_LPSPI1_CLK: + CLOCK_EnableClock(kCLOCK_Lpspi1); + break; + case MCUX_LPSPI2_CLK: + CLOCK_EnableClock(kCLOCK_Lpspi2); + break; + case MCUX_LPSPI3_CLK: + CLOCK_EnableClock(kCLOCK_Lpspi3); + break; + case MCUX_LPSPI4_CLK: + CLOCK_EnableClock(kCLOCK_Lpspi4); + break; + 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) */ + + return 0; +} + +static int mc_cgm_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) +{ + return 0; +} + +static int mc_cgm_get_subsys_rate(const struct device *dev, clock_control_subsys_t sub_system, + uint32_t *rate) +{ + uint32_t clock_name = (uint32_t)sub_system; + + switch (clock_name) { +#if defined(CONFIG_UART_MCUX_LPUART) + case MCUX_LPUART0_CLK: + case MCUX_LPUART8_CLK: + *rate = CLOCK_GetAipsPlatClkFreq(); + break; + case MCUX_LPUART1_CLK: + case MCUX_LPUART2_CLK: + case MCUX_LPUART3_CLK: + case MCUX_LPUART4_CLK: + case MCUX_LPUART5_CLK: + case MCUX_LPUART6_CLK: + case MCUX_LPUART7_CLK: + case MCUX_LPUART9_CLK: + case MCUX_LPUART10_CLK: + case MCUX_LPUART11_CLK: + case MCUX_LPUART12_CLK: + case MCUX_LPUART13_CLK: + case MCUX_LPUART14_CLK: + case MCUX_LPUART15_CLK: + *rate = CLOCK_GetAipsSlowClkFreq(); + break; +#endif /* defined(CONFIG_UART_MCUX_LPUART) */ + +#if defined(CONFIG_SPI_NXP_LPSPI) + case MCUX_LPSPI0_CLK: + *rate = CLOCK_GetAipsPlatClkFreq(); + break; + case MCUX_LPSPI1_CLK: + case MCUX_LPSPI2_CLK: + case MCUX_LPSPI3_CLK: + case MCUX_LPSPI4_CLK: + case MCUX_LPSPI5_CLK: + *rate = CLOCK_GetAipsSlowClkFreq(); + break; +#endif /* defined(CONFIG_SPI_NXP_LPSPI) */ + +#if defined(CONFIG_I2C_MCUX_LPI2C) + case MCUX_LPI2C0_CLK: + case MCUX_LPI2C1_CLK: + *rate = CLOCK_GetAipsSlowClkFreq(); + break; +#endif /* defined(CONFIG_I2C_MCUX_LPI2C) */ + +#if defined(CONFIG_CAN_MCUX_FLEXCAN) + case MCUX_FLEXCAN0_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(0); + break; + case MCUX_FLEXCAN1_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(1); + break; + case MCUX_FLEXCAN2_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(2); + break; + case MCUX_FLEXCAN3_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(3); + break; + case MCUX_FLEXCAN4_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(4); + break; + case MCUX_FLEXCAN5_CLK: + *rate = CLOCK_GetFlexcanPeClkFreq(5); + break; +#endif /* defined(CONFIG_CAN_MCUX_FLEXCAN) */ + } + return 0; +} + +static int mc_cgm_init(const struct device *dev) +{ +#if defined(FSL_FEATURE_PMC_HAS_LAST_MILE_REGULATOR) && (FSL_FEATURE_PMC_HAS_LAST_MILE_REGULATOR) + /* Enables PMC last mile regulator before enable PLL. */ + if ((PMC->LVSC & PMC_LVSC_LVD15S_MASK) != 0U) { + /* External bipolar junction transistor is connected between external voltage and + * V15 input pin. + */ + PMC->CONFIG |= PMC_CONFIG_LMBCTLEN_MASK; + } + while ((PMC->LVSC & PMC_LVSC_LVD15S_MASK) != 0U) { + } + PMC->CONFIG |= PMC_CONFIG_LMEN_MASK; + while ((PMC->CONFIG & PMC_CONFIG_LMSTAT_MASK) == 0u) { + } +#endif /* FSL_FEATURE_PMC_HAS_LAST_MILE_REGULATOR */ + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(firc), nxp_firc, okay) + /* Switch the FIRC_DIV_SEL to the desired diveder. */ + CLOCK_SetFircDiv(NXP_FIRC_DIV); + /* Disable FIRC in standby mode. */ + CLOCK_DisableFircInStandbyMode(); +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(sirc), nxp_sirc, okay) + /* Disable SIRC in standby mode. */ + CLOCK_DisableSircInStandbyMode(); +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(fxosc), nxp_fxosc, okay) + /* Enable FXOSC. */ + CLOCK_InitFxosc(&fxosc_config); +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), nxp_plldig, okay) + /* Enable PLL. */ + CLOCK_InitPll(&pll_config); +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(mc_cgm), nxp_mc_cgm, okay) + CLOCK_SelectSafeClock(kFIRC_CLK_to_MUX0); + /* Configure MUX_0_CSC dividers */ + CLOCK_SetClkMux0DivTriggerType(KCLOCK_CommonTriggerUpdate); + CLOCK_SetClkDiv(kCLOCK_DivCoreClk, NXP_PLL_MUX_0_DC_0_DIV); + CLOCK_SetClkDiv(kCLOCK_DivAipsPlatClk, NXP_PLL_MUX_0_DC_1_DIV); + CLOCK_SetClkDiv(kCLOCK_DivAipsSlowClk, NXP_PLL_MUX_0_DC_2_DIV); + CLOCK_SetClkDiv(kCLOCK_DivHseClk, NXP_PLL_MUX_0_DC_3_DIV); + CLOCK_SetClkDiv(kCLOCK_DivDcmClk, NXP_PLL_MUX_0_DC_4_DIV); +#ifdef MC_CGM_MUX_0_DC_5_DIV_MASK + CLOCK_SetClkDiv(kCLOCK_DivLbistClk, NXP_PLL_MUX_0_DC_5_DIV); +#endif +#ifdef MC_CGM_MUX_0_DC_6_DIV_MASK + CLOCK_SetClkDiv(kCLOCK_DivQspiClk, NXP_PLL_MUX_0_DC_6_DIV); +#endif + CLOCK_CommonTriggerClkMux0DivUpdate(); + CLOCK_ProgressiveClockFrequencySwitch(kPLL_PHI0_CLK_to_MUX0, &pcfs_config); +#endif + + /* Set SystemCoreClock variable. */ + SystemCoreClockUpdate(); + + return 0; +} + +static DEVICE_API(clock_control, mcux_mcxe31x_clock_api) = { + .on = mc_cgm_clock_control_on, + .off = mc_cgm_clock_control_off, + .get_rate = mc_cgm_get_subsys_rate, +}; + +DEVICE_DT_INST_DEFINE(0, mc_cgm_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &mcux_mcxe31x_clock_api); diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index 3b99555d1eead..2f0a581d24bec 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -1040,6 +1040,14 @@ int stm32_clock_control_init(const struct device *dev) #endif z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sram1)) + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AHBSRAM1); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sram2)) + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AHBSRAM2); +#endif +#endif /* Set up individual enabled clocks */ set_up_fixed_clock_sources(); diff --git a/drivers/comparator/Kconfig.silabs_acmp b/drivers/comparator/Kconfig.silabs_acmp index db684e91f9b39..79f574b017471 100644 --- a/drivers/comparator/Kconfig.silabs_acmp +++ b/drivers/comparator/Kconfig.silabs_acmp @@ -5,7 +5,7 @@ config COMPARATOR_SILABS_ACMP default y depends on DT_HAS_SILABS_ACMP_ENABLED select PINCTRL - select SOC_SILABS_ACMP + select SILABS_SISDK_ACMP help Enable the comparator driver for the Analog Comparator hardware block present on Silicon Labs devices. This block is commonly used to diff --git a/drivers/counter/Kconfig.gecko b/drivers/counter/Kconfig.gecko index ded39e296855f..ce2459e1a6c87 100644 --- a/drivers/counter/Kconfig.gecko +++ b/drivers/counter/Kconfig.gecko @@ -3,6 +3,8 @@ # Copyright (c) 2019, Piotr Mienkowski # SPDX-License-Identifier: Apache-2.0 +DT_CHOSEN_SILABS_SLEEPTIMER := silabs,sleeptimer + config COUNTER_GECKO_RTCC bool "Silicon Labs Gecko Counter (RTCC) driver" default y @@ -16,8 +18,8 @@ config COUNTER_GECKO_RTCC config COUNTER_GECKO_STIMER bool "Silicon Labs Gecko Counter Sleep Timer driver" default y - depends on DT_HAS_SILABS_GECKO_STIMER_ENABLED - select SOC_SILABS_SLEEPTIMER + depends on $(dt_chosen_enabled,$(DT_CHOSEN_SILABS_SLEEPTIMER)) + select SILABS_SISDK_SLEEPTIMER help Enable the counter driver for Sleep Timer module for Silicon Labs Gecko chips. diff --git a/drivers/counter/counter_cc23x0_lgpt.c b/drivers/counter/counter_cc23x0_lgpt.c index 1534cc70ea668..3ba0f94349f75 100644 --- a/drivers/counter/counter_cc23x0_lgpt.c +++ b/drivers/counter/counter_cc23x0_lgpt.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -23,11 +25,14 @@ LOG_MODULE_REGISTER(counter_cc23x0_lgpt, CONFIG_COUNTER_LOG_LEVEL); +#define LGPT_CLK_PRESCALE(pres) (((pres) + 1) << 8) + static void counter_cc23x0_lgpt_isr(const struct device *dev); struct counter_cc23x0_lgpt_config { struct counter_config_info counter_info; uint32_t base; + uint32_t clk_idx; uint32_t prescale; }; @@ -36,6 +41,22 @@ struct counter_cc23x0_lgpt_data { struct counter_top_cfg target_cfg; }; +static inline void lgpt_cc23x0_pm_policy_state_lock_get(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif +} + +static inline void lgpt_cc23x0_pm_policy_state_lock_put(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); +#endif +} + static int counter_cc23x0_lgpt_get_value(const struct device *dev, uint32_t *ticks) { const struct counter_cc23x0_lgpt_config *config = dev->config; @@ -221,6 +242,8 @@ static int counter_cc23x0_lgpt_start(const struct device *dev) { const struct counter_cc23x0_lgpt_config *config = dev->config; + lgpt_cc23x0_pm_policy_state_lock_get(); + LOG_DBG("[START] LGPT base[%x]\n", config->base); HWREG(config->base + LGPT_O_CTL) = LGPT_CTL_MODE_UP_PER; @@ -240,9 +263,41 @@ static int counter_cc23x0_lgpt_stop(const struct device *dev) /* Set to 0 to stop timer */ HWREG(config->base + LGPT_O_STARTCFG) = 0x0; + lgpt_cc23x0_pm_policy_state_lock_put(); + return 0; } +static void counter_cc23x0_lgpt_init_common(const struct device *dev) +{ + const struct counter_cc23x0_lgpt_config *config = dev->config; + + HWREG(config->base + LGPT_O_TGT) = config->counter_info.max_top_value; + HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(config->prescale); + HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0; +} + +#ifdef CONFIG_PM_DEVICE + +static int lgpt_cc23x0_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct counter_cc23x0_lgpt_config *config = dev->config; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + CLKCTLDisable(CLKCTL_BASE, config->clk_idx); + return 0; + case PM_DEVICE_ACTION_RESUME: + CLKCTLEnable(CLKCTL_BASE, config->clk_idx); + counter_cc23x0_lgpt_init_common(dev); + return 0; + default: + return -ENOTSUP; + } +} + +#endif /* CONFIG_PM_DEVICE */ + static DEVICE_API(counter, cc23x0_lgpt_api) = { .start = counter_cc23x0_lgpt_start, .stop = counter_cc23x0_lgpt_stop, @@ -255,48 +310,51 @@ static DEVICE_API(counter, cc23x0_lgpt_api) = { .get_freq = counter_cc23x0_lgpt_get_freq, }; -#define LGPT_CLK_PRESCALE(pres) ((pres + 1) << 8) - -#define LGPT_CC23X0_INIT_FUNC(inst) \ - static int counter_cc23x0_lgpt_init##inst(const struct device *dev) \ - { \ - const struct counter_cc23x0_lgpt_config *config = dev->config; \ - \ - CLKCTLEnable(CLKCTL_BASE, CLKCTL_LGPT##inst); \ - \ - IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ - counter_cc23x0_lgpt_isr, DEVICE_DT_INST_GET(inst), 0); \ - \ - irq_enable(DT_INST_IRQN(inst)); \ - \ - HWREG(config->base + LGPT_O_TGT) = config->counter_info.max_top_value; \ - \ - HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(config->prescale); \ - \ - HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0; \ - \ - return 0; \ +#define LGPT_CC23X0_INIT_FUNC(inst) \ + static int counter_cc23x0_lgpt_init##inst(const struct device *dev) \ + { \ + const struct counter_cc23x0_lgpt_config *config = dev->config; \ + \ + CLKCTLEnable(CLKCTL_BASE, config->clk_idx); \ + \ + IRQ_CONNECT(DT_INST_IRQN(inst), \ + DT_INST_IRQ(inst, priority), \ + counter_cc23x0_lgpt_isr, \ + DEVICE_DT_INST_GET(inst), \ + 0); \ + \ + irq_enable(DT_INST_IRQN(inst)); \ + \ + counter_cc23x0_lgpt_init_common(dev); \ + \ + return 0; \ } -#define CC23X0_LGPT_INIT(inst) \ - \ - LGPT_CC23X0_INIT_FUNC(inst); \ - \ - static const struct counter_cc23x0_lgpt_config cc23x0_lgpt_config_##inst = { \ - .counter_info = \ - { \ - .max_top_value = DT_INST_PROP(inst, max_top_value), \ - .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ - .channels = 3, \ - }, \ - .base = DT_INST_REG_ADDR(inst), \ - .prescale = DT_INST_PROP(inst, clk_prescale), \ - }; \ - \ - static struct counter_cc23x0_lgpt_data cc23x0_lgpt_data_##inst; \ - \ - DEVICE_DT_INST_DEFINE(inst, &counter_cc23x0_lgpt_init##inst, NULL, \ - &cc23x0_lgpt_data_##inst, &cc23x0_lgpt_config_##inst, POST_KERNEL, \ - CONFIG_COUNTER_INIT_PRIORITY, &cc23x0_lgpt_api); +#define CC23X0_LGPT_INIT(inst) \ + \ + LGPT_CC23X0_INIT_FUNC(inst); \ + PM_DEVICE_DT_INST_DEFINE(inst, lgpt_cc23x0_pm_action); \ + \ + static const struct counter_cc23x0_lgpt_config cc23x0_lgpt_config_##inst = { \ + .counter_info = { \ + .max_top_value = DT_INST_PROP(inst, max_top_value), \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 3, \ + }, \ + .base = DT_INST_REG_ADDR(inst), \ + .clk_idx = CLKCTL_LGPT##inst, \ + .prescale = DT_INST_PROP(inst, clk_prescale), \ + }; \ + \ + static struct counter_cc23x0_lgpt_data cc23x0_lgpt_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, \ + &counter_cc23x0_lgpt_init##inst, \ + PM_DEVICE_DT_INST_GET(inst), \ + &cc23x0_lgpt_data_##inst, \ + &cc23x0_lgpt_config_##inst, \ + POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &cc23x0_lgpt_api); DT_INST_FOREACH_STATUS_OKAY(CC23X0_LGPT_INIT); diff --git a/drivers/counter/counter_cc23x0_rtc.c b/drivers/counter/counter_cc23x0_rtc.c index 97085359d26bf..bf6c1e9869983 100644 --- a/drivers/counter/counter_cc23x0_rtc.c +++ b/drivers/counter/counter_cc23x0_rtc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -153,6 +154,23 @@ static uint32_t counter_cc23x0_get_pending_int(const struct device *dev) return -ESRCH; } +#ifdef CONFIG_PM_DEVICE + +static int rtc_cc23x0_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + return 0; + case PM_DEVICE_ACTION_RESUME: + counter_cc23x0_get_pending_int(dev); + return 0; + default: + return -ENOTSUP; + } +} + +#endif /* CONFIG_PM_DEVICE */ + static uint32_t counter_cc23x0_get_top_value(const struct device *dev) { ARG_UNUSED(dev); @@ -221,21 +239,22 @@ static DEVICE_API(counter, rtc_cc23x0_api) = { .get_freq = counter_cc23x0_get_freq, }; -#define CC23X0_INIT(inst) \ - static const struct counter_cc23x0_config cc23x0_config_##inst = { \ - .counter_info = \ - { \ - .max_top_value = UINT32_MAX, \ - .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ - .channels = 1, \ - }, \ - .base = DT_INST_REG_ADDR(inst), \ - }; \ - \ - static struct counter_cc23x0_data cc23x0_data_##inst; \ - \ - DEVICE_DT_INST_DEFINE(0, &counter_cc23x0_init, NULL, &cc23x0_data_##inst, \ - &cc23x0_config_##inst, POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, \ - &rtc_cc23x0_api); +#define CC23X0_INIT(inst) \ + PM_DEVICE_DT_INST_DEFINE(inst, rtc_cc23x0_pm_action); \ + \ + static const struct counter_cc23x0_config cc23x0_config_##inst = { \ + .counter_info = { \ + .max_top_value = UINT32_MAX, \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 1, \ + }, \ + .base = DT_INST_REG_ADDR(inst), \ + }; \ + \ + static struct counter_cc23x0_data cc23x0_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(0, &counter_cc23x0_init, PM_DEVICE_DT_INST_GET(inst), \ + &cc23x0_data_##inst, &cc23x0_config_##inst, POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, &rtc_cc23x0_api); DT_INST_FOREACH_STATUS_OKAY(CC23X0_INIT) diff --git a/drivers/counter/counter_gecko_stimer.c b/drivers/counter/counter_gecko_stimer.c index 029ccd2d920e4..63060f4f47f40 100644 --- a/drivers/counter/counter_gecko_stimer.c +++ b/drivers/counter/counter_gecko_stimer.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT silabs_gecko_stimer - #include #include #include @@ -21,7 +19,7 @@ LOG_MODULE_REGISTER(counter_gecko, CONFIG_COUNTER_LOG_LEVEL); -#define DT_RTC DT_COMPAT_GET_ANY_STATUS_OKAY(silabs_gecko_stimer) +#define DT_RTC DT_CHOSEN(silabs_sleeptimer) #define STIMER_ALARM_NUM 2 #define STIMER_MAX_VALUE 0xFFFFFFFFUL @@ -273,7 +271,7 @@ static DEVICE_API(counter, counter_gecko_driver_api) = { .get_top_value = counter_gecko_get_top_value, }; -BUILD_ASSERT((DT_INST_PROP(0, prescaler) > 0U) && (DT_INST_PROP(0, prescaler) <= 32768U)); +BUILD_ASSERT((DT_PROP(DT_RTC, prescaler) > 0U) && (DT_PROP(DT_RTC, prescaler) <= 32768U)); static void counter_gecko_0_irq_config(void) { @@ -281,22 +279,22 @@ static void counter_gecko_0_irq_config(void) IRQ_DIRECT_CONNECT(DT_IRQ(DT_RTC, irq), DT_IRQ(DT_RTC, priority), CONCAT(DT_STRING_UPPER_TOKEN_BY_IDX(DT_RTC, interrupt_names, 0), _IRQHandler), 0); - irq_enable(DT_INST_IRQN(0)); + irq_enable(DT_IRQN(DT_RTC)); #endif } static const struct counter_gecko_config counter_gecko_0_config = { .info = { .max_top_value = STIMER_MAX_VALUE, - .freq = DT_INST_PROP(0, clock_frequency) / DT_INST_PROP(0, prescaler), + .freq = DT_PROP(DT_RTC, clock_frequency) / DT_PROP(DT_RTC, prescaler), .flags = COUNTER_CONFIG_INFO_COUNT_UP, .channels = STIMER_ALARM_NUM, }, .irq_config = counter_gecko_0_irq_config, - .prescaler = DT_INST_PROP(0, prescaler), + .prescaler = DT_PROP(DT_RTC, prescaler), }; static struct counter_gecko_data counter_gecko_0_data; -DEVICE_DT_INST_DEFINE(0, counter_gecko_init, NULL, &counter_gecko_0_data, &counter_gecko_0_config, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &counter_gecko_driver_api); +DEVICE_DT_DEFINE(DT_RTC, counter_gecko_init, NULL, &counter_gecko_0_data, &counter_gecko_0_config, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &counter_gecko_driver_api); diff --git a/drivers/crypto/crypto_mchp_xec_symcr.c b/drivers/crypto/crypto_mchp_xec_symcr.c index 0845009802457..3d3ea836475f2 100644 --- a/drivers/crypto/crypto_mchp_xec_symcr.c +++ b/drivers/crypto/crypto_mchp_xec_symcr.c @@ -358,7 +358,7 @@ static int xec_symcr_do_hash(struct hash_ctx *ctx, struct hash_pkt *pkt, bool fi hs->blklen = 0; /* consumed */ } - ret = mchp_xec_rom_hash_feed_wrapper(c, (const uint8_t *)pkt->in_buf, fill_len); + ret = mchp_xec_rom_hash_feed_wrapper(c, pkt->in_buf, fill_len); if (ret) { LOG_ERR("ROM hash feed error %d", ret); return ret; diff --git a/drivers/crypto/crypto_rts5912_sha.c b/drivers/crypto/crypto_rts5912_sha.c index 113c8d8a90b56..dc4ab4ec89e9e 100644 --- a/drivers/crypto/crypto_rts5912_sha.c +++ b/drivers/crypto/crypto_rts5912_sha.c @@ -122,7 +122,7 @@ static int rts5912_sha256_process(const struct device *dev, uint8_t *input, size return 0; } -static int rts5912_sha256_update(const struct device *dev, uint8_t *input, size_t len) +static int rts5912_sha256_update(const struct device *dev, const uint8_t *input, size_t len) { struct rts5912_sha256_context *rts5912_sha256_ctx = dev->data; uint32_t remain, fill, blk_size = 0, ret_val = 0; diff --git a/drivers/crypto/crypto_smartbond.c b/drivers/crypto/crypto_smartbond.c index 1cff9f046c4bc..3861e74409aa4 100644 --- a/drivers/crypto/crypto_smartbond.c +++ b/drivers/crypto/crypto_smartbond.c @@ -390,7 +390,7 @@ static int crypto_smartbond_hash_set_algo(enum hash_algo algo) return 0; } -static int crypto_smartbond_set_in_out_buf(uint8_t *in_buf, uint8_t *out_buf, int len) +static int crypto_smartbond_set_in_out_buf(const uint8_t *in_buf, uint8_t *out_buf, int len) { if (in_buf == NULL) { return -EIO; diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index 0fc94d1e2e7d5..d76dffad7eb40 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -300,7 +300,9 @@ static int stm32_sdmmc_dma_init(struct stm32_sdmmc_priv *priv) return err; } __HAL_LINKDMA(&priv->hsd, hdmatx, priv->dma_tx_handle); - HAL_DMA_Init(&priv->dma_tx_handle); + if (HAL_DMA_Init(&priv->dma_tx_handle) != HAL_OK) { + return -EIO; + } err = stm32_sdmmc_configure_dma(&priv->dma_rx_handle, &priv->dma_rx); if (err) { @@ -308,7 +310,9 @@ static int stm32_sdmmc_dma_init(struct stm32_sdmmc_priv *priv) return err; } __HAL_LINKDMA(&priv->hsd, hdmarx, priv->dma_rx_handle); - HAL_DMA_Init(&priv->dma_rx_handle); + if (HAL_DMA_Init(&priv->dma_rx_handle) != HAL_OK) { + return -EIO; + } #endif /* STM32_SDMMC_USE_DMA_SHARED */ return err; @@ -332,14 +336,17 @@ static int stm32_sdmmc_dma_deinit(struct stm32_sdmmc_priv *priv) #else struct sdmmc_dma_stream *dma_tx = &priv->dma_tx; struct sdmmc_dma_stream *dma_rx = &priv->dma_rx; + HAL_StatusTypeDef __maybe_unused hal_ret; ret = dma_stop(dma_tx->dev, dma_tx->channel); __ASSERT(ret == 0, "TX DMA channel index corrupted"); - HAL_DMA_DeInit(&priv->dma_tx_handle); + hal_ret = HAL_DMA_DeInit(&priv->dma_tx_handle); + __ASSERT_NO_MSG(hal_ret == HAL_OK); ret = dma_stop(dma_rx->dev, dma_rx->channel); __ASSERT(ret == 0, "RX DMA channel index corrupted"); - HAL_DMA_DeInit(&priv->dma_rx_handle); + hal_ret = HAL_DMA_DeInit(&priv->dma_rx_handle); + __ASSERT_NO_MSG(hal_ret == HAL_OK); #endif return 0; } @@ -361,6 +368,7 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) { const struct device *dev = disk->dev; struct stm32_sdmmc_priv *priv = dev->data; + HAL_StatusTypeDef hal_ret; int err; err = stm32_sdmmc_pwr_on(priv); @@ -412,11 +420,11 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) } #ifdef CONFIG_SDMMC_STM32_EMMC - err = HAL_MMC_Init(&priv->hsd); + hal_ret = HAL_MMC_Init(&priv->hsd); #else - err = HAL_SD_Init(&priv->hsd); + hal_ret = HAL_SD_Init(&priv->hsd); #endif - if (err != HAL_OK) { + if (hal_ret != HAL_OK) { LOG_ERR("failed to init stm32_sdmmc (ErrorCode 0x%X)", priv->hsd.ErrorCode); err = -EIO; goto error; @@ -424,8 +432,8 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) if (SDMMC_BUS_WIDTH != SDMMC_BUS_WIDE_1B) { priv->hsd.Init.BusWide = SDMMC_BUS_WIDTH; - err = HAL_SD_ConfigWideBusOperation(&priv->hsd, priv->hsd.Init.BusWide); - if (err != HAL_OK) { + hal_ret = HAL_SD_ConfigWideBusOperation(&priv->hsd, priv->hsd.Init.BusWide); + if (hal_ret != HAL_OK) { LOG_ERR("failed to configure wide bus operation (ErrorCode 0x%X)", priv->hsd.ErrorCode); err = -EIO; @@ -449,9 +457,11 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv) { - int err = 0; + HAL_StatusTypeDef hal_ret; #if STM32_SDMMC_USE_DMA + int err; + err = stm32_sdmmc_dma_deinit(priv); if (err) { LOG_ERR("DMA deinit failed"); @@ -460,14 +470,14 @@ static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv) #endif #if defined(CONFIG_SDMMC_STM32_EMMC) - err = HAL_MMC_DeInit(&priv->hsd); + hal_ret = HAL_MMC_DeInit(&priv->hsd); #else - err = HAL_SD_DeInit(&priv->hsd); + hal_ret = HAL_SD_DeInit(&priv->hsd); stm32_sdmmc_clock_disable(priv); #endif - if (err != HAL_OK) { + if (hal_ret != HAL_OK) { LOG_ERR("failed to deinit stm32_sdmmc (ErrorCode 0x%X)", priv->hsd.ErrorCode); - return err; + return -EIO; } #if !defined(CONFIG_SDMMC_STM32_EMMC) @@ -499,23 +509,32 @@ static int stm32_sdmmc_is_card_in_transfer(HandleTypeDef *hsd) static int stm32_sdmmc_read_blocks(HandleTypeDef *hsd, uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector) { + HAL_StatusTypeDef hal_ret; + #if STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) #ifdef CONFIG_SDMMC_STM32_EMMC - return HAL_MMC_ReadBlocks_DMA(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_MMC_ReadBlocks_DMA(hsd, data_buf, start_sector, num_sector); #else - return HAL_SD_ReadBlocks_DMA(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_SD_ReadBlocks_DMA(hsd, data_buf, start_sector, num_sector); #endif -#else +#else /* STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) */ #ifdef CONFIG_SDMMC_STM32_EMMC - return HAL_MMC_ReadBlocks_IT(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_MMC_ReadBlocks_IT(hsd, data_buf, start_sector, num_sector); #else - return HAL_SD_ReadBlocks_IT(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_SD_ReadBlocks_IT(hsd, data_buf, start_sector, num_sector); #endif -#endif +#endif /* STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) */ + + if (hal_ret != HAL_OK) { + LOG_ERR("sd read block failed %d", hal_ret); + return -EIO; + } + + return 0; } static int stm32_sdmmc_access_read(struct disk_info *disk, uint8_t *data_buf, @@ -537,16 +556,17 @@ static int stm32_sdmmc_access_read(struct disk_info *disk, uint8_t *data_buf, #endif err = stm32_sdmmc_read_blocks(&priv->hsd, data_buf, start_sector, num_sector); - if (err != HAL_OK) { - LOG_ERR("sd read block failed %d", err); - err = -EIO; + if (err != 0) { goto end; } k_sem_take(&priv->sync, K_FOREVER); #if STM32_SDMMC_USE_DMA_SHARED - HAL_DMA_DeInit(&priv->dma_txrx_handle); + if (HAL_DMA_DeInit(&priv->dma_txrx_handle) != HAL_OK) { + err = -EIO; + goto end; + } #endif if (priv->status != DISK_STATUS_OK) { @@ -567,23 +587,32 @@ static int stm32_sdmmc_write_blocks(HandleTypeDef *hsd, uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector) { + HAL_StatusTypeDef hal_ret; + #if STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) #ifdef CONFIG_SDMMC_STM32_EMMC - return HAL_MMC_WriteBlocks_DMA(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_MMC_WriteBlocks_DMA(hsd, data_buf, start_sector, num_sector); #else - return HAL_SD_WriteBlocks_DMA(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_SD_WriteBlocks_DMA(hsd, data_buf, start_sector, num_sector); #endif -#else +#else /* STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) */ #ifdef CONFIG_SDMMC_STM32_EMMC - return HAL_MMC_WriteBlocks_IT(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_MMC_WriteBlocks_IT(hsd, data_buf, start_sector, num_sector); #else - return HAL_SD_WriteBlocks_IT(hsd, data_buf, start_sector, num_sector); + hal_ret = HAL_SD_WriteBlocks_IT(hsd, data_buf, start_sector, num_sector); #endif -#endif +#endif /* STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) */ + + if (hal_ret != HAL_OK) { + LOG_ERR("sd write block failed %d", hal_ret); + return -EIO; + } + + return 0; } static int stm32_sdmmc_access_write(struct disk_info *disk, @@ -606,16 +635,18 @@ static int stm32_sdmmc_access_write(struct disk_info *disk, #endif err = stm32_sdmmc_write_blocks(&priv->hsd, (uint8_t *)data_buf, start_sector, num_sector); - if (err != HAL_OK) { - LOG_ERR("sd write block failed %d", err); - err = -EIO; + if (err != 0) { goto end; } k_sem_take(&priv->sync, K_FOREVER); #if STM32_SDMMC_USE_DMA_SHARED - HAL_DMA_DeInit(&priv->dma_txrx_handle); + if (HAL_DMA_DeInit(&priv->dma_txrx_handle) != HAL_OK) { + LOG_ERR("DMA deinit error"); + err = -EIO; + goto end; + } #endif if (priv->status != DISK_STATUS_OK) { @@ -635,9 +666,9 @@ static int stm32_sdmmc_access_write(struct disk_info *disk, static int stm32_sdmmc_get_card_info(HandleTypeDef *hsd, CardInfoTypeDef *info) { #ifdef CONFIG_SDMMC_STM32_EMMC - return HAL_MMC_GetCardInfo(hsd, info); + return (HAL_MMC_GetCardInfo(hsd, info) == HAL_OK) ? 0 : -EIO; #else - return HAL_SD_GetCardInfo(hsd, info); + return (HAL_SD_GetCardInfo(hsd, info) == HAL_OK) ? 0 : -EIO; #endif } @@ -652,15 +683,15 @@ static int stm32_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd, switch (cmd) { case DISK_IOCTL_GET_SECTOR_COUNT: err = stm32_sdmmc_get_card_info(&priv->hsd, &info); - if (err != HAL_OK) { - return -EIO; + if (err != 0) { + return err; } *(uint32_t *)buff = info.LogBlockNbr; break; case DISK_IOCTL_GET_SECTOR_SIZE: err = stm32_sdmmc_get_card_info(&priv->hsd, &info); - if (err != HAL_OK) { - return -EIO; + if (err != 0) { + return err; } *(uint32_t *)buff = info.LogBlockSize; break; @@ -876,6 +907,13 @@ void stm32_sdmmc_get_card_cid(const struct device *dev, uint32_t cid[4]) memcpy(cid, &priv->hsd.CID, sizeof(priv->hsd.CID)); } +void stm32_sdmmc_get_card_csd(const struct device *dev, uint32_t csd[4]) +{ + const struct stm32_sdmmc_priv *priv = dev->data; + + memcpy(csd, &priv->hsd.CSD, sizeof(priv->hsd.CSD)); +} + #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0)) #if STM32_SDMMC_USE_DMA diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 240e7f364e182..8186dc8963c61 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -56,3 +56,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_WCH dma_wch.c) zephyr_library_sources_ifdef(CONFIG_DMA_TI_CC23X0 dma_ti_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_DMA_NPCX_GDMA dma_npcx_gdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_SF32LB dma_sf32lb.c) +zephyr_library_sources_ifdef(CONFIG_DMA_BFLB dma_bflb.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 47254e3ba3372..8612da612f7f2 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -103,4 +103,6 @@ source "drivers/dma/Kconfig.npcx" source "drivers/dma/Kconfig.sf32lb" +source "drivers/dma/Kconfig.bflb" + endif # DMA diff --git a/drivers/dma/Kconfig.bflb b/drivers/dma/Kconfig.bflb new file mode 100644 index 0000000000000..61a0bc081371f --- /dev/null +++ b/drivers/dma/Kconfig.bflb @@ -0,0 +1,9 @@ +# Copyright (c) 2025 MASSDRIVER EI +# SPDX-License-Identifier: Apache-2.0 + +config DMA_BFLB + bool "Bouffalo Lab DMA driver" + default y + depends on DT_HAS_BFLB_DMA_ENABLED + help + DMA driver for Bouffalo Lab SoCs diff --git a/drivers/dma/Kconfig.silabs b/drivers/dma/Kconfig.silabs index 54d617b4ab743..f6f1d2086c3cd 100644 --- a/drivers/dma/Kconfig.silabs +++ b/drivers/dma/Kconfig.silabs @@ -5,7 +5,7 @@ config DMA_SILABS_LDMA bool "Silabs DMA driver" default y select SYS_MEM_BLOCKS - select SOC_GECKO_LDMA + select SILABS_SISDK_LDMA depends on DT_HAS_SILABS_LDMA_ENABLED help Driver for Silabs DMA. diff --git a/drivers/dma/dma_bflb.c b/drivers/dma/dma_bflb.c new file mode 100644 index 0000000000000..18ec33ba66b22 --- /dev/null +++ b/drivers/dma/dma_bflb.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_dma + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(dma_bflb, CONFIG_DMA_LOG_LEVEL); + +#include +#include +#include +#include +#include + +#ifdef CONFIG_SOC_SERIES_BL61X +#define BFLB_DMA_CLOCK_ADDR (GLB_BASE + GLB_DMA_CFG0_OFFSET) +#else +#define BFLB_DMA_CLOCK_ADDR (GLB_BASE + GLB_CLK_CFG2_OFFSET) +#endif + +#define BFLB_DMA_CH_OFFSET(n) ((n + 1) * 0x100) + +#define BFLB_DMA_CH_NB DT_INST_PROP(0, dma_channels) + +#define BFLB_DMA_WIDTH_BYTE 0 +#define BFLB_DMA_WIDTH_2BYTE 1 +#define BFLB_DMA_WIDTH_WORD 2 +#define BFLB_DMA_WIDTH_2WORD 3 + +#define BFLB_DMA_BURST_1 0 +#define BFLB_DMA_BURST_4 1 +#define BFLB_DMA_BURST_8 2 +#define BFLB_DMA_BURST_16 3 + +#define BFLB_DMA_FLOW_M_M 0 +#define BFLB_DMA_FLOW_M_P 1 +#define BFLB_DMA_FLOW_P_M 2 +#define BFLB_DMA_FLOW_P_P 3 +#define BFLB_DMA_FLOW_SOFT 0 +#define BFLB_DMA_FLOW_PERI 4 + +struct dma_bflb_channel { + dma_callback_t cb; + void *user_data; +}; + +struct dma_bflb_data { + struct dma_bflb_channel channels[BFLB_DMA_CH_NB]; +}; + +struct dma_bflb_config { + uint32_t base_reg; +}; + +static size_t dma_bflb_get_transfer_size(const struct device *dev, uint32_t channel) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t control; + size_t size = 1; + uint32_t width; + + control = sys_read32(cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + width = (control & DMA_SWIDTH_MASK) >> DMA_SWIDTH_SHIFT; + /* Using SOURCE data width */ + switch (width) { + case BFLB_DMA_WIDTH_BYTE: + break; + case BFLB_DMA_WIDTH_2BYTE: + size *= 2U; + break; + case BFLB_DMA_WIDTH_WORD: + size *= 4U; + break; + case BFLB_DMA_WIDTH_2WORD: + size *= 8U; + break; + default: + return 0; + } + + return size; +} + +static void dma_bflb_isr(const struct device *dev) +{ + const struct dma_bflb_config *cfg = dev->config; + struct dma_bflb_data *data = dev->data; + uint32_t status, error; + + status = sys_read32(cfg->base_reg + DMA_INTTCSTATUS_OFFSET); + error = sys_read32(cfg->base_reg + DMA_INTERRORSTATUS_OFFSET); + + for (uint8_t i = 0; i < BFLB_DMA_CH_NB; i++) { + if (data->channels[i].cb) { + if (error & (1 << i)) { + data->channels[i].cb(dev, data->channels[i].user_data, i, -1); + } else if (status & (1 << i)) { + data->channels[i].cb(dev, data->channels[i].user_data, i, 0); + } + } + } + + sys_write32(error, cfg->base_reg + DMA_INTERRCLR_OFFSET); + sys_write32(status, cfg->base_reg + DMA_INTTCCLEAR_OFFSET); +} + +static int dma_bflb_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + struct dma_bflb_data *data = dev->data; + const struct dma_bflb_config *cfg = dev->config; + struct dma_block_config *block = config->head_block; + struct dma_bflb_channel *channel_control; + uint32_t ch_config; + uint32_t control = 0; + uint16_t size; + + if (channel >= BFLB_DMA_CH_NB) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + if (config->block_count > 1) { + LOG_ERR("Chained transfers not supported"); + /* TODO: add support for LLI chained transfers. */ + return -ENOTSUP; + } + + if (block->source_addr_adj == 1 || block->dest_addr_adj == 1) { + LOG_ERR("Decrement not supported"); + return -EINVAL; + } + + ch_config = sys_read32(cfg->base_reg + + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + ch_config &= ~DMA_LLICOUNTER_MASK; + + ch_config &= ~DMA_FLOWCNTRL_MASK; + if (config->channel_direction == MEMORY_TO_MEMORY) { + ch_config |= BFLB_DMA_FLOW_M_M << DMA_FLOWCNTRL_SHIFT; + } else if (config->channel_direction == PERIPHERAL_TO_MEMORY) { + ch_config |= BFLB_DMA_FLOW_P_M << DMA_FLOWCNTRL_SHIFT; + } else if (config->channel_direction == MEMORY_TO_PERIPHERAL) { + ch_config |= BFLB_DMA_FLOW_M_P << DMA_FLOWCNTRL_SHIFT; + } else if (config->channel_direction == PERIPHERAL_TO_PERIPHERAL) { + ch_config |= BFLB_DMA_FLOW_P_P << DMA_FLOWCNTRL_SHIFT; + } else { + LOG_ERR("Direction error. %d", config->channel_direction); + return -EINVAL; + } + + /* For memory we write here */ + sys_write32(block->source_address, cfg->base_reg + DMA_CxSRCADDR_OFFSET + + BFLB_DMA_CH_OFFSET(channel)); + sys_write32(block->dest_address, cfg->base_reg + DMA_CxDSTADDR_OFFSET + + BFLB_DMA_CH_OFFSET(channel)); + + /* For peripherals we treat the address as the peripheral ID */ + ch_config &= ~DMA_SRCPERIPHERAL_MASK; + ch_config &= ~DMA_DSTPERIPHERAL_MASK; + ch_config |= (block->source_address << DMA_SRCPERIPHERAL_SHIFT) + & DMA_SRCPERIPHERAL_MASK; + ch_config |= (block->dest_address << DMA_DSTPERIPHERAL_SHIFT) + & DMA_DSTPERIPHERAL_MASK; + + if (!block->source_addr_adj) { + control |= DMA_SI; + } + if (!block->dest_addr_adj) { + control |= DMA_DI; + } + + if (config->source_data_size == 1) { + control |= BFLB_DMA_WIDTH_BYTE << DMA_SWIDTH_SHIFT; + } else if (config->source_data_size == 2) { + control |= BFLB_DMA_WIDTH_2BYTE << DMA_SWIDTH_SHIFT; + } else if (config->source_data_size == 4) { + control |= BFLB_DMA_WIDTH_WORD << DMA_SWIDTH_SHIFT; + } else if (config->source_data_size == 8) { + control |= BFLB_DMA_WIDTH_2WORD << DMA_SWIDTH_SHIFT; + } else { + LOG_ERR("Invalid source data size"); + return -EINVAL; + } + + if (config->dest_data_size == 1) { + control |= BFLB_DMA_WIDTH_BYTE << DMA_DWIDTH_SHIFT; + } else if (config->dest_data_size == 2) { + control |= BFLB_DMA_WIDTH_2BYTE << DMA_DWIDTH_SHIFT; + } else if (config->dest_data_size == 4) { + control |= BFLB_DMA_WIDTH_WORD << DMA_DWIDTH_SHIFT; + } else if (config->dest_data_size == 8) { + control |= BFLB_DMA_WIDTH_2WORD << DMA_DWIDTH_SHIFT; + } else { + LOG_ERR("Invalid destination data size"); + return -EINVAL; + } + + if (config->source_burst_length == 1) { + control |= BFLB_DMA_BURST_1 << DMA_SBSIZE_SHIFT; + } else if (config->source_burst_length == 4) { + control |= BFLB_DMA_BURST_4 << DMA_SBSIZE_SHIFT; + } else if (config->source_burst_length == 8) { + control |= BFLB_DMA_BURST_8 << DMA_SBSIZE_SHIFT; + } else if (config->source_burst_length == 16) { + control |= BFLB_DMA_BURST_16 << DMA_SBSIZE_SHIFT; + } else { + LOG_ERR("Invalid source burst size"); + return -EINVAL; + } + + if (config->dest_burst_length == 1) { + control |= BFLB_DMA_BURST_1 << DMA_DBSIZE_SHIFT; + } else if (config->dest_burst_length == 4) { + control |= BFLB_DMA_BURST_4 << DMA_DBSIZE_SHIFT; + } else if (config->dest_burst_length == 8) { + control |= BFLB_DMA_BURST_8 << DMA_DBSIZE_SHIFT; + } else if (config->dest_burst_length == 16) { + control |= BFLB_DMA_BURST_16 << DMA_DBSIZE_SHIFT; + } else { + LOG_ERR("Invalid destination burst size"); + return -EINVAL; + } + + size = block->block_size / config->dest_data_size; + control |= (size << DMA_TRANSFERSIZE_SHIFT) & DMA_TRANSFERSIZE_MASK; + + /* Clear interrupts */ + sys_write32(1U << channel, cfg->base_reg + DMA_INTERRCLR_OFFSET); + sys_write32(1U << channel, cfg->base_reg + DMA_INTTCCLEAR_OFFSET); + + /* Unmask interrupts */ + ch_config &= ~(DMA_ITC | DMA_IE); + + sys_write32(control, cfg->base_reg + + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + sys_write32(ch_config, cfg->base_reg + + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + channel_control = &data->channels[channel]; + channel_control->cb = config->dma_callback; + channel_control->user_data = config->user_data; + + LOG_DBG("Configured channel %d for %08X to %08X (%u)", + channel, + block->source_address, + block->dest_address, + block->block_size); + + return 0; +} + +static int dma_bflb_start(const struct device *dev, uint32_t channel) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t config; + +#ifdef CONFIG_SOC_SERIES_BL61X + /* on BL61x, we must invalidate the output address to update the memory data */ + uint32_t control = sys_read32( + cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + size_t pending_length = (control & DMA_TRANSFERSIZE_MASK) >> DMA_TRANSFERSIZE_SHIFT; + uintptr_t addr = sys_read32( + cfg->base_reg + DMA_CxDSTADDR_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + pending_length *= dma_bflb_get_transfer_size(dev, channel); + sys_cache_data_flush_and_invd_range((void *)addr, pending_length); +#endif + + config = sys_read32(cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + config |= DMA_E; + sys_write32(config, cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + return 0; +} + +static int dma_bflb_stop(const struct device *dev, uint32_t channel) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t config; + + config = sys_read32(cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + config &= ~DMA_E; + sys_write32(config, cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + return 0; +} + +static int dma_bflb_reload(const struct device *dev, uint32_t channel, + uint32_t src, uint32_t dst, size_t size) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t control; + size_t sizediv; + + control = sys_read32(cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + sizediv = dma_bflb_get_transfer_size(dev, channel); + if (!sizediv) { + return -EINVAL; + } + + sys_write32(src, cfg->base_reg + DMA_CxSRCADDR_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + sys_write32(dst, cfg->base_reg + DMA_CxDSTADDR_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + size /= sizediv; + control &= ~DMA_TRANSFERSIZE_MASK; + control |= (size << DMA_TRANSFERSIZE_SHIFT) & DMA_TRANSFERSIZE_MASK; + sys_write32(control, cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + LOG_DBG("Reloaded channel %d for %08X to %08X (%u)", + channel, src, dst, size); + + return 0; +} + +static int dma_bflb_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t config, control, direction; + + if (channel >= BFLB_DMA_CH_NB || stat == NULL) { + return -EINVAL; + } + + config = sys_read32(cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + control = sys_read32(cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(channel)); + + if (config & DMA_E) { + stat->busy = true; + } else { + stat->busy = false; + } + + stat->pending_length = (control & DMA_TRANSFERSIZE_MASK) >> DMA_TRANSFERSIZE_SHIFT; + stat->pending_length *= dma_bflb_get_transfer_size(dev, channel); + if (!stat->pending_length) { + return -EINVAL; + } + + direction = ((config & DMA_FLOWCNTRL_MASK) >> DMA_FLOWCNTRL_SHIFT) & BFLB_DMA_FLOW_P_P; + switch (direction) { + case BFLB_DMA_FLOW_M_M: + stat->dir = MEMORY_TO_MEMORY; + break; + case BFLB_DMA_FLOW_M_P: + stat->dir = MEMORY_TO_PERIPHERAL; + break; + case BFLB_DMA_FLOW_P_M: + stat->dir = PERIPHERAL_TO_MEMORY; + break; + case BFLB_DMA_FLOW_P_P: + stat->dir = PERIPHERAL_TO_PERIPHERAL; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int dma_bflb_init(const struct device *dev) +{ + const struct dma_bflb_config *cfg = dev->config; + uint32_t tmp; + + /* Ensure DMA clocks are enabled*/ + tmp = sys_read32(BFLB_DMA_CLOCK_ADDR); + tmp |= 0xFF << GLB_DMA_CLK_EN_POS; + sys_write32(tmp, BFLB_DMA_CLOCK_ADDR); + + /* Enable DMA controller */ + tmp = sys_read32(cfg->base_reg + DMA_TOP_CONFIG_OFFSET); + tmp |= DMA_E; + sys_write32(tmp, cfg->base_reg + DMA_TOP_CONFIG_OFFSET); + + /* Ensure all channels are disabled and their interrupts masked */ + for (int i = 0; i < BFLB_DMA_CH_NB; i++) { + tmp = sys_read32(cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(i)); + tmp &= ~DMA_E; + tmp |= DMA_ITC | DMA_IE; + sys_write32(tmp, cfg->base_reg + DMA_CxCONFIG_OFFSET + BFLB_DMA_CH_OFFSET(i)); + tmp = sys_read32(cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(i)); + tmp &= ~DMA_I; + sys_write32(tmp, cfg->base_reg + DMA_CxCONTROL_OFFSET + BFLB_DMA_CH_OFFSET(i)); + } + + /* Ensure all interrupts are cleared */ + sys_write32(0xFF, cfg->base_reg + DMA_INTERRCLR_OFFSET); + sys_write32(0xFF, cfg->base_reg + DMA_INTTCCLEAR_OFFSET); + + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), dma_bflb_isr, + DEVICE_DT_INST_GET(0), 0); + irq_enable(DT_INST_IRQN(0)); + + return 0; +} + +static struct dma_bflb_data bflb_dma_data = {0}; +static struct dma_bflb_config bflb_dma_config = { + .base_reg = DT_INST_REG_ADDR(0), +}; + +static DEVICE_API(dma, dma_bflb_api) = { + .config = dma_bflb_configure, + .start = dma_bflb_start, + .stop = dma_bflb_stop, + .reload = dma_bflb_reload, + .get_status = dma_bflb_get_status, +}; + +DEVICE_DT_INST_DEFINE(0, dma_bflb_init, NULL, + &bflb_dma_data, &bflb_dma_config, PRE_KERNEL_1, + CONFIG_DMA_INIT_PRIORITY, &dma_bflb_api); diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index ed9431af645fc..0f7b85cbc0d20 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -966,6 +966,8 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, 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); #else LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT); @@ -1041,11 +1043,11 @@ static int dma_mcux_edma_init(const struct device *dev) #define IRQ_CONFIG(n, idx, fn) \ { \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + IRQ_CONNECT(DT_INST_IRQN_BY_IDX(n, idx), \ DT_INST_IRQ_BY_IDX(n, idx, priority), \ fn, \ DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ + irq_enable(DT_INST_IRQN_BY_IDX(n, idx)); \ } #define EDMA_CHANNELS_MASK(n) static uint32_t edma_channel_mask_##n[] = \ diff --git a/drivers/dma/dma_sam_xdmac.c b/drivers/dma/dma_sam_xdmac.c index 436991a482af2..eff294c6481e4 100644 --- a/drivers/dma/dma_sam_xdmac.c +++ b/drivers/dma/dma_sam_xdmac.c @@ -26,13 +26,21 @@ LOG_MODULE_REGISTER(dma_sam_xdmac); #define XDMAC_INT_ERR (XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE) -#define DMA_CHANNELS_NO XDMACCHID_NUMBER +#define DMA_CHANNELS_MAX 31 + +enum dma_state { + DMA_STATE_INIT = 0, + DMA_STATE_CONFIGURED, + DMA_STATE_RUNNING, + DMA_STATE_SUSPENDED, +}; /* DMA channel configuration */ struct sam_xdmac_channel_cfg { void *user_data; dma_callback_t callback; uint32_t data_size; + enum dma_state state; }; /* Device constant configuration parameters */ @@ -45,13 +53,15 @@ struct sam_xdmac_dev_cfg { /* Device run time data */ struct sam_xdmac_dev_data { - struct sam_xdmac_channel_cfg dma_channels[DMA_CHANNELS_NO]; + struct dma_context dma_ctx; + struct sam_xdmac_channel_cfg dma_channels[DMA_CHANNELS_MAX + 1]; }; static void sam_xdmac_isr(const struct device *dev) { const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; Xdmac * const xdmac = dev_cfg->regs; struct sam_xdmac_channel_cfg *channel_cfg; @@ -61,11 +71,12 @@ static void sam_xdmac_isr(const struct device *dev) /* Get global interrupt status */ isr_status = xdmac->XDMAC_GIS; - for (int channel = 0; channel < DMA_CHANNELS_NO; channel++) { + for (int channel = 0; channel < channel_num; channel++) { if (!(isr_status & (1 << channel))) { continue; } + dev_data->dma_channels[channel].state = DMA_STATE_CONFIGURED; channel_cfg = &dev_data->dma_channels[channel]; /* Get channel errors */ @@ -83,10 +94,13 @@ int sam_xdmac_channel_configure(const struct device *dev, uint32_t channel, struct sam_xdmac_channel_config *param) { const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; Xdmac * const xdmac = dev_cfg->regs; - if (channel >= DMA_CHANNELS_NO) { + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); return -EINVAL; } @@ -126,10 +140,13 @@ int sam_xdmac_transfer_configure(const struct device *dev, uint32_t channel, struct sam_xdmac_transfer_config *param) { const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; Xdmac * const xdmac = dev_cfg->regs; - if (channel >= DMA_CHANNELS_NO) { + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); return -EINVAL; } @@ -172,6 +189,8 @@ int sam_xdmac_transfer_configure(const struct device *dev, uint32_t channel, /* Set next descriptor configuration */ xdmac->XDMAC_CHID[channel].XDMAC_CNDC = param->ndc; + dev_data->dma_channels[channel].state = DMA_STATE_CONFIGURED; + return 0; } @@ -179,13 +198,21 @@ static int sam_xdmac_config(const struct device *dev, uint32_t channel, struct dma_config *cfg) { struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; struct sam_xdmac_channel_config channel_cfg; struct sam_xdmac_transfer_config transfer_cfg; uint32_t burst_size; uint32_t data_size; int ret; - if (channel >= DMA_CHANNELS_NO) { + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); + return -EINVAL; + } + + if (dev_data->dma_channels[channel].state != DMA_STATE_INIT && + dev_data->dma_channels[channel].state != DMA_STATE_CONFIGURED) { + LOG_ERR("Config Channel %d at invalidate state", channel); return -EINVAL; } @@ -233,6 +260,10 @@ static int sam_xdmac_config(const struct device *dev, uint32_t channel, | XDMAC_CC_MBSIZE(burst_size == 0U ? 0 : burst_size - 1) | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_INCREMENTED_AM; +#if defined(CONFIG_SOC_SERIES_SAMA7G5) + /* When a memory-to-memory transfer is performed, configure PERID to 0x7F. */ + cfg->dma_slot = 0x7F; +#endif break; case MEMORY_TO_PERIPHERAL: channel_cfg.cfg = @@ -254,11 +285,14 @@ static int sam_xdmac_config(const struct device *dev, uint32_t channel, return -EINVAL; } - channel_cfg.cfg |= - XDMAC_CC_DWIDTH(data_size) - | XDMAC_CC_SIF_AHB_IF1 - | XDMAC_CC_DIF_AHB_IF1 - | XDMAC_CC_PERID(cfg->dma_slot); + channel_cfg.cfg |= XDMAC_CC_DWIDTH(data_size) | +#ifdef XDMAC_CC_SIF_AHB_IF1 + XDMAC_CC_SIF_AHB_IF1 | +#endif +#ifdef XDMAC_CC_DIF_AHB_IF1 + XDMAC_CC_DIF_AHB_IF1 | +#endif + XDMAC_CC_PERID(cfg->dma_slot); channel_cfg.ds_msp = 0U; channel_cfg.sus = 0U; channel_cfg.dus = 0U; @@ -300,11 +334,19 @@ static int sam_xdmac_transfer_reload(const struct device *dev, uint32_t channel, int sam_xdmac_transfer_start(const struct device *dev, uint32_t channel) { const struct sam_xdmac_dev_cfg *config = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; Xdmac * const xdmac = config->regs; - if (channel >= DMA_CHANNELS_NO) { - LOG_DBG("Channel %d out of range", channel); + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); + return -EINVAL; + } + + if (dev_data->dma_channels[channel].state != DMA_STATE_CONFIGURED && + dev_data->dma_channels[channel].state != DMA_STATE_RUNNING) { + LOG_ERR("Start Channel %d at invalidate state", channel); return -EINVAL; } @@ -319,16 +361,26 @@ int sam_xdmac_transfer_start(const struct device *dev, uint32_t channel) /* Enable channel */ xdmac->XDMAC_GE = XDMAC_GE_EN0 << channel; + dev_data->dma_channels[channel].state = DMA_STATE_RUNNING; + return 0; } int sam_xdmac_transfer_stop(const struct device *dev, uint32_t channel) { const struct sam_xdmac_dev_cfg *config = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; Xdmac * const xdmac = config->regs; - if (channel >= DMA_CHANNELS_NO) { + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); + return -EINVAL; + } + + if (dev_data->dma_channels[channel].state == DMA_STATE_INIT) { + LOG_ERR("Channel %d not configured", channel); return -EINVAL; } @@ -346,15 +398,24 @@ int sam_xdmac_transfer_stop(const struct device *dev, uint32_t channel) /* Clear the pending Interrupt Status bit(s) */ (void)xdmac->XDMAC_CHID[channel].XDMAC_CIS; + dev_data->dma_channels[channel].state = DMA_STATE_CONFIGURED; + return 0; } static int sam_xdmac_initialize(const struct device *dev) { const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; Xdmac * const xdmac = dev_cfg->regs; + dev_data->dma_ctx.dma_channels = FIELD_GET(XDMAC_GTYPE_NB_CH_Msk, xdmac->XDMAC_GTYPE) + 1; + if (dev_data->dma_ctx.dma_channels > DMA_CHANNELS_MAX + 1) { + LOG_ERR("Maximum supported channels is %d", DMA_CHANNELS_MAX + 1); + return -EINVAL; + } + /* Configure interrupts */ dev_cfg->irq_config(); @@ -375,6 +436,98 @@ static int sam_xdmac_initialize(const struct device *dev) return 0; } +static int xdmac_suspend(const struct device *dev, uint32_t channel) +{ + const struct sam_xdmac_dev_cfg *config = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; + + Xdmac * const xdmac = config->regs; + + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); + return -EINVAL; + } + + switch (dev_data->dma_channels[channel].state) { + case DMA_STATE_RUNNING: + break; + case DMA_STATE_SUSPENDED: + return 0; + default: + LOG_ERR("Suspend Channel %d at invalidate state", channel); + return -EINVAL; + } + + if (!(xdmac->XDMAC_GS & BIT(channel))) { + LOG_DBG("Channel %d not enabled", channel); + return -EINVAL; + } + +#if defined(CONFIG_SOC_SERIES_SAMX7X) + if (xdmac->XDMAC_GRS & BIT(channel) || xdmac->XDMAC_GWS & BIT(channel)) { +#elif defined(CONFIG_SOC_SERIES_SAMA7G5) + if (xdmac->XDMAC_GRSS & BIT(channel) || xdmac->XDMAC_GWSS & BIT(channel)) { +#else +#error Unsupported SoC family +#endif + LOG_DBG("Channel %d already suspended", channel); + return 0; + } + + xdmac->XDMAC_GRWS |= BIT(channel); + + dev_data->dma_channels[channel].state = DMA_STATE_SUSPENDED; + + return 0; +} + +static int xdmac_resume(const struct device *dev, uint32_t channel) +{ + const struct sam_xdmac_dev_cfg *config = dev->config; + struct sam_xdmac_dev_data *const dev_data = dev->data; + uint32_t channel_num = dev_data->dma_ctx.dma_channels; + + Xdmac * const xdmac = config->regs; + + if (channel >= channel_num) { + LOG_ERR("Channel %d out of range", channel); + return -EINVAL; + } + + switch (dev_data->dma_channels[channel].state) { + case DMA_STATE_SUSPENDED: + break; + case DMA_STATE_RUNNING: + return 0; + default: + LOG_ERR("Resume Channel %d at invalidate state", channel); + return -EINVAL; + } + + if (!(xdmac->XDMAC_GS & BIT(channel))) { + LOG_DBG("Channel %d not enabled", channel); + return -EINVAL; + } + +#if defined(CONFIG_SOC_SERIES_SAMX7X) + if (!(xdmac->XDMAC_GRS & BIT(channel) || xdmac->XDMAC_GWS & BIT(channel))) { +#elif defined(CONFIG_SOC_SERIES_SAMA7G5) + if (!(xdmac->XDMAC_GRSS & BIT(channel) || xdmac->XDMAC_GWSS & BIT(channel))) { +#else +#error Unsupported SoC family +#endif + LOG_DBG("Channel %d not suspended", channel); + return 0; + } + + xdmac->XDMAC_GRWR |= BIT(channel); + + dev_data->dma_channels[channel].state = DMA_STATE_RUNNING; + + return 0; +} + static int sam_xdmac_get_status(const struct device *dev, uint32_t channel, struct dma_status *status) { @@ -404,26 +557,34 @@ static DEVICE_API(dma, sam_xdmac_driver_api) = { .reload = sam_xdmac_transfer_reload, .start = sam_xdmac_transfer_start, .stop = sam_xdmac_transfer_stop, + .suspend = xdmac_suspend, + .resume = xdmac_resume, .get_status = sam_xdmac_get_status, }; -/* DMA0 */ - -static void dma0_sam_irq_config(void) -{ - IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), sam_xdmac_isr, - DEVICE_DT_INST_GET(0), 0); -} - -static const struct sam_xdmac_dev_cfg dma0_sam_config = { - .regs = (Xdmac *)DT_INST_REG_ADDR(0), - .irq_config = dma0_sam_irq_config, - .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(0), - .irq_id = DT_INST_IRQN(0), -}; - -static struct sam_xdmac_dev_data dma0_sam_data; - -DEVICE_DT_INST_DEFINE(0, sam_xdmac_initialize, NULL, - &dma0_sam_data, &dma0_sam_config, POST_KERNEL, - CONFIG_DMA_INIT_PRIORITY, &sam_xdmac_driver_api); +#define DMA_INIT(n) \ + static void dma##n##_irq_config(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + sam_xdmac_isr, DEVICE_DT_INST_GET(n), 0); \ + } \ + \ + static const struct sam_xdmac_dev_cfg dma##n##_config = { \ + .regs = (Xdmac *)DT_INST_REG_ADDR(n), \ + .irq_config = dma##n##_irq_config, \ + .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n), \ + .irq_id = DT_INST_IRQN(n), \ + }; \ + \ + static ATOMIC_DEFINE(dma_channels_atomic_##n, DMA_CHANNELS_MAX); \ + \ + static struct sam_xdmac_dev_data dma##n##_data = { \ + .dma_ctx.magic = DMA_MAGIC, \ + .dma_ctx.atomic = dma_channels_atomic_##n, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &sam_xdmac_initialize, NULL, \ + &dma##n##_data, &dma##n##_config, POST_KERNEL, \ + CONFIG_DMA_INIT_PRIORITY, &sam_xdmac_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DMA_INIT) diff --git a/drivers/dma/dma_silabs_siwx91x.c b/drivers/dma/dma_silabs_siwx91x.c index 7cd1290d336c0..21b06bc598158 100644 --- a/drivers/dma/dma_silabs_siwx91x.c +++ b/drivers/dma/dma_silabs_siwx91x.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include "rsi_rom_udma.h" #include "rsi_rom_udma_wrapper.h" @@ -39,6 +41,7 @@ struct dma_siwx91x_channel_info { void *cb_data; /* User callback data */ RSI_UDMA_DESC_T *sg_desc_addr_info; /* Scatter-Gather table start address */ enum dma_xfer_dir xfer_direction; /* mem<->mem ot per<->mem */ + bool channel_active; /* Channel active flag */ }; struct dma_siwx91x_config { @@ -60,6 +63,16 @@ struct dma_siwx91x_data { */ }; +static void siwx91x_dma_pm_policy_state_lock_get(void) +{ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +} + +static void siwx91x_dma_pm_policy_state_lock_put(void) +{ + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +} + static enum dma_xfer_dir siwx91x_transfer_direction(uint32_t dir) { if (dir == MEMORY_TO_MEMORY) { @@ -482,7 +495,17 @@ static int siwx91x_dma_start(const struct device *dev, uint32_t channel) return -EINVAL; } + /* Get the power management policy state lock */ + if (!data->zephyr_channel_info[channel].channel_active) { + siwx91x_dma_pm_policy_state_lock_get(); + data->zephyr_channel_info[channel].channel_active = true; + } + if (RSI_UDMA_ChannelEnable(udma_handle, channel) != 0) { + if (data->zephyr_channel_info[channel].channel_active) { + siwx91x_dma_pm_policy_state_lock_put(); + data->zephyr_channel_info[channel].channel_active = false; + } return -EINVAL; } @@ -510,6 +533,11 @@ static int siwx91x_dma_stop(const struct device *dev, uint32_t channel) return -EIO; } + if (data->zephyr_channel_info[channel].channel_active) { + siwx91x_dma_pm_policy_state_lock_put(); + data->zephyr_channel_info[channel].channel_active = false; + } + return 0; } @@ -560,8 +588,7 @@ bool siwx91x_dma_chan_filter(const struct device *dev, int channel, void *filter } } -/* Function to initialize DMA peripheral */ -static int siwx91x_dma_init(const struct device *dev) +static int dma_siwx91x_pm_action(const struct device *dev, enum pm_device_action action) { const struct dma_siwx91x_config *cfg = dev->config; struct dma_siwx91x_data *data = dev->data; @@ -573,25 +600,45 @@ static int siwx91x_dma_init(const struct device *dev) }; int ret; - ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys); - if (ret) { - return ret; - } + switch (action) { + case PM_DEVICE_ACTION_RESUME: + break; + case PM_DEVICE_ACTION_SUSPEND: + break; + case PM_DEVICE_ACTION_TURN_ON: + ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys); + if (ret < 0 && ret != -EALREADY) { + return ret; + } - udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL, - (uint32_t *)&data->udma_handle); - if (udma_handle != &data->udma_handle) { - return -EINVAL; + udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL, + (uint32_t *)&data->udma_handle); + if (udma_handle != &data->udma_handle) { + return -EINVAL; + } + + if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) { + return -EBUSY; + } + break; + case PM_DEVICE_ACTION_TURN_OFF: + break; + default: + return -ENOTSUP; } + return 0; +} + +/* Function to initialize DMA peripheral */ +static int siwx91x_dma_init(const struct device *dev) +{ + const struct dma_siwx91x_config *cfg = dev->config; + /* Connect the DMA interrupt */ cfg->irq_configure(); - if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) { - return -EBUSY; - } - - return 0; + return pm_device_driver_init(dev, dma_siwx91x_pm_action); } static void siwx91x_dma_isr(const struct device *dev) @@ -639,6 +686,10 @@ static void siwx91x_dma_isr(const struct device *dev) dev, data->zephyr_channel_info[channel].cb_data, channel, 0); } sys_write32(BIT(channel), (mem_addr_t)&cfg->reg->UDMA_DONE_STATUS_REG); + if (data->zephyr_channel_info[channel].channel_active) { + siwx91x_dma_pm_policy_state_lock_put(); + data->zephyr_channel_info[channel].channel_active = false; + } } else { /* Call UDMA ROM IRQ handler. */ ROMAPI_UDMA_WRAPPER_API->uDMAx_IRQHandler(&udma_resources, udma_resources.desc, @@ -701,7 +752,10 @@ static DEVICE_API(dma, siwx91x_dma_api) = { (siwx91x_dma_chan_desc##inst)), \ .irq_configure = siwx91x_dma_irq_configure_##inst, \ }; \ - DEVICE_DT_INST_DEFINE(inst, siwx91x_dma_init, NULL, &dma_data_##inst, &dma_cfg_##inst, \ - POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, &siwx91x_dma_api); + PM_DEVICE_DT_INST_DEFINE(inst, dma_siwx91x_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, siwx91x_dma_init, PM_DEVICE_DT_INST_GET(inst), \ + &dma_data_##inst, &dma_cfg_##inst, POST_KERNEL, \ + CONFIG_DMA_INIT_PRIORITY, \ + &siwx91x_dma_api); DT_INST_FOREACH_STATUS_OKAY(SIWX91X_DMA_INIT) diff --git a/drivers/eeprom/eeprom_fm25xxx.c b/drivers/eeprom/eeprom_fm25xxx.c index f0061c84265c1..f35d7de2d20ad 100644 --- a/drivers/eeprom/eeprom_fm25xxx.c +++ b/drivers/eeprom/eeprom_fm25xxx.c @@ -104,7 +104,7 @@ int eeprom_fm25xxx_read(const struct device *dev, off_t offset, void *data, size sys_put_be24(offset, &read_op[1]); break; default: - LOG_ERR("Invalid number of address bytes %u", addr_bytes); + LOG_ERR("Invalid number of address bytes %zu", addr_bytes); return -EINVAL; } @@ -182,7 +182,7 @@ int eeprom_fm25xxx_write(const struct device *dev, off_t offset, const void *dat sys_put_be24(offset, &write_op[1]); break; default: - LOG_ERR("Invalid number of address bytes %u", addr_bytes); + LOG_ERR("Invalid number of address bytes %zu", addr_bytes); return -EINVAL; } diff --git a/drivers/eeprom/eeprom_stm32.c b/drivers/eeprom/eeprom_stm32.c index a3288fe3dc6de..076b547279fb5 100644 --- a/drivers/eeprom/eeprom_stm32.c +++ b/drivers/eeprom/eeprom_stm32.c @@ -57,7 +57,7 @@ static int eeprom_stm32_write(const struct device *dev, off_t offset, { const struct eeprom_stm32_config *config = dev->config; const uint8_t *pbuf = buf; - HAL_StatusTypeDef ret = HAL_OK; + HAL_StatusTypeDef hal_ret; if (!len) { return 0; @@ -70,17 +70,21 @@ static int eeprom_stm32_write(const struct device *dev, off_t offset, k_mutex_lock(&lock, K_FOREVER); - HAL_FLASHEx_DATAEEPROM_Unlock(); + hal_ret = HAL_FLASHEx_DATAEEPROM_Unlock(); + if (hal_ret != HAL_OK) { + LOG_ERR("failed to unlock to EEPROM"); + goto out; + } while (len) { - ret = HAL_FLASHEx_DATAEEPROM_Program( - FLASH_TYPEPROGRAMDATA_BYTE, - config->addr + offset, *pbuf); - if (ret) { - LOG_ERR("failed to write to EEPROM (err %d)", ret); - HAL_FLASHEx_DATAEEPROM_Lock(); - k_mutex_unlock(&lock); - return ret; + hal_ret = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, + config->addr + offset, *pbuf); + if (hal_ret != HAL_OK) { + LOG_ERR("failed to write to EEPROM (err %d)", hal_ret); + if (HAL_FLASHEx_DATAEEPROM_Lock() != HAL_OK) { + LOG_ERR("failed to lock to EEPROM"); + } + goto out; } pbuf++; @@ -88,14 +92,19 @@ static int eeprom_stm32_write(const struct device *dev, off_t offset, len--; } - ret = HAL_FLASHEx_DATAEEPROM_Lock(); - if (ret) { - LOG_ERR("failed to lock EEPROM (err %d)", ret); + hal_ret = HAL_FLASHEx_DATAEEPROM_Lock(); + if (hal_ret != HAL_OK) { + LOG_ERR("failed to lock EEPROM"); } +out: k_mutex_unlock(&lock); - return ret; + if (hal_ret != HAL_OK) { + return -EIO; + } + + return 0; } static size_t eeprom_stm32_size(const struct device *dev) diff --git a/drivers/entropy/Kconfig.gecko b/drivers/entropy/Kconfig.gecko index e096cb33a851c..621e82326f8e3 100644 --- a/drivers/entropy/Kconfig.gecko +++ b/drivers/entropy/Kconfig.gecko @@ -19,6 +19,7 @@ config ENTROPY_GECKO_SE default y depends on DT_HAS_SILABS_GECKO_SEMAILBOX_ENABLED select ENTROPY_HAS_DRIVER + select SILABS_SISDK_SE help This option enables the true random number generator driver based on the Secure Element (SE) module. diff --git a/drivers/entropy/entropy_gecko_trng.c b/drivers/entropy/entropy_gecko_trng.c index 68b8833b49506..8eda146c52ef9 100644 --- a/drivers/entropy/entropy_gecko_trng.c +++ b/drivers/entropy/entropy_gecko_trng.c @@ -80,6 +80,7 @@ static int entropy_gecko_trng_get_entropy(const struct device *dev, #ifndef CONFIG_CRYPTO_ACC_GECKO_TRNG available = TRNG0->FIFOLEVEL * 4; #else + CMU_ClockEnable(cmuClock_CRYPTOACC, true); available = S2_FIFO_LEVEL * 4; #endif if (available == 0) { @@ -107,6 +108,7 @@ static int entropy_gecko_trng_get_entropy_isr(const struct device *dev, #ifndef CONFIG_CRYPTO_ACC_GECKO_TRNG size_t available = TRNG0->FIFOLEVEL * 4; #else + CMU_ClockEnable(cmuClock_CRYPTOACC, true); size_t available = S2_FIFO_LEVEL * 4; #endif diff --git a/drivers/espi/espi_realtek_rts5912.c b/drivers/espi/espi_realtek_rts5912.c index 4490bd7bdd408..c0c83dcb964df 100644 --- a/drivers/espi/espi_realtek_rts5912.c +++ b/drivers/espi/espi_realtek_rts5912.c @@ -23,6 +23,14 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL); #include "reg/reg_kbc.h" #include "reg/reg_port80.h" +#ifdef CONFIG_PM +#include "reg/reg_gpio.h" +#include +#include +#include "reg/reg_system.h" +#include "zephyr/drivers/gpio/gpio_rts5912.h" +#endif + BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "support only one espi compatible node"); struct espi_rts5912_config { @@ -56,6 +64,9 @@ struct espi_rts5912_config { volatile struct port80_reg *const port80_reg; uint32_t port80_clk_grp; uint32_t port80_clk_idx; +#endif +#ifdef CONFIG_PM + struct gpio_dt_spec cs_pin; #endif const struct device *clk_dev; const struct pinctrl_dev_config *pcfg; @@ -1200,7 +1211,6 @@ static void notify_host_warning(const struct device *dev, enum espi_vwire_signal uint8_t status = 0; espi_rts5912_receive_vwire(dev, signal, &status); - k_busy_wait(200); switch (signal) { case ESPI_VWIRE_SIGNAL_SUS_WARN: @@ -1397,8 +1407,6 @@ static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_sig static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal, uint8_t *level) { - const struct espi_rts5912_config *const espi_config = dev->config; - volatile struct espi_reg *const espi_reg = espi_config->espi_reg; uint8_t vw_idx, lev_msk, valid_msk; uint8_t vw_data; @@ -1415,9 +1423,6 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_ vw_data = espi_vw_ch_cached_data.idx2; break; case VW_CH_IDX3: - if (espi_vw_ch_cached_data.idx3 != espi_reg->EVIDX3) { - espi_vw_ch_cached_data.idx3 = espi_reg->EVIDX3; - } vw_data = espi_vw_ch_cached_data.idx3; break; case VW_CH_IDX4: @@ -1430,60 +1435,33 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_ vw_data = espi_vw_tx_cached_data.idx6; break; case VW_CH_IDX7: - if (espi_vw_ch_cached_data.idx7 != espi_reg->EVIDX7) { - espi_vw_ch_cached_data.idx7 = espi_reg->EVIDX7; - } vw_data = espi_vw_ch_cached_data.idx7; break; case VW_CH_IDX40: vw_data = espi_vw_tx_cached_data.idx40; break; case VW_CH_IDX41: - if (espi_vw_ch_cached_data.idx41 != espi_reg->EVIDX41) { - espi_vw_ch_cached_data.idx41 = espi_reg->EVIDX41; - } vw_data = espi_vw_ch_cached_data.idx41; break; case VW_CH_IDX42: - if (espi_vw_ch_cached_data.idx42 != espi_reg->EVIDX42) { - espi_vw_ch_cached_data.idx42 = espi_reg->EVIDX42; - } vw_data = espi_vw_ch_cached_data.idx42; break; case VW_CH_IDX43: - if (espi_vw_ch_cached_data.idx43 != espi_reg->EVIDX43) { - espi_vw_ch_cached_data.idx43 = espi_reg->EVIDX43; - } vw_data = espi_vw_ch_cached_data.idx43; break; case VW_CH_IDX44: - if (espi_vw_ch_cached_data.idx44 != espi_reg->EVIDX44) { - espi_vw_ch_cached_data.idx44 = espi_reg->EVIDX44; - } vw_data = espi_vw_ch_cached_data.idx44; break; case VW_CH_IDX47: - if (espi_vw_ch_cached_data.idx47 != espi_reg->EVIDX47) { - espi_vw_ch_cached_data.idx47 = espi_reg->EVIDX47; - } vw_data = espi_vw_ch_cached_data.idx47; break; case VW_CH_IDX4A: - if (espi_vw_ch_cached_data.idx4a != espi_reg->EVIDX4A) { - espi_vw_ch_cached_data.idx4a = espi_reg->EVIDX4A; - } vw_data = espi_vw_ch_cached_data.idx4a; break; case VW_CH_IDX51: - if (espi_vw_ch_cached_data.idx51 != espi_reg->EVIDX51) { - espi_vw_ch_cached_data.idx51 = espi_reg->EVIDX51; - } vw_data = espi_vw_ch_cached_data.idx51; break; case VW_CH_IDX61: - if (espi_vw_ch_cached_data.idx61 != espi_reg->EVIDX61) { - espi_vw_ch_cached_data.idx61 = espi_reg->EVIDX61; - } vw_data = espi_vw_ch_cached_data.idx61; break; default: @@ -2296,7 +2274,18 @@ static void espi_bus_reset_setup(const struct device *dev) DEVICE_DT_GET(DT_DRV_INST(0)), 0); irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), bus_rst, irq)); } +#ifdef CONFIG_PM +void espi_cs_low_isr(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) +{ + gpio_flags_t cs_pin_config; + gpio_pin_get_config(port, pins, &cs_pin_config); + if (cs_pin_config & GPIO_INT_ENABLE) { + gpio_pin_interrupt_configure(port, (find_msb_set(pins) - 1), + GPIO_INT_MODE_DISABLED); + } +} +#endif static int espi_rts5912_init(const struct device *dev) { const struct espi_rts5912_config *const espi_config = dev->config; @@ -2396,13 +2385,44 @@ static int espi_rts5912_init(const struct device *dev) goto exit; } #endif - +#ifdef CONFIG_PM + static struct gpio_callback cb; + uint32_t cs_irq_nun = gpio_rts5912_get_pin_num(&espi_config->cs_pin); + + NVIC_ClearPendingIRQ(cs_irq_nun); + gpio_init_callback(&cb, espi_cs_low_isr, BIT(espi_config->cs_pin.pin)); + gpio_add_callback(espi_config->cs_pin.port, &cb); + irq_enable(cs_irq_nun); +#endif exit: return rc; } +#ifdef CONFIG_PM +static inline int espi_rts5912_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct espi_rts5912_config *const espi_config = dev->config; + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; -PINCTRL_DT_INST_DEFINE(0); + switch (action) { + case PM_DEVICE_ACTION_RESUME: + sys_reg->SLPCTRL &= ~SYSTEM_SLPCTRL_GPIOWKEN_Msk; + gpio_pin_interrupt_configure_dt(&espi_config->cs_pin, GPIO_INT_MODE_DISABLED); + break; + case PM_DEVICE_ACTION_SUSPEND: + sys_reg->SLPCTRL |= SYSTEM_SLPCTRL_GPIOWKEN_Msk; + gpio_pin_interrupt_configure_dt(&espi_config->cs_pin, + GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW); + break; + default: + return -ENOTSUP; + } + return 0; +} +PM_DEVICE_DT_INST_DEFINE(0, espi_rts5912_pm_action); +#endif + +PINCTRL_DT_INST_DEFINE(0); static struct espi_rts5912_data espi_rts5912_data_0; static const struct espi_rts5912_config espi_rts5912_config = { @@ -2437,10 +2457,18 @@ static const struct espi_rts5912_config espi_rts5912_config = { .port80_reg = (volatile struct port80_reg *const)DT_INST_REG_ADDR_BY_NAME(0, port80), .port80_clk_grp = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_grp), .port80_clk_idx = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_idx), +#endif +#ifdef CONFIG_PM + .cs_pin = GPIO_DT_SPEC_INST_GET(0, cs_gpios), #endif .clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)), .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; - +#ifdef CONFIG_PM +DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, PM_DEVICE_DT_INST_GET(0), &espi_rts5912_data_0, + &espi_rts5912_config, PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, + &espi_rts5912_driver_api); +#else DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, NULL, &espi_rts5912_data_0, &espi_rts5912_config, PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, &espi_rts5912_driver_api); +#endif diff --git a/drivers/ethernet/Kconfig.nxp_enet b/drivers/ethernet/Kconfig.nxp_enet index 953ce84d51233..538543fb96bcb 100644 --- a/drivers/ethernet/Kconfig.nxp_enet +++ b/drivers/ethernet/Kconfig.nxp_enet @@ -12,7 +12,7 @@ config ETH_NXP_ENET depends on DT_HAS_NXP_ENET_MAC_ENABLED select NOCACHE_MEMORY if CPU_HAS_DCACHE select ARM_MPU if CPU_CORTEX_M7 - select NET_POWER_MANAGEMENT if (PM_DEVICE && SOC_FAMILY_KINETIS) + imply NET_POWER_MANAGEMENT select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL select HWINFO if $(dt_compat_any_has_prop,$(DT_COMPAT_NXP_ENET_MAC),$(DT_NXP_UNIQUE_MAC_PROP),True) diff --git a/drivers/ethernet/eth_nxp_enet.c b/drivers/ethernet/eth_nxp_enet.c index a19b3ec3f7ebb..40b2d69f4b237 100644 --- a/drivers/ethernet/eth_nxp_enet.c +++ b/drivers/ethernet/eth_nxp_enet.c @@ -799,14 +799,11 @@ static int eth_nxp_enet_device_pm_action(const struct device *dev, enum pm_devic return ret; } - ENET_Reset(data->base); - ENET_Down(data->base); - clock_control_off(config->clock_dev, (clock_control_subsys_t)config->clock_subsys); + ENET_EnableSleepMode(data->base, true); } else if (action == PM_DEVICE_ACTION_RESUME) { LOG_DBG("Resuming"); - clock_control_on(config->clock_dev, (clock_control_subsys_t)config->clock_subsys); - eth_nxp_enet_init(dev); + ENET_EnableSleepMode(data->base, false); net_if_resume(data->iface); } else { return -ENOTSUP; diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 5cb3b336499e5..80924322fa125 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -42,6 +42,7 @@ config PHY_ADIN2111 default y depends on DT_HAS_ADI_ADIN2111_PHY_ENABLED || DT_HAS_ADI_ADIN1100_PHY_ENABLED select MDIO + select GPIO if $(dt_compat_any_has_prop,$(DT_COMPAT_ADI_ADIN1100_PHY),reset-gpios) help Enable ADIN2111 PHY driver. diff --git a/drivers/ethernet/phy/phy_adin2111.c b/drivers/ethernet/phy/phy_adin2111.c index 8ba0023fd2499..411f5673254d2 100644 --- a/drivers/ethernet/phy/phy_adin2111.c +++ b/drivers/ethernet/phy/phy_adin2111.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL); /* Software reset, CLK_25 disabled time*/ #define ADIN1100_PHY_SFT_RESET_MS 25U +#define ADIN1100_PHY_HRD_RESET_MS 70U +#define ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US 16U /* PHYs autonegotiation complete timeout */ #define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U @@ -90,6 +93,9 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL); struct phy_adin2111_config { const struct device *mdio; +#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) + const struct gpio_dt_spec reset_gpio; +#endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */ uint8_t phy_addr; bool led0_en; bool led1_en; @@ -352,6 +358,30 @@ static int phy_adin2111_reset(const struct device *dev) { int ret; +#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) + const struct phy_adin2111_config *config = dev->config; + + if (config->reset_gpio.port != NULL) { + /* Assert reset (min. reset pulse width 10us) */ + ret = gpio_pin_set_dt(&config->reset_gpio, 1); + if (ret < 0) { + return ret; + } + k_busy_wait(ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US); + + /* Deassert reset */ + ret = gpio_pin_set_dt(&config->reset_gpio, 0); + if (ret < 0) { + return ret; + } + + k_msleep(ADIN1100_PHY_HRD_RESET_MS); + + return 0; + } +#endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */ + + /* Perform software reset */ ret = phy_adin2111_c22_write(dev, MII_BMCR, MII_BMCR_RESET); if (ret < 0) { return ret; @@ -439,6 +469,15 @@ static int phy_adin2111_init(const struct device *dev) data->state.is_up = false; data->state.speed = LINK_FULL_10BASE; +#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) + if (cfg->reset_gpio.port != NULL) { + ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + } +#endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */ + /* * For adin1100 and further mii stuff, * reset may not be performed from the mac layer, doing a clean reset here. @@ -617,9 +656,17 @@ static DEVICE_API(ethphy, phy_adin2111_api) = { .write = phy_adin2111_reg_write, }; +#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) +#define RESET_GPIO(n) \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), +#else +#define RESET_GPIO(n) +#endif /* reset gpio */ + #define ADIN2111_PHY_INITIALIZE(n, model) \ static const struct phy_adin2111_config phy_adin##model##_config_##n = { \ .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \ + RESET_GPIO(n) \ .phy_addr = DT_INST_REG_ADDR(n), \ .led0_en = DT_INST_PROP(n, led0_en), \ .led1_en = DT_INST_PROP(n, led1_en), \ diff --git a/drivers/ethernet/phy/phy_ti_dp83867.c b/drivers/ethernet/phy/phy_ti_dp83867.c index 24d54520092c9..8c105641f6e04 100644 --- a/drivers/ethernet/phy/phy_ti_dp83867.c +++ b/drivers/ethernet/phy/phy_ti_dp83867.c @@ -295,8 +295,10 @@ static int phy_ti_dp83867_reset(const struct device *dev) if (ret < 0) { LOG_ERR("Error writing phy (%d) basic control register", config->addr); } - +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) done: +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + /* POR release time (minimum specified is T4=195us) */ k_busy_wait(PHY_TI_DP83867_POR_DELAY); @@ -313,7 +315,7 @@ static int phy_ti_dp83867_cfg_link(const struct device *dev, enum phy_link_speed const struct ti_dp83867_config *config = dev->config; struct ti_dp83867_data *data = dev->data; int ret; - uint32_t val; + __maybe_unused uint32_t val; if (flags & PHY_FLAG_AUTO_NEGOTIATION_DISABLED) { LOG_ERR("Disabling auto-negotiation is not supported by this driver"); diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index b7352f2458360..3ed0fdaf9879f 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -42,6 +42,8 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_NPCX_FIU_NOR flash_npcx_fiu_nor.c) zephyr_library_sources_ifdef(CONFIG_FLASH_NPCX_FIU_QSPI flash_npcx_fiu_qspi.c) zephyr_library_sources_ifdef(CONFIG_FLASH_RENESAS_RA_OSPI_B flash_renesas_ra_ospi_b.c) zephyr_library_sources_ifdef(CONFIG_FLASH_RENESAS_RA_QSPI flash_renesas_ra_qspi.c) +zephyr_library_sources_ifdef(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC flash_renesas_rz_qspi.c) +zephyr_library_sources_ifdef(CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI flash_renesas_rz_qspi.c) zephyr_library_sources_ifdef(CONFIG_FLASH_RPI_PICO flash_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_FLASH_SF32LB_MPI_QSPI_NOR flash_sf32lb_mpi_qspi_nor.c) zephyr_library_sources_ifdef(CONFIG_FLASH_STM32_OSPI flash_stm32_ospi.c) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 04740b078905c..f563bf703aafe 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -198,6 +198,7 @@ source "drivers/flash/Kconfig.renesas_ra" source "drivers/flash/Kconfig.renesas_ra_ospi" source "drivers/flash/Kconfig.renesas_ra_qspi" source "drivers/flash/Kconfig.renesas_rx" +source "drivers/flash/Kconfig.renesas_rz_qspi" source "drivers/flash/Kconfig.rpi_pico" source "drivers/flash/Kconfig.rts5912" source "drivers/flash/Kconfig.rv32m1" diff --git a/drivers/flash/Kconfig.esp32 b/drivers/flash/Kconfig.esp32 index 4da80bce0c0fd..aa34e04045113 100644 --- a/drivers/flash/Kconfig.esp32 +++ b/drivers/flash/Kconfig.esp32 @@ -15,3 +15,34 @@ config MPU_ALLOW_FLASH_WRITE bool "Add MPU access to write to flash" help Enable this to allow MPU RWX access to flash memory + +if SOC_FLASH_ESP32 + +config ESP_FLASH_ASYNC + bool "Use asynchronous work thread to execute the flash access operations" + depends on MULTITHREADING && !MCUBOOT + help + Enabling this makes the flash access operations deferred to the work thread. + Meaning every flash read or write would be postponed and executed when available. + +config ESP_FLASH_ASYNC_WORK + bool "Use dedicated work thread to perform the work tasks" + depends on ESP_FLASH_ASYNC + help + Use dedicated work thread to perform the workqueue tasks with flash asynchronous operations. + +config ESP_FLASH_ASYNC_WORK_STACK_SIZE + int "Stack size for dedicated work thread" + depends on ESP_FLASH_ASYNC_WORK + default 1024 + help + Define stack size for a dedicated work thread processing workqueue. + +config ESP_FLASH_ASYNC_WORK_PRIORITY + int "Thread priority for dedicated work thread" + depends on ESP_FLASH_ASYNC_WORK + default 5 + help + Define thread priority for a dedicated work thread processing workqueue. + +endif # SOC_FLASH_ESP32 diff --git a/drivers/flash/Kconfig.renesas_rz_qspi b/drivers/flash/Kconfig.renesas_rz_qspi new file mode 100644 index 0000000000000..ae9ca41297540 --- /dev/null +++ b/drivers/flash/Kconfig.renesas_rz_qspi @@ -0,0 +1,37 @@ +# Renesas RZ Family + +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config FLASH_RENESAS_RZ_QSPI_XSPI + bool "Renesas RZ Quad-SPI XSPI driver" + default y + depends on DT_HAS_RENESAS_RZ_QSPI_XSPI_ENABLED + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE + select USE_RZ_FSP_QSPI_XSPI + select FLASH_JESD216 + select PINCTRL + help + Enable Quad-SPI XSPI Nor flash driver for RZ series + +config FLASH_RENESAS_RZ_QSPI_SPIBSC + bool "Renesas RZ Quad-SPI SPIBSC driver" + default y + depends on DT_HAS_RENESAS_RZ_QSPI_SPIBSC_ENABLED + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE + select USE_RZ_FSP_QSPI_SPIBSC + select FLASH_JESD216 + select PINCTRL + help + Enable Quad-SPI SPIBSC Nor flash driver for RZ series + +config FLASH_RENESAS_RZ_MIRROR_OFFSET + hex + default 0x0 if SOC_SERIES_RZA3UL + default 0x20000000 if SOC_SERIES_RZT2M || SOC_SERIES_RZN2L + help + Offset of mirror area in flash memory diff --git a/drivers/flash/Kconfig.silabs b/drivers/flash/Kconfig.silabs index 5890f98ed340f..2f36eb5699317 100644 --- a/drivers/flash/Kconfig.silabs +++ b/drivers/flash/Kconfig.silabs @@ -7,7 +7,7 @@ config SOC_FLASH_SILABS_S2 depends on DT_HAS_SILABS_SERIES2_FLASH_CONTROLLER_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT - select SOC_GECKO_MSC + select SILABS_SISDK_MSC select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index da91199c1c4d7..88a3e5031f9f0 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,11 +45,37 @@ LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL); #define ALIGN_OFFSET(num, align) ((num) & ((align) - 1)) #endif +#ifdef CONFIG_ESP_FLASH_ASYNC_WORK +#define ESP_FLASH_WORKQUEUE_STACK_SIZE CONFIG_ESP_FLASH_ASYNC_WORK_STACK_SIZE +#define ESP_FLASH_WORKQUEUE_PRIORITY CONFIG_ESP_FLASH_ASYNC_WORK_PRIORITY +K_THREAD_STACK_DEFINE(esp_flash_workqueue_stack, ESP_FLASH_WORKQUEUE_STACK_SIZE); +static struct k_work_q esp_flash_workqueue; +#endif /* CONFIG_ESP_FLASH_ASYNC_WORK */ + +#ifdef CONFIG_ESP_FLASH_ASYNC +enum { + FLASH_OP_NONE, + FLASH_OP_READ, + FLASH_OP_WRITE, + FLASH_OP_ERASE +}; +#endif + struct flash_esp32_dev_config { spi_dev_t *controller; }; struct flash_esp32_dev_data { +#ifdef CONFIG_ESP_FLASH_ASYNC + struct k_work work; + struct k_mutex lock; + const struct device *dev; + int type; + off_t addr; + size_t len; + void *buf; + int ret; +#endif #ifdef CONFIG_MULTITHREADING struct k_sem sem; #endif @@ -60,7 +86,7 @@ static const struct flash_parameters flash_esp32_parameters = { .erase_value = 0xff, }; -#ifdef CONFIG_MULTITHREADING +#if defined(CONFIG_MULTITHREADING) && !defined(CONFIG_ESP_FLASH_ASYNC) static inline void flash_esp32_sem_take(const struct device *dev) { struct flash_esp32_dev_data *data = dev->data; @@ -79,7 +105,7 @@ static inline void flash_esp32_sem_give(const struct device *dev) #define flash_esp32_sem_take(dev) do {} while (0) #define flash_esp32_sem_give(dev) do {} while (0) -#endif /* CONFIG_MULTITHREADING */ +#endif /* CONFIG_MULTITHREADING && !CONFIG_ESP_FLASH_ASYNC */ #include #include @@ -374,12 +400,9 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe } #else flash_esp32_sem_take(dev); - ret = flash_esp32_read_check_enc(address, buffer, length); - flash_esp32_sem_give(dev); -#endif - +#endif /* CONFIG_MCUBOOT */ if (ret != 0) { LOG_ERR("Flash read error: %d", ret); return -EIO; @@ -388,9 +411,7 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe return 0; } -static int flash_esp32_write(const struct device *dev, - off_t address, - const void *buffer, +static int flash_esp32_write(const struct device *dev, off_t address, const void *buffer, size_t length) { int ret = 0; @@ -423,11 +444,10 @@ static int flash_esp32_write(const struct device *dev, } #else ret = flash_esp32_write_check_enc(address, buffer, length); -#endif +#endif /* CONFIG_ESP_FLASH_ENCRYPTION */ flash_esp32_sem_give(dev); -#endif - +#endif /* CONFIG_MCUBOOT */ if (ret != 0) { LOG_ERR("Flash write error: %d", ret); return -EIO; @@ -480,10 +500,10 @@ static int flash_esp32_erase(const struct device *dev, off_t start, size_t len) } #else ret = esp_flash_erase_region(NULL, start, len); -#endif +#endif /* CONFIG_ESP_FLASH_ENCRYPTION */ flash_esp32_sem_give(dev); -#endif +#endif /* CONFIG_MCUBOOT */ if (ret != 0) { LOG_ERR("Flash erase error: %d", ret); return -EIO; @@ -491,6 +511,83 @@ static int flash_esp32_erase(const struct device *dev, off_t start, size_t len) return 0; } +#ifdef CONFIG_ESP_FLASH_ASYNC +static void flash_work_handler(struct k_work *work) +{ + struct flash_esp32_dev_data *data = CONTAINER_OF(work, struct flash_esp32_dev_data, work); + + if (data->type == FLASH_OP_READ) { + data->ret = flash_esp32_read(data->dev, data->addr, data->buf, data->len); + } else if (data->type == FLASH_OP_WRITE) { + data->ret = flash_esp32_write(data->dev, data->addr, data->buf, data->len); + } else if (data->type == FLASH_OP_ERASE) { + data->ret = flash_esp32_erase(data->dev, data->addr, data->len); + } else { + data->ret = -EINVAL; + } + + k_sem_give(&data->sem); +} + +static int flash_esp32_read_async(const struct device *dev, off_t address, + void *buffer, size_t length) +{ + struct flash_esp32_dev_data *data = dev->data; + + k_mutex_lock(&data->lock, K_TIMEOUT_ABS_SEC(3)); + + data->dev = dev; + data->addr = address; + data->buf = buffer; + data->len = length; + data->type = FLASH_OP_READ; + + k_work_submit(&data->work); + k_sem_take(&data->sem, FLASH_SEM_TIMEOUT); + k_mutex_unlock(&data->lock); + + return data->ret; +} + +static int flash_esp32_write_async(const struct device *dev, off_t address, + const void *buffer, size_t length) +{ + struct flash_esp32_dev_data *data = dev->data; + + k_mutex_lock(&data->lock, K_TIMEOUT_ABS_SEC(3)); + + data->dev = dev; + data->addr = address; + data->buf = (void *) buffer; + data->len = length; + data->type = FLASH_OP_WRITE; + + k_work_submit(&data->work); + k_sem_take(&data->sem, FLASH_SEM_TIMEOUT); + k_mutex_unlock(&data->lock); + + return 0; +} +static int flash_esp32_erase_async(const struct device *dev, off_t start, size_t len) +{ + struct flash_esp32_dev_data *data = dev->data; + + k_mutex_lock(&data->lock, K_TIMEOUT_ABS_SEC(3)); + + data->addr = start; + data->len = len; + data->buf = NULL; + data->type = FLASH_OP_ERASE; + + k_work_submit(&data->work); + k_sem_take(&data->sem, FLASH_SEM_TIMEOUT); + k_mutex_unlock(&data->lock); + + return 0; +} +#endif + + #if CONFIG_FLASH_PAGE_LAYOUT static const struct flash_pages_layout flash_esp32_pages_layout = { .pages_count = DT_REG_SIZE(SOC_NV_FLASH_NODE) / FLASH_ERASE_BLK_SZ, @@ -504,7 +601,7 @@ void flash_esp32_page_layout(const struct device *dev, *layout = &flash_esp32_pages_layout; *layout_size = 1; } -#endif /* CONFIG_FLASH_PAGE_LAYOUT */ +#endif static const struct flash_parameters * flash_esp32_get_parameters(const struct device *dev) @@ -517,18 +614,37 @@ flash_esp32_get_parameters(const struct device *dev) static int flash_esp32_init(const struct device *dev) { #ifdef CONFIG_MULTITHREADING - struct flash_esp32_dev_data *const dev_data = dev->data; - - k_sem_init(&dev_data->sem, 1, 1); + struct flash_esp32_dev_data *const data = dev->data; + +#ifdef CONFIG_ESP_FLASH_ASYNC + k_sem_init(&data->sem, 0, 1); + k_mutex_init(&data->lock); + k_work_init(&data->work, flash_work_handler); + +#ifdef CONFIG_ESP_FLASH_ASYNC_WORK + k_work_queue_init(&esp_flash_workqueue); + k_work_queue_start(&esp_flash_workqueue, esp_flash_workqueue_stack, + K_THREAD_STACK_SIZEOF(esp_flash_workqueue_stack), + ESP_FLASH_WORKQUEUE_PRIORITY, NULL); + k_work_submit_to_queue(&esp_flash_workqueue, &data->work); +#endif +#else + k_sem_init(&data->sem, 1, 1); +#endif /* CONFIG_ESP_FLASH_ASYNC */ #endif /* CONFIG_MULTITHREADING */ - return 0; } static DEVICE_API(flash, flash_esp32_driver_api) = { +#ifdef CONFIG_ESP_FLASH_ASYNC + .read = flash_esp32_read_async, + .write = flash_esp32_write_async, + .erase = flash_esp32_erase_async, +#else .read = flash_esp32_read, .write = flash_esp32_write, .erase = flash_esp32_erase, +#endif .get_parameters = flash_esp32_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_esp32_page_layout, diff --git a/drivers/flash/flash_renesas_rz_qspi.c b/drivers/flash/flash_renesas_rz_qspi.c new file mode 100644 index 0000000000000..5c744b499263e --- /dev/null +++ b/drivers/flash/flash_renesas_rz_qspi.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "spi_nor.h" +#include "r_spi_flash_api.h" + +#if defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) +#include "r_spibsc.h" +#else +#include "r_xspi_qspi.h" +#endif + +LOG_MODULE_REGISTER(renesas_rz_qspi, CONFIG_FLASH_LOG_LEVEL); + +#if defined(CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI) +#define QSPI_DEFAULT_SR (0x40) +#define QSPI_UPDATE_CR (0xC0) /* Configuration register (DC0=1, DC1=1 (Dummy cycle = 10)) */ +#define QSPI_DATA_CR_UPDATE (QSPI_UPDATE_CR << 8 | QSPI_DEFAULT_SR) +#endif /* CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI */ + +#define FLASH_RZ_BASE_ADDRESS (CONFIG_FLASH_BASE_ADDRESS - CONFIG_FLASH_RENESAS_RZ_MIRROR_OFFSET) + +/* QSPI COMMANDS */ +#define QSPI_CMD_RDSFDP (0x5A) /* Read SFDP */ + +/* XIP (Execute In Place) mode */ +#define QSPI_CMD_XIP_ENTER (0xA5) /* XIP Enter command */ +#define QSPI_CMD_XIP_EXIT (0xFF) /* XIP Exit command */ + +#define QSPI_CMD_QUAD_PAGE_PROGRAM (0x33) + +/* One byte data transfer */ +#define DATA_LENGTH_DEFAULT_BYTE (0U) +#define ONE_BYTE (1U) +#define TWO_BYTE (2U) +#define THREE_BYTE (3U) +#define FOUR_BYTE (4U) + +/* Default erase value */ +#define QSPI_ERASE_VALUE (0xFF) + +/* Maximum memory buffer size of write operation in memory-map mode */ +#if defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) +#define QSPI_MAX_BUFFER_SIZE 256U +#else +#define QSPI_MAX_BUFFER_SIZE 64U +#endif + +struct flash_renesas_rz_data { + spi_flash_ctrl_t *fsp_ctrl; + spi_flash_cfg_t *fsp_cfg; + + struct k_sem sem; +}; + +struct flash_renesas_rz_config { + const struct pinctrl_dev_config *pin_cfg; + const spi_flash_api_t *fsp_api; + + uint32_t erase_block_size; + uint32_t flash_size; + struct flash_parameters flash_param; +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + struct flash_pages_layout layout; +#endif +}; + +static const spi_flash_erase_command_t g_erase_command_list[4] = { + {.command = SPI_NOR_CMD_SE, .size = SPI_NOR_SECTOR_SIZE}, + {.command = SPI_NOR_CMD_BE_32K, .size = SPI_NOR_BLOCK_32K_SIZE}, + {.command = SPI_NOR_CMD_BE, .size = SPI_NOR_BLOCK_SIZE}, + {.command = SPI_NOR_CMD_CE, .size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE}, +}; + +static void acquire_device(const struct device *dev) +{ + struct flash_renesas_rz_data *dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); +} + +static void release_device(const struct device *dev) +{ + struct flash_renesas_rz_data *dev_data = dev->data; + + k_sem_give(&dev_data->sem); +} + +static int qspi_wait_until_ready(const struct device *dev) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *data = dev->data; + spi_flash_status_t status = {.write_in_progress = true}; + uint32_t timeout = 0xFFFFFF; + fsp_err_t err; + + while ((status.write_in_progress) && (timeout > 0)) { + err = config->fsp_api->statusGet(data->fsp_ctrl, &status); + if (err != FSP_SUCCESS) { + LOG_ERR("Status get failed"); + return -EIO; + } + timeout--; + } + + return 0; +} + +#if CONFIG_FLASH_PAGE_LAYOUT +void flash_renesas_rz_page_layout(const struct device *dev, + const struct flash_pages_layout **layout, size_t *layout_size) +{ + const struct flash_renesas_rz_config *config = dev->config; + + *layout = &config->layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +#if defined(CONFIG_FLASH_JESD216_API) +static int qspi_flash_rz_read_jedec_id(const struct device *dev, uint8_t *id) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *data = dev->data; + int ret = 0; + + if (id == NULL) { + return -EINVAL; + } + + spi_flash_direct_transfer_t trans = { + .command = SPI_NOR_CMD_RDID, + .address = 0, + .data = 0, + .command_length = 1U, + .address_length = 0U, + .data_length = THREE_BYTE, + .dummy_cycles = 0U, + }; + + acquire_device(dev); + ret = config->fsp_api->directTransfer(data->fsp_ctrl, &trans, + SPI_FLASH_DIRECT_TRANSFER_DIR_READ); + if (FSP_SUCCESS != (fsp_err_t)ret) { + LOG_ERR("Failed to read device id"); + release_device(dev); + return -EIO; + } + + /* Get flash device ID */ + memcpy(id, &trans.data, sizeof(trans.data)); + release_device(dev); + + return ret; +} + +static int qspi_flash_renesas_rz_sfdp_read(const struct device *dev, off_t addr, void *data, + size_t len) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *dev_data = dev->data; + int ret = 0; + size_t size; + + spi_flash_direct_transfer_t trans = { + .command = QSPI_CMD_RDSFDP, + .address = addr, + .data = 0, + .command_length = 1U, + .address_length = 3U, + .data_length = FOUR_BYTE, + .dummy_cycles = SPI_NOR_DUMMY_RD, + }; + + acquire_device(dev); + while (len > 0) { + size = MIN(len, trans.data_length); + trans.address = addr; + trans.data_length = size; + + ret = config->fsp_api->directTransfer(dev_data->fsp_ctrl, &trans, + SPI_FLASH_DIRECT_TRANSFER_DIR_READ); + + if (FSP_SUCCESS != (fsp_err_t)ret) { + LOG_ERR("Failed to read SFDP id"); + release_device(dev); + return -EIO; + } + + memcpy(data, &trans.data, size); + + len -= size; + addr += size; + data = (uint8_t *)data + size; + } + + release_device(dev); + return ret; +} +#endif + +static bool qspi_flash_rz_valid(uint32_t area_size, off_t offset, size_t len) +{ + if ((offset < 0) || (offset >= area_size) || ((area_size - offset) < len)) { + return false; + } + + return true; +} + +static int qspi_flash_rz_erase(const struct device *dev, off_t offset, size_t len) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *data = dev->data; + int err = 0; + struct flash_pages_info page_info_start, page_info_end; + uint32_t erase_size; + int rc; + + if (!len) { + return 0; + } + + if (!qspi_flash_rz_valid(config->flash_size, offset, len)) { + LOG_ERR("The offset 0x%lx is invalid", (long)offset); + return -EINVAL; + } + + if (0 != (len % config->erase_block_size)) { + LOG_ERR("The size %zu is not align with block size (%u)", len, + config->erase_block_size); + return -EINVAL; + } + + rc = flash_get_page_info_by_offs(dev, offset, &page_info_start); + if ((rc != 0) || (offset != page_info_start.start_offset)) { + LOG_ERR("The offset 0x%lx is not aligned with the starting sector", (long)offset); + return -EINVAL; + } + + rc = flash_get_page_info_by_offs(dev, (offset + len), &page_info_end); + if ((rc != 0) || ((offset + len) != page_info_end.start_offset)) { + LOG_ERR("The size %zu is not aligned with the ending sector", len); + return -EINVAL; + } + + acquire_device(dev); + while (len > 0) { + if (len < SPI_NOR_BLOCK_32K_SIZE) { + erase_size = SPI_NOR_SECTOR_SIZE; + } else if (len < SPI_NOR_BLOCK_SIZE) { + erase_size = SPI_NOR_BLOCK_32K_SIZE; + } else { + erase_size = SPI_NOR_BLOCK_SIZE; + } + + uint8_t *dest = (uint8_t *)FLASH_RZ_BASE_ADDRESS; + + dest += (size_t)offset; + err = config->fsp_api->erase(data->fsp_ctrl, dest, erase_size); + if (FSP_SUCCESS != (fsp_err_t)err) { + LOG_ERR("Erase failed"); + err = -EIO; + break; + } + + err = qspi_wait_until_ready(dev); + if (err) { + LOG_ERR("Failed to get status for QSPI operation"); + err = -EIO; + break; + } + + offset += erase_size; + len -= erase_size; + +#if defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) + spibsc_instance_ctrl_t *p_ctrl = (spibsc_instance_ctrl_t *)data->fsp_ctrl; + + /* Invalidating SPIBSC cache */ + p_ctrl->p_reg->DRCR_b.RCF = 1; + sys_cache_data_invd_range((void *)dest, erase_size); +#endif + } + release_device(dev); + + return err; +} + +static int qspi_flash_rz_read(const struct device *dev, off_t offset, void *data, size_t len) +{ + const struct flash_renesas_rz_config *config = dev->config; + + if (!len) { + return 0; + } + + if (!data) { + return -EINVAL; + } + + if (!qspi_flash_rz_valid(config->flash_size, offset, len)) { + return -EINVAL; + } + + acquire_device(dev); + + uint8_t *dest = (uint8_t *)FLASH_RZ_BASE_ADDRESS; + + dest += (size_t)offset; + memcpy(data, dest, len); + release_device(dev); + + return 0; +} + +static int qspi_flash_rz_write(const struct device *dev, off_t offset, const void *data, size_t len) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *dev_data = dev->data; + int err = 0; + uint32_t remaining_bytes = len; + uint32_t size = (uint32_t)len; + + if (!len) { + return 0; + } + + if (!data) { + return -EINVAL; + } + + if (!qspi_flash_rz_valid(config->flash_size, offset, len)) { + return -EINVAL; + } + + acquire_device(dev); + while (remaining_bytes > 0) { + size = MIN(remaining_bytes, QSPI_MAX_BUFFER_SIZE); + uint8_t *dest = (uint8_t *)FLASH_RZ_BASE_ADDRESS; + + dest += (size_t)offset; + err = config->fsp_api->write(dev_data->fsp_ctrl, (const uint8_t *)data, dest, size); + if (FSP_SUCCESS != (fsp_err_t)err) { + LOG_ERR("Flash write failed"); + err = -EIO; + break; + } + + err = qspi_wait_until_ready(dev); + if (err) { + LOG_ERR("Failed to get status for QSPI operation"); + err = -EIO; + break; + } + + remaining_bytes -= size; + offset += size; + data = (const uint8_t *)data + size; + +#if defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) + spibsc_instance_ctrl_t *p_ctrl = (spibsc_instance_ctrl_t *)dev_data->fsp_ctrl; + + /* Invalidating SPIBSC cache */ + p_ctrl->p_reg->DRCR_b.RCF = 1; + sys_cache_data_invd_range((void *)dest, size); +#endif + } + release_device(dev); + return err; +} + +static int qspi_flash_rz_get_size(const struct device *dev, uint64_t *size) +{ + const struct flash_renesas_rz_config *config = dev->config; + + *size = (uint64_t)config->flash_size; + + return 0; +} + +static const struct flash_parameters *qspi_flash_rz_get_parameters(const struct device *dev) +{ + const struct flash_renesas_rz_config *config = dev->config; + + return &config->flash_param; +} + +#if CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI +static int spi_flash_direct_write(const struct device *dev, uint8_t command, uint32_t tx_data, + uint8_t data_length) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *data = dev->data; + int ret; + + spi_flash_direct_transfer_t trans = { + .command = command, + .address = 0U, + .data = tx_data, + .command_length = 1U, + .address_length = 0U, + .data_length = data_length, + .dummy_cycles = 0U, + }; + + ret = config->fsp_api->directTransfer(data->fsp_ctrl, &trans, + SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE); + if (FSP_SUCCESS != (fsp_err_t)ret) { + LOG_ERR("Failed to write command"); + return -EIO; + }; + + return ret; +} +#endif + +static int flash_renesas_rz_init(const struct device *dev) +{ + const struct flash_renesas_rz_config *config = dev->config; + struct flash_renesas_rz_data *data = dev->data; + int ret = 0; + +#if CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI + ret = pinctrl_apply_state(config->pin_cfg, PINCTRL_STATE_DEFAULT); + if (ret) { + LOG_ERR("Failed to configure pins for QSPI with code: %d", ret); + return -EIO; + } +#endif + k_sem_init(&data->sem, 1, 1); + + ret = config->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + if (FSP_SUCCESS != (fsp_err_t)ret) { + LOG_ERR("Open failed"); + return -EIO; + } + +#if CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI + /* Write Enable Command */ + ret = spi_flash_direct_write(dev, data->fsp_cfg->write_enable_command, 0U, + DATA_LENGTH_DEFAULT_BYTE); + if (ret) { + return ret; + } + + /* Write Status Command */ + ret = spi_flash_direct_write(dev, SPI_NOR_CMD_WRSR, QSPI_DATA_CR_UPDATE, TWO_BYTE); + if (ret) { + return ret; + } +#endif + return ret; +} + +static DEVICE_API(flash, flash_renesas_rz_qspi_driver_api) = { + .erase = qspi_flash_rz_erase, + .write = qspi_flash_rz_write, + .read = qspi_flash_rz_read, + .get_parameters = qspi_flash_rz_get_parameters, + .get_size = qspi_flash_rz_get_size, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_renesas_rz_page_layout, +#endif +#if defined(CONFIG_FLASH_JESD216_API) + .sfdp_read = qspi_flash_renesas_rz_sfdp_read, + .read_jedec_id = qspi_flash_rz_read_jedec_id, +#endif +}; + +#define DT_DRV_COMPAT renesas_rz_qspi_xspi + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define FLASH_RENESAS_RZ_QSPI_XSPI_DEFINE(n) \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(n)); \ + static xspi_qspi_timing_setting_t g_qspi##n##_timing_settings = { \ + .command_to_command_interval = XSPI_QSPI_COMMAND_INTERVAL_CLOCKS_2, \ + .cs_pullup_lag = XSPI_QSPI_CS_PULLUP_CLOCKS_1, \ + .cs_pulldown_lead = XSPI_QSPI_CS_PULLDOWN_CLOCKS_1}; \ + static xspi_qspi_address_space_t g_qspi##n##_address_space_settings = { \ + .unit0_cs0_end_address = XSPI_QSPI_CFG_UNIT_0_CS_0_END_ADDRESS, \ + .unit0_cs1_start_address = XSPI_QSPI_CFG_UNIT_0_CS_1_START_ADDRESS, \ + .unit0_cs1_end_address = XSPI_QSPI_CFG_UNIT_0_CS_1_END_ADDRESS, \ + .unit1_cs0_end_address = XSPI_QSPI_CFG_UNIT_1_CS_0_END_ADDRESS, \ + .unit1_cs1_start_address = XSPI_QSPI_CFG_UNIT_1_CS_1_START_ADDRESS, \ + .unit1_cs1_end_address = XSPI_QSPI_CFG_UNIT_1_CS_1_END_ADDRESS, \ + }; \ + static const xspi_qspi_extended_cfg_t g_qspi##n##_extended_cfg = { \ + .unit = n, \ + .chip_select = XSPI_QSPI_CHIP_SELECT_##n, \ + .memory_size = XSPI_QSPI_MEMORY_SIZE_64MB, \ + .p_timing_settings = &g_qspi##n##_timing_settings, \ + .prefetch_en = \ + (xspi_qspi_prefetch_function_t)XSPI_QSPI_CFG_UNIT_##n##_PREFETCH_FUNCTION, \ + .p_address_space = &g_qspi##n##_address_space_settings, \ + }; \ + static spi_flash_cfg_t g_qspi##n##_cfg = { \ + .spi_protocol = SPI_FLASH_PROTOCOL_1S_1S_1S, \ + .read_mode = SPI_FLASH_READ_MODE_FAST_READ, \ + .address_bytes = SPI_FLASH_ADDRESS_BYTES_3, \ + .dummy_clocks = SPI_FLASH_DUMMY_CLOCKS_10, \ + .read_command = SPI_NOR_CMD_READ_FAST, \ + .page_program_command = SPI_NOR_CMD_PP, \ + .page_program_address_lines = SPI_FLASH_DATA_LINES_4, \ + .page_size_bytes = SPI_NOR_PAGE_SIZE, \ + .write_enable_command = SPI_NOR_CMD_WREN, \ + .status_command = SPI_NOR_CMD_RDSR, \ + .write_status_bit = 0, \ + .xip_enter_command = QSPI_CMD_XIP_ENTER, \ + .xip_exit_command = QSPI_CMD_XIP_EXIT, \ + .p_erase_command_list = &g_erase_command_list[0], \ + .erase_command_list_length = ARRAY_SIZE(g_erase_command_list), \ + .p_extend = &g_qspi##n##_extended_cfg, \ + }; \ + static xspi_qspi_instance_ctrl_t g_qspi##n##_ctrl; \ + static struct flash_renesas_rz_data flash_renesas_rz_data_##n = { \ + .fsp_ctrl = &g_qspi##n##_ctrl, \ + .fsp_cfg = &g_qspi##n##_cfg, \ + }; \ + static const struct flash_renesas_rz_config flash_renesas_rz_config_##n = { \ + .pin_cfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(n)), \ + .fsp_api = &g_spi_flash_on_xspi_qspi, \ + .flash_size = DT_INST_REG_SIZE(n), \ + .erase_block_size = DT_INST_PROP_OR(n, erase_block_size, 4096), \ + .flash_param = \ + { \ + .write_block_size = DT_INST_PROP(n, write_block_size), \ + .erase_value = QSPI_ERASE_VALUE, \ + }, \ + IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, \ + (.layout = { \ + .pages_count = \ + DT_INST_REG_SIZE(n) / DT_INST_PROP_OR(n, erase_block_size, 4096), \ + .pages_size = DT_INST_PROP_OR(n, erase_block_size, 4096), \ + },))}; \ + DEVICE_DT_INST_DEFINE(n, flash_renesas_rz_init, NULL, &flash_renesas_rz_data_##n, \ + &flash_renesas_rz_config_##n, POST_KERNEL, \ + CONFIG_FLASH_INIT_PRIORITY, &flash_renesas_rz_qspi_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(FLASH_RENESAS_RZ_QSPI_XSPI_DEFINE) +#endif + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT renesas_rz_qspi_spibsc + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define FLASH_RENESAS_RZ_QSPI_SPIBSC_DEFINE(n) \ + static const spibsc_extended_cfg_t g_qspi##n##_extended_cfg = { \ + .delay = \ + { \ + .slch = 0, \ + .clsh = 0, \ + .shsl = 6, \ + }, \ + .io_fix_mask = (0u << 2) | (1u << 3), \ + .io_fix_value = (1u << 2) | (1u << 3), \ + }; \ + static spi_flash_cfg_t g_qspi##n##_cfg = { \ + .spi_protocol = SPI_FLASH_PROTOCOL_EXTENDED_SPI, \ + .read_mode = SPI_FLASH_READ_MODE_FAST_READ_QUAD_IO, \ + .address_bytes = SPI_FLASH_ADDRESS_BYTES_3, \ + .dummy_clocks = SPI_FLASH_DUMMY_CLOCKS_DEFAULT, \ + .read_command = SPI_NOR_CMD_4READ, \ + .page_program_command = QSPI_CMD_QUAD_PAGE_PROGRAM, \ + .page_program_address_lines = SPI_FLASH_DATA_LINES_4, \ + .page_size_bytes = SPI_NOR_PAGE_SIZE, \ + .write_enable_command = SPI_NOR_CMD_WREN, \ + .status_command = SPI_NOR_CMD_RDSR, \ + .write_status_bit = 0, \ + .xip_enter_command = QSPI_CMD_XIP_ENTER, \ + .xip_exit_command = QSPI_CMD_XIP_EXIT, \ + .p_erase_command_list = &g_erase_command_list[0], \ + .erase_command_list_length = ARRAY_SIZE(g_erase_command_list), \ + .p_extend = &g_qspi##n##_extended_cfg, \ + }; \ + static spibsc_instance_ctrl_t g_qspi##n##_ctrl; \ + static struct flash_renesas_rz_data flash_renesas_rz_data_##n = { \ + .fsp_ctrl = &g_qspi##n##_ctrl, \ + .fsp_cfg = &g_qspi##n##_cfg, \ + }; \ + static const struct flash_renesas_rz_config flash_renesas_rz_config_##n = { \ + .pin_cfg = NULL, \ + .fsp_api = &g_spi_flash_on_spibsc, \ + .flash_size = DT_INST_REG_SIZE(n), \ + .erase_block_size = DT_INST_PROP_OR(n, erase_block_size, 4096), \ + .flash_param = \ + { \ + .write_block_size = DT_INST_PROP(n, write_block_size), \ + .erase_value = QSPI_ERASE_VALUE, \ + }, \ + IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, \ + (.layout = { \ + .pages_count = \ + DT_INST_REG_SIZE(n) / DT_INST_PROP_OR(n, erase_block_size, 4096), \ + .pages_size = DT_INST_PROP_OR(n, erase_block_size, 4096), \ + },))}; \ + DEVICE_DT_INST_DEFINE(n, flash_renesas_rz_init, NULL, &flash_renesas_rz_data_##n, \ + &flash_renesas_rz_config_##n, POST_KERNEL, \ + CONFIG_FLASH_INIT_PRIORITY, &flash_renesas_rz_qspi_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(FLASH_RENESAS_RZ_QSPI_SPIBSC_DEFINE) +#endif diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index d95f3a18d723e..17592b008e194 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -720,17 +720,12 @@ static int ospi_write_unprotect(const struct device *dev) cmd_unprotect.AddressMode = HAL_OSPI_ADDRESS_NONE; cmd_unprotect.DataMode = HAL_OSPI_DATA_NONE; - if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { - ret = stm32_ospi_write_enable(dev_data, OSPI_SPI_MODE, OSPI_STR_TRANSFER); - - if (ret != 0) { - return ret; - } - - ret = ospi_send_cmd(dev, &cmd_unprotect); + ret = stm32_ospi_write_enable(dev_data, OSPI_SPI_MODE, OSPI_STR_TRANSFER); + if (ret != 0) { + return ret; } - return ret; + return ospi_send_cmd(dev, &cmd_unprotect); } /* Write Flash configuration register 2 with new dummy cycles */ @@ -2599,12 +2594,14 @@ static int flash_stm32_ospi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - ret = ospi_write_unprotect(dev); - if (ret != 0) { - LOG_ERR("write unprotect failed: %d", ret); - return -ENODEV; + if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { + ret = ospi_write_unprotect(dev); + if (ret != 0) { + LOG_ERR("write unprotect failed: %d", ret); + return -ENODEV; + } + LOG_DBG("Write Un-protected"); } - LOG_DBG("Write Un-protected"); #ifdef CONFIG_STM32_MEMMAP /* Now configure the octo Flash in MemoryMapped (access by address) */ diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index 4f55d40b9e0a5..83b945cc93b27 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -454,17 +454,12 @@ static int qspi_write_unprotect(const struct device *dev) .InstructionMode = QSPI_INSTRUCTION_1_LINE, }; - if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { - ret = qspi_send_cmd(dev, &cmd_write_en); - - if (ret != 0) { - return ret; - } - - ret = qspi_send_cmd(dev, &cmd_unprotect); + ret = qspi_send_cmd(dev, &cmd_write_en); + if (ret != 0) { + return ret; } - return ret; + return qspi_send_cmd(dev, &cmd_unprotect); } /* @@ -1601,7 +1596,9 @@ static int flash_stm32_qspi_init(const struct device *dev) /* Initialize DMA HAL */ __HAL_LINKDMA(&dev_data->hqspi, hdma, hdma); - HAL_DMA_Init(&hdma); + if (HAL_DMA_Init(&hdma) != HAL_OK) { + return -EIO; + } #endif /* STM32_QSPI_USE_DMA */ @@ -1648,7 +1645,9 @@ static int flash_stm32_qspi_init(const struct device *dev) dev_data->hqspi.Init.FlashID = QSPI_FLASH_ID_1; #endif /* STM32_QSPI_DOUBLE_FLASH */ - HAL_QSPI_Init(&dev_data->hqspi); + if (HAL_QSPI_Init(&dev_data->hqspi) != HAL_OK) { + return -EIO; + } #if DT_NODE_HAS_PROP(DT_NODELABEL(quadspi), flash_id) && \ defined(QUADSPI_CR_FSEL) @@ -1658,8 +1657,10 @@ static int flash_stm32_qspi_init(const struct device *dev) */ uint8_t qspi_flash_id = DT_PROP(DT_NODELABEL(quadspi), flash_id); - HAL_QSPI_SetFlashID(&dev_data->hqspi, - (qspi_flash_id - 1) << QUADSPI_CR_FSEL_Pos); + if (HAL_QSPI_SetFlashID(&dev_data->hqspi, + (qspi_flash_id - 1) << QUADSPI_CR_FSEL_Pos) != HAL_OK) { + return -EIO; + } #endif /* Initialize semaphores */ k_sem_init(&dev_data->sem, 1, 1); @@ -1739,12 +1740,14 @@ static int flash_stm32_qspi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - ret = qspi_write_unprotect(dev); - if (ret != 0) { - LOG_ERR("write unprotect failed: %d", ret); - return -ENODEV; + if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { + ret = qspi_write_unprotect(dev); + if (ret != 0) { + LOG_ERR("write unprotect failed: %d", ret); + return -ENODEV; + } + LOG_DBG("Write Un-protected"); } - LOG_DBG("Write Un-protected"); #ifdef CONFIG_STM32_MEMMAP ret = stm32_qspi_set_memory_mapped(dev); diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index a7a2d56d90f57..75a5a151921a5 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -390,7 +390,9 @@ static int stm32_xspi_wait_auto_polling(const struct device *dev, if (k_sem_take(&dev_data->sync, K_MSEC(timeout_ms)) != 0) { LOG_ERR("XSPI AutoPoll wait failed"); - HAL_XSPI_Abort(&dev_data->hxspi); + if (HAL_XSPI_Abort(&dev_data->hxspi) != HAL_OK) { + LOG_ERR("XSPI abort failed"); + } k_sem_reset(&dev_data->sync); return -EIO; } @@ -579,17 +581,12 @@ static int xspi_write_unprotect(const struct device *dev) cmd_unprotect.AddressMode = HAL_XSPI_ADDRESS_NONE; cmd_unprotect.DataMode = HAL_XSPI_DATA_NONE; - if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { - ret = stm32_xspi_write_enable(dev, XSPI_SPI_MODE, XSPI_STR_TRANSFER); - - if (ret != 0) { - return ret; - } - - ret = xspi_send_cmd(dev, &cmd_unprotect); + ret = stm32_xspi_write_enable(dev, XSPI_SPI_MODE, XSPI_STR_TRANSFER); + if (ret != 0) { + return ret; } - return ret; + return xspi_send_cmd(dev, &cmd_unprotect); } /* Write Flash configuration register 2 with new dummy cycles */ @@ -2401,12 +2398,14 @@ static int flash_stm32_xspi_init(const struct device *dev) } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - ret = xspi_write_unprotect(dev); - if (ret != 0) { - LOG_ERR("write unprotect failed: %d", ret); - return -ENODEV; + if (IS_ENABLED(DT_INST_PROP(0, requires_ulbpr))) { + ret = xspi_write_unprotect(dev); + if (ret != 0) { + LOG_ERR("write unprotect failed: %d", ret); + return -ENODEV; + } + LOG_DBG("Write Un-protected"); } - LOG_DBG("Write Un-protected"); #ifdef CONFIG_STM32_MEMMAP ret = stm32_xspi_set_memorymap(dev); diff --git a/drivers/flash/spi_nor.h b/drivers/flash/spi_nor.h index 6952d7ea4d70d..3dd66642290de 100644 --- a/drivers/flash/spi_nor.h +++ b/drivers/flash/spi_nor.h @@ -91,9 +91,10 @@ #define SPI_NOR_OCMD_BULKE 0x609F /* Octa Bulk Erase */ /* Page, sector, and block size are standard, not configurable. */ - #define SPI_NOR_PAGE_SIZE 0x0100U - #define SPI_NOR_SECTOR_SIZE 0x1000U - #define SPI_NOR_BLOCK_SIZE 0x10000U +#define SPI_NOR_PAGE_SIZE 0x0100U +#define SPI_NOR_SECTOR_SIZE 0x1000U +#define SPI_NOR_BLOCK_32K_SIZE 0x8000U +#define SPI_NOR_BLOCK_SIZE 0x10000U /* Flash Auto-polling values */ #define SPI_NOR_WREN_MATCH 0x02 diff --git a/drivers/fuel_gauge/CMakeLists.txt b/drivers/fuel_gauge/CMakeLists.txt index afd417040cf89..fa1a0f12bcbfe 100644 --- a/drivers/fuel_gauge/CMakeLists.txt +++ b/drivers/fuel_gauge/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory_ifdef(CONFIG_FUEL_GAUGE_AXP2101 axp2101) add_subdirectory_ifdef(CONFIG_LC709203F lc709203f) add_subdirectory_ifdef(CONFIG_SY24561 sy24561) add_subdirectory_ifdef(CONFIG_BQ40Z50 bq40z50) +add_subdirectory_ifdef(CONFIG_FUEL_GAUGE_LTC2959 ltc2959) zephyr_library_sources_ifdef(CONFIG_USERSPACE fuel_gauge_syscall_handlers.c) diff --git a/drivers/fuel_gauge/Kconfig b/drivers/fuel_gauge/Kconfig index c7168036e3eac..cb4ca429c863f 100644 --- a/drivers/fuel_gauge/Kconfig +++ b/drivers/fuel_gauge/Kconfig @@ -27,5 +27,6 @@ source "drivers/fuel_gauge/composite/Kconfig" source "drivers/fuel_gauge/axp2101/Kconfig" source "drivers/fuel_gauge/lc709203f/Kconfig" source "drivers/fuel_gauge/sy24561/Kconfig" +source "drivers/fuel_gauge/ltc2959/Kconfig" endif # FUEL_GAUGE diff --git a/drivers/fuel_gauge/ltc2959/CMakeLists.txt b/drivers/fuel_gauge/ltc2959/CMakeLists.txt new file mode 100644 index 0000000000000..3c072d684ab17 --- /dev/null +++ b/drivers/fuel_gauge/ltc2959/CMakeLists.txt @@ -0,0 +1,4 @@ +zephyr_library_sources(ltc2959.c) + +zephyr_include_directories_ifdef(CONFIG_EMUL_LTC2959 .) +zephyr_library_sources_ifdef(CONFIG_EMUL_LTC2959 ./emul_ltc2959.c) diff --git a/drivers/fuel_gauge/ltc2959/Kconfig b/drivers/fuel_gauge/ltc2959/Kconfig new file mode 100644 index 0000000000000..070b809c85cca --- /dev/null +++ b/drivers/fuel_gauge/ltc2959/Kconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Nathan Winslow +# +# SPDX-License-Identifier: Apache-2.0 + +config FUEL_GAUGE_LTC2959 + depends on DT_HAS_ADI_LTC2959_ENABLED + bool "LTC2959 Fuel Gauge" + default y + select I2C + help + Enable the LTC2959 fuel gauge driver from Analog Devices. + +config EMUL_LTC2959 + bool "Emulate an LTC2959 fuel gauge" + default y + depends on EMUL + depends on FUEL_GAUGE_LTC2959 + help + It provides readings which follow a simple sequence, thus allowing + test code to check that things are working as expected. diff --git a/drivers/fuel_gauge/ltc2959/emul_ltc2959.c b/drivers/fuel_gauge/ltc2959/emul_ltc2959.c new file mode 100644 index 0000000000000..fe40019cc8142 --- /dev/null +++ b/drivers/fuel_gauge/ltc2959/emul_ltc2959.c @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2025 Nathan Winslow + * SPDX-License-Identifier: Apache-2.0 + * + * Emulator for ltc2959 fuel gauge + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT adi_ltc2959 + +LOG_MODULE_REGISTER(EMUL_LTC2959); + +#include "ltc2959.h" + +struct ltc2959_emul_data { + uint8_t regs[LTC2959_REG_GPIO_THRESH_LOW_LSB + 1]; /* enough for all regs */ +}; + +struct ltc2959_emul_cfg { + /* I2C Address of emulator */ + uint16_t addr; +}; + +static int ltc2959_emul_reset(const struct emul *target) +{ + struct ltc2959_emul_data *data = (struct ltc2959_emul_data *)target->data; + + memset(data->regs, 0, sizeof(data->regs)); + + /* Values according to pgs 10-11 of the LTC2959 datasheet */ + data->regs[LTC2959_REG_STATUS] = 0x01; + data->regs[LTC2959_REG_ADC_CONTROL] = 0x18; + data->regs[LTC2959_REG_CC_CONTROL] = 0x50; + data->regs[LTC2959_REG_ACC_CHARGE_3] = 0x80; + data->regs[LTC2959_REG_CHG_THRESH_HIGH_3] = 0xFF; + data->regs[LTC2959_REG_CHG_THRESH_HIGH_2] = 0xFF; + data->regs[LTC2959_REG_CHG_THRESH_HIGH_1] = 0xFF; + data->regs[LTC2959_REG_CHG_THRESH_HIGH_0] = 0xFF; + data->regs[LTC2959_REG_VOLT_THRESH_HIGH_MSB] = 0xFF; + data->regs[LTC2959_REG_VOLT_THRESH_HIGH_LSB] = 0xFF; + data->regs[LTC2959_REG_CURR_THRESH_HIGH_MSB] = 0x7F; + data->regs[LTC2959_REG_CURR_THRESH_HIGH_LSB] = 0xFF; + data->regs[LTC2959_REG_CURR_THRESH_LOW_MSB] = 0x80; + data->regs[LTC2959_REG_MAX_CURRENT_MSB] = 0x80; + data->regs[LTC2959_REG_MIN_CURRENT_MSB] = 0x7F; + data->regs[LTC2959_REG_MIN_CURRENT_LSB] = 0xFF; + data->regs[LTC2959_REG_TEMP_THRESH_HIGH_MSB] = 0xFF; + data->regs[LTC2959_REG_TEMP_THRESH_HIGH_LSB] = 0xFF; + data->regs[LTC2959_REG_GPIO_THRESH_HIGH_MSB] = 0x7F; + data->regs[LTC2959_REG_GPIO_THRESH_HIGH_LSB] = 0xFF; + data->regs[LTC2959_REG_GPIO_THRESH_LOW_MSB] = 0x80; + + return 0; +} + +static int emul_ltc2959_reg_write(const struct emul *target, int reg, int val) +{ + struct ltc2959_emul_data *data = target->data; + + switch (reg) { + case LTC2959_REG_ADC_CONTROL: + case LTC2959_REG_CC_CONTROL: + case LTC2959_REG_ACC_CHARGE_3: + case LTC2959_REG_ACC_CHARGE_2: + case LTC2959_REG_ACC_CHARGE_1: + case LTC2959_REG_ACC_CHARGE_0: + case LTC2959_REG_CHG_THRESH_LOW_3: + case LTC2959_REG_CHG_THRESH_LOW_2: + case LTC2959_REG_CHG_THRESH_LOW_1: + case LTC2959_REG_CHG_THRESH_LOW_0: + case LTC2959_REG_CHG_THRESH_HIGH_3: + case LTC2959_REG_CHG_THRESH_HIGH_2: + case LTC2959_REG_CHG_THRESH_HIGH_1: + case LTC2959_REG_CHG_THRESH_HIGH_0: + case LTC2959_REG_VOLT_THRESH_HIGH_MSB: + case LTC2959_REG_VOLT_THRESH_HIGH_LSB: + case LTC2959_REG_VOLT_THRESH_LOW_MSB: + case LTC2959_REG_VOLT_THRESH_LOW_LSB: + case LTC2959_REG_MAX_VOLTAGE_MSB: + case LTC2959_REG_MAX_VOLTAGE_LSB: + case LTC2959_REG_MIN_VOLTAGE_MSB: + case LTC2959_REG_MIN_VOLTAGE_LSB: + case LTC2959_REG_CURR_THRESH_HIGH_MSB: + case LTC2959_REG_CURR_THRESH_HIGH_LSB: + case LTC2959_REG_CURR_THRESH_LOW_MSB: + case LTC2959_REG_CURR_THRESH_LOW_LSB: + case LTC2959_REG_MAX_CURRENT_MSB: + case LTC2959_REG_MAX_CURRENT_LSB: + case LTC2959_REG_MIN_CURRENT_MSB: + case LTC2959_REG_MIN_CURRENT_LSB: + case LTC2959_REG_TEMP_THRESH_HIGH_MSB: + case LTC2959_REG_TEMP_THRESH_HIGH_LSB: + case LTC2959_REG_TEMP_THRESH_LOW_MSB: + case LTC2959_REG_TEMP_THRESH_LOW_LSB: + case LTC2959_REG_GPIO_THRESH_HIGH_MSB: + case LTC2959_REG_GPIO_THRESH_HIGH_LSB: + case LTC2959_REG_GPIO_THRESH_LOW_MSB: + case LTC2959_REG_GPIO_THRESH_LOW_LSB: + data->regs[reg] = val; + break; + + case LTC2959_REG_STATUS: + case LTC2959_REG_VOLTAGE_MSB: + case LTC2959_REG_VOLTAGE_LSB: + case LTC2959_REG_CURRENT_MSB: + case LTC2959_REG_CURRENT_LSB: + case LTC2959_REG_TEMP_MSB: + case LTC2959_REG_TEMP_LSB: + case LTC2959_REG_GPIO_VOLTAGE_MSB: + case LTC2959_REG_GPIO_VOLTAGE_LSB: + default: + LOG_ERR("Unknown or Read Only Register: 0x%x", reg); + return -EIO; + } + return 0; +} + +static int emul_ltc2959_reg_read(const struct emul *target, int reg, int *val) +{ + if (reg < LTC2959_REG_STATUS || reg > LTC2959_REG_GPIO_THRESH_LOW_LSB) { + LOG_ERR("Unknown Register: 0x%x", reg); + return -EIO; + } + + struct ltc2959_emul_data *data = target->data; + *val = data->regs[reg]; + + return 0; +} + +static int ltc2959_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, int num_msgs, + int addr) +{ + __ASSERT_NO_MSG(msgs && num_msgs); + i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false); + + switch (num_msgs) { + case 1: { + /* Single write: [reg, data0, data1, ...] */ + struct i2c_msg *m = &msgs[0]; + + if (m->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected single-message read"); + return -EIO; + } + if (m->len < 2) { + LOG_ERR("Single-message write must be reg+data (len=%d)", m->len); + return -EIO; + } + uint8_t reg = m->buf[0]; + + for (size_t i = 1; i < m->len; i++, reg++) { + int ret = emul_ltc2959_reg_write(target, reg, m->buf[i]); + + if (ret < 0) { + return ret; + } + } + return 0; + } + + case 2: { + /* Two-message: [reg], then [read N] OR [write N] */ + struct i2c_msg *m0 = &msgs[0]; + struct i2c_msg *m1 = &msgs[1]; + + if ((m0->flags & I2C_MSG_READ) || m0->len != 1) { + LOG_ERR("Invalid first msg (flags=0x%x len=%d)", m0->flags, m0->len); + return -EIO; + } + + uint8_t reg = m0->buf[0]; + + if (m1->flags & I2C_MSG_READ) { + /* Burst READ: stream N bytes starting at reg */ + for (size_t i = 0; i < m1->len; i++) { + int val; + int ret = emul_ltc2959_reg_read(target, reg + i, &val); + + if (ret < 0) { + return ret; + } + + m1->buf[i] = (uint8_t)val; + } + return 0; + } + /* Burst WRITE: stream N bytes into reg..reg+N-1 */ + if (!m1->len) { + LOG_ERR("Empty write"); + return -EIO; + } + for (size_t i = 0; i < m1->len; i++) { + int ret = emul_ltc2959_reg_write(target, reg + i, m1->buf[i]); + + if (ret < 0) { + return ret; + } + } + return 0; + } + + default: + LOG_ERR("Unsupported number of I2C messages: %d", num_msgs); + return -EIO; + } +} + +/* The I2C emulator API required by Zephyr. */ +static const struct i2c_emul_api ltc2959_emul_api_i2c = { + .transfer = ltc2959_emul_transfer_i2c, +}; + +#ifdef CONFIG_ZTEST +#include + +/* Add test reset handlers in when using emulators with tests */ +#define LTC2959_EMUL_RESET_RULE_BEFORE(inst) ltc2959_emul_reset(EMUL_DT_GET(DT_DRV_INST(inst))); + +static void ltc2959_gauge_reset_rule_after(const struct ztest_unit_test *test, void *data) +{ + ARG_UNUSED(test); + ARG_UNUSED(data); + + DT_INST_FOREACH_STATUS_OKAY(LTC2959_EMUL_RESET_RULE_BEFORE) +} +ZTEST_RULE(ltc2959_gauge_reset, NULL, ltc2959_gauge_reset_rule_after); +#endif /* CONFIG_ZTEST */ + +static int ltc2959_emul_init(const struct emul *target, const struct device *parent) +{ + ARG_UNUSED(parent); + ltc2959_emul_reset(target); + return 0; +} + +/* + * Main instantiation macro. + */ +#define DEFINE_LTC2959_EMUL(n) \ + static struct ltc2959_emul_data ltc2959_emul_data_##n; \ + static const struct ltc2959_emul_cfg ltc2959_emul_cfg_##n = { \ + .addr = DT_INST_REG_ADDR(n), \ + }; \ + EMUL_DT_INST_DEFINE(n, ltc2959_emul_init, <c2959_emul_data_##n, <c2959_emul_cfg_##n, \ + <c2959_emul_api_i2c, NULL) + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_LTC2959_EMUL); diff --git a/drivers/fuel_gauge/ltc2959/ltc2959.c b/drivers/fuel_gauge/ltc2959/ltc2959.c new file mode 100644 index 0000000000000..32f2cec1eed85 --- /dev/null +++ b/drivers/fuel_gauge/ltc2959/ltc2959.c @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2025, Nathan Winslow + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ltc2959.h" + +#define DT_DRV_COMPAT adi_ltc2959 + +LOG_MODULE_REGISTER(LTC2959, CONFIG_FUEL_GAUGE_LOG_LEVEL); + +#define LTC2959_TEMP_K_SF (8250) +#define LTC2959_VOLT_UV_SF (955) /* µV per full-scale (16-bit) */ +#define LTC2959_GPIO_BIPOLAR_UV_SF (97500) +#define LTC2959_GPIO_UNIPOLAR_UV_SF (1560000) +#define LTC2959_VOLT_THRESH_UV_SCALAR (62600000) + +/* CONTROL Register Bit Masks */ +#define LTC2959_CTRL_ADC_MODE_MASK GENMASK(7, 5) +#define LTC2959_CTRL_GPIO_MODE_MASK GENMASK(4, 3) +#define LTC2959_CTRL_VIN_SEL_BIT BIT(2) +#define LTC2959_CTRL_RESERVED_MASK GENMASK(1, 0) + +#define LTC2959_CC_WRITABLE_MASK (BIT(7) | BIT(6) | BIT(3)) /* 0xC8 */ +#define LTC2959_CC_RESERVED_FIXED BIT(4) + +/* Used when ACR is controlled via firmware */ +#define LTC2959_ACR_CLR (0xFFFFFFFF) +/* ACR base (50 mΩ) LSB: 533 nAh = 0.533 µAh */ +#define LTC2959_ACR_UAH_NUM (533u) /* numerator (µAh) */ +#define LTC2959_ACR_UAH_DEN (1000u) /* denominator (—) */ +#define LTC2959_ACR_RSENSE_REF_MOHM (50u) + +/* Voltage source selection (bit 2 of Control Register) */ +#define LTC2959_VIN_VDD (0x0 << 2) +#define LTC2959_VIN_SENSEN (0x1 << 2) + +/* STATUS Register Bit Definitions (0x00) */ +enum ltc2959_status_flags { + LTC2959_STATUS_GPIO_ALERT = BIT(7), /* Default: 0 */ + LTC2959_STATUS_CURRENT_ALERT = BIT(6), /* Default: 0 */ + LTC2959_STATUS_CHARGE_OVER_UNDER = BIT(5), /* Default: 0 */ + LTC2959_STATUS_TEMP_ALERT = BIT(4), /* Default: 0 */ + LTC2959_STATUS_CHARGE_HIGH = BIT(3), /* Default: 0 */ + LTC2959_STATUS_CHARGE_LOW = BIT(2), /* Default: 0 */ + LTC2959_STATUS_VOLTAGE_ALERT = BIT(1), /* Default: 0 */ + LTC2959_STATUS_UVLO = BIT(0) /* Default: 1 */ +}; + +/* ADC mode values (bits 7:5 of CONTROL register 0x01) */ +enum ltc2959_adc_modes { + LTC2959_ADC_MODE_SLEEP = 0x00, + LTC2959_ADC_MODE_SMART_SLEEP = 0x20, + LTC2959_ADC_MODE_CONT_V = 0x40, + LTC2959_ADC_MODE_CONT_I = 0x60, + LTC2959_ADC_MODE_CONT_VI = 0x80, + LTC2959_ADC_MODE_SINGLE_SHOT = 0xA0, + LTC2959_ADC_MODE_CONT_VIT = 0xC0 /* recommended for full telemetry */ +}; + +/* GPIO mode bits (bits 4:3 of CONTROL register 0x01) */ +enum ltc2959_gpio_modes { + LTC2959_GPIO_MODE_ALERT = 0x00, + LTC2959_GPIO_MODE_CHGCOMP = 0x08, + LTC2959_GPIO_MODE_BIPOLAR = 0x10, + LTC2959_GPIO_MODE_UNIPOLAR = 0x18, +}; + +/* CC Control bits (CC register 0x02)*/ +enum ltc2959_cc_options { + LTC2959_CC_DEADBAND_0UV = (0b00 << 6), + LTC2959_CC_DEADBAND_20UV = (0b01 << 6), + LTC2959_CC_DEADBAND_40UV = (0b10 << 6), + LTC2959_CC_DEADBAND_80UV = (0b11 << 6), + LTC2959_CC_DO_NOT_COUNT = BIT(3), +}; + +struct ltc2959_config { + struct i2c_dt_spec i2c; + int32_t current_lsb_ua; + uint32_t rsense_milliohms; +}; + +static int ltc2959_read16(const struct device *dev, uint8_t reg, uint16_t *value) +{ + uint8_t buf[2]; + const struct ltc2959_config *cfg = dev->config; + int ret = i2c_burst_read_dt(&cfg->i2c, reg, buf, sizeof(buf)); + + if (ret < 0) { + LOG_ERR("Failed to read 16-bit register 0x%02X", reg); + return ret; + } + + *value = sys_get_be16(buf); + return 0; +} + +static int ltc2959_read32(const struct device *dev, uint8_t reg, uint32_t *value) +{ + uint8_t buf[4]; + const struct ltc2959_config *cfg = dev->config; + int ret = i2c_burst_read_dt(&cfg->i2c, reg, buf, sizeof(buf)); + + if (ret < 0) { + LOG_ERR("Failed to read 32-bit register 0x%02X", reg); + return ret; + } + + *value = sys_get_be32(buf); + return 0; +} + +static int ltc2959_get_adc_mode(const struct device *dev, uint8_t *mode) +{ + const struct ltc2959_config *cfg = dev->config; + + return i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_ADC_CONTROL, mode); +} + +static int ltc2959_set_adc_mode(const struct device *dev, uint8_t mode) +{ + const struct ltc2959_config *cfg = dev->config; + uint8_t ctrl; + int ret; + + if ((mode & ~(LTC2959_CTRL_ADC_MODE_MASK | LTC2959_CTRL_GPIO_MODE_MASK | + LTC2959_CTRL_VIN_SEL_BIT)) != 0U) { + return -EINVAL; + } + + ret = i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_ADC_CONTROL, &ctrl); + + if (ret < 0) { + return ret; + } + + ctrl &= ~(LTC2959_CTRL_ADC_MODE_MASK | LTC2959_CTRL_GPIO_MODE_MASK | + LTC2959_CTRL_VIN_SEL_BIT); + ctrl |= mode; + + ret = i2c_reg_write_byte_dt(&cfg->i2c, LTC2959_REG_ADC_CONTROL, ctrl); + + if (ret < 0) { + LOG_ERR("Failed to set ADC mode: 0x%02x (ctrl=0x%02x)", mode, ctrl); + return ret; + } + + return 0; +} + +static int ltc2959_get_cc_config(const struct device *dev, uint8_t *value) +{ + const struct ltc2959_config *cfg = dev->config; + + return i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_CC_CONTROL, value); +} + +static int ltc2959_set_cc_config(const struct device *dev, uint8_t value) +{ + const struct ltc2959_config *cfg = dev->config; + uint8_t mask = (value & LTC2959_CC_WRITABLE_MASK) | LTC2959_CC_RESERVED_FIXED; + + LOG_DBG("setting cc to: 0x%02X", mask); + return i2c_reg_write_byte_dt(&cfg->i2c, LTC2959_REG_CC_CONTROL, mask); +} + +static inline uint32_t u64_div_round_closest_u32_sat(uint64_t n, uint32_t d) +{ + /* round-to-nearest: (n + d/2) / d, with saturation to u32 */ + uint64_t q = (n + (uint64_t)(d / 2u)) / d; + + return (q > UINT32_MAX) ? UINT32_MAX : (uint32_t)q; +} + +static inline uint32_t ltc2959_counts_to_uah(uint32_t counts, const struct ltc2959_config *cfg) +{ + /* µAh = counts * 0.533µAh * (50 mΩ / r_sense) */ + uint64_t prod = (uint64_t)counts * (uint64_t)LTC2959_ACR_UAH_NUM * + (uint64_t)LTC2959_ACR_RSENSE_REF_MOHM; + uint32_t den = LTC2959_ACR_UAH_DEN * cfg->rsense_milliohms; + + return u64_div_round_closest_u32_sat(prod, den); +} + +static inline uint32_t ltc2959_uah_to_counts(uint32_t uah, const struct ltc2959_config *cfg) +{ + /* counts = µAh * (r_sense / 50 mΩ) * 1000 / 533 */ + uint64_t prod = + (uint64_t)uah * (uint64_t)LTC2959_ACR_UAH_DEN * (uint64_t)cfg->rsense_milliohms; + uint32_t den = LTC2959_ACR_UAH_NUM * LTC2959_ACR_RSENSE_REF_MOHM; + + return u64_div_round_closest_u32_sat(prod, den); +} + +static int ltc2959_read_acr(const struct device *dev, uint32_t *value) +{ + return ltc2959_read32(dev, LTC2959_REG_ACC_CHARGE_3, value); +} + +static int ltc2959_write_acr(const struct device *dev, uint32_t value) +{ + const struct ltc2959_config *cfg = dev->config; + uint8_t buf[4]; + + sys_put_be32(value, buf); + return i2c_burst_write_dt(&cfg->i2c, LTC2959_REG_ACC_CHARGE_3, buf, sizeof(buf)); +} + +static int ltc2959_get_gpio_voltage_uv(const struct device *dev, int32_t *value_uv) +{ + uint8_t ctrl; + uint16_t raw; + + int ret = ltc2959_get_adc_mode(dev, &ctrl); + + if (ret < 0) { + return ret; + } + + ret = ltc2959_read16(dev, LTC2959_REG_GPIO_VOLTAGE_MSB, &raw); + + if (ret < 0) { + return ret; + } + + int16_t raw_signed = (int16_t)raw; + uint8_t gpio_mode = ctrl & LTC2959_CTRL_GPIO_MODE_MASK; + + switch (gpio_mode) { + case LTC2959_GPIO_MODE_BIPOLAR: + *value_uv = ((int64_t)raw_signed * LTC2959_GPIO_BIPOLAR_UV_SF) >> 15; + break; + + case LTC2959_GPIO_MODE_UNIPOLAR: + *value_uv = + (int32_t)(((uint64_t)raw * (uint64_t)LTC2959_GPIO_UNIPOLAR_UV_SF) >> 15); + break; + + default: + LOG_ERR("Unsupported GPIO analog mode: 0x%x", gpio_mode); + return -EINVAL; + } + + return 0; +} + +static int ltc2959_get_gpio_threshold_uv(const struct device *dev, bool high, int32_t *value_uv) +{ + uint8_t reg = high ? LTC2959_REG_GPIO_THRESH_HIGH_MSB : LTC2959_REG_GPIO_THRESH_LOW_MSB; + const struct ltc2959_config *cfg = dev->config; + uint8_t ctrl; + + int ret = i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_ADC_CONTROL, &ctrl); + + if (ret < 0) { + LOG_ERR("NO CTRL: %i", ret); + return ret; + } + + uint16_t raw_th; + + ret = ltc2959_read16(dev, reg, &raw_th); + + if (ret < 0) { + return ret; + } + + int16_t raw_signed = (int16_t)raw_th; + uint8_t gpio_mode = ctrl & LTC2959_CTRL_GPIO_MODE_MASK; + + switch (gpio_mode) { + case LTC2959_GPIO_MODE_BIPOLAR: + *value_uv = ((int64_t)raw_signed * LTC2959_GPIO_BIPOLAR_UV_SF) >> 15; + break; + + case LTC2959_GPIO_MODE_UNIPOLAR: + *value_uv = + (int32_t)(((uint64_t)raw_th * (uint64_t)LTC2959_GPIO_UNIPOLAR_UV_SF) >> 15); + break; + + default: + LOG_ERR("Unsupported GPIO mode: 0x%x", gpio_mode); + return -ENOTSUP; + } + return 0; +} + +static int ltc2959_set_gpio_threshold_uv(const struct device *dev, bool high, int32_t value_uv) +{ + uint8_t reg = high ? LTC2959_REG_GPIO_THRESH_HIGH_MSB : LTC2959_REG_GPIO_THRESH_LOW_MSB; + + const struct ltc2959_config *cfg = dev->config; + + uint8_t ctrl; + int ret = i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_ADC_CONTROL, &ctrl); + + if (ret < 0) { + return ret; + } + + uint8_t gpio_mode = ctrl & LTC2959_CTRL_GPIO_MODE_MASK; + + switch (gpio_mode) { + case LTC2959_GPIO_MODE_BIPOLAR: { + int64_t raw_bp64 = ((int64_t)value_uv * 32768) / LTC2959_GPIO_BIPOLAR_UV_SF; + + if ((raw_bp64 < INT16_MIN) || (raw_bp64 > INT16_MAX)) { + return -ERANGE; + } + + uint16_t raw_bp = (uint16_t)((int16_t)raw_bp64); + uint8_t buf[2]; + + sys_put_be16(raw_bp, buf); + return i2c_burst_write_dt(&cfg->i2c, reg, buf, sizeof(buf)); + } + case LTC2959_GPIO_MODE_UNIPOLAR: { + + if (value_uv < 0) { + return -ERANGE; + } + + int64_t raw_up64 = ((int64_t)value_uv * 32768) / LTC2959_GPIO_UNIPOLAR_UV_SF; + + if ((raw_up64 < 0) || (raw_up64 > UINT16_MAX)) { + return -ERANGE; + } + + uint16_t raw_up = (uint16_t)raw_up64; + uint8_t buf[2]; + + sys_put_be16(raw_up, buf); + return i2c_burst_write_dt(&cfg->i2c, reg, buf, sizeof(buf)); + } + default: + break; + } + + LOG_ERR("Unsupported GPIO mode: 0x%02x", gpio_mode); + return -ENOTSUP; +} + +static int ltc2959_get_voltage_threshold_uv(const struct device *dev, bool high, uint32_t *value) +{ + uint8_t reg = high ? LTC2959_REG_VOLT_THRESH_HIGH_MSB : LTC2959_REG_VOLT_THRESH_LOW_MSB; + uint16_t raw; + int ret = ltc2959_read16(dev, reg, &raw); + + if (ret < 0) { + LOG_ERR("Failed to get voltage threshold: %i", ret); + return ret; + } + + *value = ((uint64_t)raw * LTC2959_VOLT_THRESH_UV_SCALAR) >> 15; + + return 0; +} + +static int ltc2959_set_voltage_threshold_uv(const struct device *dev, bool high, uint32_t value) +{ + uint8_t reg = high ? LTC2959_REG_VOLT_THRESH_HIGH_MSB : LTC2959_REG_VOLT_THRESH_LOW_MSB; + uint64_t raw64 = ((uint64_t)value << 15) / LTC2959_VOLT_THRESH_UV_SCALAR; + + if (raw64 > UINT16_MAX) { + return -ERANGE; + } + + uint16_t raw = (uint16_t)raw64; + + uint8_t buf[2]; + + sys_put_be16(raw, buf); + const struct ltc2959_config *cfg = dev->config; + + return i2c_burst_write_dt(&cfg->i2c, reg, buf, sizeof(buf)); +} + +static int ltc2959_get_current_threshold_ua(const struct device *dev, bool high, int32_t *value_ua) +{ + uint8_t reg = high ? LTC2959_REG_CURR_THRESH_HIGH_MSB : LTC2959_REG_CURR_THRESH_LOW_MSB; + + uint16_t raw_cth; + int ret = ltc2959_read16(dev, reg, &raw_cth); + + if (ret < 0) { + return ret; + } + + const struct ltc2959_config *cfg = dev->config; + int16_t signed_raw = (int16_t)raw_cth; + *value_ua = signed_raw * cfg->current_lsb_ua; + + return 0; +} + +static int ltc2959_set_current_threshold_ua(const struct device *dev, bool high, int32_t value_ua) +{ + uint8_t reg = high ? LTC2959_REG_CURR_THRESH_HIGH_MSB : LTC2959_REG_CURR_THRESH_LOW_MSB; + const struct ltc2959_config *cfg = dev->config; + + if (!cfg->current_lsb_ua) { + return -ERANGE; + } + + int32_t raw32 = value_ua / cfg->current_lsb_ua; + + /* To account for cases where current thresholds are +-2A */ + int16_t raw16 = CLAMP(raw32, INT16_MIN, INT16_MAX); + uint8_t buf[2]; + + sys_put_be16(raw16, buf); + return i2c_burst_write_dt(&cfg->i2c, reg, buf, sizeof(buf)); +} + +static int ltc2959_get_temp_threshold_dK(const struct device *dev, bool high, uint16_t *value_dK) +{ + uint8_t reg = high ? LTC2959_REG_TEMP_THRESH_HIGH_MSB : LTC2959_REG_TEMP_THRESH_LOW_MSB; + uint16_t raw_tth; + int ret = ltc2959_read16(dev, reg, &raw_tth); + + if (ret < 0) { + return ret; + } + + *value_dK = ((uint32_t)raw_tth * LTC2959_TEMP_K_SF) >> 16; + + return 0; +} + +static int ltc2959_set_temp_threshold_dK(const struct device *dev, bool high, uint16_t value_dK) +{ + uint8_t reg = high ? LTC2959_REG_TEMP_THRESH_HIGH_MSB : LTC2959_REG_TEMP_THRESH_LOW_MSB; + uint64_t raw64 = ((uint64_t)value_dK << 16) / LTC2959_TEMP_K_SF; + + if (raw64 > UINT16_MAX) { + return -ERANGE; + } + + uint16_t raw = (uint16_t)raw64; + uint8_t buf[2]; + + sys_put_be16(raw, buf); + const struct ltc2959_config *cfg = dev->config; + + return i2c_burst_write_dt(&cfg->i2c, reg, buf, sizeof(buf)); +} + +static int ltc2959_get_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val *val) +{ + const struct ltc2959_config *cfg = dev->config; + int ret; + + switch (prop) { + case FUEL_GAUGE_STATUS: { + uint8_t raw_st; + + ret = i2c_reg_read_byte_dt(&cfg->i2c, LTC2959_REG_STATUS, &raw_st); + + if (ret < 0) { + return ret; + } + + val->fg_status = raw_st; + + break; + } + case FUEL_GAUGE_VOLTAGE: { + uint16_t raw_voltage; + + ret = ltc2959_read16(dev, LTC2959_REG_VOLTAGE_MSB, &raw_voltage); + + if (ret < 0) { + return ret; + } + /** + * NOTE: LSB = 62.6V / 65536 = ~955 µV + * Zephyr's API expects this value in microvolts + * https://docs.zephyrproject.org/latest/doxygen/html/group__fuel__gauge__interface.html + */ + val->voltage = raw_voltage * LTC2959_VOLT_UV_SF; + + return 0; + } + case FUEL_GAUGE_CURRENT: { + uint16_t raw_current; + + ret = ltc2959_read16(dev, LTC2959_REG_CURRENT_MSB, &raw_current); + + if (ret < 0) { + return ret; + } + + /* Signed 16-bit value from ADC */ + int16_t current_raw = (int16_t)raw_current; + + val->current = current_raw * cfg->current_lsb_ua; + + break; + } + case FUEL_GAUGE_TEMPERATURE: { + uint16_t raw_temp; + + ret = ltc2959_read16(dev, LTC2959_REG_TEMP_MSB, &raw_temp); + + if (ret < 0) { + return ret; + } + /** + * NOTE: + * Temp is in deciKelvin as per API requirements. + * from the datasheet: + * T(°C) = 825 * (raw / 65536) - 273.15 + * T(dK) = 8250 * (raw / 65536) + * 65536 = 2 ^ 16, so we can avoid division altogether. + */ + val->temperature = ((uint32_t)raw_temp * LTC2959_TEMP_K_SF) >> 16; + break; + } + case FUEL_GAUGE_REMAINING_CAPACITY: { + uint32_t acr; + + ret = ltc2959_read_acr(dev, &acr); + + if (ret < 0) { + return ret; + } + + val->remaining_capacity = ltc2959_counts_to_uah(acr, cfg); + break; + } + case FUEL_GAUGE_ADC_MODE: + ret = ltc2959_get_adc_mode(dev, &val->adc_mode); + break; + + case FUEL_GAUGE_HIGH_VOLTAGE_ALARM: + ret = ltc2959_get_voltage_threshold_uv(dev, true, &val->high_voltage_alarm); + break; + + case FUEL_GAUGE_LOW_VOLTAGE_ALARM: + ret = ltc2959_get_voltage_threshold_uv(dev, false, &val->low_voltage_alarm); + break; + + case FUEL_GAUGE_HIGH_CURRENT_ALARM: + ret = ltc2959_get_current_threshold_ua(dev, true, &val->high_current_alarm); + break; + + case FUEL_GAUGE_LOW_CURRENT_ALARM: + ret = ltc2959_get_current_threshold_ua(dev, false, &val->low_current_alarm); + break; + + case FUEL_GAUGE_HIGH_TEMPERATURE_ALARM: + ret = ltc2959_get_temp_threshold_dK(dev, true, &val->high_temperature_alarm); + break; + + case FUEL_GAUGE_LOW_TEMPERATURE_ALARM: + ret = ltc2959_get_temp_threshold_dK(dev, false, &val->low_temperature_alarm); + break; + + case FUEL_GAUGE_GPIO_VOLTAGE: + ret = ltc2959_get_gpio_voltage_uv(dev, &val->gpio_voltage); + break; + + case FUEL_GAUGE_HIGH_GPIO_ALARM: + ret = ltc2959_get_gpio_threshold_uv(dev, true, &val->high_gpio_alarm); + break; + + case FUEL_GAUGE_LOW_GPIO_ALARM: + ret = ltc2959_get_gpio_threshold_uv(dev, false, &val->low_gpio_alarm); + break; + + case FUEL_GAUGE_CC_CONFIG: + ret = ltc2959_get_cc_config(dev, &val->cc_config); + break; + + default: + return -ENOTSUP; + } + return ret; +} + +static int ltc2959_set_prop(const struct device *dev, fuel_gauge_prop_t prop, + union fuel_gauge_prop_val val) +{ + int ret = 0; + const struct ltc2959_config *cfg = dev->config; + + switch (prop) { + case FUEL_GAUGE_ADC_MODE: + ret = ltc2959_set_adc_mode(dev, val.adc_mode); + break; + + case FUEL_GAUGE_LOW_VOLTAGE_ALARM: + ret = ltc2959_set_voltage_threshold_uv(dev, false, val.low_voltage_alarm); + break; + + case FUEL_GAUGE_HIGH_VOLTAGE_ALARM: + ret = ltc2959_set_voltage_threshold_uv(dev, true, val.high_voltage_alarm); + break; + + case FUEL_GAUGE_LOW_CURRENT_ALARM: + ret = ltc2959_set_current_threshold_ua(dev, false, val.low_current_alarm); + break; + + case FUEL_GAUGE_HIGH_CURRENT_ALARM: + ret = ltc2959_set_current_threshold_ua(dev, true, val.high_current_alarm); + break; + + case FUEL_GAUGE_LOW_TEMPERATURE_ALARM: + ret = ltc2959_set_temp_threshold_dK(dev, false, val.low_temperature_alarm); + break; + + case FUEL_GAUGE_HIGH_TEMPERATURE_ALARM: + ret = ltc2959_set_temp_threshold_dK(dev, true, val.high_temperature_alarm); + break; + + case FUEL_GAUGE_LOW_GPIO_ALARM: + ret = ltc2959_set_gpio_threshold_uv(dev, false, val.low_gpio_alarm); + break; + + case FUEL_GAUGE_HIGH_GPIO_ALARM: + ret = ltc2959_set_gpio_threshold_uv(dev, true, val.high_gpio_alarm); + break; + + case FUEL_GAUGE_CC_CONFIG: + LOG_DBG("config stats: 0x%02X", val.cc_config); + ret = ltc2959_set_cc_config(dev, val.cc_config); + break; + + case FUEL_GAUGE_REMAINING_CAPACITY: { + uint32_t counts = ltc2959_uah_to_counts(val.remaining_capacity, cfg); + + if (counts == LTC2959_ACR_CLR) { + counts = LTC2959_ACR_CLR - 1; + } + ret = ltc2959_write_acr(dev, counts); + break; + } + default: + ret = -ENOTSUP; + break; + } + return ret; +} + +static int ltc2959_init(const struct device *dev) +{ + const struct ltc2959_config *cfg = dev->config; + + if (!device_is_ready(cfg->i2c.bus)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + return 0; +} + +static DEVICE_API(fuel_gauge, ltc2959_driver_api) = { + .get_property = <c2959_get_prop, + .set_property = <c2959_set_prop, +}; + +#define LTC2959_DEFINE(inst) \ + BUILD_ASSERT(DT_NODE_HAS_PROP(DT_DRV_INST(inst), rsense_milliohms)); \ + BUILD_ASSERT(DT_INST_PROP(inst, rsense_milliohms) > 0); \ + static const struct ltc2959_config ltc2959_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .current_lsb_ua = (97500000 / (DT_INST_PROP(inst, rsense_milliohms) * 32768)), \ + .rsense_milliohms = DT_INST_PROP(inst, rsense_milliohms), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, ltc2959_init, NULL, NULL, <c2959_config_##inst, POST_KERNEL, \ + CONFIG_FUEL_GAUGE_INIT_PRIORITY, <c2959_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(LTC2959_DEFINE) diff --git a/drivers/fuel_gauge/ltc2959/ltc2959.h b/drivers/fuel_gauge/ltc2959/ltc2959.h new file mode 100644 index 0000000000000..09b78159d2e90 --- /dev/null +++ b/drivers/fuel_gauge/ltc2959/ltc2959.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Nathan Winslow + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_FUELGAUGE_LTC2959_GAUGE_H_ +#define ZEPHYR_DRIVERS_FUELGAUGE_LTC2959_GAUGE_H_ + +#include +#include + +enum ltc2959_regs { + /* Status and Control */ + LTC2959_REG_STATUS = 0x00, + LTC2959_REG_ADC_CONTROL = 0x01, + LTC2959_REG_CC_CONTROL = 0x02, + + /* Accumulated Charge (uint32_t) */ + LTC2959_REG_ACC_CHARGE_3 = 0x03, + LTC2959_REG_ACC_CHARGE_2 = 0x04, + LTC2959_REG_ACC_CHARGE_1 = 0x05, + LTC2959_REG_ACC_CHARGE_0 = 0x06, + + /* Charge Thresholds (Low and High, uint32_t each) */ + LTC2959_REG_CHG_THRESH_LOW_3 = 0x07, + LTC2959_REG_CHG_THRESH_LOW_2 = 0x08, + LTC2959_REG_CHG_THRESH_LOW_1 = 0x09, + LTC2959_REG_CHG_THRESH_LOW_0 = 0x0A, + LTC2959_REG_CHG_THRESH_HIGH_3 = 0x0B, + LTC2959_REG_CHG_THRESH_HIGH_2 = 0x0C, + LTC2959_REG_CHG_THRESH_HIGH_1 = 0x0D, + LTC2959_REG_CHG_THRESH_HIGH_0 = 0x0E, + + /* Voltage (uint16_t) */ + LTC2959_REG_VOLTAGE_MSB = 0x0F, + LTC2959_REG_VOLTAGE_LSB = 0x10, + LTC2959_REG_VOLT_THRESH_HIGH_MSB = 0x11, + LTC2959_REG_VOLT_THRESH_HIGH_LSB = 0x12, + LTC2959_REG_VOLT_THRESH_LOW_MSB = 0x13, + LTC2959_REG_VOLT_THRESH_LOW_LSB = 0x14, + LTC2959_REG_MAX_VOLTAGE_MSB = 0x15, + LTC2959_REG_MAX_VOLTAGE_LSB = 0x16, + LTC2959_REG_MIN_VOLTAGE_MSB = 0x17, + LTC2959_REG_MIN_VOLTAGE_LSB = 0x18, + + /* Current (int16_t) */ + LTC2959_REG_CURRENT_MSB = 0x19, + LTC2959_REG_CURRENT_LSB = 0x1A, + LTC2959_REG_CURR_THRESH_HIGH_MSB = 0x1B, + LTC2959_REG_CURR_THRESH_HIGH_LSB = 0x1C, + LTC2959_REG_CURR_THRESH_LOW_MSB = 0x1D, + LTC2959_REG_CURR_THRESH_LOW_LSB = 0x1E, + LTC2959_REG_MAX_CURRENT_MSB = 0x1F, + LTC2959_REG_MAX_CURRENT_LSB = 0x20, + LTC2959_REG_MIN_CURRENT_MSB = 0x21, + LTC2959_REG_MIN_CURRENT_LSB = 0x22, + + /* Temperature (uint16_t) */ + LTC2959_REG_TEMP_MSB = 0x23, + LTC2959_REG_TEMP_LSB = 0x24, + LTC2959_REG_TEMP_THRESH_HIGH_MSB = 0x25, + LTC2959_REG_TEMP_THRESH_HIGH_LSB = 0x26, + LTC2959_REG_TEMP_THRESH_LOW_MSB = 0x27, + LTC2959_REG_TEMP_THRESH_LOW_LSB = 0x28, + + /* GPIO */ + LTC2959_REG_GPIO_VOLTAGE_MSB = 0x29, + LTC2959_REG_GPIO_VOLTAGE_LSB = 0x2A, + LTC2959_REG_GPIO_THRESH_HIGH_MSB = 0x2B, + LTC2959_REG_GPIO_THRESH_HIGH_LSB = 0x2C, + LTC2959_REG_GPIO_THRESH_LOW_MSB = 0x2D, + LTC2959_REG_GPIO_THRESH_LOW_LSB = 0x2E, +}; + +#endif /* END ZEPHYR_DRIVERS_FUELGAUGE_LTC2959_GAUGE_H_ */ diff --git a/drivers/gnss/Kconfig.emul b/drivers/gnss/Kconfig.emul index b6667f36864bd..cb3cfdd3e6647 100644 --- a/drivers/gnss/Kconfig.emul +++ b/drivers/gnss/Kconfig.emul @@ -9,3 +9,12 @@ config GNSS_EMUL select TIMEOUT_64BIT help Enable emulated GNSS driver. + +config GNSS_EMUL_MANUAL_UPDATE + bool "Internal state manually updated through gnss_emul_set_data" + depends on GNSS_EMUL + help + The internal state of the GNSS emulator (location, time, etc) + must be updated through gnss_emul_set_data, instead of automatically + transitioning to hardcoded states at hardcoded times. Once the current + time is set, the published time automatically increments. diff --git a/drivers/gnss/gnss_emul.c b/drivers/gnss/gnss_emul.c index ac1761d84c855..5c706c9ce105f 100644 --- a/drivers/gnss/gnss_emul.c +++ b/drivers/gnss/gnss_emul.c @@ -35,10 +35,12 @@ struct gnss_emul_data { struct k_sem lock; int64_t resume_timestamp_ms; int64_t fix_timestamp_ms; + int64_t boot_realtime_ms; uint32_t fix_interval_ms; enum gnss_navigation_mode nav_mode; gnss_systems_t enabled_systems; struct gnss_data data; + bool active; #ifdef CONFIG_GNSS_SATELLITES struct gnss_satellite satellites[GNSS_EMUL_SUPPORTED_SYSTEMS_COUNT]; @@ -73,24 +75,6 @@ static void gnss_emul_update_fix_timestamp(const struct device *dev, bool resumi } } -static bool gnss_emul_fix_is_acquired(const struct device *dev) -{ - struct gnss_emul_data *data = dev->data; - int64_t time_since_resume; - - time_since_resume = data->fix_timestamp_ms - data->resume_timestamp_ms; - return time_since_resume >= GNSS_EMUL_FIX_ACQUIRE_TIME_MS; -} - -#ifdef CONFIG_PM_DEVICE -static void gnss_emul_clear_fix_timestamp(const struct device *dev) -{ - struct gnss_emul_data *data = dev->data; - - data->fix_timestamp_ms = 0; -} -#endif - static void gnss_emul_schedule_work(const struct device *dev) { struct gnss_emul_data *data = dev->data; @@ -110,7 +94,7 @@ static bool gnss_emul_is_resumed(const struct device *dev) { struct gnss_emul_data *data = dev->data; - return data->fix_timestamp_ms > 0; + return data->active; } static void gnss_emul_lock(const struct device *dev) @@ -140,7 +124,7 @@ static int gnss_emul_set_fix_rate(const struct device *dev, uint32_t fix_interva return 0; } -static int gnss_emul_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms) +int gnss_emul_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms) { struct gnss_emul_data *data = dev->data; @@ -161,8 +145,7 @@ static int gnss_emul_set_navigation_mode(const struct device *dev, return 0; } -static int gnss_emul_get_navigation_mode(const struct device *dev, - enum gnss_navigation_mode *mode) +int gnss_emul_get_navigation_mode(const struct device *dev, enum gnss_navigation_mode *mode) { struct gnss_emul_data *data = dev->data; @@ -182,7 +165,7 @@ static int gnss_emul_set_enabled_systems(const struct device *dev, gnss_systems_ return 0; } -static int gnss_emul_get_enabled_systems(const struct device *dev, gnss_systems_t *systems) +int gnss_emul_get_enabled_systems(const struct device *dev, gnss_systems_t *systems) { struct gnss_emul_data *data = dev->data; @@ -190,42 +173,6 @@ static int gnss_emul_get_enabled_systems(const struct device *dev, gnss_systems_ return 0; } -#ifdef CONFIG_PM_DEVICE -static void gnss_emul_resume(const struct device *dev) -{ - gnss_emul_update_fix_timestamp(dev, true); -} - -static void gnss_emul_suspend(const struct device *dev) -{ - gnss_emul_clear_fix_timestamp(dev); -} - -static int gnss_emul_pm_action(const struct device *dev, enum pm_device_action action) -{ - int ret = 0; - - gnss_emul_lock(dev); - - switch (action) { - case PM_DEVICE_ACTION_SUSPEND: - gnss_emul_suspend(dev); - break; - - case PM_DEVICE_ACTION_RESUME: - gnss_emul_resume(dev); - break; - - default: - ret = -ENOTSUP; - break; - } - - gnss_emul_unlock(dev); - return ret; -} -#endif - static int gnss_emul_api_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms) { int ret = -ENODEV; @@ -346,35 +293,26 @@ static DEVICE_API(gnss, api) = { .get_supported_systems = gnss_emul_api_get_supported_systems, }; -static void gnss_emul_clear_data(const struct device *dev) +void gnss_emul_clear_data(const struct device *dev) { struct gnss_emul_data *data = dev->data; memset(&data->data, 0, sizeof(data->data)); } -static void gnss_emul_set_fix(const struct device *dev) -{ - struct gnss_emul_data *data = dev->data; - - data->data.info.satellites_cnt = 8; - data->data.info.hdop = 100; - data->data.info.fix_status = GNSS_FIX_STATUS_GNSS_FIX; - data->data.info.fix_quality = GNSS_FIX_QUALITY_GNSS_SPS; -} - static void gnss_emul_set_utc(const struct device *dev) { struct gnss_emul_data *data = dev->data; + int64_t timestamp_realtime; time_t timestamp; struct tm datetime; uint16_t millisecond; - timestamp = (time_t)(data->fix_timestamp_ms / 1000); + timestamp_realtime = data->boot_realtime_ms + data->fix_timestamp_ms; + timestamp = (time_t)(timestamp_realtime / 1000); gmtime_r(×tamp, &datetime); - millisecond = (uint16_t)(data->fix_timestamp_ms % 1000) - + (uint16_t)(datetime.tm_sec * 1000); + millisecond = (uint16_t)(timestamp_realtime % 1000) + (uint16_t)(datetime.tm_sec * 1000); data->data.utc.hour = datetime.tm_hour; data->data.utc.millisecond = millisecond; @@ -384,6 +322,40 @@ static void gnss_emul_set_utc(const struct device *dev) data->data.utc.century_year = datetime.tm_year % 100; } +#ifdef CONFIG_GNSS_EMUL_MANUAL_UPDATE + +void gnss_emul_set_data(const struct device *dev, const struct navigation_data *nav, + const struct gnss_info *info, int64_t boot_realtime_ms) +{ + struct gnss_emul_data *data = dev->data; + + data->data.nav_data = *nav; + data->data.info = *info; + data->boot_realtime_ms = boot_realtime_ms; + gnss_emul_set_utc(dev); +} + +#else + +static bool gnss_emul_fix_is_acquired(const struct device *dev) +{ + struct gnss_emul_data *data = dev->data; + int64_t time_since_resume; + + time_since_resume = data->fix_timestamp_ms - data->resume_timestamp_ms; + return time_since_resume >= GNSS_EMUL_FIX_ACQUIRE_TIME_MS; +} + +static void gnss_emul_set_fix(const struct device *dev) +{ + struct gnss_emul_data *data = dev->data; + + data->data.info.satellites_cnt = 8; + data->data.info.hdop = 100; + data->data.info.fix_status = GNSS_FIX_STATUS_GNSS_FIX; + data->data.info.fix_quality = GNSS_FIX_QUALITY_GNSS_SPS; +} + static void gnss_emul_set_nav_data(const struct device *dev) { struct gnss_emul_data *data = dev->data; @@ -395,6 +367,8 @@ static void gnss_emul_set_nav_data(const struct device *dev) data->data.nav_data.altitude = 20000; } +#endif /* CONFIG_GNSS_EMUL_MANUAL_UPDATE */ + #ifdef CONFIG_GNSS_SATELLITES static void gnss_emul_clear_satellites(const struct device *dev) { @@ -444,6 +418,11 @@ static void gnss_emul_work_handler(struct k_work *work) struct gnss_emul_data *data = CONTAINER_OF(dwork, struct gnss_emul_data, data_dwork); const struct device *dev = data->dev; +#ifdef CONFIG_GNSS_EMUL_MANUAL_UPDATE + /* Tick the timestamp */ + gnss_emul_set_utc(dev); +#else + /* Automatically update internal state if not done manually */ if (!gnss_emul_fix_is_acquired(dev)) { gnss_emul_clear_data(dev); } else { @@ -451,6 +430,7 @@ static void gnss_emul_work_handler(struct k_work *work) gnss_emul_set_utc(dev); gnss_emul_set_nav_data(dev); } +#endif /* CONFIG_GNSS_EMUL_MANUAL_UPDATE */ gnss_publish_data(dev, &data->data); @@ -463,27 +443,57 @@ static void gnss_emul_work_handler(struct k_work *work) gnss_emul_schedule_work(dev); } -static void gnss_emul_init_data(const struct device *dev) +static void gnss_emul_resume(const struct device *dev) { struct gnss_emul_data *data = dev->data; - data->dev = dev; - k_sem_init(&data->lock, 1, 1); - k_work_init_delayable(&data->data_dwork, gnss_emul_work_handler); + data->active = true; + gnss_emul_update_fix_timestamp(dev, true); + gnss_emul_schedule_work(dev); } -static int gnss_emul_init(const struct device *dev) +static void gnss_emul_suspend(const struct device *dev) { - gnss_emul_init_data(dev); + struct gnss_emul_data *data = dev->data; - if (pm_device_is_powered(dev)) { - gnss_emul_update_fix_timestamp(dev, true); - gnss_emul_schedule_work(dev); - } else { - pm_device_init_off(dev); + data->active = false; + gnss_emul_cancel_work(dev); + gnss_emul_clear_data(dev); +} + +static int gnss_emul_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret = 0; + + gnss_emul_lock(dev); + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + gnss_emul_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + gnss_emul_resume(dev); + break; + + default: + ret = -ENOTSUP; + break; } - return pm_device_runtime_enable(dev); + gnss_emul_unlock(dev); + return ret; +} + +static int gnss_emul_init(const struct device *dev) +{ + struct gnss_emul_data *data = dev->data; + + data->dev = dev; + k_sem_init(&data->lock, 1, 1); + k_work_init_delayable(&data->data_dwork, gnss_emul_work_handler); + + return pm_device_driver_init(dev, gnss_emul_pm_action); } #define GNSS_EMUL_NAME(inst, name) _CONCAT(name, inst) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index a95bed6cbb86d..5f65645bf9691 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -12,9 +12,6 @@ #include #include #include -#ifdef CONFIG_SOC_GECKO_DEV_INIT -#include -#endif #include @@ -391,9 +388,6 @@ DEVICE_DT_DEFINE(DT_INST(0, silabs_gecko_gpio), static int gpio_gecko_common_init(const struct device *dev) { -#ifdef CONFIG_SOC_GECKO_DEV_INIT - CMU_ClockEnable(cmuClock_GPIO, true); -#endif gpio_gecko_common_data.count = 0; IRQ_CONNECT(GPIO_EVEN_IRQn, DT_IRQ_BY_NAME(DT_INST(0, silabs_gecko_gpio), gpio_even, priority), diff --git a/drivers/hwinfo/Kconfig.silabs_series2 b/drivers/hwinfo/Kconfig.silabs_series2 index d898f94afbd87..0d5b7864a6aa3 100644 --- a/drivers/hwinfo/Kconfig.silabs_series2 +++ b/drivers/hwinfo/Kconfig.silabs_series2 @@ -6,6 +6,6 @@ config HWINFO_SILABS_S2 default y depends on SOC_FAMILY_SILABS_S2 select HWINFO_HAS_DRIVER - select SOC_GECKO_RMU + select SILABS_SISDK_RMU help Enable Silabs Series 2 hwinfo driver. diff --git a/drivers/i2c/i2c_cc23x0.c b/drivers/i2c/i2c_cc23x0.c index 50668a9cbfe12..eb2db11ab3a3d 100644 --- a/drivers/i2c/i2c_cc23x0.c +++ b/drivers/i2c/i2c_cc23x0.c @@ -30,6 +30,7 @@ struct i2c_cc23x0_data { struct k_sem lock; struct k_sem complete; volatile uint32_t error; + uint32_t cfg; }; struct i2c_cc23x0_config { @@ -37,6 +38,22 @@ struct i2c_cc23x0_config { const struct pinctrl_dev_config *pcfg; }; +static inline void i2c_cc23x0_pm_policy_state_lock_get(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif +} + +static inline void i2c_cc23x0_pm_policy_state_lock_put(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif +} + static int i2c_cc23x0_transmit(const struct device *dev, const uint8_t *buf, uint32_t len, uint16_t addr) { @@ -53,7 +70,7 @@ static int i2c_cc23x0_transmit(const struct device *dev, const uint8_t *buf, uin /* Single transmission */ if (len == 1) { - I2CControllerPutData(base, *buf); + I2CControllerPutData(base, buf[0]); I2CControllerCommand(base, I2C_CONTROLLER_CMD_SINGLE_SEND); k_sem_take(&data->complete, K_FOREVER); return data->error == I2C_MASTER_ERR_NONE ? 0 : -EIO; @@ -103,18 +120,19 @@ static int i2c_cc23x0_receive(const struct device *dev, uint8_t *buf, uint32_t l if (len == 0) { return -EIO; } - I2CControllerSetTargetAddr(base, addr, true); + I2CControllerSetTargetAddr(base, addr, true); /* Single receive */ if (len == 1) { + buf[0] = I2CControllerGetData(base); I2CControllerCommand(base, I2C_CONTROLLER_CMD_SINGLE_RECEIVE); + k_sem_take(&data->complete, K_FOREVER); if (data->error != I2C_MASTER_ERR_NONE) { return -EIO; } - - *buf = I2CControllerGetData(base); + buf[0] = I2CControllerGetData(base); return 0; } @@ -127,7 +145,6 @@ static int i2c_cc23x0_receive(const struct device *dev, uint8_t *buf, uint32_t l } buf[0] = I2CControllerGetData(base); - for (int i = 1; i < len - 1; i++) { I2CControllerCommand(base, I2C_CONTROLLER_CMD_BURST_RECEIVE_CONT); k_sem_take(&data->complete, K_FOREVER); @@ -159,6 +176,7 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u uint16_t addr) { struct i2c_cc23x0_data *data = dev->data; + const struct i2c_cc23x0_config *config = dev->config; int ret = 0; if (num_msgs == 0) { @@ -167,6 +185,8 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u k_sem_take(&data->lock, K_FOREVER); + i2c_cc23x0_pm_policy_state_lock_get(); + for (int i = 0; i < num_msgs; i++) { /* Not supported by hardware */ if (msgs[i].flags & I2C_MSG_ADDR_10_BITS) { @@ -184,6 +204,13 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u break; } } + + while (I2CControllerBusy(config->base)) { + ; + } + + i2c_cc23x0_pm_policy_state_lock_put(); + k_sem_give(&data->lock); return ret; @@ -227,6 +254,33 @@ static int i2c_cc23x0_configure(const struct device *dev, uint32_t dev_config) return 0; } +#ifdef CONFIG_PM_DEVICE + +static int i2c_cc23x0_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct i2c_cc23x0_config *config = dev->config; + struct i2c_cc23x0_data *data = dev->data; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + I2CControllerDisable(config->base); + I2CControllerDisableInt(config->base); + CLKCTLDisable(CLKCTL_BASE, CLKCTL_I2C0); + break; + case PM_DEVICE_ACTION_RESUME: + CLKCTLEnable(CLKCTL_BASE, CLKCTL_I2C0); + i2c_cc23x0_configure(dev, data->cfg | I2C_MODE_CONTROLLER); + I2CControllerEnableInt(config->base); + break; + default: + return -ENOTSUP; + } + + return 0; +} + +#endif /* CONFIG_PM_DEVICE */ + static void i2c_cc23x0_isr(const struct device *dev) { const struct i2c_cc23x0_config *config = dev->config; @@ -237,8 +291,12 @@ static void i2c_cc23x0_isr(const struct device *dev) I2CControllerClearInt(base); data->error = I2CControllerError(base); - - k_sem_give(&data->complete); + if (data->error) { + LOG_ERR("Error [%x]", data->error); + } + if (!I2CControllerBusy(config->base)) { + k_sem_give(&data->complete); + } } } @@ -290,8 +348,8 @@ static const struct i2c_driver_api i2c_cc23x0_driver_api = {.configure = i2c_cc2 .complete = Z_SEM_INITIALIZER(i2c_cc23x0_##id##_data.complete, 0, 1), \ .error = I2C_MASTER_ERR_NONE}; \ \ - I2C_DEVICE_DT_INST_DEFINE(id, i2c_cc23x0_init##id, NULL, &i2c_cc23x0_##id##_data, \ - &i2c_cc23x0_##id##_config, POST_KERNEL, \ + I2C_DEVICE_DT_INST_DEFINE(id, i2c_cc23x0_init##id, PM_DEVICE_DT_INST_GET(id), \ + &i2c_cc23x0_##id##_data, &i2c_cc23x0_##id##_config, POST_KERNEL, \ CONFIG_I2C_INIT_PRIORITY, &i2c_cc23x0_driver_api); DT_INST_FOREACH_STATUS_OKAY(CC23X0_I2C); diff --git a/drivers/i2s/Kconfig.stm32 b/drivers/i2s/Kconfig.stm32 index 697aee3b08462..68961d873f491 100644 --- a/drivers/i2s/Kconfig.stm32 +++ b/drivers/i2s/Kconfig.stm32 @@ -35,6 +35,7 @@ menuconfig I2S_STM32_SAI select USE_STM32_HAL_DMA select USE_STM32_HAL_DMA_EX select USE_STM32_HAL_SAI + select USE_STM32_HAL_SAI_EX if SOC_SERIES_STM32F4X help Enable SAI support on the STM32 family of processors. diff --git a/drivers/i2s/i2s_stm32_sai.c b/drivers/i2s/i2s_stm32_sai.c index e80fdd41dc425..9a5ee27d10d3b 100644 --- a/drivers/i2s/i2s_stm32_sai.c +++ b/drivers/i2s/i2s_stm32_sai.c @@ -283,11 +283,17 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) } hdma->Instance = STM32_DMA_GET_INSTANCE(stream->reg, stream->dma_channel); +#if defined(CONFIG_SOC_SERIES_STM32F4X) + hdma->Init.Channel = dma_cfg.dma_slot * DMA_CHANNEL_1; +#else hdma->Init.Request = dma_cfg.dma_slot; +#endif hdma->Init.Mode = DMA_NORMAL; #if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32L4X) || \ - defined(CONFIG_SOC_SERIES_STM32G4X) || defined(CONFIG_SOC_SERIES_STM32L5X) + defined(CONFIG_SOC_SERIES_STM32G4X) || defined(CONFIG_SOC_SERIES_STM32L5X) || \ + defined(CONFIG_SOC_SERIES_STM32F4X) + hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma->Init.Priority = DMA_PRIORITY_HIGH; @@ -304,7 +310,7 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; #endif -#if defined(CONFIG_SOC_SERIES_STM32H7X) +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32F4X) hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; #endif @@ -312,7 +318,8 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; #if !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) && \ - !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) + !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) && \ + !defined(CONFIG_SOC_SERIES_STM32F4X) hdma->Init.SrcInc = DMA_SINC_INCREMENTED; hdma->Init.DestInc = DMA_DINC_FIXED; #endif @@ -322,7 +329,8 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; #if !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) && \ - !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) + !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) && \ + !defined(CONFIG_SOC_SERIES_STM32F4X) hdma->Init.SrcInc = DMA_SINC_FIXED; hdma->Init.DestInc = DMA_DINC_INCREMENTED; #endif @@ -342,7 +350,8 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) return -EIO; } #elif !defined(CONFIG_SOC_SERIES_STM32H7X) && !defined(CONFIG_SOC_SERIES_STM32L4X) && \ - !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) + !defined(CONFIG_SOC_SERIES_STM32G4X) && !defined(CONFIG_SOC_SERIES_STM32L5X) && \ + !defined(CONFIG_SOC_SERIES_STM32F4X) if (HAL_DMA_ConfigChannelAttributes(&dev_data->hdma, DMA_CHANNEL_NPRIV) != HAL_OK) { LOG_ERR("HAL_DMA_ConfigChannelAttributes: "); return -EIO; @@ -458,7 +467,7 @@ static int i2s_stm32_sai_configure(const struct device *dev, enum i2s_dir dir, } /* Control of MCLK output from SAI configuration is not possible on STM32L4xx MCUs */ -#if !defined(CONFIG_SOC_SERIES_STM32L4X) +#if !defined(CONFIG_SOC_SERIES_STM32L4X) && !defined(CONFIG_SOC_SERIES_STM32F4X) if (cfg->mclk_enable && stream->master) { hsai->Init.MckOutput = SAI_MCK_OUTPUT_ENABLE; } else { @@ -472,7 +481,7 @@ static int i2s_stm32_sai_configure(const struct device *dev, enum i2s_dir dir, hsai->Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; /* MckOverSampling is not supported by all STM32L4xx MCUs */ -#if !defined(CONFIG_SOC_SERIES_STM32L4X) +#if !defined(CONFIG_SOC_SERIES_STM32L4X) && !defined(CONFIG_SOC_SERIES_STM32F4X) if (cfg->mclk_div == (enum mclk_divider)MCLK_DIV_256) { hsai->Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE; } else { diff --git a/drivers/input/input_analog_axis.c b/drivers/input/input_analog_axis.c index f58d4b77a4025..7a6879c01b313 100644 --- a/drivers/input/input_analog_axis.c +++ b/drivers/input/input_analog_axis.c @@ -204,7 +204,7 @@ static void analog_axis_loop(const struct device *dev) out = analog_axis_out_linear(dev, i, raw_val); } - out = CLAMP(out, axis_cfg->out_min, axis_cfg->out_max); + out = clamp(out, axis_cfg->out_min, axis_cfg->out_max); if (axis_cfg->invert_output) { out = axis_cfg->out_max - out; diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 747749a958b94..7cd8badef3bba 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -309,7 +309,7 @@ static void input_kbd_matrix_poll(const struct device *dev) } else { poll_period_us = cfg->stable_poll_period_us; } - wait_period_us = CLAMP(poll_period_us - k_cyc_to_us_floor32(cycles_diff), + wait_period_us = clamp(poll_period_us - k_cyc_to_us_floor32(cycles_diff), USEC_PER_MSEC, poll_period_us); LOG_DBG("wait_period_us: %d", wait_period_us); diff --git a/drivers/input/input_stmpe811.c b/drivers/input/input_stmpe811.c index b2f95cb5066ce..8c5521dc40c6b 100644 --- a/drivers/input/input_stmpe811.c +++ b/drivers/input/input_stmpe811.c @@ -344,8 +344,8 @@ static void stmpe811_report_touch(const struct device *dev) y = (((int)data->touch_y - config->raw_y_min) * common->screen_height) / (config->raw_y_max - config->raw_y_min); - x = CLAMP(x, 0, common->screen_width); - y = CLAMP(y, 0, common->screen_height); + x = clamp(x, 0, common->screen_width); + y = clamp(y, 0, common->screen_height); } input_touchscreen_report_pos(dev, x, y, K_FOREVER); diff --git a/drivers/interrupt_controller/Kconfig.nxp_siul2 b/drivers/interrupt_controller/Kconfig.nxp_siul2 index ba439cd5d60cf..ae2c64f261c51 100644 --- a/drivers/interrupt_controller/Kconfig.nxp_siul2 +++ b/drivers/interrupt_controller/Kconfig.nxp_siul2 @@ -15,7 +15,7 @@ if NXP_SIUL2_EIRQ config NXP_SIUL2_EIRQ_EXT_INTERRUPTS_MAX int default 8 if SOC_SERIES_S32ZE - default 32 if SOC_SERIES_S32K3 + default 32 if SOC_SERIES_S32K3 || SOC_SERIES_MCXE31X help Number of SIUL2 external interrupts per controller. This is a SoC integration option. diff --git a/drivers/interrupt_controller/intc_nxp_siul2_eirq.c b/drivers/interrupt_controller/intc_nxp_siul2_eirq.c index 27cc145e877b0..8668925d9beef 100644 --- a/drivers/interrupt_controller/intc_nxp_siul2_eirq.c +++ b/drivers/interrupt_controller/intc_nxp_siul2_eirq.c @@ -28,13 +28,20 @@ #define SIUL2_IFER0 0x28 /* SIUL2 Interrupt Filter Maximum Counter Register */ #define SIUL2_IFMCR(n) (0x30 + 0x4 * (n)) +#ifndef SIUL2_IFMCR_MAXCNT_MASK #define SIUL2_IFMCR_MAXCNT_MASK GENMASK(3, 0) +#endif +#ifndef SIUL2_IFMCR_MAXCNT #define SIUL2_IFMCR_MAXCNT(v) FIELD_PREP(SIUL2_IFMCR_MAXCNT_MASK, (v)) +#endif /* SIUL2 Interrupt Filter Clock Prescaler Register */ #define SIUL2_IFCPR 0xb0 +#ifndef SIUL2_IFCPR_IFCP_MASK #define SIUL2_IFCPR_IFCP_MASK GENMASK(3, 0) +#endif +#ifndef SIUL2_IFCPR_IFCP #define SIUL2_IFCPR_IFCP(v) FIELD_PREP(SIUL2_IFCPR_IFCP_MASK, (v)) - +#endif /* Handy accessors */ #define REG_READ(r) sys_read32(config->base + (r)) #define REG_WRITE(r, v) sys_write32((v), config->base + (r)) diff --git a/drivers/misc/ethos_u/CMakeLists.txt b/drivers/misc/ethos_u/CMakeLists.txt index 975fbc8deb77b..3ec600b5ada3f 100644 --- a/drivers/misc/ethos_u/CMakeLists.txt +++ b/drivers/misc/ethos_u/CMakeLists.txt @@ -6,3 +6,4 @@ zephyr_library() zephyr_library_sources(ethos_u_common.c) zephyr_library_sources_ifdef(CONFIG_ETHOS_U_ARM ethos_u_arm.c) zephyr_library_sources_ifdef(CONFIG_ETHOS_U_NUMAKER ethos_u_numaker.c) +zephyr_library_sources_ifdef(CONFIG_ETHOS_U_RENESAS ethos_u_renesas.c) diff --git a/drivers/misc/ethos_u/Kconfig b/drivers/misc/ethos_u/Kconfig index 24aacb0b81817..eb65ba5d3eb71 100644 --- a/drivers/misc/ethos_u/Kconfig +++ b/drivers/misc/ethos_u/Kconfig @@ -6,6 +6,7 @@ choice depends on ETHOS_U default ETHOS_U_ARM if DT_HAS_ARM_ETHOS_U_ENABLED default ETHOS_U_NUMAKER if DT_HAS_NUVOTON_NUMAKER_NPU_ENABLED + default ETHOS_U_RENESAS if DT_HAS_RENESAS_RA_NPU_ENABLED config ETHOS_U_ARM bool "Arm Ethos-U NPU driver" @@ -17,6 +18,11 @@ config ETHOS_U_NUMAKER help Enables Nuvoton NuMaker frontend of Arm Ethos-U NPU driver +config ETHOS_U_RENESAS + bool "Renesas RA Ethos-U NPU driver" + help + Enables Renesas RA frontend of Arm Ethos-U NPU driver. + endchoice config ETHOS_U_DCACHE diff --git a/drivers/misc/ethos_u/ethos_u_renesas.c b/drivers/misc/ethos_u/ethos_u_renesas.c new file mode 100644 index 0000000000000..c57efc4280e4a --- /dev/null +++ b/drivers/misc/ethos_u/ethos_u_renesas.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ethos_u_common.h" + +#define DT_DRV_COMPAT renesas_ra_npu +LOG_MODULE_REGISTER(renesas_ra_npu, CONFIG_ETHOS_U_LOG_LEVEL); + +struct ethos_u_renesas_config { + const struct ethosu_dts_info ethosu_dts_info; + const struct device *clock_dev; + const struct clock_control_ra_subsys_cfg clock_subsys; +}; + +void ethos_u_renesas_ra_irq_handler(const struct device *dev) +{ + struct ethosu_data *data = dev->data; + struct ethosu_driver *drv = &data->drv; + IRQn_Type irq = R_FSP_CurrentIrqGet(); + + ethosu_irq_handler(drv); + + R_BSP_IrqStatusClear(irq); +} + +static int ethos_u_renesas_ra_init(const struct device *dev) +{ + const struct ethos_u_renesas_config *config = dev->config; + const struct ethosu_dts_info ethosu_dts_info = config->ethosu_dts_info; + struct ethosu_data *data = dev->data; + struct ethosu_driver *drv = &data->drv; + struct ethosu_driver_version version; + int err; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_subsys); + if (err < 0) { + LOG_ERR("Could not initialize clock (%d)", err); + 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); + + ethosu_get_driver_version(&version); + + LOG_DBG("Version. major=%u, minor=%u, patch=%u", version.major, version.minor, + version.patch); + + if (ethosu_init(drv, ethosu_dts_info.base_addr, NULL, 0, ethosu_dts_info.secure_enable, + ethosu_dts_info.privilege_enable)) { + LOG_ERR("Failed to initialize NPU with ethosu_init()."); + return -EINVAL; + } + + ethosu_dts_info.irq_config(); + + return 0; +} + +#define ETHOSU_RENESAS_RA_DEVICE_INIT(idx) \ + static struct ethosu_data ethosu_data_##idx; \ + \ + static void ethosu_zephyr_irq_config_##idx(void) \ + { \ + R_ICU->IELSR_b[DT_INST_IRQ_BY_NAME(idx, npu_irq, irq)].IELS = \ + BSP_PRV_IELS_ENUM(EVENT_NPU_IRQ); \ + \ + BSP_ASSIGN_EVENT_TO_CURRENT_CORE(BSP_PRV_IELS_ENUM(EVENT_NPU_IRQ)); \ + \ + IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), \ + ethos_u_renesas_ra_irq_handler, DEVICE_DT_INST_GET(idx), 0); \ + \ + irq_enable(DT_INST_IRQN(idx)); \ + } \ + \ + static const struct ethos_u_renesas_config ethos_u_renesas_config##idx = { \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_subsys = \ + { \ + .mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(idx, 0, mstp), \ + .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(idx, 0, stop_bit), \ + }, \ + .ethosu_dts_info = \ + { \ + .base_addr = (void *)DT_INST_REG_ADDR(idx), \ + .secure_enable = DT_INST_PROP(idx, secure_enable), \ + .privilege_enable = DT_INST_PROP(idx, privilege_enable), \ + .irq_config = ðosu_zephyr_irq_config_##idx, \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, ethos_u_renesas_ra_init, NULL, ðosu_data_##idx, \ + ðos_u_renesas_config##idx, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + +DT_INST_FOREACH_STATUS_OKAY(ETHOSU_RENESAS_RA_DEVICE_INIT); diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index cc746ff9770e5..2d5a97ec76437 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -40,6 +40,15 @@ config MODEM_CELLULAR if MODEM_CELLULAR +config MODEM_CELLULAR_INIT_PRIORITY + int "Cellular modem driver initialization priority" + default 79 + range 0 99 + help + Driver initialization priority for cellular modem drivers. + Defaults to less than GNSS_INIT_PRIORITY, as LTE modems often + integrate a GNSS modem. + config MODEM_CELLULAR_APN string "Static APN" default "internet" diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 31c28533bf3f9..c09c9a12795ad 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1391,11 +1391,15 @@ static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data * { const struct modem_cellular_config *config = (const struct modem_cellular_config *)data->dev->config; + struct cellular_evt_modem_comms_check_result result; switch (evt) { case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + result.success = evt == MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS; + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + modem_cellular_emit_event(data, CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT, &result); break; case MODEM_CELLULAR_EVENT_TIMEOUT: @@ -3005,8 +3009,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, \ DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \ &MODEM_CELLULAR_INST_NAME(data, inst), \ - &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ - &modem_cellular_api); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, \ + CONFIG_MODEM_CELLULAR_INIT_PRIORITY, &modem_cellular_api); #define MODEM_CELLULAR_DEVICE_QUECTEL_BG9X(inst) \ MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ diff --git a/drivers/peci/peci_npcx.c b/drivers/peci/peci_npcx.c index 24e3f1d4bac60..9a0518a6c21e1 100644 --- a/drivers/peci/peci_npcx.c +++ b/drivers/peci/peci_npcx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,12 @@ static int peci_npcx_transfer(const struct device *dev, struct peci_msg *msg) enum peci_command_code cmd_code = msg->cmd_code; int ret = 0; + /* + * suspend-to-idle stops PECI module clocks (derived from APB2), which + * must remain active during a transaction + */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + k_sem_take(&data->lock, K_FOREVER); if (peci_tx_buf->len > PECI_NPCX_MAX_TX_BUF_LEN || @@ -194,6 +201,7 @@ static int peci_npcx_transfer(const struct device *dev, struct peci_msg *msg) out: k_sem_give(&data->lock); + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); return ret; } diff --git a/drivers/pinctrl/Kconfig.nxp_siul2 b/drivers/pinctrl/Kconfig.nxp_siul2 index e60391fa8445a..1650f9d386853 100644 --- a/drivers/pinctrl/Kconfig.nxp_siul2 +++ b/drivers/pinctrl/Kconfig.nxp_siul2 @@ -4,6 +4,7 @@ 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 + depends on DT_HAS_NXP_S32ZE_SIUL2_PINCTRL_ENABLED || DT_HAS_NXP_S32K3_SIUL2_PINCTRL_ENABLED || \ + DT_HAS_NXP_MCXE31X_SIUL2_PINCTRL_ENABLED help Enable pin controller driver for NXP SIUL2. diff --git a/drivers/ps2/ps2_npcx_controller.c b/drivers/ps2/ps2_npcx_controller.c index e121ff5e3688f..358708b972bfa 100644 --- a/drivers/ps2/ps2_npcx_controller.c +++ b/drivers/ps2/ps2_npcx_controller.c @@ -252,7 +252,11 @@ static void ps2_npcx_ctrl_isr(const struct device *dev) * ACH = 5 : Channel 3 */ active_ch = GET_FIELD(inst->PSTAT, NPCX_PSTAT_ACH); +#if defined(CONFIG_NPCX_SOC_VARIANT_NPCKN) + active_ch = active_ch > 2 ? (active_ch - 1) : active_ch; +#else active_ch = active_ch > 2 ? (active_ch - 2) : (active_ch - 1); +#endif LOG_DBG("ACH: %d\n", active_ch); /* diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index c976a24b44c44..3497f51688ec4 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -46,6 +46,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_BBLED_XEC pwm_mchp_xec_bbled.c) zephyr_library_sources_ifdef(CONFIG_PWM_INTEL_BLINKY pwm_intel_blinky.c) zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU4 pwm_xmc4xxx_ccu4.c) zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU8 pwm_xmc4xxx_ccu8.c) +zephyr_library_sources_ifdef(CONFIG_PWM_MCHP_G1_TCC pwm_mchp_tcc_g1.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_CTIMER pwm_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_MSPM0 pwm_mspm0.c) zephyr_library_sources_ifdef(CONFIG_PWM_NUMAKER pwm_numaker.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index f0db0f8b10c16..3b9911b2de94e 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -110,6 +110,8 @@ source "drivers/pwm/Kconfig.xmc4xxx_ccu4" source "drivers/pwm/Kconfig.xmc4xxx_ccu8" +source "drivers/pwm/Kconfig.mchp" + source "drivers/pwm/Kconfig.mcux_ctimer" source "drivers/pwm/Kconfig.mspm0" diff --git a/drivers/pwm/Kconfig.mchp b/drivers/pwm/Kconfig.mchp new file mode 100644 index 0000000000000..d468b0ee49b5e --- /dev/null +++ b/drivers/pwm/Kconfig.mchp @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +menu "Microchip PWM Drivers" + +config PWM_MCHP_G1_TCC + bool "Microchip TCC G1 PWM driver" + default y + depends on DT_HAS_MICROCHIP_TCC_G1_PWM_ENABLED + select PINCTRL + help + Enable the Microchip Pulse Width Modulation(PWM) driver. + +endmenu diff --git a/drivers/pwm/Kconfig.mcux_qtmr b/drivers/pwm/Kconfig.mcux_qtmr index 150473ddae89c..d091d63a0b4e8 100644 --- a/drivers/pwm/Kconfig.mcux_qtmr +++ b/drivers/pwm/Kconfig.mcux_qtmr @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 config PWM_MCUX_QTMR @@ -9,3 +9,23 @@ config PWM_MCUX_QTMR select PINCTRL help Enable QTMR based pwm driver. + +config PWM_CAPTURE_MCUX_QTMR_FILTER_PERIOD + int "MCUX QMTR PWM Input Filter Sample Period" + depends on PWM_MCUX_QTMR && PWM_CAPTURE + range 0 255 + default 0 + help + Indicates the sampling period (in IP bus clock cycles) of + the TMR input signals. If the value is 0x00 (default), then + the input filter is bypassed. + +config PWM_CAPTURE_MCUX_QTMR_FILTER_COUNT + int "MCUX QMTR PWM Input Filter Sample Count" + depends on PWM_MCUX_QTMR && PWM_CAPTURE + range 0 7 + default 0 + help + Indicates the number of consecutive samples that must agree prior to the + input filter accepting an input transition. The real number of samples is + (value +3). For example, a value of 0x0 indicates 3 samples. diff --git a/drivers/pwm/pwm_cc23x0_timer.c b/drivers/pwm/pwm_cc23x0_timer.c index b74975d921e2b..d0a3f97caa399 100644 --- a/drivers/pwm/pwm_cc23x0_timer.c +++ b/drivers/pwm/pwm_cc23x0_timer.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include @@ -34,6 +36,22 @@ struct pwm_cc23x0_config { const struct pinctrl_dev_config *pcfg; }; +static inline void pwm_cc23x0_pm_policy_state_lock_get(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif +} + +static inline void pwm_cc23x0_pm_policy_state_lock_put(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); +#endif +} + static int pwm_cc23x0_set_cycles(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, pwm_flags_t flags) { @@ -41,6 +59,10 @@ static int pwm_cc23x0_set_cycles(const struct device *dev, uint32_t channel, uin LOG_DBG("set cycles period[%x] pulse[%x]", period, pulse); + if (pulse == 0) { + pwm_cc23x0_pm_policy_state_lock_get(); + } + if ((config->base != LGPT3_BASE) && (pulse > 0xffff || period > 0xffff || pulse > period)) { /* LGPT0, LGPT1, LGPT2 - 16bit counters */ LOG_ERR("Period of pulse out of range"); @@ -72,6 +94,10 @@ static int pwm_cc23x0_set_cycles(const struct device *dev, uint32_t channel, uin /* Activate LGPT */ HWREG(config->base + LGPT_O_STARTCFG) = 0x1; + if (pulse > 0) { + pwm_cc23x0_pm_policy_state_lock_put(); + } + return 0; } @@ -90,7 +116,7 @@ static const struct pwm_driver_api pwm_cc23x0_driver_api = { .get_cycles_per_sec = pwm_cc23x0_get_cycles_per_sec, }; -static int pwm_cc23x0_activate_clock(const struct device *dev) +static int pwm_cc23x0_clock_action(const struct device *dev, bool activate) { const struct pwm_cc23x0_config *config = dev->config; struct pwm_cc23x0_data *data = dev->data; @@ -113,13 +139,35 @@ static int pwm_cc23x0_activate_clock(const struct device *dev) return -EINVAL; } - CLKCTLEnable(CLKCTL_BASE, lgpt_clk_id); - HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(data->prescale); - HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0; + if (activate) { + CLKCTLEnable(CLKCTL_BASE, lgpt_clk_id); + HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(data->prescale); + HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0; + } else { + CLKCTLDisable(CLKCTL_BASE, lgpt_clk_id); + } return 0; } +#ifdef CONFIG_PM_DEVICE + +static int pwm_cc23x0_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + pwm_cc23x0_clock_action(dev, false); + return 0; + case PM_DEVICE_ACTION_RESUME: + pwm_cc23x0_clock_action(dev, true); + return 0; + default: + return -ENOTSUP; + } +} + +#endif /* CONFIG_PM_DEVICE */ + #define DT_TIMER(idx) DT_INST_PARENT(idx) #define DT_TIMER_BASE_ADDR(idx) (DT_REG_ADDR(DT_TIMER(idx))) @@ -137,12 +185,13 @@ static int pwm_cc23x0_init(const struct device *dev) return ret; } - pwm_cc23x0_activate_clock(dev); + pwm_cc23x0_clock_action(dev, true); return 0; } #define PWM_DEVICE_INIT(idx) \ + PM_DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_pm_action); \ PINCTRL_DT_INST_DEFINE(idx); \ LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_PWM_LOG_LEVEL); \ \ @@ -156,7 +205,7 @@ static int pwm_cc23x0_init(const struct device *dev) .base_clk = DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency), \ }; \ \ - DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_init, NULL, &pwm_cc23x0_##idx##_data, \ + DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_init, NULL, &pwm_cc23x0_##idx##_data, \ &pwm_cc23x0_##idx##_config, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ &pwm_cc23x0_driver_api) diff --git a/drivers/pwm/pwm_mchp_tcc_g1.c b/drivers/pwm/pwm_mchp_tcc_g1.c new file mode 100644 index 0000000000000..ee6d9d05b1f2c --- /dev/null +++ b/drivers/pwm/pwm_mchp_tcc_g1.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file pwm_mchp_tcc_g1.c + * @brief PWM driver for Microchip tcc g1 peripheral. + * + * This file provides the implementation of pwm functions + * for Microchip tcc g1 Peripheral. + */ + +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + * @brief Devicetree definitions + *****************************************************************************/ +#define DT_DRV_COMPAT microchip_tcc_g1_pwm + +/******************************************* + * Const and Macro Defines + *******************************************/ + +LOG_MODULE_REGISTER(pwm_mchp_tcc_g1, CONFIG_PWM_LOG_LEVEL); + +#define PWM_REG(addr) ((tcc_registers_t *)addr) + +#define MCHP_PWM_SUCCESS 0 + +/** + * @brief Timeout duration for acquiring the PWM lock. + * + * This macro defines the timeout duration for acquiring the PWM lock. + * The timeout is specified in milliseconds. + */ +#define MCHP_PWM_LOCK_TIMEOUT K_MSEC(10) + +/** + * @brief Initialize the PWM lock. + * + * This macro initializes the PWM lock. + * + * @param p_lock Pointer to the lock to be initialized. + */ +#define MCHP_PWM_DATA_LOCK_INIT(p_lock) k_mutex_init(p_lock) + +/** + * @brief Acquire the PWM lock. + * + * This macro acquires the PWM lock. If the lock is not available, the + * function will wait for the specified timeout duration. + * + * @param p_lock Pointer to the lock to be acquired. + * @return 0 if the lock was successfully acquired, or a negative error code. + */ +#define MCHP_PWM_DATA_LOCK(p_lock) k_mutex_lock(p_lock, MCHP_PWM_LOCK_TIMEOUT) + +/** + * @brief Release the PWM lock. + * + * This macro releases the PWM lock. + * + * @param p_lock Pointer to the lock to be released. + * @return 0 if the lock was successfully released, or a negative error code. + */ +#define MCHP_PWM_DATA_UNLOCK(p_lock) k_mutex_unlock(p_lock) + +/* Timeout values for WAIT_FOR macro */ +#define TIMEOUT_VALUE_US 1000 +#define DELAY_US 2 + +/*********************************** + * Typedefs and Enum Declarations + **********************************/ +typedef enum { + 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 +} pwm_prescale_modes_t; + +/** + * @brief Structure for managing flags for the pwm. + */ +typedef enum { + PWM_MCHP_FLAGS_CAPTURE_TYPE_PERIOD, + PWM_MCHP_FLAGS_CAPTURE_TYPE_PULSE, + PWM_MCHP_FLAGS_CAPTURE_TYPE_BOTH, + PWM_MCHP_FLAGS_CAPTURE_MODE_SINGLE, + PWM_MCHP_FLAGS_CAPTURE_MODE_CONTINUOUS, +} pwm_mchp_flags_t; + +/** + * @brief Structure to hold PWM data specific to Microchip hardware. + */ +typedef struct { + struct k_mutex lock; /* Lock type for PWM configuration */ +} pwm_mchp_data_t; + +typedef struct mchp_counter_clock { + /* Clock driver */ + const struct device *clock_dev; + + /* Main clock subsystem. */ + clock_control_subsys_t host_core_sync_clk; + /* Generic clock subsystem. */ + clock_control_subsys_t periph_async_clk; +} pwm_mchp_clock_t; + +/** + * @brief Structure to hold the configuration for Microchip PWM. + */ +typedef struct { + pwm_mchp_clock_t pwm_clock; /* PWM clock configuration */ + const struct pinctrl_dev_config *pinctrl_config; /* Pin control configuration */ + void *regs; /* Pointer to PWM peripheral registers */ + uint32_t max_bit_width; /* Used for finding out the resolution of the pwm peripheral */ + uint16_t prescaler; /* Prescaler value for PWM */ + uint8_t channels; /* Number of PWM channels */ + uint32_t freq; /* Frequency of the PWM signal */ +} pwm_mchp_config_t; + +/*********************************** + * Internal functions + ***********************************/ + +/** + *Get the prescale value based on the given prescaler. + */ +static uint32_t tcc_get_prescale_val(uint32_t prescaler) +{ + uint32_t prescaler_val = 0; + + switch (prescaler) { + case PWM_PRESCALE_1: + prescaler_val = TCC_CTRLA_PRESCALER_DIV1; + break; + case PWM_PRESCALE_2: + prescaler_val = TCC_CTRLA_PRESCALER_DIV2; + break; + case PWM_PRESCALE_4: + prescaler_val = TCC_CTRLA_PRESCALER_DIV4; + break; + case PWM_PRESCALE_8: + prescaler_val = TCC_CTRLA_PRESCALER_DIV8; + break; + case PWM_PRESCALE_16: + prescaler_val = TCC_CTRLA_PRESCALER_DIV16; + break; + case PWM_PRESCALE_64: + prescaler_val = TCC_CTRLA_PRESCALER_DIV64; + break; + case PWM_PRESCALE_256: + prescaler_val = TCC_CTRLA_PRESCALER_DIV256; + break; + case PWM_PRESCALE_1024: + prescaler_val = TCC_CTRLA_PRESCALER_DIV1024; + break; + default: + prescaler_val = TCC_CTRLA_PRESCALER_DIV1; /* Default fallback */ + LOG_ERR("Unsupported prescaler specified in dts. Initialising with default " + "prescaler of DIV1"); + + break; + } + + return prescaler_val; +} + +/** + *Enable or disable the PWM instance. + */ +static inline void tcc_enable(void *pwm_reg, bool enable) +{ + + if (enable != 0) { + PWM_REG(pwm_reg)->TCC_CTRLA |= TCC_CTRLA_ENABLE(1); + } else { + PWM_REG(pwm_reg)->TCC_CTRLA &= ~TCC_CTRLA_ENABLE(1); + } + LOG_DBG("%s %d invoked", __func__, enable); +} + +/** + *Wait for the PWM instance to complete synchronization. + */ +static inline void tcc_sync_wait(void *pwm_reg) +{ + + if (!WAIT_FOR(((PWM_REG(pwm_reg)->TCC_SYNCBUSY) != 0), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US))) { + LOG_ERR("TCC_SYNCBUSY wait timed out"); + } + LOG_DBG("%s invoked", __func__); +} + +/** + *Set the output inversion for a specific PWM channel. + */ +static int32_t tcc_set_invert(void *pwm_reg, uint32_t channel) +{ + uint32_t invert_mask = 1 << (channel + TCC_DRVCTRL_INVEN0_Pos); + + tcc_enable(pwm_reg, false); + tcc_sync_wait(pwm_reg); + PWM_REG(pwm_reg)->TCC_DRVCTRL |= invert_mask; + tcc_enable(pwm_reg, true); + tcc_sync_wait(pwm_reg); + LOG_DBG("tcc set invert 0x%x invoked", invert_mask); + + return MCHP_PWM_SUCCESS; +} + +/** + *Initialize the PWM instance with the specified prescaler. + */ +void tcc_init(void *pwm_reg, uint32_t prescaler) +{ + prescaler = tcc_get_prescale_val(prescaler); + PWM_REG(pwm_reg)->TCC_CTRLA = TCC_CTRLA_SWRST(1); + tcc_sync_wait(pwm_reg); + PWM_REG(pwm_reg)->TCC_CTRLA |= prescaler; + PWM_REG(pwm_reg)->TCC_WAVE = TCC_WAVE_WAVEGEN_NPWM; + PWM_REG(pwm_reg)->TCC_PER = TCC_PER_PER(0); + tcc_enable(pwm_reg, true); +} + +/** + *Get the output inversion status for a specific PWM channel. + */ +static inline bool tcc_get_invert_status(void *pwm_reg, uint32_t channel) +{ + uint32_t invert_status = 0; + uint32_t invert_mask = 1 << (channel + TCC_DRVCTRL_INVEN0_Pos); + + LOG_DBG("tcc get invert status 0x%x invoked", invert_mask); + invert_status = PWM_REG(pwm_reg)->TCC_DRVCTRL & invert_mask; + + return (invert_status == 0) ? true : false; +} + +/*********************************** + * Zephyr APIs + **********************************/ +/** + * @brief Set the PWM cycles for a specific channel. + * + * This function sets the PWM period and pulse width for a specified channel. It also handles the + * polarity inversion if required. + * + * @param pwm_dev Pointer to the PWM device structure. + * @param channel PWM channel number. + * @param period PWM period in cycles. + * @param pulse PWM pulse width in cycles. + * @param flags PWM flags (e.g., polarity inversion). + * + * @return 0 on success, -EINVAL if the channel is invalid or the period/pulse is out of range. + */ +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 pwm_mchp_config_t *const mchp_pwm_cfg = pwm_dev->config; + pwm_mchp_data_t *mchp_pwm_data = pwm_dev->data; + int ret_val = -EINVAL; + uint32_t top = (BIT(mchp_pwm_cfg->max_bit_width) - 1); + + MCHP_PWM_DATA_LOCK(&mchp_pwm_data->lock); + + if (channel >= mchp_pwm_cfg->channels) { + LOG_ERR("channel %d is invalid", channel); + } else if ((period > top) || (pulse > top)) { + LOG_ERR("period or pulse is out of range"); + } else { + + bool invert_flag_set = ((flags & PWM_POLARITY_INVERTED) != 0); + bool not_inverted = tcc_get_invert_status(mchp_pwm_cfg->regs, channel); + + if ((invert_flag_set == true) && (not_inverted == true)) { + tcc_set_invert(mchp_pwm_cfg->regs, channel); + } + + PWM_REG(mchp_pwm_cfg->regs)->TCC_CCBUF[channel] = TCC_CCBUF_CCBUF(pulse); + PWM_REG(mchp_pwm_cfg->regs)->TCC_PER = TCC_PER_PER(period); + ret_val = MCHP_PWM_SUCCESS; + } + + MCHP_PWM_DATA_UNLOCK(&mchp_pwm_data->lock); + + return ret_val; +} + +/** + * @brief Get the number of PWM cycles per second for a specific channel. + * + * This function retrieves the frequency of the PWM signal in cycles per second for a specified + * channel. + * + * @param pwm_dev Pointer to the PWM device structure. + * @param channel PWM channel number. + * @param cycles Pointer to store the number of cycles per second. + * + * @return 0 on success, -EINVAL if the channel is invalid. + */ +static int pwm_mchp_get_cycles_per_sec(const struct device *pwm_dev, uint32_t channel, + uint64_t *cycles) +{ + const pwm_mchp_config_t *const mchp_pwm_cfg = pwm_dev->config; + pwm_mchp_data_t *mchp_pwm_data = pwm_dev->data; + uint32_t periph_clk_freq = 0; + int ret_val = -EINVAL; + + MCHP_PWM_DATA_LOCK(&mchp_pwm_data->lock); + + if (channel < (mchp_pwm_cfg->channels)) { + /* clang-format off */ + clock_control_get_rate( + mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.periph_async_clk, + &periph_clk_freq); + /* clang-format on */ + *cycles = periph_clk_freq / mchp_pwm_cfg->prescaler; + ret_val = MCHP_PWM_SUCCESS; + } else { + LOG_ERR("channel %d is invalid", channel); + } + + MCHP_PWM_DATA_UNLOCK(&mchp_pwm_data->lock); + + return ret_val; +} + +/****************************************************************************** + * @brief Zephyr driver instance creation + *****************************************************************************/ + +/** + * @brief PWM driver API structure for the Microchip PWM device. + * + * This structure defines the API functions for the Microchip PWM driver, including setting PWM + * cycles, getting the number of cycles per second, and optionally configuring, enabling, and + * disabling PWM capture. + */ +static DEVICE_API(pwm, pwm_mchp_api) = { + .set_cycles = pwm_mchp_set_cycles, + .get_cycles_per_sec = pwm_mchp_get_cycles_per_sec, +}; + +/** + * @brief Initialize the Microchip PWM device. + * + * This function initializes the Microchip PWM device by applying the pin control configuration and + * initializing the PWM hardware with the specified prescaler. + * + * @param pwm_dev Pointer to the PWM device structure. + * + * @return 0 on success, negative error code on failure. + */ +static int pwm_mchp_init(const struct device *pwm_dev) +{ + int ret_val; + const pwm_mchp_config_t *const mchp_pwm_cfg = pwm_dev->config; + pwm_mchp_data_t *mchp_pwm_data = pwm_dev->data; + + MCHP_PWM_DATA_LOCK_INIT(&mchp_pwm_data->lock); + do { + + ret_val = clock_control_on(mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.periph_async_clk); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Failed to enable the periph_async_clk for PWM: %d", ret_val); + break; + } + ret_val = clock_control_on(mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.host_core_sync_clk); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Failed to enable the host_core_sync_clk for PWM: %d", ret_val); + break; + } + 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); + break; + } + tcc_init(mchp_pwm_cfg->regs, mchp_pwm_cfg->prescaler); + } while (0); + ret_val = (ret_val == -EALREADY) ? 0 : ret_val; + + return ret_val; +} + +/** + * @brief Macro to define the PWM data structure for a specific instance. + * + * This macro defines the PWM data structure for a specific instance of the Microchip PWM device. + * + * @param n Instance number. + * @param ip IP identifier. + */ +#define PWM_MCHP_DATA_DEFN(n) static pwm_mchp_data_t pwm_mchp_data_##n + +/** + * @brief Macro to assign clock configurations for the Microchip PWM device. + * + * This macro assigns the clock configurations for the PWM device, including the + * host core synchronous clock, and + * peripheral asynchronous clock (conditionally). + * + * @param n Device tree node number. + * + * @note This macro conditionally includes peripheral asynchronous clock configurations based on + * the presence of relevant device tree properties. + */ +/* clang-format off */ +#define PWM_MCHP_CLOCK_ASSIGN(n) \ + .pwm_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .pwm_clock.host_core_sync_clk = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem)),\ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CLOCKS_CTLR_BY_NAME(n, rtcclk)), \ + (.pwm_clock.periph_async_clk = \ + (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, rtcclk, subsystem)),), \ + ()) COND_CODE_1(DT_NODE_EXISTS(DT_INST_CLOCKS_CTLR_BY_NAME(n, gclk)), \ + (.pwm_clock.periph_async_clk = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem)),),\ + ()) +/* clang-format on */ + +/** + * @brief Macro to define the PWM configuration structure for a specific instance. + * + * This macro defines the PWM configuration structure for a specific instance of the Microchip PWM + * device. + * + * @param n Instance number. + */ +#define PWM_MCHP_CONFIG_DEFN(n) \ + static const pwm_mchp_config_t 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)} + +/** + * @brief Macro to define the device structure for a specific instance of the PWM device. + * + * This macro defines the device structure for a specific instance of the Microchip PWM device. + * It uses the DEVICE_DT_INST_DEFINE macro to create the device instance with the specified + * initialization function, data structure, configuration structure, and driver API. + * + * @param n Instance number. + */ +#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) + +/** + *Initialize the PWM device with pin control, data, and configuration definitions. + */ +#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); + +/* Run init macro for each pwm-generic node */ +DT_INST_FOREACH_STATUS_OKAY(PWM_MCHP_DEVICE_INIT) diff --git a/drivers/pwm/pwm_mcux_qtmr.c b/drivers/pwm/pwm_mcux_qtmr.c index 44b33b829f718..670adf52a96fc 100644 --- a/drivers/pwm/pwm_mcux_qtmr.c +++ b/drivers/pwm/pwm_mcux_qtmr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, NXP + * Copyright (c) 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -26,10 +27,29 @@ struct pwm_mcux_qtmr_config { const struct pinctrl_dev_config *pincfg; const struct device *clock_dev; clock_control_subsys_t clock_subsys; +#ifdef CONFIG_PWM_CAPTURE + void (*irq_config_func)(const struct device *dev); +#endif /* CONFIG_PWM_CAPTURE */ }; +#ifdef CONFIG_PWM_CAPTURE +struct pwm_mcux_qtmr_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint32_t overflow_count; + uint32_t channel; + bool continuous : 1; + bool overflowed : 1; + bool pulse_capture: 1; + bool first_edge_captured : 1; +}; +#endif /* CONFIG_PWM_CAPTURE */ + struct pwm_mcux_qtmr_data { struct k_mutex lock; +#ifdef CONFIG_PWM_CAPTURE + struct pwm_mcux_qtmr_capture_data capture; +#endif /* CONFIG_PWM_CAPTURE */ }; static int mcux_qtmr_pwm_set_cycles(const struct device *dev, uint32_t channel, @@ -38,7 +58,7 @@ static int mcux_qtmr_pwm_set_cycles(const struct device *dev, uint32_t channel, { const struct pwm_mcux_qtmr_config *config = dev->config; struct pwm_mcux_qtmr_data *data = dev->data; - uint32_t periodCount, highCount, lowCount; + uint32_t highCount, lowCount; uint16_t reg; if (channel >= CHANNEL_COUNT) { @@ -47,7 +67,6 @@ static int mcux_qtmr_pwm_set_cycles(const struct device *dev, uint32_t channel, } /* Counter values to generate a PWM signal */ - periodCount = period_cycles; highCount = pulse_cycles; lowCount = period_cycles - pulse_cycles; @@ -90,12 +109,12 @@ static int mcux_qtmr_pwm_set_cycles(const struct device *dev, uint32_t channel, reg = config->base->CHANNEL[channel].CTRL; reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK; - if (highCount == periodCount) { - /* Set OFLAG output on compare */ - reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare)); - } else if (periodCount == 0U) { - /* Clear OFLAG output on compare */ + if (pulse_cycles == 0U) { + /* 0% duty cycle, clear OFLAG output on compare */ reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ClearOnCompare)); + } else if (pulse_cycles == period_cycles) { + /* 100% duty cycle, set OFLAG output on compare */ + reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare)); } else { /* Toggle OFLAG output using alternating compare register */ reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg)); @@ -124,6 +143,198 @@ static int mcux_qtmr_pwm_get_cycles_per_sec(const struct device *dev, uint32_t c return 0; } +#ifdef CONFIG_PWM_CAPTURE +static inline bool mcux_qtmr_channel_is_active(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + + return (config->base->CHANNEL[channel].CTRL & TMR_CTRL_CM_MASK) != 0U; +} + +static int mcux_qtmr_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_qtmr_config *config = dev->config; + struct pwm_mcux_qtmr_data *data = dev->data; + bool inverted = (flags & PWM_POLARITY_MASK) == PWM_POLARITY_INVERTED; + + if (channel >= CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + if (mcux_qtmr_channel_is_active(dev, channel)) { + LOG_ERR("pwm capture 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; + } + + data->capture.callback = cb; + data->capture.user_data = user_data; + data->capture.channel = channel; + data->capture.continuous = + (flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS; + + if (flags & PWM_CAPTURE_TYPE_PERIOD) { + data->capture.pulse_capture = false; + /* set reloadOnCapture to true to reload counter when capture event happends, + * so only second caputre value is needed when calculating ticks + */ + QTMR_SetupInputCapture(config->base, + (qtmr_channel_selection_t)channel, + (qtmr_input_source_t)channel, + inverted, true, kQTMR_RisingEdge); + } else { + data->capture.pulse_capture = true; + QTMR_SetupInputCapture(config->base, + (qtmr_channel_selection_t)channel, + (qtmr_input_source_t)channel, + inverted, true, kQTMR_RisingAndFallingEdge); + } + QTMR_EnableInterrupts(config->base, channel, + kQTMR_EdgeInterruptEnable | kQTMR_OverflowInterruptEnable); + + return 0; +} + +static int mcux_qtmr_enable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + struct pwm_mcux_qtmr_data *data = dev->data; + + if (channel >= CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + if (!data->capture.callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + if (mcux_qtmr_channel_is_active(dev, channel)) { + LOG_ERR("PWM capture already enabled"); + return -EBUSY; + } + + data->capture.overflowed = false; + data->capture.first_edge_captured = false; + data->capture.overflow_count = 0; + QTMR_StartTimer(config->base, channel, kQTMR_PriSrcRiseEdge); + + return 0; +} + +static int mcux_qtmr_disable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + + if (channel >= CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + QTMR_StopTimer(config->base, channel); + return 0; +} + +static int mcux_qtmr_calc_ticks(uint32_t overflows, uint32_t capture, + uint32_t *result) +{ + uint32_t pulse; + + /* Calculate cycles from overflow counter */ + if (u32_mul_overflow(overflows, 0xFFFFU, &pulse)) { + return -ERANGE; + } + + /* Add pulse width */ + if (u32_add_overflow(pulse, capture, &pulse)) { + return -ERANGE; + } + + *result = pulse; + + return 0; +} + +static void mcux_qtmr_isr(const struct device *dev) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + struct pwm_mcux_qtmr_data *data = dev->data; + uint32_t ticks = 0; + uint32_t timeCapt = 0; + int err = 0; + uint32_t flags; + + flags = QTMR_GetStatus(config->base, data->capture.channel); + QTMR_ClearStatusFlags(config->base, data->capture.channel, flags); + + if ((flags & kQTMR_OverflowFlag) != 0U) { + data->capture.overflowed |= u32_add_overflow(1, + data->capture.overflow_count, &data->capture.overflow_count); + } + + if ((flags & kQTMR_EdgeFlag) == 0U) { + return; + } + + if (!data->capture.first_edge_captured) { + data->capture.first_edge_captured = true; + data->capture.overflow_count = 0; + data->capture.overflowed = false; + return; + } + + if (data->capture.overflowed) { + err = -ERANGE; + } else { + /* calculate ticks from second capture */ + timeCapt = config->base->CHANNEL[data->capture.channel].CAPT; + err = mcux_qtmr_calc_ticks(data->capture.overflow_count, timeCapt, &ticks); + } + + if (data->capture.pulse_capture) { + data->capture.callback(dev, data->capture.channel, + 0, ticks, err, data->capture.user_data); + } else { + data->capture.callback(dev, data->capture.channel, + ticks, 0, err, data->capture.user_data); + } + + /* Prepare for next capture */ + data->capture.overflowed = false; + data->capture.overflow_count = 0; + + if (data->capture.continuous) { + if (data->capture.pulse_capture) { + data->capture.first_edge_captured = false; + } else { + /* No action required. In continuous period capture mode, + * first edge of next period captureis second edge of this + * capture (this edge) + */ + } + } else { + /* Stop timer and disable interrupts for single capture*/ + data->capture.first_edge_captured = false; + QTMR_DisableInterrupts(config->base, data->capture.channel, + kQTMR_EdgeInterruptEnable | kQTMR_OverflowInterruptEnable); + QTMR_StopTimer(config->base, data->capture.channel); + } +} +#endif /* CONFIG_PWM_CAPTURE */ static int mcux_qtmr_pwm_init(const struct device *dev) { @@ -142,6 +353,13 @@ static int mcux_qtmr_pwm_init(const struct device *dev) QTMR_GetDefaultConfig(&qtmr_config); qtmr_config.primarySource = kQTMR_ClockDivide_1 + (31 - __builtin_clz(config->prescaler)); +#ifdef CONFIG_PWM_CAPTURE + config->irq_config_func(dev); + + qtmr_config.faultFilterCount = CONFIG_PWM_CAPTURE_MCUX_QTMR_FILTER_COUNT; + qtmr_config.faultFilterPeriod = CONFIG_PWM_CAPTURE_MCUX_QTMR_FILTER_PERIOD; +#endif /* CONFIG_PWM_CAPTURE */ + for (int i = 0; i < CHANNEL_COUNT; i++) { QTMR_Init(config->base, i, &qtmr_config); } @@ -152,22 +370,50 @@ static int mcux_qtmr_pwm_init(const struct device *dev) static DEVICE_API(pwm, pwm_mcux_qtmr_driver_api) = { .set_cycles = mcux_qtmr_pwm_set_cycles, .get_cycles_per_sec = mcux_qtmr_pwm_get_cycles_per_sec, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = mcux_qtmr_configure_capture, + .enable_capture = mcux_qtmr_enable_capture, + .disable_capture = mcux_qtmr_disable_capture, +#endif }; -#define PWM_MCUX_QTMR_DEVICE_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static struct pwm_mcux_qtmr_data pwm_mcux_qtmr_data_##n; \ - \ - static const struct pwm_mcux_qtmr_config pwm_mcux_qtmr_config_##n = { \ +#ifdef CONFIG_PWM_CAPTURE +#define QTMR_CONFIG_FUNC(n) \ +static void mcux_qtmr_config_func_##n(const struct device *dev) \ +{ \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + mcux_qtmr_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ +} +#define QTMR_CFG_CAPTURE_INIT(n) \ + .irq_config_func = mcux_qtmr_config_func_##n +#define QTMR_INIT_CFG(n) QTMR_DECLARE_CFG(n, QTMR_CFG_CAPTURE_INIT(n)) +#else /* !CONFIG_PWM_CAPTURE */ +#define QTMR_CONFIG_FUNC(n) +#define QTMR_CFG_CAPTURE_INIT +#define QTMR_INIT_CFG(n) QTMR_DECLARE_CFG(n, QTMR_CFG_CAPTURE_INIT) +#endif /* !CONFIG_PWM_CAPTURE */ + +#define QTMR_DECLARE_CFG(n, CAPTURE_INIT) \ + static const struct pwm_mcux_qtmr_config pwm_mcux_qtmr_config_##n = { \ .base = (TMR_Type *)DT_INST_REG_ADDR(n), \ .prescaler = DT_INST_PROP(n, prescaler), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, mcux_qtmr_pwm_init, NULL, &pwm_mcux_qtmr_data_##n, \ - &pwm_mcux_qtmr_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ - &pwm_mcux_qtmr_driver_api); + CAPTURE_INIT \ + } -DT_INST_FOREACH_STATUS_OKAY(PWM_MCUX_QTMR_DEVICE_INIT) +#define QTMR_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct pwm_mcux_qtmr_config pwm_mcux_qtmr_config_##n; \ + static struct pwm_mcux_qtmr_data pwm_mcux_qtmr_data_##n; \ + DEVICE_DT_INST_DEFINE(n, &mcux_qtmr_pwm_init, NULL, \ + &pwm_mcux_qtmr_data_##n, \ + &pwm_mcux_qtmr_config_##n, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_mcux_qtmr_driver_api); \ + QTMR_CONFIG_FUNC(n) \ + QTMR_INIT_CFG(n); + +DT_INST_FOREACH_STATUS_OKAY(QTMR_DEVICE) diff --git a/drivers/reset/CMakeLists.txt b/drivers/reset/CMakeLists.txt index 363720f271304..9646ba6dd5a8f 100644 --- a/drivers/reset/CMakeLists.txt +++ b/drivers/reset/CMakeLists.txt @@ -15,4 +15,5 @@ zephyr_library_sources_ifdef(CONFIG_RESET_NXP_MRCC reset_nxp_mrcc.c) zephyr_library_sources_ifdef(CONFIG_RESET_NXP_RSTCTL reset_nxp_rstctl.c) zephyr_library_sources_ifdef(CONFIG_RESET_MMIO reset_mmio.c) zephyr_library_sources_ifdef(CONFIG_RESET_MCHP_MSS reset_mchp_mss.c) +zephyr_library_sources_ifdef(CONFIG_RESET_MCHP_RSTC_G1 reset_mchp_rstc_g1.c) zephyr_library_sources_ifdef(CONFIG_RESET_SF32LB reset_sf32lb.c) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index b5c76cc70c9fe..8562f2c183586 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -38,6 +38,7 @@ rsource "Kconfig.lpc_syscon" rsource "Kconfig.nxp_mrcc" rsource "Kconfig.nxp_rstctl" rsource "Kconfig.mmio" +rsource "Kconfig.mchp" rsource "Kconfig.mchp_mss" rsource "Kconfig.sf32lb" diff --git a/drivers/reset/Kconfig.mchp b/drivers/reset/Kconfig.mchp new file mode 100644 index 0000000000000..61d5920e9d04c --- /dev/null +++ b/drivers/reset/Kconfig.mchp @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config RESET_MCHP_RSTC_G1 + bool "Microchip Reset Controller g1 peripheral driver" + default y + depends on DT_HAS_MICROCHIP_RSTC_G1_RESET_ENABLED + help + Enable RESET driver for Microchip G1. diff --git a/drivers/reset/reset_mchp_rstc_g1.c b/drivers/reset/reset_mchp_rstc_g1.c new file mode 100644 index 0000000000000..33d141aaff34a --- /dev/null +++ b/drivers/reset/reset_mchp_rstc_g1.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2025 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 + +#define DT_DRV_COMPAT microchip_rstc_g1_reset + +/* Maximum number of reset lines supported by the controller */ +#define MCHP_RST_LINE_MAX 8 + +struct reset_mchp_config { + rstc_registers_t *regs; +}; + +/** + * @brief Get the status of a reset line. + * + * This function checks if the specified reset line is currently asserted. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] id Reset line ID (0-7). + * @param[out] status Pointer to a variable to store the status (1 = asserted, 0 = not asserted). + * + * @retval 0 On success. + * @retval -EINVAL If the reset line ID is invalid. + */ +static int reset_mchp_status(const struct device *dev, uint32_t id, uint8_t *status) +{ + int ret = 0; + uint8_t rcause = 0; + + if (id >= MCHP_RST_LINE_MAX) { + ret = -EINVAL; + } else { + rcause = (((const struct reset_mchp_config *)((dev)->config))->regs)->RSTC_RCAUSE; + *status = (rcause & BIT(id)) ? 1 : 0; + } + + return ret; +} + +/** + * @brief Assert (activate) a reset line. + * + * This function asserts the specified reset line. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] id Reset line ID. + * + * @retval -ENOTSUP Operation not supported by hardware. + */ +static int reset_mchp_line_assert(const struct device *dev, uint32_t id) +{ + return -ENOTSUP; +} + +/** + * @brief Deassert (deactivate) a reset line. + * + * This function deasserts the specified reset line. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] id Reset line ID. + * + * @retval -ENOTSUP Operation not supported by hardware. + */ +static int reset_mchp_line_deassert(const struct device *dev, uint32_t id) +{ + return -ENOTSUP; +} + +/** + * @brief Toggle a reset line (assert then deassert). + * + * This function asserts and then deasserts the specified reset line, with a short delay in between. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] id Reset line ID. + * + * @retval -ENOTSUP Operation not supported by hardware. + */ +static int reset_mchp_line_toggle(const struct device *dev, uint32_t id) +{ + return -ENOTSUP; +} + +static DEVICE_API(reset, reset_mchp_api) = { + .status = reset_mchp_status, + .line_assert = reset_mchp_line_assert, + .line_deassert = reset_mchp_line_deassert, + .line_toggle = reset_mchp_line_toggle, +}; + +/* Configuration instance for the Microchip RSTC g1 reset controller */ +static const struct reset_mchp_config reset_mchp_config = { + .regs = (rstc_registers_t *)DT_INST_REG_ADDR(0), +}; + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1, + "Only one Microchip RSTC g1 instance is supported."); + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &reset_mchp_config, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &reset_mchp_api) diff --git a/drivers/sensor/adi/CMakeLists.txt b/drivers/sensor/adi/CMakeLists.txt index f0bb5910cf972..e524f38dc5e68 100644 --- a/drivers/sensor/adi/CMakeLists.txt +++ b/drivers/sensor/adi/CMakeLists.txt @@ -10,4 +10,5 @@ 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_SENSOR_MAX32664C max32664c) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/adi/Kconfig b/drivers/sensor/adi/Kconfig index dea030c68034d..d0812de2dcee4 100644 --- a/drivers/sensor/adi/Kconfig +++ b/drivers/sensor/adi/Kconfig @@ -10,4 +10,5 @@ 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/max32664c/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/adi/adxl345/adxl345_stream.c b/drivers/sensor/adi/adxl345/adxl345_stream.c index 9550efb43bdd3..6de0df79699ef 100644 --- a/drivers/sensor/adi/adxl345/adxl345_stream.c +++ b/drivers/sensor/adi/adxl345/adxl345_stream.c @@ -309,11 +309,9 @@ static void adxl345_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq return; } - enum sensor_stream_data_opt data_opt; - - if (fifo_wmark_cfg != NULL) { - data_opt = fifo_wmark_cfg->opt; - } + /* fifo_wmark_cfg is guaranteed to be non-NULL here since fifo_full_irq is true */ + __ASSERT_NO_MSG(fifo_wmark_cfg != NULL); + enum sensor_stream_data_opt data_opt = fifo_wmark_cfg->opt; if (data_opt == SENSOR_STREAM_DATA_NOP || data_opt == SENSOR_STREAM_DATA_DROP) { uint8_t *buf; diff --git a/drivers/sensor/adi/max32664c/CMakeLists.txt b/drivers/sensor/adi/max32664c/CMakeLists.txt new file mode 100644 index 0000000000000..b36663c699fa7 --- /dev/null +++ b/drivers/sensor/adi/max32664c/CMakeLists.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_sources_ifdef(CONFIG_MAX32664C_USE_FIRMWARE_LOADER max32664c_bl.c) + +zephyr_sources_ifdef(CONFIG_MAX32664C_USE_INTERRUPT max32664c_interrupt.c) + +zephyr_sources_ifdef(CONFIG_SENSOR_MAX32664C max32664c.c + max32664c_worker.c + max32664c_init.c + max32664c_acc.c + ) diff --git a/drivers/sensor/adi/max32664c/Kconfig b/drivers/sensor/adi/max32664c/Kconfig new file mode 100644 index 0000000000000..5b939fa826ba3 --- /dev/null +++ b/drivers/sensor/adi/max32664c/Kconfig @@ -0,0 +1,45 @@ +# Copyright(c) 2025, Daniel Kampert +# SPDX-License-Identifier: Apache-2.0 + +config SENSOR_MAX32664C + bool "MAX32664C Driver" + default y + depends on DT_HAS_MAXIM_MAX32664C_ENABLED + select I2C + help + Enable the driver for the MAX32664C biometric sensor hub. + +if SENSOR_MAX32664C +config MAX32664C_USE_FIRMWARE_LOADER + bool "Use this option if you want to flash the sensor hub over the I2C firmware loader" + +config MAX32664C_USE_EXTERNAL_ACC + bool "Use this option if you want to use an external accelerometer" + +config MAX32664C_USE_EXTENDED_REPORTS + bool "Use this option if you want to use extended reports instead of the default reports" + +config MAX32664C_USE_STATIC_MEMORY + bool "Disable this option if the driver should use dynamic memory" + default y + +config MAX32664C_QUEUE_SIZE + int "Length of the message queue" + default 32 + +config MAX32664C_SAMPLE_BUFFER_SIZE + depends on MAX32664C_USE_STATIC_MEMORY + int "Length of the sample buffer for the I2C reading thread" + default 64 + help + This is the number of samples that will be read from the sensor hub in one go. + The maximum value is 64, but you can set it lower if you want to reduce memory usage. + +config MAX32664C_THREAD_STACK_SIZE + int "MAX32664C sample thread stack size" + default 4096 + +config MAX32664C_USE_INTERRUPT + bool "Use this option if you want to use the MFIO interrupt support" + depends on GPIO +endif diff --git a/drivers/sensor/adi/max32664c/max32664c.c b/drivers/sensor/adi/max32664c/max32664c.c new file mode 100644 index 0000000000000..99d89cc655b88 --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c.c @@ -0,0 +1,1101 @@ +/* + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "max32664c.h" + +#define DT_DRV_COMPAT maxim_max32664c + +#if (DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0) +#warning "max32664c driver enabled without any devices" +#endif + +LOG_MODULE_REGISTER(maxim_max32664c, CONFIG_SENSOR_LOG_LEVEL); + +int max32664c_i2c_transmit(const struct device *dev, uint8_t *tx_buf, uint8_t tx_len, + uint8_t *rx_buf, uint32_t rx_len, uint16_t delay_ms) +{ + const struct max32664c_config *config = dev->config; + + /* Wake up the sensor hub before the transmission starts (min. 300 us) */ + gpio_pin_set_dt(&config->mfio_gpio, false); + k_usleep(500); + + if (i2c_write_dt(&config->i2c, tx_buf, tx_len)) { + LOG_ERR("I2C transmission error!"); + return -EBUSY; + } + + k_msleep(delay_ms); + + if (i2c_read_dt(&config->i2c, rx_buf, rx_len)) { + LOG_ERR("I2C read error!"); + return -EBUSY; + } + + k_msleep(MAX32664C_DEFAULT_CMD_DELAY); + + /* The sensor hub can enter sleep mode again now */ + gpio_pin_set_dt(&config->mfio_gpio, true); + k_usleep(300); + + /* Check the status byte for a valid transaction */ + if (rx_buf[0] != 0) { + return -EINVAL; + } + + return 0; +} + +/** @brief Check the accelerometer and AFE WHOAMI registers. + * This function is called during device initialization. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_check_sensors(const struct device *dev) +{ + uint8_t afe_id; + uint8_t tx[3]; + uint8_t rx[2]; + struct max32664c_data *data = dev->data; + const struct max32664c_config *config = dev->config; + + LOG_DBG("Checking sensors..."); + + /* Read MAX86141 WHOAMI */ + tx[0] = 0x41; + tx[1] = 0x00; + tx[2] = 0xFF; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + if (config->use_max86141) { + LOG_DBG("\tUsing MAX86141 as AFE"); + afe_id = 0x25; + } else if (config->use_max86161) { + LOG_DBG("\tUsing MAX86161 as AFE"); + afe_id = 0x36; + } else { + LOG_ERR("\tNo AFE defined!"); + return -ENODEV; + } + + data->afe_id = rx[1]; + if (data->afe_id != afe_id) { + LOG_ERR("\tAFE WHOAMI failed: 0x%X", data->afe_id); + return -ENODEV; + } + + LOG_DBG("\tAFE WHOAMI OK: 0x%X", data->afe_id); + + /* Read Accelerometer WHOAMI */ + tx[0] = 0x41; + tx[1] = 0x04; + tx[2] = 0x0F; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + data->accel_id = rx[1]; + /* The sensor hub firmware supports only two accelerometers and one is set to */ + /* EoL. The remaining one is the ST LIS2DS12. */ + if (data->accel_id != 0x43) { + LOG_ERR("\tAccelerometer WHOAMI failed: 0x%X", data->accel_id); + return -ENODEV; + } + + LOG_DBG("\tAccelerometer WHOAMI OK: 0x%X", data->accel_id); + + return 0; +} + +/** @brief Stop the current algorithm. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_stop_algo(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[3]; + struct max32664c_data *data = dev->data; + + if (data->op_mode == MAX32664C_OP_MODE_IDLE) { + LOG_DBG("No algorithm running, nothing to stop."); + return 0; + } + + LOG_DBG("Stop the current algorithm..."); + + /* Stop the algorithm */ + tx[0] = 0x52; + tx[1] = 0x07; + tx[2] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, 120)) { + return -EINVAL; + } + + switch (data->op_mode) { + case MAX32664C_OP_MODE_RAW: { +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_msgq_cleanup(&data->raw_report_queue); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + break; + } +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + case MAX32664C_OP_MODE_ALGO_AEC_EXT: + case MAX32664C_OP_MODE_ALGO_AGC_EXT: { +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_msgq_cleanup(&data->ext_report_queue); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + break; + } +#else + case MAX32664C_OP_MODE_ALGO_AEC: + case MAX32664C_OP_MODE_ALGO_AGC: { +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_msgq_cleanup(&data->report_queue); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + break; + } +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + case MAX32664C_OP_MODE_SCD: { +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_msgq_cleanup(&data->scd_report_queue); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + break; + } + default: { + LOG_ERR("Unknown algorithm mode: %d", data->op_mode); + return -EINVAL; + } + }; + + data->op_mode = MAX32664C_OP_MODE_IDLE; + + k_thread_suspend(data->thread_id); + + return 0; +} + +/** @brief Put the device into raw measurement mode. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_set_mode_raw(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[4]; + struct max32664c_data *data = dev->data; + + /* Stop the current algorithm mode */ + if (max32664c_stop_algo(dev)) { + LOG_ERR("Failed to stop the algorithm!"); + return -EINVAL; + } + + LOG_INF("Entering RAW mode..."); + + /* Set the output format to sensor data only */ + tx[0] = 0x10; + tx[1] = 0x00; + tx[2] = MAX32664C_OUT_SENSOR_ONLY; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Enable the AFE */ + tx[0] = 0x44; + tx[1] = 0x00; + tx[2] = 0x01; + tx[3] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, 250)) { + return -EINVAL; + } + + /* Enable the accelerometer */ + if (max32664c_acc_enable(dev, true)) { + return -EINVAL; + } + + /* Set AFE sample rate to 100 Hz */ + tx[0] = 0x40; + tx[1] = 0x00; + tx[2] = 0x12; + tx[3] = 0x18; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set the LED current */ + for (uint8_t i = 0; i < sizeof(data->led_current); i++) { + tx[0] = 0x40; + tx[1] = 0x00; + tx[2] = 0x23 + i; + tx[3] = data->led_current[i]; + LOG_INF("Set LED%d current: %u", i + 1, data->led_current[i]); + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set LED%d current", i + 1); + return -EINVAL; + } + } + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + if (k_msgq_alloc_init(&data->raw_report_queue, sizeof(struct max32664c_raw_report_t), + CONFIG_MAX32664C_QUEUE_SIZE)) { + LOG_ERR("Failed to allocate RAW report queue!"); + return -ENOMEM; + } +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + data->op_mode = MAX32664C_OP_MODE_RAW; + + k_thread_resume(data->thread_id); + + return 0; +} + +/** @brief Put the sensor hub into algorithm mode. + * @param dev Pointer to device + * @param device_mode Target device mode + * @param algo_mode Target algorithm mode + * @param extended Set to #true when the extended mode should be used + * @return 0 when successful + */ +static int max32664c_set_mode_algo(const struct device *dev, enum max32664c_device_mode device_mode, + enum max32664c_algo_mode algo_mode, bool extended) +{ + uint8_t rx; + uint8_t tx[5]; + struct max32664c_data *data = dev->data; + + /* Stop the current algorithm mode */ + if (max32664c_stop_algo(dev)) { + LOG_ERR("Failed to stop the algorithm!"); + return -EINVAL; + } + + LOG_DBG("Entering algorithm mode..."); + +#ifndef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + if (extended) { + LOG_ERR("No support for extended reports enabled!"); + return -EINVAL; + } +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + + /* Set the output mode to sensor and algorithm data */ + tx[0] = 0x10; + tx[1] = 0x00; + tx[2] = MAX32664C_OUT_ALGO_AND_SENSOR; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set the algorithm mode */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x0A; + tx[3] = algo_mode; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + if (device_mode == MAX32664C_OP_MODE_ALGO_AEC) { + LOG_DBG("Entering AEC mode..."); + + /* Enable AEC */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x0B; + tx[3] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Enable Auto PD */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x12; + tx[3] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Enable SCD */ + LOG_DBG("Enabling SCD..."); + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x0C; + tx[3] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + data->op_mode = MAX32664C_OP_MODE_ALGO_AEC; + + if (extended) { + data->op_mode = MAX32664C_OP_MODE_ALGO_AEC_EXT; + } + } else if (device_mode == MAX32664C_OP_MODE_ALGO_AGC) { + LOG_DBG("Entering AGC mode..."); + + /* TODO: Test if this works */ + /* Set the LED current */ + for (uint8_t i = 0; i < sizeof(data->led_current); i++) { + tx[0] = 0x40; + tx[1] = 0x00; + tx[2] = 0x23 + i; + tx[3] = data->led_current[i]; + LOG_INF("Set LED%d current: %u", i + 1, data->led_current[i]); + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, + MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set LED%d current", i + 1); + return -EINVAL; + } + } + + /* Enable AEC */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x0B; + tx[3] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Disable PD auto current calculation */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x12; + tx[3] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Disable SCD */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x0C; + tx[3] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set AGC target PD current to 10 uA */ + /* TODO: Add setting of PD current via API or DT? */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x11; + tx[3] = 0x00; + tx[4] = 0x64; + if (max32664c_i2c_transmit(dev, tx, 5, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + data->op_mode = MAX32664C_OP_MODE_ALGO_AGC; + + if (extended) { + data->op_mode = MAX32664C_OP_MODE_ALGO_AGC_EXT; + } + } else { + LOG_ERR("Invalid mode!"); + return -EINVAL; + } + + /* Enable HR and SpO2 algorithm */ + tx[2] = 0x01; + if (extended) { + tx[2] = 0x02; + } + + tx[0] = 0x52; + tx[1] = 0x07; + + /* Use the maximum time to cover all modes (see Table 6 and 12 in the User Guide) */ + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, 500)) { + return -EINVAL; + } + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + if (k_msgq_alloc_init(&data->raw_report_queue, sizeof(struct max32664c_raw_report_t), + CONFIG_MAX32664C_QUEUE_SIZE)) { + LOG_ERR("Failed to allocate RAW report queue!"); + return -ENOMEM; + } + + if (!extended && k_msgq_alloc_init(&data->report_queue, sizeof(struct max32664c_report_t), + CONFIG_MAX32664C_QUEUE_SIZE)) { + LOG_ERR("Failed to allocate report queue!"); + return -ENOMEM; + } + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + if (extended && + k_msgq_alloc_init(&data->ext_report_queue, sizeof(struct max32664c_ext_report_t), + CONFIG_MAX32664C_QUEUE_SIZE)) { + LOG_ERR("Failed to allocate extended report queue!"); + return -ENOMEM; + } +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + k_thread_resume(data->thread_id); + + return 0; +} + +/** @brief Enable the skin contact detection only mode. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_set_mode_scd(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[4]; + struct max32664c_data *data = dev->data; + + /* Stop the current algorithm mode */ + if (max32664c_stop_algo(dev)) { + LOG_ERR("Failed to stop the algorithm!"); + return -EINVAL; + } + + LOG_DBG("MAX32664C entering SCD mode..."); + + /* Use LED2 for SCD */ + tx[0] = 0xE5; + tx[1] = 0x02; + if (max32664c_i2c_transmit(dev, tx, 2, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set the output mode to algorithm data */ + tx[0] = 0x10; + tx[1] = 0x00; + tx[2] = MAX32664C_OUT_ALGORITHM_ONLY; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Enable SCD only algorithm */ + tx[0] = 0x52; + tx[1] = 0x07; + tx[2] = 0x03; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, 500)) { + return -EINVAL; + } + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + if (k_msgq_alloc_init(&data->scd_report_queue, sizeof(struct max32664c_scd_report_t), + CONFIG_MAX32664C_QUEUE_SIZE)) { + LOG_ERR("Failed to allocate SCD report queue!"); + return -ENOMEM; + } +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + data->op_mode = MAX32664C_OP_MODE_SCD; + + k_thread_resume(data->thread_id); + + return 0; +} + +static int max32664c_set_mode_wake_on_motion(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[6]; + struct max32664c_data *data = dev->data; + + LOG_DBG("MAX32664C entering wake on motion mode..."); + + /* Stop the current algorithm */ + tx[0] = 0x52; + tx[1] = 0x07; + tx[2] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set the motion detection threshold (see Table 12 in the SpO2 and Heart Rate Using Guide) + */ + tx[0] = 0x46; + tx[1] = 0x04; + tx[2] = 0x00; + tx[3] = 0x01; + tx[4] = MAX32664C_MOTION_TIME(data->motion_time); + tx[5] = MAX32664C_MOTION_THRESHOLD(data->motion_threshold); + if (max32664c_i2c_transmit(dev, tx, 6, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Set the output mode to sensor data */ + tx[0] = 0x10; + tx[1] = 0x00; + tx[2] = MAX32664C_OUT_SENSOR_ONLY; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Enable the accelerometer */ + if (max32664c_acc_enable(dev, true)) { + return -EINVAL; + } + + data->op_mode = MAX32664C_OP_MODE_WAKE_ON_MOTION; + + return 0; +} + +static int max32664c_exit_mode_wake_on_motion(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[6]; + struct max32664c_data *data = dev->data; + + LOG_DBG("MAX32664C exiting wake on motion mode..."); + + /* Exit wake on motion mode */ + tx[0] = 0x46; + tx[1] = 0x04; + tx[2] = 0x00; + tx[3] = 0x00; + tx[4] = 0xFF; + tx[5] = 0xFF; + if (max32664c_i2c_transmit(dev, tx, 6, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + /* Disable the accelerometer */ + if (max32664c_acc_enable(dev, false)) { + return -EINVAL; + } + + data->op_mode = MAX32664C_OP_MODE_IDLE; + + return 0; +} + +static int max32664c_disable_sensors(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[4]; + struct max32664c_data *data = dev->data; + + if (max32664c_stop_algo(dev)) { + LOG_ERR("Failed to stop the algorithm!"); + return -EINVAL; + } + + /* Leave wake on motion first because we disable the accelerometer */ + if (max32664c_exit_mode_wake_on_motion(dev)) { + LOG_ERR("Failed to exit wake on motion mode!"); + return -EINVAL; + } + + LOG_DBG("Disable the sensors..."); + + /* Disable the AFE */ + tx[0] = 0x44; + tx[1] = 0x00; + tx[2] = 0x00; + tx[3] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, 250)) { + return -EINVAL; + } + + /* Disable the accelerometer */ + if (max32664c_acc_enable(dev, false)) { + return -EINVAL; + } + + data->op_mode = MAX32664C_OP_MODE_IDLE; + + return 0; +} + +static int max32664c_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct max32664c_data *data = dev->data; + + switch (data->op_mode) { + case MAX32664C_OP_MODE_STOP_ALGO: + case MAX32664C_OP_MODE_IDLE: + LOG_DBG("Device is idle, no data to fetch!"); + return -EAGAIN; + case MAX32664C_OP_MODE_SCD: + k_msgq_get(&data->scd_report_queue, &data->scd, K_NO_WAIT); + return 0; +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + case MAX32664C_OP_MODE_ALGO_AEC_EXT: + case MAX32664C_OP_MODE_ALGO_AGC_EXT: + k_msgq_get(&data->ext_report_queue, &data->ext, K_NO_WAIT); + return 0; +#else + case MAX32664C_OP_MODE_ALGO_AEC: + case MAX32664C_OP_MODE_ALGO_AGC: + k_msgq_get(&data->report_queue, &data->report, K_NO_WAIT); + return 0; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + /* Raw data are reported with normal and extended algorithms so we need to fetch them too */ + case MAX32664C_OP_MODE_RAW: + k_msgq_get(&data->raw_report_queue, &data->raw, K_NO_WAIT); + return 0; + default: + return -ENOTSUP; + } +} + +static int max32664c_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct max32664c_data *data = dev->data; + + switch ((int)chan) { + case SENSOR_CHAN_ACCEL_X: { + val->val1 = data->raw.acc.x; + break; + } + case SENSOR_CHAN_ACCEL_Y: { + val->val1 = data->raw.acc.y; + break; + } + case SENSOR_CHAN_ACCEL_Z: { + val->val1 = data->raw.acc.z; + break; + } + case SENSOR_CHAN_GREEN: { + val->val1 = data->raw.PPG1; + break; + } + case SENSOR_CHAN_IR: { + val->val1 = data->raw.PPG2; + break; + } + case SENSOR_CHAN_RED: { + val->val1 = data->raw.PPG3; + break; + } + case SENSOR_CHAN_MAX32664C_HEARTRATE: { +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + val->val1 = data->ext.hr; + val->val2 = data->ext.hr_confidence; +#else + val->val1 = data->report.hr; + val->val2 = data->report.hr_confidence; +#endif + break; + } + case SENSOR_CHAN_MAX32664C_RESPIRATION_RATE: { +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + val->val1 = data->ext.rr; + val->val2 = data->ext.rr_confidence; +#else + val->val1 = data->report.rr; + val->val2 = data->report.rr_confidence; +#endif + break; + } + case SENSOR_CHAN_MAX32664C_BLOOD_OXYGEN_SATURATION: { +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + val->val1 = data->ext.spo2_meas.value; + val->val2 = data->ext.spo2_meas.confidence; +#else + val->val1 = data->report.spo2_meas.value; + val->val2 = data->report.spo2_meas.confidence; +#endif + break; + } + case SENSOR_CHAN_MAX32664C_SKIN_CONTACT: { + val->val1 = data->report.scd_state; + break; + } + default: { + LOG_ERR("Channel %u not supported!", chan); + return -ENOTSUP; + } + } + + return 0; +} + +static int max32664c_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + int err; + uint8_t tx[5]; + uint8_t rx; + struct max32664c_data *data = dev->data; + + err = 0; + + switch ((int)attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: { + break; + } + case SENSOR_ATTR_MAX32664C_HEIGHT: { + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x06; + tx[3] = (val->val1 & 0xFF00) >> 8; + tx[4] = val->val1 & 0x00FF; + if (max32664c_i2c_transmit(dev, tx, 5, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set height!"); + return -EINVAL; + } + + break; + } + case SENSOR_ATTR_MAX32664C_WEIGHT: { + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x07; + tx[3] = (val->val1 & 0xFF00) >> 8; + tx[4] = val->val1 & 0x00FF; + if (max32664c_i2c_transmit(dev, tx, 5, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set weight!"); + return -EINVAL; + } + + break; + } + case SENSOR_ATTR_MAX32664C_AGE: { + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x08; + tx[3] = val->val1 & 0x00FF; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set age!"); + return -EINVAL; + } + + break; + } + case SENSOR_ATTR_MAX32664C_GENDER: { + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x08; + tx[3] = val->val1 & 0x00FF; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set gender!"); + return -EINVAL; + } + + break; + } + case SENSOR_ATTR_SLOPE_DUR: { + data->motion_time = val->val1; + break; + } + case SENSOR_ATTR_SLOPE_TH: { + data->motion_threshold = val->val1; + break; + } + case SENSOR_ATTR_CONFIGURATION: { + switch ((int)chan) { + case SENSOR_CHAN_GREEN: { + data->led_current[0] = val->val1 & 0xFF; + break; + } + case SENSOR_CHAN_IR: { + data->led_current[1] = val->val1 & 0xFF; + break; + } + case SENSOR_CHAN_RED: { + data->led_current[2] = val->val1 & 0xFF; + break; + } + default: { + LOG_ERR("Channel %u not supported for setting attribute!", (int)chan); + return -ENOTSUP; + } + } + break; + } + case SENSOR_ATTR_MAX32664C_OP_MODE: { + switch (val->val1) { + case MAX32664C_OP_MODE_ALGO_AEC: { +#ifndef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + err = max32664c_set_mode_algo(dev, MAX32664C_OP_MODE_ALGO_AEC, val->val2, + false); +#else + return -EINVAL; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + break; + } + case MAX32664C_OP_MODE_ALGO_AEC_EXT: { +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + err = max32664c_set_mode_algo(dev, MAX32664C_OP_MODE_ALGO_AEC, val->val2, + true); +#else + return -EINVAL; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + break; + } + case MAX32664C_OP_MODE_ALGO_AGC: { +#ifndef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + err = max32664c_set_mode_algo(dev, MAX32664C_OP_MODE_ALGO_AGC, val->val2, + false); +#else + return -EINVAL; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + break; + } + case MAX32664C_OP_MODE_ALGO_AGC_EXT: { +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + err = max32664c_set_mode_algo(dev, MAX32664C_OP_MODE_ALGO_AGC, val->val2, + true); +#else + return -EINVAL; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + break; + } + case MAX32664C_OP_MODE_RAW: { + err = max32664c_set_mode_raw(dev); + break; + } + case MAX32664C_OP_MODE_SCD: { + err = max32664c_set_mode_scd(dev); + break; + } + case MAX32664C_OP_MODE_WAKE_ON_MOTION: { + err = max32664c_set_mode_wake_on_motion(dev); + break; + } + case MAX32664C_OP_MODE_EXIT_WAKE_ON_MOTION: { + err = max32664c_exit_mode_wake_on_motion(dev); + break; + } + case MAX32664C_OP_MODE_STOP_ALGO: { + err = max32664c_stop_algo(dev); + break; + } + case MAX32664C_OP_MODE_IDLE: { + err = max32664c_disable_sensors(dev); + break; + } + default: { + LOG_ERR("Unsupported sensor operation mode"); + return -ENOTSUP; + } + } + + break; + } + default: { + LOG_ERR("Unsupported sensor attribute!"); + return -ENOTSUP; + } + } + + return err; +} + +static int max32664c_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + struct max32664c_data *data = dev->data; + + switch ((int)attr) { + case SENSOR_ATTR_MAX32664C_OP_MODE: { + val->val1 = data->op_mode; + val->val2 = 0; + break; + } + case SENSOR_ATTR_CONFIGURATION: { + switch ((int)chan) { + case SENSOR_CHAN_GREEN: { + val->val1 = data->led_current[0]; + break; + } + case SENSOR_CHAN_IR: { + val->val1 = data->led_current[1]; + break; + } + case SENSOR_CHAN_RED: { + val->val1 = data->led_current[2]; + break; + } + default: { + LOG_ERR("Channel %u not supported for getting attribute!", (int)chan); + return -ENOTSUP; + } + } + break; + } + default: { + LOG_ERR("Unsupported sensor attribute!"); + return -ENOTSUP; + } + } + + return 0; +} + +static DEVICE_API(sensor, max32664c_driver_api) = { + .attr_set = max32664c_attr_set, + .attr_get = max32664c_attr_get, + .sample_fetch = max32664c_sample_fetch, + .channel_get = max32664c_channel_get, +}; + +static int max32664c_init(const struct device *dev) +{ + uint8_t tx[2]; + uint8_t rx[4]; + const struct max32664c_config *config = dev->config; + struct max32664c_data *data = dev->data; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C not ready"); + return -ENODEV; + } + + gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT); + gpio_pin_configure_dt(&config->mfio_gpio, GPIO_OUTPUT); + + /* Put the hub into application mode */ + LOG_DBG("Set app mode"); + gpio_pin_set_dt(&config->reset_gpio, false); + k_msleep(20); + + gpio_pin_set_dt(&config->mfio_gpio, true); + k_msleep(20); + + /* Wait for 50 ms (switch into app mode) + 1500 ms (initialization) */ + /* (see page 17 of the User Guide) */ + gpio_pin_set_dt(&config->reset_gpio, true); + k_msleep(1600); + + /* Read the device mode */ + tx[0] = 0x02; + tx[1] = 0x00; + if (max32664c_i2c_transmit(dev, tx, 2, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + data->op_mode = rx[1]; + LOG_DBG("Mode: %x ", data->op_mode); + if (data->op_mode != 0) { + return -EINVAL; + } + + /* Read the firmware version */ + tx[0] = 0xFF; + tx[1] = 0x03; + if (max32664c_i2c_transmit(dev, tx, 2, rx, 4, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + memcpy(data->hub_ver, &rx[1], 3); + + LOG_DBG("Version: %d.%d.%d", data->hub_ver[0], data->hub_ver[1], data->hub_ver[2]); + + if (max32664c_check_sensors(dev)) { + return -EINVAL; + } + + if (max32664c_init_hub(dev)) { + return -EINVAL; + } + +#ifdef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_msgq_init(&data->raw_report_queue, data->raw_report_queue_buffer, + sizeof(struct max32664c_raw_report_t), + sizeof(data->raw_report_queue_buffer) / sizeof(struct max32664c_raw_report_t)); + + k_msgq_init(&data->scd_report_queue, data->scd_report_queue_buffer, + sizeof(struct max32664c_scd_report_t), + sizeof(data->scd_report_queue_buffer) / sizeof(struct max32664c_scd_report_t)); + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + k_msgq_init(&data->ext_report_queue, data->ext_report_queue_buffer, + sizeof(struct max32664c_ext_report_t), + sizeof(data->ext_report_queue_buffer) / sizeof(struct max32664c_ext_report_t)); +#else + k_msgq_init(&data->report_queue, data->report_queue_buffer, + sizeof(struct max32664c_report_t), + sizeof(data->report_queue_buffer) / sizeof(struct max32664c_report_t)); +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int max32664c_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: { + break; + } + case PM_DEVICE_ACTION_SUSPEND: { + const struct max32664c_config *config = dev->config; + + /* Pulling MFIO high will cause the hub to enter sleep mode */ + gpio_pin_set_dt(&config->mfio_gpio, true); + k_msleep(20); + break; + } + case PM_DEVICE_ACTION_TURN_OFF: { + uint8_t rx; + uint8_t tx[3]; + + /* Send a shut down command */ + /* NOTE: Toggling RSTN is needed to wake the device */ + tx[0] = 0x01; + tx[1] = 0x00; + tx[2] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + break; + } + case PM_DEVICE_ACTION_TURN_ON: { + /* Toggling RSTN is needed to turn the device on */ + max32664c_init(dev); + break; + } + default: { + return -ENOTSUP; + } + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + +#define MAX32664C_INIT(inst) \ + static struct max32664c_data max32664c_data_##inst; \ + \ + static const struct max32664c_config max32664c_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios), \ + .mfio_gpio = GPIO_DT_SPEC_INST_GET(inst, mfio_gpios), \ + .spo2_calib = DT_INST_PROP(inst, spo2_calib), \ + .hr_config = DT_INST_PROP(inst, hr_config), \ + .spo2_config = DT_INST_PROP(inst, spo2_config), \ + .use_max86141 = DT_INST_PROP(inst, use_max86141), \ + .use_max86161 = DT_INST_PROP(inst, use_max86161), \ + .motion_time = DT_INST_PROP(inst, motion_time), \ + .motion_threshold = DT_INST_PROP(inst, motion_threshold), \ + .min_integration_time_idx = DT_INST_ENUM_IDX(inst, min_integration_time), \ + .min_sampling_rate_idx = DT_INST_ENUM_IDX(inst, min_sampling_rate), \ + .max_integration_time_idx = DT_INST_ENUM_IDX(inst, max_integration_time), \ + .max_sampling_rate_idx = DT_INST_ENUM_IDX(inst, max_sampling_rate), \ + .report_period = DT_INST_PROP(inst, report_period), \ + .led_current = DT_INST_PROP(inst, led_current), \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, max32664c_pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, max32664c_init, PM_DEVICE_DT_INST_GET(inst), \ + &max32664c_data_##inst, &max32664c_config_##inst, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &max32664c_driver_api) + +DT_INST_FOREACH_STATUS_OKAY(MAX32664C_INIT) diff --git a/drivers/sensor/adi/max32664c/max32664c.h b/drivers/sensor/adi/max32664c/max32664c.h new file mode 100644 index 0000000000000..facca74416dec --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +#define MAX32664C_BIT_STATUS_NO_ERR 1 +#define MAX32664C_BIT_STATUS_DATA_RDY 3 +#define MAX32664C_BIT_STATUS_OUT_OVFL 4 +#define MAX32664C_BIT_STATUS_IN_OVFL 5 +#define MAX32664C_BIT_STATUS_BUSY 6 + +#define MAX32664C_DEFAULT_CMD_DELAY 10 + +/** @brief Output formats of the sensor hub. + */ +enum max32664c_output_format { + MAX32664C_OUT_PAUSE, + MAX32664C_OUT_SENSOR_ONLY, + MAX32664C_OUT_ALGORITHM_ONLY, + MAX32664C_OUT_ALGO_AND_SENSOR, +}; + +/** @brief Skin contact detection states. + * @note The SCD states are only available when the SCD only mode is enabled. + */ +enum max32664c_scd_states { + MAX32664C_SCD_STATE_UNKNOWN, + MAX32664C_SCD_STATE_OFF_SKIN, + MAX32664C_SCD_STATE_ON_OBJECT, + MAX32664C_SCD_STATE_ON_SKIN, +}; + +/** @brief LED current structure. + */ +struct max32664c_led_current_t { + uint8_t adj_flag; + uint16_t adj_val; +} __packed; + +/** @brief SpO2 measurement result structure. + */ +struct max32664c_spo2_meas_t { + uint8_t confidence; + uint16_t value; + uint8_t complete; + uint8_t low_signal_quality; + uint8_t motion; + uint8_t low_pi; + uint8_t unreliable_r; + uint8_t state; +} __packed; + +/** @brief Extended SpO2 measurement result structure. + */ +struct max32664c_ext_spo2_meas_t { + uint8_t confidence; + uint16_t value; + uint8_t valid_percent; + uint8_t low_signal_flag; + uint8_t motion_flag; + uint8_t low_pi_flag; + uint8_t unreliable_r_flag; + uint8_t state; +} __packed; + +/** @brief Raw data structure, reported by the sensor hub. + */ +struct max32664c_raw_report_t { + uint32_t PPG1: 24; + uint32_t PPG2: 24; + uint32_t PPG3: 24; + uint32_t PPG4: 24; + uint32_t PPG5: 24; + uint32_t PPG6: 24; + struct max32664c_acc_data_t acc; +} __packed; + +/** @brief SCD only data structure, reported by the sensor hub. + */ +struct max32664c_scd_report_t { + uint8_t scd_classifier; +} __packed; + +/** @brief Algorithm data structure, reported by the sensor hub. + */ +struct max32664c_report_t { + uint8_t op_mode; + uint16_t hr; + uint8_t hr_confidence; + uint16_t rr; + uint8_t rr_confidence; + uint8_t activity_class; + uint16_t r; + struct max32664c_spo2_meas_t spo2_meas; + uint8_t scd_state; +} __packed; + +/** @brief Extended algorithm data structure, reported by the sensor hub. + */ +struct max32664c_ext_report_t { + uint8_t op_mode; + uint16_t hr; + uint8_t hr_confidence; + uint16_t rr; + uint8_t rr_confidence; + uint8_t activity_class; + + uint32_t total_walk_steps; + uint32_t total_run_steps; + uint32_t total_energy_kcal; + uint32_t total_amr_kcal; + + struct max32664c_led_current_t led_current_adj1; + struct max32664c_led_current_t led_current_adj2; + struct max32664c_led_current_t led_current_adj3; + + uint8_t integration_time_adj_flag; + uint8_t requested_integration_time; + + uint8_t sampling_rate_adj_flag; + uint8_t requested_sampling_rate; + uint8_t requested_sampling_average; + + uint8_t hrm_afe_ctrl_state; + uint8_t is_high_motion_for_hrm; + + uint8_t scd_state; + + uint16_t r_value; + struct max32664c_ext_spo2_meas_t spo2_meas; + + uint8_t ibi_offset; + uint8_t unreliable_orientation_flag; + + uint8_t reserved[2]; +} __packed; + +/** @brief Device configuration structure. + */ +struct max32664c_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec reset_gpio; + +#ifdef CONFIG_MAX32664C_USE_INTERRUPT + const struct device *dev; + struct gpio_callback gpio_cb; + struct k_work interrupt_work; +#endif /* CONFIG_MAX32664C_USE_INTERRUPT */ + + struct gpio_dt_spec mfio_gpio; + + int32_t spo2_calib[3]; + uint16_t motion_time; + uint16_t motion_threshold; + + uint8_t hr_config[2]; + uint8_t spo2_config[2]; + uint8_t led_current[3]; /**< Initial LED current in mA */ + uint8_t min_integration_time_idx; + uint8_t min_sampling_rate_idx; + uint8_t max_integration_time_idx; + uint8_t max_sampling_rate_idx; + uint8_t report_period; /*< Samples report period */ + + bool use_max86141; + bool use_max86161; +}; + +/** @brief Device runtime data structure. + */ +struct max32664c_data { + struct max32664c_raw_report_t raw; + struct max32664c_scd_report_t scd; + struct max32664c_report_t report; + struct max32664c_ext_report_t ext; + + enum max32664c_device_mode op_mode; /**< Current device mode */ + + uint8_t motion_time; /**< Motion time in milliseconds */ + uint8_t motion_threshold; /**< Motion threshold in milli-g */ + uint8_t led_current[3]; /**< LED current in mA */ + uint8_t min_integration_time_idx; + uint8_t min_sampling_rate_idx; + uint8_t max_integration_time_idx; + uint8_t max_sampling_rate_idx; + uint8_t report_period; /*< Samples report period */ + uint8_t afe_id; + uint8_t accel_id; + uint8_t hub_ver[3]; + + /* Internal */ + struct k_thread thread; + k_tid_t thread_id; + bool is_thread_running; + +#ifdef CONFIG_MAX32664C_USE_STATIC_MEMORY + /** @brief This buffer is used to read all available messages from the sensor hub plus the + * status byte. The buffer size is defined by the CONFIG_MAX32664C_SAMPLE_BUFFER_SIZE + * Kconfig and the largest possible message. The buffer must contain enough space to store + * all available messages at every time because it is not possible to read a single message + * from the sensor hub. + */ +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + uint8_t max32664_i2c_buffer[(CONFIG_MAX32664C_SAMPLE_BUFFER_SIZE * + (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_ext_report_t))) + + 1]; +#else + uint8_t max32664_i2c_buffer[(CONFIG_MAX32664C_SAMPLE_BUFFER_SIZE * + (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_report_t))) + + 1]; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ +#else + uint8_t *max32664_i2c_buffer; +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_MAX32664C_THREAD_STACK_SIZE); + + struct k_msgq raw_report_queue; + struct k_msgq scd_report_queue; + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + struct k_msgq ext_report_queue; +#else + struct k_msgq report_queue; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + +#ifdef CONFIG_MAX32664C_USE_STATIC_MEMORY + uint8_t raw_report_queue_buffer[CONFIG_MAX32664C_QUEUE_SIZE * + sizeof(struct max32664c_raw_report_t)]; + uint8_t scd_report_queue_buffer[CONFIG_MAX32664C_QUEUE_SIZE * + sizeof(struct max32664c_scd_report_t)]; + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + uint8_t ext_report_queue_buffer[CONFIG_MAX32664C_QUEUE_SIZE * + (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_ext_report_t))]; +#else + uint8_t report_queue_buffer[CONFIG_MAX32664C_QUEUE_SIZE * + (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_report_t))]; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY*/ +}; + +/** @brief Enable / Disable the accelerometer. + * NOTE: This code is untested and may not work as expected. + * @param dev Pointer to device + * @param enable Enable / Disable + * @return 0 when successful + */ +int max32664c_acc_enable(const struct device *dev, bool enable); + +/** @brief Background worker for reading the sensor hub. + * @param dev Pointer to device + */ +void max32664c_worker(const struct device *dev); + +/** @brief Read / write data from / to the sensor hub. + * @param dev Pointer to device + * @param tx_buf Pointer to transmit buffer + * @param tx_len Length of transmit buffer + * @param rx_buf Pointer to receive buffer + * NOTE: The buffer must be large enough to store the response and the status byte! + * @param rx_len Length of the receive buffer + * @param delay Command delay (milliseconds) + * @return 0 when successful + */ +int max32664c_i2c_transmit(const struct device *dev, uint8_t *tx_buf, uint8_t tx_len, + uint8_t *rx_buf, uint32_t rx_len, uint16_t delay); + +/** @brief Run a basic initialization on the sensor hub. + * @param dev Pointer to device + * @return 0 when successful + */ +int max32664c_init_hub(const struct device *dev); + +#if CONFIG_MAX32664C_USE_INTERRUPT +/** @brief Initialize the interrupt support for the sensor hub. + * @param dev Pointer to device + * @return 0 when successful + */ +int max32664c_init_interrupt(const struct device *dev); +#endif /* CONFIG_MAX32664C_USE_INTERRUPT */ diff --git a/drivers/sensor/adi/max32664c/max32664c_acc.c b/drivers/sensor/adi/max32664c/max32664c_acc.c new file mode 100644 index 0000000000000..1b8dfc1b07d1c --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c_acc.c @@ -0,0 +1,58 @@ +/* + * External accelerometer driver for the MAX32664C biometric sensor hub. + * + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "max32664c.h" + +LOG_MODULE_REGISTER(maxim_max32664c_acc, CONFIG_SENSOR_LOG_LEVEL); + +int max32664c_acc_enable(const struct device *dev, bool enable) +{ + uint8_t tx[4]; + uint8_t rx; + + tx[0] = 0x44; + tx[1] = 0x04; + tx[2] = enable; + +#if CONFIG_MAX32664C_USE_EXTERNAL_ACC + tx[3] = 1; +#else + tx[3] = 0; +#endif /* CONFIG_MAX32664C_USE_EXTERNAL_ACC */ + + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, 20)) { + return -EINVAL; + } + + return 0; +} + +#ifdef CONFIG_MAX32664C_USE_EXTERNAL_ACC +int max32664c_acc_fill_fifo(const struct device *dev, struct max32664c_acc_data_t *data, + uint8_t length) +{ + uint8_t tx[2 + 16 * sizeof(struct max32664c_acc_data_t)]; + uint8_t rx; + + if (length > 16) { + LOG_ERR("Length exceeds maximum of 16 samples!"); + return -EINVAL; + } + + tx[0] = 0x14; + tx[1] = 0x00; + memcpy(&tx[2], data, length * sizeof(struct max32664c_acc_data_t)); + + if (max32664c_i2c_transmit(dev, tx, 2 + (length * sizeof(struct max32664c_acc_data_t)), &rx, + 1, 20)) { + return -EINVAL; + } + + return 0; +} +#endif /* CONFIG_MAX32664C_USE_EXTERNAL_ACC */ diff --git a/drivers/sensor/adi/max32664c/max32664c_bl.c b/drivers/sensor/adi/max32664c/max32664c_bl.c new file mode 100644 index 0000000000000..147c9aefe3bdf --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c_bl.c @@ -0,0 +1,383 @@ +/* + * I2C firmware loader for the MAX32664C biometric sensor hub. + * + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "max32664c.h" + +#define MAX32664C_FW_PAGE_SIZE 8192 +#define MAX32664C_FW_UPDATE_CRC_SIZE 16 +#define MAX32664C_FW_UPDATE_WRITE_SIZE (MAX32664C_FW_PAGE_SIZE + MAX32664C_FW_UPDATE_CRC_SIZE) +#define MAX32664C_DEFAULT_CMD_DELAY_MS 10 +#define MAX32664C_PAGE_WRITE_DELAY_MS 680 + +static uint8_t max32664c_fw_init_vector[11]; +static uint8_t max32664c_fw_auth_vector[16]; + +LOG_MODULE_REGISTER(max32664_loader, CONFIG_SENSOR_LOG_LEVEL); + +/** @brief Read / write bootloader data from / to the sensor hub. + * @param dev Pointer to device + * @param tx_buf Pointer to transmit buffer + * @param tx_len Length of transmit buffer + * @param rx_buf Pointer to receive buffer + * NOTE: The buffer must be large enough to store the response and the status byte! + * @param rx_len Length of the receive buffer + * @return 0 when successful + */ +static int max32664c_bl_i2c_transmit(const struct device *dev, uint8_t *tx_buf, uint8_t tx_len, + uint8_t *rx_buf, uint8_t rx_len) +{ + int err; + const struct max32664c_config *config = dev->config; + + err = i2c_write_dt(&config->i2c, tx_buf, tx_len); + if (err) { + LOG_ERR("I2C transmission error %d!", err); + return err; + } + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + err = i2c_read_dt(&config->i2c, rx_buf, rx_len); + if (err) { + LOG_ERR("I2C transmission error %d!", err); + return err; + } + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + + /* Check the status byte for a valid transaction */ + LOG_DBG("Status: %u", rx_buf[0]); + if (rx_buf[0] != 0) { + return -EINVAL; + } + + return 0; +} + +/** @brief Read application data from the sensor hub. + * @param dev Pointer to device + * @param family Family byte + * @param index Index byte + * @param rx_buf Pointer to receive buffer + * NOTE: The buffer must be large enough to store the response and the status byte! + * @param rx_len Length of receive buffer + * @return 0 when successful + */ +static int max32664c_app_i2c_read(const struct device *dev, uint8_t family, uint8_t index, + uint8_t *rx_buf, uint8_t rx_len) +{ + uint8_t tx_buf[] = {family, index}; + const struct max32664c_config *config = dev->config; + + /* Wake the sensor hub before starting an I2C read (see page 17 of the user Guide) */ + gpio_pin_set_dt(&config->mfio_gpio, false); + k_usleep(300); + + i2c_write_dt(&config->i2c, tx_buf, sizeof(tx_buf)); + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + i2c_read_dt(&config->i2c, rx_buf, rx_len); + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + + gpio_pin_set_dt(&config->mfio_gpio, true); + + /* Check the status byte for a valid transaction */ + if (rx_buf[0] != 0) { + return -EINVAL; + } + + return 0; +} + +/** @brief Write a page of data into the sensor hub. + * @param dev Pointer to device + * @param data Pointer to firmware data + * @param offset Start address in the firmware data + * @return 0 when successful + */ +static int max32664c_bl_write_page(const struct device *dev, const uint8_t *data, uint32_t offset) +{ + int err; + uint8_t rx_buf; + uint8_t *tx_buf; + const struct max32664c_config *config = dev->config; + + /* Alloc memory for one page plus two command bytes */ + tx_buf = (uint8_t *)k_malloc(MAX32664C_FW_UPDATE_WRITE_SIZE + 2); + if (tx_buf == NULL) { + return -ENOMEM; + } + + /* Copy the data for one page into the buffer but leave space for the two command bytes */ + memcpy(&tx_buf[2], &data[offset], MAX32664C_FW_UPDATE_WRITE_SIZE); + + /* Set the two command bytes */ + tx_buf[0] = 0x80; + tx_buf[1] = 0x04; + + if (i2c_write_dt(&config->i2c, tx_buf, MAX32664C_FW_UPDATE_WRITE_SIZE + 2)) { + err = -EINVAL; + goto max32664c_bl_write_page_exit; + }; + k_msleep(MAX32664C_PAGE_WRITE_DELAY_MS); + err = i2c_read_dt(&config->i2c, &rx_buf, 1); + if (err) { + LOG_ERR("I2C read error %d!", err); + err = -EINVAL; + goto max32664c_bl_write_page_exit; + }; + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + + err = rx_buf; + + LOG_DBG("Write page status: %u", err); + +max32664c_bl_write_page_exit: + k_free(tx_buf); + return err; +} + +/** @brief Erase the application from the sensor hub. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_bl_erase_app(const struct device *dev) +{ + uint8_t tx_buf[2] = {0x80, 0x03}; + uint8_t rx_buf; + const struct max32664c_config *config = dev->config; + + if (i2c_write_dt(&config->i2c, tx_buf, sizeof(tx_buf))) { + return -EINVAL; + }; + + k_msleep(1500); + + if (i2c_read_dt(&config->i2c, &rx_buf, sizeof(rx_buf))) { + return -EINVAL; + }; + + k_msleep(MAX32664C_DEFAULT_CMD_DELAY_MS); + + /* Check the status byte for a valid transaction */ + if (rx_buf != 0) { + return -EINVAL; + } + + return 0; +} + +/** @brief Load the firmware into the hub. + * NOTE: See User Guide, Table 9 for the required steps. + * @param dev Pointer to device + * @param firmware Pointer to firmware data + * @param size Firmware size + * @return 0 when successful + */ +static int max32664c_bl_load_fw(const struct device *dev, const uint8_t *firmware, uint32_t size) +{ + uint8_t rx_buf; + uint8_t tx_buf[18] = {0}; + uint32_t page_offset; + + /* Get the number of pages from the firmware file (see User Guide page 53) */ + uint8_t num_pages = firmware[0x44]; + + LOG_INF("Loading firmware..."); + LOG_INF("\tSize: %u", size); + LOG_INF("\tPages: %u", num_pages); + + /* Set the number of pages */ + tx_buf[0] = 0x80; + tx_buf[1] = 0x02; + tx_buf[2] = 0x00; + tx_buf[3] = num_pages; + if (max32664c_bl_i2c_transmit(dev, tx_buf, 4, &rx_buf, 1)) { + return -EINVAL; + } + + if (rx_buf != 0) { + LOG_ERR("Failed to set number of pages: %d", rx_buf); + return -EINVAL; + } + + /* Get the initialization and authentication vectors from the firmware */ + /* (see User Guide page 53) */ + memcpy(max32664c_fw_init_vector, &firmware[0x28], sizeof(max32664c_fw_init_vector)); + memcpy(max32664c_fw_auth_vector, &firmware[0x34], sizeof(max32664c_fw_auth_vector)); + + /* Write the initialization vector */ + LOG_INF("\tWriting init vector..."); + tx_buf[0] = 0x80; + tx_buf[1] = 0x00; + memcpy(&tx_buf[2], max32664c_fw_init_vector, sizeof(max32664c_fw_init_vector)); + if (max32664c_bl_i2c_transmit(dev, tx_buf, 13, &rx_buf, 1)) { + return -EINVAL; + } + if (rx_buf != 0) { + LOG_ERR("Failed to set init vector: %d", rx_buf); + return -EINVAL; + } + + /* Write the authentication vector */ + LOG_INF("\tWriting auth vector..."); + tx_buf[0] = 0x80; + tx_buf[1] = 0x01; + memcpy(&tx_buf[2], max32664c_fw_auth_vector, sizeof(max32664c_fw_auth_vector)); + if (max32664c_bl_i2c_transmit(dev, tx_buf, 18, &rx_buf, 1)) { + return -EINVAL; + } + if (rx_buf != 0) { + LOG_ERR("Failed to set auth vector: %d", rx_buf); + return -EINVAL; + } + + /* Remove the old app from the hub */ + LOG_INF("\tRemove old app..."); + if (max32664c_bl_erase_app(dev)) { + return -EINVAL; + } + + /* Write the new firmware */ + LOG_INF("\tWriting new firmware..."); + page_offset = 0x4C; + for (uint8_t i = 0; i < num_pages; i++) { + uint8_t status; + + LOG_INF("\t\tPage: %d of %d", (i + 1), num_pages); + LOG_INF("\t\tOffset: 0x%x", page_offset); + status = max32664c_bl_write_page(dev, firmware, page_offset); + LOG_INF("\t\tStatus: %u", status); + if (status != 0) { + return -EINVAL; + } + + page_offset += MAX32664C_FW_UPDATE_WRITE_SIZE; + } + + LOG_INF("\tSuccessful!"); + + return max32664c_bl_leave(dev); +} + +int max32664c_bl_enter(const struct device *dev, const uint8_t *firmware, uint32_t size) +{ + uint8_t rx_buf[4] = {0}; + uint8_t tx_buf[3]; + const struct max32664c_config *config = dev->config; + + gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT); + gpio_pin_configure_dt(&config->mfio_gpio, GPIO_OUTPUT); + + /* Put the processor into bootloader mode */ + LOG_INF("Entering bootloader mode"); + gpio_pin_set_dt(&config->reset_gpio, false); + k_msleep(20); + + gpio_pin_set_dt(&config->mfio_gpio, false); + k_msleep(20); + + gpio_pin_set_dt(&config->reset_gpio, true); + k_msleep(200); + + /* Set bootloader mode */ + tx_buf[0] = 0x01; + tx_buf[1] = 0x00; + tx_buf[2] = 0x08; + if (max32664c_bl_i2c_transmit(dev, tx_buf, 3, rx_buf, 1)) { + return -EINVAL; + } + + /* Read the device mode */ + tx_buf[0] = 0x02; + tx_buf[1] = 0x00; + if (max32664c_bl_i2c_transmit(dev, tx_buf, 2, rx_buf, 2)) { + return -EINVAL; + } + + LOG_DBG("Mode: %x ", rx_buf[1]); + if (rx_buf[1] != 8) { + LOG_ERR("Device not in bootloader mode!"); + return -EINVAL; + } + + /* Read the bootloader information */ + tx_buf[0] = 0x81; + tx_buf[1] = 0x00; + if (max32664c_bl_i2c_transmit(dev, tx_buf, 2, rx_buf, 4)) { + return -EINVAL; + } + + LOG_INF("Version: %d.%d.%d", rx_buf[1], rx_buf[2], rx_buf[3]); + + /* Read the bootloader page size */ + tx_buf[0] = 0x81; + tx_buf[1] = 0x01; + if (max32664c_bl_i2c_transmit(dev, tx_buf, 2, rx_buf, 3)) { + return -EINVAL; + } + + LOG_INF("Page size: %u", (uint16_t)(rx_buf[1] << 8) | rx_buf[2]); + + return max32664c_bl_load_fw(dev, firmware, size); +} + +int max32664c_bl_leave(const struct device *dev) +{ + uint8_t hub_ver[3]; + uint8_t rx_buf[4] = {0}; + const struct max32664c_config *config = dev->config; + + gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT); + gpio_pin_configure_dt(&config->mfio_gpio, GPIO_OUTPUT); + + LOG_INF("Entering app mode"); + gpio_pin_set_dt(&config->reset_gpio, true); + gpio_pin_set_dt(&config->mfio_gpio, false); + k_msleep(2000); + + gpio_pin_set_dt(&config->reset_gpio, false); + k_msleep(5); + + gpio_pin_set_dt(&config->mfio_gpio, true); + k_msleep(15); + + gpio_pin_set_dt(&config->reset_gpio, true); + k_msleep(1700); + + /* Read the device mode */ + if (max32664c_app_i2c_read(dev, 0x02, 0x00, rx_buf, 2)) { + return -EINVAL; + } + + LOG_DBG("Mode: %x ", rx_buf[1]); + if (rx_buf[1] != 0) { + LOG_ERR("Device not in application mode!"); + return -EINVAL; + } + + /* Read the MCU type */ + if (max32664c_app_i2c_read(dev, 0xFF, 0x00, rx_buf, 2)) { + return -EINVAL; + } + + LOG_INF("MCU type: %u", rx_buf[1]); + + /* Read the firmware version */ + if (max32664c_app_i2c_read(dev, 0xFF, 0x03, rx_buf, 4)) { + return -EINVAL; + } + + memcpy(hub_ver, &rx_buf[1], 3); + + LOG_INF("Version: %d.%d.%d", hub_ver[0], hub_ver[1], hub_ver[2]); + + return 0; +} diff --git a/drivers/sensor/adi/max32664c/max32664c_init.c b/drivers/sensor/adi/max32664c/max32664c_init.c new file mode 100644 index 0000000000000..e65d2ec6af3c4 --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c_init.c @@ -0,0 +1,246 @@ +/* + * Initialization code for the MAX32664C biometric sensor hub. + * + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "max32664c.h" + +LOG_MODULE_REGISTER(maxim_max32664c_init, CONFIG_SENSOR_LOG_LEVEL); + +/** @brief Set the SpO2 calibration coefficients. + * NOTE: See page 10 of the SpO2 and Heart Rate User Guide for additional information. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_set_spo2_coeffs(const struct device *dev) +{ + const struct max32664c_config *config = dev->config; + + uint8_t tx[15]; + uint8_t rx; + + /* Write the calibration coefficients */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x00; + + /* Copy the A value (index 0) into the transmission buffer */ + memcpy(&tx[3], &config->spo2_calib[0], sizeof(int32_t)); + + /* Copy the B value (index 1) into the transmission buffer */ + memcpy(&tx[7], &config->spo2_calib[1], sizeof(int32_t)); + + /* Copy the C value (index 2) into the transmission buffer */ + memcpy(&tx[11], &config->spo2_calib[2], sizeof(int32_t)); + + return max32664c_i2c_transmit(dev, tx, sizeof(tx), &rx, sizeof(rx), + MAX32664C_DEFAULT_CMD_DELAY); +} + +/** @brief Write the default configuration to the sensor hub. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_write_config(const struct device *dev) +{ + uint8_t rx; + uint8_t tx[5]; + const struct max32664c_config *config = dev->config; + struct max32664c_data *data = dev->data; + + /* Write the default settings */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x13; + tx[3] = config->min_integration_time_idx; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not write minimum integration time!"); + return -EINVAL; + } + + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x14; + tx[3] = config->min_sampling_rate_idx; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not write minimum sampling rate!"); + return -EINVAL; + } + + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x15; + tx[3] = config->max_integration_time_idx; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not write maximum integration time!"); + return -EINVAL; + } + + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x16; + tx[3] = config->max_sampling_rate_idx; + if (max32664c_i2c_transmit(dev, tx, 4, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not write maximum sampling rate!"); + return -EINVAL; + } + + tx[0] = 0x10; + tx[1] = 0x02; + tx[2] = config->report_period; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set report period!"); + return -EINVAL; + } + + /* Configure WHRM */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x17; + tx[3] = config->hr_config[0]; + tx[4] = config->hr_config[1]; + LOG_DBG("Configuring WHRM: 0x%02X%02X", tx[3], tx[4]); + if (max32664c_i2c_transmit(dev, tx, 5, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not configure WHRM!"); + return -EINVAL; + } + + /* Configure SpO2 */ + tx[0] = 0x50; + tx[1] = 0x07; + tx[2] = 0x18; + tx[3] = config->spo2_config[0]; + tx[4] = config->spo2_config[1]; + LOG_DBG("Configuring SpO2: 0x%02X%02X", tx[3], tx[4]); + if (max32664c_i2c_transmit(dev, tx, 5, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not configure SpO2!"); + return -EINVAL; + } + + /* Set the interrupt threshold */ + tx[0] = 0x10; + tx[1] = 0x01; + tx[2] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 3, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not set interrupt threshold!"); + return -EINVAL; + } + + if (max32664c_set_spo2_coeffs(dev)) { + LOG_ERR("Can not set SpO2 calibration coefficients!"); + return -EINVAL; + } + + data->motion_time = config->motion_time; + data->motion_threshold = config->motion_threshold; + memcpy(data->led_current, config->led_current, sizeof(data->led_current)); + + return 0; +} + +/** @brief Read the configuration from the sensor hub. + * @param dev Pointer to device + * @return 0 when successful + */ +static int max32664c_read_config(const struct device *dev) +{ + uint8_t tx[3]; + uint8_t rx[2]; + struct max32664c_data *data = dev->data; + + tx[0] = 0x11; + tx[1] = 0x02; + if (max32664c_i2c_transmit(dev, tx, 2, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not read report period!"); + return -EINVAL; + } + data->report_period = rx[1]; + + tx[0] = 0x51; + tx[1] = 0x07; + tx[2] = 0x13; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not read minimum integration time!"); + return -EINVAL; + } + data->min_integration_time_idx = rx[1]; + + tx[0] = 0x51; + tx[1] = 0x07; + tx[2] = 0x14; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not read minimum sampling rate!"); + return -EINVAL; + } + data->min_sampling_rate_idx = rx[1]; + + tx[0] = 0x51; + tx[1] = 0x07; + tx[2] = 0x15; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not read maximum integration time!"); + return -EINVAL; + } + data->max_integration_time_idx = rx[1]; + + tx[0] = 0x51; + tx[1] = 0x07; + tx[2] = 0x16; + if (max32664c_i2c_transmit(dev, tx, 3, rx, 2, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not read maximum sampling rate!"); + return -EINVAL; + } + data->max_sampling_rate_idx = rx[1]; + + return 0; +} + +int max32664c_init_hub(const struct device *dev) +{ + struct max32664c_data *data = dev->data; + + LOG_DBG("Initialize sensor hub"); + + if (max32664c_write_config(dev)) { + LOG_ERR("Can not write default configuration!"); + return -EINVAL; + } + + if (max32664c_read_config(dev)) { + LOG_ERR("Can not read configuration!"); + return -EINVAL; + } + + data->is_thread_running = true; + data->thread_id = k_thread_create(&data->thread, data->thread_stack, + K_THREAD_STACK_SIZEOF(data->thread_stack), + (k_thread_entry_t)max32664c_worker, (void *)dev, NULL, + NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_NO_WAIT); + k_thread_suspend(data->thread_id); + k_thread_name_set(data->thread_id, "max32664c_worker"); + + LOG_DBG("Initial configuration:"); + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + LOG_DBG("\tUsing dynamic memory for queues and buffers"); +#else + LOG_DBG("\tUsing static memory for queues and buffers"); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + LOG_DBG("\tUsing extended reports"); +#else + LOG_DBG("\tUsing normal reports"); +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS*/ + + LOG_DBG("\tReport period: %u", data->report_period); + LOG_DBG("\tMinimum integration time: %u", data->min_integration_time_idx); + LOG_DBG("\tMinimum sampling rate: %u", data->min_sampling_rate_idx); + LOG_DBG("\tMaximum integration time: %u", data->max_integration_time_idx); + LOG_DBG("\tMaximum sampling rate: %u", data->max_sampling_rate_idx); + + return 0; +} diff --git a/drivers/sensor/adi/max32664c/max32664c_interrupt.c b/drivers/sensor/adi/max32664c/max32664c_interrupt.c new file mode 100644 index 0000000000000..492cdf3e639db --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c_interrupt.c @@ -0,0 +1,80 @@ +/* + * Trigger code for the MAX32664C biometric sensor hub. + * + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "max32664c.h" + +LOG_MODULE_REGISTER(maxim_max32664c_interrupt, CONFIG_SENSOR_LOG_LEVEL); + +#ifdef CONFIG_MAX32664C_USE_INTERRUPT +static void max32664c_interrupt_worker(struct k_work *p_work) +{ + struct max32664c_data *data = CONTAINER_OF(p_work, struct max32664c_data, interrupt_work); + + /* TODO */ +} + +static void max32664c_gpio_callback_handler(const struct device *p_port, struct gpio_callback *p_cb, + gpio_port_pins_t pins) +{ + ARG_UNUSED(pins); + ARG_UNUSED(p_port); + + struct max32664c_data *data = CONTAINER_OF(p_cb, struct max32664c_data, gpio_cb); + + k_work_submit(&data->interrupt_work); +} + +int max32664c_init_interrupt(const struct device *dev) +{ + LOG_DBG("\tUsing MFIO interrupt mode"); + + int err; + uint8_t tx[2]; + uint8_t rx; + struct max32664c_data *data = dev->data; + const struct max32664c_config *config = dev->config; + + LOG_DBG("Configure interrupt pin"); + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("GPIO not ready!"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (err < 0) { + LOG_ERR("Failed to configure GPIO! Error: %u", err); + return err; + } + + err = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_FALLING); + if (err < 0) { + LOG_ERR("Failed to configure interrupt! Error: %u", err); + return err; + } + + gpio_init_callback(&data->gpio_cb, max32664c_gpio_callback_handler, + BIT(config->int_gpio.pin)); + + err = gpio_add_callback_dt(&config->int_gpio, &data->gpio_cb); + if (err < 0) { + LOG_ERR("Failed to add GPIO callback! Error: %u", err); + return err; + } + + data->interrupt_work.handler = max32664c_interrupt_worker; + + tx[0] = 0xB8; + tx[1] = 0x01; + if (max32664c_i2c_transmit(dev, tx, 2, &rx, 1, MAX32664C_DEFAULT_CMD_DELAY)) { + LOG_ERR("Can not enable interrupt mode!"); + return -EINVAL; + } + + return 0; +} +#endif /* CONFIG_MAX32664C_USE_INTERRUPT */ diff --git a/drivers/sensor/adi/max32664c/max32664c_worker.c b/drivers/sensor/adi/max32664c/max32664c_worker.c new file mode 100644 index 0000000000000..4943c62191909 --- /dev/null +++ b/drivers/sensor/adi/max32664c/max32664c_worker.c @@ -0,0 +1,369 @@ +/* + * Background worker for the MAX32664C biometric sensor hub. + * + * Copyright (c) 2025, Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "max32664c.h" + +LOG_MODULE_REGISTER(maxim_max32664c_worker, CONFIG_SENSOR_LOG_LEVEL); + +/** @brief Read the status from the sensor hub. + * NOTE: Table 7 Sensor Hub Status Byte + * @param dev Pointer to device + * @param status Pointer to status byte + * @param i2c_error Pointer to I2C error byte + * @return 0 when successful, otherwise an error code + */ +static int max32664c_get_hub_status(const struct device *dev, uint8_t *status, uint8_t *i2c_error) +{ + uint8_t tx[2] = {0x00, 0x00}; + uint8_t rx[2]; + + if (max32664c_i2c_transmit(dev, tx, sizeof(tx), rx, sizeof(rx), + MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + *i2c_error = rx[0]; + *status = rx[1]; + + return 0; +} + +/** @brief Read the FIFO sample count. + * @param dev Pointer to device + * @param fifo Pointer to FIFO count + */ +static int max32664c_get_fifo_count(const struct device *dev, uint8_t *fifo) +{ + uint8_t tx[2] = {0x12, 0x00}; + uint8_t rx[2]; + + if (max32664c_i2c_transmit(dev, tx, sizeof(tx), rx, sizeof(rx), + MAX32664C_DEFAULT_CMD_DELAY)) { + return -EINVAL; + } + + *fifo = rx[1]; + + return rx[0]; +} + +/** @brief Push a item into the message queue. + * @param msgq Pointer to message queue + * @param data Pointer to data to push + */ +static void max32664c_push_to_queue(struct k_msgq *msgq, const void *data) +{ + while (k_msgq_put(msgq, data, K_NO_WAIT) != 0) { + k_msgq_purge(msgq); + } +} + +/** @brief Process the buffer to get the raw data from the sensor hub. + * @param dev Pointer to device + */ +static void max32664c_parse_and_push_raw(const struct device *dev) +{ + struct max32664c_data *data = dev->data; + struct max32664c_raw_report_t report; + + report.PPG1 = ((uint32_t)(data->max32664_i2c_buffer[1]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[2]) << 8) | + data->max32664_i2c_buffer[3]; + report.PPG2 = ((uint32_t)(data->max32664_i2c_buffer[4]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[5]) << 8) | + data->max32664_i2c_buffer[6]; + report.PPG3 = ((uint32_t)(data->max32664_i2c_buffer[7]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[8]) << 8) | + data->max32664_i2c_buffer[9]; + + /* PPG4 to 6 are used for PD2 */ + report.PPG4 = 0; + report.PPG5 = 0; + report.PPG6 = 0; + + report.acc.x = + ((int16_t)(data->max32664_i2c_buffer[19]) << 8) | data->max32664_i2c_buffer[20]; + report.acc.y = + ((int16_t)(data->max32664_i2c_buffer[21]) << 8) | data->max32664_i2c_buffer[22]; + report.acc.z = + ((int16_t)(data->max32664_i2c_buffer[23]) << 8) | data->max32664_i2c_buffer[24]; + + max32664c_push_to_queue(&data->raw_report_queue, &report); +} + +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS +/** @brief Process the buffer to get the extended report data from the sensor hub. + * @param dev Pointer to device + */ +static void max32664c_parse_and_push_ext_report(const struct device *dev) +{ + struct max32664c_data *data = dev->data; + struct max32664c_ext_report_t report; + + report.op_mode = data->max32664_i2c_buffer[25]; + report.hr = + (((uint16_t)(data->max32664_i2c_buffer[26]) << 8) | data->max32664_i2c_buffer[27]) / + 10; + report.hr_confidence = data->max32664_i2c_buffer[28]; + report.rr = + (((uint16_t)(data->max32664_i2c_buffer[29]) << 8) | data->max32664_i2c_buffer[30]) / + 10; + report.rr_confidence = data->max32664_i2c_buffer[31]; + report.activity_class = data->max32664_i2c_buffer[32]; + report.total_walk_steps = data->max32664_i2c_buffer[33] | + ((uint32_t)(data->max32664_i2c_buffer[34]) << 8) | + ((uint32_t)(data->max32664_i2c_buffer[35]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[36]) << 24); + report.total_run_steps = data->max32664_i2c_buffer[37] | + ((uint32_t)(data->max32664_i2c_buffer[38]) << 8) | + ((uint32_t)(data->max32664_i2c_buffer[39]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[40]) << 24); + report.total_energy_kcal = data->max32664_i2c_buffer[41] | + ((uint32_t)(data->max32664_i2c_buffer[42]) << 8) | + ((uint32_t)(data->max32664_i2c_buffer[43]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[44]) << 24); + report.total_amr_kcal = data->max32664_i2c_buffer[45] | + ((uint32_t)(data->max32664_i2c_buffer[46]) << 8) | + ((uint32_t)(data->max32664_i2c_buffer[47]) << 16) | + ((uint32_t)(data->max32664_i2c_buffer[48]) << 24); + report.led_current_adj1.adj_flag = data->max32664_i2c_buffer[49]; + report.led_current_adj1.adj_val = + (((uint16_t)(data->max32664_i2c_buffer[50]) << 8) | data->max32664_i2c_buffer[51]) / + 10; + report.led_current_adj2.adj_flag = data->max32664_i2c_buffer[52]; + report.led_current_adj2.adj_val = + (((uint16_t)(data->max32664_i2c_buffer[53]) << 8) | data->max32664_i2c_buffer[54]) / + 10; + report.led_current_adj3.adj_flag = data->max32664_i2c_buffer[55]; + report.led_current_adj3.adj_val = + (((uint16_t)(data->max32664_i2c_buffer[56]) << 8) | data->max32664_i2c_buffer[57]) / + 10; + report.integration_time_adj_flag = data->max32664_i2c_buffer[58]; + report.requested_integration_time = data->max32664_i2c_buffer[59]; + report.sampling_rate_adj_flag = data->max32664_i2c_buffer[60]; + report.requested_sampling_rate = data->max32664_i2c_buffer[61]; + report.requested_sampling_average = data->max32664_i2c_buffer[62]; + report.hrm_afe_ctrl_state = data->max32664_i2c_buffer[63]; + report.is_high_motion_for_hrm = data->max32664_i2c_buffer[64]; + report.scd_state = data->max32664_i2c_buffer[65]; + report.r_value = + (((uint16_t)(data->max32664_i2c_buffer[66]) << 8) | data->max32664_i2c_buffer[67]) / + 1000; + report.spo2_meas.confidence = data->max32664_i2c_buffer[68]; + report.spo2_meas.value = + (((uint16_t)(data->max32664_i2c_buffer[69]) << 8) | data->max32664_i2c_buffer[70]) / + 10; + report.spo2_meas.valid_percent = data->max32664_i2c_buffer[71]; + report.spo2_meas.low_signal_flag = data->max32664_i2c_buffer[72]; + report.spo2_meas.motion_flag = data->max32664_i2c_buffer[73]; + report.spo2_meas.low_pi_flag = data->max32664_i2c_buffer[74]; + report.spo2_meas.unreliable_r_flag = data->max32664_i2c_buffer[75]; + report.spo2_meas.state = data->max32664_i2c_buffer[76]; + report.ibi_offset = data->max32664_i2c_buffer[77]; + report.unreliable_orientation_flag = data->max32664_i2c_buffer[78]; + report.reserved[0] = data->max32664_i2c_buffer[79]; + report.reserved[1] = data->max32664_i2c_buffer[80]; + + max32664c_push_to_queue(&data->ext_report_queue, &report); +} +#else +/** @brief Process the buffer to get the report data from the sensor hub. + * @param dev Pointer to device + */ +static void max32664c_parse_and_push_report(const struct device *dev) +{ + struct max32664c_data *data = dev->data; + struct max32664c_report_t report; + + report.op_mode = data->max32664_i2c_buffer[25]; + report.hr = + (((uint16_t)(data->max32664_i2c_buffer[26]) << 8) | data->max32664_i2c_buffer[27]) / + 10; + report.hr_confidence = data->max32664_i2c_buffer[28]; + report.rr = + (((uint16_t)(data->max32664_i2c_buffer[29]) << 8) | data->max32664_i2c_buffer[30]) / + 10; + report.rr_confidence = data->max32664_i2c_buffer[31]; + report.activity_class = data->max32664_i2c_buffer[32]; + report.r = + (((uint16_t)(data->max32664_i2c_buffer[33]) << 8) | data->max32664_i2c_buffer[34]) / + 1000; + report.spo2_meas.confidence = data->max32664_i2c_buffer[35]; + report.spo2_meas.value = + (((uint16_t)(data->max32664_i2c_buffer[36]) << 8) | data->max32664_i2c_buffer[37]) / + 10; + report.spo2_meas.complete = data->max32664_i2c_buffer[38]; + report.spo2_meas.low_signal_quality = data->max32664_i2c_buffer[39]; + report.spo2_meas.motion = data->max32664_i2c_buffer[40]; + report.spo2_meas.low_pi = data->max32664_i2c_buffer[41]; + report.spo2_meas.unreliable_r = data->max32664_i2c_buffer[42]; + report.spo2_meas.state = data->max32664_i2c_buffer[43]; + report.scd_state = data->max32664_i2c_buffer[44]; + + max32664c_push_to_queue(&data->report_queue, &report); +} +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + +/** @brief Worker thread to read the sensor hub. + * This thread does the following: + * - It polls the sensor hub periodically for new results + * - If new messages are available it reads the number of samples + * - Then it reads all the samples to clear the FIFO. + * It's necessary to clear the complete FIFO because the sensor hub + * doesn´t support the reading of a single message and not clearing + * the FIFO can cause a FIFO overrun. + * - Extract the message data from the FIRST item from the FIFO and + * copy them into the right message structure + * - Put the message into a message queue + * @param dev Pointer to device + */ +void max32664c_worker(const struct device *dev) +{ + int err; + uint8_t fifo = 0; + uint8_t status = 0; + uint8_t i2c_error = 0; + struct max32664c_data *data = dev->data; + + LOG_DBG("Starting worker thread for device: %s", dev->name); + + while (data->is_thread_running) { + err = max32664c_get_hub_status(dev, &status, &i2c_error); + if (err) { + LOG_ERR("Failed to get hub status! Error: %d", err); + continue; + } + + if (!(status & (1 << MAX32664C_BIT_STATUS_DATA_RDY))) { + LOG_WRN("No data ready! Status: 0x%X", status); + k_msleep(100); + continue; + } + + err = max32664c_get_fifo_count(dev, &fifo); + if (err) { + LOG_ERR("Failed to get FIFO count! Error: %d", err); + continue; + } + + if (fifo == 0) { + LOG_DBG("No data available in the FIFO."); + continue; + } +#ifdef CONFIG_MAX32664C_USE_STATIC_MEMORY + else if (fifo > CONFIG_MAX32664C_SAMPLE_BUFFER_SIZE) { + LOG_ERR("FIFO count %u exceeds maximum buffer size %u!", + fifo, CONFIG_MAX32664C_SAMPLE_BUFFER_SIZE); + + /* TODO: Find a good way to clear the FIFO */ + continue; + } +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + size_t buffer_size = fifo * (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_ext_report_t)) + + 1; +#else + size_t buffer_size = fifo * (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_report_t)) + + 1; +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + + LOG_DBG("Allocating memory %u samples", fifo); + LOG_DBG("Allocating memory for the I2C buffer with size: %u", buffer_size); + data->max32664_i2c_buffer = (uint8_t *)k_malloc(buffer_size); + + if (data->max32664_i2c_buffer == NULL) { + LOG_ERR("Can not allocate memory for the I2C buffer!"); + continue; + } +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + uint8_t tx[2] = {0x12, 0x01}; + + switch (data->op_mode) { + case MAX32664C_OP_MODE_RAW: { + /* Get all samples to clear the FIFO */ + max32664c_i2c_transmit( + dev, tx, 2, data->max32664_i2c_buffer, + (fifo * (sizeof(struct max32664c_raw_report_t))) + + 1, + MAX32664C_DEFAULT_CMD_DELAY); + + if (data->max32664_i2c_buffer[0] != 0) { + break; + } + + max32664c_parse_and_push_raw(dev); + + break; + } +#ifdef CONFIG_MAX32664C_USE_EXTENDED_REPORTS + case MAX32664C_OP_MODE_ALGO_AEC_EXT: + case MAX32664C_OP_MODE_ALGO_AGC_EXT: { + + /* Get all samples to clear the FIFO */ + max32664c_i2c_transmit( + dev, tx, 2, data->max32664_i2c_buffer, + (fifo * (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_ext_report_t))) + + 1, + MAX32664C_DEFAULT_CMD_DELAY); + + if (data->max32664_i2c_buffer[0] != 0) { + break; + } + + max32664c_parse_and_push_raw(dev); + max32664c_parse_and_push_ext_report(dev); + + break; + } +#else + case MAX32664C_OP_MODE_ALGO_AEC: + case MAX32664C_OP_MODE_ALGO_AGC: { + + /* Get all samples to clear the FIFO */ + max32664c_i2c_transmit( + dev, tx, 2, data->max32664_i2c_buffer, + (fifo * (sizeof(struct max32664c_raw_report_t) + + sizeof(struct max32664c_report_t))) + + 1, + MAX32664C_DEFAULT_CMD_DELAY); + + if (data->max32664_i2c_buffer[0] != 0) { + break; + } + + max32664c_parse_and_push_raw(dev); + max32664c_parse_and_push_report(dev); + + break; + } +#endif /* CONFIG_MAX32664C_USE_EXTENDED_REPORTS */ + default: { + break; + } + } + + if (data->max32664_i2c_buffer[0] != 0) { + LOG_ERR("Can not read report! Status: 0x%X", + data->max32664_i2c_buffer[0]); + } + +#ifndef CONFIG_MAX32664C_USE_STATIC_MEMORY + k_free(data->max32664_i2c_buffer); +#endif /* CONFIG_MAX32664C_USE_STATIC_MEMORY */ + + k_msleep(100); + } +} diff --git a/drivers/sensor/bosch/bmi08x/CMakeLists.txt b/drivers/sensor/bosch/bmi08x/CMakeLists.txt index 0282cc73d2051..5899fedf05971 100644 --- a/drivers/sensor/bosch/bmi08x/CMakeLists.txt +++ b/drivers/sensor/bosch/bmi08x/CMakeLists.txt @@ -7,3 +7,12 @@ zephyr_library_sources(bmi08x_gyro.c) zephyr_library_sources(bmi08x.c) zephyr_library_sources_ifdef(CONFIG_BMI08X_ACCEL_TRIGGER bmi08x_accel_trigger.c) zephyr_library_sources_ifdef(CONFIG_BMI08X_GYRO_TRIGGER bmi08x_gyro_trigger.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API + bmi08x_bus.c + bmi08x_gyro_async.c + bmi08x_gyro_decoder.c + bmi08x_accel_async.c + bmi08x_accel_decoder.c +) +zephyr_library_sources_ifdef(CONFIG_BMI08X_GYRO_STREAM bmi08x_gyro_stream.c) +zephyr_library_sources_ifdef(CONFIG_BMI08X_ACCEL_STREAM bmi08x_accel_stream.c) diff --git a/drivers/sensor/bosch/bmi08x/Kconfig b/drivers/sensor/bosch/bmi08x/Kconfig index cbe40bf5c26e5..fc0a17baeda34 100644 --- a/drivers/sensor/bosch/bmi08x/Kconfig +++ b/drivers/sensor/bosch/bmi08x/Kconfig @@ -11,6 +11,8 @@ menuconfig BMI08X || $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_GYRO),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_ACCEL),spi) \ || $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_GYRO),spi) + select SPI_RTIO if SPI + select I2C_RTIO if I2C help Enable Bosch BMI08X inertial measurement unit that provides acceleration and angular rate measurements. @@ -19,7 +21,7 @@ if BMI08X choice BMI08X_ACCEL_TRIGGER_MODE prompt "Accelerometer trigger mode" - default BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD + default BMI08X_ACCEL_TRIGGER_NONE help Specify the type of triggering to be used by the driver. @@ -39,6 +41,13 @@ config BMI08X_ACCEL_TRIGGER_OWN_THREAD select BMI08X_ACCEL_TRIGGER endchoice +config BMI08X_ACCEL_STREAM + bool "Accelerometer Streaming Mode (FIFO)" + depends on !BMI08X_ACCEL_TRIGGER + depends on GPIO + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_BOSCH_BMI08X_ACCEL),int-gpios) + + config BMI08X_ACCEL_TRIGGER bool @@ -59,7 +68,6 @@ config BMI08X_ACCEL_THREAD_STACK_SIZE choice BMI08X_GYRO_TRIGGER_MODE prompt "Gyroscope trigger mode" default BMI08X_GYRO_TRIGGER_NONE - default BMI08X_GYRO_TRIGGER_GLOBAL_THREAD help Specify the type of triggering to be used by the driver. @@ -75,6 +83,12 @@ config BMI08X_GYRO_TRIGGER_OWN_THREAD select BMI08X_GYRO_TRIGGER endchoice +config BMI08X_GYRO_STREAM + bool "Gyroscope Streaming Mode (FIFO)" + depends on !BMI08X_GYRO_TRIGGER + depends on GPIO + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_BOSCH_BMI08X_GYRO),int-gpios) + config BMI08X_GYRO_TRIGGER bool diff --git a/drivers/sensor/bosch/bmi08x/bmi08x.h b/drivers/sensor/bosch/bmi08x/bmi08x.h index 83926126e4844..5aa4dd7a5779c 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x.h +++ b/drivers/sensor/bosch/bmi08x/bmi08x.h @@ -14,6 +14,8 @@ #include #include +#include "bmi08x_bus.h" + /* Accel Chip Id register */ #define BMI08X_REG_ACCEL_CHIP_ID 0x00 @@ -65,6 +67,15 @@ /* Sensor temperature LSB data register */ #define BMI08X_REG_TEMP_LSB 0x23 +/* Accel FIFO Length (low byte) */ +#define BMI08X_REG_ACCEL_FIFO_LEN_0 0x24 + +/* Accel FIFO Length (high byte) */ +#define BMI08X_REG_ACCEL_FIFO_LEN_1 0x25 + +/* Accel FIFO Data register */ +#define BMI08X_REG_ACCEL_FIFO_DATA 0x26 + /* Accel general purpose register 4*/ #define BMI08X_REG_ACCEL_GP_4 0x27 @@ -77,6 +88,18 @@ /* Accel range setting register */ #define BMI08X_REG_ACCEL_RANGE 0x41 +/* Accel FIFO Watermark (low byte) */ +#define BMI08X_REG_ACCEL_FIFO_WTM_0 0x46 + +/* Accel FIFO Watermark (high byte) */ +#define BMI08X_REG_ACCEL_FIFO_WTM_1 0x47 + +/* Accel FIFO Config (FIFO mode) */ +#define BMI08X_REG_ACCEL_FIFO_CONFIG_0 0x48 + +/* Accel FIFO Config (Interrupt enabling) */ +#define BMI08X_REG_ACCEL_FIFO_CONFIG_1 0x49 + /* Accel Interrupt pin 1 configuration register */ #define BMI08X_REG_ACCEL_INT1_IO_CONF 0x53 @@ -262,6 +285,9 @@ /* Gyro Interrupt status register */ #define BMI08X_REG_GYRO_INT_STAT_1 0x0A +/* FIFO Status register (Overrun and Frame counter) */ +#define BMI08X_REG_FIFO_STATUS 0x0E + /* Gyro Range register */ #define BMI08X_REG_GYRO_RANGE 0x0F @@ -283,9 +309,21 @@ /* Gyro Interrupt Map register */ #define BMI08X_REG_GYRO_INT3_INT4_IO_MAP 0x18 +/* FIFO Watermark enable */ +#define BMI08X_REG_GYRO_FIFO_WM_EN 0x1E + /* Gyro Self test register */ #define BMI08X_REG_GYRO_SELF_TEST 0x3C +/* FIFO Config register (FIFO Watermark) */ +#define BMI08X_REG_GYRO_FIFO_CONFIG_0 0x3D + +/* FIFO Config register (FIFO Mode) */ +#define BMI08X_REG_GYRO_FIFO_CONFIG_1 0x3E + +/* FIFO Data register */ +#define BMI08X_REG_GYRO_FIFO_DATA 0x3F + /* Gyro unique chip identifier */ #define BMI08X_GYRO_CHIP_ID 0x0F @@ -469,8 +507,9 @@ struct bmi08x_gyro_bus_io { struct bmi08x_accel_config { union bmi08x_bus bus; const struct bmi08x_accel_bus_io *api; -#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) struct gpio_dt_spec int_gpio; +#if defined(CONFIG_SENSOR_ASYNC_API) + struct bmi08x_rtio_bus rtio_bus; #endif #if defined(CONFIG_BMI08X_ACCEL_TRIGGER) || BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC uint8_t int1_map; @@ -488,8 +527,9 @@ struct bmi08x_accel_config { struct bmi08x_gyro_config { union bmi08x_bus bus; const struct bmi08x_gyro_bus_io *api; -#if defined(CONFIG_BMI08X_GYRO_TRIGGER) struct gpio_dt_spec int_gpio; +#if defined(CONFIG_SENSOR_ASYNC_API) + struct bmi08x_rtio_bus rtio_bus; #endif #if defined(CONFIG_BMI08X_GYRO_TRIGGER) || BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC uint8_t int3_4_map; @@ -500,11 +540,20 @@ struct bmi08x_gyro_config { }; struct bmi08x_accel_data { -#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) + const struct device *dev; +#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) || defined(CONFIG_SENSOR_ASYNC_API) struct gpio_callback gpio_cb; #endif uint16_t acc_sample[3]; uint16_t scale; /* micro m/s^2/lsb */ + uint16_t range; +#if defined(CONFIG_SENSOR_ASYNC_API) + struct { + struct rtio_iodev_sqe *iodev_sqe; + atomic_t state; + uint8_t fifo_wm; + } stream; +#endif #if defined(CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD) K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_BMI08X_ACCEL_THREAD_STACK_SIZE); @@ -512,7 +561,6 @@ struct bmi08x_accel_data { struct k_sem sem; #elif defined(CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD) struct k_work work; - const struct device *dev; #endif #ifdef CONFIG_BMI08X_ACCEL_TRIGGER @@ -523,11 +571,20 @@ struct bmi08x_accel_data { }; struct bmi08x_gyro_data { -#if defined(CONFIG_BMI08X_GYRO_TRIGGER) + const struct device *dev; +#if defined(CONFIG_BMI08X_GYRO_TRIGGER) || defined(CONFIG_SENSOR_ASYNC_API) struct gpio_callback gpio_cb; #endif uint16_t gyr_sample[3]; uint16_t scale; /* micro radians/s/lsb */ + uint16_t range; +#if defined(CONFIG_SENSOR_ASYNC_API) + struct { + struct rtio_iodev_sqe *iodev_sqe; + atomic_t state; + uint8_t fifo_wm; + } stream; +#endif #if defined(CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD) K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_BMI08X_GYRO_THREAD_STACK_SIZE); @@ -535,7 +592,6 @@ struct bmi08x_gyro_data { struct k_sem sem; #elif defined(CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD) struct k_work work; - const struct device *dev; #endif #ifdef CONFIG_BMI08X_GYRO_TRIGGER @@ -544,6 +600,62 @@ struct bmi08x_gyro_data { #endif /* CONFIG_BMI08X_GYRO_TRIGGER */ }; +struct bmi08x_accel_frame { + uint8_t header; + union { + struct { + uint16_t payload[3]; + } accel; + struct { + uint8_t skipped_frames; + } skip; + struct { + uint8_t time[3]; + } sensortime; + struct { + uint8_t change; + } fifo_config; + }; +} __packed; + +struct bmi08x_gyro_frame { + uint16_t payload[3]; +} __packed; + +struct bmi08x_accel_encoded_data { + struct { + uint64_t timestamp; + uint16_t range; + uint8_t chip_id; + bool has_accel; + bool is_streaming; + uint16_t fifo_len; + uint8_t sample_count; + uint16_t buf_len; + } header; + union { + uint16_t payload[3]; + uint8_t fifo[0]; /* Left as bytes since it can contain multiple frames */ + }; +}; + +struct bmi08x_gyro_encoded_data { + struct { + uint64_t timestamp; + uint16_t range; + bool has_gyro; + bool is_streaming; + uint8_t int_status; + uint8_t fifo_status; + uint8_t sample_count; + } header; + union { + struct bmi08x_gyro_frame frame; + struct bmi08x_gyro_frame fifo[0]; + } __packed; +}; + + /* common functions for accel and gyro */ int bmi08x_freq_to_odr_val(uint16_t freq_int, uint16_t freq_milli); int32_t bmi08x_range_to_reg_val(uint16_t range, const struct bmi08x_range *range_map, diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c index 6053638b0d4c8..e8f0eafa7141e 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c @@ -6,16 +6,21 @@ */ #include +#include #include #include #include #include #include #include +#include #define DT_DRV_COMPAT bosch_bmi08x_accel #include "bmi08x.h" #include "bmi08x_config_file.h" +#include "bmi08x_accel_async.h" +#include "bmi08x_accel_stream.h" +#include "bmi08x_accel_decoder.h" LOG_MODULE_REGISTER(BMI08X_ACCEL, CONFIG_SENSOR_LOG_LEVEL); @@ -320,6 +325,7 @@ static int bmi08x_acc_range_set(const struct device *dev, int32_t range) } data->scale = BMI08X_ACC_SCALE(range); + data->range = reg_val; return ret; } @@ -538,6 +544,10 @@ static DEVICE_API(sensor, bmi08x_api) = { .attr_set = bmi08x_attr_set, #ifdef CONFIG_BMI08X_ACCEL_TRIGGER .trigger_set = bmi08x_trigger_set_acc, +#endif +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = bmi08x_accel_async_submit, + .get_decoder = bmi08x_accel_decoder_get, #endif .sample_fetch = bmi08x_sample_fetch, .channel_get = bmi08x_channel_get, @@ -719,6 +729,14 @@ int bmi08x_accel_init(const struct device *dev) } #endif +#if defined(CONFIG_BMI08X_ACCEL_STREAM) + ret = bmi08x_accel_stream_init(dev); + if (ret < 0) { + LOG_ERR("Failed to init stream: %d", ret); + return ret; + } +#endif + return ret; } @@ -784,22 +802,44 @@ int bmi08x_accel_init(const struct device *dev) #define BMI08X_CREATE_INST(inst) \ \ + RTIO_DEFINE(bmi08x_accel_rtio_ctx_##inst, 16, 16); \ + \ + COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (I2C_DT_IODEV_DEFINE(bmi08x_accel_rtio_bus_##inst, \ + DT_DRV_INST(inst))), \ + (COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (SPI_DT_IODEV_DEFINE(bmi08x_accel_rtio_bus_##inst, \ + DT_DRV_INST(inst), \ + SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB)),\ + ()))); \ + \ IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_DATA_SYNC(inst);)) \ IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_DATA_SYNC_ODR(inst);)) \ IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_GYRO_DATA_SYNC_EN(inst);)) \ \ - static struct bmi08x_accel_data bmi08x_drv_##inst; \ + static struct bmi08x_accel_data bmi08x_drv_##inst = { \ + IF_ENABLED(CONFIG_BMI08X_ACCEL_STREAM, \ + (.stream.fifo_wm = DT_INST_PROP_OR(inst, fifo_watermark, 0),)) \ + }; \ + \ \ static const struct bmi08x_accel_config bmi08x_config_##inst = { \ COND_CODE_1(DT_INST_ON_BUS(inst, spi), (BMI08X_CONFIG_SPI(inst)), \ (BMI08X_CONFIG_I2C(inst))) \ .api = COND_CODE_1(DT_INST_ON_BUS(inst, spi), (&bmi08x_spi_api), \ (&bmi08x_i2c_api)), \ - IF_ENABLED(CONFIG_BMI08X_ACCEL_TRIGGER, \ - (.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),)) \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ BMI08X_ACCEL_TRIGGER_PINS(inst) \ .accel_hz = DT_INST_ENUM_IDX(inst, accel_hz) + 5, \ - .accel_fs = DT_INST_PROP(inst, accel_fs), BMI08X_DATA_SYNC_REG(inst)}; \ + .rtio_bus = { \ + .ctx = &bmi08x_accel_rtio_ctx_##inst, \ + .iodev = &bmi08x_accel_rtio_bus_##inst, \ + .type = COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (BMI08X_RTIO_BUS_TYPE_I2C), \ + (BMI08X_RTIO_BUS_TYPE_SPI)), \ + }, \ + .accel_fs = DT_INST_PROP(inst, accel_fs), BMI08X_DATA_SYNC_REG(inst) \ + }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, bmi08x_accel_pm_action); \ SENSOR_DEVICE_DT_INST_DEFINE(inst, bmi08x_accel_init, PM_DEVICE_DT_INST_GET(inst), \ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.c new file mode 100644 index 0000000000000..7eaa9dfdb22a2 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_accel +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_accel_stream.h" +#include "bmi08x_accel_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_ACCEL_ASYNC, CONFIG_SENSOR_LOG_LEVEL); + +static void bmi08x_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, int result, + void *arg) +{ + struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)arg; + + (void)rtio_flush_completion_queue(ctx); + if (result >= 0) { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } else { + rtio_iodev_sqe_err(iodev_sqe, result); + } +} + +static void bmi08x_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + uint32_t buf_len_req = sizeof(struct bmi08x_accel_encoded_data); + struct bmi08x_accel_encoded_data *edata; + uint32_t buf_len; + int err; + + err = rtio_sqe_rx_buf(iodev_sqe, buf_len_req, buf_len_req, (uint8_t **)&edata, &buf_len); + CHECKIF(err < 0 || buf_len < buf_len_req || !edata) { + LOG_ERR("Failed to get a read-buffer of size %u bytes", buf_len_req); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + bmi08x_accel_encode_header(dev, edata, false, 0); + + struct rtio_sqe *out_sqe; + struct rtio_sqe *complete_sqe; + const struct bmi08x_accel_config *config = dev->config; + + err = bmi08x_prep_reg_read_rtio_async(&config->rtio_bus, BMI08X_REG_ACCEL_X_LSB, + (uint8_t *)edata->payload, sizeof(edata->payload), + &out_sqe, true); + if (err < 0) { + LOG_ERR("Failed to perpare async read operation"); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + + complete_sqe = rtio_sqe_acquire(config->rtio_bus.ctx); + if (!complete_sqe) { + LOG_ERR("Failed to perpare async read operation"); + rtio_sqe_drop_all(config->rtio_bus.ctx); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + + rtio_sqe_prep_callback_no_cqe(complete_sqe, bmi08x_complete_result, iodev_sqe, (void *)dev); + rtio_submit(config->rtio_bus.ctx, 0); +} + +void bmi08x_accel_async_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) { + bmi08x_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_BMI08X_ACCEL_STREAM)) { + bmi08x_accel_stream_submit(dev, iodev_sqe); + } else { + LOG_ERR("Streaming not supported"); + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + } +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.h b/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.h new file mode 100644 index 0000000000000..241814fa39d2a --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_async.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_ASYNC_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_ASYNC_H_ + +#include +#include + +void bmi08x_accel_async_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_ASYNC_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.c new file mode 100644 index 0000000000000..767f2a6aca4c5 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_accel +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_accel_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_ACCEL_DECODER, CONFIG_SENSOR_LOG_LEVEL); + +enum bmi08x_accel_fifo_header { + BMI08X_ACCEL_FIFO_FRAME_ACCEL = 0x84, + BMI08X_ACCEL_FIFO_FRAME_SKIP = 0x40, + BMI08X_ACCEL_FIFO_FRAME_TIME = 0x44, + BMI08X_ACCEL_FIFO_FRAME_CONFIG = 0x48, + BMI08X_ACCEL_FIFO_FRAME_DROP = 0x50, + BMI08X_ACCEL_FIFO_FRAME_EMPTY = 0x80, +}; + +struct frame_len { + enum bmi08x_accel_fifo_header header; + uint8_t len; +} fifo_frame_len[] = { + {.header = BMI08X_ACCEL_FIFO_FRAME_ACCEL, .len = 7}, + {.header = BMI08X_ACCEL_FIFO_FRAME_SKIP, .len = 2}, + {.header = BMI08X_ACCEL_FIFO_FRAME_TIME, .len = 4}, + {.header = BMI08X_ACCEL_FIFO_FRAME_CONFIG, .len = 2}, + {.header = BMI08X_ACCEL_FIFO_FRAME_DROP, .len = 2}, + {.header = BMI08X_ACCEL_FIFO_FRAME_EMPTY, .len = 2}, +}; + +void bmi08x_accel_encode_header(const struct device *dev, struct bmi08x_accel_encoded_data *edata, + bool is_streaming, uint16_t buf_len) +{ + struct bmi08x_accel_data *data = dev->data; + uint64_t cycles; + + if (sensor_clock_get_cycles(&cycles) == 0) { + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); + } else { + edata->header.timestamp = 0; + } + edata->header.has_accel = true; + edata->header.range = data->range; + edata->header.chip_id = data->accel_chip_id; + edata->header.is_streaming = is_streaming; + edata->header.sample_count = is_streaming ? data->stream.fifo_wm : 1; + edata->header.buf_len = buf_len; +} + +static int bmi08x_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + const struct bmi08x_accel_encoded_data *edata = + (const struct bmi08x_accel_encoded_data *)buffer; + + if (!edata->header.has_accel || chan_spec.chan_idx != 0) { + return -ENODATA; + } + + if (chan_spec.chan_type != SENSOR_CHAN_ACCEL_XYZ) { + return -EINVAL; + } + + *frame_count = edata->header.sample_count; + return 0; +} + +static int bmi08x_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, + size_t *frame_size) +{ + if (chan_spec.chan_idx != 0 || chan_spec.chan_type != SENSOR_CHAN_ACCEL_XYZ) { + return -EINVAL; + } + + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; +} + +static inline void fixed_point_from_encoded_data(const uint16_t encoded_payload[3], uint8_t shift, + uint32_t fsr_value_g, q31_t output[3]) +{ + for (size_t i = 0 ; i < 3 ; i++) { + int64_t raw_value; + + raw_value = sign_extend_64(encoded_payload[i], 15); + raw_value = (raw_value * fsr_value_g << (31 - 5 - 15)) * SENSOR_G / 1000000; + + output[i] = raw_value; + } +} + +static inline int bmi08x_decode_one_shot(const struct bmi08x_accel_encoded_data *edata, + uint32_t *fit, struct sensor_three_axis_data *data_output) +{ + uint32_t fsr_value_g = (edata->header.chip_id == BMI085_ACCEL_CHIP_ID) ? 2 : 3; + + if (*fit != 0) { + return -ENODATA; + } + + /** Bits we need to represent the integer part of FSR in m/s2: + * - 2 - 3 G (19.6 - 29.4 m/s2) = 5 bits. + * - 4 - 6 G (39.2 - 58.8 m/s2) = 6 bits. + * - 8 - 12 G (78.4 - 117.6 m/s2) = 7 bits. + * - 16 - 24 G (156.8 235.2 m/s2) = 8 bits. + */ + data_output->shift = 5 + edata->header.range; + data_output->header.reading_count = 1; + data_output->header.base_timestamp_ns = edata->header.timestamp; + fixed_point_from_encoded_data(edata->payload, data_output->shift, fsr_value_g, + data_output->readings[0].values); + + return ++(*fit); +} + +static inline int fifo_get_frame_len(enum bmi08x_accel_fifo_header header) +{ + for (size_t i = 0 ; i < ARRAY_SIZE(fifo_frame_len) ; i++) { + if (header == fifo_frame_len[i].header) { + return fifo_frame_len[i].len; + } + } + return -EINVAL; +} + +static inline int bmi08x_decode_fifo(const struct bmi08x_accel_encoded_data *edata, uint32_t *fit, + uint16_t max_count, struct sensor_three_axis_data *data_output) +{ + uint8_t reading_count = 0; + uint32_t fsr_value_g = edata->header.chip_id == BMI085_ACCEL_CHIP_ID ? 2 : 3; + + if (*fit >= edata->header.buf_len) { + return -ENODATA; + } + + /** Bits we need to represent the integer part of FSR in m/s2: + * - 2 - 3 G (19.6 - 29.4 m/s2) = 5 bits. + * - 4 - 6 G (39.2 - 58.8 m/s2) = 6 bits. + * - 8 - 12 G (78.4 - 117.6 m/s2) = 7 bits. + * - 16 - 24 G (156.8 235.2 m/s2) = 8 bits. + */ + data_output->shift = 5 + edata->header.range; + data_output->header.reading_count = 0; + data_output->header.base_timestamp_ns = edata->header.timestamp; + + do { + uint8_t header_byte = edata->fifo[*fit] & 0xFC; + int frame_len = fifo_get_frame_len(header_byte); + + if (frame_len < 0) { + LOG_WRN("Invalid frame header: 0x%02X", header_byte); + return frame_len; + } + + if (header_byte == BMI08X_ACCEL_FIFO_FRAME_ACCEL && + *fit + frame_len <= edata->header.buf_len) { + const uint16_t *values = (const uint16_t *)&edata->fifo[*fit + 1]; + + fixed_point_from_encoded_data( + values, data_output->shift, fsr_value_g, + data_output->readings[reading_count].values); + reading_count++; + } + *fit += frame_len; + } while (*fit < edata->header.buf_len && reading_count < max_count); + + data_output->header.reading_count = reading_count; + return reading_count; +} + +static int bmi08x_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + struct sensor_three_axis_data *data_output = (struct sensor_three_axis_data *)data_out; + const struct bmi08x_accel_encoded_data *edata = + (const struct bmi08x_accel_encoded_data *)buffer; + + if (chan_spec.chan_type != SENSOR_CHAN_ACCEL_XYZ || chan_spec.chan_idx != 0 || + max_count == 0 || !edata->header.has_accel) { + return -EINVAL; + } + + if (edata->header.is_streaming) { + return bmi08x_decode_fifo(edata, fit, max_count, data_output); + } else { + return bmi08x_decode_one_shot(edata, fit, data_output); + } +} + +static bool bmi08x_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) +{ + const struct bmi08x_accel_encoded_data *edata = + (const struct bmi08x_accel_encoded_data *)buffer; + + return edata->header.is_streaming && edata->header.fifo_len > 0 && + trigger == SENSOR_TRIG_FIFO_WATERMARK; +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = bmi08x_decoder_get_frame_count, + .get_size_info = bmi08x_decoder_get_size_info, + .decode = bmi08x_decoder_decode, + .has_trigger = bmi08x_decoder_has_trigger, +}; + +int bmi08x_accel_decoder_get(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + return 0; +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.h b/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.h new file mode 100644 index 0000000000000..7bda48059cbd4 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_decoder.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_DECODER_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_DECODER_H_ + +#include +#include +#include "bmi08x.h" + +void bmi08x_accel_encode_header(const struct device *dev, struct bmi08x_accel_encoded_data *edata, + bool is_streaming, uint16_t buf_len); +int bmi08x_accel_decoder_get(const struct device *dev, const struct sensor_decoder_api **decoder); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_DECODER_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.c new file mode 100644 index 0000000000000..3141ad2a0d330 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_accel +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_accel_stream.h" +#include "bmi08x_accel_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_ACCEL_STREAM, CONFIG_SENSOR_LOG_LEVEL); + +enum bmi08x_stream_state { + BMI08X_STREAM_OFF, + BMI08X_STREAM_ON, + BMI08X_STREAM_BUSY, +}; + +static inline void bmi08x_stream_result(const struct device *dev, int result) +{ + struct bmi08x_accel_data *data = dev->data; + const struct bmi08x_accel_config *config = dev->config; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + + data->stream.iodev_sqe = NULL; + (void)rtio_flush_completion_queue(config->rtio_bus.ctx); + if (result >= 0) { + (void)atomic_set(&data->stream.state, BMI08X_STREAM_ON); + if (iodev_sqe) { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } + } else { + (void)atomic_set(&data->stream.state, BMI08X_STREAM_OFF); + if (iodev_sqe) { + rtio_iodev_sqe_err(iodev_sqe, result); + } + } +} + +static void bmi08x_stream_complete_handler(struct rtio *ctx, const struct rtio_sqe *sqe, int err, + void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct bmi08x_accel_data *data = dev->data; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + struct bmi08x_accel_encoded_data *edata; + uint32_t buf_len; + int ret; + + ret = rtio_sqe_rx_buf(iodev_sqe, 0, 0, (uint8_t **)&edata, &buf_len); + if (ret < 0 || buf_len == 0 || edata->header.fifo_len == 0) { + err = -EIO; + } + + bmi08x_stream_result(dev, err); +} + +static inline void bmi08x_accel_stream_evt_handler(const struct device *dev) +{ + struct bmi08x_accel_data *data = dev->data; + const struct bmi08x_accel_config *config = dev->config; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + int ret; + struct bmi08x_accel_encoded_data *edata; + uint32_t buf_len; + size_t readout_len = sizeof(struct bmi08x_accel_frame) * (data->stream.fifo_wm + 1); + size_t required_len = sizeof(struct bmi08x_accel_encoded_data) + readout_len; + struct rtio_sqe *out_sqe; + + CHECKIF(!iodev_sqe || atomic_get(&data->stream.state) == BMI08X_STREAM_OFF) { + LOG_WRN("Event with Stream is Off. Disabling stream"); + bmi08x_stream_result(dev, -EIO); + return; + } + CHECKIF(atomic_cas(&data->stream.state, BMI08X_STREAM_ON, BMI08X_STREAM_BUSY) == false) { + LOG_DBG("Event while Stream is busy. Ignoring"); + return; + } + + ret = rtio_sqe_rx_buf(iodev_sqe, required_len, required_len, (uint8_t **)&edata, &buf_len); + CHECKIF(ret < 0 || buf_len < required_len) { + LOG_ERR("Failed to obtain buffer. Err: %d, Req-len: %d", ret, required_len); + bmi08x_stream_result(dev, -ENOMEM); + return; + } + bmi08x_accel_encode_header(dev, edata, true, readout_len); + + struct reg_val_read { + uint8_t reg; + void *buf; + size_t len; + } streaming_readout[] = { + {.reg = BMI08X_REG_ACCEL_FIFO_LEN_0, .buf = &edata->header.fifo_len, .len = 2}, + {.reg = BMI08X_REG_ACCEL_FIFO_DATA, .buf = edata->fifo, .len = readout_len}, + }; + + for (size_t i = 0 ; i < ARRAY_SIZE(streaming_readout) ; i++) { + ret = bmi08x_prep_reg_read_rtio_async(&config->rtio_bus, streaming_readout[i].reg, + (uint8_t *)streaming_readout[i].buf, + streaming_readout[i].len, &out_sqe, true); + CHECKIF(ret < 0 || !out_sqe) { + bmi08x_stream_result(dev, -EIO); + return; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + } + out_sqe = rtio_sqe_acquire(config->rtio_bus.ctx); + CHECKIF(!out_sqe) { + bmi08x_stream_result(dev, -EIO); + return; + } + rtio_sqe_prep_callback_no_cqe(out_sqe, bmi08x_stream_complete_handler, (void *)dev, NULL); + (void)rtio_submit(config->rtio_bus.ctx, 0); +} + +static void bmi08x_accel_gpio_callback(const struct device *port, struct gpio_callback *cb, + uint32_t pin) +{ + struct bmi08x_accel_data *data = CONTAINER_OF(cb, struct bmi08x_accel_data, gpio_cb); + const struct device *dev = data->dev; + const struct bmi08x_accel_config *cfg = dev->config; + + (void)gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + (void)gpio_remove_callback(cfg->int_gpio.port, &data->gpio_cb); + bmi08x_accel_stream_evt_handler(dev); +} + +static inline int start_stream(const struct device *dev) +{ + struct bmi08x_accel_data *data = dev->data; + const struct bmi08x_accel_config *cfg = dev->config; + struct rtio_sqe *out_sqe; + int ret; + uint16_t fifo_wm_bytes = data->stream.fifo_wm * sizeof(struct bmi08x_accel_frame); + struct reg_vals { + uint8_t reg; + uint8_t val; + } stream_cfg_reg_writes[] = { + {.reg = BMI08X_REG_ACCEL_FIFO_WTM_0, .val = fifo_wm_bytes & 0xFF}, + {.reg = BMI08X_REG_ACCEL_FIFO_WTM_1, .val = (fifo_wm_bytes >> 8) & 0x1F}, + {.reg = BMI08X_REG_ACCEL_FIFO_CONFIG_0, .val = BIT(1) | BIT(0)}, /* FIFO Mode */ + {.reg = BMI08X_REG_ACCEL_FIFO_CONFIG_1, .val = BIT(6) | BIT(4)}, + {.reg = BMI08X_REG_ACCEL_INT1_INT2_MAP_DATA, .val = BIT(0) | BIT(1)}, /* INT1 */ + {.reg = BMI08X_REG_ACCEL_INT1_IO_CONF, .val = BIT(1) | BIT(3)}, /* Push-pull */ + }; + + for (size_t i = 0 ; i < ARRAY_SIZE(stream_cfg_reg_writes) ; i++) { + ret = bmi08x_prep_reg_write_rtio_async(&cfg->rtio_bus, stream_cfg_reg_writes[i].reg, + &stream_cfg_reg_writes[i].val, 1, &out_sqe); + CHECKIF(ret < 0 || !out_sqe) { + return ret; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + } + out_sqe->flags &= ~RTIO_SQE_CHAINED; + + /** We Synchronously write the stream since we want to do be done before enabling the + * interrupts. In the event that we're recovering from a failure, the interrupt line + * will be de-asserted. + */ + (void)rtio_submit(cfg->rtio_bus.ctx, ret); + return 0; +} + +void bmi08x_accel_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct bmi08x_accel_data *data = dev->data; + const struct bmi08x_accel_config *cfg = dev->config; + const struct sensor_read_config *stream_cfg = iodev_sqe->sqe.iodev->data; + int ret = 0; + + if (stream_cfg->count != 1 || + stream_cfg->triggers->trigger != SENSOR_TRIG_FIFO_WATERMARK || + stream_cfg->triggers->opt != SENSOR_STREAM_DATA_INCLUDE) { + LOG_ERR("Invalid stream configuration"); + rtio_iodev_sqe_err(iodev_sqe, -EINVAL); + return; + } + data->stream.iodev_sqe = iodev_sqe; + + if (atomic_cas(&data->stream.state, BMI08X_STREAM_OFF, BMI08X_STREAM_ON) == true) { + ret = start_stream(dev); + if (ret != 0) { + LOG_ERR("Failed to configure stream"); + bmi08x_stream_result(dev, ret); + return; + } + } + (void)gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb); + (void)gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_LEVEL_HIGH); +} + +int bmi08x_accel_stream_init(const struct device *dev) +{ + struct bmi08x_accel_data *data = dev->data; + const struct bmi08x_accel_config *cfg = dev->config; + int ret; + + if (!gpio_is_ready_dt(&cfg->int_gpio)) { + LOG_ERR("GPIO device not ready: %p - dev: %p", &cfg->int_gpio, dev); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO: %d", ret); + return ret; + } + ret = gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO: %d", ret); + return ret; + } + gpio_init_callback(&data->gpio_cb, bmi08x_accel_gpio_callback, BIT(cfg->int_gpio.pin)); + data->dev = dev; + + return 0; +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.h b/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.h new file mode 100644 index 0000000000000..8caaa1547dc80 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_stream.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_STREAM_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_STREAM_H_ + +#include +#include + +int bmi08x_accel_stream_init(const struct device *dev); +void bmi08x_accel_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_ACCEL_STREAM_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_bus.c b/drivers/sensor/bosch/bmi08x/bmi08x_bus.c new file mode 100644 index 0000000000000..92f96f4cd499b --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_bus.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bmi08x_bus.h" + +static uint8_t dummy_byte_val; + +int bmi08x_prep_reg_read_rtio_async(const struct bmi08x_rtio_bus *bus, + uint8_t reg, uint8_t *buf, size_t size, + struct rtio_sqe **out, bool dummy_byte) +{ + struct rtio *ctx = bus->ctx; + struct rtio_iodev *iodev = bus->iodev; + struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(ctx); + size_t sqe_ct = 2; + + if (!write_reg_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + reg |= BIT(7); + rtio_sqe_prep_tiny_write(write_reg_sqe, iodev, RTIO_PRIO_NORM, ®, 1, NULL); + write_reg_sqe->flags |= RTIO_SQE_TRANSACTION; + + if (dummy_byte) { + struct rtio_sqe *dummy_byte_sqe = rtio_sqe_acquire(ctx); + + if (!dummy_byte_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + rtio_sqe_prep_read(dummy_byte_sqe, iodev, RTIO_PRIO_NORM, &dummy_byte_val, 1, + NULL); + dummy_byte_sqe->flags |= RTIO_SQE_TRANSACTION; + sqe_ct++; + } + struct rtio_sqe *read_buf_sqe = rtio_sqe_acquire(ctx); + + if (!read_buf_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + rtio_sqe_prep_read(read_buf_sqe, iodev, RTIO_PRIO_NORM, buf, size, NULL); + if (bus->type == BMI08X_RTIO_BUS_TYPE_I2C) { + read_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = read_buf_sqe; + } + + return sqe_ct; +} + +int bmi08x_prep_reg_write_rtio_async(const struct bmi08x_rtio_bus *bus, + uint8_t reg, const uint8_t *buf, size_t size, + struct rtio_sqe **out) +{ + struct rtio *ctx = bus->ctx; + struct rtio_iodev *iodev = bus->iodev; + struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(ctx); + struct rtio_sqe *write_buf_sqe = rtio_sqe_acquire(ctx); + + if (!write_reg_sqe || !write_buf_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + + /** More than 7 won't work with tiny-write */ + if (size > 7) { + return -EINVAL; + } + + 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, buf, size, NULL); + if (bus->type == BMI08X_RTIO_BUS_TYPE_I2C) { + write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP; + } + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = write_buf_sqe; + } + + return 2; +} + +int bmi08x_reg_read_rtio(const struct bmi08x_rtio_bus *bus, uint8_t start, uint8_t *buf, int size, + bool dummy_byte) +{ + struct rtio *ctx = bus->ctx; + struct rtio_cqe *cqe; + int ret; + + ret = bmi08x_prep_reg_read_rtio_async(bus, start, buf, size, NULL, dummy_byte); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} + +int bmi08x_reg_write_rtio(const struct bmi08x_rtio_bus *bus, uint8_t reg, const uint8_t *buf, + int size) +{ + struct rtio *ctx = bus->ctx; + struct rtio_cqe *cqe; + int ret; + + ret = bmi08x_prep_reg_write_rtio_async(bus, reg, buf, size, NULL); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_bus.h b/drivers/sensor/bosch/bmi08x/bmi08x_bus.h new file mode 100644 index 0000000000000..f2ef90c0986ff --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_bus.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_RTIO_BUS_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_RTIO_BUS_H_ + +#include +#include + +enum bmi08x_rtio_bus_type { + BMI08X_RTIO_BUS_TYPE_I2C, + BMI08X_RTIO_BUS_TYPE_SPI, +}; + +struct bmi08x_rtio_bus { + struct rtio *ctx; + struct rtio_iodev *iodev; + enum bmi08x_rtio_bus_type type; +}; + +int bmi08x_prep_reg_read_rtio_async(const struct bmi08x_rtio_bus *bus, + uint8_t reg, uint8_t *buf, size_t size, + struct rtio_sqe **out, bool dummy_byte); + +int bmi08x_prep_reg_write_rtio_async(const struct bmi08x_rtio_bus *bus, + uint8_t reg, const uint8_t *buf, size_t size, + struct rtio_sqe **out); + +int bmi08x_reg_read_rtio(const struct bmi08x_rtio_bus *bus, uint8_t start, uint8_t *buf, int size, + bool dummy_byte); + +int bmi08x_reg_write_rtio(const struct bmi08x_rtio_bus *bus, uint8_t reg, const uint8_t *buf, + int size); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_RTIO_BUS_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro.c b/drivers/sensor/bosch/bmi08x/bmi08x_gyro.c index 9fec8f71222e9..c9371812d64c9 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_gyro.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro.c @@ -6,15 +6,23 @@ */ #include +#include #include #include #include #include #include #include +#include +#include +#include #define DT_DRV_COMPAT bosch_bmi08x_gyro #include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_gyro_async.h" +#include "bmi08x_gyro_stream.h" +#include "bmi08x_gyro_decoder.h" LOG_MODULE_REGISTER(BMI08X_GYRO, CONFIG_SENSOR_LOG_LEVEL); @@ -178,6 +186,7 @@ static int bmi08x_gyr_range_set(const struct device *dev, uint16_t range) } bmi08x->scale = BMI08X_GYR_SCALE(range); + bmi08x->range = reg_val; return ret; } @@ -334,6 +343,10 @@ static DEVICE_API(sensor, bmi08x_api) = { .attr_set = bmi08x_attr_set, #ifdef CONFIG_BMI08X_GYRO_TRIGGER .trigger_set = bmi08x_trigger_set_gyr, +#endif +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = bmi08x_gyro_async_submit, + .get_decoder = bmi08x_gyro_decoder_get, #endif .sample_fetch = bmi08x_sample_fetch, .channel_get = bmi08x_channel_get, @@ -416,6 +429,14 @@ int bmi08x_gyro_init(const struct device *dev) } #endif +#if defined(CONFIG_BMI08X_GYRO_STREAM) + ret = bmi08x_gyro_stream_init(dev); + if (ret < 0) { + LOG_ERR("Failed to init stream: %d", ret); + return ret; + } +#endif + return ret; } @@ -444,17 +465,45 @@ BUILD_ASSERT(CONFIG_BMI08X_GYRO_TRIGGER_NONE, #define BMI08X_CREATE_INST(inst) \ \ - static struct bmi08x_gyro_data bmi08x_drv_##inst; \ + IF_ENABLED(CONFIG_BMI08X_GYRO_STREAM, \ + (BUILD_ASSERT(DT_INST_PROP_OR(inst, fifo_watermark, 0) > 0 && \ + DT_INST_PROP_OR(inst, fifo_watermark, 0) < 100, \ + "FIFO Watermark must be defined for streaming mode, and be " \ + "within 1 and 99. Please define fifo-watermark accordingly or " \ + "disable CONFIG_BMI08X_GYRO_STREAM"))); \ + \ + RTIO_DEFINE(bmi08x_gyro_rtio_ctx_##inst, 16, 16); \ + \ + COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (I2C_DT_IODEV_DEFINE(bmi08x_gyro_rtio_bus_##inst, \ + DT_DRV_INST(inst))), \ + (COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (SPI_DT_IODEV_DEFINE(bmi08x_gyro_rtio_bus_##inst, \ + DT_DRV_INST(inst), \ + SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB)),\ + ()))); \ + \ + static struct bmi08x_gyro_data bmi08x_drv_##inst = { \ + IF_ENABLED(CONFIG_BMI08X_GYRO_STREAM, \ + (.stream.fifo_wm = DT_INST_PROP_OR(inst, fifo_watermark, 0),)) \ + }; \ \ static const struct bmi08x_gyro_config bmi08x_config_##inst = { \ COND_CODE_1(DT_INST_ON_BUS(inst, spi), (BMI08X_CONFIG_SPI(inst)), \ (BMI08X_CONFIG_I2C(inst))) \ .api = COND_CODE_1(DT_INST_ON_BUS(inst, spi), (&bmi08x_spi_api), \ (&bmi08x_i2c_api)), \ - IF_ENABLED(CONFIG_BMI08X_GYRO_TRIGGER, \ - (.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),)) \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ .gyro_hz = DT_INST_ENUM_IDX(inst, gyro_hz), \ - BMI08X_GYRO_TRIGGER_PINS(inst).gyro_fs = DT_INST_PROP(inst, gyro_fs), \ + BMI08X_GYRO_TRIGGER_PINS(inst) \ + .gyro_fs = DT_INST_PROP(inst, gyro_fs), \ + .rtio_bus = { \ + .ctx = &bmi08x_gyro_rtio_ctx_##inst, \ + .iodev = &bmi08x_gyro_rtio_bus_##inst, \ + .type = COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (BMI08X_RTIO_BUS_TYPE_I2C), \ + (BMI08X_RTIO_BUS_TYPE_SPI)), \ + }, \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, bmi08x_gyro_pm_action); \ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.c b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.c new file mode 100644 index 0000000000000..0eae888a36edd --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_gyro +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_gyro_stream.h" +#include "bmi08x_gyro_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_GYRO_ASYNC, CONFIG_SENSOR_LOG_LEVEL); + +static void bmi08x_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, int result, + void *arg) +{ + struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)arg; + + (void)rtio_flush_completion_queue(ctx); + if (result >= 0) { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } else { + rtio_iodev_sqe_err(iodev_sqe, result); + } +} + +static void bmi08x_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + uint32_t buf_len_req = sizeof(struct bmi08x_gyro_encoded_data); + struct bmi08x_gyro_encoded_data *edata; + uint32_t buf_len; + int err; + + err = rtio_sqe_rx_buf(iodev_sqe, buf_len_req, buf_len_req, (uint8_t **)&edata, &buf_len); + CHECKIF(err < 0 || buf_len < buf_len_req || !edata) { + LOG_ERR("Failed to get a read-buffer of size %u bytes", buf_len_req); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + bmi08x_gyro_encode_header(dev, edata, false); + + struct rtio_sqe *out_sqe; + struct rtio_sqe *complete_sqe; + const struct bmi08x_gyro_config *config = dev->config; + + err = bmi08x_prep_reg_read_rtio_async(&config->rtio_bus, BMI08X_REG_GYRO_X_LSB, + (uint8_t *)edata->frame.payload, + sizeof(edata->frame.payload), &out_sqe, false); + if (err < 0) { + LOG_ERR("Failed to perpare async read operation"); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + + complete_sqe = rtio_sqe_acquire(config->rtio_bus.ctx); + if (!complete_sqe) { + LOG_ERR("Failed to perpare async read operation"); + rtio_sqe_drop_all(config->rtio_bus.ctx); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + + rtio_sqe_prep_callback_no_cqe(complete_sqe, bmi08x_complete_result, iodev_sqe, (void *)dev); + rtio_submit(config->rtio_bus.ctx, 0); +} + +void bmi08x_gyro_async_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) { + bmi08x_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_BMI08X_GYRO_STREAM)) { + bmi08x_gyro_stream_submit(dev, iodev_sqe); + } else { + LOG_ERR("Streaming not enabled"); + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + } +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.h b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.h new file mode 100644 index 0000000000000..9b2b15f8f16d8 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_async.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_ASYNC_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_ASYNC_H_ + +#include +#include +#include + +void bmi08x_gyro_async_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_ASYNC_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.c b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.c new file mode 100644 index 0000000000000..57d7f6d1694d6 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_gyro +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_gyro_stream.h" +#include "bmi08x_gyro_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_GYRO_DECODER, CONFIG_SENSOR_LOG_LEVEL); + +void bmi08x_gyro_encode_header(const struct device *dev, struct bmi08x_gyro_encoded_data *edata, + bool is_streaming) +{ + struct bmi08x_gyro_data *data = dev->data; + uint64_t cycles; + + if (sensor_clock_get_cycles(&cycles) == 0) { + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); + } else { + edata->header.timestamp = 0; + } + edata->header.has_gyro = true; + edata->header.range = data->range; + edata->header.is_streaming = is_streaming; + edata->header.sample_count = is_streaming ? data->stream.fifo_wm : 1; +} + +static int bmi08x_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + const struct bmi08x_gyro_encoded_data *edata = + (const struct bmi08x_gyro_encoded_data *)buffer; + + if (!edata->header.has_gyro || chan_spec.chan_idx != 0) { + return -ENODATA; + } + if (chan_spec.chan_type != SENSOR_CHAN_GYRO_XYZ) { + return -EINVAL; + } + + *frame_count = edata->header.sample_count; + return 0; +} + +static int bmi08x_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, + size_t *frame_size) +{ + if (chan_spec.chan_idx != 0 || chan_spec.chan_type != SENSOR_CHAN_GYRO_XYZ) { + return -EINVAL; + } + + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; +} + +static int bmi08x_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct bmi08x_gyro_encoded_data *edata = + (const struct bmi08x_gyro_encoded_data *)buffer; + struct sensor_three_axis_data *data_output = (struct sensor_three_axis_data *)data_out; + uint32_t fit0 = *fit; + + if (chan_spec.chan_type != SENSOR_CHAN_GYRO_XYZ || chan_spec.chan_idx != 0 || + max_count == 0) { + return -EINVAL; + } + if (!edata->header.has_gyro || *fit >= edata->header.sample_count) { + return -ENODATA; + } + if (edata->header.is_streaming && + ((edata->header.fifo_status & 0x7F) == 0)) { + return -ENODATA; + } + uint32_t max_samples = MIN(edata->header.sample_count, edata->header.fifo_status & 0x7F); + + /** Bits we need to represent the integer part of FSR in rad/s: + * - 2000 dps (34.91 rad/s) = 6 bits. + * - 1000 dps (17.45 rad/s) = 5 bits. + * - 500 dps (8.73 rad/s) = 4 bits. + * - 250 dps (4.36 rad/s) = 3 bits. + * - 125 dps (2.18 rad/s) = 2 bits. + */ + data_output->shift = 6 - edata->header.range; + data_output->header.base_timestamp_ns = edata->header.timestamp; + + do { + for (size_t i = 0 ; i < 3 ; i++) { + int64_t raw_value; + + raw_value = sign_extend_64(edata->fifo[*fit].payload[i], 15); + raw_value = (raw_value * 2000 << (31 - 6 - 15)) * SENSOR_PI / 1000000 / 180; + + data_output->readings[*fit - fit0].values[i] = raw_value; + } + } while (++(*fit) < MIN(max_samples, fit0 + max_count)); + + data_output->header.reading_count = *fit - fit0; + + return data_output->header.reading_count; +} + +static bool bmi08x_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) +{ + const struct bmi08x_gyro_encoded_data *edata = + (const struct bmi08x_gyro_encoded_data *)buffer; + + return trigger == SENSOR_TRIG_FIFO_WATERMARK && + edata->header.has_gyro && + edata->header.is_streaming && + edata->header.int_status & BIT(4) && + (edata->header.fifo_status & BIT_MASK(7)) > 0; +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = bmi08x_decoder_get_frame_count, + .get_size_info = bmi08x_decoder_get_size_info, + .decode = bmi08x_decoder_decode, + .has_trigger = bmi08x_decoder_has_trigger, +}; + +int bmi08x_gyro_decoder_get(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + return 0; +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.h b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.h new file mode 100644 index 0000000000000..3baa7f6ab5c8a --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_decoder.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_DECODER_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_DECODER_H_ + +#include +#include +#include "bmi08x.h" + +void bmi08x_gyro_encode_header(const struct device *dev, struct bmi08x_gyro_encoded_data *edata, + bool is_streaming); +int bmi08x_gyro_decoder_get(const struct device *dev, const struct sensor_decoder_api **decoder); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_DECODER_H_ */ diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.c b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.c new file mode 100644 index 0000000000000..8dc0af395a386 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bmi08x_gyro +#include "bmi08x.h" +#include "bmi08x_bus.h" +#include "bmi08x_gyro_stream.h" +#include "bmi08x_gyro_decoder.h" + +#include +LOG_MODULE_REGISTER(BMI08X_GYRO_STREAM, CONFIG_SENSOR_LOG_LEVEL); + +enum bmi08x_stream_state { + BMI08X_STREAM_OFF, + BMI08X_STREAM_ON, + BMI08X_STREAM_BUSY, +}; + +static inline void bmi08x_stream_result(const struct device *dev, int result) +{ + struct bmi08x_gyro_data *data = dev->data; + const struct bmi08x_gyro_config *config = dev->config; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + + data->stream.iodev_sqe = NULL; + (void)rtio_flush_completion_queue(config->rtio_bus.ctx); + if (result >= 0) { + (void)atomic_set(&data->stream.state, BMI08X_STREAM_ON); + if (iodev_sqe) { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } + } else { + (void)atomic_set(&data->stream.state, BMI08X_STREAM_OFF); + if (iodev_sqe) { + rtio_iodev_sqe_err(iodev_sqe, result); + } + } +} + +static void bmi08x_stream_complete_handler(struct rtio *ctx, const struct rtio_sqe *sqe, int err, + void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct bmi08x_gyro_data *data = dev->data; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + struct bmi08x_gyro_encoded_data *edata; + uint32_t buf_len; + int ret; + + ret = rtio_sqe_rx_buf(iodev_sqe, 0, 0, (uint8_t **)&edata, &buf_len); + if (ret < 0 || buf_len == 0 || edata->header.int_status == 0 || + edata->header.fifo_status == 0) { + err = -EIO; + } + + bmi08x_stream_result(dev, err); +} + +static inline void bmi08x_gyro_stream_evt_handler(const struct device *dev) +{ + struct bmi08x_gyro_data *data = dev->data; + const struct bmi08x_gyro_config *config = dev->config; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + int ret; + struct bmi08x_gyro_encoded_data *edata; + uint32_t buf_len; + size_t readout_len = sizeof(struct bmi08x_gyro_frame) * data->stream.fifo_wm; + size_t required_len = sizeof(struct bmi08x_gyro_encoded_data) + readout_len; + struct rtio_sqe *out_sqe; + + CHECKIF(!iodev_sqe || atomic_get(&data->stream.state) == BMI08X_STREAM_OFF) { + LOG_WRN("Event with Stream is Off. Disabling stream"); + bmi08x_stream_result(dev, -EIO); + return; + } + CHECKIF(atomic_cas(&data->stream.state, BMI08X_STREAM_ON, BMI08X_STREAM_BUSY) == false) { + LOG_DBG("Event while Stream is busy. Ignoring"); + return; + } + + ret = rtio_sqe_rx_buf(iodev_sqe, required_len, required_len, (uint8_t **)&edata, &buf_len); + CHECKIF(ret < 0 || buf_len < required_len) { + LOG_ERR("Failed to obtain buffer. Err: %d, Req-len: %d", ret, required_len); + bmi08x_stream_result(dev, -ENOMEM); + return; + } + bmi08x_gyro_encode_header(dev, edata, true); + + struct reg_val_read { + uint8_t reg; + void *buf; + size_t len; + } streaming_readout[] = { + {.reg = BMI08X_REG_GYRO_INT_STAT_1, .buf = &edata->header.int_status, .len = 1,}, + {.reg = BMI08X_REG_FIFO_STATUS, .buf = &edata->header.fifo_status, .len = 1}, + {.reg = BMI08X_REG_GYRO_FIFO_DATA, .buf = edata->fifo, .len = readout_len}, + }; + + for (size_t i = 0 ; i < ARRAY_SIZE(streaming_readout) ; i++) { + ret = bmi08x_prep_reg_read_rtio_async(&config->rtio_bus, streaming_readout[i].reg, + (uint8_t *)streaming_readout[i].buf, + streaming_readout[i].len, &out_sqe, false); + CHECKIF(ret < 0 || !out_sqe) { + bmi08x_stream_result(dev, -EIO); + return; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + } + out_sqe = rtio_sqe_acquire(config->rtio_bus.ctx); + CHECKIF(!out_sqe) { + rtio_sqe_drop_all(config->rtio_bus.ctx); + bmi08x_stream_result(dev, -EIO); + return; + } + rtio_sqe_prep_callback_no_cqe(out_sqe, bmi08x_stream_complete_handler, (void *)dev, NULL); + (void)rtio_submit(config->rtio_bus.ctx, 0); +} + +static void bmi08x_gyro_gpio_callback(const struct device *port, struct gpio_callback *cb, + uint32_t pin) +{ + struct bmi08x_gyro_data *data = CONTAINER_OF(cb, struct bmi08x_gyro_data, gpio_cb); + const struct device *dev = data->dev; + const struct bmi08x_accel_config *cfg = dev->config; + + (void)gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + (void)gpio_remove_callback(cfg->int_gpio.port, &data->gpio_cb); + bmi08x_gyro_stream_evt_handler(dev); +} + +static inline int start_stream(const struct device *dev) +{ + struct bmi08x_gyro_data *data = dev->data; + const struct bmi08x_gyro_config *cfg = dev->config; + struct rtio_sqe *out_sqe; + int ret; + struct reg_vals { + uint8_t reg; + uint8_t val; + } stream_cfg_reg_writes[] = { + {.reg = BMI08X_REG_GYRO_FIFO_CONFIG_1, .val = 0x80}, /* FIFO Stream mode */ + {.reg = BMI08X_REG_GYRO_FIFO_CONFIG_0, .val = data->stream.fifo_wm}, /* WM Level */ + {.reg = BMI08X_REG_GYRO_FIFO_WM_EN, .val = 0x88}, /* Enable FIFO WM */ + {.reg = BMI08X_REG_GYRO_INT3_INT4_IO_MAP, .val = BIT(2)}, /* FIFO INT to INT3 */ + {.reg = BMI08X_REG_GYRO_INT3_INT4_IO_CONF, .val = BIT(0)}, /* Push-pull act-high */ + {.reg = BMI08X_REG_GYRO_INT_CTRL, .val = BIT(6)}, /* Enable FIFO Interrupts */ + }; + + for (size_t i = 0 ; i < ARRAY_SIZE(stream_cfg_reg_writes) ; i++) { + ret = bmi08x_prep_reg_write_rtio_async(&cfg->rtio_bus, stream_cfg_reg_writes[i].reg, + &stream_cfg_reg_writes[i].val, 1, &out_sqe); + CHECKIF(ret < 0 || !out_sqe) { + return ret; + } + out_sqe->flags |= RTIO_SQE_CHAINED; + } + out_sqe->flags &= ~RTIO_SQE_CHAINED; + + /** We Synchronously write the stream since we want to do be done before enabling the + * interrupts. In the event that we're recovering from a failure, the interrupt line + * will be de-asserted. + */ + (void)rtio_submit(cfg->rtio_bus.ctx, ret); + return 0; +} + +void bmi08x_gyro_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct bmi08x_gyro_data *data = dev->data; + const struct bmi08x_gyro_config *cfg = dev->config; + const struct sensor_read_config *stream_cfg = iodev_sqe->sqe.iodev->data; + int ret = 0; + + if (stream_cfg->count != 1 || + stream_cfg->triggers->trigger != SENSOR_TRIG_FIFO_WATERMARK || + stream_cfg->triggers->opt != SENSOR_STREAM_DATA_INCLUDE) { + LOG_ERR("Invalid stream configuration"); + rtio_iodev_sqe_err(iodev_sqe, -EINVAL); + return; + } + data->stream.iodev_sqe = iodev_sqe; + + if (atomic_cas(&data->stream.state, BMI08X_STREAM_OFF, BMI08X_STREAM_ON) == true) { + ret = start_stream(dev); + if (ret != 0) { + LOG_ERR("Failed to configure stream"); + bmi08x_stream_result(dev, ret); + return; + } + } + (void)gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb); + (void)gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_LEVEL_HIGH); +} + +int bmi08x_gyro_stream_init(const struct device *dev) +{ + struct bmi08x_gyro_data *data = dev->data; + const struct bmi08x_gyro_config *cfg = dev->config; + int ret; + + if (!gpio_is_ready_dt(&cfg->int_gpio)) { + LOG_ERR("GPIO device not ready: %p - dev: %p", &cfg->int_gpio, dev); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO: %d", ret); + return ret; + } + ret = gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO: %d", ret); + return ret; + } + gpio_init_callback(&data->gpio_cb, bmi08x_gyro_gpio_callback, BIT(cfg->int_gpio.pin)); + data->dev = dev; + + return 0; +} diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.h b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.h new file mode 100644 index 0000000000000..676e008544966 --- /dev/null +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_stream.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_STREAM_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_STREAM_H_ + +#include +#include + +int bmi08x_gyro_stream_init(const struct device *dev); +void bmi08x_gyro_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_BMI08X_GYRO_STREAM_H_ */ diff --git a/drivers/sensor/omron/2smpb_02e/2smpb_02e.c b/drivers/sensor/omron/2smpb_02e/2smpb_02e.c new file mode 100644 index 0000000000000..6bcebd822810e --- /dev/null +++ b/drivers/sensor/omron/2smpb_02e/2smpb_02e.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2025 CATIE + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT omron_2smpb_02e + +#include +#include +#include + +LOG_MODULE_REGISTER(O2SMPB_02E, CONFIG_SENSOR_LOG_LEVEL); + +/* + * Calibration coefficients for the Omron 2SMPB-02E sensor. + * + * These coefficients are used in the sensor's compensation algorithm to + * convert raw temperature and pressure readings into calibrated values. + * The values are derived from the sensor's datasheet. + * + * Reference: Omron 2SMPB-02E Application Note / Datasheet. + */ +#define COEFFICIENT_A1_A -6.3E-03 +#define COEFFICIENT_A1_S 4.3E-04 +#define COEFFICIENT_A2_A -1.9E-11 +#define COEFFICIENT_A2_S 1.2E-10 +#define COEFFICIENT_BT1_A 1.0E-01 +#define COEFFICIENT_BT1_S 9.1E-02 +#define COEFFICIENT_BT2_A 1.2E-08 +#define COEFFICIENT_BT2_S 1.2E-06 +#define COEFFICIENT_BP1_A 3.3E-02 +#define COEFFICIENT_BP1_S 1.9E-02 +#define COEFFICIENT_B11_A 2.1E-07 +#define COEFFICIENT_B11_S 1.4E-07 +#define COEFFICIENT_BP2_A -6.3E-10 +#define COEFFICIENT_BP2_S 3.5E-10 +#define COEFFICIENT_B12_A 2.9E-13 +#define COEFFICIENT_B12_S 7.6E-13 +#define COEFFICIENT_B21_A 2.1E-15 +#define COEFFICIENT_B21_S 1.2E-14 +#define COEFFICIENT_BP3_A 1.3E-16 +#define COEFFICIENT_BP3_S 7.9E-17 + +#define U20TOS32(x) (-(x & 0x00080000) + (x & 0xFFF7FFFF)) +#define U16TOS16(x) (-(x & 0x8000) | (x & 0x7FFF)) + +#define O2SMPB_02_REG_TEMP_TXD0 0xFC +#define O2SMPB_02_REG_TEMP_TXD1 0xFB +#define O2SMPB_02_REG_TEMP_TXD2 0xFA +#define O2SMPB_02_REG_PRESS_TXD0 0xF9 +#define O2SMPB_02_REG_PRESS_TXD1 0xF8 +#define O2SMPB_02_REG_PRESS_TXD2 0xF7 +#define O2SMPB_02_REG_RESET 0xE0 +#define O2SMPB_02_REG_CTRL_MEAS 0xF4 +#define O2SMPB_02_REG_CHIP_ID 0xD1 +#define O2SMPB_02_REG_COE_b00_1 0xA0 + +#define CALC_COEFF(A, S, OTP) ((A) + ((S) * (OTP) / 32767.0)) + +struct o2smpb_02e_config { + struct i2c_dt_spec i2c; +}; + +struct o2smpb_02e_data { + int32_t b00; + int32_t a0; + float bt1; + float bp1; + float bt2; + float b11; + float bp2; + float b12; + float b21; + float bp3; + float a1; + float a2; + int32_t dt; + int32_t dp; +}; + +static int o2smpb_02e_read_coefficients(const struct device *dev) +{ + struct o2smpb_02e_data *data = dev->data; + const struct o2smpb_02e_config *config = dev->config; + uint8_t buffer[25]; + + if (i2c_burst_read_dt(&config->i2c, O2SMPB_02_REG_COE_b00_1, buffer, sizeof(buffer)) < 0) { + LOG_ERR("Failed to read coefficients"); + return -EIO; + } + + /* K = OTP / 16 */ + data->a0 = + (int32_t)U20TOS32((buffer[18] << 12 | buffer[19] << 4 | (buffer[24] & 0x0F))) >> 4; + data->b00 = + (int32_t)U20TOS32((buffer[0] << 12 | buffer[1] << 4 | (buffer[24] & 0xF0) >> 4)) >> + 4; + + /* K = A + (S * OTP) / 32767 */ + int16_t bt1 = U16TOS16((buffer[2] << 8 | buffer[3])); + int16_t bp1 = U16TOS16((buffer[6] << 8 | buffer[7])); + int16_t bt2 = U16TOS16((buffer[4] << 8 | buffer[5])); + int16_t b11 = U16TOS16((buffer[8] << 8 | buffer[9])); + int16_t bp2 = U16TOS16((buffer[10] << 8 | buffer[11])); + int16_t b12 = U16TOS16((buffer[12] << 8 | buffer[13])); + int16_t b21 = U16TOS16((buffer[14] << 8 | buffer[15])); + int16_t bp3 = U16TOS16((buffer[16] << 8 | buffer[17])); + int16_t a1 = U16TOS16((buffer[20] << 8 | buffer[21])); + int16_t a2 = U16TOS16((buffer[22] << 8 | buffer[23])); + + data->bt1 = CALC_COEFF(COEFFICIENT_BT1_A, COEFFICIENT_BT1_S, bt1); + data->bp1 = CALC_COEFF(COEFFICIENT_BP1_A, COEFFICIENT_BP1_S, bp1); + data->bt2 = CALC_COEFF(COEFFICIENT_BT2_A, COEFFICIENT_BT2_S, bt2); + data->b11 = CALC_COEFF(COEFFICIENT_B11_A, COEFFICIENT_B11_S, b11); + data->bp2 = CALC_COEFF(COEFFICIENT_BP2_A, COEFFICIENT_BP2_S, bp2); + data->b12 = CALC_COEFF(COEFFICIENT_B12_A, COEFFICIENT_B12_S, b12); + data->b21 = CALC_COEFF(COEFFICIENT_B21_A, COEFFICIENT_B21_S, b21); + data->bp3 = CALC_COEFF(COEFFICIENT_BP3_A, COEFFICIENT_BP3_S, bp3); + data->a1 = CALC_COEFF(COEFFICIENT_A1_A, COEFFICIENT_A1_S, a1); + data->a2 = CALC_COEFF(COEFFICIENT_A2_A, COEFFICIENT_A2_S, a2); + + return 0; +} + +static int o2smpb_02e_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct o2smpb_02e_data *data = dev->data; + const struct o2smpb_02e_config *config = dev->config; + + uint8_t buffer[3]; + + /* Force mode */ + if (i2c_reg_write_byte_dt(&config->i2c, O2SMPB_02_REG_CTRL_MEAS, + (uint8_t)(0x101 << 5 | 0x101 << 2 | 0x1)) < 0) { + LOG_ERR("Could not set sensor to force mode"); + return -EIO; + } + + k_sleep(K_MSEC(500)); + + if (i2c_burst_read_dt(&config->i2c, O2SMPB_02_REG_TEMP_TXD2, buffer, sizeof(buffer)) < 0) { + LOG_ERR("Could not read sensor data"); + return -EIO; + } + + data->dt = (buffer[0] << 16 | buffer[1] << 8 | buffer[2]) - (0x1 << 23); + + if (i2c_burst_read_dt(&config->i2c, O2SMPB_02_REG_PRESS_TXD2, buffer, sizeof(buffer)) < 0) { + LOG_ERR("Could not read sensor data"); + return -EIO; + } + + data->dp = (buffer[0] << 16 | buffer[1] << 8 | buffer[2]) - (0x1 << 23); + + return 0; +} + +static int o2smpb_02e_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct o2smpb_02e_data *data = dev->data; + + switch (chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + float temp = + (data->a0) + ((data->a1) + (data->a2) * (float)data->dt) * (float)data->dt; + temp /= 256.0f; + + sensor_value_from_float(val, temp); + break; + case SENSOR_CHAN_PRESS: + float tr = + (data->a0) + ((data->a1) + (data->a2) * (float)data->dt) * (float)data->dt; + + float press = data->b00 + data->bt1 * tr + data->bp1 * (float)data->dp + + data->b11 * (float)data->dp * tr + data->bt2 * tr * tr + + data->bp2 * (float)data->dp * (float)data->dp + + data->b12 * (float)data->dp * tr * tr + + data->b21 * (float)data->dp * (float)data->dp * tr + + data->bp3 * (float)data->dp * (float)data->dp * (float)data->dp; + press /= 1000.0f; + + sensor_value_from_float(val, press); + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int o2smpb_02e_init(const struct device *dev) +{ + const struct o2smpb_02e_config *config = dev->config; + uint8_t chip_id; + + /* Reset the sensor */ + i2c_reg_write_byte_dt(&config->i2c, O2SMPB_02_REG_RESET, 0xE6); + + k_sleep(K_MSEC(10)); + + /* Read CHIP ID register to make sure the device is present */ + i2c_reg_read_byte_dt(&config->i2c, O2SMPB_02_REG_CHIP_ID, &chip_id); + + if (chip_id != 0x5C) { + LOG_ERR("Invalid chip ID"); + return -EIO; + } + + if (o2smpb_02e_read_coefficients(dev) < 0) { + LOG_ERR("Failed to read calibration coefficients"); + return -EIO; + } + + return 0; +} + +static DEVICE_API(sensor, o2smpb_02e_api_funcs) = { + .sample_fetch = o2smpb_02e_sample_fetch, + .channel_get = o2smpb_02e_channel_get, +}; + +#define O2SMPB_02E_INIT(n) \ + static const struct o2smpb_02e_config o2smpb_02e_config_##n = { \ + .i2c = I2C_DT_SPEC_INST_GET(n), \ + }; \ + static struct o2smpb_02e_data o2smpb_02e_data_##n; \ + SENSOR_DEVICE_DT_INST_DEFINE(n, o2smpb_02e_init, NULL, &o2smpb_02e_data_##n, \ + &o2smpb_02e_config_##n, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &o2smpb_02e_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(O2SMPB_02E_INIT) diff --git a/drivers/sensor/omron/2smpb_02e/CMakeLists.txt b/drivers/sensor/omron/2smpb_02e/CMakeLists.txt new file mode 100644 index 0000000000000..5ed6172b676e3 --- /dev/null +++ b/drivers/sensor/omron/2smpb_02e/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2025 CATIE +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(2smpb_02e.c) diff --git a/drivers/sensor/omron/2smpb_02e/Kconfig b/drivers/sensor/omron/2smpb_02e/Kconfig new file mode 100644 index 0000000000000..d3c49107b33fe --- /dev/null +++ b/drivers/sensor/omron/2smpb_02e/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 CATIE +# SPDX-License-Identifier: Apache-2.0 + +config 2SMPB_02E + bool "OMRON 2SMPB_02E digital barometric pressure sensor" + default y + depends on DT_HAS_OMRON_2SMPB_02E_ENABLED + select I2C + select FPU if CPU_HAS_FPU + help + Enable driver for OMRON O2SMPB_02E digital barometric pressure sensor. diff --git a/drivers/sensor/omron/CMakeLists.txt b/drivers/sensor/omron/CMakeLists.txt index 0237de521fa7f..c82213c7798f4 100644 --- a/drivers/sensor/omron/CMakeLists.txt +++ b/drivers/sensor/omron/CMakeLists.txt @@ -2,5 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # zephyr-keep-sorted-start +add_subdirectory_ifdef(CONFIG_2SMPB_02E 2smpb_02e) add_subdirectory_ifdef(CONFIG_D6F d6f) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/omron/Kconfig b/drivers/sensor/omron/Kconfig index fce9097a74efe..d27f0a6b7fa68 100644 --- a/drivers/sensor/omron/Kconfig +++ b/drivers/sensor/omron/Kconfig @@ -2,5 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # zephyr-keep-sorted-start +source "drivers/sensor/omron/2smpb_02e/Kconfig" source "drivers/sensor/omron/d6f/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/pixart/paa3905/paa3905_stream.c b/drivers/sensor/pixart/paa3905/paa3905_stream.c index 3f8b281bb8cab..3984da5ec95dd 100644 --- a/drivers/sensor/pixart/paa3905/paa3905_stream.c +++ b/drivers/sensor/pixart/paa3905/paa3905_stream.c @@ -59,6 +59,7 @@ static void start_drdy_backup_timer(const struct device *dev) static void paa3905_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, + int err, void *arg) { const struct device *dev = (const struct device *)arg; @@ -66,7 +67,6 @@ static void paa3905_complete_result(struct rtio *ctx, struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; struct paa3905_encoded_data *edata = sqe->userdata; struct rtio_cqe *cqe; - int err; edata->header.events.drdy = true && data->stream.settings.enabled.drdy; @@ -85,6 +85,22 @@ static void paa3905_complete_result(struct rtio *ctx, start_drdy_backup_timer(dev); } + /* Flush RTIO bus CQEs */ + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + if (err >= 0) { + err = cqe->result; + } + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + if (err < 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + /** Attempt chip recovery if erratic behavior is detected */ if (!REG_OBSERVATION_CHIP_OK(edata->observation)) { @@ -101,15 +117,6 @@ static void paa3905_complete_result(struct rtio *ctx, } else { rtio_iodev_sqe_ok(iodev_sqe, 0); } - - /* Flush RTIO bus CQEs */ - do { - cqe = rtio_cqe_consume(ctx); - if (cqe != NULL) { - err = cqe->result; - rtio_cqe_release(ctx, cqe); - } - } while (cqe != NULL); } static void paa3905_stream_get_data(const struct device *dev) diff --git a/drivers/sensor/pixart/pat9136/pat9136_stream.c b/drivers/sensor/pixart/pat9136/pat9136_stream.c index 3f7bff784f211..3a1e1e6b86a2d 100644 --- a/drivers/sensor/pixart/pat9136/pat9136_stream.c +++ b/drivers/sensor/pixart/pat9136/pat9136_stream.c @@ -45,6 +45,7 @@ static void start_drdy_cooldown_timer(const struct device *dev) static void pat9136_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, + int result, void *arg) { const struct device *dev = (const struct device *)arg; @@ -74,11 +75,13 @@ static void pat9136_complete_result(struct rtio *ctx, /** Attempt chip recovery if erratic behavior is detected */ if (!REG_OBSERVATION_READ_IS_VALID(edata->observation)) { - LOG_WRN("CHIP OK register indicates issues. Attempting chip recovery: 0x%02X", edata->observation); + result = -EAGAIN; + } - rtio_iodev_sqe_err(iodev_sqe, -EAGAIN); + if (result < 0) { + rtio_iodev_sqe_err(iodev_sqe, result); } else { rtio_iodev_sqe_ok(iodev_sqe, 0); } diff --git a/drivers/sensor/pni/rm3100/rm3100_stream.c b/drivers/sensor/pni/rm3100/rm3100_stream.c index d56a44336ce33..3f633cb924328 100644 --- a/drivers/sensor/pni/rm3100/rm3100_stream.c +++ b/drivers/sensor/pni/rm3100/rm3100_stream.c @@ -16,13 +16,13 @@ #include LOG_MODULE_REGISTER(RM3100_STREAM, CONFIG_SENSOR_LOG_LEVEL); -static void rm3100_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, void *arg) +static void rm3100_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, int err, + void *arg) { const struct device *dev = (const struct device *)arg; struct rm3100_data *data = dev->data; struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; struct rtio_cqe *cqe; - int err = 0; struct rm3100_encoded_data *edata = sqe->userdata; edata->header.events.drdy = ((edata->header.status != 0) && @@ -39,7 +39,9 @@ static void rm3100_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, do { cqe = rtio_cqe_consume(ctx); if (cqe != NULL) { - err = cqe->result; + if (err >= 0) { + err = cqe->result; + } rtio_cqe_release(ctx, cqe); } } while (cqe != NULL); @@ -181,13 +183,6 @@ static void rm3100_gpio_callback(const struct device *gpio_dev, rm3100_stream_get_data(dev); } -static inline bool settings_changed(const struct rm3100_stream *a, - const struct rm3100_stream *b) -{ - return (a->settings.enabled.drdy != b->settings.enabled.drdy) || - (a->settings.opt.drdy != b->settings.opt.drdy); -} - void rm3100_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { diff --git a/drivers/sensor/st/qdec_stm32/qdec_stm32.c b/drivers/sensor/st/qdec_stm32/qdec_stm32.c index d3ed5b4b1f2e9..01bddb810a4ec 100644 --- a/drivers/sensor/st/qdec_stm32/qdec_stm32.c +++ b/drivers/sensor/st/qdec_stm32/qdec_stm32.c @@ -114,12 +114,6 @@ static int qdec_stm32_initialize(const struct device *dev) return retval; } - if (dev_cfg->counts_per_revolution < 1) { - LOG_ERR("Invalid number of counts per revolution (%d)", - dev_cfg->counts_per_revolution); - return -EINVAL; - } - /* Ensure that the counter will always count up to a multiple of counts_per_revolution */ if (IS_TIM_32B_COUNTER_INSTANCE(dev_cfg->timer_inst)) { max_counter_value = UINT32_MAX - (UINT32_MAX % dev_cfg->counts_per_revolution) - 1; @@ -146,6 +140,9 @@ static DEVICE_API(sensor, qdec_stm32_driver_api) = { }; #define QDEC_STM32_INIT(n) \ + BUILD_ASSERT(DT_INST_PROP(n, st_counts_per_revolution) > 0, \ + "Counts per revolution must be above 0"); \ + \ BUILD_ASSERT(!(DT_INST_PROP(n, st_encoder_mode) & ~TIM_SMCR_SMS), \ "Encoder mode is not supported by this MCU"); \ \ diff --git a/drivers/sensor/tdk/icm4268x/CMakeLists.txt b/drivers/sensor/tdk/icm4268x/CMakeLists.txt index 76a814f2baa81..e3db420ccce22 100644 --- a/drivers/sensor/tdk/icm4268x/CMakeLists.txt +++ b/drivers/sensor/tdk/icm4268x/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library_sources( icm4268x.c icm4268x_common.c icm4268x_spi.c + icm4268x_bus.c ) zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API icm4268x_rtio.c) diff --git a/drivers/sensor/tdk/icm4268x/icm4268x.c b/drivers/sensor/tdk/icm4268x/icm4268x.c index 8dcbe50d0b1e4..60e63d98b8ccc 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x.c @@ -339,7 +339,7 @@ void icm4268x_unlock(const struct device *dev) #define ICM4268X_RTIO_DEFINE(inst) \ SPI_DT_IODEV_DEFINE(icm4268x_spi_iodev_##inst, DT_DRV_INST(inst), ICM4268X_SPI_CFG); \ - RTIO_DEFINE(icm4268x_rtio_##inst, 8, 4); + RTIO_DEFINE(icm4268x_rtio_##inst, 32, 32); #define ICM42688_DT_CONFIG_INIT(inst) \ { \ @@ -374,8 +374,13 @@ void icm4268x_unlock(const struct device *dev) IF_ENABLED(CONFIG_ICM4268X_STREAM, (ICM4268X_RTIO_DEFINE(inst))); \ static struct icm4268x_dev_data icm4268x_driver_##inst = { \ .cfg = ICM42688_DT_CONFIG_INIT(inst), \ - IF_ENABLED(CONFIG_ICM4268X_STREAM, (.r = &icm4268x_rtio_##inst, \ - .spi_iodev = &icm4268x_spi_iodev_##inst,)) \ + IF_ENABLED(CONFIG_ICM4268X_STREAM, \ + ( \ + .bus.rtio = { \ + .ctx = &icm4268x_rtio_##inst, \ + .iodev = &icm4268x_spi_iodev_##inst, \ + }, \ + )) \ }; /** The rest of the Device-tree configuration is validated in the YAML diff --git a/drivers/sensor/tdk/icm4268x/icm4268x.h b/drivers/sensor/tdk/icm4268x/icm4268x.h index 032eeabc302b0..9af998ea335c3 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x.h @@ -14,6 +14,7 @@ #include #include #include +#include "icm4268x_bus.h" struct alignment { int8_t index; @@ -341,6 +342,7 @@ struct icm4268x_cfg { bool fifo_en; int32_t batch_ticks; + uint16_t fifo_wm; bool fifo_hires; /* TODO additional FIFO options */ @@ -358,6 +360,12 @@ struct icm4268x_trigger_entry { sensor_trigger_handler_t handler; }; +enum icm4268x_stream_state { + ICM4268X_STREAM_OFF = 0, + ICM4268X_STREAM_ON = 1, + ICM4268X_STREAM_BUSY = 2, +}; + /** * @brief Device data (struct device) */ @@ -373,12 +381,11 @@ struct icm4268x_dev_data { #endif #ifdef CONFIG_ICM4268X_STREAM struct rtio_iodev_sqe *streaming_sqe; - struct rtio *r; - struct rtio_iodev *spi_iodev; + struct icm4268x_bus bus; uint8_t int_status; uint16_t fifo_count; uint64_t timestamp; - atomic_t reading_fifo; + atomic_t state; #endif /* CONFIG_ICM4268X_STREAM */ const struct device *dev; struct gpio_callback gpio_cb; diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_bus.c b/drivers/sensor/tdk/icm4268x/icm4268x_bus.c new file mode 100644 index 0000000000000..ffbbb75aeb129 --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/icm4268x_bus.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "icm4268x_bus.h" + +int icm4268x_prep_reg_read_rtio_async(const struct icm4268x_bus *bus, + uint8_t reg, uint8_t *buf, size_t size, + struct rtio_sqe **out) +{ + 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 *read_buf_sqe = rtio_sqe_acquire(ctx); + + if (!write_reg_sqe || !read_buf_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_read(read_buf_sqe, iodev, RTIO_PRIO_NORM, buf, size, NULL); + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = read_buf_sqe; + } + + return 2; +} + +int icm4268x_prep_reg_write_rtio_async(const struct icm4268x_bus *bus, + uint8_t reg, const uint8_t *buf, size_t size, + struct rtio_sqe **out) +{ + 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); + + if (!write_reg_sqe || !write_buf_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + + /** More than 7 won't work with tiny-write */ + if (size > 7) { + return -EINVAL; + } + + 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, buf, size, NULL); + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = write_buf_sqe; + } + + return 2; +} + +int icm4268x_reg_read_rtio(const struct icm4268x_bus *bus, uint8_t start, uint8_t *buf, int size) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_cqe *cqe; + int ret; + + ret = icm4268x_prep_reg_read_rtio_async(bus, start, buf, size, NULL); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} + +int icm4268x_reg_write_rtio(const struct icm4268x_bus *bus, uint8_t reg, const uint8_t *buf, + int size) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_cqe *cqe; + int ret; + + ret = icm4268x_prep_reg_write_rtio_async(bus, reg, buf, size, NULL); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_bus.h b/drivers/sensor/tdk/icm4268x/icm4268x_bus.h new file mode 100644 index 0000000000000..6ee94cc0d66a8 --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/icm4268x_bus.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_ICM4268X_BUS_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_ICM4268X_BUS_H_ + +#include +#include + +struct icm4268x_bus { + struct { + struct rtio *ctx; + struct rtio_iodev *iodev; + } rtio; +}; + +int icm4268x_prep_reg_read_rtio_async(const struct icm4268x_bus *bus, uint8_t reg, uint8_t *buf, + size_t size, struct rtio_sqe **out); + +int icm4268x_prep_reg_write_rtio_async(const struct icm4268x_bus *bus, uint8_t reg, + const uint8_t *buf, size_t size, struct rtio_sqe **out); + +int icm4268x_reg_read_rtio(const struct icm4268x_bus *bus, uint8_t start, uint8_t *buf, int size); + +int icm4268x_reg_write_rtio(const struct icm4268x_bus *bus, uint8_t reg, const uint8_t *buf, + int size); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_ICM4268X_BUS_H_ */ diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_common.c b/drivers/sensor/tdk/icm4268x/icm4268x_common.c index a89e81b601e82..7d20b906e4f55 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x_common.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_common.c @@ -329,8 +329,10 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg) } /* Set watermark and interrupt handling first */ - uint16_t fifo_wm = icm4268x_compute_fifo_wm(cfg); - uint8_t fifo_wml = fifo_wm & 0xFF; + cfg->fifo_wm = icm4268x_compute_fifo_wm(cfg); + + uint8_t fifo_wml = cfg->fifo_wm & 0xFF; + uint8_t fifo_wmh = (cfg->fifo_wm >> 8) & 0x0F; LOG_DBG("FIFO_CONFIG2( (0x%x)) (WM Low) 0x%x", REG_FIFO_CONFIG2, fifo_wml); res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG2, fifo_wml); @@ -339,8 +341,6 @@ int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg) return -EINVAL; } - uint8_t fifo_wmh = (fifo_wm >> 8) & 0x0F; - LOG_DBG("FIFO_CONFIG3 (0x%x) (WM High) 0x%x", REG_FIFO_CONFIG3, fifo_wmh); res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG3, fifo_wmh); if (res != 0) { diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h index 6d2cace1a5cb3..0f7cd6c32104c 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h @@ -18,7 +18,7 @@ struct icm4268x_decoder_header { uint8_t accel_fs: 3; uint8_t variant: 1; struct alignment axis_align[3]; -} __attribute__((__packed__)); +}; struct icm4268x_fifo_data { struct icm4268x_decoder_header header; @@ -28,7 +28,7 @@ struct icm4268x_fifo_data { uint16_t fifo_count: 11; uint16_t padding1: 5; uint16_t rtc_freq; -} __attribute__((__packed__)); +}; struct icm4268x_encoded_data { struct icm4268x_decoder_header header; diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c index c59aff475d4fb..22e5915ca37c4 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c @@ -45,9 +45,10 @@ static int icm4268x_rtio_sample_fetch(const struct device *dev, int16_t readings return 0; } -static void icm4268x_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +void icm4268x_submit_one_shot_sync(struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + const struct device *dev = cfg->sensor; const struct sensor_chan_spec *const channels = cfg->channels; const size_t num_channels = cfg->count; uint32_t min_buf_len = sizeof(struct icm4268x_encoded_data); @@ -84,21 +85,7 @@ static void icm4268x_submit_one_shot(const struct device *dev, struct rtio_iodev rtio_iodev_sqe_ok(iodev_sqe, 0); } -void icm4268x_submit_sync(struct rtio_iodev_sqe *iodev_sqe) -{ - const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; - const struct device *dev = cfg->sensor; - - if (!cfg->is_streaming) { - icm4268x_submit_one_shot(dev, iodev_sqe); - } else if (IS_ENABLED(CONFIG_ICM4268X_STREAM)) { - icm4268x_submit_stream(dev, iodev_sqe); - } else { - rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); - } -} - -void icm4268x_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +static void icm4268x_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { struct rtio_work_req *req = rtio_work_req_alloc(); @@ -109,8 +96,18 @@ void icm4268x_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) return; } - rtio_work_req_submit(req, iodev_sqe, icm4268x_submit_sync); + rtio_work_req_submit(req, iodev_sqe, icm4268x_submit_one_shot_sync); } -BUILD_ASSERT(sizeof(struct icm4268x_decoder_header) == 15, - "icm4268x_decoder_header size is not equal to 15"); +void icm4268x_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) { + icm4268x_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_ICM4268X_STREAM)) { + icm4268x_submit_stream(dev, iodev_sqe); + } else { + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + } +} diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c b/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c index 5013c6af1357c..83f332d7c9b83 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c @@ -5,17 +5,20 @@ */ #include +#include #include #include "icm4268x.h" #include "icm4268x_decoder.h" #include "icm4268x_reg.h" #include "icm4268x_rtio.h" +#include "icm4268x_bus.h" LOG_MODULE_DECLARE(ICM4268X_RTIO, CONFIG_SENSOR_LOG_LEVEL); void icm4268x_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + const struct icm4268x_dev_cfg *dev_cfg = (const struct icm4268x_dev_cfg *)sensor->config; struct icm4268x_dev_data *data = sensor->data; struct icm4268x_cfg new_config = data->cfg; @@ -46,68 +49,62 @@ void icm4268x_submit_stream(const struct device *sensor, struct rtio_iodev_sqe * int rc = icm4268x_safely_configure(sensor, &new_config); if (rc != 0) { - LOG_ERR("Failed to configure sensor"); + LOG_ERR("%p Failed to configure sensor", sensor); rtio_iodev_sqe_err(iodev_sqe, rc); return; } } + (void)atomic_set(&data->state, ICM4268X_STREAM_ON); data->streaming_sqe = iodev_sqe; + (void)gpio_pin_interrupt_configure_dt(&dev_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); } -static void icm4268x_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, int result, void *arg) +static struct sensor_stream_trigger * +icm4268x_get_read_config_trigger(const struct sensor_read_config *cfg, + enum sensor_trigger_type trig) { - ARG_UNUSED(result); + for (int i = 0; i < cfg->count; ++i) { + if (cfg->triggers[i].trigger == trig) { + return &cfg->triggers[i]; + } + } + LOG_DBG("Unsupported trigger (%d)", trig); + return NULL; +} - const struct device *dev = arg; +static inline void icm4268x_stream_result(const struct device *dev, int result) +{ struct icm4268x_dev_data *drv_data = dev->data; - const struct icm4268x_dev_cfg *drv_cfg = dev->config; - struct rtio_iodev_sqe *iodev_sqe = sqe->userdata; - - rtio_iodev_sqe_ok(iodev_sqe, drv_data->fifo_count); + struct rtio_iodev_sqe *streaming_sqe = drv_data->streaming_sqe; - gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + drv_data->streaming_sqe = NULL; + if (result < 0) { + rtio_iodev_sqe_err(streaming_sqe, result); + } else { + rtio_iodev_sqe_ok(streaming_sqe, result); + } } -static void icm4268x_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, - int result, void *arg) +static void icm4268x_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, int result, void *arg) { ARG_UNUSED(result); const struct device *dev = arg; struct icm4268x_dev_data *drv_data = dev->data; - const struct icm4268x_dev_cfg *drv_cfg = dev->config; - struct rtio_iodev *spi_iodev = drv_data->spi_iodev; - uint8_t *fifo_count_buf = (uint8_t *)&drv_data->fifo_count; - uint16_t fifo_count = ((fifo_count_buf[0] << 8) | fifo_count_buf[1]); - - drv_data->fifo_count = fifo_count; - - /* Pull a operation from our device iodev queue, validated to only be reads */ - struct rtio_iodev_sqe *iodev_sqe = drv_data->streaming_sqe; - - drv_data->streaming_sqe = NULL; - - /* Not inherently an underrun/overrun as we may have a buffer to fill next time */ - if (iodev_sqe == NULL) { - LOG_DBG("No pending SQE"); - gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); - return; - } - - const size_t packet_size = drv_data->cfg.fifo_hires ? 20 : 16; - const size_t min_read_size = sizeof(struct icm4268x_fifo_data) + packet_size; - const size_t ideal_read_size = sizeof(struct icm4268x_fifo_data) + fifo_count; + const struct icm4268x_dev_cfg *dev_cfg = (const struct icm4268x_dev_cfg *)dev->config; + struct rtio_iodev_sqe *streaming_sqe = drv_data->streaming_sqe; uint8_t *buf; uint32_t buf_len; + int rc; - if (rtio_sqe_rx_buf(iodev_sqe, min_read_size, ideal_read_size, &buf, &buf_len) != 0) { - LOG_ERR("Failed to get buffer"); - rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + if (drv_data->streaming_sqe == NULL || + FIELD_GET(RTIO_SQE_CANCELED, drv_data->streaming_sqe->sqe.flags)) { + LOG_ERR("%p Complete CB triggered with NULL handle. Disabling Interrupt", dev); + (void)gpio_pin_interrupt_configure_dt(&dev_cfg->gpio_int1, GPIO_INT_DISABLE); + (void)atomic_set(&drv_data->state, ICM4268X_STREAM_OFF); return; } - LOG_DBG("Requesting buffer [%u, %u] got %u", (unsigned int)min_read_size, - (unsigned int)ideal_read_size, buf_len); /** FSR are fixed for high-resolution, at which point we should * override driver FS config. @@ -126,11 +123,17 @@ static void icm4268x_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, default: CODE_UNREACHABLE; } + /* Even if we flushed the fifo, we still need room for the header to return result info */ + size_t required_len = sizeof(struct icm4268x_fifo_data); - /* Read FIFO and call back to rtio with rtio_sqe completion */ - /* TODO is packet format even needed? the fifo has a header per packet - * already - */ + rc = rtio_sqe_rx_buf(streaming_sqe, required_len, required_len, &buf, &buf_len); + CHECKIF(rc < 0 || !buf) { + LOG_ERR("%p Failed to obtain SQE buffer: %d", dev, rc); + icm4268x_stream_result(dev, -ENOMEM); + return; + } + + struct icm4268x_fifo_data *edata = (struct icm4268x_fifo_data *)buf; struct icm4268x_fifo_data hdr = { .header = { .is_fifo = true, @@ -145,222 +148,129 @@ static void icm4268x_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, .int_status = drv_data->int_status, .gyro_odr = drv_data->cfg.gyro_odr, .accel_odr = drv_data->cfg.accel_odr, + .fifo_count = drv_data->cfg.fifo_wm, .rtc_freq = drv_data->cfg.rtc_freq, }; - uint32_t buf_avail = buf_len; + *edata = hdr; - memcpy(buf, &hdr, sizeof(hdr)); - buf_avail -= sizeof(hdr); + if (FIELD_GET(BIT_FIFO_FULL_INT, edata->int_status) == true) { + uint8_t val = BIT_FIFO_FLUSH; - uint32_t read_len = MIN(fifo_count, buf_avail); - uint32_t pkts = read_len / packet_size; - - read_len = pkts * packet_size; - ((struct icm4268x_fifo_data *)buf)->fifo_count = read_len; - - __ASSERT_NO_MSG(read_len % packet_size == 0); - - uint8_t *read_buf = buf + sizeof(hdr); + LOG_WRN("%p FIFO Full bit is set. Flushing FIFO...", dev); + rc = icm4268x_prep_reg_write_rtio_async(&drv_data->bus, REG_SIGNAL_PATH_RESET, + &val, 1, NULL); + CHECKIF(rc < 0) { + LOG_ERR("%p Failed to flush the FIFO buffer: %d", dev, rc); + icm4268x_stream_result(dev, rc); + return; + } + rtio_submit(drv_data->bus.rtio.ctx, 0); + } - /* Flush out completions */ struct rtio_cqe *cqe; do { - cqe = rtio_cqe_consume(r); + cqe = rtio_cqe_consume(drv_data->bus.rtio.ctx); if (cqe != NULL) { - rtio_cqe_release(r, cqe); + if (rc >= 0) { + rc = cqe->result; + } + rtio_cqe_release(drv_data->bus.rtio.ctx, cqe); } } while (cqe != NULL); - /* Setup new rtio chain to read the fifo data and report then check the - * result - */ - struct rtio_sqe *write_fifo_addr = rtio_sqe_acquire(r); - __ASSERT_NO_MSG(write_fifo_addr != NULL); - struct rtio_sqe *read_fifo_data = rtio_sqe_acquire(r); - __ASSERT_NO_MSG(read_fifo_data != NULL); - struct rtio_sqe *complete_op = rtio_sqe_acquire(r); - __ASSERT_NO_MSG(complete_op != NULL); - const uint8_t reg_addr = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_FIFO_DATA); - - rtio_sqe_prep_tiny_write(write_fifo_addr, spi_iodev, RTIO_PRIO_NORM, ®_addr, 1, NULL); - write_fifo_addr->flags = RTIO_SQE_TRANSACTION; - rtio_sqe_prep_read(read_fifo_data, spi_iodev, RTIO_PRIO_NORM, read_buf, read_len, - iodev_sqe); - read_fifo_data->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(complete_op, icm4268x_complete_cb, (void *)dev, iodev_sqe); - - rtio_submit(r, 0); -} - -static struct sensor_stream_trigger * -icm4268x_get_read_config_trigger(const struct sensor_read_config *cfg, - enum sensor_trigger_type trig) -{ - for (int i = 0; i < cfg->count; ++i) { - if (cfg->triggers[i].trigger == trig) { - return &cfg->triggers[i]; - } - } - LOG_DBG("Unsupported trigger (%d)", trig); - return NULL; + (void)atomic_set(&drv_data->state, ICM4268X_STREAM_OFF); + icm4268x_stream_result(dev, rc); } -static void icm4268x_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, - int result, void *arg) +void icm4268x_fifo_event(const struct device *dev) { - ARG_UNUSED(result); - - const struct device *dev = arg; struct icm4268x_dev_data *drv_data = dev->data; - const struct icm4268x_dev_cfg *drv_cfg = dev->config; - struct rtio_iodev *spi_iodev = drv_data->spi_iodev; - struct rtio_iodev_sqe *streaming_sqe = drv_data->streaming_sqe; - struct sensor_read_config *read_config; + const struct icm4268x_dev_cfg *dev_cfg = (const struct icm4268x_dev_cfg *)dev->config; + struct rtio_sqe *sqe; + uint64_t cycles; + int rc; - if (streaming_sqe == NULL) { + if (drv_data->streaming_sqe == NULL || + FIELD_GET(RTIO_SQE_CANCELED, drv_data->streaming_sqe->sqe.flags)) { + LOG_ERR("%p FIFO event triggered with no stream submisssion. Disabling IRQ", dev); + (void)gpio_pin_interrupt_configure_dt(&dev_cfg->gpio_int1, GPIO_INT_DISABLE); + (void)atomic_set(&drv_data->state, ICM4268X_STREAM_OFF); return; } - - read_config = (struct sensor_read_config *)streaming_sqe->sqe.iodev->data; - __ASSERT_NO_MSG(read_config != NULL); - - if (!read_config->is_streaming) { - /* Oops, not really configured for streaming data */ + if (atomic_cas(&drv_data->state, ICM4268X_STREAM_ON, ICM4268X_STREAM_BUSY) == false) { + LOG_WRN("%p Callback triggered while stream is busy. Ignoring request", dev); return; } - struct sensor_stream_trigger *fifo_ths_cfg = - icm4268x_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_WATERMARK); - bool has_fifo_ths_trig = fifo_ths_cfg != NULL && - FIELD_GET(BIT_FIFO_THS_INT, drv_data->int_status) != 0; - - struct sensor_stream_trigger *fifo_full_cfg = - icm4268x_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_FULL); - bool has_fifo_full_trig = fifo_full_cfg != NULL && - FIELD_GET(BIT_FIFO_FULL_INT, drv_data->int_status) != 0; - - if (!has_fifo_ths_trig && !has_fifo_full_trig) { - LOG_DBG("No FIFO trigger is configured"); - gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("%p Failed to get sensor clock cycles", dev); + icm4268x_stream_result(dev, rc); return; } + drv_data->timestamp = sensor_clock_cycles_to_ns(cycles); - /* Flush completions */ - struct rtio_cqe *cqe; - - do { - cqe = rtio_cqe_consume(r); - if (cqe != NULL) { - rtio_cqe_release(r, cqe); - } - } while (cqe != NULL); - - 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); + rc = icm4268x_prep_reg_read_rtio_async(&drv_data->bus, REG_INT_STATUS | REG_SPI_READ_BIT, + &drv_data->int_status, 1, &sqe); + CHECKIF(rc < 0 || !sqe) { + LOG_ERR("%p Could not prepare async read: %d", dev, rc); + icm4268x_stream_result(dev, -ENOMEM); + return; } + sqe->flags |= RTIO_SQE_CHAINED; - if (data_opt == SENSOR_STREAM_DATA_NOP || data_opt == SENSOR_STREAM_DATA_DROP) { + struct sensor_read_config *read_config = + (struct sensor_read_config *)drv_data->streaming_sqe->sqe.iodev->data; + struct sensor_stream_trigger *fifo_ths_cfg = + icm4268x_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_WATERMARK); + + if (fifo_ths_cfg && fifo_ths_cfg->opt == SENSOR_STREAM_DATA_INCLUDE) { uint8_t *buf; uint32_t buf_len; - - /* Clear streaming_sqe since we're done with the call */ - drv_data->streaming_sqe = NULL; - if (rtio_sqe_rx_buf(streaming_sqe, sizeof(struct icm4268x_fifo_data), - sizeof(struct icm4268x_fifo_data), &buf, &buf_len) != 0) { - rtio_iodev_sqe_err(streaming_sqe, -ENOMEM); + uint16_t payload_read_len = drv_data->cfg.fifo_wm; + size_t required_len = sizeof(struct icm4268x_fifo_data) + payload_read_len; + + rc = rtio_sqe_rx_buf(drv_data->streaming_sqe, required_len, required_len, &buf, + &buf_len); + if (rc < 0) { + LOG_ERR("%p Failed to allocate buffer for the FIFO read: %d", dev, rc); + icm4268x_stream_result(dev, rc); return; } - struct icm4268x_fifo_data *data = (struct icm4268x_fifo_data *)buf; - - memset(buf, 0, buf_len); - data->header.timestamp = drv_data->timestamp; - data->int_status = drv_data->int_status; - data->fifo_count = 0; - rtio_iodev_sqe_ok(streaming_sqe, 0); - gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); - if (data_opt == SENSOR_STREAM_DATA_DROP) { - /* Flush the FIFO */ - struct rtio_sqe *write_signal_path_reset = rtio_sqe_acquire(r); - uint8_t write_buffer[] = { - FIELD_GET(REG_ADDRESS_MASK, REG_SIGNAL_PATH_RESET), - BIT_FIFO_FLUSH, - }; - - rtio_sqe_prep_tiny_write(write_signal_path_reset, spi_iodev, RTIO_PRIO_NORM, - write_buffer, ARRAY_SIZE(write_buffer), NULL); - /* TODO Add a new flag for fire-and-forget so we don't have to block here */ - rtio_submit(r, 1); - ARG_UNUSED(rtio_cqe_consume(r)); + /** We fill we data first, the header we'll fill once we have + * read all the data. + */ + uint8_t *read_buf = buf + sizeof(struct icm4268x_fifo_data); + + rc = icm4268x_prep_reg_read_rtio_async(&drv_data->bus, + REG_FIFO_DATA | REG_SPI_READ_BIT, + read_buf, payload_read_len, &sqe); + if (rc < 0 || !sqe) { + LOG_ERR("%p Could not prepare async read: %d", dev, rc); + icm4268x_stream_result(dev, -ENOMEM); + return; } - return; - } - - /* We need the data, read the fifo length */ - struct rtio_sqe *write_fifo_count_reg = rtio_sqe_acquire(r); - struct rtio_sqe *read_fifo_count = rtio_sqe_acquire(r); - struct rtio_sqe *check_fifo_count = rtio_sqe_acquire(r); - uint8_t reg = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_FIFO_COUNTH); - uint8_t *read_buf = (uint8_t *)&drv_data->fifo_count; - - rtio_sqe_prep_tiny_write(write_fifo_count_reg, spi_iodev, RTIO_PRIO_NORM, ®, 1, NULL); - write_fifo_count_reg->flags = RTIO_SQE_TRANSACTION; - rtio_sqe_prep_read(read_fifo_count, spi_iodev, RTIO_PRIO_NORM, read_buf, 2, NULL); - read_fifo_count->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(check_fifo_count, icm4268x_fifo_count_cb, arg, NULL); - - rtio_submit(r, 0); -} - -void icm4268x_fifo_event(const struct device *dev) -{ - struct icm4268x_dev_data *drv_data = dev->data; - struct rtio_iodev *spi_iodev = drv_data->spi_iodev; - struct rtio *r = drv_data->r; - uint64_t cycles; - int rc; - - if (drv_data->streaming_sqe == NULL) { - return; - } - - rc = sensor_clock_get_cycles(&cycles); - if (rc != 0) { - LOG_ERR("Failed to get sensor clock cycles"); - rtio_iodev_sqe_err(drv_data->streaming_sqe, rc); - return; + sqe->flags |= RTIO_SQE_CHAINED; + } else { + /** Because we don't want the data, flush it and be done with + * it. The trigger can be passed on to the user regardless. + */ + uint8_t val = BIT_FIFO_FLUSH; + + rc = icm4268x_prep_reg_write_rtio_async(&drv_data->bus, REG_SIGNAL_PATH_RESET, + &val, 1, &sqe); + if (rc < 0 || !sqe) { + LOG_ERR("%p Could not prepare async read: %d", dev, rc); + icm4268x_stream_result(dev, -ENOMEM); + return; + } + sqe->flags |= RTIO_SQE_CHAINED; } - drv_data->timestamp = sensor_clock_cycles_to_ns(cycles); + struct rtio_sqe *cb_sqe = rtio_sqe_acquire(drv_data->bus.rtio.ctx); - /* - * Setup rtio chain of ops with inline calls to make decisions - * 1. read int status - * 2. call to check int status and get pending RX operation - * 4. read fifo len - * 5. call to determine read len - * 6. read fifo - * 7. call to report completion - */ - struct rtio_sqe *write_int_reg = rtio_sqe_acquire(r); - struct rtio_sqe *read_int_reg = rtio_sqe_acquire(r); - struct rtio_sqe *check_int_status = rtio_sqe_acquire(r); - uint8_t reg = REG_SPI_READ_BIT | FIELD_GET(REG_ADDRESS_MASK, REG_INT_STATUS); - - rtio_sqe_prep_tiny_write(write_int_reg, spi_iodev, RTIO_PRIO_NORM, ®, 1, NULL); - write_int_reg->flags = RTIO_SQE_TRANSACTION; - rtio_sqe_prep_read(read_int_reg, spi_iodev, RTIO_PRIO_NORM, &drv_data->int_status, 1, NULL); - read_int_reg->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(check_int_status, icm4268x_int_status_cb, (void *)dev, NULL); - rtio_submit(r, 0); + rtio_sqe_prep_callback(cb_sqe, icm4268x_complete_cb, (void *)dev, NULL); + rtio_submit(drv_data->bus.rtio.ctx, 0); } diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c index cbbd6b9205e16..d844a3be391cd 100644 --- a/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c @@ -147,7 +147,7 @@ int icm4268x_trigger_init(const struct device *dev) #elif defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) data->work.handler = icm4268x_work_handler; #endif - return gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); + return 0; } int icm4268x_trigger_enable_interrupt(const struct device *dev, struct icm4268x_cfg *new_cfg) diff --git a/drivers/sensor/tdk/icm45686/icm45686_stream.c b/drivers/sensor/tdk/icm45686/icm45686_stream.c index f76838f118bc0..190d32e3c342d 100644 --- a/drivers/sensor/tdk/icm45686/icm45686_stream.c +++ b/drivers/sensor/tdk/icm45686/icm45686_stream.c @@ -573,18 +573,17 @@ int icm45686_stream_init(const struct device *dev) } #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(invensense_icm45686, i3c) /** I3C devices use IBI only if no GPIO INT pin is defined. */ - } else if (data->rtio.type == ICM45686_BUS_I3C) { - const struct i3c_iodev_data *iodev_data = data->rtio.iodev->data; + } else if (data->bus.rtio.type == ICM45686_BUS_I3C) { + const struct i3c_iodev_data *iodev_data = data->bus.rtio.iodev->data; - data->rtio.i3c.desc = i3c_device_find(iodev_data->bus, - &data->rtio.i3c.id); - if (data->rtio.i3c.desc == NULL) { + data->bus.rtio.i3c.desc = i3c_device_find(iodev_data->bus, &data->bus.rtio.i3c.id); + if (data->bus.rtio.i3c.desc == NULL) { LOG_ERR("Failed to find I3C device"); return -ENODEV; } - data->rtio.i3c.desc->ibi_cb = icm45686_ibi_cb; + data->bus.rtio.i3c.desc->ibi_cb = icm45686_ibi_cb; - err = i3c_ibi_enable(data->rtio.i3c.desc); + err = i3c_ibi_enable(data->bus.rtio.i3c.desc); if (err) { LOG_ERR("Failed to enable IBI: %d", err); return err; diff --git a/drivers/sensor/vishay/CMakeLists.txt b/drivers/sensor/vishay/CMakeLists.txt index c0462dba8620d..56ff0b09bbaac 100644 --- a/drivers/sensor/vishay/CMakeLists.txt +++ b/drivers/sensor/vishay/CMakeLists.txt @@ -5,5 +5,6 @@ add_subdirectory_ifdef(CONFIG_VCNL36825T vcnl36825t) add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040) add_subdirectory_ifdef(CONFIG_VEML6031 veml6031) +add_subdirectory_ifdef(CONFIG_VEML6046 veml6046) add_subdirectory_ifdef(CONFIG_VEML7700 veml7700) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/vishay/Kconfig b/drivers/sensor/vishay/Kconfig index 564a9740c9c8e..a203cadd9947b 100644 --- a/drivers/sensor/vishay/Kconfig +++ b/drivers/sensor/vishay/Kconfig @@ -5,5 +5,6 @@ source "drivers/sensor/vishay/vcnl36825t/Kconfig" source "drivers/sensor/vishay/vcnl4040/Kconfig" source "drivers/sensor/vishay/veml6031/Kconfig" +source "drivers/sensor/vishay/veml6046/Kconfig" source "drivers/sensor/vishay/veml7700/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/vishay/veml6031/veml6031.c b/drivers/sensor/vishay/veml6031/veml6031.c index b36b0a4c8d909..b2511b2586f79 100644 --- a/drivers/sensor/vishay/veml6031/veml6031.c +++ b/drivers/sensor/vishay/veml6031/veml6031.c @@ -57,33 +57,6 @@ LOG_MODULE_REGISTER(VEML6031, CONFIG_SENSOR_LOG_LEVEL); #define VEML6031_CMDCODE_ID_H 0x15 #define VEML6031_CMDCODE_ALS_INT 0x17 -/* - * ALS integration time struct. - */ -struct veml6031_it_data { - enum veml6031_it num; - uint8_t val; - int us; -}; - -/* - * ALS integration time setting values. - * - * The enumerators of enum veml6031_it provide - * indices into this array to get the related value for the - * ALS_IT configuration bits. - */ -static const struct veml6031_it_data veml6031_it_values[] = { - {VEML6031_IT_3_125, 0x00, 3125}, /* 3.125 - 0b0000 */ - {VEML6031_IT_6_25, 0x01, 6250}, /* 6.25 - 0b0001 */ - {VEML6031_IT_12_5, 0x02, 12500}, /* 12.5 - 0b0010 */ - {VEML6031_IT_25, 0x03, 25000}, /* 25 - 0b0011 */ - {VEML6031_IT_50, 0x04, 50000}, /* 50 - 0b0100 */ - {VEML6031_IT_100, 0x05, 100000}, /* 100 - 0b0101 */ - {VEML6031_IT_200, 0x06, 200000}, /* 200 - 0b0110 */ - {VEML6031_IT_400, 0x07, 400000}, /* 400 - 0b0111 */ -}; - /* * Resolution matrix for values to convert between data provided * by the sensor ("counts") and lux. @@ -93,7 +66,7 @@ static const struct veml6031_it_data veml6031_it_values[] = { * and enum veml6031_als_it are used for indices into this matrix. */ static const float - veml6031_resolution[VEML6031_DIV4_COUNT][VEML6031_GAIN_COUNT][VEML6031_IT_COUNT] = { + veml6031_resolution[VEML6031_DIV4_COUNT][VEML60XX_GAIN_COUNT][VEML60XX_IT_COUNT] = { /*3.125ms 6.25ms 12.5ms 25ms 50ms 100ms 200ms 400ms IT */ /* size 4/4 */ { @@ -131,9 +104,9 @@ struct veml6031_data { uint8_t ir_sd; /* ALS and IR channel shutdown */ uint8_t cal; /* Power on ready */ enum veml6031_div4 div4; /* effective photodiode size */ - enum veml6031_gain gain; /* gain selection */ - enum veml6031_it itim; /* ALS integration time */ - enum veml6031_pers pers; /* ALS persistens protect */ + enum veml60xx_gain gain; /* gain selection */ + enum veml60xx_it itim; /* ALS integration time */ + enum veml60xx_pers pers; /* ALS persistence protect */ uint16_t thresh_high; uint16_t thresh_low; uint16_t als_data; @@ -142,30 +115,15 @@ struct veml6031_data { uint32_t int_flags; }; -static bool veml6031_gain_in_range(int32_t gain) -{ - return (gain >= VEML6031_GAIN_1) && (gain <= VEML6031_GAIN_0_5); -} - -static bool veml6031_itim_in_range(int32_t itim) -{ - return (itim >= VEML6031_IT_3_125) && (itim <= VEML6031_IT_400); -} - static bool veml6031_div4_in_range(int32_t div4) { return (div4 >= VEML6031_SIZE_4_4) && (div4 <= VEML6031_SIZE_1_4); } -static bool veml6031_pers_in_range(int32_t pers) -{ - return (pers >= VEML6031_PERS_1) && (pers <= VEML6031_PERS_8); -} - static void veml6031_sleep_by_integration_time(const struct veml6031_data *data) { - if (veml6031_itim_in_range(data->itim)) { - k_sleep(K_USEC(veml6031_it_values[data->itim].us)); + if (veml60xx_it_in_range(data->itim)) { + k_sleep(K_USEC(veml60xx_it_values[data->itim].us)); } else { LOG_WRN_ONCE("Wrong settings: itim:%d. Most likely an application bug!", data->itim); @@ -174,28 +132,8 @@ static void veml6031_sleep_by_integration_time(const struct veml6031_data *data) static int veml6031_check_settings(const struct veml6031_data *data) { - return veml6031_div4_in_range(data->div4) && veml6031_gain_in_range(data->gain) && - veml6031_itim_in_range(data->itim); -} - -static int veml6031_check_gain(const struct sensor_value *val) -{ - return veml6031_gain_in_range(val->val1); -} - -static int veml6031_check_it(const struct sensor_value *val) -{ - return veml6031_itim_in_range(val->val1); -} - -static int veml6031_check_div4(const struct sensor_value *val) -{ - return veml6031_div4_in_range(val->val1); -} - -static int veml6031_check_pers(const struct sensor_value *val) -{ - return veml6031_pers_in_range(val->val1); + return veml6031_div4_in_range(data->div4) && veml60xx_gain_in_range(data->gain) && + veml60xx_it_in_range(data->itim); } static int veml6031_read(const struct device *dev, uint8_t cmd, uint8_t *data) @@ -368,29 +306,29 @@ static int veml6031_attr_set(const struct device *dev, enum sensor_channel chan, /* SENSOR_ATTR_.*_THRESH are not in enum sensor_attribute_veml6031 */ switch ((int)attr) { case SENSOR_ATTR_VEML6031_IT: - if (veml6031_check_it(val)) { - data->itim = (enum veml6031_it)val->val1; + if (veml60xx_it_in_range(val->val1)) { + data->itim = (enum veml60xx_it)val->val1; } else { return -EINVAL; } break; case SENSOR_ATTR_VEML6031_DIV4: - if (veml6031_check_div4(val)) { + if (veml6031_div4_in_range(val->val1)) { data->div4 = (enum veml6031_div4)val->val1; } else { return -EINVAL; } break; case SENSOR_ATTR_VEML6031_GAIN: - if (veml6031_check_gain(val)) { - data->gain = (enum veml6031_gain)val->val1; + if (veml60xx_gain_in_range(val->val1)) { + data->gain = (enum veml60xx_gain)val->val1; } else { return -EINVAL; } break; case SENSOR_ATTR_VEML6031_PERS: - if (veml6031_check_pers(val)) { - data->pers = (enum veml6031_pers)val->val1; + if (veml60xx_pers_in_range(val->val1)) { + data->pers = (enum veml60xx_pers)val->val1; } else { return -EINVAL; } @@ -651,9 +589,9 @@ static DEVICE_API(sensor, veml6031_api) = { static struct veml6031_data veml6031_data_##n = {.trig = 1, \ .af = 1, \ .div4 = VEML6031_SIZE_4_4, \ - .gain = VEML6031_GAIN_1, \ - .itim = VEML6031_IT_100, \ - .pers = VEML6031_PERS_1, \ + .gain = VEML60XX_GAIN_1, \ + .itim = VEML60XX_IT_100, \ + .pers = VEML60XX_PERS_1, \ .thresh_high = 0xFFFF}; \ \ static const struct veml6031_config veml6031_config_##n = { \ diff --git a/drivers/sensor/vishay/veml6046/CMakeLists.txt b/drivers/sensor/vishay/veml6046/CMakeLists.txt new file mode 100644 index 0000000000000..c31cfff011a18 --- /dev/null +++ b/drivers/sensor/vishay/veml6046/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Andreas Klinger +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(veml6046.c) diff --git a/drivers/sensor/vishay/veml6046/Kconfig b/drivers/sensor/vishay/veml6046/Kconfig new file mode 100644 index 0000000000000..06e057e07ec21 --- /dev/null +++ b/drivers/sensor/vishay/veml6046/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Andreas Klinger +# SPDX-License-Identifier: Apache-2.0 + +# Vishay VEML6046 RGBIR color sensor driver options. + +config VEML6046 + bool "Vishay VEML6046 RGBIR color sensor" + default y + depends on DT_HAS_VISHAY_VEML6046_ENABLED + select I2C + help + Enable Vishay VEML6046 RGBIR color sensor driver. diff --git a/drivers/sensor/vishay/veml6046/veml6046.c b/drivers/sensor/vishay/veml6046/veml6046.c new file mode 100644 index 0000000000000..89faea0e2d141 --- /dev/null +++ b/drivers/sensor/vishay/veml6046/veml6046.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2025 Andreas Klinger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT vishay_veml6046 + +#include +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(VEML6046, CONFIG_SENSOR_LOG_LEVEL); + +/* + * ID code of device + */ +#define VEML6046_DEFAULT_ID 0x01 + +/* + * Bit mask to check for data ready in single measurement. + */ +#define VEML6046_AF_DATA_READY BIT(3) + +/* + * Maximum value of RGBIR data which also means that the sensor is in + * saturation and that the measured value might be wrong. + * In such a case the user program should reduce one or more of the following + * attributes to get a relyable value: + * gain + * integration time + * effective photodiode size divider + */ +#define VEML6046_DATA_OVERFLOW 0xFFFF + +/* + * 16-bit command register addresses + */ +#define VEML6046_CMDCODE_RGB_CONF_0 0x00 +#define VEML6046_CMDCODE_RGB_CONF_1 0x01 +#define VEML6046_CMDCODE_G_THDH_L 0x04 +#define VEML6046_CMDCODE_G_THDH_H 0x05 +#define VEML6046_CMDCODE_G_THDL_L 0x06 +#define VEML6046_CMDCODE_G_THDL_H 0x07 +#define VEML6046_CMDCODE_R_DATA_L 0x10 +#define VEML6046_CMDCODE_R_DATA_H 0x11 +#define VEML6046_CMDCODE_G_DATA_L 0x12 +#define VEML6046_CMDCODE_G_DATA_H 0x13 +#define VEML6046_CMDCODE_B_DATA_L 0x14 +#define VEML6046_CMDCODE_B_DATA_H 0x15 +#define VEML6046_CMDCODE_IR_DATA_L 0x16 +#define VEML6046_CMDCODE_IR_DATA_H 0x17 +#define VEML6046_CMDCODE_ID_L 0x18 +#define VEML6046_CMDCODE_ID_H 0x19 +#define VEML6046_CMDCODE_INT_L 0x1A +#define VEML6046_CMDCODE_INT_H 0x1B + +/* + * Resolution matrix for values to convert between data provided + * by the sensor ("counts") and lux. + * + * These values depend on the current size, gain and integration time settings. + * The enumerators of enum veml6046_pdd, enum veml60xx_gain and enum + * veml6046_als_it are used for indices into this matrix. + */ +static const float + veml6046_resolution[VEML6046_PDD_COUNT][VEML60XX_GAIN_COUNT][VEML60XX_IT_COUNT] = { + /*3.125ms 6.25ms 12.5ms 25ms 50ms 100ms 200ms 400ms IT */ + /* size 2/2 */ + { + {1.3440f, 0.6720f, 0.3360f, 0.1680f, 0.0840f, 0.0420f, 0.0210f, + 0.0105f}, /* Gain 1 */ + {0.6720f, 0.3360f, 0.1680f, 0.0840f, 0.0420f, 0.0210f, 0.0105f, + 0.0053f}, /* Gain 2 */ + {2.0364f, 1.0182f, 0.5091f, 0.2545f, 0.1273f, 0.0636f, 0.0318f, + 0.0159f}, /* Gain 0.66 */ + {2.6880f, 1.3440f, 0.6720f, 0.3360f, 0.1680f, 0.0840f, 0.0420f, + 0.0210f}, /* Gain 0.5 */ + }, + { + /* size 1/2 */ + {2.6880f, 1.3440f, 0.6720f, 0.3360f, 0.1680f, 0.0840f, 0.0420f, + 0.0210f}, /* Gain 1 */ + {1.3440f, 0.6720f, 0.3360f, 0.1680f, 0.0840f, 0.0420f, 0.0210f, + 0.0105f}, /* Gain 2 */ + {4.0727f, 2.0364f, 1.0182f, 0.5091f, 0.2545f, 0.1273f, 0.0636f, + 0.0318f}, /* Gain 0.66 */ + {5.3760f, 2.6880f, 1.3440f, 0.6720f, 0.3360f, 0.1680f, 0.0840f, + 0.0420f}, /* Gain 0.5 */ + }, +}; + +struct veml6046_config { + struct i2c_dt_spec bus; +}; + +struct veml6046_data { + uint8_t sd; /* Band gap and LDO shutdown */ + uint8_t int_en; /* ALS interrupt enable */ + uint8_t trig; /* ALS active force trigger */ + enum veml6046_pdd pdd; /* effective photodiode size divider */ + enum veml60xx_gain gain; /* gain selection */ + enum veml60xx_it itim; /* ALS integration time */ + enum veml60xx_pers pers; /* ALS persistens protect */ + uint16_t thresh_high; + uint16_t thresh_low; + uint16_t red_data; + uint16_t green_data; + uint16_t blue_data; + uint16_t ir_data; + uint32_t red_lux; + uint32_t green_lux; + uint32_t blue_lux; + uint32_t ir_lux; +}; + +static bool veml6046_pdd_in_range(int32_t pdd) +{ + return pdd >= VEML6046_SIZE_2_2 && pdd <= VEML6046_SIZE_1_2; +} + +static int veml6046_read16(const struct device *dev, uint8_t cmd, uint16_t *data) +{ + const struct veml6046_config *conf = dev->config; + int ret; + + ret = i2c_burst_read_dt(&conf->bus, cmd, (uint8_t *)data, 2); + if (ret < 0) { + return ret; + } + + *data = sys_le16_to_cpu(*data); + + return 0; +} + +/* + * This function excepts an array of uint8_t data[2] with the two corresponding + * values set accordingly to the register map of the sensor. + */ +static int veml6046_write16(const struct device *dev, uint8_t cmd, uint8_t *data) +{ + const struct veml6046_config *conf = dev->config; + + return i2c_burst_write_dt(&conf->bus, cmd, data, 2); +} + +static int veml6046_write_conf(const struct device *dev) +{ + int ret; + struct veml6046_data *data = dev->data; + uint8_t conf[2] = {0, 0}; + + /* Bits 7 -> RGB_ON_1 */ + if (data->sd) { + conf[1] |= BIT(7); + } + /* Bits 6 -> Effective photodiode size */ + conf[1] |= data->pdd << 6; + /* Bit 5 -> reserved */ + /* Bits 4:3 -> Gain selection */ + conf[1] |= data->gain << 3; + /* Bits 2:1 -> ALS persistence protect number */ + conf[1] |= data->pers << 1; + /* Bit 0 -> Calibration should always be 1 when using the sensor */ + conf[1] |= BIT(0); + /* Bit 7 -> reserved, have to be 0 */ + /* Bits 6:4 -> integration time (ALS_IT) */ + conf[0] |= data->itim << 4; + /* Bit 3 -> Active force mode is always enabled + * Auto mode would continuously deliver data which is not what we want + * in this driver + */ + conf[0] |= BIT(3); + /* Bit 2 -> ALS active force trigger */ + if (data->trig) { + conf[0] |= BIT(2); + } + /* Bit 1 -> ALS interrupt enable */ + if (data->int_en) { + conf[0] |= BIT(1); + } + /* Bit 0 -> shut down setting (SD) */ + if (data->sd) { + conf[0] |= BIT(0); + } + + ret = veml6046_write16(dev, VEML6046_CMDCODE_RGB_CONF_0, conf); + if (ret) { + LOG_ERR("Error while writing conf[0] ret: %d", ret); + return ret; + } + + return 0; +} + +static int veml6046_write_thresh_high(const struct device *dev) +{ + int ret; + const struct veml6046_data *data = dev->data; + uint8_t val[2]; + + val[0] = data->thresh_high & 0xFF; + val[1] = data->thresh_high >> 8; + + LOG_DBG("Writing high threshold counts: %d", data->thresh_high); + ret = veml6046_write16(dev, VEML6046_CMDCODE_G_THDH_L, val); + if (ret) { + return ret; + } + + return 0; +} + +static int veml6046_write_thresh_low(const struct device *dev) +{ + int ret; + const struct veml6046_data *data = dev->data; + uint8_t val[2]; + + val[0] = data->thresh_low & 0xFF; + val[1] = data->thresh_low >> 8; + + LOG_DBG("Writing low threshold counts: %d", data->thresh_low); + ret = veml6046_write16(dev, VEML6046_CMDCODE_G_THDL_L, val); + if (ret) { + return ret; + } + + return 0; +} + +static int veml6046_fetch(const struct device *dev) +{ + struct veml6046_data *data = dev->data; + int ret; + + ret = veml6046_read16(dev, VEML6046_CMDCODE_R_DATA_L, &data->red_data); + if (ret) { + return ret; + } + + ret = veml6046_read16(dev, VEML6046_CMDCODE_G_DATA_L, &data->green_data); + if (ret) { + return ret; + } + + ret = veml6046_read16(dev, VEML6046_CMDCODE_B_DATA_L, &data->blue_data); + if (ret) { + return ret; + } + + ret = veml6046_read16(dev, VEML6046_CMDCODE_IR_DATA_L, &data->ir_data); + if (ret) { + return ret; + } + + data->red_lux = data->red_data * veml6046_resolution[data->pdd][data->gain][data->itim]; + data->green_lux = data->green_data * veml6046_resolution[data->pdd][data->gain][data->itim]; + data->blue_lux = data->blue_data * veml6046_resolution[data->pdd][data->gain][data->itim]; + data->ir_lux = data->ir_data * veml6046_resolution[data->pdd][data->gain][data->itim]; + + LOG_DBG("Read (R/G/B/IR): counts=%d/%d/%d/%d, lux=%d/%d/%d/%d", + data->red_data, data->green_data, data->blue_data, data->ir_data, + data->red_lux, data->green_lux, data->blue_lux, data->ir_lux); + + if ((data->red_data == VEML6046_DATA_OVERFLOW) || + (data->green_data == VEML6046_DATA_OVERFLOW) || + (data->blue_data == VEML6046_DATA_OVERFLOW) || + (data->ir_data == VEML6046_DATA_OVERFLOW)) { + return -E2BIG; + } + + return 0; +} + +static int veml6046_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + struct veml6046_data *data = dev->data; + + if (chan != SENSOR_CHAN_LIGHT) { + return -ENOTSUP; + } + + /* SENSOR_ATTR_.*_THRESH are not in enum sensor_attribute_veml6046 */ + switch ((int)attr) { + case SENSOR_ATTR_VEML6046_IT: + if (veml60xx_it_in_range(val->val1)) { + data->itim = (enum veml60xx_it)val->val1; + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_VEML6046_PDD: + if (veml6046_pdd_in_range(val->val1)) { + data->pdd = (enum veml6046_pdd)val->val1; + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_VEML6046_GAIN: + if (veml60xx_gain_in_range(val->val1)) { + data->gain = (enum veml60xx_gain)val->val1; + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_VEML6046_PERS: + if (veml60xx_pers_in_range(val->val1)) { + data->pers = (enum veml60xx_pers)val->val1; + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_LOWER_THRESH: + data->thresh_low = + val->val1 / veml6046_resolution[data->pdd][data->gain][data->itim]; + return veml6046_write_thresh_low(dev); + case SENSOR_ATTR_UPPER_THRESH: + data->thresh_high = + val->val1 / veml6046_resolution[data->pdd][data->gain][data->itim]; + return veml6046_write_thresh_high(dev); + default: + return -ENOTSUP; + } + + return 0; +} + +static int veml6046_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + struct veml6046_data *data = dev->data; + + if (chan != SENSOR_CHAN_LIGHT) { + return -ENOTSUP; + } + + /* SENSOR_ATTR_.*_THRESH are not in enum sensor_attribute_veml6046 */ + switch ((int)attr) { + case SENSOR_ATTR_VEML6046_IT: + val->val1 = data->itim; + break; + case SENSOR_ATTR_VEML6046_PDD: + val->val1 = data->pdd; + break; + case SENSOR_ATTR_VEML6046_GAIN: + val->val1 = data->gain; + break; + case SENSOR_ATTR_VEML6046_PERS: + val->val1 = data->pers; + break; + case SENSOR_ATTR_LOWER_THRESH: + val->val1 = data->thresh_low + * veml6046_resolution[data->pdd][data->gain][data->itim]; + break; + case SENSOR_ATTR_UPPER_THRESH: + val->val1 = data->thresh_high + * veml6046_resolution[data->pdd][data->gain][data->itim]; + break; + default: + return -ENOTSUP; + } + + val->val2 = 0; + + return 0; +} + +static int veml6046_perform_single_measurement(const struct device *dev) +{ + struct veml6046_data *data = dev->data; + int ret; + uint16_t val; + int cnt = 0; + + data->trig = 1; + data->int_en = 0; + data->sd = 0; + + ret = veml6046_write_conf(dev); + if (ret) { + return ret; + } + + ret = veml6046_read16(dev, VEML6046_CMDCODE_INT_L, &val); + if (ret) { + return ret; + } + + k_sleep(K_USEC(veml60xx_it_values[data->itim].us)); + + while (1) { + ret = veml6046_read16(dev, VEML6046_CMDCODE_INT_L, &val); + if (ret) { + return ret; + } + + if ((val >> 8) & VEML6046_AF_DATA_READY) { + break; + } + + if (cnt > 10) { + return -EAGAIN; + } + + k_sleep(K_USEC(veml60xx_it_values[data->itim].us / 10)); + + cnt++; + } + + LOG_DBG("read VEML6046_CMDCODE_INT_H: %02X (%d)", val >> 8, cnt); + + return 0; +} + +static int veml6046_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + int ret; + + /* Start sensor for new measurement */ + if (chan == SENSOR_CHAN_RED || chan == SENSOR_CHAN_GREEN || + chan == SENSOR_CHAN_BLUE || chan == SENSOR_CHAN_IR || + chan == SENSOR_CHAN_ALL) { + ret = veml6046_perform_single_measurement(dev); + if (ret < 0) { + return ret; + } + + return veml6046_fetch(dev); + } else { + return -ENOTSUP; + } + + return 0; +} + +static int veml6046_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct veml6046_data *data = dev->data; + + switch ((int)chan) { + case SENSOR_CHAN_RED: + val->val1 = data->red_lux; + break; + case SENSOR_CHAN_GREEN: + val->val1 = data->green_lux; + break; + case SENSOR_CHAN_BLUE: + val->val1 = data->blue_lux; + break; + case SENSOR_CHAN_IR: + val->val1 = data->ir_lux; + break; + case SENSOR_CHAN_VEML6046_RED_RAW_COUNTS: + val->val1 = data->red_data; + break; + case SENSOR_CHAN_VEML6046_GREEN_RAW_COUNTS: + val->val1 = data->green_data; + break; + case SENSOR_CHAN_VEML6046_BLUE_RAW_COUNTS: + val->val1 = data->blue_data; + break; + case SENSOR_CHAN_VEML6046_IR_RAW_COUNTS: + val->val1 = data->ir_data; + break; + default: + return -ENOTSUP; + } + + val->val2 = 0; + + return 0; +} + +#ifdef CONFIG_PM_DEVICE + +static int veml6046_set_shutdown_flag(const struct device *dev, uint8_t new_val) +{ + struct veml6046_data *data = dev->data; + uint8_t prev_sd; + int ret; + + prev_sd = data->sd; + data->sd = new_val; + + ret = veml6046_write_conf(dev); + if (ret < 0) { + data->sd = prev_sd; + } + return ret; +} + +static int veml6046_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + return veml6046_set_shutdown_flag(dev, 1); + + case PM_DEVICE_ACTION_RESUME: + return veml6046_set_shutdown_flag(dev, 0); + + default: + return -ENOTSUP; + } + return 0; +} + +#endif /* CONFIG_PM_DEVICE */ + +static int veml6046_init(const struct device *dev) +{ + const struct veml6046_config *conf = dev->config; + int ret; + uint16_t val; + + if (!i2c_is_ready_dt(&conf->bus)) { + LOG_ERR("VEML device not ready"); + return -ENODEV; + } + + ret = veml6046_read16(dev, VEML6046_CMDCODE_ID_L, &val); + if (ret) { + LOG_ERR("Error while reading ID. ret: %d", ret); + return ret; + } + if ((val & 0x00FF) != VEML6046_DEFAULT_ID) { + LOG_ERR("Device ID wrong: %d", val & 0x00FF); + return -EIO; + } + + LOG_DBG("veml6046 found package: %02d address: %02X version: %3s", + val >> 14, val >> 12 & 0x03 ? 0x10 : 0x29, + val >> 8 & 0x0F ? "XXX" : "A01"); + + /* Initialize sensor configuration */ + ret = veml6046_write_thresh_low(dev); + if (ret < 0) { + LOG_ERR("Error while writing thresh low. ret: %d", ret); + return ret; + } + + ret = veml6046_write_thresh_high(dev); + if (ret < 0) { + LOG_ERR("Error while writing thresh high. ret: %d", ret); + return ret; + } + + ret = veml6046_write_conf(dev); + if (ret < 0) { + LOG_ERR("Error while writing config. ret: %d", ret); + return ret; + } + + return 0; +} + +static DEVICE_API(sensor, veml6046_api) = { + .sample_fetch = veml6046_sample_fetch, + .channel_get = veml6046_channel_get, + .attr_set = veml6046_attr_set, + .attr_get = veml6046_attr_get, +}; + +#define VEML6046_INIT(n) \ + static struct veml6046_data veml6046_data_##n = {.trig = 0, \ + .pdd = VEML6046_SIZE_2_2, \ + .gain = VEML60XX_GAIN_1, \ + .itim = VEML60XX_IT_100, \ + .pers = VEML60XX_PERS_1, \ + .thresh_high = 0xFFFF}; \ + \ + static const struct veml6046_config veml6046_config_##n = { \ + .bus = I2C_DT_SPEC_INST_GET(n)}; \ + \ + PM_DEVICE_DT_INST_DEFINE(n, veml6046_pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, veml6046_init, PM_DEVICE_DT_INST_GET(n), \ + &veml6046_data_##n, &veml6046_config_##n, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &veml6046_api); + +DT_INST_FOREACH_STATUS_OKAY(VEML6046_INIT) diff --git a/drivers/serial/Kconfig.silabs_eusart b/drivers/serial/Kconfig.silabs_eusart index e13d80d37ec69..0d206f6624327 100644 --- a/drivers/serial/Kconfig.silabs_eusart +++ b/drivers/serial/Kconfig.silabs_eusart @@ -8,7 +8,7 @@ config UART_SILABS_EUSART depends on DT_HAS_SILABS_EUSART_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - select SOC_GECKO_EUSART + select SILABS_SISDK_EUSART select SERIAL_SUPPORT_ASYNC \ if DT_HAS_SILABS_LDMA_ENABLED select DMA if UART_ASYNC_API diff --git a/drivers/serial/Kconfig.silabs_usart b/drivers/serial/Kconfig.silabs_usart index a2088577d42af..6d0a9318929f6 100644 --- a/drivers/serial/Kconfig.silabs_usart +++ b/drivers/serial/Kconfig.silabs_usart @@ -7,7 +7,7 @@ config UART_SILABS_USART depends on DT_HAS_SILABS_USART_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - select SOC_GECKO_USART + select SILABS_SISDK_USART select SERIAL_SUPPORT_ASYNC \ if DT_HAS_SILABS_LDMA_ENABLED select DMA if UART_ASYNC_API diff --git a/drivers/serial/uart_renesas_rx_sci.c b/drivers/serial/uart_renesas_rx_sci.c index aa9de7963c59b..afbc0d003c447 100644 --- a/drivers/serial/uart_renesas_rx_sci.c +++ b/drivers/serial/uart_renesas_rx_sci.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "r_sci_rx_if.h" #include "iodefine_sci.h" @@ -60,6 +62,8 @@ static void uart_rx_sci_txi_isr(const struct device *dev); struct uart_rx_sci_config { uint32_t regs; const struct pinctrl_dev_config *pcfg; + const struct device *clock; + struct clock_control_rx_subsys_cfg clock_subsys; }; struct uart_rx_sci_data { @@ -293,6 +297,9 @@ static void uart_rx_irq_tx_enable(const struct device *dev) sci->SCR.BYTE |= (BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); irq_enable(data->tei_irq); +#ifdef CONFIG_PM_DEVICE + pm_device_busy_set(dev); +#endif } static void uart_rx_irq_tx_disable(const struct device *dev) @@ -302,6 +309,9 @@ static void uart_rx_irq_tx_disable(const struct device *dev) sci->SCR.BYTE &= ~(BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); irq_disable(data->tei_irq); +#ifdef CONFIG_PM_DEVICE + pm_device_busy_clear(dev); +#endif } static int uart_rx_irq_tx_ready(const struct device *dev) @@ -324,6 +334,9 @@ static void uart_rx_irq_rx_enable(const struct device *dev) volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.RIE = 1U; +#ifdef CONFIG_PM_DEVICE + pm_device_busy_set(dev); +#endif } static void uart_rx_irq_rx_disable(const struct device *dev) @@ -331,6 +344,9 @@ static void uart_rx_irq_rx_disable(const struct device *dev) volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.RIE = 0U; +#ifdef CONFIG_PM_DEVICE + pm_device_busy_clear(dev); +#endif } static int uart_rx_irq_rx_ready(const struct device *dev) @@ -532,6 +548,11 @@ static int uart_rx_sci_async_tx(const struct device *dev, const uint8_t *buf, si goto end; } +#ifdef CONFIG_PM + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif + enable_tx(dev); data->tx_buffer = (uint8_t *)buf; data->tx_buf_cap = len; @@ -804,14 +825,12 @@ static int uart_rx_init(const struct device *dev) #endif sci_err = R_SCI_Open(data->channel, SCI_MODE_ASYNC, &data->sci_config, NULL, &data->hdl); - if (sci_err) { return -EIO; } /* Set the Asynchronous Start Bit Edge Detection Select to falling edge on the RXDn pin */ sci_err = R_SCI_Control(data->hdl, SCI_CMD_START_BIT_EDGE, FIT_NO_PTR); - if (sci_err) { return -EIO; } @@ -819,6 +838,37 @@ static int uart_rx_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int uart_rx_sci_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct uart_rx_sci_config *config = dev->config; + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = clock_control_on(config->clock, + (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + break; + + case PM_DEVICE_ACTION_SUSPEND: + ret = clock_control_off(config->clock, + (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif + static DEVICE_API(uart, uart_rx_driver_api) = { .poll_in = uart_rx_sci_poll_in, .poll_out = uart_rx_sci_poll_out, @@ -924,6 +974,10 @@ static void uart_rx_sci_tei_isr(const struct device *dev) .data.tx.len = data->tx_buf_cap, }; async_user_callback(dev, &event); +#ifdef CONFIG_PM + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif #endif } @@ -1043,6 +1097,12 @@ static void uart_rx_sci_eri_isr(const struct device *dev) static const struct uart_rx_sci_config uart_rx_sci_config_##index = { \ .regs = DT_REG_ADDR(DT_INST_PARENT(index)), \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(index)), \ + .clock = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(index))), \ + .clock_subsys = \ + { \ + .mstp = DT_CLOCKS_CELL(DT_INST_PARENT(index), mstp), \ + .stop_bit = DT_CLOCKS_CELL(DT_INST_PARENT(index), stop_bit), \ + }, \ }; \ \ static struct uart_rx_sci_data uart_rx_sci_data_##index = { \ @@ -1068,9 +1128,9 @@ static void uart_rx_sci_eri_isr(const struct device *dev) } \ return 0; \ }; \ - \ - DEVICE_DT_INST_DEFINE(index, uart_rx_init_##index, NULL, &uart_rx_sci_data_##index, \ - &uart_rx_sci_config_##index, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, &uart_rx_driver_api); + PM_DEVICE_DT_INST_DEFINE(index, uart_rx_sci_pm_action); \ + DEVICE_DT_INST_DEFINE(index, uart_rx_init_##index, PM_DEVICE_DT_INST_GET(index), \ + &uart_rx_sci_data_##index, &uart_rx_sci_config_##index, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, &uart_rx_driver_api); DT_INST_FOREACH_STATUS_OKAY(UART_RX_INIT) diff --git a/drivers/serial/uart_silabs_eusart.c b/drivers/serial/uart_silabs_eusart.c index 5def91e1d3ab8..9424fdb5106f0 100644 --- a/drivers/serial/uart_silabs_eusart.c +++ b/drivers/serial/uart_silabs_eusart.c @@ -470,9 +470,12 @@ __maybe_unused static void eusart_dma_tx_cb(const struct device *dma_dev, void * { const struct device *uart_dev = user_data; struct eusart_data *data = uart_dev->data; + const struct eusart_config *config = uart_dev->config; dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); data->dma_tx.enabled = false; + + EUSART_IntEnable(config->eusart, EUSART_IF_TXC); } static int eusart_async_tx(const struct device *dev, const uint8_t *tx_data, size_t buf_size, @@ -500,7 +503,6 @@ static int eusart_async_tx(const struct device *dev, const uint8_t *tx_data, siz eusart_pm_lock_get(dev, EUSART_PM_LOCK_TX); EUSART_IntClear(config->eusart, EUSART_IF_TXC); - EUSART_IntEnable(config->eusart, EUSART_IF_TXC); ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &data->dma_tx.dma_cfg); if (ret) { diff --git a/drivers/serial/uart_silabs_usart.c b/drivers/serial/uart_silabs_usart.c index e0482bafe1fa6..bfb5a2362801f 100644 --- a/drivers/serial/uart_silabs_usart.c +++ b/drivers/serial/uart_silabs_usart.c @@ -461,9 +461,12 @@ void uart_silabs_dma_tx_cb(const struct device *dma_dev, void *user_data, uint32 { const struct device *uart_dev = user_data; struct uart_silabs_data *data = uart_dev->data; + const struct uart_silabs_config *config = uart_dev->config; dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); data->dma_tx.enabled = false; + + USART_IntEnable(config->base, USART_IF_TXC); } static int uart_silabs_async_tx(const struct device *dev, const uint8_t *tx_data, size_t buf_size, @@ -499,7 +502,6 @@ static int uart_silabs_async_tx(const struct device *dev, const uint8_t *tx_data (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX); USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2); - USART_IntEnable(config->base, USART_IF_TXC); if (timeout >= 0) { USART_IntEnable(config->base, USART_IF_TCMP2); } @@ -537,11 +539,12 @@ static int uart_silabs_async_tx_abort(const struct device *dev) USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2); (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX); + dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); + if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) { data->dma_tx.counter = tx_buffer_length - stat.pending_length; } - dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); data->dma_tx.enabled = false; async_evt_tx_abort(data); diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index 6ceda851b1e17..7425ace593281 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -54,11 +54,13 @@ zephyr_library_sources_ifdef(CONFIG_SPI_PW spi_pw.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_RX spi_renesas_rx.c) +zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RZ spi_renesas_rz.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RZ_RSPI spi_renesas_rz_rspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_RPI_PICO_PIO spi_rpi_pico_pio.c) zephyr_library_sources_ifdef(CONFIG_SPI_RV32M1_LPSPI spi_rv32m1_lpspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_SAM spi_sam.c) zephyr_library_sources_ifdef(CONFIG_SPI_SAM0 spi_sam0.c) +zephyr_library_sources_ifdef(CONFIG_SPI_SC18IS606 spi_sc18is606.c) zephyr_library_sources_ifdef(CONFIG_SPI_SEDI spi_sedi.c) zephyr_library_sources_ifdef(CONFIG_SPI_SIFIVE spi_sifive.c) zephyr_library_sources_ifdef(CONFIG_SPI_SILABS_EUSART spi_silabs_eusart.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a083f021c7533..d97de01b04f52 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -137,6 +137,7 @@ source "drivers/spi/Kconfig.rpi_pico" source "drivers/spi/Kconfig.rv32m1_lpspi" source "drivers/spi/Kconfig.sam" source "drivers/spi/Kconfig.sam0" +source "drivers/spi/Kconfig.sc18is606" source "drivers/spi/Kconfig.sedi" source "drivers/spi/Kconfig.sifive" source "drivers/spi/Kconfig.silabs_eusart" diff --git a/drivers/spi/Kconfig.renesas_rz b/drivers/spi/Kconfig.renesas_rz index d379e691767da..fc52532a13672 100644 --- a/drivers/spi/Kconfig.renesas_rz +++ b/drivers/spi/Kconfig.renesas_rz @@ -23,6 +23,32 @@ config SPI_RENESAS_RZ_RSPI_DMAC help Enable the SPI DMA mode for SPI instances +endif # SPI_RENESAS_RZ_RSPI + +config SPI_RENESAS_RZ + bool "Renesas RZ SPI" + default y + depends on DT_HAS_RENESAS_RZ_SPI_ENABLED + select USE_RZ_FSP_SPI + select PINCTRL + help + Enable Renesas RZ SPI Driver. + +if SPI_RENESAS_RZ + +config SPI_RENESAS_RZ_INTERRUPT + bool "RZ SPI Interrupt Support" + help + Enable Interrupt support for the SPI. + +config SPI_USE_HW_SS + bool "RZ SPI Hardware Peripheral Select support" + default y + help + Use Hardware Peripheral Select instead of Software Peripheral Select. + +endif # SPI_RENESAS_RZ + if SPI_RTIO config SPI_RTIO_SQ_SIZE int "Number of available submission queue entries" @@ -40,5 +66,3 @@ config SPI_RTIO_CQ_SIZE default 8 # Sensible default that covers most common spi transactions endif # SPI_RTIO - -endif # SPI_RENESAS_RZ_RSPI diff --git a/drivers/spi/Kconfig.sc18is606 b/drivers/spi/Kconfig.sc18is606 new file mode 100644 index 0000000000000..acf2790a5afaf --- /dev/null +++ b/drivers/spi/Kconfig.sc18is606 @@ -0,0 +1,22 @@ +# Copyright (c) 2025, tinyvision.ai +# SPDX-License-Identifier: Apache-2.0 + +config SPI_SC18IS606 + bool "NXP SC18IS606 SPI controller driver" + default y + select I2C + depends on DT_HAS_NXP_SC18IS606_SPI_ENABLED + help + Enable driver for the NXP SC18IS606 SPI controller driver + +if SPI_SC18IS606 + +config SPI_SC18IS606_INIT_PRIORITY + int "SC18IS606 SPI init priority" + default 59 + help + SC18IS606 SPI controller initialization priority + + Note: Has to be greater than the I2C initialization priority. + +endif diff --git a/drivers/spi/Kconfig.silabs_eusart b/drivers/spi/Kconfig.silabs_eusart index a2644fd13ed8e..408f2460eecdf 100644 --- a/drivers/spi/Kconfig.silabs_eusart +++ b/drivers/spi/Kconfig.silabs_eusart @@ -9,7 +9,7 @@ config SPI_SILABS_EUSART default y depends on DT_HAS_SILABS_EUSART_SPI_ENABLED depends on GPIO - select SOC_GECKO_EUSART + select SILABS_SISDK_EUSART select PINCTRL if SOC_FAMILY_SILABS_S2 help Enable the EUSART SPI driver diff --git a/drivers/spi/Kconfig.silabs_usart b/drivers/spi/Kconfig.silabs_usart index 23a93a5784720..2ad5843bdd983 100644 --- a/drivers/spi/Kconfig.silabs_usart +++ b/drivers/spi/Kconfig.silabs_usart @@ -8,7 +8,8 @@ config SPI_SILABS_USART default y depends on DT_HAS_SILABS_USART_SPI_ENABLED depends on GPIO - select SOC_GECKO_USART + select SOC_GECKO_USART if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 + select SILABS_SISDK_USART if SOC_FAMILY_SILABS_S2 select CLOCK_CONTROL_SILABS_SERIES if SOC_FAMILY_SILABS_S2 select PINCTRL if SOC_FAMILY_SILABS_S2 help diff --git a/drivers/spi/spi_max32.c b/drivers/spi/spi_max32.c index 2e149507f59c5..5b553d901b678 100644 --- a/drivers/spi/spi_max32.c +++ b/drivers/spi/spi_max32.c @@ -205,6 +205,37 @@ static void spi_max32_setup(mxc_spi_regs_t *spi, mxc_spi_req_t *req, uint8_t dfs MXC_SPI_ClearFlags(spi); } +static void spi_cs_assert(const struct device *dev) +{ + const struct max32_spi_config *cfg = dev->config; + struct max32_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + if (spi_cs_is_gpio(ctx->config)) { + MXC_SPI_HWSSControl(cfg->regs, false); + spi_context_cs_control(ctx, true); + } else { + MXC_SPI_HWSSControl(cfg->regs, true); + cfg->regs->ctrl0 = (cfg->regs->ctrl0 & ~MXC_F_SPI_CTRL0_START) | + ADI_MAX32_SPI_CTRL0_SS_CTRL; + } +} + +static void spi_cs_deassert(const struct device *dev) +{ + const struct max32_spi_config *cfg = dev->config; + struct max32_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + if (spi_cs_is_gpio(ctx->config)) { + spi_context_cs_control(ctx, false); + } else { + cfg->regs->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL | + ADI_MAX32_SPI_CTRL_EN); + cfg->regs->ctrl0 |= ADI_MAX32_SPI_CTRL_EN; + } +} + #ifndef CONFIG_SPI_MAX32_INTERRUPT static int spi_max32_transceive_sync(mxc_spi_regs_t *spi, struct max32_spi_data *data, uint8_t dfs_shift) @@ -228,15 +259,23 @@ static int spi_max32_transceive_sync(mxc_spi_regs_t *spi, struct max32_spi_data req->txCnt += MXC_SPI_WriteTXFIFO(spi, &req->txData[req->txCnt], remain); } - if (!(spi->ctrl0 & MXC_F_SPI_CTRL0_START)) { - spi->ctrl0 |= MXC_F_SPI_CTRL0_START; - } } if (req->rxCnt < rx_len) { req->rxCnt += MXC_SPI_ReadRXFIFO(spi, &req->rxData[req->rxCnt], rx_len - req->rxCnt); } + + if (!(spi->ctrl0 & MXC_F_SPI_CTRL0_START)) { + /* Transfer not started */ + if ((MXC_SPI_GetTXFIFOAvailable(spi) - MXC_SPI_FIFO_DEPTH) > 0) { + /* Data remaining in the TX FIFO, ensure TX started */ + spi->ctrl0 |= MXC_F_SPI_CTRL0_START; + } else if (MXC_SPI_GetRXFIFOAvailable(spi) < (rx_len - req->rxCnt)) { + /* Not enough data into the RX FIFO */ + spi->ctrl0 |= MXC_F_SPI_CTRL0_START; + } + } } while ((req->txCnt < tx_len) || (req->rxCnt < rx_len)); do { @@ -307,7 +346,19 @@ static int spi_max32_transceive(const struct device *dev) break; } #else - data->req.txLen = len; + if ((ctx->config->operation & SPI_HALF_DUPLEX) +#if defined(CONFIG_SPI_EXTENDED_MODES) + || (ctx->config->operation & SPI_LINES_DUAL) + || (ctx->config->operation & SPI_LINES_QUAD) + || (ctx->config->operation & SPI_LINES_OCTAL) +#endif + ) { + /* Half duplex mode, tx should be set only if no rx */ + data->req.txLen = ctx->tx_buf ? len : 0; + } else { + /* Full duplex mode, tx and rx can be set independently */ + data->req.txLen = len; + } data->req.txData = (uint8_t *)ctx->tx_buf; data->req.rxLen = len; data->req.rxData = ctx->rx_buf; @@ -375,10 +426,6 @@ static int transceive(const struct device *dev, const struct spi_config *config, int ret = 0; struct max32_spi_data *data = dev->data; struct spi_context *ctx = &data->ctx; -#ifndef CONFIG_SPI_RTIO - const struct max32_spi_config *cfg = dev->config; - bool hw_cs_ctrl = true; -#endif #ifndef CONFIG_SPI_MAX32_INTERRUPT if (async) { @@ -397,19 +444,8 @@ static int transceive(const struct device *dev, const struct spi_config *config, spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); - /* Check if CS GPIO exists */ - if (spi_cs_is_gpio(config)) { - hw_cs_ctrl = false; - } - MXC_SPI_HWSSControl(cfg->regs, hw_cs_ctrl); - - /* Assert the CS line if HW control disabled */ - if (!hw_cs_ctrl) { - spi_context_cs_control(ctx, true); - } else { - cfg->regs->ctrl0 = - (cfg->regs->ctrl0 & ~MXC_F_SPI_CTRL0_START) | ADI_MAX32_SPI_CTRL0_SS_CTRL; - } + /* Assert the CS line */ + spi_cs_assert(dev); #ifdef CONFIG_SPI_MAX32_INTERRUPT do { @@ -433,15 +469,9 @@ static int transceive(const struct device *dev, const struct spi_config *config, #endif /* CONFIG_SPI_MAX32_INTERRUPT */ - /* Deassert the CS line if hw control disabled */ - if (!async) { - if (!hw_cs_ctrl) { - spi_context_cs_control(ctx, false); - } else { - cfg->regs->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL | - ADI_MAX32_SPI_CTRL_EN); - cfg->regs->ctrl0 |= ADI_MAX32_SPI_CTRL_EN; - } + /* Deassert the CS line if hold mode is not enabled */ + if (!async && !(ctx->config->operation & SPI_HOLD_ON_CS)) { + spi_cs_deassert(dev); } #else /* Guard against unsupported word lengths here, as spi_configure is @@ -573,8 +603,6 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con uint32_t len, word_count; uint8_t dfs_shift; - bool hw_cs_ctrl = true; - spi_context_lock(ctx, async, cb, userdata, config); MXC_SPI_ClearTXFIFO(spi); @@ -605,18 +633,8 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); - /* Check if CS GPIO exists */ - if (spi_cs_is_gpio(config)) { - hw_cs_ctrl = false; - } - MXC_SPI_HWSSControl(cfg->regs, hw_cs_ctrl); - - /* Assert the CS line if HW control disabled */ - if (!hw_cs_ctrl) { - spi_context_cs_control(ctx, true); - } else { - spi->ctrl0 = (spi->ctrl0 & ~MXC_F_SPI_CTRL0_START) | ADI_MAX32_SPI_CTRL0_SS_CTRL; - } + /* Assert the CS line */ + spi_cs_assert(dev); MXC_SPI_SetSlave(cfg->regs, ctx->config->slave); @@ -665,14 +683,8 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con } unlock: - /* Deassert the CS line if hw control disabled */ - if (!hw_cs_ctrl) { - spi_context_cs_control(ctx, false); - } else { - spi->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL | - ADI_MAX32_SPI_CTRL_EN); - spi->ctrl0 |= ADI_MAX32_SPI_CTRL_EN; - } + /* Deassert the CS line */ + spi_cs_deassert(dev); spi_context_release(ctx, ret); @@ -712,26 +724,12 @@ static inline void spi_max32_iodev_prepare_start(const struct device *dev) struct spi_rtio *rtio_ctx = data->rtio_ctx; struct spi_dt_spec *spi_dt_spec = rtio_ctx->txn_curr->sqe.iodev->data; struct spi_config *spi_config = &spi_dt_spec->config; - struct max32_spi_config *cfg = (struct max32_spi_config *)dev->config; int ret; - bool hw_cs_ctrl = true; ret = spi_configure(dev, spi_config); __ASSERT(!ret, "%d", ret); - /* Check if CS GPIO exists */ - if (spi_cs_is_gpio(spi_config)) { - hw_cs_ctrl = false; - } - MXC_SPI_HWSSControl(cfg->regs, hw_cs_ctrl); - - /* Assert the CS line if HW control disabled */ - if (!hw_cs_ctrl) { - spi_context_cs_control(&data->ctx, true); - } else { - cfg->regs->ctrl0 = - (cfg->regs->ctrl0 & ~MXC_F_SPI_CTRL0_START) | MXC_F_SPI_CTRL0_SS_CTRL; - }; + spi_cs_assert(dev); } static void spi_max32_iodev_complete(const struct device *dev, int status) @@ -743,16 +741,7 @@ static void spi_max32_iodev_complete(const struct device *dev, int status) rtio_ctx->txn_curr = rtio_txn_next(rtio_ctx->txn_curr); spi_max32_iodev_start(dev); } else { - struct max32_spi_config *cfg = (struct max32_spi_config *)dev->config; - bool hw_cs_ctrl = true; - - if (!hw_cs_ctrl) { - spi_context_cs_control(&data->ctx, false); - } else { - cfg->regs->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | MXC_F_SPI_CTRL0_SS_CTRL | - ADI_MAX32_SPI_CTRL_EN); - cfg->regs->ctrl0 |= ADI_MAX32_SPI_CTRL_EN; - } + spi_cs_deassert(dev); if (spi_rtio_complete(rtio_ctx, status)) { spi_max32_iodev_prepare_start(dev); @@ -820,13 +809,7 @@ static void spi_max32_callback(mxc_spi_req_t *req, int error) if (ctx->asynchronous && ((spi_context_tx_on(ctx) || spi_context_rx_on(ctx)))) { k_work_submit(&data->async_work); } else { - if (spi_cs_is_gpio(ctx->config)) { - spi_context_cs_control(ctx, false); - } else { - req->spi->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL | - ADI_MAX32_SPI_CTRL_EN); - req->spi->ctrl0 |= ADI_MAX32_SPI_CTRL_EN; - } + spi_cs_deassert(dev); spi_context_complete(ctx, dev, error == E_NO_ERROR ? 0 : -EIO); } #else @@ -900,12 +883,17 @@ static void spi_max32_isr(const struct device *dev) static int api_release(const struct device *dev, const struct spi_config *config) { struct max32_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; #ifndef CONFIG_SPI_RTIO if (!spi_context_configured(&data->ctx, config)) { return -EINVAL; } #endif + + if (ctx->config->operation & SPI_HOLD_ON_CS) { + spi_cs_deassert(dev); + } spi_context_unlock_unconditionally(&data->ctx); return 0; } diff --git a/drivers/spi/spi_renesas_rz.c b/drivers/spi/spi_renesas_rz.c new file mode 100644 index 0000000000000..34dc519db6b1e --- /dev/null +++ b/drivers/spi/spi_renesas_rz.c @@ -0,0 +1,779 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_spi + +#include +#include +#include +#include +#include +#include "r_spi.h" +#ifdef CONFIG_SPI_RTIO +#include +#include +#endif +#include + +LOG_MODULE_REGISTER(rz_spi); + +#define LOG_DEV_ERR(dev, format, ...) LOG_ERR("%s:" #format, (dev)->name, ##__VA_ARGS__) + +#include "spi_context.h" + +#define SPI_RZ_SPSRC_CLR 0xFD80 +#define SPI_RZ_TRANSMIT_RECEIVE 0x0 +#define SPI_RZ_TX_ONLY 0x1 + +struct spi_rz_config { + const struct pinctrl_dev_config *pinctrl_dev; + const spi_api_t *fsp_api; + spi_clock_source_t clock_source; +}; + +struct spi_rz_data { + struct spi_context ctx; + uint8_t dfs; + uint32_t data_len; + spi_cfg_t *fsp_config; + spi_instance_ctrl_t *fsp_ctrl; +#ifdef CONFIG_SPI_RTIO + struct spi_rtio *rtio_ctx; +#endif /* CONFIG_SPI_RTIO */ +}; + +#if defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) +void spi_rxi_isr(void); +void spi_txi_isr(void); +void spi_tei_isr(void); +void spi_eri_isr(void); +#endif /* CONFIG_SPI_RENESAS_RZ_INTERRUPT */ + +#ifdef CONFIG_SPI_RTIO +static void spi_rz_iodev_complete(const struct device *dev, int status); +#else +static bool spi_rz_transfer_ongoing(struct spi_rz_data *data) +{ +#if defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) + return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); +#else + if (spi_context_total_tx_len(&data->ctx) == spi_context_total_rx_len(&data->ctx)) { + return (spi_context_tx_on(&data->ctx) && spi_context_rx_on(&data->ctx)); + } else { + return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); + } +#endif +} +#endif /* CONFIG_SPI_RTIO */ + +static void spi_callback(spi_callback_args_t *p_args) +{ + struct device *dev = (struct device *)p_args->p_context; + struct spi_rz_data *data = dev->data; + + switch (p_args->event) { + case SPI_EVENT_TRANSFER_COMPLETE: + spi_context_cs_control(&data->ctx, false); +#ifdef CONFIG_SPI_RTIO + struct spi_rtio *rtio_ctx = data->rtio_ctx; + + if (rtio_ctx->txn_head != NULL) { + spi_rz_iodev_complete(dev, 0); + } +#endif + spi_context_complete(&data->ctx, dev, 0); + break; + case SPI_EVENT_ERR_MODE_FAULT: /* Mode fault error */ + case SPI_EVENT_ERR_READ_OVERFLOW: /* Read overflow error */ + case SPI_EVENT_ERR_PARITY: /* Parity error */ + case SPI_EVENT_ERR_OVERRUN: /* Overrun error */ + case SPI_EVENT_ERR_FRAMING: /* Framing error */ + case SPI_EVENT_ERR_MODE_UNDERRUN: /* Underrun error */ + spi_context_cs_control(&data->ctx, false); + spi_context_complete(&data->ctx, dev, -EIO); + break; + default: + break; + } +} + +static int spi_rz_configure(const struct device *dev, const struct spi_config *spi_cfg) +{ + struct spi_rz_data *data = dev->data; + const struct spi_rz_config *config = dev->config; + spi_extended_cfg_t *spi_extend = (spi_extended_cfg_t *)data->fsp_config->p_extend; + fsp_err_t err; + + if (spi_context_configured(&data->ctx, spi_cfg)) { + /* This configuration is already in use */ + return 0; + } + + if (data->fsp_ctrl->open != 0) { + config->fsp_api->close(data->fsp_ctrl); + } + + if (spi_cfg->operation & SPI_FRAME_FORMAT_TI) { + LOG_ERR("TI frame not supported"); + return -ENOTSUP; + } + + if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) && + (spi_cfg->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_DEV_ERR(dev, "Only single line mode is supported"); + return -ENOTSUP; + } + + /* SPI mode */ + if (spi_cfg->operation & SPI_OP_MODE_SLAVE) { + data->fsp_config->operating_mode = SPI_MODE_SLAVE; + } else { + data->fsp_config->operating_mode = SPI_MODE_MASTER; + } + + /* SPI POLARITY */ + if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { + data->fsp_config->clk_polarity = SPI_CLK_POLARITY_HIGH; + } else { + data->fsp_config->clk_polarity = SPI_CLK_POLARITY_LOW; + } + + /* SPI PHASE */ + if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) { + data->fsp_config->clk_phase = SPI_CLK_PHASE_EDGE_EVEN; + } else { + data->fsp_config->clk_phase = SPI_CLK_PHASE_EDGE_ODD; + } + + /* SPI bit order */ + if (spi_cfg->operation & SPI_TRANSFER_LSB) { + data->fsp_config->bit_order = SPI_BIT_ORDER_LSB_FIRST; + } else { + data->fsp_config->bit_order = SPI_BIT_ORDER_MSB_FIRST; + } + + data->dfs = ((SPI_WORD_SIZE_GET(spi_cfg->operation) - 1) / 8) + 1; + data->fsp_ctrl->bit_width = (spi_bit_width_t)(SPI_WORD_SIZE_GET(spi_cfg->operation) - 1); + if ((data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_32_BITS) || + (data->fsp_ctrl->bit_width < SPI_BIT_WIDTH_4_BITS)) { + LOG_ERR("Unsupported SPI word size: %u", SPI_WORD_SIZE_GET(spi_cfg->operation)); + return -ENOTSUP; + } + + /* SPI slave select polarity */ + if (spi_cfg->operation & SPI_CS_ACTIVE_HIGH) { + spi_extend->ssl_polarity = SPI_SSLP_HIGH; + } else { + spi_extend->ssl_polarity = SPI_SSLP_LOW; + } + + /* Calculate bitrate */ + if ((spi_cfg->frequency > 0) && (!(spi_cfg->operation & SPI_OP_MODE_SLAVE))) { + err = R_SPI_CalculateBitrate(spi_cfg->frequency, config->clock_source, + &spi_extend->spck_div); + + if (err != FSP_SUCCESS) { + LOG_DEV_ERR(dev, "spi: bitrate calculate error: %d", err); + return -ENOSYS; + } + } + + spi_extend->spi_comm = SPI_COMMUNICATION_FULL_DUPLEX; + + if (spi_cs_is_gpio(spi_cfg) || !IS_ENABLED(CONFIG_SPI_USE_HW_SS)) { + if ((spi_cfg->operation & SPI_OP_MODE_SLAVE) && + (data->fsp_config->clk_phase == SPI_CLK_PHASE_EDGE_ODD)) { + LOG_DEV_ERR(dev, "The CPHA bit must be set to 1 slave mode"); + return -EIO; + } + spi_extend->spi_clksyn = SPI_SSL_MODE_CLK_SYN; + } else { + spi_extend->spi_clksyn = SPI_SSL_MODE_SPI; + switch (spi_cfg->slave) { + case 0: + spi_extend->ssl_select = SPI_SSL_SELECT_SSL0; + break; + case 1: + spi_extend->ssl_select = SPI_SSL_SELECT_SSL1; + break; + case 2: + spi_extend->ssl_select = SPI_SSL_SELECT_SSL2; + break; + case 3: + spi_extend->ssl_select = SPI_SSL_SELECT_SSL3; + break; + default: + LOG_ERR("Invalid SSL"); + return -EINVAL; + } + } + + spi_extend->receive_fifo_threshold = 0; + spi_extend->transmit_fifo_threshold = 0; + + /* Open module r_spi. */ + err = config->fsp_api->open(data->fsp_ctrl, data->fsp_config); + if (err != FSP_SUCCESS) { + LOG_ERR("R_SPI_Open error: %d", err); + return -EIO; + } + + data->ctx.config = spi_cfg; + + return 0; +} + +#if !defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) +static int spi_rz_spi_transceive_data(struct spi_rz_data *data) +{ + uint32_t tx; + uint32_t rx; + + if (spi_context_tx_buf_on(&data->ctx)) { + if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_16_BITS) { + tx = *(uint32_t *)(data->ctx.tx_buf); + } else if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_8_BITS) { + tx = *(uint16_t *)(data->ctx.tx_buf); + } else { + tx = *(uint8_t *)(data->ctx.tx_buf); + } + } else { + tx = 0U; + } + + while (!data->fsp_ctrl->p_regs->SPSR_b.SPTEF) { + } + + /* TX transfer */ + if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_16_BITS) { + data->fsp_ctrl->p_regs->SPDR = (uint32_t)tx; + } else if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_8_BITS) { + data->fsp_ctrl->p_regs->SPDR = (uint16_t)tx; + } else { + data->fsp_ctrl->p_regs->SPDR = (uint8_t)tx; + } + + data->fsp_ctrl->p_regs->SPSRC_b.SPTEFC = 1; /* Clear SPTEF flag */ + spi_context_update_tx(&data->ctx, data->dfs, 1); + + if (data->fsp_ctrl->p_regs->SPCR_b.TXMD == 0x0) { + while (!data->fsp_ctrl->p_regs->SPSR_b.SPRF) { + } + + if (SPI_BIT_WIDTH_16_BITS < data->fsp_ctrl->bit_width) { + rx = (uint32_t)data->fsp_ctrl->p_regs->SPDR; + } else if (SPI_BIT_WIDTH_8_BITS >= data->fsp_ctrl->bit_width) { + rx = (uint8_t)data->fsp_ctrl->p_regs->SPDR; + } else { + rx = (uint16_t)data->fsp_ctrl->p_regs->SPDR; + } + + /* RX transfer */ + if (spi_context_rx_buf_on(&data->ctx)) { + + /* Read data from Data Register */ + if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_16_BITS) { + UNALIGNED_PUT(rx, (uint32_t *)data->ctx.rx_buf); + } else if (data->fsp_ctrl->bit_width > SPI_BIT_WIDTH_8_BITS) { + UNALIGNED_PUT(rx, (uint16_t *)data->ctx.rx_buf); + } else { + UNALIGNED_PUT(rx, (uint8_t *)data->ctx.rx_buf); + } + } + spi_context_update_rx(&data->ctx, data->dfs, 1); + data->fsp_ctrl->p_regs->SPSRC_b.SPRFC = 1; /* Clear SPRF flag */ + } + return 0; +} +#endif /* CONFIG_SPI_RENESAS_RZ_INTERRUPT */ + +static int transceive(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + struct spi_rz_data *data = dev->data; + struct spi_context *spi_ctx = &data->ctx; + int ret = 0; + + if (!tx_bufs && !rx_bufs) { + return 0; + } + +#ifndef CONFIG_SPI_RENESAS_RZ_INTERRUPT + if (asynchronous) { + return -ENOTSUP; + } +#endif + spi_context_lock(spi_ctx, asynchronous, cb, userdata, spi_cfg); + /* Configure module SPI. */ + ret = spi_rz_configure(dev, spi_cfg); + if (ret) { + spi_context_release(spi_ctx, ret); + return -EIO; + } +#ifndef CONFIG_SPI_RTIO + /* Setup tx buffer and rx buffer info. */ + spi_context_buffers_setup(spi_ctx, tx_bufs, rx_bufs, data->dfs); + spi_context_cs_control(spi_ctx, true); +#if defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) + const struct spi_rz_config *config = dev->config; + + if (!spi_context_total_tx_len(&data->ctx) && !spi_context_total_rx_len(&data->ctx)) { + goto end_transceive; + } + 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.tx_buf == NULL) { /* If there is only the rx buffer */ + ret = config->fsp_api->read(data->fsp_ctrl, data->ctx.rx_buf, data->data_len, + data->fsp_ctrl->bit_width); + } else if (data->ctx.rx_buf == NULL) { /* If there is only the tx buffer */ + ret = config->fsp_api->write(data->fsp_ctrl, data->ctx.tx_buf, data->data_len, + data->fsp_ctrl->bit_width); + } else { + ret = config->fsp_api->writeRead(data->fsp_ctrl, data->ctx.tx_buf, data->ctx.rx_buf, + data->data_len, data->fsp_ctrl->bit_width); + } + if (ret) { + LOG_ERR("Async transmit fail: %d", ret); + spi_context_cs_control(spi_ctx, false); + spi_context_release(spi_ctx, ret); + return -EIO; + } + ret = spi_context_wait_for_completion(spi_ctx); +end_transceive: +#else + /* Enable the SPI transfer */ + data->fsp_ctrl->p_regs->SPCR_b.TXMD = SPI_RZ_TRANSMIT_RECEIVE; + if (!spi_context_rx_on(&data->ctx)) { + data->fsp_ctrl->p_regs->SPCR_b.TXMD = SPI_RZ_TX_ONLY; /* tx only */ + } + + /* Configure data length based on the selected bit width . */ + uint32_t spcmd0 = data->fsp_ctrl->p_regs->SPCMD[0]; + + spcmd0 &= (uint32_t)~R_SPI0_SPCMD_SPB_Msk; + spcmd0 |= (uint32_t)(data->fsp_ctrl->bit_width) << R_SPI0_SPCMD_SPB_Pos; + data->fsp_ctrl->p_regs->SPCMD[0] = spcmd0; + + /* FIFO clear */ + data->fsp_ctrl->p_regs->SPFCR_b.SPFRST = 1; + /* Enable the SPI Transfer */ + data->fsp_ctrl->p_regs->SPCR_b.SPE = 1; + + do { + spi_rz_spi_transceive_data(data); + } while (spi_rz_transfer_ongoing(data)); + + /* Wait for transmit complete */ + while (data->fsp_ctrl->p_regs->SPSR_b.IDLNF) { + } + + /* Disable the SPI Transfer */ + data->fsp_ctrl->p_regs->SPCR_b.SPE = 0x0; + +#endif /* CONFIG_SPI_RENESAS_RZ_INTERRUPT */ + +#ifdef CONFIG_SPI_SLAVE + if (spi_context_is_slave(spi_ctx) && !ret) { + ret = spi_ctx->recv_frames; + } +#endif /* CONFIG_SPI_SLAVE */ + + spi_context_cs_control(spi_ctx, false); + +#else + struct spi_rtio *rtio_ctx = data->rtio_ctx; + + ret = spi_rtio_transceive(rtio_ctx, spi_cfg, tx_bufs, rx_bufs); + +#endif + spi_context_release(spi_ctx, ret); + + return ret; +} + +static int spi_rz_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); +} + +static int spi_rz_release(const struct device *dev, const struct spi_config *config) +{ + struct spi_rz_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_rz_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +#ifdef CONFIG_SPI_RTIO + +static inline void spi_rz_iodev_prepare_start(const struct device *dev) +{ + struct spi_rz_data *data = dev->data; + struct spi_rtio *rtio_ctx = data->rtio_ctx; + struct spi_dt_spec *spi_dt_spec = rtio_ctx->txn_curr->sqe.iodev->data; + struct spi_config *spi_config = &spi_dt_spec->config; + int err; + + err = spi_rz_configure(dev, spi_config); + if (err != 0) { + LOG_ERR("RTIO config spi error: %d", err); + spi_rz_iodev_complete(dev, err); + return; + } + spi_context_cs_control(&data->ctx, true); +} + +static void spi_rz_iodev_start(const struct device *dev) +{ + struct spi_rz_data *data = dev->data; + const struct spi_rz_config *config = dev->config; + struct spi_rtio *rtio_ctx = data->rtio_ctx; + struct rtio_sqe *sqe = &rtio_ctx->txn_curr->sqe; + int ret = 0; + + switch (sqe->op) { + case RTIO_OP_RX: + data->data_len = sqe->rx.buf_len / data->dfs; + ret = config->fsp_api->read(data->fsp_ctrl, sqe->rx.buf, data->data_len, + data->fsp_ctrl->bit_width); + break; + case RTIO_OP_TX: + data->data_len = sqe->tx.buf_len / data->dfs; + ret = config->fsp_api->write(data->fsp_ctrl, sqe->tx.buf, data->data_len, + data->fsp_ctrl->bit_width); + break; + case RTIO_OP_TINY_TX: + data->data_len = sqe->tiny_tx.buf_len / data->dfs; + ret = config->fsp_api->write(data->fsp_ctrl, sqe->tiny_tx.buf, data->data_len, + data->fsp_ctrl->bit_width); + break; + case RTIO_OP_TXRX: + data->data_len = sqe->txrx.buf_len / data->dfs; + ret = config->fsp_api->writeRead(data->fsp_ctrl, sqe->txrx.tx_buf, sqe->txrx.rx_buf, + data->data_len, data->fsp_ctrl->bit_width); + break; + default: + spi_rz_iodev_complete(dev, -EINVAL); + break; + } + + if (ret != 0) { + spi_rz_iodev_complete(dev, ret); + } +} + +static void spi_rz_iodev_complete(const struct device *dev, int status) +{ + struct spi_rz_data *data = dev->data; + struct spi_rtio *rtio_ctx = data->rtio_ctx; + + if (!status && rtio_ctx->txn_curr->sqe.flags & RTIO_SQE_TRANSACTION) { + rtio_ctx->txn_curr = rtio_txn_next(rtio_ctx->txn_curr); + spi_rz_iodev_start(dev); + } else { + spi_context_cs_control(&data->ctx, false); + + /* + * Submit the result of the operation to the completion queue + * This may start the next asynchronous request if one is available + */ + if (spi_rtio_complete(rtio_ctx, status)) { + spi_rz_iodev_prepare_start(dev); + spi_rz_iodev_start(dev); + } + } +} + +static void spi_rz_iodev_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct spi_rz_data *data = dev->data; + struct spi_rtio *rtio_ctx = data->rtio_ctx; + + /* Submit sqe to the queue */ + if (spi_rtio_submit(rtio_ctx, iodev_sqe)) { + spi_rz_iodev_prepare_start(dev); + spi_rz_iodev_start(dev); + } +} + +#endif /* CONFIG_SPI_RTIO */ + +static DEVICE_API(spi, spi_rz_driver_api) = { + .transceive = spi_rz_transceive_sync, + .release = spi_rz_release, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_rz_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rz_iodev_submit, +#endif /* CONFIG_SPI_RTIO */ +}; + +#if defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) +#if !defined(CONFIG_SPI_RTIO) +static void spi_rz_retransmit(struct spi_rz_data *data) +{ + spi_bit_width_t spi_width = + (spi_bit_width_t)(SPI_WORD_SIZE_GET(data->ctx.config->operation) - 1); + + if (data->ctx.rx_len == 0) { + data->data_len = data->ctx.tx_len; + data->fsp_ctrl->p_tx_data = data->ctx.tx_buf; + data->fsp_ctrl->p_rx_data = NULL; + } else if (data->ctx.tx_len == 0) { + data->data_len = data->ctx.rx_len; + data->fsp_ctrl->p_tx_data = NULL; + data->fsp_ctrl->p_rx_data = data->ctx.rx_buf; + } else { + data->data_len = MIN(data->ctx.tx_len, data->ctx.rx_len); + data->fsp_ctrl->p_tx_data = data->ctx.tx_buf; + data->fsp_ctrl->p_rx_data = data->ctx.rx_buf; + } + + data->fsp_ctrl->bit_width = spi_width; + data->fsp_ctrl->rx_count = 0; + data->fsp_ctrl->tx_count = 0; + data->fsp_ctrl->count = data->data_len; +} +#endif /* !CONFIG_SPI_RTIO */ + +static void spi_rz_rxi_isr(const struct device *dev) +{ +#ifndef CONFIG_SPI_SLAVE + ARG_UNUSED(dev); + spi_rxi_isr(); +#else + struct spi_rz_data *data = dev->data; + + spi_rxi_isr(); + + if (spi_context_is_slave(&data->ctx) && 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; + } + R_BSP_IrqDisable(data->fsp_config->tei_irq); + + /* Writing 0 to SPE generatates a TXI IRQ. Disable the TXI IRQ. + * (See Section 38.2.1 SPI Control Register in the RA6T2 manual R01UH0886EJ0100). + */ + R_BSP_IrqDisable(data->fsp_config->txi_irq); + + /* Disable the SPI Transfer. */ + data->fsp_ctrl->p_regs->SPCR_b.SPE = 0; + + /* Re-enable the TXI IRQ and clear the pending IRQ. */ + R_BSP_IrqEnable(data->fsp_config->txi_irq); + + spi_context_cs_control(&data->ctx, false); + spi_context_complete(&data->ctx, dev, 0); + } + +#endif +} + +static void spi_rz_txi_isr(const struct device *dev) +{ + ARG_UNUSED(dev); + spi_txi_isr(); +} + +static void spi_rz_tei_isr(const struct device *dev) +{ +#ifndef CONFIG_SPI_RTIO + struct spi_rz_data *data = dev->data; + + if (data->fsp_ctrl->rx_count == data->fsp_ctrl->count) { + spi_context_update_rx(&data->ctx, data->dfs, data->data_len); + } + if (data->fsp_ctrl->tx_count == data->fsp_ctrl->count) { + spi_context_update_tx(&data->ctx, data->dfs, data->data_len); + } + + if (spi_rz_transfer_ongoing(data)) { + R_BSP_IrqDisable(data->fsp_ctrl->p_cfg->txi_irq); + /* Disable the SPI Transfer. */ + data->fsp_ctrl->p_regs->SPCR_b.SPE = 0U; + data->fsp_ctrl->p_regs->SPSRC = SPI_RZ_SPSRC_CLR; + R_BSP_IrqEnable(data->fsp_ctrl->p_cfg->txi_irq); + data->fsp_ctrl->p_regs->SPCR_b.SPE = 1U; + spi_rz_retransmit(data); + } else { + spi_tei_isr(); + } +#else + spi_tei_isr(); +#endif /* CONFIG_SPI_RTIO */ +} + +static void spi_rz_eri_isr(const struct device *dev) +{ + ARG_UNUSED(dev); + spi_eri_isr(); +} +#endif /* CONFIG_SPI_RENESAS_RZ_INTERRUPT || CONFIG_SPI_RTIO */ + +static int spi_rz_init(const struct device *dev) +{ + const struct spi_rz_config *config = dev->config; + struct spi_rz_data *data = dev->data; + int ret; + + ret = pinctrl_apply_state(config->pinctrl_dev, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("pinctrl_apply_state fail: %d", ret); + return ret; + } + + ret = spi_context_cs_configure_all(&data->ctx); + if (ret < 0) { + LOG_ERR("spi_context_cs_configure_all fail: %d", ret); + return ret; + } +#ifdef CONFIG_SPI_RTIO + spi_rtio_init(data->rtio_ctx, dev); +#endif /* CONFIG_SPI_RTIO */ + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#if defined(CONFIG_SPI_RTIO) +#define SPI_RZ_RTIO_DEFINE(n) \ + SPI_RTIO_DEFINE(spi_rz_rtio_##n, CONFIG_SPI_RTIO_SQ_SIZE, CONFIG_SPI_RTIO_CQ_SIZE) +#else +#define SPI_RZ_RTIO_DEFINE(n) +#endif + +#if defined(CONFIG_SPI_RENESAS_RZ_INTERRUPT) +#define RZ_SPI_IRQ_INIT(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, rxi, irq), \ + DT_INST_IRQ_BY_NAME(n, rxi, priority), spi_rz_rxi_isr, \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ_BY_NAME(n, rxi, flags)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, txi, irq), \ + DT_INST_IRQ_BY_NAME(n, txi, priority), spi_rz_txi_isr, \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ_BY_NAME(n, txi, flags)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, eri, irq), \ + DT_INST_IRQ_BY_NAME(n, eri, priority), spi_rz_eri_isr, \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ_BY_NAME(n, eri, flags)); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, tei, irq), \ + DT_INST_IRQ_BY_NAME(n, tei, priority), spi_rz_tei_isr, \ + DEVICE_DT_INST_GET(n), DT_INST_IRQ_BY_NAME(n, tei, flags)); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, rxi, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, txi, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, eri, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, tei, irq)); \ + } while (0) + +#else +#define RZ_SPI_IRQ_INIT(n) +#endif /* CONFIG_SPI_RENESAS_RZ_INTERRUPT */ + +#define SPI_RZ_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + SPI_RZ_RTIO_DEFINE(n); \ + static spi_instance_ctrl_t g_spi##n##_ctrl; \ + static spi_extended_cfg_t g_spi_##n##_cfg_extend = { \ + .spi_clksyn = SPI_SSL_MODE_SPI, \ + .spi_comm = SPI_COMMUNICATION_FULL_DUPLEX, \ + .ssl_polarity = SPI_SSLP_LOW, \ + .ssl_select = SPI_SSL_SELECT_SSL0, \ + .mosi_idle = SPI_MOSI_IDLE_VALUE_FIXING_DISABLE, \ + .parity = SPI_PARITY_MODE_DISABLE, \ + .byte_swap = SPI_BYTE_SWAP_DISABLE, \ + .clock_source = SPI_CLOCK_SOURCE_SPI0ASYNCCLK, \ + .spck_div = \ + { \ + .spbr = 4, \ + .brdv = 0, \ + }, \ + .spck_delay = SPI_DELAY_COUNT_1, \ + .ssl_negation_delay = SPI_DELAY_COUNT_1, \ + .next_access_delay = SPI_DELAY_COUNT_1, \ + .transmit_fifo_threshold = 0, \ + .receive_fifo_threshold = 0, \ + .receive_data_ready_detect_adjustment = 0, \ + .master_receive_clock = SPI_MASTER_RECEIVE_CLOCK_MRIOCLK, \ + .mrioclk_analog_delay = SPI_MRIOCLK_ANALOG_DELAY_NODELAY, \ + .mrclk_digital_delay = SPI_MRCLK_DIGITAL_DELAY_CLOCK_0, \ + }; \ + static spi_cfg_t g_spi_##n##_config = { \ + .channel = DT_INST_PROP(n, channel), \ + .eri_irq = DT_INST_IRQ_BY_NAME(n, eri, irq), \ + .rxi_ipl = DT_INST_IRQ_BY_NAME(n, rxi, priority), \ + .txi_ipl = DT_INST_IRQ_BY_NAME(n, txi, priority), \ + .eri_ipl = DT_INST_IRQ_BY_NAME(n, eri, priority), \ + .operating_mode = SPI_MODE_MASTER, \ + .clk_phase = SPI_CLK_PHASE_EDGE_ODD, \ + .clk_polarity = SPI_CLK_POLARITY_LOW, \ + .mode_fault = SPI_MODE_FAULT_ERROR_ENABLE, \ + .bit_order = SPI_BIT_ORDER_MSB_FIRST, \ + .p_callback = spi_callback, \ + .p_context = DEVICE_DT_INST_GET(n), \ + .p_extend = &g_spi_##n##_cfg_extend, \ + .rxi_irq = DT_INST_IRQ_BY_NAME(n, rxi, irq), \ + .txi_irq = DT_INST_IRQ_BY_NAME(n, txi, irq), \ + .tei_irq = DT_INST_IRQ_BY_NAME(n, tei, irq), \ + .p_transfer_tx = NULL, \ + .p_transfer_rx = NULL, \ + }; \ + static const struct spi_rz_config spi_rz_config_##n = { \ + .pinctrl_dev = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .fsp_api = &g_spi_on_spi, \ + .clock_source = (spi_clock_source_t)DT_INST_PROP(n, clk_src), \ + }; \ + \ + static struct spi_rz_data spi_rz_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_rz_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_rz_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx).fsp_ctrl = &g_spi##n##_ctrl, \ + .fsp_config = &g_spi_##n##_config, \ + IF_ENABLED(CONFIG_SPI_RTIO, \ + (.rtio_ctx = &spi_rz_rtio_##n,)) }; \ + \ + static int spi_rz_init_##n(const struct device *dev) \ + { \ + int err = spi_rz_init(dev); \ + if (err != 0) { \ + return err; \ + } \ + RZ_SPI_IRQ_INIT(n); \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(n, &spi_rz_init_##n, NULL, &spi_rz_data_##n, &spi_rz_config_##n, \ + POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_rz_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SPI_RZ_INIT) diff --git a/drivers/spi/spi_renesas_rz_rspi.c b/drivers/spi/spi_renesas_rz_rspi.c index f5290ce95692b..c8f1709610f83 100644 --- a/drivers/spi/spi_renesas_rz_rspi.c +++ b/drivers/spi/spi_renesas_rz_rspi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,9 +46,9 @@ struct spi_rz_rspi_data { }; #ifdef CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT -void rspi_rxi_isr(void); -void rspi_txi_isr(void); -void rspi_eri_isr(void); +void rspi_rxi_isr(void *irq); +void rspi_txi_isr(void *irq); +void rspi_eri_isr(void *irq); #elif defined(CONFIG_SPI_RENESAS_RZ_RSPI_DMAC) void dmac_b_int_isr(void); void rspi_tx_dmac_callback(rspi_instance_ctrl_t *p_ctrl); @@ -63,10 +63,10 @@ static bool spi_rz_rspi_transfer_ongoing(struct spi_rz_rspi_data *data) #if defined(CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT) return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); #else - if (spi_context_total_tx_len(&data->ctx) < spi_context_total_rx_len(&data->ctx)) { - return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); - } else { + if (spi_context_total_tx_len(&data->ctx) == spi_context_total_rx_len(&data->ctx)) { return (spi_context_tx_on(&data->ctx) && spi_context_rx_on(&data->ctx)); + } else { + return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); } #endif } @@ -100,20 +100,23 @@ static void spi_rz_rspi_retransmit(const struct device *dev) #ifdef CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT static void spi_rz_rspi_rxi_isr(const struct device *dev) { - ARG_UNUSED(dev); - rspi_rxi_isr(); + struct spi_rz_rspi_data *data = dev->data; + + rspi_rxi_isr((void *)data->fsp_config->rxi_irq); } static void spi_rz_rspi_txi_isr(const struct device *dev) { - ARG_UNUSED(dev); - rspi_txi_isr(); + struct spi_rz_rspi_data *data = dev->data; + + rspi_txi_isr((void *)data->fsp_config->txi_irq); } static void spi_rz_rspi_eri_isr(const struct device *dev) { - ARG_UNUSED(dev); - rspi_eri_isr(); + struct spi_rz_rspi_data *data = dev->data; + + rspi_eri_isr((void *)data->fsp_config->eri_irq); } #endif /* CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT */ @@ -263,6 +266,7 @@ static int spi_rz_rspi_transceive_data(struct spi_rz_rspi_data *data) { R_RSPI0_Type *p_spi_reg = (R_RSPI0_Type *)data->fsp_ctrl->p_regs; uint32_t data_count = (p_spi_reg->SPBFDR & R_RSPI0_SPBFDR_T_Msk) >> R_RSPI0_SPBFDR_T_Pos; + uint32_t rx; data_count = 8 - data_count; @@ -295,21 +299,28 @@ static int spi_rz_rspi_transceive_data(struct spi_rz_rspi_data *data) spi_context_update_tx(&data->ctx, data->dfs, 1); /* RX transfer */ - if (spi_context_rx_on(&data->ctx)) { + while (!p_spi_reg->SPSR_b.SPRF) { + } - while (!p_spi_reg->SPSR_b.SPRF) { - } + if (data->dfs > 2) { + rx = (uint32_t)p_spi_reg->SPDR_b.SPD; + } else if (data->dfs > 1) { + rx = (uint16_t)p_spi_reg->SPDR_hword.L; + } else { + rx = (uint8_t)p_spi_reg->SPDR_byte.LL; + } + if (spi_context_rx_buf_on(&data->ctx)) { /* Read data from Data Register */ if (data->dfs > 2) { - UNALIGNED_PUT(p_spi_reg->SPDR_b.SPD, (uint32_t *)data->ctx.rx_buf); + UNALIGNED_PUT(rx, (uint32_t *)data->ctx.rx_buf); } else if (data->dfs > 1) { - UNALIGNED_PUT(p_spi_reg->SPDR_hword.L, (uint16_t *)data->ctx.rx_buf); + UNALIGNED_PUT(rx, (uint16_t *)data->ctx.rx_buf); } else { - UNALIGNED_PUT(p_spi_reg->SPDR_byte.LL, (uint8_t *)data->ctx.rx_buf); + UNALIGNED_PUT(rx, (uint8_t *)data->ctx.rx_buf); } - spi_context_update_rx(&data->ctx, data->dfs, 1); } + spi_context_update_rx(&data->ctx, data->dfs, 1); return 0; } #endif /* #if !defined(CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT) */ diff --git a/drivers/spi/spi_sc18is606.c b/drivers/spi/spi_sc18is606.c new file mode 100644 index 0000000000000..327a222bf4db2 --- /dev/null +++ b/drivers/spi/spi_sc18is606.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2025, tinyvision.ai + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_sc18is606_spi + +#include +LOG_MODULE_REGISTER(spi_sc18is606, CONFIG_SPI_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "spi_context.h" + +#define SC18IS606_CONFIG_SPI 0xF0 +#define CLEAR_INTERRUPT 0xF1 +#define IDLE_MODE 0xF2 +#define SC18IS606_LSB_MASK GENMASK(5, 5) +#define SC18IS606_MODE_MASK GENMASK(3, 2) +#define SC18IS606_FREQ_MASK GENMASK(1, 0) + +#include "spi_sc18is606.h" + +struct nxp_sc18is606_data { + struct k_mutex bridge_lock; + struct spi_context ctx; + uint8_t frequency_idx; + uint8_t spi_mode; + struct gpio_callback int_cb; + struct k_sem int_sem; +}; + +struct nxp_sc18is606_config { + const struct i2c_dt_spec i2c_controller; + const struct gpio_dt_spec reset_gpios; + const struct gpio_dt_spec int_gpios; +}; + +int nxp_sc18is606_claim(const struct device *dev) +{ + struct nxp_sc18is606_data *data = dev->data; + + return k_mutex_lock(&data->bridge_lock, K_FOREVER); +} + +int nxp_sc18is606_release(const struct device *dev) +{ + struct nxp_sc18is606_data *data = dev->data; + + return k_mutex_unlock(&data->bridge_lock); +} + +int nxp_sc18is606_transfer(const struct device *dev, const uint8_t *tx_data, uint8_t tx_len, + uint8_t *rx_data, uint8_t rx_len, uint8_t *id_buf) +{ + struct nxp_sc18is606_data *data = dev->data; + const struct nxp_sc18is606_config *info = dev->config; + int ret; + + ret = k_mutex_lock(&data->bridge_lock, K_FOREVER); + if (ret < 0) { + return ret; + } + + if (tx_data != NULL) { + if (id_buf != NULL) { + struct i2c_msg tx_msg[2] = { + { + .buf = id_buf, + .len = 1, + .flags = I2C_MSG_WRITE, + }, + { + .buf = (uint8_t *)tx_data, + .len = tx_len, + .flags = I2C_MSG_WRITE, + }, + }; + + ret = i2c_transfer_dt(&info->i2c_controller, tx_msg, 2); + } else { + struct i2c_msg tx_msg[1] = {{ + .buf = (uint8_t *)tx_data, + .len = tx_len, + .flags = I2C_MSG_WRITE, + }}; + + ret = i2c_transfer_dt(&info->i2c_controller, tx_msg, 1); + } + + if (ret != 0) { + LOG_ERR("SPI write failed: %d", ret); + goto out; + } + } + + /*If interrupt pin is used wait before next transaction*/ + if (info->int_gpios.port) { + ret = k_sem_take(&data->int_sem, K_MSEC(5)); + if (ret != 0) { + LOG_WRN("Interrupt semaphore timedout, proceeding with read"); + } + } + + if (rx_data != NULL) { + /*What is the time*/ + k_timepoint_t end; + + /*Set a deadline in a second*/ + end = sys_timepoint_calc(K_MSEC(1)); + + do { + ret = i2c_read(info->i2c_controller.bus, rx_data, rx_len, + info->i2c_controller.addr); + if (ret >= 0) { + break; + } + } while (!sys_timepoint_expired(end)); /*Keep reading while in the deadline*/ + + if (ret < 0) { + LOG_ERR("Failed to read data (%d)", ret); + goto out; + } + } + + ret = 0; + +out: + k_mutex_unlock(&data->bridge_lock); + return ret; +} + +static int sc18is606_spi_configure(const struct device *dev, const struct spi_config *config) +{ + struct nxp_sc18is606_data *data = dev->data; + uint8_t cfg_byte = 0; + uint8_t buffer[2]; + + if ((config->operation & SPI_OP_MODE_SLAVE) != 0U) { + LOG_ERR("SC18IS606 does not support Slave mode"); + return -ENOTSUP; + } + + if ((config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Unsupported line configuration"); + return -ENOTSUP; + } + + const int bits = SPI_WORD_SIZE_GET(config->operation); + + if (bits > 8) { + LOG_ERR("Word sizes > 8 bits not supported"); + return -ENOTSUP; + } + + /* Build SC18IS606 configuration byte*/ + cfg_byte |= FIELD_PREP(SC18IS606_LSB_MASK, (config->operation & SPI_TRANSFER_LSB) >> 4); + + cfg_byte |= FIELD_PREP(SC18IS606_MODE_MASK, (SPI_MODE_GET(config->operation) >> 1)); + + cfg_byte |= FIELD_PREP(SC18IS606_FREQ_MASK, config->frequency); + + data->ctx.config = config; + + buffer[0] = SC18IS606_CONFIG_SPI; + buffer[1] = cfg_byte; + cfg_byte |= ((config->operation & SPI_TRANSFER_LSB) >> 4) << 5; + + return nxp_sc18is606_transfer(dev, buffer, sizeof(buffer), NULL, 0, NULL); +} + +static int sc18is606_spi_transceive(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_buffer_set, + const struct spi_buf_set *rx_buffer_set) +{ + int ret; + + ret = sc18is606_spi_configure(dev, spi_cfg); + if (ret < 0) { + return ret; + } + + if (!tx_buffer_set && !rx_buffer_set) { + LOG_ERR("SC18IS606 at least one buffer_set should be set"); + return -EINVAL; + } + + /* CS line to be Used */ + uint8_t ss_idx = spi_cfg->slave; + + if (ss_idx > 2) { + LOG_ERR("SC18IS606: Invalid SS Index (%u) must be 0-2", ss_idx); + return -EINVAL; + } + + uint8_t function_id = (1 << ss_idx) & 0x07; + + if (tx_buffer_set && tx_buffer_set->buffers && tx_buffer_set->count > 0) { + for (size_t i = 0; i < tx_buffer_set->count; i++) { + const struct spi_buf *tx_buf = &tx_buffer_set->buffers[i]; + + uint8_t id_buf[1] = {function_id}; + + ret = nxp_sc18is606_transfer(dev, tx_buf->buf, tx_buf->len, NULL, 0, + id_buf); + if (ret < 0) { + LOG_ERR("SC18IS606: TX of size: %d failed %s", tx_buf->len, + dev->name); + return ret; + } + } + } + + if (rx_buffer_set && rx_buffer_set->buffers && rx_buffer_set->count > 0) { + for (size_t i = 0; i < rx_buffer_set->count; i++) { + /* Function ID first to select the device */ + uint8_t cmd_buf[1] = {function_id}; + + const struct spi_buf *rx_buf = &rx_buffer_set->buffers[i]; + + ret = nxp_sc18is606_transfer(dev, cmd_buf, sizeof(cmd_buf), rx_buf->buf, + rx_buf->len, NULL); + + if (ret < 0) { + LOG_ERR("SC18IS606: RX of size: %d failed on (%s)", rx_buf->len, + dev->name); + return ret; + } + } + } + + return ret; +} + +int sc18is606_spi_release(const struct device *dev, const struct spi_config *config) +{ + struct nxp_sc18is606_data *data = dev->data; + + struct spi_context *ctx = &data->ctx; + + spi_context_unlock_unconditionally(ctx); + + return 0; +} + +static DEVICE_API(spi, sc18is606_api) = { + .transceive = sc18is606_spi_transceive, + .release = sc18is606_spi_release, +}; + +static void sc18is606_int_isr(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct nxp_sc18is606_data *data = CONTAINER_OF(cb, struct nxp_sc18is606_data, int_cb); + + k_sem_give(&data->int_sem); +} + +static int int_gpios_setup(const struct device *dev) +{ + struct nxp_sc18is606_data *data = dev->data; + const struct nxp_sc18is606_config *cfg = dev->config; + int ret; + + if (!gpio_is_ready_dt(&cfg->int_gpios)) { + LOG_ERR("SC18IS606 Int GPIO not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&cfg->int_gpios, GPIO_INPUT); + if (ret != 0U) { + LOG_ERR("Failed to configure SC18IS606 int gpio (%d)", ret); + return ret; + } + + ret = k_sem_init(&data->int_sem, 0, 1); + if (ret != 0U) { + LOG_ERR("Failed to Initialize Interrupt Semaphore (%d)", ret); + return ret; + } + + gpio_init_callback(&data->int_cb, sc18is606_int_isr, BIT(cfg->int_gpios.pin)); + + ret = gpio_add_callback(cfg->int_gpios.port, &data->int_cb); + if (ret != 0U) { + LOG_ERR("Failed to assign the Interrupt callback (%d)", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->int_gpios, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0U) { + LOG_ERR("Failed to configure the GPIO interrupt edge (%d)", ret); + return ret; + } + + return ret; +} + +static int sc18is606_init(const struct device *dev) +{ + const struct nxp_sc18is606_config *cfg = dev->config; + struct nxp_sc18is606_data *data = dev->data; + int ret; + + struct spi_config my_config = { + .frequency = data->frequency_idx, + .operation = data->spi_mode, + .slave = 0, + }; + + if (!device_is_ready(cfg->i2c_controller.bus)) { + LOG_ERR("I2C controller %s not found", cfg->i2c_controller.bus->name); + return -ENODEV; + } + + LOG_INF("Using I2C controller: %s", cfg->i2c_controller.bus->name); + + ret = sc18is606_spi_configure(dev, &my_config); + if (ret != 0) { + LOG_ERR("Failed to CONFIGURE the SC18IS606: %d", ret); + return ret; + } + + if (cfg->reset_gpios.port) { + if (!gpio_is_ready_dt(&cfg->reset_gpios)) { + LOG_ERR("SC18IS606 Reset GPIO not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&cfg->reset_gpios, GPIO_OUTPUT_ACTIVE); + if (ret != 0U) { + LOG_ERR("Failed to configure SC18IS606 reset GPIO (%d)", ret); + return ret; + } + + ret = gpio_pin_set_dt(&cfg->reset_gpios, 0); + if (ret != 0U) { + LOG_ERR("Failed to reset Bridge via Reset pin (%d)", ret); + return ret; + } + } + + if (cfg->int_gpios.port) { + ret = int_gpios_setup(dev); + if (ret != 0U) { + LOG_ERR("Could not set up device int_gpios (%d)", ret); + return ret; + } + } + LOG_INF("SC18IS606 initialized"); + return 0; +} + +#define SPI_SC18IS606_DEFINE(inst) \ + static struct nxp_sc18is606_data sc18is606_data_##inst = { \ + .frequency_idx = DT_INST_ENUM_IDX(inst, frequency), \ + .spi_mode = DT_INST_PROP(inst, spi_mode), \ + }; \ + static const struct nxp_sc18is606_config sc18is606_config_##inst = { \ + .i2c_controller = I2C_DT_SPEC_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .reset_gpios = GPIO_DT_SPEC_GET_OR(DT_INST_PARENT(inst), reset_gpios, {0}), \ + .int_gpios = GPIO_DT_SPEC_GET_OR(DT_INST_PARENT(inst), int_gpios, {0}), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, sc18is606_init, NULL, &sc18is606_data_##inst, \ + &sc18is606_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &sc18is606_api); + +DT_INST_FOREACH_STATUS_OKAY(SPI_SC18IS606_DEFINE) diff --git a/drivers/spi/spi_sc18is606.h b/drivers/spi/spi_sc18is606.h new file mode 100644 index 0000000000000..b3a0302feb7ef --- /dev/null +++ b/drivers/spi/spi_sc18is606.h @@ -0,0 +1,60 @@ +/* + * Copyright (c), 2025 tinyvision.ai Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_I2C_SPI_SC18IS606_H_ +#define ZEPHYR_DRIVERS_I2C_SPI_SC18IS606_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* @brief Claim the SC18IS606 bridge + * + * @warning After calling this routine, the device cannot be used by any other thread + * until the calling bridge releases it with the counterpart function of this. + * + * @param dev SC18IS606 device + * @retval 0 Device is claimed + * @retval -EBUSY The device cannot be claimed + */ +int nxp_sc18is606_claim(const struct device *dev); + +/* @brief Release the SC18IS606 bridge + * + * @warning this routine can only be called once a device has been locked + * + * @param dev SC18IS606 bridge + * + * @retval 0 Device is released + * @retval -EINVAL The device has no locks on it. + */ +int nxp_sc18is606_release(const struct device *dev); + +/* @brief Transfer data using I2C to or from the bridge + * + * This routine implements the synchronization between the SPI controller and GPIO cntroller + * + * @param dev SC18IS606 bridge + * @param tx_data Data to be sent out + * @param tx_len Tx Data length + * @param rx_data Container to receive data + * @param rx_len size of expected receipt + * @param id_buf Function id data if used + * + * @retval 0 Transfer success + * @retval -EAGAIN device lock timed out + * @retval -EBUSY device already locked + */ +int nxp_sc18is606_transfer(const struct device *dev, const uint8_t *tx_data, uint8_t tx_len, + uint8_t *rx_data, uint8_t rx_len, uint8_t *id_buf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 2fb7e06dd549f..9ce1e7553145d 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "clock_update.h" LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL); @@ -209,6 +211,7 @@ static void gspi_siwx91x_dma_rx_callback(const struct device *dev, void *user_da spi_context_cs_control(instance_ctx, false); spi_context_complete(instance_ctx, spi_dev, status); + pm_device_runtime_put_async(spi_dev, K_NO_WAIT); } static int gspi_siwx91x_dma_config(const struct device *dev, @@ -533,8 +536,15 @@ static int gspi_siwx91x_transceive(const struct device *dev, const struct spi_co struct gspi_siwx91x_data *data = dev->data; int ret = 0; + ret = pm_device_runtime_get(dev); + if (ret < 0) { + return ret; + } + if (!spi_siwx91x_is_dma_enabled_instance(dev) && asynchronous) { ret = -ENOTSUP; + pm_device_runtime_put(dev); + return ret; } spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); @@ -559,6 +569,7 @@ static int gspi_siwx91x_transceive(const struct device *dev, const struct spi_co /* Perform synchronous polling transceive */ ret = gspi_siwx91x_transceive_polling_sync(dev, &data->ctx); spi_context_unlock_unconditionally(&data->ctx); + pm_device_runtime_put(dev); } return ret; @@ -592,35 +603,57 @@ static int gspi_siwx91x_release(const struct device *dev, const struct spi_confi return 0; } -static int gspi_siwx91x_init(const struct device *dev) +static int gspi_siwx91x_pm_action(const struct device *dev, enum pm_device_action action) { const struct gspi_siwx91x_config *cfg = dev->config; struct gspi_siwx91x_data *data = dev->data; int ret; - ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys); - if (ret) { - return ret; - } + switch (action) { + case PM_DEVICE_ACTION_RESUME: + break; + case PM_DEVICE_ACTION_SUSPEND: + break; + case PM_DEVICE_ACTION_TURN_ON: + ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys); + if (ret < 0 && ret != -EALREADY) { + return ret; + } - ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); - if (ret) { - return ret; - } + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0 && ret != -ENOENT) { + return ret; + } - ret = spi_context_cs_configure_all(&data->ctx); - if (ret) { - return ret; - } + ret = spi_context_cs_configure_all(&data->ctx); + if (ret) { + return ret; + } - spi_context_unlock_unconditionally(&data->ctx); + spi_context_unlock_unconditionally(&data->ctx); - cfg->reg->GSPI_BUS_MODE_b.SPI_HIGH_PERFORMANCE_EN = 1; - cfg->reg->GSPI_CONFIG1_b.GSPI_MANUAL_CSN = 0; + cfg->reg->GSPI_BUS_MODE_b.SPI_HIGH_PERFORMANCE_EN = 1; + cfg->reg->GSPI_CONFIG1_b.GSPI_MANUAL_CSN = 0; + data->ctx.config = NULL; + break; + case PM_DEVICE_ACTION_TURN_OFF: + ret = clock_control_off(cfg->clock_dev, cfg->clock_subsys); + if (ret < 0 && ret != -EALREADY) { + return ret; + } + break; + default: + return -ENOTSUP; + } return 0; } +static int gspi_siwx91x_init(const struct device *dev) +{ + return pm_device_driver_init(dev, gspi_siwx91x_pm_action); +} + static DEVICE_API(spi, gspi_siwx91x_driver_api) = { .transceive = gspi_siwx91x_transceive_sync, #ifdef CONFIG_SPI_ASYNC @@ -662,8 +695,9 @@ static DEVICE_API(spi, gspi_siwx91x_driver_api) = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .mosi_overrun = (uint8_t)SPI_MOSI_OVERRUN_DT(inst), \ }; \ - DEVICE_DT_INST_DEFINE(inst, &gspi_siwx91x_init, NULL, &gspi_data_##inst, \ - &gspi_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &gspi_siwx91x_driver_api); + PM_DEVICE_DT_INST_DEFINE(inst, gspi_siwx91x_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, &gspi_siwx91x_init, PM_DEVICE_DT_INST_GET(inst), \ + &gspi_data_##inst, &gspi_config_##inst, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &gspi_siwx91x_driver_api); DT_INST_FOREACH_STATUS_OKAY(SIWX91X_GSPI_INIT) diff --git a/drivers/timer/Kconfig.gecko b/drivers/timer/Kconfig.gecko index cd53f9977b5cc..80f4dc22ae676 100644 --- a/drivers/timer/Kconfig.gecko +++ b/drivers/timer/Kconfig.gecko @@ -5,7 +5,7 @@ config GECKO_BURTC_TIMER bool "SiLabs Gecko BURTC system clock driver" depends on SOC_FAMILY_SILABS_S2 depends on DT_HAS_SILABS_GECKO_BURTC_ENABLED - select SOC_GECKO_BURTC + select SILABS_SISDK_BURTC select TICKLESS_CAPABLE select TIMER_READS_ITS_FREQUENCY_AT_RUNTIME help diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index c596462a6e28f..1ddd473c01a09 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -7,7 +7,7 @@ config NRF_RTC_TIMER bool "nRF Real Time Counter (NRF_RTC1) Timer" depends on CLOCK_CONTROL depends on SOC_COMPATIBLE_NRF - depends on !DT_HAS_NORDIC_NRF_RTC_ENABLED && !DT_HAS_NORDIC_NRF_GRTC_ENABLED + depends on !$(dt_nodelabel_enabled,rtc1) && !DT_HAS_NORDIC_NRF_GRTC_ENABLED select TICKLESS_CAPABLE select SYSTEM_TIMER_HAS_DISABLE_SUPPORT select NRFX_PPI if SOC_NRF52832 diff --git a/drivers/timer/Kconfig.silabs b/drivers/timer/Kconfig.silabs index aa7a013e9c005..813cae6c19bec 100644 --- a/drivers/timer/Kconfig.silabs +++ b/drivers/timer/Kconfig.silabs @@ -1,11 +1,13 @@ # Copyright (c) 2024 Silicon Laboratories Inc. # SPDX-License-Identifier: Apache-2.0 +DT_CHOSEN_SILABS_SLEEPTIMER := silabs,sleeptimer + config SILABS_SLEEPTIMER_TIMER bool "Silabs Sleeptimer system clock driver" depends on SOC_FAMILY_SILABS_S2 || SOC_FAMILY_SILABS_SIWX91X - depends on DT_HAS_SILABS_GECKO_STIMER_ENABLED - select SOC_SILABS_SLEEPTIMER + depends on $(dt_chosen_enabled,$(DT_CHOSEN_SILABS_SLEEPTIMER)) + select SILABS_SISDK_SLEEPTIMER select TICKLESS_CAPABLE select TIMER_READS_ITS_FREQUENCY_AT_RUNTIME help diff --git a/drivers/timer/mcux_lptmr_timer.c b/drivers/timer/mcux_lptmr_timer.c index f83e4c39e26a7..9e95503b44f00 100644 --- a/drivers/timer/mcux_lptmr_timer.c +++ b/drivers/timer/mcux_lptmr_timer.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Vestas Wind Systems A/S + * Copyright (c) 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,33 +18,13 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "No LPTMR instance enabled in devicetree"); -/* Prescaler mapping */ -#define LPTMR_PRESCALER_2 kLPTMR_Prescale_Glitch_0 -#define LPTMR_PRESCALER_4 kLPTMR_Prescale_Glitch_1 -#define LPTMR_PRESCALER_8 kLPTMR_Prescale_Glitch_2 -#define LPTMR_PRESCALER_16 kLPTMR_Prescale_Glitch_3 -#define LPTMR_PRESCALER_32 kLPTMR_Prescale_Glitch_4 -#define LPTMR_PRESCALER_64 kLPTMR_Prescale_Glitch_5 -#define LPTMR_PRESCALER_128 kLPTMR_Prescale_Glitch_6 -#define LPTMR_PRESCALER_256 kLPTMR_Prescale_Glitch_7 -#define LPTMR_PRESCALER_512 kLPTMR_Prescale_Glitch_8 -#define LPTMR_PRESCALER_1024 kLPTMR_Prescale_Glitch_9 -#define LPTMR_PRESCALER_2048 kLPTMR_Prescale_Glitch_10 -#define LPTMR_PRESCALER_4096 kLPTMR_Prescale_Glitch_11 -#define LPTMR_PRESCALER_8192 kLPTMR_Prescale_Glitch_12 -#define LPTMR_PRESCALER_16384 kLPTMR_Prescale_Glitch_13 -#define LPTMR_PRESCALER_32768 kLPTMR_Prescale_Glitch_14 -#define LPTMR_PRESCALER_65536 kLPTMR_Prescale_Glitch_15 -#define TO_LPTMR_PRESCALER(val) _DO_CONCAT(LPTMR_PRESCALER_, val) - /* Prescaler clock mapping */ #define TO_LPTMR_CLK_SEL(val) _DO_CONCAT(kLPTMR_PrescalerClock_, val) /* Devicetree properties */ #define LPTMR_BASE ((LPTMR_Type *)(DT_INST_REG_ADDR(0))) -#define LPTMR_CLK_SOURCE TO_LPTMR_CLK_SEL(DT_INST_PROP(0, clk_source)); -#define LPTMR_PRESCALER TO_LPTMR_PRESCALER(DT_INST_PROP(0, prescaler)); -#define LPTMR_BYPASS_PRESCALER DT_INST_PROP(0, prescaler) == 1 +#define LPTMR_CLK_SOURCE TO_LPTMR_CLK_SEL(DT_INST_PROP_OR(0, clk_source, 0)) +#define LPTMR_PRESCALER BIT(DT_INST_PROP_OR(0, prescale_glitch_filter, 0)) #define LPTMR_IRQN DT_INST_IRQN(0) #define LPTMR_IRQ_PRIORITY DT_INST_IRQ(0, priority) @@ -100,18 +81,12 @@ static int sys_clock_driver_init(void) { lptmr_config_t config; - LPTMR_GetDefaultConfig(&config); config.timerMode = kLPTMR_TimerModeTimeCounter; config.enableFreeRunning = false; config.prescalerClockSource = LPTMR_CLK_SOURCE; - -#if LPTMR_BYPASS_PRESCALER - config.bypassPrescaler = true; -#else /* LPTMR_BYPASS_PRESCALER */ - config.bypassPrescaler = false; + config.bypassPrescaler = !LPTMR_PRESCALER; config.value = LPTMR_PRESCALER; -#endif /* !LPTMR_BYPASS_PRESCALER */ LPTMR_Init(LPTMR_BASE, &config); diff --git a/drivers/timer/silabs_sleeptimer_timer.c b/drivers/timer/silabs_sleeptimer_timer.c index d0e643d21bfa2..1313a095687ec 100644 --- a/drivers/timer/silabs_sleeptimer_timer.c +++ b/drivers/timer/silabs_sleeptimer_timer.c @@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(silabs_sleeptimer_timer); /* Maximum time interval between timer interrupts (in hw_cycles) */ #define MAX_TIMEOUT_CYC (UINT32_MAX >> 1) -#define DT_RTC DT_COMPAT_GET_ANY_STATUS_OKAY(silabs_gecko_stimer) +#define DT_RTC DT_CHOSEN(silabs_sleeptimer) /* Ensure interrupt names don't expand to register interface struct pointers */ #undef RTCC diff --git a/drivers/usb/device/usb_dc_stm32.c b/drivers/usb/device/usb_dc_stm32.c index ea560ad751a4e..0d90f93dc583c 100644 --- a/drivers/usb/device/usb_dc_stm32.c +++ b/drivers/usb/device/usb_dc_stm32.c @@ -349,7 +349,7 @@ static int usb_dc_stm32_phy_specific_clock_enable(const struct device *const clk #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) /* Enable Vdd USB voltage monitoring */ LL_PWR_EnableVddUSBMonitoring(); - while (__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)) { + while (!__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)) { /* Wait for VDD33USB ready */ } /* Enable VDDUSB */ diff --git a/drivers/usb/udc/Kconfig.dwc2 b/drivers/usb/udc/Kconfig.dwc2 index ff3b169e66a51..43fdf0c96731d 100644 --- a/drivers/usb/udc/Kconfig.dwc2 +++ b/drivers/usb/udc/Kconfig.dwc2 @@ -37,6 +37,7 @@ config UDC_DWC2_PTI config UDC_DWC2_STACK_SIZE int "UDC DWC2 driver internal thread stack size" + default 1024 if SOC_SERIES_ESP32S3 default 512 help DWC2 driver internal thread stack size. diff --git a/drivers/usb/udc/Kconfig.stm32 b/drivers/usb/udc/Kconfig.stm32 index 11f885f0dfcc3..e99839ca92b98 100644 --- a/drivers/usb/udc/Kconfig.stm32 +++ b/drivers/usb/udc/Kconfig.stm32 @@ -58,7 +58,11 @@ config UDC_STM32_OTG_RXFIFO_BASELINE_SIZE config UDC_STM32_CLOCK_CHECK bool "Runtime USB 48MHz clock check" - default y if !(SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32U5X) + default n if SOC_SERIES_STM32F1X || \ + SOC_SERIES_STM32F3X || \ + SOC_SERIES_STM32U5X || \ + SOC_SERIES_STM32WBAX + default y help Enable USB clock 48MHz configuration runtime check. In specific cases, this check might provide wrong verdict and should diff --git a/drivers/usb/udc/udc_dwc2_vendor_quirks.h b/drivers/usb/udc/udc_dwc2_vendor_quirks.h index 6766649161ea8..192554e5928e7 100644 --- a/drivers/usb/udc/udc_dwc2_vendor_quirks.h +++ b/drivers/usb/udc/udc_dwc2_vendor_quirks.h @@ -607,30 +607,42 @@ static inline int esp32_usb_otg_init(const struct device *dev, return ret; } -static inline int esp32_usb_otg_enable_phy(struct phy_context_t *phy_ctx, bool enable) +static inline int esp32_usb_otg_enable_clk(struct phy_context_t *phy_ctx) { - LOG_MODULE_DECLARE(udc_dwc2, CONFIG_UDC_DRIVER_LOG_LEVEL); + usb_wrap_ll_enable_bus_clock(true); - if (enable) { - usb_wrap_ll_enable_bus_clock(true); - usb_wrap_hal_init(&phy_ctx->wrap_hal); + usb_wrap_ll_reset_register(); + usb_wrap_hal_init(&phy_ctx->wrap_hal); #if USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_wrap_hal_phy_set_external(&phy_ctx->wrap_hal, - (phy_ctx->target == USB_PHY_TARGET_EXT)); + usb_wrap_hal_phy_set_external(&phy_ctx->wrap_hal, (phy_ctx->target == USB_PHY_TARGET_EXT)); #endif + return 0; +} + +static inline int esp32_usb_otg_enable_phy(struct phy_context_t *phy_ctx, bool enable) +{ + LOG_MODULE_DECLARE(udc_dwc2, CONFIG_UDC_DRIVER_LOG_LEVEL); + + if (enable) { + usb_wrap_ll_phy_enable_pad(phy_ctx->wrap_hal.dev, true); LOG_DBG("PHY enabled"); } else { - usb_wrap_ll_enable_bus_clock(false); usb_wrap_ll_phy_enable_pad(phy_ctx->wrap_hal.dev, false); - LOG_DBG("PHY disabled"); } return 0; } +static inline int esp32_usb_otg_shutdown(struct phy_context_t *phy_ctx) +{ + usb_wrap_ll_enable_bus_clock(false); + + return 0; +} + #define QUIRK_ESP32_USB_OTG_DEFINE(n) \ \ static struct phy_context_t phy_ctx_##n = { \ @@ -660,6 +672,11 @@ static inline int esp32_usb_otg_enable_phy(struct phy_context_t *phy_ctx, bool e &usb_otg_config_##n, &usb_otg_data_##n); \ } \ \ + static int esp32_usb_otg_enable_clk_##n(const struct device *dev) \ + { \ + return esp32_usb_otg_enable_clk(&phy_ctx_##n); \ + } \ + \ static int esp32_usb_otg_enable_phy_##n(const struct device *dev) \ { \ return esp32_usb_otg_enable_phy(&phy_ctx_##n, true); \ @@ -668,12 +685,19 @@ static inline int esp32_usb_otg_enable_phy(struct phy_context_t *phy_ctx, bool e static int esp32_usb_otg_disable_phy_##n(const struct device *dev) \ { \ return esp32_usb_otg_enable_phy(&phy_ctx_##n, false); \ + } \ + static int esp32_usb_otg_shutdown_##n(const struct device *dev) \ + { \ + esp_intr_free(usb_otg_data_##n.int_handle); \ + return esp32_usb_otg_shutdown(&phy_ctx_##n); \ } \ \ const struct dwc2_vendor_quirks dwc2_vendor_quirks_##n = { \ .init = esp32_usb_otg_init_##n, \ + .pre_enable = esp32_usb_otg_enable_clk_##n, \ .post_enable = esp32_usb_otg_enable_phy_##n, \ .disable = esp32_usb_otg_disable_phy_##n, \ + .shutdown = esp32_usb_otg_shutdown_##n, \ }; \ #define UDC_DWC2_IRQ_DT_INST_DEFINE(n) \ diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index de57cabb2f788..23c8232f9217e 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -135,7 +135,7 @@ LOG_MODULE_REGISTER(udc_stm32, CONFIG_UDC_DRIVER_LOG_LEVEL); #define USB_USBPHYC_CR_FSEL_24MHZ USB_USBPHYC_CR_FSEL_1 #endif -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) && defined(CONFIG_SOC_SERIES_STM32U5X) +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) static const int syscfg_otg_hs_phy_clk[] = { SYSCFG_OTG_HS_PHY_CLK_SELECT_1, /* 16Mhz */ SYSCFG_OTG_HS_PHY_CLK_SELECT_2, /* 19.2Mhz */ @@ -1258,14 +1258,37 @@ static int priv_clock_enable(void) } #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) */ #elif defined(CONFIG_SOC_SERIES_STM32N6X) - /* Enable Vdd USB voltage monitoring */ + /* Enable Vdd33USB voltage monitoring */ LL_PWR_EnableVddUSBMonitoring(); - while (__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)) { - /* Wait FOR VDD33USB ready */ + 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) @@ -1331,16 +1354,31 @@ static int priv_clock_enable(void) /* Peripheral OTGPHY clock enable */ LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTGPHY1); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) + const struct stm32_pclken hsphy_clk[] = STM32_DT_CLOCKS(DT_NODELABEL(otghs_phy)); + const uint32_t hsphy_clknum = DT_NUM_CLOCKS(DT_NODELABEL(otghs_phy)); + /* Configure OTG PHY reference clock through SYSCFG */ - LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_SYSCFG); + __HAL_RCC_SYSCFG_CLK_ENABLE(); + HAL_SYSCFG_SetOTGPHYReferenceClockSelection( syscfg_otg_hs_phy_clk[DT_ENUM_IDX(DT_NODELABEL(otghs_phy), clock_reference)] ); /* De-assert reset and enable clock of OTG PHY */ HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_USBPHY); + + if (hsphy_clknum > 1) { + if (clock_control_configure(clk, (void *)&hsphy_clk[1], NULL) != 0) { + LOG_ERR("Failed OTGHS PHY mux configuration"); + return -EIO; + } + } + + if (clock_control_on(clk, (void *)&hsphy_clk[0]) != 0) { + LOG_ERR("Failed enabling OTGHS PHY clock"); + return -EIO; + } #elif defined(CONFIG_SOC_SERIES_STM32H7X) /* * If HS PHY (over ULPI) is used, enable ULPI interface clock. @@ -1366,6 +1404,13 @@ static int priv_clock_enable(void) #else /* CONFIG_SOC_SERIES_STM32F2X || CONFIG_SOC_SERIES_STM32F4X */ if (UDC_STM32_NODE_PHY_ITFACE(DT_DRV_INST(0)) == PCD_PHY_ULPI) { LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_OTGHSULPI); + } else if (UDC_STM32_NODE_SPEED(DT_DRV_INST(0)) == PCD_SPEED_HIGH_IN_FULL) { + /* + * Some parts of the STM32F4 series require the OTGHSULPILPEN to be + * cleared if the OTG_HS is used in FS mode. Disable it on all parts + * since it has no nefarious effect if performed when not required. + */ + LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI); } #endif /* CONFIG_SOC_SERIES_* */ #elif defined(CONFIG_SOC_SERIES_STM32H7X) && DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otgfs) diff --git a/drivers/video/Kconfig.stm32_dcmipp b/drivers/video/Kconfig.stm32_dcmipp index e986312a6d7ad..728db10a284a0 100644 --- a/drivers/video/Kconfig.stm32_dcmipp +++ b/drivers/video/Kconfig.stm32_dcmipp @@ -17,6 +17,14 @@ config VIDEO_STM32_DCMIPP if VIDEO_STM32_DCMIPP +config VIDEO_STM32_DCMIPP_INIT_PRIORITY + int "STM32 DCMIPP initialization priority" + default 61 + help + System initialization priority for DCMIPP drivers. + This priority needs to be lower than VIDEO_INIT_PRIORITY + to ensure that the source device (sensor) initializes first. + config VIDEO_STM32_DCMIPP_SENSOR_WIDTH int "Width of the sensor frame" default 2592 diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index e390395a1c8a4..055d5199ae7ec 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -87,8 +87,10 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) struct video_stm32_dcmi_data *dev_data = CONTAINER_OF(hdcmi, struct video_stm32_dcmi_data, hdcmi); struct video_buffer *vbuf; + HAL_StatusTypeDef __maybe_unused hal_ret; - HAL_DCMI_Suspend(hdcmi); + hal_ret = HAL_DCMI_Suspend(hdcmi); + __ASSERT_NO_MSG(hal_ret == HAL_OK); vbuf = k_fifo_get(&dev_data->fifo_in, K_NO_WAIT); @@ -103,7 +105,8 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) k_fifo_put(&dev_data->fifo_out, vbuf); resume: - HAL_DCMI_Resume(hdcmi); + hal_ret = HAL_DCMI_Resume(hdcmi); + __ASSERT_NO_MSG(hal_ret == HAL_OK); } static void stm32_dcmi_isr(const struct device *dev) @@ -252,6 +255,7 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable, { struct video_stm32_dcmi_data *data = dev->data; const struct video_stm32_dcmi_config *config = dev->config; + HAL_StatusTypeDef hal_ret; int err; if (!enable) { @@ -260,8 +264,8 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable, return err; } - err = HAL_DCMI_Stop(&data->hdcmi); - if (err != HAL_OK) { + hal_ret = HAL_DCMI_Stop(&data->hdcmi); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to stop DCMI"); return -EIO; } @@ -283,9 +287,9 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable, data->hdcmi.Instance->CR &= ~(DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1); data->hdcmi.Instance->CR |= STM32_DCMI_GET_CAPTURE_RATE(data->capture_rate); - err = HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS, - (uint32_t)data->vbuf->buffer, data->vbuf->bytesused / 4); - if (err != HAL_OK) { + hal_ret = HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS, + (uint32_t)data->vbuf->buffer, data->vbuf->bytesused / 4); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to start DCMI DMA"); return -EIO; } @@ -577,8 +581,7 @@ static int video_stm32_dcmi_init(const struct device *dev) config->irq_config(dev); /* Initialize DCMI peripheral */ - err = HAL_DCMI_Init(&data->hdcmi); - if (err != HAL_OK) { + if (HAL_DCMI_Init(&data->hdcmi) != HAL_OK) { LOG_ERR("DCMI initialization failed."); return -EIO; } diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index 37c7d1724598b..24db419289586 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -196,15 +196,15 @@ void HAL_DCMIPP_PIPE_FrameEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t struct stm32_dcmipp_data *dcmipp = CONTAINER_OF(hdcmipp, struct stm32_dcmipp_data, hdcmipp); struct stm32_dcmipp_pipe_data *pipe = dcmipp->pipe[Pipe]; + HAL_StatusTypeDef hal_ret; uint32_t bytesused; - int ret; __ASSERT(pipe->active, "Unexpected behavior, active_buf must not be NULL"); /* Counter is only available on Pipe0 */ if (Pipe == DCMIPP_PIPE0) { - ret = HAL_DCMIPP_PIPE_GetDataCounter(hdcmipp, Pipe, &bytesused); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_GetDataCounter(hdcmipp, Pipe, &bytesused); + if (hal_ret != HAL_OK) { LOG_WRN("Failed to read counter - buffer in error"); pipe->active->bytesused = 0; } else { @@ -324,7 +324,7 @@ static int stm32_dcmipp_conf_parallel(const struct device *dev, struct stm32_dcmipp_data *dcmipp = dev->data; const struct stm32_dcmipp_config *config = dev->config; DCMIPP_ParallelConfTypeDef parallel_cfg = { 0 }; - int ret; + HAL_StatusTypeDef hal_ret; parallel_cfg.Format = input_fmt->dcmipp_format; parallel_cfg.SwapCycles = DCMIPP_SWAPCYCLES_DISABLE; @@ -334,8 +334,8 @@ static int stm32_dcmipp_conf_parallel(const struct device *dev, parallel_cfg.ExtendedDataMode = DCMIPP_INTERFACE_8BITS; parallel_cfg.SynchroMode = DCMIPP_SYNCHRO_HARDWARE; - ret = HAL_DCMIPP_PARALLEL_SetConfig(&dcmipp->hdcmipp, ¶llel_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PARALLEL_SetConfig(&dcmipp->hdcmipp, ¶llel_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure DCMIPP Parallel interface"); return -EIO; } @@ -381,8 +381,9 @@ static int stm32_dcmipp_conf_csi(const struct device *dev, uint32_t dcmipp_csi_b const struct stm32_dcmipp_config *config = dev->config; struct stm32_dcmipp_data *dcmipp = dev->data; DCMIPP_CSI_ConfTypeDef csiconf = { 0 }; + HAL_StatusTypeDef hal_ret; int64_t phy_bitrate; - int err, i; + int i; csiconf.NumberOfLanes = config->csi.nb_lanes == 2 ? DCMIPP_CSI_TWO_DATA_LANES : DCMIPP_CSI_ONE_DATA_LANE; @@ -411,17 +412,17 @@ static int stm32_dcmipp_conf_csi(const struct device *dev, uint32_t dcmipp_csi_b } csiconf.PHYBitrate = stm32_dcmipp_bitrate[i].PHYBitrate; - err = HAL_DCMIPP_CSI_SetConfig(&dcmipp->hdcmipp, &csiconf); - if (err != HAL_OK) { + hal_ret = HAL_DCMIPP_CSI_SetConfig(&dcmipp->hdcmipp, &csiconf); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure DCMIPP CSI"); return -EIO; } /* Set Virtual Channel config */ /* TODO - need to be able to use an alternate VC, info coming from the source */ - err = HAL_DCMIPP_CSI_SetVCConfig(&dcmipp->hdcmipp, DCMIPP_VIRTUAL_CHANNEL0, - dcmipp_csi_bpp); - if (err != HAL_OK) { + hal_ret = HAL_DCMIPP_CSI_SetVCConfig(&dcmipp->hdcmipp, DCMIPP_VIRTUAL_CHANNEL0, + dcmipp_csi_bpp); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to set CSI configuration"); return -EIO; } @@ -645,43 +646,6 @@ static void stm32_dcmipp_get_isp_decimation(struct stm32_dcmipp_data *dcmipp) static int stm32_dcmipp_get_fmt(const struct device *dev, struct video_format *fmt) { struct stm32_dcmipp_pipe_data *pipe = dev->data; -#if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) - struct stm32_dcmipp_data *dcmipp = pipe->dcmipp; - const struct stm32_dcmipp_config *config = dev->config; - static atomic_t isp_init_once; - int ret; - - /* Initialize the external ISP handling stack */ - /* - * TODO - this is not the right place to do that, however we need to know - * the source format before calling the isp_init handler hence can't - * do that within the stm32_dcmipp_init function due to unknown - * driver initialization order - * - * Would need an ops that get called when both side of an endpoint get - * initiialized - */ - if (atomic_cas(&isp_init_once, 0, 1) && - (pipe->id == DCMIPP_PIPE1 || pipe->id == DCMIPP_PIPE2)) { - /* - * It is necessary to perform a dummy configuration here otherwise any - * ISP related configuration done by the stm32_dcmipp_isp_init will - * fail due to the HAL DCMIPP driver not being in READY state - */ - ret = stm32_dcmipp_conf_parallel(dcmipp->dev, &stm32_dcmipp_input_fmt_desc[0]); - if (ret < 0) { - LOG_ERR("Failed to perform dummy parallel configuration"); - return ret; - } - - ret = stm32_dcmipp_isp_init(&dcmipp->hdcmipp, config->source_dev); - if (ret < 0) { - LOG_ERR("Failed to initialize the ISP"); - return ret; - } - stm32_dcmipp_get_isp_decimation(dcmipp); - } -#endif *fmt = pipe->fmt; @@ -694,7 +658,7 @@ static int stm32_dcmipp_set_crop(struct stm32_dcmipp_pipe_data *pipe) DCMIPP_CropConfTypeDef crop_cfg; uint32_t frame_width = dcmipp->source_fmt.width; uint32_t frame_height = dcmipp->source_fmt.height; - int ret; + HAL_StatusTypeDef hal_ret; #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) if (pipe->id == DCMIPP_PIPE1 || pipe->id == DCMIPP_PIPE2) { @@ -705,8 +669,8 @@ static int stm32_dcmipp_set_crop(struct stm32_dcmipp_pipe_data *pipe) /* If crop area is equal to frame size, disable the crop */ if (pipe->crop.width == frame_width && pipe->crop.height == frame_height) { - ret = HAL_DCMIPP_PIPE_DisableCrop(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableCrop(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable pipe crop"); return -EIO; } @@ -734,14 +698,14 @@ static int stm32_dcmipp_set_crop(struct stm32_dcmipp_pipe_data *pipe) } #endif - ret = HAL_DCMIPP_PIPE_SetCropConfig(&dcmipp->hdcmipp, pipe->id, &crop_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_SetCropConfig(&dcmipp->hdcmipp, pipe->id, &crop_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure pipe crop"); return -EIO; } - ret = HAL_DCMIPP_PIPE_EnableCrop(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableCrop(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to enable pipe crop"); return -EIO; } @@ -763,17 +727,17 @@ static int stm32_dcmipp_set_downscale(struct stm32_dcmipp_pipe_data *pipe) DCMIPP_DownsizeTypeDef downsize_cfg; struct video_rect *compose = &pipe->compose; uint32_t hdec = 1, vdec = 1; - int ret; + HAL_StatusTypeDef hal_ret; if (compose->width == pipe->crop.width && compose->height == pipe->crop.height) { - ret = HAL_DCMIPP_PIPE_DisableDecimation(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableDecimation(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable the pipe decimation"); return -EIO; } - ret = HAL_DCMIPP_PIPE_DisableDownsize(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableDownsize(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable the pipe downsize"); return -EIO; } @@ -792,8 +756,8 @@ static int stm32_dcmipp_set_downscale(struct stm32_dcmipp_pipe_data *pipe) } if (hdec == 1 && vdec == 1) { - ret = HAL_DCMIPP_PIPE_DisableDecimation(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableDecimation(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable the pipe decimation"); return -EIO; } @@ -802,13 +766,13 @@ static int stm32_dcmipp_set_downscale(struct stm32_dcmipp_pipe_data *pipe) dec_cfg.HRatio = __builtin_ctz(hdec) << DCMIPP_P1DECR_HDEC_Pos; dec_cfg.VRatio = __builtin_ctz(vdec) << DCMIPP_P1DECR_VDEC_Pos; - ret = HAL_DCMIPP_PIPE_SetDecimationConfig(&dcmipp->hdcmipp, pipe->id, &dec_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_SetDecimationConfig(&dcmipp->hdcmipp, pipe->id, &dec_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable the pipe decimation"); return -EIO; } - ret = HAL_DCMIPP_PIPE_EnableDecimation(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableDecimation(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to enable the pipe decimation"); return -EIO; } @@ -838,14 +802,14 @@ static int stm32_dcmipp_set_downscale(struct stm32_dcmipp_pipe_data *pipe) downsize_cfg.HSize = compose->width; downsize_cfg.VSize = compose->height; - ret = HAL_DCMIPP_PIPE_SetDownsizeConfig(&dcmipp->hdcmipp, pipe->id, &downsize_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_SetDownsizeConfig(&dcmipp->hdcmipp, pipe->id, &downsize_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure the pipe downsize"); return -EIO; } - ret = HAL_DCMIPP_PIPE_EnableDownsize(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableDownsize(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to enable the pipe downsize"); return -EIO; } @@ -874,7 +838,7 @@ static int stm32_dcmipp_set_yuv_conversion(struct stm32_dcmipp_pipe_data *pipe, { struct stm32_dcmipp_data *dcmipp = pipe->dcmipp; const DCMIPP_ColorConversionConfTypeDef *cfg = NULL; - int ret; + HAL_StatusTypeDef hal_ret; /* No YUV conversion on pipe 2 */ if (pipe->id == DCMIPP_PIPE2) { @@ -892,8 +856,8 @@ static int stm32_dcmipp_set_yuv_conversion(struct stm32_dcmipp_pipe_data *pipe, /* Need to perform YUV to RGB conversion */ cfg = &stm32_dcmipp_yuv_to_rgb; } else { - ret = HAL_DCMIPP_PIPE_DisableYUVConversion(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableYUVConversion(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable YUV conversion"); return -EIO; } @@ -901,14 +865,14 @@ static int stm32_dcmipp_set_yuv_conversion(struct stm32_dcmipp_pipe_data *pipe, return 0; } - ret = HAL_DCMIPP_PIPE_SetYUVConversionConfig(&dcmipp->hdcmipp, pipe->id, cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_SetYUVConversionConfig(&dcmipp->hdcmipp, pipe->id, cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to setup YUV conversion"); return -EIO; } - ret = HAL_DCMIPP_PIPE_EnableYUVConversion(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableYUVConversion(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable YUV conversion"); return -EIO; } @@ -925,7 +889,7 @@ static int stm32_dcmipp_start_pipeline(const struct device *dev, #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) struct video_format *fmt = &pipe->fmt; #endif - int ret; + HAL_StatusTypeDef hal_ret; #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) if (VIDEO_FMT_IS_PLANAR(fmt)) { @@ -938,20 +902,21 @@ static int stm32_dcmipp_start_pipeline(const struct device *dev, }; if (config->bus_type == VIDEO_BUS_TYPE_PARALLEL) { - ret = HAL_DCMIPP_PIPE_FullPlanarStart(&dcmipp->hdcmipp, pipe->id, - &planar_addr, DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_PIPE_FullPlanarStart(&dcmipp->hdcmipp, pipe->id, + &planar_addr, + DCMIPP_MODE_CONTINUOUS); } #if defined(STM32_DCMIPP_HAS_CSI) else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { - ret = HAL_DCMIPP_CSI_PIPE_FullPlanarStart(&dcmipp->hdcmipp, pipe->id, - DCMIPP_VIRTUAL_CHANNEL0, - &planar_addr, - DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_CSI_PIPE_FullPlanarStart(&dcmipp->hdcmipp, pipe->id, + DCMIPP_VIRTUAL_CHANNEL0, + &planar_addr, + DCMIPP_MODE_CONTINUOUS); } #endif else { LOG_ERR("Invalid bus_type"); - ret = -EINVAL; + hal_ret = HAL_ERROR; } } else if (VIDEO_FMT_IS_SEMI_PLANAR(fmt)) { uint8_t *uv_addr = pipe->next->buffer + VIDEO_FMT_PLANAR_Y_PLANE_SIZE(fmt); @@ -961,45 +926,45 @@ static int stm32_dcmipp_start_pipeline(const struct device *dev, }; if (config->bus_type == VIDEO_BUS_TYPE_PARALLEL) { - ret = HAL_DCMIPP_PIPE_SemiPlanarStart(&dcmipp->hdcmipp, pipe->id, - &semiplanar_addr, - DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_PIPE_SemiPlanarStart(&dcmipp->hdcmipp, pipe->id, + &semiplanar_addr, + DCMIPP_MODE_CONTINUOUS); } #if defined(STM32_DCMIPP_HAS_CSI) else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { - ret = HAL_DCMIPP_CSI_PIPE_SemiPlanarStart(&dcmipp->hdcmipp, pipe->id, - DCMIPP_VIRTUAL_CHANNEL0, - &semiplanar_addr, - DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_CSI_PIPE_SemiPlanarStart(&dcmipp->hdcmipp, pipe->id, + DCMIPP_VIRTUAL_CHANNEL0, + &semiplanar_addr, + DCMIPP_MODE_CONTINUOUS); } #endif else { LOG_ERR("Invalid bus_type"); - ret = -EINVAL; + hal_ret = HAL_ERROR; } } else { #endif if (config->bus_type == VIDEO_BUS_TYPE_PARALLEL) { - ret = HAL_DCMIPP_PIPE_Start(&dcmipp->hdcmipp, pipe->id, - (uint32_t)pipe->next->buffer, - DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_PIPE_Start(&dcmipp->hdcmipp, pipe->id, + (uint32_t)pipe->next->buffer, + DCMIPP_MODE_CONTINUOUS); } #if defined(STM32_DCMIPP_HAS_CSI) else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { - ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id, - DCMIPP_VIRTUAL_CHANNEL0, - (uint32_t)pipe->next->buffer, - DCMIPP_MODE_CONTINUOUS); + hal_ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id, + DCMIPP_VIRTUAL_CHANNEL0, + (uint32_t)pipe->next->buffer, + DCMIPP_MODE_CONTINUOUS); } #endif else { LOG_ERR("Invalid bus_type"); - ret = -EINVAL; + hal_ret = HAL_ERROR; } #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) } #endif - if (ret != HAL_OK) { + if (hal_ret != HAL_OK) { return -EIO; } @@ -1018,6 +983,7 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) DCMIPP_CSI_PIPE_ConfTypeDef csi_pipe_cfg = { 0 }; #endif DCMIPP_PipeConfTypeDef pipe_cfg = { 0 }; + HAL_StatusTypeDef hal_ret; int ret; k_mutex_lock(&pipe->lock, K_FOREVER); @@ -1072,10 +1038,10 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) /* Configure the Pipe input */ csi_pipe_cfg.DataTypeMode = DCMIPP_DTMODE_DTIDA; csi_pipe_cfg.DataTypeIDA = input_fmt->dcmipp_csi_dt; - ret = HAL_DCMIPP_CSI_PIPE_SetConfig(&dcmipp->hdcmipp, - pipe->id == DCMIPP_PIPE2 ? DCMIPP_PIPE1 : pipe->id, - &csi_pipe_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_CSI_PIPE_SetConfig(&dcmipp->hdcmipp, + pipe->id == DCMIPP_PIPE2 ? DCMIPP_PIPE1 : pipe->id, + &csi_pipe_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure pipe #%d input", pipe->id); ret = -EIO; goto out; @@ -1097,8 +1063,8 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) pipe_cfg.PixelPackerFormat = mapping->pixels.dcmipp_format; } #endif - ret = HAL_DCMIPP_PIPE_SetConfig(&dcmipp->hdcmipp, pipe->id, &pipe_cfg); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_SetConfig(&dcmipp->hdcmipp, pipe->id, &pipe_cfg); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to configure pipe #%d", pipe->id); ret = -EIO; goto out; @@ -1113,9 +1079,9 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) /* Only the PIPE0 has a limiter */ /* Set Limiter to avoid buffer overflow, in number of 32 bits words */ - ret = HAL_DCMIPP_PIPE_EnableLimitEvent(&dcmipp->hdcmipp, DCMIPP_PIPE0, - (fmt->pitch * fmt->height) / 4); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableLimitEvent(&dcmipp->hdcmipp, DCMIPP_PIPE0, + (fmt->pitch * fmt->height) / 4); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to set limiter"); ret = -EIO; goto out; @@ -1128,15 +1094,15 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) /* Enable / disable SWAPRB if necessary */ if (mapping->pixels.swap_uv) { - ret = HAL_DCMIPP_PIPE_EnableRedBlueSwap(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableRedBlueSwap(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to enable Red-Blue swap"); ret = -EIO; goto out; } } else { - ret = HAL_DCMIPP_PIPE_DisableRedBlueSwap(&dcmipp->hdcmipp, pipe->id); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableRedBlueSwap(&dcmipp->hdcmipp, pipe->id); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable Red-Blue swap"); ret = -EIO; goto out; @@ -1145,17 +1111,18 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) if (source_colorspace == VIDEO_COLORSPACE_RAW) { /* Enable demosaicing if input format is Bayer */ - ret = HAL_DCMIPP_PIPE_EnableISPRawBayer2RGB(&dcmipp->hdcmipp, DCMIPP_PIPE1); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_EnableISPRawBayer2RGB(&dcmipp->hdcmipp, + DCMIPP_PIPE1); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to enable demosaicing"); ret = -EIO; goto out; } } else { /* Disable demosaicing */ - ret = HAL_DCMIPP_PIPE_DisableISPRawBayer2RGB(&dcmipp->hdcmipp, - DCMIPP_PIPE1); - if (ret != HAL_OK) { + hal_ret = HAL_DCMIPP_PIPE_DisableISPRawBayer2RGB(&dcmipp->hdcmipp, + DCMIPP_PIPE1); + if (hal_ret != HAL_OK) { LOG_ERR("Failed to disable demosaicing"); ret = -EIO; goto out; @@ -1180,12 +1147,6 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) goto out; } } - - /* Initialize the external ISP handling stack */ - ret = stm32_dcmipp_isp_init(&dcmipp->hdcmipp, config->source_dev); - if (ret < 0) { - goto out; - } #endif /* Enable the DCMIPP Pipeline */ @@ -1201,12 +1162,18 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) if (ret < 0) { LOG_ERR("Failed to start the source"); if (config->bus_type == VIDEO_BUS_TYPE_PARALLEL) { - HAL_DCMIPP_PIPE_Stop(&dcmipp->hdcmipp, pipe->id); + if (HAL_DCMIPP_PIPE_Stop(&dcmipp->hdcmipp, pipe->id) != HAL_OK) { + ret = -EIO; + goto out; + } } #if defined(STM32_DCMIPP_HAS_CSI) else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { - HAL_DCMIPP_CSI_PIPE_Stop(&dcmipp->hdcmipp, pipe->id, - DCMIPP_VIRTUAL_CHANNEL0); + if (HAL_DCMIPP_CSI_PIPE_Stop(&dcmipp->hdcmipp, pipe->id, + DCMIPP_VIRTUAL_CHANNEL0) != HAL_OK) { + ret = -EIO; + goto out; + } } #endif else { @@ -1258,12 +1225,18 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) #endif /* Disable the DCMIPP Pipeline */ + ret = 0; if (config->bus_type == VIDEO_BUS_TYPE_PARALLEL) { - ret = HAL_DCMIPP_PIPE_Stop(&dcmipp->hdcmipp, pipe->id); + if (HAL_DCMIPP_PIPE_Stop(&dcmipp->hdcmipp, pipe->id) != HAL_OK) { + ret = -EIO; + } } #if defined(STM32_DCMIPP_HAS_CSI) else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { - ret = HAL_DCMIPP_CSI_PIPE_Stop(&dcmipp->hdcmipp, pipe->id, DCMIPP_VIRTUAL_CHANNEL0); + if (HAL_DCMIPP_CSI_PIPE_Stop(&dcmipp->hdcmipp, pipe->id, + DCMIPP_VIRTUAL_CHANNEL0) != HAL_OK) { + ret = -EIO; + } } #endif else { @@ -1271,9 +1244,8 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) ret = -EIO; goto out; } - if (ret != HAL_OK) { + if (ret < 0) { LOG_ERR("Failed to stop the pipeline"); - ret = -EIO; goto out; } @@ -1680,6 +1652,33 @@ static int stm32_dcmipp_init(const struct device *dev) return -EIO; } +#if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) + /* Check if source device is ready */ + if (!device_is_ready(cfg->source_dev)) { + LOG_ERR("Source device not ready"); + return -ENODEV; + } + + /* + * It is necessary to perform a dummy configuration here otherwise any + * ISP related configuration done by the stm32_dcmipp_isp_init will + * fail due to the HAL DCMIPP driver not being in READY state + */ + err = stm32_dcmipp_conf_parallel(dcmipp->dev, &stm32_dcmipp_input_fmt_desc[0]); + if (err < 0) { + LOG_ERR("Failed to perform dummy parallel configuration"); + return err; + } + + err = stm32_dcmipp_isp_init(&dcmipp->hdcmipp, cfg->source_dev); + if (err < 0) { + LOG_ERR("Failed to initialize the ISP"); + return err; + } + + stm32_dcmipp_get_isp_decimation(dcmipp); +#endif + LOG_DBG("%s initialized", dev->name); return 0; @@ -1729,7 +1728,7 @@ static void stm32_dcmipp_isr(const struct device *dev) DEVICE_DT_DEFINE(node_id, &stm32_dcmipp_pipe_init, NULL, \ &stm32_dcmipp_pipe_##node_id, \ &stm32_dcmipp_config_##inst, \ - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \ + POST_KERNEL, CONFIG_VIDEO_STM32_DCMIPP_INIT_PRIORITY, \ &stm32_dcmipp_driver_api); \ \ VIDEO_DEVICE_DEFINE(dcmipp_##inst_pipe_##node_id, DEVICE_DT_GET(node_id), SOURCE_DEV(inst)); @@ -1814,7 +1813,7 @@ static void stm32_dcmipp_isr(const struct device *dev) DEVICE_DT_INST_DEFINE(inst, &stm32_dcmipp_init, \ NULL, &stm32_dcmipp_data_##inst, \ &stm32_dcmipp_config_##inst, \ - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \ + POST_KERNEL, CONFIG_VIDEO_STM32_DCMIPP_INIT_PRIORITY, \ NULL); \ \ STM32_DCMIPP_PIPES(inst) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index abd1608454dfb..082ee0bc01dc0 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -322,26 +322,26 @@ int EWLmemcmp(const void *s1, const void *s2, uint32_t n) return memcmp(s1, s2, n); } -i32 EWLWaitHwRdy(const void *instance, uint32_t *slicesReady) +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; - uint32_t ret = EWL_HW_WAIT_TIMEOUT; + int32_t ret = EWL_HW_WAIT_TIMEOUT; volatile uint32_t irq_stats; - uint32_t prevSlicesReady = 0; + 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 clrByWrite1 = EWLReadReg(inst, BASE_HWFuse2) & HWCFGIrqClearSupport; + uint32_t clr_by_write_1 = EWLReadReg(inst, BASE_HWFuse2) & HWCFGIrqClearSupport; do { irq_stats = sys_read32(config->reg + BASE_HEncIRQ); /* get the number of completed slices from ASIC registers. */ - if (slicesReady != NULL && *slicesReady > prevSlicesReady) { - *slicesReady = FIELD_GET(NUM_SLICES_READY_MASK, + if (slices_ready != NULL && *slices_ready > prev_slices_ready) { + *slices_ready = FIELD_GET(NUM_SLICES_READY_MASK, sys_read32(config->reg + BASE_HEncControl7)); } @@ -362,7 +362,7 @@ i32 EWLWaitHwRdy(const void *instance, uint32_t *slicesReady) irq_stats &= ~(ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE); - if (clrByWrite1 != 0UL) { + if (clr_by_write_1 != 0UL) { clr_stats = ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE; } else { clr_stats = irq_stats; @@ -373,20 +373,25 @@ i32 EWLWaitHwRdy(const void *instance, uint32_t *slicesReady) break; } - if (slicesReady != NULL && *slicesReady > prevSlicesReady) { + 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_DBG("encoding = %d ms", k_ticks_to_ms_ceil32(sys_clock_tick_get_32() - start)); - if (slicesReady != NULL) { - LOG_DBG("slicesReady = %d", *slicesReady); + if (slices_ready != NULL) { + LOG_DBG("slices_ready = %d", *slices_ready); } - return ret; + return EWL_OK; } void EWLassert(bool expr, const char *str_expr, const char *file, unsigned int line) @@ -465,7 +470,7 @@ static int stm32_venc_get_fmt(const struct device *dev, struct video_format *fmt static int encoder_prepare(struct stm32_venc_data *data) { - H264EncRet ret; + H264EncRet h264ret; H264EncConfig cfg = {0}; H264EncPreProcessingCfg preproc_cfg = {0}; H264EncRateCtrl ratectrl_cfg = {0}; @@ -489,42 +494,42 @@ static int encoder_prepare(struct stm32_venc_data *data) cfg.svctLevel = 0; cfg.viewMode = H264ENC_BASE_VIEW_SINGLE_BUFFER; - ret = H264EncInit(&cfg, &data->encoder); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncInit error=%d", ret); + h264ret = H264EncInit(&cfg, &data->encoder); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncInit error=%d", h264ret); return -EIO; } /* set format conversion for preprocessing */ - ret = H264EncGetPreProcessing(data->encoder, &preproc_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncGetPreProcessing error=%d", ret); + h264ret = H264EncGetPreProcessing(data->encoder, &preproc_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncGetPreProcessing error=%d", h264ret); return -EIO; } preproc_cfg.inputType = to_h264pixfmt(data->in_fmt.pixelformat); - ret = H264EncSetPreProcessing(data->encoder, &preproc_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncSetPreProcessing error=%d", ret); + h264ret = H264EncSetPreProcessing(data->encoder, &preproc_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncSetPreProcessing error=%d", h264ret); return -EIO; } /* setup coding ctrl */ - ret = H264EncGetCodingCtrl(data->encoder, &codingctrl_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncGetCodingCtrl error=%d", ret); + h264ret = H264EncGetCodingCtrl(data->encoder, &codingctrl_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncGetCodingCtrl error=%d", h264ret); return -EIO; } - ret = H264EncSetCodingCtrl(data->encoder, &codingctrl_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncSetCodingCtrl error=%d", ret); + h264ret = H264EncSetCodingCtrl(data->encoder, &codingctrl_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncSetCodingCtrl error=%d", h264ret); return -EIO; } /* set bit rate configuration */ - ret = H264EncGetRateCtrl(data->encoder, &ratectrl_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncGetRateCtrl error=%d", ret); + h264ret = H264EncGetRateCtrl(data->encoder, &ratectrl_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncGetRateCtrl error=%d", h264ret); return -EIO; } @@ -537,9 +542,9 @@ static int encoder_prepare(struct stm32_venc_data *data) ratectrl_cfg.qpMin = ratectrl_cfg.qpHdr; ratectrl_cfg.qpMax = ratectrl_cfg.qpHdr; - ret = H264EncSetRateCtrl(data->encoder, &ratectrl_cfg); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncSetRateCtrl error=%d", ret); + h264ret = H264EncSetRateCtrl(data->encoder, &ratectrl_cfg); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncSetRateCtrl error=%d", h264ret); return -EIO; } @@ -548,22 +553,22 @@ static int encoder_prepare(struct stm32_venc_data *data) static int encoder_start(struct stm32_venc_data *data, struct video_buffer *output) { - H264EncRet ret; - H264EncIn encIn = {0}; - H264EncOut encOut = {0}; + H264EncRet h264ret; + H264EncIn enc_in = {0}; + H264EncOut enc_out = {0}; - encIn.pOutBuf = (uint32_t *)output->buffer; - encIn.busOutBuf = (uint32_t)encIn.pOutBuf; - encIn.outBufSize = output->size; + enc_in.pOutBuf = (uint32_t *)output->buffer; + enc_in.busOutBuf = (uint32_t)enc_in.pOutBuf; + enc_in.outBufSize = output->size; /* create stream */ - ret = H264EncStrmStart(data->encoder, &encIn, &encOut); - if (ret != H264ENC_OK) { - LOG_ERR("H264EncStrmStart error=%d", ret); + h264ret = H264EncStrmStart(data->encoder, &enc_in, &enc_out); + if (h264ret != H264ENC_OK) { + LOG_ERR("H264EncStrmStart error=%d", h264ret); return -EIO; } - output->bytesused = encOut.streamSize; + output->bytesused = enc_out.streamSize; LOG_DBG("SPS/PPS generated, size= %d", output->bytesused); data->resync = true; @@ -573,11 +578,11 @@ static int encoder_start(struct stm32_venc_data *data, struct video_buffer *outp static int encoder_end(struct stm32_venc_data *data) { - H264EncIn encIn = {0}; - H264EncOut encOut = {0}; + H264EncIn enc_in = {0}; + H264EncOut enc_out = {0}; if (data->encoder != NULL) { - H264EncStrmEnd(data->encoder, &encIn, &encOut); + H264EncStrmEnd(data->encoder, &enc_in, &enc_out); data->encoder = NULL; } @@ -586,11 +591,12 @@ static int encoder_end(struct stm32_venc_data *data) static int encode_frame(struct stm32_venc_data *data) { - int ret = H264ENC_FRAME_READY; + int ret = 0; + H264EncRet h264ret = H264ENC_FRAME_READY; struct video_buffer *input; struct video_buffer *output; - H264EncIn encIn = {0}; - H264EncOut encOut = {0}; + H264EncIn enc_in = {0}; + H264EncOut enc_out = {0}; if (k_fifo_is_empty(&data->in_fifo_in) || k_fifo_is_empty(&data->out_fifo_in)) { /* Encoding deferred to next buffer queueing */ @@ -618,41 +624,41 @@ static int encode_frame(struct stm32_venc_data *data) /* one key frame every seconds */ if ((data->frame_nb % VENC_DEFAULT_FRAMERATE) == 0 || data->resync) { /* if frame is the first or resync needed: set as intra coded */ - encIn.codingType = H264ENC_INTRA_FRAME; + enc_in.codingType = H264ENC_INTRA_FRAME; } else { /* if there was a frame previously, set as predicted */ - encIn.timeIncrement = 1; - encIn.codingType = H264ENC_PREDICTED_FRAME; + enc_in.timeIncrement = 1; + enc_in.codingType = H264ENC_PREDICTED_FRAME; } - encIn.ipf = H264ENC_REFERENCE_AND_REFRESH; - encIn.ltrf = H264ENC_REFERENCE; + enc_in.ipf = H264ENC_REFERENCE_AND_REFRESH; + enc_in.ltrf = H264ENC_REFERENCE; /* set input buffers to structures */ - encIn.busLuma = (ptr_t)input->buffer; - encIn.busChromaU = (ptr_t)encIn.busLuma + data->in_fmt.width * data->in_fmt.height; + enc_in.busLuma = (ptr_t)input->buffer; + enc_in.busChromaU = (ptr_t)enc_in.busLuma + data->in_fmt.width * data->in_fmt.height; - encIn.pOutBuf = (uint32_t *)output->buffer; - encIn.busOutBuf = (uint32_t)encIn.pOutBuf; - encIn.outBufSize = output->size; - encOut.streamSize = 0; + enc_in.pOutBuf = (uint32_t *)output->buffer; + enc_in.busOutBuf = (uint32_t)enc_in.pOutBuf; + enc_in.outBufSize = output->size; + enc_out.streamSize = 0; - ret = H264EncStrmEncode(data->encoder, &encIn, &encOut, NULL, NULL, NULL); - output->bytesused = encOut.streamSize; - LOG_DBG("output=%p, encOut.streamSize=%d", output, encOut.streamSize); + h264ret = H264EncStrmEncode(data->encoder, &enc_in, &enc_out, NULL, NULL, NULL); + output->bytesused = enc_out.streamSize; + LOG_DBG("output=%p, enc_out.streamSize=%d", output, enc_out.streamSize); - switch (ret) { + switch (h264ret) { case H264ENC_FRAME_READY: /* save stream */ - if (encOut.streamSize == 0) { + if (enc_out.streamSize == 0) { /* Nothing encoded */ data->resync = true; goto out; } - output->bytesused = encOut.streamSize; + output->bytesused = enc_out.streamSize; break; case H264ENC_FUSE_ERROR: - LOG_ERR("H264EncStrmEncode error=%d", ret); + LOG_ERR("H264EncStrmEncode error=%d", h264ret); LOG_ERR("DCMIPP and VENC desync at frame %d, restart the video", data->frame_nb); encoder_end(data); @@ -663,7 +669,7 @@ static int encode_frame(struct stm32_venc_data *data) } break; default: - LOG_ERR("H264EncStrmEncode error=%d", ret); + LOG_ERR("H264EncStrmEncode error=%d", h264ret); LOG_ERR("error encoding frame %d", data->frame_nb); encoder_end(data); @@ -835,19 +841,19 @@ static const struct stm32_venc_config stm32_venc_config_0 = { .irq_config = stm32_venc_irq_config_func, }; -static void RISAF_Config(void) +static void risaf_config(void) { /* Define and initialize the master configuration structure */ - RIMC_MasterConfig_t RIMC_master = {0}; + 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; + 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); + 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, @@ -884,7 +890,7 @@ static int stm32_venc_init(const struct device *dev) /* Run IRQ init */ config->irq_config(dev); - RISAF_Config(); + risaf_config(); LOG_DBG("CPU frequency : %d", HAL_RCC_GetCpuClockFreq() / 1000000); LOG_DBG("sysclk frequency : %d", HAL_RCC_GetSysClockFreq() / 1000000); diff --git a/drivers/watchdog/Kconfig.gecko b/drivers/watchdog/Kconfig.gecko index 55fbd7b8e1755..e0b55fac846cd 100644 --- a/drivers/watchdog/Kconfig.gecko +++ b/drivers/watchdog/Kconfig.gecko @@ -10,6 +10,7 @@ config WDT_GECKO default y depends on DT_HAS_SILABS_GECKO_WDOG_ENABLED select HAS_WDT_DISABLE_AT_BOOT - select SOC_GECKO_WDOG + select SOC_GECKO_WDOG if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 + select SILABS_SISDK_WDOG if SOC_FAMILY_SILABS_S2 help Enable WDOG driver for Silicon Labs Gecko MCUs. diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c index fb1846e3d5eb1..7604b82b66ea1 100644 --- a/drivers/wifi/infineon/airoc_wifi.c +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -13,6 +13,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); @@ -811,6 +812,80 @@ static int airoc_mgmt_ap_disable(const struct device *dev) return 0; } +static int airoc_iface_status(const struct device *dev, struct wifi_iface_status *status) +{ + struct airoc_wifi_data *data = dev->data; + whd_result_t result; + wl_bss_info_t bss_info; + whd_security_t security_info = 0; + uint32_t wpa_data_rate_value = 0; + uint32_t join_status; + + if (airoc_if == NULL) { + return -ENOTSUP; + } + + status->iface_mode = + (data->is_ap_up ? WIFI_MODE_AP + : (data->is_sta_connected ? WIFI_MODE_INFRA : WIFI_MODE_UNKNOWN)); + + join_status = whd_wifi_is_ready_to_transceive(airoc_if); + + if (join_status == WHD_SUCCESS) { + status->state = WIFI_STATE_COMPLETED; + } else if (join_status == WHD_JOIN_IN_PROGRESS) { + status->state = WIFI_STATE_ASSOCIATING; + } else if (join_status == WHD_NOT_KEYED) { + status->state = WIFI_STATE_AUTHENTICATING; + } else { + status->state = WIFI_STATE_DISCONNECTED; + } + + result = whd_wifi_get_ap_info(airoc_if, &bss_info, &security_info); + + if (result == WHD_SUCCESS) { + memcpy(&(status->bssid[0]), &(bss_info.BSSID), sizeof(whd_mac_t)); + + whd_wifi_get_channel(airoc_if, (int *)&status->channel); + + status->band = (status->channel <= CH_MAX_2G_CHANNEL) ? WIFI_FREQ_BAND_2_4_GHZ + : WIFI_FREQ_BAND_5_GHZ; + + status->rssi = (int)bss_info.RSSI; + + status->ssid_len = bss_info.SSID_len; + strncpy(status->ssid, bss_info.SSID, status->ssid_len); + + status->security = convert_whd_security_to_zephyr(security_info); + + status->beacon_interval = (unsigned short)bss_info.beacon_period; + status->dtim_period = (unsigned char)bss_info.dtim_period; + + status->twt_capable = false; + } + + whd_wifi_get_ioctl_value(airoc_if, WLC_GET_RATE, &wpa_data_rate_value); + status->current_phy_tx_rate = wpa_data_rate_value; + + /* Unbelievably, this appears to be the only way to determine the phy mode with + * the whd SDK that we're currently using. Note that the logic below is only valid on + * devices that are limited to the 2.4Ghz band. Other versions of the SDK and chip + * evidently allow one to obtain a phy_mode value directly from bss_info + */ + if (wpa_data_rate_value > 54) { + status->link_mode = WIFI_4; + } else if (wpa_data_rate_value == 6 || wpa_data_rate_value == 9 || + wpa_data_rate_value == 12 || wpa_data_rate_value == 18 || + wpa_data_rate_value == 24 || wpa_data_rate_value == 36 || + wpa_data_rate_value == 48 || wpa_data_rate_value == 54) { + status->link_mode = WIFI_3; + } else { + status->link_mode = WIFI_1; + } + + return 0; +} + static int airoc_init(const struct device *dev) { int ret; @@ -864,6 +939,7 @@ static const struct wifi_mgmt_ops airoc_wifi_mgmt = { .disconnect = airoc_mgmt_disconnect, .ap_enable = airoc_mgmt_ap_enable, .ap_disable = airoc_mgmt_ap_disable, + .iface_status = airoc_iface_status, #if defined(CONFIG_NET_STATISTICS_WIFI) .get_stats = airoc_mgmt_wifi_stats, #endif diff --git a/dts/arm/infineon/cat1b/psc3/psc3.dtsi b/dts/arm/infineon/cat1b/psc3/psc3.dtsi index 4fd0e445ba677..e5841caf190b0 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3.dtsi @@ -128,12 +128,20 @@ #gpio-cells = <2>; }; - adc0: adc@42b70000 { - compatible = "infineon,adc-hppass-saradc"; - reg = <0x42b70000 0x10000>; - interrupts = <109 4>; - status = "disabled"; - #io-channel-cells = <1>; + hppass_analog0: analog@42b00000 { + reg = <0x42b00000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + adc0: adc@70000 { + compatible = "infineon,hppass-sar-adc"; + /* Offset within HPPASS analog region => 0x42b70000 physical */ + reg = <0x00070000 0x10000>; + interrupts = <109 4>; + status = "disabled"; + #io-channel-cells = <1>; + }; }; ipc0: ipc@421d0000 { diff --git a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi index 22ad1853b7c48..ac013a84dc21d 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi @@ -128,12 +128,20 @@ #gpio-cells = <2>; }; - adc0: adc@52b70000 { - compatible = "infineon,adc-hppass-saradc"; - reg = <0x52b70000 0x10000>; - interrupts = <109 4>; - status = "disabled"; - #io-channel-cells = <1>; + hppass_analog0: analog@52b00000 { + reg = <0x52b00000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + adc0: adc@70000 { + compatible = "infineon,hppass-sar-adc"; + /* Offset within HPPASS analog region */ + reg = <0x00070000 0x10000>; + interrupts = <109 4>; + status = "disabled"; + #io-channel-cells = <1>; + }; }; ipc0: ipc@521d0000 { diff --git a/dts/arm/microchip/mec/mec5.dtsi b/dts/arm/microchip/mec/mec5.dtsi index b0e3ad69cf82c..87b9345e37692 100644 --- a/dts/arm/microchip/mec/mec5.dtsi +++ b/dts/arm/microchip/mec/mec5.dtsi @@ -34,6 +34,7 @@ reg = <0x40080100 0x100 0x4000a400 0x100>; reg-names = "pcrr", "vbatr"; interrupts = <174 0>; + girqs = <20 9>; status = "disabled"; }; @@ -171,6 +172,7 @@ reg = <0x40081000 0x80 0x40081300 0x04 0x40081380 0x04 0x400813fc 0x04>; interrupts = <3 2>; + girqs = <11 255>; gpio-controller; #gpio-cells = <2>; }; @@ -180,6 +182,7 @@ reg = <0x40081080 0x80 0x40081304 0x04 0x40081384 0x04 0x400813f8 0x4>; interrupts = <2 2>; + girqs = <10 255>; gpio-controller; #gpio-cells = <2>; }; @@ -190,7 +193,8 @@ 0x40081388 0x04 0x400813f4 0x04>; gpio-controller; interrupts = <1 2>; - #gpio-cells = <2>; + girqs = <9 255>; + #gpio-cells=<2>; }; gpio_140_176: gpio@40081180 { @@ -199,7 +203,8 @@ 0x4008138c 0x04 0x400813f0 0x04>; gpio-controller; interrupts = <0 2>; - #gpio-cells = <2>; + girqs = <8 255>; + #gpio-cells=<2>; }; gpio_200_236: gpio@40081200 { @@ -208,7 +213,8 @@ 0x40081390 0x04 0x400813ec 0x04>; gpio-controller; interrupts = <4 2>; - #gpio-cells = <2>; + girqs = <12 255>; + #gpio-cells=<2>; }; gpio_240_276: gpio@40081280 { @@ -217,25 +223,29 @@ 0x40081394 0x04 0x400813e8 0x04>; gpio-controller; interrupts = <17 2>; - #gpio-cells = <2>; + girqs = <26 255>; + #gpio-cells=<2>; }; }; uart0: uart@400f2400 { reg = <0x400f2400 0x400>; interrupts = <40 1>; + girqs = <15 0>; status = "disabled"; }; uart1: uart@400f2800 { reg = <0x400f2800 0x400>; interrupts = <41 1>; + girqs = <15 1>; status = "disabled"; }; watchdog0: watchdog@40000400 { reg = <0x40000400 0x400>; interrupts = <171 0>; + girqs = <21 2>; status = "disabled"; }; @@ -253,6 +263,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000c00 0x20>; interrupts = <136 0>; + girqs = <23 0>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffff>; @@ -263,6 +274,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000c20 0x20>; interrupts = <137 0>; + girqs = <23 1>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffff>; @@ -273,6 +285,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000c40 0x20>; interrupts = <138 0>; + girqs = <23 2>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffff>; @@ -283,6 +296,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000c60 0x20>; interrupts = <139 0>; + girqs = <23 3>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffff>; @@ -293,6 +307,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000c80 0x20>; interrupts = <140 0>; + girqs = <23 4>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffffffff>; @@ -303,6 +318,7 @@ compatible = "microchip,xec-basic-timer"; reg = <0x40000ca0 0x20>; interrupts = <141 0>; + girqs = <23 5>; clock-frequency = <48000000>; prescaler = <0>; max-value = <0xffffffff>; @@ -312,57 +328,69 @@ cntr0: timer@40000d00 { reg = <0x40000d00 0x20>; interrupts = <142 0>; + girqs = <23 6>; status = "disabled"; }; cntr1: timer@40000d20 { reg = <0x40000d20 0x20>; interrupts = <143 0>; + girqs = <23 7>; status = "disabled"; }; cntr2: timer@40000d40 { reg = <0x40000d40 0x20>; interrupts = <144 0>; + girqs = <23 8>; status = "disabled"; }; cntr3: timer@40000d60 { reg = <0x40000d60 0x20>; interrupts = <145 0>; + girqs = <23 9>; status = "disabled"; }; cctmr0: timer@40001000 { reg = <0x40001000 0x40>; interrupts = <146 0>, <147 0>, <148 0>, <149 0>, - <150 0>, <151 0>, <152 0>, <153 0>, - <154 0>; + <150 0>, <151 0>, <152 0>, <153 0>, <154 0>; + interrupt-names = "counter", "cap0", "cap1", "cap2", "cap3", + "cap4", "cap5", "comp0", "comp1"; + girqs = <18 20>, <18 21>, <18 22>, <18 23>, + <18 24>, <18 25>, <18 26>, <18 27>, <18 28>; status = "disabled"; }; hibtimer0: timer@40009800 { reg = <0x40009800 0x20>; interrupts = <112 0>; + girqs = <23 16>; status = "disabled"; }; hibtimer1: timer@40009820 { reg = <0x40009820 0x20>; interrupts = <113 0>; + girqs = <23 17>; status = "disabled"; }; weektmr0: timer@4000ac80 { reg = <0x4000ac80 0x80>; - interrupts = <114 0>, <115 0>, <116 0>, - <117 0>, <118 0>; + interrupts = <114 0>, <115 0>, <116 0>, <117 0>, <118 0>; + interrupt-names = "wk_alarm", "subwk_alarm", "one_sec", "sub_sec", "syspp"; + girqs = <21 3>, <21 4>, <21 5>, <21 6>, <21 7>; status = "disabled"; }; rtc0: rtc@400f5000 { reg = <0x400f5000 0x100>; interrupts = <119 3>, <120 3>; + interrupt-names = "rtc", "rtc_alarm"; + girqs = <21 8>, <21 9>; status = "disabled"; }; @@ -374,15 +402,18 @@ vci0: vci@4000ae00 { reg = <0x4000ae00 0x40>; - interrupts = <121 0>, <122 0>, <123 0>, - <124 0>, <125 0>; + interrupts = <121 2>, <122 2>, <123 2>, <124 2>, <125 2>, <126 2>; + interrupt-names = "vci_ovrd_in", "vci_in0", "vci_in1", "vci_in2", + "vci_in3", "vci_in4"; + girqs = <21 10>, <21 11>, <21 12>, <21 13>, <21 14>, <21 15>; status = "disabled"; }; i2c_smb_0: i2c@40004000 { reg = <0x40004000 0x80>; clock-frequency = ; - interrupts = <20 1>; + interrupts = <20 2>; + girqs = <13 0>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -391,7 +422,8 @@ i2c_smb_1: i2c@40004400 { reg = <0x40004400 0x80>; clock-frequency = ; - interrupts = <21 1>; + interrupts = <21 2>; + girqs = <13 1>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -400,7 +432,8 @@ i2c_smb_2: i2c@40004800 { reg = <0x40004800 0x80>; clock-frequency = ; - interrupts = <22 1>; + interrupts = <22 2>; + girqs = <13 2>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -409,7 +442,8 @@ i2c_smb_3: i2c@40004c00 { reg = <0x40004C00 0x80>; clock-frequency = ; - interrupts = <23 1>; + interrupts = <23 2>; + girqs = <13 3>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -418,7 +452,8 @@ i2c_smb_4: i2c@40005000 { reg = <0x40005000 0x80>; clock-frequency = ; - interrupts = <158 1>; + interrupts = <158 2>; + girqs = <13 4>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -426,7 +461,8 @@ ps2_0: ps2@40009000 { reg = <0x40009000 0x40>; - interrupts = <100 1>; + interrupts = <100 3>; + girqs = <18 10>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -488,7 +524,8 @@ tach0: tach@40006000 { reg = <0x40006000 0x10>; - interrupts = <71 4>; + interrupts = <71 3>; + girqs = <17 1>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -496,7 +533,8 @@ tach1: tach@40006010 { reg = <0x40006010 0x10>; - interrupts = <72 4>; + interrupts = <72 3>; + girqs = <17 2>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -504,7 +542,8 @@ tach2: tach@40006020 { reg = <0x40006020 0x10>; - interrupts = <73 4>; + interrupts = <73 3>; + girqs = <17 3>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -512,7 +551,8 @@ tach3: tach@40006030 { reg = <0x40006030 0x10>; - interrupts = <159 4>; + interrupts = <159 3>; + girqs = <17 4>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -520,19 +560,25 @@ rpmfan0: rpmfan@4000a000 { reg = <0x4000a000 0x80>; - interrupts = <74 1>, <75 1>; + interrupts = <74 3>, <75 3>; + interrupt-names = "stall", "spin"; + girqs = <17 20>, <17 21>; status = "disabled"; }; rpmfan1: rpmfan@4000a080 { reg = <0x4000a080 0x80>; - interrupts = <76 1>, <77 1>; + interrupts = <76 3>, <77 3>; + interrupt-names = "stall", "spin"; + girqs = <17 22>, <17 23>; status = "disabled"; }; adc0: adc@40007c00 { reg = <0x40007c00 0x90>; - interrupts = <78 0>, <79 0>; + interrupts = <78 3>, <79 3>; + interrupt-names = "single", "repeat"; + girqs = <17 8>, <17 9>; interrupt-names = "single", "repeat"; status = "disabled"; #io-channel-cells = <1>; @@ -541,7 +587,8 @@ peci0: peci@40006400 { reg = <0x40006400 0x80>; - interrupts = <70 4>; + interrupts = <70 3>; + girqs = <17 0>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -550,6 +597,7 @@ qspi0: spi@40070000 { reg = <0x40070000 0x400>; interrupts = <91 2>; + girqs = <18 1>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -557,55 +605,65 @@ prochot0: prochot@40003400 { reg = <0x40003400 0x20>; - interrupts = <87 0>; + interrupts = <87 3>; + girqs = <17 17>; status = "disabled"; }; rcid0: rcid@40001400 { reg = <0x40001400 0x80>; - interrupts = <80 0>; + interrupts = <80 3>; + girqs = <17 10>; status = "disabled"; }; rcid1: rcid@40001480 { reg = <0x40001480 0x80>; - interrupts = <81 0>; + interrupts = <81 3>; + girqs = <17 11>; status = "disabled"; }; rcid2: rcid@40001500 { reg = <0x40001500 0x80>; - interrupts = <82 0>; + interrupts = <82 3>; + girqs = <17 12>; status = "disabled"; }; bbled0: bbled@4000b800 { reg = <0x4000b800 0x100>; - interrupts = <83 0>; + interrupts = <83 3>; + girqs = <17 13>; status = "disabled"; }; bbled1: bbled@4000b900 { reg = <0x4000b900 0x100>; - interrupts = <84 0>; + interrupts = <84 3>; + girqs = <17 14>; status = "disabled"; }; bbled2: bbled@4000ba00 { reg = <0x4000ba00 0x100>; - interrupts = <85 0>; + interrupts = <85 3>; + girqs = <17 15>; status = "disabled"; }; bbled3: bbled@4000bb00 { reg = <0x4000bb00 0x100>; - interrupts = <86 0>; + interrupts = <86 3>; + girqs = <17 16>; status = "disabled"; }; bclink0: bclink@4000cd00 { reg = <0x4000cd00 0x20>; - interrupts = <96 0>, <97 0>; + interrupts = <96 3>, <97 3>; + interrupt-names = "bcm_err", "bcm_done"; + girqs = <18 7>, <18 6>; status = "disabled"; }; @@ -632,6 +690,8 @@ interrupt-names = "pc", "bm1", "bm2", "ltr", "oob_up", "oob_dn", "fc", "erst", "vw_chan_en", "vwct_0_6", "vwct_7_10"; + girqs = <19 0>, <19 1>, <19 2>, <19 3>, <19 4>, <19 5>, + <19 6>, <19 7>, <19 8>, <24 255>, <25 255>; status = "disabled"; /* Devices accessible to the Host via Logical Device mechanism. @@ -642,6 +702,7 @@ mbox0: mbox@400f0000 { reg = <0x400f0000 0x200>; interrupts = <60 3>; + girqs = <15 20>; status = "disabled"; }; @@ -649,6 +710,7 @@ reg = <0x400f0400 0x400>, <0x400f2000 0x400>; interrupts = <59 3>, <58 3>; interrupt-names = "ibf", "obe"; + girqs = <15 19>, <15 18>; status = "disabled"; }; @@ -656,6 +718,7 @@ reg = <0x400f0800 0x400>; interrupts = <45 3>, <46 3>; interrupt-names = "ibf", "obe"; + girqs = <15 5>, <15 6>; status = "disabled"; }; @@ -663,6 +726,7 @@ reg = <0x400f0c00 0x400>; interrupts = <47 3>, <48 3>; interrupt-names = "ibf", "obe"; + girqs = <15 7>, <15 8>; status = "disabled"; }; @@ -670,6 +734,7 @@ reg = <0x400f1000 0x400>; interrupts = <49 3>, <50 3>; interrupt-names = "ibf", "obe"; + girqs = <15 9>, <15 10>; status = "disabled"; }; @@ -677,6 +742,7 @@ reg = <0x400f1400 0x400>; interrupts = <51 3>, <52 3>; interrupt-names = "ibf", "obe"; + girqs = <15 11>, <15 12>; status = "disabled"; }; @@ -684,6 +750,7 @@ reg = <0x400f1800 0x400>; interrupts = <53 3>, <54 3>; interrupt-names = "ibf", "obe"; + girqs = <15 13>, <15 14>; status = "disabled"; }; @@ -691,30 +758,35 @@ reg = <0x400f1c00 0x400>; interrupts = <55 3>, <56 3>, <57 3>; interrupt-names = "ctl", "en", "sts"; + girqs = <15 15>, <15 16>, <15 17>; status = "disabled"; }; glue: glue_logic@400f3c00 { reg = <0x400f3c00 0x200>; interrupts = <172 1>; + girqs = <21 26>; status = "disabled"; }; emi0: emi@400f4000 { reg = <0x400f4000 0x400>; interrupts = <42 3>; + girqs = <15 2>; status = "disabled"; }; emi1: emi@400f4400 { reg = <0x400f4400 0x400>; interrupts = <43 3>; + girqs = <15 3>; status = "disabled"; }; emi2: emi@400f4800 { reg = <0x400f4800 0x400>; interrupts = <44 3>; + girqs = <15 4>; status = "disabled"; }; @@ -725,21 +797,23 @@ p80bd0: p80bd@400f8000 { reg = <0x400f8000 0x400>; interrupts = <62 0>; + girqs = <15 22>; status = "disabled"; }; - }; - /* eSPI target attached flash controller. - * When this device is fully activated via its driver, it takes - * ownership of the QSPI controller. EC access to QSPI - * registers is discarded by hardware. - */ - espi_taf0: espi_taf@40008000 { - reg = <0x40008000 0x400>, <0x40070000 0x400>, <0x40071000 0x400>; - reg-names = "tafbr", "tafqspi", "tafcomm"; - interrupts = <166 3>, <167 3>; - interrupt-names = "done", "err"; - status = "disabled"; + /* eSPI target attached flash controller. + * When this device is fully activated via its driver, it takes + * ownership of the QSPI controller. EC access to QSPI + * registers is discarded by hardware. + */ + espi_taf0: espi_taf@40008000 { + reg = <0x40008000 0x400>, <0x40071000 0x400>; + reg-names = "tafbr", "tafcomm"; + interrupts = <166 3>, <167 3>; + interrupt-names = "done", "err"; + girqs = <19 9>, <19 10>; + status = "disabled"; + }; }; }; }; diff --git a/dts/arm/microchip/mec/mec5/mec5_pkg176_uarts.dtsi b/dts/arm/microchip/mec/mec5/mec5_pkg176_uarts.dtsi deleted file mode 100644 index b1ebea4552707..0000000000000 --- a/dts/arm/microchip/mec/mec5/mec5_pkg176_uarts.dtsi +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024 Microchip Technology Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* Microchip MEC5 MEC174x, MEC540x, MEC175x, and MEC550x add two more UART's - * in the 176-pin (LJ) package. - * Include this file in the soc {} section in the above chip DTSI files. - */ -uart2: uart@400f2c00 { - reg = <0x400f2c00 0x400>; - interrupts = <183 1>; - clock-frequency = <1843200>; - current-speed = <38400>; - status = "disabled"; -}; - -uart3: uart@400f3000 { - reg = <0x400f3000 0x400>; - interrupts = <184 1>; - clock-frequency = <1843200>; - current-speed = <38400>; - status = "disabled"; -}; diff --git a/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi b/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi index 694e95fa885ef..3cc2cc8d2d567 100644 --- a/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi @@ -23,11 +23,38 @@ #include "mec5/mec5_gpspi_v2.dtsi" #include "mec5/mec5_eeprom_8kb.dtsi" #include "mec5/mec5_pkg176_pwms.dtsi" - #include "mec5/mec5_pkg176_uarts.dtsi" + + ps2_1: ps2@40009040 { + reg = <0x40009040 0x40>; + interrupts = <101 3>; + girqs = <18 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; + girqs = <21 25>; + status = "disabled"; + }; + + uart2: uart@400f2c00 { + reg = <0x400f2c00 0x400>; + interrupts = <183 2>; + girqs = <15 25>; + clock-frequency = <1843200>; + current-speed = <115200>; + status = "disabled"; + }; + + uart3: uart@400f3000 { + reg = <0x400f3000 0x400>; + interrupts = <184 2>; + girqs = <15 26>; + 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 5d16b727bf5c3..e5b18db3e2f82 100644 --- a/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi @@ -23,17 +23,28 @@ #include "mec5/mec5_gpspi_v2.dtsi" #include "mec5/mec5_eeprom_8kb.dtsi" + ps2_1: ps2@40009040 { + reg = <0x40009040 0x40>; + interrupts = <101 3>; + girqs = <18 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; + girqs = <21 25>; status = "disabled"; }; uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; - interrupts = <183 1>; + interrupts = <183 2>; + girqs = <15 25>; clock-frequency = <1843200>; - current-speed = <38400>; + current-speed = <115200>; status = "disabled"; }; }; diff --git a/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi b/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi index 1d278d3e7db8a..cd9fa15534c6e 100644 --- a/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi @@ -23,13 +23,39 @@ #include "mec5/mec5_eeprom_8kb.dtsi" #include "mec5/mec5_gpspi_v2.dtsi" #include "mec5/mec5_pkg176_pwms.dtsi" - #include "mec5/mec5_pkg176_uarts.dtsi" #include "mec5/mec5_i3c.dtsi" + ps2_1: ps2@40009040 { + reg = <0x40009040 0x40>; + interrupts = <101 3>; + girqs = <18 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; status = "disabled"; }; + + uart2: uart@400f2c00 { + reg = <0x400f2c00 0x400>; + interrupts = <183 2>; + girqs = <15 25>; + clock-frequency = <1843200>; + current-speed = <115200>; + status = "disabled"; + }; + + uart3: uart@400f3000 { + reg = <0x400f3000 0x400>; + interrupts = <184 2>; + girqs = <15 26>; + 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 df30851445728..f80e73d29f640 100644 --- a/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi @@ -24,17 +24,28 @@ #include "mec5/mec5_gpspi_v2.dtsi" #include "mec5/mec5_i3c.dtsi" + ps2_1: ps2@40009040 { + reg = <0x40009040 0x40>; + interrupts = <101 3>; + girqs = <18 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; + girqs = <21 25>; status = "disabled"; }; uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; - interrupts = <183 1>; + interrupts = <183 2>; + girqs = <15 25>; clock-frequency = <1843200>; - current-speed = <38400>; + current-speed = <115200>; status = "disabled"; }; }; diff --git a/dts/arm/microchip/mec/mec5_mech1723nlj.dtsi b/dts/arm/microchip/mec/mec5_mech1723nlj.dtsi index 82a0aa2b2e048..ef52a56ea76d9 100644 --- a/dts/arm/microchip/mec/mec5_mech1723nlj.dtsi +++ b/dts/arm/microchip/mec/mec5_mech1723nlj.dtsi @@ -27,6 +27,7 @@ kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; + girqs = <21 25>; status = "disabled"; }; }; diff --git a/dts/arm/microchip/mec/mec5_mech1723nsz.dtsi b/dts/arm/microchip/mec/mec5_mech1723nsz.dtsi index 02cdbab26fc69..8184582e83c1b 100644 --- a/dts/arm/microchip/mec/mec5_mech1723nsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mech1723nsz.dtsi @@ -26,6 +26,7 @@ kscan0: kscan@40009c00 { reg = <0x40009c00 0x18>; interrupts = <135 0>; + girqs = <21 25>; status = "disabled"; }; }; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_1051_ca.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_1051_ca.dtsi new file mode 100644 index 0000000000000..91334645d5464 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_1051_ca.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(1)>; + }; + + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(512)>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_2051_ca.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_2051_ca.dtsi new file mode 100644 index 0000000000000..01cad81f1a375 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_2051_ca.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(2)>; + }; + + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(512)>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_4010_ca.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_4010_ca.dtsi new file mode 100644 index 0000000000000..ef0c4115ee646 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_4010_ca.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(4)>; + }; + + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_M(1)>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_8110_ca.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_8110_ca.dtsi new file mode 100644 index 0000000000000..f592d9bcdbfcc --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_8110_ca.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(8)>; + }; + + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_M(1)>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca.dtsi new file mode 100644 index 0000000000000..9fdaef3a8f95e --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca.dtsi @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + flash0: flash@8000000 { + compatible = "soc-nv-flash"; + write-block-size = <8>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + }; + + porta: gpio@44840000 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840000 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portb: gpio@44840080 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840080 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portc: gpio@44840100 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840100 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portd: gpio@44840180 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840180 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_100.dtsi new file mode 100644 index 0000000000000..ffc24df06c27f --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_100.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_144.dtsi new file mode 100644 index 0000000000000..ffc24df06c27f --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_144.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_176.dtsi new file mode 100644 index 0000000000000..d8d8e4f8c44c3 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_176.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + porte: gpio@44840200 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840200 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portf: gpio@44840280 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840280 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portg: gpio@44840300 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840300 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_208.dtsi new file mode 100644 index 0000000000000..d8d8e4f8c44c3 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/common/pic32cz_ca_208.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + porte: gpio@44840200 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840200 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portf: gpio@44840280 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840280 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + + portg: gpio@44840300 { + status = "disabled"; + compatible = "microchip,port-g1-gpio"; + reg = <0x44840300 0x80>; + gpio-controller; + #gpio-cells = <2>; + #microchip,pin-cells = <2>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80100.dtsi new file mode 100644 index 0000000000000..2f635a4b33689 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80144.dtsi new file mode 100644 index 0000000000000..29f60b2194bd9 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80176.dtsi new file mode 100644 index 0000000000000..db11ef5defafe --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80208.dtsi new file mode 100644 index 0000000000000..fcde5e4923a91 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz2051ca80208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80100.dtsi new file mode 100644 index 0000000000000..1531dbb0beb63 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80144.dtsi new file mode 100644 index 0000000000000..8ca3da5228e35 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80176.dtsi new file mode 100644 index 0000000000000..8ebcc3dc3d1e4 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80208.dtsi new file mode 100644 index 0000000000000..7dd5bac8da05c --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz4010ca80208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80100.dtsi new file mode 100644 index 0000000000000..c20876e390487 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80144.dtsi new file mode 100644 index 0000000000000..55cb09f063df4 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80176.dtsi new file mode 100644 index 0000000000000..b75f0715ca1d5 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80208.dtsi new file mode 100644 index 0000000000000..cac3e7ea75d63 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca80/pic32cz8110ca80208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90100.dtsi new file mode 100644 index 0000000000000..2f635a4b33689 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90144.dtsi new file mode 100644 index 0000000000000..29f60b2194bd9 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90176.dtsi new file mode 100644 index 0000000000000..db11ef5defafe --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90208.dtsi new file mode 100644 index 0000000000000..fcde5e4923a91 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz2051ca90208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90100.dtsi new file mode 100644 index 0000000000000..1531dbb0beb63 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90144.dtsi new file mode 100644 index 0000000000000..8ca3da5228e35 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90176.dtsi new file mode 100644 index 0000000000000..8ebcc3dc3d1e4 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90208.dtsi new file mode 100644 index 0000000000000..7dd5bac8da05c --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz4010ca90208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90100.dtsi new file mode 100644 index 0000000000000..c20876e390487 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90144.dtsi new file mode 100644 index 0000000000000..55cb09f063df4 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90176.dtsi new file mode 100644 index 0000000000000..b75f0715ca1d5 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90208.dtsi new file mode 100644 index 0000000000000..cac3e7ea75d63 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca90/pic32cz8110ca90208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91100.dtsi new file mode 100644 index 0000000000000..2f635a4b33689 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91144.dtsi new file mode 100644 index 0000000000000..29f60b2194bd9 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91176.dtsi new file mode 100644 index 0000000000000..db11ef5defafe --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz2051ca91176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91100.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91100.dtsi new file mode 100644 index 0000000000000..1531dbb0beb63 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91100.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91144.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91144.dtsi new file mode 100644 index 0000000000000..8ca3da5228e35 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91144.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91176.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91176.dtsi new file mode 100644 index 0000000000000..8ebcc3dc3d1e4 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91176.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include diff --git a/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91208.dtsi b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91208.dtsi new file mode 100644 index 0000000000000..7dd5bac8da05c --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cz_ca/pic32cz_ca91/pic32cz4010ca91208.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include 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 d799321d5be4e..efc33042eff97 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi @@ -5,6 +5,7 @@ */ #include +#include #include / { @@ -54,6 +55,12 @@ }; }; + rstc: rstc@40000c00 { + compatible = "microchip,rstc-g1-reset"; + status = "disabled"; + reg = <0x40000c00 0x400>; + }; + sercom0: sercom@40003000 { compatible = "microchip,sercom-g1"; status = "disabled"; @@ -117,6 +124,39 @@ clock-names = "mclk", "gclk"; }; + tcc0: tcc@41016000 { + compatible = "microchip,tcc-g1"; + reg = <0x41016000 0x2000>; + interrupts = <85 0>, <86 0>, <87 0>, <88 0>, <89 0>, <90 0>, <91 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TCC0>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC0>; + clock-names = "mclk", "gclk"; + max-bit-width = <24>; + channels = <6>; + }; + + tcc1: tcc@41018000 { + compatible = "microchip,tcc-g1"; + reg = <0x41018000 0x2000>; + interrupts = <92 0>, <93 0>, <94 0>, <95 0>, <96 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TCC1>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC1>; + clock-names = "mclk", "gclk"; + max-bit-width = <24>; + channels = <4>; + }; + + tcc2: tcc@42000c00 { + compatible = "microchip,tcc-g1"; + reg = <0x42000c00 0x2000>; + interrupts = <97 0>, <98 0>, <99 0>, <100 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TCC2>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC2>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <3>; + }; + sercom4: sercom@43000000 { compatible = "microchip,sercom-g1"; status = "disabled"; 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 new file mode 100644 index 0000000000000..68e36423459e1 --- /dev/null +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + tcc3: tcc@42001000 { + compatible = "microchip,tcc-g1"; + reg = <0x42001000 0x2000>; + interrupts = <101 0>, <102 0>, <103 0>; + clocks = <&mclkperiphperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TCC3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC3>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; + + tcc4: tcc@43001000 { + compatible = "microchip,tcc-g1"; + reg = <0x43001000 0x2000>; + interrupts = <104 0>, <105 0>, <106 0>; + clocks = <&mclkperiphperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TCC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; + }; +}; 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 208a4cec49da4..dd74a5e521e08 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 @@ -6,6 +6,17 @@ / { soc { + tcc3: tcc@42001000 { + compatible = "microchip,tcc-g1"; + reg = <0x42001000 0x2000>; + interrupts = <101 0>, <102 0>, <103 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TCC3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC3>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; + sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; status = "disabled"; @@ -25,5 +36,16 @@ <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM7_CORE>; clock-names = "mclk", "gclk"; }; + + tcc4: tcc@43001000 { + compatible = "microchip,tcc-g1"; + reg = <0x43001000 0x2000>; + interrupts = <104 0>, <105 0>, <106 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TCC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; }; }; 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 208a4cec49da4..dd74a5e521e08 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 @@ -6,6 +6,17 @@ / { soc { + tcc3: tcc@42001000 { + compatible = "microchip,tcc-g1"; + reg = <0x42001000 0x2000>; + interrupts = <101 0>, <102 0>, <103 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TCC3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC3>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; + sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; status = "disabled"; @@ -25,5 +36,16 @@ <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM7_CORE>; clock-names = "mclk", "gclk"; }; + + tcc4: tcc@43001000 { + compatible = "microchip,tcc-g1"; + reg = <0x43001000 0x2000>; + interrupts = <104 0>, <105 0>, <106 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TCC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TCC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + }; }; }; diff --git a/dts/arm/microchip/sam/sama7d6.dtsi b/dts/arm/microchip/sam/sama7d6.dtsi new file mode 100644 index 0000000000000..da766b5d3a924 --- /dev/null +++ b/dts/arm/microchip/sam/sama7d6.dtsi @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include +#include + +/ { + model = "Microchip SAMA7D65 family SoC"; + compatible = "microchip,sama7d6"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0>; + }; + }; + + clocks { + main_xtal: main_xtal { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + slow_xtal: slow_xtal { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + }; + + soc { + sram: memory@100000 { + compatible = "mmio-sram"; + reg = <0x00100000 DT_SIZE_K(128)>; + }; + + pinctrl: pinctrl@e0014000 { + compatible = "microchip,sama7g5-pinctrl"; + reg = <0xe0014000 0x800>; + }; + + pmc: clock-controller@e0018000 { + compatible = "microchip,sam-pmc"; + reg = <0xe0018000 0x200>; + #clock-cells = <2>; + clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>; + clock-names = "td_slck", "md_slck", "main_xtal"; + }; + + clk32k: clock-controller@e001d500 { + compatible = "microchip,sama7g5-sckc", "microchip,sam9x60-sckc"; + reg = <0xe001d500 0x4>; + clocks = <&slow_xtal>; + #clock-cells = <1>; + }; + + rtc: rtc@e001d800 { + compatible = "atmel,sam-rtc"; + reg = <0xe001d800 0x30>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&clk32k 1>; + }; + + pit64b0: timer@e1800000 { + compatible = "microchip,sam-pit64b", "microchip,sam9x60-pit64b"; + reg = <0xe1800000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + }; + + flx0: flexcom@e1820000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe1820000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe1820000 0x800>; + status = "disabled"; + + i2c0: i2c0@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 34>; + status = "disabled"; + }; + + uart0: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 34>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx1: flexcom@e1824000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe1824000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe1824000 0x800>; + status = "disabled"; + + i2c1: i2c1@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; + status = "disabled"; + }; + + uart1: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx2: flexcom@e1828000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe1828000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe1828000 0x800>; + status = "disabled"; + + i2c2: i2c2@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 36>; + status = "disabled"; + }; + + uart2: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 36>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx3: flexcom@e182c000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe182c000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe182c000 0x800>; + status = "disabled"; + + i2c3: i2c3@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; + status = "disabled"; + }; + + uart3: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx4: flexcom@e2018000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe2018000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe2018000 0x800>; + status = "disabled"; + + i2c4: i2c4@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 38>; + status = "disabled"; + }; + + uart4: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 38>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx5: flexcom@e201c000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe201c000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe201c000 0x800>; + status = "disabled"; + + i2c5: i2c5@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; + status = "disabled"; + }; + + uart5: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx6: flexcom@e2020000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe2020000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe2020000 0x800>; + status = "disabled"; + + i2c6: i2c6@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 40>; + status = "disabled"; + }; + + uart6: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 40>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx7: flexcom@e2024000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe2024000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe2024000 0x800>; + status = "disabled"; + + i2c7: i2c7@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; + status = "disabled"; + }; + + uart7: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx8: flexcom@e281c000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe281c000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe281c000 0x800>; + status = "disabled"; + + i2c8: i2c8@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; + status = "disabled"; + }; + + uart8: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx9: flexcom@e2820000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe2820000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe2820000 0x800>; + status = "disabled"; + + i2c9: i2c9@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 43>; + status = "disabled"; + }; + + uart9: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 43>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + flx10: flexcom@e2824000 { + compatible = "microchip,sam-flexcom"; + reg = <0xe2824000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xe2824000 0x800>; + status = "disabled"; + + i2c10: i2c10@600 { + compatible = "atmel,sam-i2c-twi"; + reg = <0x600 0x200>; + clock-frequency = ; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 44>; + status = "disabled"; + }; + + uart10: serial@200 { + compatible = "atmel,sam-usart"; + reg = <0x200 0x200>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 44>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + }; + + gic: interrupt-controller@e8c11000 { + compatible = "arm,gic-v2", "arm,gic"; + reg = <0xe8c11000 0x1000>, <0xe8c12000 0x100>; + interrupt-controller; + #interrupt-cells = <4>; + }; + }; +}; diff --git a/dts/arm/microchip/sam/sama7g5.dtsi b/dts/arm/microchip/sam/sama7g5.dtsi index 65064d1502033..e067dffbafad5 100644 --- a/dts/arm/microchip/sam/sama7g5.dtsi +++ b/dts/arm/microchip/sam/sama7g5.dtsi @@ -46,6 +46,39 @@ #clock-cells = <1>; }; + dma0: dma-controller@e2808000 { + compatible = "atmel,sam-xdmac"; + reg = <0xe2808000 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + #dma-cells = <2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 22>; + clock-names = "dma_clk"; + status = "disabled"; + }; + + dma1: dma-controller@e280c000 { + compatible = "atmel,sam-xdmac"; + reg = <0xe280c000 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + #dma-cells = <2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 23>; + clock-names = "dma_clk"; + status = "disabled"; + }; + + dma2: dma-controller@e1200000 { + compatible = "atmel,sam-xdmac"; + reg = <0xe1200000 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + #dma-cells = <2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 24>; + clock-names = "dma_clk"; + status = "disabled"; + }; + flx0: flexcom@e1818000 { compatible = "microchip,sam-flexcom"; reg = <0xe1818000 0x200>; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index b9762248a5dfd..2dca938eaad66 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -60,7 +60,8 @@ reg = <0x50000000 0x10000000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x50000000 0x10000000>; + ranges = <0x0 0x50000000 0x10000000>, + <0x10000000 0x10000000 0x10000000>; /* Common nRF5340 Application MCU * peripheral description diff --git a/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi b/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi index d5aa024dd6d30..dff01d80d7fef 100644 --- a/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi @@ -66,7 +66,11 @@ nvic: &cpuapp_nvic {}; }; &grtc { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>, +#else interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>, +#endif <229 NRF_DEFAULT_IRQ_PRIORITY>; /* reserved for Zero Latency IRQs */ }; diff --git a/dts/arm/nuvoton/npck/npck.dtsi b/dts/arm/nuvoton/npck/npck.dtsi index 4fbb9cfcbeea8..ad083a755eb5d 100644 --- a/dts/arm/nuvoton/npck/npck.dtsi +++ b/dts/arm/nuvoton/npck/npck.dtsi @@ -535,13 +535,13 @@ /* PS2 Channels - Please use them as PS2 node */ ps2_channel2: io_ps2_channel2 { compatible = "nuvoton,npcx-ps2-channel"; - channel = <0x01>; + channel = <0x02>; status = "disabled"; }; ps2_channel3: io_ps2_channel3 { compatible = "nuvoton,npcx-ps2-channel"; - channel = <0x02>; + channel = <0x03>; status = "disabled"; }; }; diff --git a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi index 3ad260e4b5d55..1889513eed11e 100644 --- a/dts/arm/nxp/nxp_lpc55S2x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S2x_common.dtsi @@ -38,6 +38,11 @@ compatible = "arm,armv8m-mpu"; reg = <0xe000ed90 0x40>; }; + + itm: itm@e0000000 { + compatible = "arm,armv8m-itm"; + reg = <0xe0000000 0x1000>; + }; }; }; }; diff --git a/dts/arm/nxp/nxp_mcxa344.dtsi b/dts/arm/nxp/nxp_mcxa344.dtsi new file mode 100644 index 0000000000000..e7376d9bbcc16 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxa344.dtsi @@ -0,0 +1,477 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "nxp,port-pinctrl"; + status = "okay"; + }; + + cmc { + compatible = "nxp,cmc-reset-cause"; + }; + + soc { + syscon: syscon@40091000 { + compatible = "nxp,lpc-syscon"; + reg = <0x40091000 0x4000>; + #clock-cells = <1>; + reset: reset { + compatible = "nxp,lpc-syscon-reset"; + #reset-cells = <1>; + }; + }; + + sramx: memory@4000000 { + compatible = "mmio-sram"; + reg = <0x4000000 DT_SIZE_K(16)>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(48)>; + }; + + porta: pinmux@400bc000 { + compatible = "nxp,port-pinmux"; + reg = <0x400bc000 0x1000>; + clocks = <&syscon MCUX_PORT0_CLK>; + }; + + portb: pinmux@400bd000 { + compatible = "nxp,port-pinmux"; + reg = <0x400bd000 0x1000>; + clocks = <&syscon MCUX_PORT1_CLK>; + }; + + portc: pinmux@400be000 { + compatible = "nxp,port-pinmux"; + reg = <0x400be000 0x1000>; + clocks = <&syscon MCUX_PORT2_CLK>; + }; + + portd: pinmux@400bf000 { + compatible = "nxp,port-pinmux"; + reg = <0x400bf000 0x1000>; + clocks = <&syscon MCUX_PORT3_CLK>; + }; + + porte: pinmux@400c0000 { + compatible = "nxp,port-pinmux"; + reg = <0x400c0000 0x1000>; + clocks = <&syscon MCUX_PORT4_CLK>; + }; + + gpio0: gpio@40102000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x40102000 0x1000>; + interrupts = <71 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porta>; + }; + + gpio1: gpio@40103000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x40103000 0x1000>; + interrupts = <72 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portb>; + }; + + gpio2: gpio@40104000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x40104000 0x1000>; + interrupts = <73 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portc>; + }; + + gpio3: gpio@40105000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x40105000 0x1000>; + interrupts = <74 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portd>; + }; + + gpio4: gpio@40106000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x40106000 0x1000>; + interrupts = <75 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porte>; + }; + + lpuart0: lpuart@4009f000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0x4009f000 0x1000>; + interrupts = <31 0>; + clocks = <&syscon MCUX_LPUART0_CLK>; + /* DMA channels 0 and 1, muxed to LPUART0 RX and TX */ + dmas = <&edma0 0 21>, <&edma0 1 22>; + dma-names = "rx", "tx"; + }; + + lpuart1: lpuart@400a0000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0x400a0000 0x1000>; + interrupts = <32 0>; + clocks = <&syscon MCUX_LPUART1_CLK>; + /* DMA channels 2 and 3, muxed to LPUART1 RX and TX */ + dmas = <&edma0 2 23>, <&edma0 3 24>; + dma-names = "rx", "tx"; + }; + + lpuart2: lpuart@400a1000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0x400a1000 0x1000>; + interrupts = <33 0>; + clocks = <&syscon MCUX_LPUART2_CLK>; + /* DMA channels 4 and 5, muxed to LPUART2 RX and TX */ + dmas = <&edma0 4 25>, <&edma0 5 26>; + dma-names = "rx", "tx"; + }; + + lpuart3: lpuart@400a2000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0x400a2000 0x1000>; + interrupts = <34 0>; + clocks = <&syscon MCUX_LPUART3_CLK>; + /* DMA channels 6 and 7, muxed to LPUART3 RX and TX */ + dmas = <&edma0 6 27>, <&edma0 7 28>; + dma-names = "rx", "tx"; + }; + + fmu: flash-controller@40095000 { + compatible = "nxp,msf1"; + reg = <0x40095000 0x1000>; + interrupts = <12 0>; + + #address-cells = <1>; + #size-cells = <1>; + + flash: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(256)>; + erase-block-size = <8192>; + write-block-size = <128>; + }; + + uuid: uuid@1100800 { + compatible = "nxp,lpc-uid"; + reg = <0x1100800 0x10>; + }; + }; + + ctimer0: ctimer@40004000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40004000 0x1000>; + interrupts = <39 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER0_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer1: ctimer@40005000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40005000 0x1000>; + interrupts = <40 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER1_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer2: ctimer@40006000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40006000 0x1000>; + interrupts = <41 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER2_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + edma0: dma-controller@40080000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <8>; + dma-requests = <86>; + + reg = <0x40080000 0x1000>; + interrupts = <2 0>, <3 0>, <4 0>, <5 0>, + <6 0>, <7 0>, <8 0>, <9 0>; + no-error-irq; + status = "disabled"; + }; + + flexcan0: can@400cc000 { + compatible = "nxp,flexcan"; + reg = <0x400cc000 0x1000>; + interrupts = <19 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN0_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexpwm0: flexpwm@400a9000 { + compatible = "nxp,flexpwm"; + reg = <0x400a9000 0x1000>; + interrupt-names = "RELOAD-ERROR", "FAULT"; + interrupts = <44 0>, <45 0>; + flexpwm0_pwm0: pwm0 { + compatible = "nxp,imx-pwm"; + index = <0>; + interrupts = <46 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + + flexpwm0_pwm1: pwm1 { + compatible = "nxp,imx-pwm"; + index = <1>; + interrupts = <47 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + + flexpwm0_pwm2: pwm2 { + compatible = "nxp,imx-pwm"; + index = <2>; + interrupts = <48 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + }; + + flexpwm1: flexpwm@400aa000 { + compatible = "nxp,flexpwm"; + reg = <0x400aa000 0x1000>; + interrupt-names = "RELOAD-ERROR", "FAULT"; + interrupts = <79 0>, <80 0>; + flexpwm1_pwm0: pwm0 { + compatible = "nxp,imx-pwm"; + index = <0>; + interrupts = <81 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + + flexpwm1_pwm1: pwm1 { + compatible = "nxp,imx-pwm"; + index = <1>; + interrupts = <82 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + + flexpwm1_pwm2: pwm2 { + compatible = "nxp,imx-pwm"; + index = <2>; + interrupts = <83 0>; + #pwm-cells = <3>; + clocks = <&syscon MCUX_BUS_CLK>; + nxp,prescaler = <128>; + status = "disabled"; + run-in-wait; + }; + }; + + lpadc0: lpadc@400af000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x400af000 0x1000>; + interrupts = <62 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <2>; + calibration-average = <128>; + power-level = <0>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC1_CLK>; + }; + + lpadc1: lpadc@400b0000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x400b0000 0x1000>; + interrupts = <63 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <2>; + calibration-average = <128>; + power-level = <1>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC2_CLK>; + }; + + lpcmp0: lpcmp@400b1000 { + compatible = "nxp,lpcmp"; + reg = <0x400b1000 0x1000>; + interrupts = <64 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + lpcmp1: lpcmp@400b2000 { + compatible = "nxp,lpcmp"; + reg = <0x400b2000 0x1000>; + interrupts = <65 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + lpcmp2: lpcmp@400b3000 { + compatible = "nxp,lpcmp"; + reg = <0x400b3000 0x1000>; + interrupts = <66 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + lpi2c0: i2c@4009a000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4009a000 0x1000>; + interrupts = <26 0>; + clocks = <&syscon MCUX_LPI2C0_CLK>; + status = "disabled"; + }; + + lpi2c1: i2c@4009b000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4009b000 0x1000>; + interrupts = <27 0>; + clocks = <&syscon MCUX_LPI2C1_CLK>; + status = "disabled"; + }; + + lpspi0: spi@4009c000 { + compatible = "nxp,lpspi"; + reg = <0x4009c000 0x1000>; + interrupts = <28 0>; + clocks = <&syscon MCUX_LPSPI0_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi1: spi@4009d000 { + compatible = "nxp,lpspi"; + reg = <0x4009d000 0x1000>; + interrupts = <29 0>; + clocks = <&syscon MCUX_LPSPI1_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lptmr0: lptmr@400ab000 { + compatible = "nxp,lptmr"; + reg = <0x400ab000 0x1000>; + interrupts = <55 0>; + clock-frequency = <16000>; + prescale-glitch-filter = <0>; + clk-source = <1>; + resolution = <32>; + status = "disabled"; + }; + + ostimer0: timers@400ad000 { + compatible = "nxp,os-timer"; + reg = <0x400ad000 0x1000>; + interrupts = <57 0>; + status = "disabled"; + }; + + temp0: temp0 { + compatible = "nxp,lpadc-temp40"; + status = "disabled"; + }; + + wwdt0: watchdog@4000c000 { + compatible = "nxp,lpc-wwdt"; + reg = <0x4000c000 0x1000>; + interrupts = <60 0>; + status = "disabled"; + clk-divider = <1>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/nxp/nxp_mcxe245.dtsi b/dts/arm/nxp/nxp_mcxe245.dtsi new file mode 100644 index 0000000000000..d17ea02eba7ce --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe245.dtsi @@ -0,0 +1,57 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* + * SRAM_L and SRAM_U form a continuous block in memory map, + * but misaligned accesses across the 0x20000000 boundary + * are not supported. Therefore two separate memory nodes + * are created. + */ + sram_l: sram@1fff8000 { + compatible = "mmio-sram"; + reg = <0x1fff8000 DT_SIZE_K(32)>; + }; + + sram_u: sram@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(28)>; + zephyr,memory-region = "SRAMU"; + }; +}; + +&ftfc { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(512)>; + erase-block-size = ; + write-block-size = <8>; + }; +}; + +&flexcan1 { + compatible = "nxp,flexcan"; + interrupts = <85 0>, <86 0>, <88 0>; + interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; +}; + +&flexcan2 { + compatible = "nxp,flexcan"; + interrupts = <92 0>, <93 0>, <95 0>; + interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; +}; + +/delete-node/ &ftm4; +/delete-node/ &ftm5; +/delete-node/ &ftm6; +/delete-node/ &ftm7; +/delete-node/ &enet; +/delete-node/ &lpi2c1; +/delete-node/ &sai0; +/delete-node/ &sai1; diff --git a/dts/arm/nxp/nxp_mcxe246.dtsi b/dts/arm/nxp/nxp_mcxe246.dtsi new file mode 100644 index 0000000000000..342e5384a89fd --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe246.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* + * SRAM_L and SRAM_U form a continuous block in memory map, + * but misaligned accesses across the 0x20000000 boundary + * are not supported. Therefore two separate memory nodes + * are created. + */ + sram_l: sram@1fff0000 { + compatible = "mmio-sram"; + reg = <0x1fff0000 DT_SIZE_K(64)>; + }; + + sram_u: sram@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(60)>; + zephyr,memory-region = "SRAMU"; + }; +}; + +&ftfc { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_M(1)>; + erase-block-size = ; + write-block-size = <8>; + }; +}; + +&flexcan2 { + compatible = "nxp,flexcan"; + interrupts = <92 0>, <93 0>, <95 0>; + interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; +}; + +/delete-node/ &ftm4; +/delete-node/ &ftm5; +/delete-node/ &enet; +/delete-node/ &lpi2c1; +/delete-node/ &sai0; +/delete-node/ &sai1; diff --git a/dts/arm/nxp/nxp_mcxe247.dtsi b/dts/arm/nxp/nxp_mcxe247.dtsi new file mode 100644 index 0000000000000..fbeb9a5f69734 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe247.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* + * SRAM_L and SRAM_U form a continuous block in memory map, + * but misaligned accesses across the 0x20000000 boundary + * are not supported. Therefore two separate memory nodes + * are created. + */ + sram_l: sram@1ffe0000 { + compatible = "mmio-sram"; + reg = <0x1ffe0000 DT_SIZE_K(128)>; + }; + + sram_u: sram@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(124)>; + zephyr,memory-region = "SRAMU"; + }; +}; + +&ftfc { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(1536)>; + erase-block-size = ; + write-block-size = <8>; + }; +}; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi new file mode 100644 index 0000000000000..3fa43feb3c76d --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -0,0 +1,629 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + aliases { + watchdog0 = &wdog; + }; + + chosen { + zephyr,flash-controller = &ftfc; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4f"; + reg = <0>; + }; + }; + + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "nxp,port-pinctrl"; + status = "okay"; + }; + + soc { + scg: scg@40064000 { + compatible = "nxp,kinetis-scg"; + sosc-mode = ; + reg = <0x40064000 0x1000>; + #clock-cells = <1>; + + sosc_clk: sosc_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + status = "disabled"; + }; + + pll: pll { + compatible = "fixed-factor-clock"; + clocks = <&sosc_clk>; + clock-div = <1>; + clock-mult = <40>; + #clock-cells = <0>; + }; + + spll_clk: spll_clk { + compatible = "fixed-factor-clock"; + clocks = <&pll>; + clock-div = <2>; + #clock-cells = <0>; + status = "disabled"; + }; + + sirc_clk: sirc_clk { + compatible = "fixed-clock"; + clock-frequency = <8000000>; + #clock-cells = <0>; + }; + + firc_clk: firc_clk { + compatible = "fixed-clock"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + core_clk: core_clk { + compatible = "fixed-factor-clock"; + clocks = <&firc_clk>; + clock-div = <1>; + #clock-cells = <0>; + }; + + bus_clk: bus_clk { + compatible = "fixed-factor-clock"; + clocks = <&core_clk>; + clock-div = <1>; + #clock-cells = <0>; + }; + + slow_clk: slow_clk { + compatible = "fixed-factor-clock"; + clocks = <&core_clk>; + clock-div = <2>; + #clock-cells = <0>; + }; + + splldiv1_clk: splldiv1_clk { + compatible = "fixed-factor-clock"; + clocks = <&spll_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + splldiv2_clk: splldiv2_clk { + compatible = "fixed-factor-clock"; + clocks = <&spll_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + soscdiv1_clk: soscdiv1_clk { + compatible = "fixed-factor-clock"; + clocks = <&sosc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + soscdiv2_clk: soscdiv2_clk { + compatible = "fixed-factor-clock"; + clocks = <&sosc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + sircdiv1_clk: sircdiv1_clk { + compatible = "fixed-factor-clock"; + clocks = <&sirc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + sircdiv2_clk: sircdiv2_clk { + compatible = "fixed-factor-clock"; + clocks = <&sirc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + fircdiv1_clk: fircdiv1_clk { + compatible = "fixed-factor-clock"; + clocks = <&firc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + fircdiv2_clk: fircdiv2_clk { + compatible = "fixed-factor-clock"; + clocks = <&firc_clk>; + clock-div = <0>; + #clock-cells = <0>; + }; + + }; + + pcc: pcc@40065000 { + compatible = "nxp,kinetis-pcc"; + reg = <0x40065000 0x1000>; + #clock-cells = <2>; + }; + + ftfc: flash-controller@40020000 { + compatible = "nxp,kinetis-ftfc"; + reg = <0x40020000 0x1000>; + interrupts = <18 0>, <19 0>, <21 0>; + interrupt-names = "command-complete", "read-collision", "double-bit"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + + edma: dma-controller@40008000 { + compatible = "nxp,mcux-edma"; + nxp,version = <2>; + dma-channels = <16>; + dma-requests = <64>; + nxp,mem2mem; + reg = <0x40008000 0x1000>, <0x40021000 0x1000>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>, <6 0>, <7 0>, + <8 0>, <9 0>, <10 0>, <11 0>, + <12 0>, <13 0>, <14 0>, <15 0>, + <16 0>; + #dma-cells = <2>; + status = "disabled"; + }; + + adc0: adc@4003b000 { + compatible = "nxp,adc12"; + reg = <0x4003b000 0x1000>; + interrupts = <39 0>; + clocks = <&pcc 0xec KINETIS_PCC_SRC_FIRC_ASYNC>; + clk-source = <0>; + clk-divider = <1>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc1: adc@40027000 { + compatible = "nxp,adc12"; + reg = <0x40027000 0x1000>; + interrupts = <40 0>; + clocks = <&pcc 0x9c KINETIS_PCC_SRC_FIRC_ASYNC>; + clk-source = <0>; + clk-divider = <1>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + cmp0: cmp@40073000 { + compatible = "nxp,kinetis-acmp"; + reg = <0x40073000 0x1000>; + interrupts = <41 0>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + status = "disabled"; + }; + + enet: ethernet@40079000 { + compatible = "nxp,enet"; + reg = <0x40079000 0x620>; + clocks = <&core_clk>; + enet_mac: ethernet { + compatible = "nxp,enet-mac"; + interrupts = <73 0>, <74 0>, <75 0>; + interrupt-names = "TX", "RX", "ERR"; + nxp,mdio = <&enet_mdio>; + ptp-clock = <&enet_ptp_clock>; + phy-connection-type = "rmii"; + status = "disabled"; + }; + enet_mdio: mdio { + compatible = "nxp,enet-mdio"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + enet_ptp_clock: ptp_clock { + compatible = "nxp,enet-ptp-clock"; + interrupts = <72 0>; + interrupt-names = "IEEE1588_TMR"; + clocks = <&pcc 0x1e4 KINETIS_PCC_SRC_SPLL_ASYNC>; + status = "disabled"; + }; + }; + + ewm0: ewm@40061000 { + compatible = "nxp,ewm"; + reg = <0x40061000 0x6>; + interrupts = <22 0>; + clk-divider = <0x0>; + status = "disabled"; + }; + + flexcan0: can@40024000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40024000 0x1000>; + 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>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan1: can@40025000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + 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>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan2: can@4002b000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + 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>; + clk-source = <0>; + status = "disabled"; + }; + + flexio0: flexio@4005a000 { + compatible = "nxp,flexio"; + reg = <0x4005a000 0x1000>; + interrupts = <69 0>; + clocks = <&pcc 0x168 KINETIS_PCC_SRC_FIRC_ASYNC>; + status = "disabled"; + }; + + ftm0: ftm@40038000 { + compatible = "nxp,ftm"; + reg = <0x40038000 0x1000>; + interrupts = <99 0>, <100 0>, <101 0>, <102 0>, <104 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0xe0 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm1: ftm@40039000 { + compatible = "nxp,ftm"; + reg = <0x40039000 0x1000>; + interrupts = <105 0>, <106 0>, <107 0>, <108 0>, <110 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0xe4 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm2: ftm@4003a000 { + compatible = "nxp,ftm"; + reg = <0x4003a000 0x1000>; + interrupts = <111 0>, <112 0>, <113 0>, <114 0>, <116 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0xe8 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm3: ftm@40026000 { + compatible = "nxp,ftm"; + reg = <0x40026000 0x1000>; + interrupts = <117 0>, <118 0>, <119 0>, <120 0>, <122 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0x98 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm4: ftm@4006e000 { + compatible = "nxp,ftm"; + reg = <0x4006e000 0x1000>; + interrupts = <123 0>, <124 0>, <125 0>, <126 0>, <128 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0x1b8 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm5: ftm@4006f000 { + compatible = "nxp,ftm"; + reg = <0x4006f000 0x1000>; + interrupts = <129 0>, <130 0>, <131 0>, <132 0>, <134 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0x1bc KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm6: ftm@40070000 { + compatible = "nxp,ftm"; + reg = <0x40070000 0x1000>; + interrupts = <135 0>, <136 0>, <137 0>, <138 0>, <140 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0x1c0 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + ftm7: ftm@40071000 { + compatible = "nxp,ftm"; + reg = <0x40071000 0x1000>; + interrupts = <141 0>, <142 0>, <143 0>, <144 0>, <146 0>; + interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; + clocks = <&pcc 0x1c4 KINETIS_PCC_SRC_FIRC_ASYNC>; + prescaler = <1>; + status = "disabled"; + }; + + gpioa: gpio@400ff000 { + compatible = "nxp,kinetis-gpio"; + reg = <0x400ff000 0x40>; + interrupts = <59 2>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porta>; + status = "disabled"; + }; + + gpiob: gpio@400ff040 { + compatible = "nxp,kinetis-gpio"; + reg = <0x400ff040 0x40>; + interrupts = <60 2>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portb>; + status = "disabled"; + }; + + gpioc: gpio@400ff080 { + compatible = "nxp,kinetis-gpio"; + reg = <0x400ff080 0x40>; + interrupts = <61 2>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portc>; + status = "disabled"; + }; + + gpiod: gpio@400ff0c0 { + compatible = "nxp,kinetis-gpio"; + reg = <0x400ff0c0 0x40>; + interrupts = <62 2>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portd>; + status = "disabled"; + }; + + gpioe: gpio@400ff100 { + compatible = "nxp,kinetis-gpio"; + reg = <0x400ff100 0x40>; + interrupts = <63 2>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porte>; + status = "disabled"; + }; + + lpi2c0: i2c@40066000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40066000 0x1000>; + interrupts = <24 0>, <25 0>; + interrupt-names = "controller", "target"; + clocks = <&pcc 0x198 KINETIS_PCC_SRC_FIRC_ASYNC>; + status = "disabled"; + }; + + lpi2c1: i2c@40067000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40067000 0x1000>; + interrupts = <29 0>, <30 0>; + interrupt-names = "controller", "target"; + clocks = <&pcc 0x19c KINETIS_PCC_SRC_FIRC_ASYNC>; + status = "disabled"; + }; + + lpspi0: spi@4002c000 { + compatible = "nxp,lpspi"; + reg = <0x4002c000 0x1000>; + interrupts = <26 0>; + clocks = <&pcc 0xb0 KINETIS_PCC_SRC_FIRC_ASYNC>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + status = "disabled"; + }; + + lpspi1: spi@4002d000 { + compatible = "nxp,lpspi"; + reg = <0x4002d000 0x1000>; + interrupts = <27 0>; + clocks = <&pcc 0xb4 KINETIS_PCC_SRC_FIRC_ASYNC>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + status = "disabled"; + }; + + lpspi2: spi@4002e000 { + compatible = "nxp,lpspi"; + reg = <0x4002e000 0x1000>; + interrupts = <28 0>; + clocks = <&pcc 0xb8 KINETIS_PCC_SRC_FIRC_ASYNC>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + status = "disabled"; + }; + + lptmr0: lptmr@40040000 { + compatible = "nxp,lptmr"; + reg = <0x40040000 0x1000>; + interrupts = <58 0>; + clock-frequency = <1000>; + prescale-glitch-filter = <0>; + clk-source = <1>; + resolution = <16>; + status = "disabled"; + }; + + lpuart0: uart@4006a000 { + compatible = "nxp,lpuart"; + reg = <0x4006a000 0x1000>; + interrupts = <31 0>; + clocks = <&pcc 0x1a8 KINETIS_PCC_SRC_FIRC_ASYNC>; + dmas = <&edma 0 2>, <&edma 1 3>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + lpuart1: uart@4006b000 { + compatible = "nxp,lpuart"; + reg = <0x4006b000 0x1000>; + interrupts = <33 0>; + clocks = <&pcc 0x1ac KINETIS_PCC_SRC_FIRC_ASYNC>; + dmas = <&edma 2 4>, <&edma 3 5>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + lpuart2: uart@4006c000 { + compatible = "nxp,lpuart"; + reg = <0x4006c000 0x1000>; + interrupts = <35 0>; + clocks = <&pcc 0x1b0 KINETIS_PCC_SRC_FIRC_ASYNC>; + dmas = <&edma 4 6>, <&edma 5 7>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + mpu: mpu@4000d000 { + compatible = "nxp,sysmpu"; + reg = <0x4000d000 0x1000>; + status = "disabled"; + }; + + pmc: pmc@4007d000 { + reg = <0x4007d000 0x1000>; + + lpo: lpo128k { + compatible = "fixed-clock"; + clock-frequency = <128000>; + #clock-cells = <0>; + }; + }; + + porta: pinmux@40049000 { + compatible = "nxp,port-pinmux"; + reg = <0x40049000 0x1000>; + clocks = <&pcc 0x124 KINETIS_PCC_SRC_NONE_OR_EXT>; + }; + + portb: pinmux@4004a000 { + compatible = "nxp,port-pinmux"; + reg = <0x4004a000 0x1000>; + clocks = <&pcc 0x128 KINETIS_PCC_SRC_NONE_OR_EXT>; + }; + + portc: pinmux@4004b000 { + compatible = "nxp,port-pinmux"; + reg = <0x4004b000 0x1000>; + clocks = <&pcc 0x12c KINETIS_PCC_SRC_NONE_OR_EXT>; + }; + + portd: pinmux@4004c000 { + compatible = "nxp,port-pinmux"; + reg = <0x4004c000 0x1000>; + clocks = <&pcc 0x130 KINETIS_PCC_SRC_NONE_OR_EXT>; + }; + + porte: pinmux@4004d000 { + compatible = "nxp,port-pinmux"; + reg = <0x4004d000 0x1000>; + clocks = <&pcc 0x134 KINETIS_PCC_SRC_NONE_OR_EXT>; + }; + + rtc: rtc@4003d000 { + compatible = "nxp,rtc"; + reg = <0x4003d000 0x1000>; + interrupts = <46 0>, <47 0>; + interrupt-names = "alarm", "seconds"; + clock-source = "LPO"; + clock-frequency = <1000>; + prescaler = <1000>; + status = "disabled"; + }; + + sai0: sai@40054000 { + compatible = "nxp,mcux-i2s"; + reg = < 0x40054000 0x1000>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + interrupts = <70 0>, <71 0>; + dmas = <&edma 6 60>, <&edma 7 61>; + dma-names = "rx", "tx"; + nxp,rx-dma-channel = <6>; + nxp,tx-dma-channel = <7>; + #address-cells = <1>; + #size-cells = <0>; + #pinmux-cells = <2>; + status = "disabled"; + }; + + sai1: sai@40055000 { + compatible = "nxp,mcux-i2s"; + reg = < 0x40055000 0x1000>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + interrupts = <55 0>, <56 0>; + dmas = <&edma 8 12>, <&edma 9 13>; + dma-names = "rx", "tx"; + nxp,rx-dma-channel = <8>; + nxp,tx-dma-channel = <9>; + #address-cells = <1>; + #size-cells = <0>; + #pinmux-cells = <2>; + status = "disabled"; + }; + + wdog: watchdog@40052000 { + compatible = "nxp,wdog32"; + reg = <0x40052000 0x1000>; + interrupts = <22 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <256>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/nxp/nxp_mcxe31b.dtsi b/dts/arm/nxp/nxp_mcxe31b.dtsi new file mode 100644 index 0000000000000..ba7fec4f3b4d0 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe31b.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + itcm: memory@0 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x0 DT_SIZE_K(32)>; + zephyr,memory-region = "ITCM"; + }; + + itcm1: memory@11400000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x11400000 DT_SIZE_K(32)>; + zephyr,memory-region = "ITCM1"; + }; + + dtcm: memory@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(64)>; + zephyr,memory-region = "DTCM"; + }; + + /* stdby_ram memory supports content retention in Standby mode */ + stdby_ram: memory@20400000 { + compatible = "mmio-sram"; + reg = <0x20400000 DT_SIZE_K(32)>; + }; + + /* sram memory is available only in Run mode */ + sram: memory@20408000 { + compatible = "mmio-sram"; + reg = <0x20408000 DT_SIZE_K(288)>; + }; + + dtcm1: memory@21400000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21400000 DT_SIZE_K(64)>; + zephyr,memory-region = "DTCM1"; + }; + + peripheral: peripheral@40000000 { + ranges = <0x0 0x40000000 0x10000000>; + }; + }; +}; + +#include diff --git a/dts/arm/nxp/nxp_mcxe31x_common.dtsi b/dts/arm/nxp/nxp_mcxe31x_common.dtsi new file mode 100644 index 0000000000000..9dfd5ef039a31 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxe31x_common.dtsi @@ -0,0 +1,1062 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <0x1>; + #size-cells = <0>; + + core0: cpu@0 { + reg = <0>; + device_type = "cpu"; + compatible = "arm,cortex-m7"; + }; + }; + + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "nxp,mcxe31x-siul2-pinctrl"; + status = "okay"; + }; +}; + +&peripheral { + #address-cells = <1>; + #size-cells = <1>; + + adc_0: adc@a0000 { + compatible = "nxp,adc"; + reg = <0xa0000 0x3d4>; + interrupts = <180 0>; + status = "disabled"; + }; + + adc_1: adc@a4000 { + compatible = "nxp,adc"; + reg = <0xa4000 0x3d4>; + interrupts = <181 0>; + status = "disabled"; + }; + + adc_2: adc@a8000 { + compatible = "nxp,adc"; + reg = <0xa8000 0x3d4>; + interrupts = <182 0>; + status = "disabled"; + }; + + axbs_lite: axbs@200000 { + compatible = "nxp,axbs"; + reg = <0x200000 0x630>; + status = "disabled"; + }; + + bctu: bctu@84000 { + compatible = "nxp,bctu"; + reg = <0x84000 0x490>; + status = "disabled"; + }; + + cmu_0: cmu-fc@2bc000 { + compatible = "nxp,cmu-fc"; + reg = <0x2bc000 0x34>; + status = "disabled"; + }; + + cmu_1: cmu-fm@2bc020 { + compatible = "nxp,cmu-fm"; + reg = <0x2bc020 0x2c>; + status = "disabled"; + }; + + cmu_2: cmu-fm@2bc040 { + compatible = "nxp,cmu-fm"; + reg = <0x2bc040 0x2c>; + status = "disabled"; + }; + + cmu_3: cmu-fc@2bc060 { + compatible = "nxp,cmu-fc"; + reg = <0x2bc060 0x34>; + status = "disabled"; + }; + + cmu_4: cmu-fc@2bc080 { + compatible = "nxp,cmu-fc"; + reg = <0x2bc080 0x34>; + status = "disabled"; + }; + + cmu_5: cmu-fc@2bc0a0 { + compatible = "nxp,cmu-fc"; + reg = <0x2bc0a0 0x34>; + status = "disabled"; + }; + + configuration: configuration@39c000 { + compatible = "nxp,configuration"; + reg = <0x39c000 0x84>; + status = "disabled"; + }; + + crc: crc@380000 { + compatible = "nxp,crc"; + reg = <0x380000 0x28>; + }; + + dcm: dcm@2ac000 { + compatible = "nxp,dcm"; + reg = <0x2ac000 0xa0>; + status = "disabled"; + }; + + dcm_gpr: dcm-gpr@2ac200 { + compatible = "nxp,dcm-gpr"; + reg = <0x2ac200 0x510>; + status = "disabled"; + }; + + dmamux_0: dmamux@280000 { + compatible = "nxp,dmamux"; + reg = <0x280000 0x17>; + status = "disabled"; + }; + + dmamux_1: dmamux@284000 { + compatible = "nxp,dmamux"; + reg = <0x284000 0x17>; + status = "disabled"; + }; + + edma: edma@20c000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + reg = <0x20c000 0x19c>; + dma-channels = <32>; + dma-requests = <128>; + 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>, + <16 0>, <17 0>, <18 0>, <19 0>, + <20 0>, <21 0>, <22 0>, <23 0>, + <24 0>, <25 0>, <26 0>, <27 0>, + <28 0>, <29 0>, <30 0>, <31 0>, + <32 0>, <33 0>, <34 0>, <35 0>; + status = "disabled"; + }; + + eim: eim@258000 { + compatible = "nxp,eim"; + reg = <0x258000 0x8a4>; + status = "disabled"; + }; + + emac: emac@480000 { + compatible = "nxp,emac"; + reg = <0x480000 0x120c>; + interrupts = <105 0>; + status = "disabled"; + }; + + emios_0: emios@88000 { + compatible = "nxp,emios"; + reg = <0x88000 0x338>; + interrupts = <61 0>, <62 0>, <63 0>, <64 0>, + <65 0>, <66 0>; + interrupt-names = "emios0-2", "emios0-3", "emios0-4", + "emios0-5", "emios0-6", "emios0-7"; + status = "disabled"; + }; + + emios_1: emios@8c000 { + compatible = "nxp,emios"; + reg = <0x8c000 0x338>; + status = "disabled"; + }; + + emios_2: emios@90000 { + compatible = "nxp,emios"; + reg = <0x90000 0x338>; + status = "disabled"; + }; + + erm: erm@25c000 { + compatible = "nxp,erm"; + reg = <0x25c000 0x258>; + interrupts = <36 0>, <37 0>; + interrupt-names = "erm-0", "erm-1"; + status = "disabled"; + }; + + fccu: fccu@384000 { + compatible = "nxp,fccu"; + reg = <0x384000 0x158>; + status = "disabled"; + }; + + firc: firc@2d0000 { + compatible = "nxp,firc"; + reg = <0x2d0000 0x28>; + status = "disabled"; + }; + + flash: flash-c40@2ec000 { + compatible = "nxp,pflash"; + reg = <0x2ec000 0x19c>; + interrupts = <48 0>, <49 0>, <50 0>; + interrupt-names = "flash-0", "flash-1", "flash-2"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + program_flash: memory@400000 { + compatible = "soc-nv-flash"; + reg = <0x400000 DT_SIZE_K(4096)>; + }; + }; + + flexcan_0: flexcan@304000 { + compatible = "nxp,flexcan"; + reg = <0x304000 0x321c>; + 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"; + }; + + flexcan_1: flexcan@308000 { + compatible = "nxp,flexcan"; + reg = <0x308000 0xd4c>; + 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"; + }; + + flexcan_2: flexcan@30c000 { + compatible = "nxp,flexcan"; + reg = <0x30c000 0xd4c>; + 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"; + }; + + flexcan_3: flexcan@310000 { + compatible = "nxp,flexcan"; + reg = <0x310000 0xccc>; + interrupts = <119 0>, <120 0>; + interrupt-names = "flexcan3-0", "flexcan3-1"; + clocks = <&mc_cgm MCUX_FLEXCAN3_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan_4: flexcan@314000 { + compatible = "nxp,flexcan"; + reg = <0x314000 0xccc>; + interrupts = <121 0>, <122 0>; + interrupt-names = "flexcan4-0", "flexcan4-1"; + clocks = <&mc_cgm MCUX_FLEXCAN4_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan_5: flexcan@318000 { + compatible = "nxp,flexcan"; + reg = <0x318000 0xccc>; + interrupts = <123 0>, <124 0>; + interrupt-names = "flexcan5-0", "flexcan5-1"; + clocks = <&mc_cgm MCUX_FLEXCAN5_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexio: flexio@324000 { + compatible = "nxp,flexio"; + reg = <0x324000 0x93c>; + interrupts = <139 0>; + clocks = <&mc_cgm MCUX_FLEXIO_CLK>; + status = "disabled"; + }; + + fxosc: fxosc@2d4000 { + compatible = "nxp,fxosc"; + reg = <0x2d4000 0x24>; + status = "disabled"; + }; + + intm: intm@27c000 { + compatible = "nxp,intm"; + reg = <0x27c000 0x64>; + status = "disabled"; + }; + + jdc: jdc@394000 { + compatible = "nxp,jdc"; + reg = <0x394000 0x2c>; + status = "disabled"; + }; + + lcu_0: lcu@98000 { + compatible = "nxp,lcu"; + reg = <0x98000 0x2c8>; + interrupts = <92 0>; + status = "disabled"; + }; + + lcu_1: lcu@9c000 { + compatible = "nxp,lcu"; + reg = <0x9c000 0x2c8>; + interrupts = <93 0>; + status = "disabled"; + }; + + lpcmp_0: lpcmp@370000 { + compatible = "nxp,lpcmp"; + reg = <0x370000 0x50>; + interrupts = <183 0>; + status = "disabled"; + }; + + lpcmp_1: lpcmp@374000 { + compatible = "nxp,lpcmp"; + reg = <0x374000 0x50>; + interrupts = <184 0>; + status = "disabled"; + }; + + lpcmp_2: lpcmp@4e8000 { + compatible = "nxp,lpcmp"; + reg = <0x4e8000 0x50>; + interrupts = <185 0>; + status = "disabled"; + }; + + lpi2c_0: lpi2c@350000 { + compatible = "nxp,lpi2c"; + reg = <0x350000 0x190>; + interrupts = <161 0>; + clocks = <&mc_cgm MCUX_LPI2C0_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpi2c_1: lpi2c@354000 { + compatible = "nxp,lpi2c"; + reg = <0x354000 0x190>; + interrupts = <162 0>; + clocks = <&mc_cgm MCUX_LPI2C1_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_0: lpspi@358000 { + compatible = "nxp,lpspi"; + reg = <0x358000 0x81c>; + interrupts = <165 0>; + clocks = <&mc_cgm MCUX_LPSPI0_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_1: lpspi@35c000 { + compatible = "nxp,lpspi"; + reg = <0x35c000 0x81c>; + interrupts = <166 0>; + clocks = <&mc_cgm MCUX_LPSPI1_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_2: lpspi@360000 { + compatible = "nxp,lpspi"; + reg = <0x360000 0x81c>; + interrupts = <167 0>; + clocks = <&mc_cgm MCUX_LPSPI2_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_3: lpspi@364000 { + compatible = "nxp,lpspi"; + reg = <0x364000 0x81c>; + interrupts = <168 0>; + clocks = <&mc_cgm MCUX_LPSPI3_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_4: lpspi@4bc000 { + compatible = "nxp,lpspi"; + reg = <0x4bc000 0x81c>; + interrupts = <169 0>; + clocks = <&mc_cgm MCUX_LPSPI4_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi_5: lpspi@4c0000 { + compatible = "nxp,lpspi"; + reg = <0x4c0000 0x81c>; + interrupts = <170 0>; + clocks = <&mc_cgm MCUX_LPSPI5_CLK>; + rx-fifo-size = <4>; + tx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpuart_0: lpuart@328000 { + compatible = "nxp,lpuart"; + reg = <0x328000 0x50>; + interrupts = <141 0>; + clocks = <&mc_cgm MCUX_LPUART0_CLK>; + status = "disabled"; + }; + + lpuart_1: lpuart@32c000 { + compatible = "nxp,lpuart"; + reg = <0x32c000 0x50>; + interrupts = <142 0>; + clocks = <&mc_cgm MCUX_LPUART1_CLK>; + status = "disabled"; + }; + + lpuart_2: lpuart@330000 { + compatible = "nxp,lpuart"; + reg = <0x330000 0x50>; + interrupts = <143 0>; + clocks = <&mc_cgm MCUX_LPUART2_CLK>; + status = "disabled"; + }; + + lpuart_3: lpuart@334000 { + compatible = "nxp,lpuart"; + reg = <0x334000 0x50>; + interrupts = <144 0>; + clocks = <&mc_cgm MCUX_LPUART3_CLK>; + status = "disabled"; + }; + + lpuart_4: lpuart@338000 { + compatible = "nxp,lpuart"; + reg = <0x338000 0x50>; + interrupts = <145 0>; + clocks = <&mc_cgm MCUX_LPUART4_CLK>; + status = "disabled"; + }; + + lpuart_5: lpuart@33c000 { + compatible = "nxp,lpuart"; + reg = <0x33c000 0x50>; + interrupts = <146 0>; + clocks = <&mc_cgm MCUX_LPUART5_CLK>; + status = "disabled"; + }; + + lpuart_6: lpuart@340000 { + compatible = "nxp,lpuart"; + reg = <0x340000 0x50>; + interrupts = <147 0>; + clocks = <&mc_cgm MCUX_LPUART6_CLK>; + status = "disabled"; + }; + + lpuart_7: lpuart@344000 { + compatible = "nxp,lpuart"; + reg = <0x344000 0x50>; + interrupts = <148 0>; + clocks = <&mc_cgm MCUX_LPUART7_CLK>; + status = "disabled"; + }; + + lpuart_8: lpuart@48c000 { + compatible = "nxp,lpuart"; + reg = <0x48c000 0x50>; + interrupts = <149 0>; + clocks = <&mc_cgm MCUX_LPUART8_CLK>; + status = "disabled"; + }; + + lpuart_9: lpuart@490000 { + compatible = "nxp,lpuart"; + reg = <0x490000 0x50>; + interrupts = <150 0>; + clocks = <&mc_cgm MCUX_LPUART9_CLK>; + status = "disabled"; + }; + + lpuart_10: lpuart@494000 { + compatible = "nxp,lpuart"; + reg = <0x494000 0x50>; + interrupts = <151 0>; + clocks = <&mc_cgm MCUX_LPUART10_CLK>; + status = "disabled"; + }; + + lpuart_11: lpuart@498000 { + compatible = "nxp,lpuart"; + reg = <0x498000 0x50>; + interrupts = <152 0>; + clocks = <&mc_cgm MCUX_LPUART11_CLK>; + status = "disabled"; + }; + + lpuart_12: lpuart@49c000 { + compatible = "nxp,lpuart"; + reg = <0x49c000 0x50>; + interrupts = <153 0>; + clocks = <&mc_cgm MCUX_LPUART12_CLK>; + status = "disabled"; + }; + + lpuart_13: lpuart@4a0000 { + compatible = "nxp,lpuart"; + reg = <0x4a0000 0x50>; + interrupts = <154 0>; + clocks = <&mc_cgm MCUX_LPUART13_CLK>; + status = "disabled"; + }; + + lpuart_14: lpuart@4a4000 { + compatible = "nxp,lpuart"; + reg = <0x4a4000 0x50>; + interrupts = <155 0>; + clocks = <&mc_cgm MCUX_LPUART14_CLK>; + status = "disabled"; + }; + + lpuart_15: lpuart@4a8000 { + compatible = "nxp,lpuart"; + reg = <0x4a8000 0x50>; + interrupts = <156 0>; + clocks = <&mc_cgm MCUX_LPUART15_CLK>; + status = "disabled"; + }; + + mc_cgm: mc_cgm@2d8000 { + compatible = "nxp,mc-cgm"; + reg = <0x2d8000 0x61c>; + #clock-cells = <1>; + status = "disabled"; + }; + + mc_me: mc-me@2dc000 { + compatible = "nxp,mc-me"; + reg = <0x2dc000 0x554>; + status = "disabled"; + }; + + mc_rgm: mc-rgm@28c000 { + compatible = "nxp,mc-rgm"; + reg = <0x28c000 0x4c>; + status = "disabled"; + }; + + mcm_0: mcm@e0080000 { + compatible = "nxp,mcm"; + reg = <0xe0080000 0x430>; + status = "disabled"; + }; + + mdm_ap: mdm-ap@250600 { + compatible = "nxp,mdm-ap"; + reg = <0x250600 0x11c>; + status = "disabled"; + }; + + mscm: mscm@260000 { + compatible = "nxp,mscm"; + reg = <0x260000 0xa6e>; + status = "disabled"; + }; + + mu0_b: mu@38c000 { + compatible = "nxp,mu"; + reg = <0x38c000 0x2ac>; + status = "disabled"; + }; + + mu1_b: mu@4ec000 { + compatible = "nxp,mu"; + reg = <0x4ec000 0x2ac>; + }; + + pflash: pflash@268000 { + compatible = "nxp,pflash"; + reg = <0x268000 0x4dc>; + status = "disabled"; + }; + + pit_0: pit@b0000 { + compatible = "nxp,pit"; + reg = <0xb0000 0x15c>; + interrupts = <96 0>; + clocks = <&mc_cgm MCUX_PIT0_CLK>; + max-load-value = <0xffffffff>; + status = "disabled"; + }; + + pit_1: pit@b4000 { + compatible = "nxp,pit"; + reg = <0xb4000 0x15c>; + interrupts = <97 0>; + clocks = <&mc_cgm MCUX_PIT1_CLK>; + max-load-value = <0xffffffff>; + status = "disabled"; + }; + + pit_2: pit@2fc000 { + compatible = "nxp,pit"; + reg = <0x2fc000 0x15c>; + interrupts = <98 0>; + clocks = <&mc_cgm MCUX_PIT2_CLK>; + max-load-value = <0xffffffff>; + status = "disabled"; + }; + + pll: plldig@402e0000 { + compatible = "nxp,plldig"; + reg = <0x402e0000 0xa4>; + status = "disabled"; + }; + + pmc: pmc@2e8000 { + compatible = "nxp,pmc"; + reg = <0x2e8000 0x2c>; + interrupts = <52 0>; + status = "disabled"; + }; + + pramc_0: pramc@264000 { + compatible = "nxp,pramc"; + reg = <0x264000 0x20>; + status = "disabled"; + }; + + pramc_1: pramc@464000 { + compatible = "nxp,pramc"; + reg = <0x464000 0x20>; + status = "disabled"; + }; + + quadspi: qspi@4cc000 { + compatible = "nxp,qspi"; + reg = <0x4cc000 0x37c>; + interrupts = <173 0>; + status = "disabled"; + }; + + quadspi_ardb: @68000000 { + compatible = "nxp,"; + reg = <0x68000000 0x21c>; + status = "disabled"; + }; + + rtc: rtc@288000 { + compatible = "nxp,rtc"; + reg = <0x288000 0x34>; + interrupts = <102 0>; + status = "disabled"; + }; + + sai_0: sai@36c000 { + compatible = "nxp,sai"; + reg = <0x36c000 0x100>; + interrupts = <174 0>; + status = "disabled"; + }; + + sai_1: sai@4dc000 { + compatible = "nxp,sai"; + reg = <0x4dc000 0x100>; + interrupts = <175 0>; + status = "disabled"; + }; + + sda_ap: sda-ap@254700 { + compatible = "nxp,sda-ap"; + reg = <0x254700 0x11c>; + status = "disabled"; + }; + + selftest: selftest-gpr@3b0000 { + compatible = "nxp,selftest-gpr"; + reg = <0x3b0000 0x34>; + status = "disabled"; + }; + + sema42: sema42@460000 { + compatible = "nxp,sema42"; + reg = <0x460000 0x52>; + status = "disabled"; + }; + + sirc: sirc@402c8000 { + compatible = "nxp,sirc"; + reg = <0x402c8000 0x2c>; + status = "disabled"; + }; + + siul2_0: siul2@290000 { + reg = <0x290000 0x17d4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x290000 0x17d4>; + + eirq0: eirq@10 { + compatible = "nxp,siul2-eirq"; + reg = <0x10 0xb4>; + #address-cells = <0>; + interrupts = <53 0>, <54 0>, <55 0>, <56 0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpioa_l: gpio@1702 { + compatible = "nxp,siul2-gpio"; + reg = <0x1702 0x02>, <0x240 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 0>, <1 1>, <2 2>, <3 3>, <4 4>, + <5 5>, <6 6>, <7 7>, <8 16>, <9 17>, + <10 18>, <11 19>, <12 20>, <13 21>, + <14 22>, <15 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <1 9>, <2 4>, <6 19>, + <8 27>, <9 25>, <13 8>, <15 24>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioa_h: gpio@1700 { + compatible = "nxp,siul2-gpio"; + reg = <0x1700 0x02>, <0x280 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 4>, <2 0>, <3 1>, <4 2>, + <5 3>, <9 5>, <12 6>, <14 7>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 35>, <4 63>, <9 38>, + <10 39>, <14 41>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiob_l: gpio@1706 { + compatible = "nxp,siul2-gpio"; + reg = <0x1706 0x02>, <0x2c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 8>, <1 9>, <2 10>, <3 11>, <4 12>, + <5 13>, <8 14>, <9 15>, <10 24>, <11 25>, + <12 26>, <13 27>, <14 28>, <15 29>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 11>, <2 12>, <8 29>, + <9 21>, <11 20>, <12 16>, <13 15>, <15 37>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + gpio-reserved-ranges = <6 2>; + status = "disabled"; + }; + + gpiob_h: gpio@1704 { + compatible = "nxp,siul2-gpio"; + reg = <0x1704 0x02>, <0x300 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 30>, <1 31>, <5 8>, <6 9>, <7 10>, + <8 11>, <9 12>, <10 13>, <12 14>, <15 15>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 17>, <1 18>, <3 42>, + <5 43>, <7 44>, <10 45>, <12 46>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioc_l: gpio@170a { + compatible = "nxp,siul2-gpio"; + reg = <0x170a 0x02>, <0x340 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 1>, <1 1>, <2 2>, <3 3>, <4 4>, + <5 5>, <6 6>, <7 7>, <8 16>, <9 17>, + <10 18>, <11 19>, <12 20>, <13 21>, + <14 22>, <15 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <6 7>, <7 6>, <9 14>, <11 22>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioc_h: gpio@1708 { + compatible = "nxp,siul2-gpio"; + reg = <0x1708 0x02>, <0x380 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <4 16>, <5 17>, <7 18>, <8 19>, + <9 20>, <10 21>, <11 22>, <13 23>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <2 40>, <4 47>, <7 48>, + <8 50>, <9 49>, <10 52>, <13 51>, <15 53>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiod_l: gpio@170e { + compatible = "nxp,siul2-gpio"; + reg = <0x170e 0x02>, <0x3c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 8>, <1 9>, <2 10>, <3 11>, <4 12>, + <5 13>, <6 14>, <7 15>, <8 24>, + <9 25>, <10 26>, <11 27>, <12 28>, + <13 29>, <14 30>, <15 31>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 10>, <2 13>, <3 5>, + <4 26>, <13 28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiod_h: gpio@170c { + compatible = "nxp,siul2-gpio"; + reg = <0x170c 0x02>, <0x400 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <1 24>, <4 25>, <5 26>, <6 27>, + <7 28>, <8 29>, <11 30>, <12 31>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <4 58>, <7 54>, <11 55>, + <13 56>, <15 57>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioe_l: gpio@1712 { + compatible = "nxp,siul2-gpio"; + reg = <0x1712 0x02>, <0x440 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 0>, <1 1>, <2 2>, <3 3>, + <4 4>, <5 5>, <6 6>, <8 7>, + <9 8>, <10 9>, <11 10>, <12 11>, + <13 12>, <14 13>, <15 14>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 30>, <2 31>, <5 36>, + <6 33>, <11 32>, <14 34>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioe_h: gpio@1710 { + compatible = "nxp,siul2-gpio"; + reg = <0x1710 0x02>, <0x480 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 15>; + nxp,wkpu = <&wkpu>; + nxp,wkpu-interrupts = <0 23>, <2 59>, <5 60>, + <7 61>, <9 62>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiof_l: gpio@1716 { + compatible = "nxp,siul2-gpio"; + reg = <0x1716 0x02>, <0x4c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 0>, <1 1>, <2 2>, <3 3>, + <4 4>, <5 5>, <6 6>, <7 7>, + <8 16>, <9 17>, <10 18>, <11 19>, + <12 20>, <13 21>, <14 22>, <15 23>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiof_h: gpio@1714 { + compatible = "nxp,siul2-gpio"; + reg = <0x1714 0x02>, <0x500 0x40>; + reg-names = "pgpdo", "mscr"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiog_l: gpio@171a { + compatible = "nxp,siul2-gpio"; + reg = <0x171a 0x02>, <0x540 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 8>, <1 9>, <2 10>, <3 11>, + <4 12>, <5 13>, <6 14>, <7 15>, + <8 24>, <9 25>, <10 26>, <11 27>, + <12 28>, <13 29>, <14 30>, <15 31>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiog_h: gpio@1718 { + compatible = "nxp,siul2-gpio"; + reg = <0x1718 0x02>, <0x580 0x40>; + reg-names = "pgpdo", "mscr"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + }; + + stcu: stcu@3a0000 { + compatible = "nxp,stcu"; + reg = <0x3a0000 0x2260>; + status = "disabled"; + }; + + stm_0: stm@274000 { + compatible = "nxp,stm"; + reg = <0x274000 0x68>; + interrupts = <39 0>; + status = "disabled"; + }; + + stm_1: stm@474000 { + compatible = "nxp,stm"; + reg = <0x474000 0x68>; + interrupts = <40 0>; + status = "disabled"; + }; + + swt_0: swt@270000 { + compatible = "nxp,swt"; + reg = <0x270000 0x3c>; + interrupts = <42 0>; + status = "disabled"; + }; + + sxosc: sxosc@402cc000 { + compatible = "nxp,sxosc"; + reg = <0x402cc000 0x24>; + status = "disabled"; + }; + + tempsense: tempsense@37c000 { + compatible = "nxp,tempsense"; + reg = <0x37c000 0x30>; + status = "disabled"; + }; + + trgmux: trgmux@80000 { + compatible = "nxp,trgmux"; + reg = <0x80000 0xbc>; + status = "disabled"; + }; + + tspc: tspc@2c4000 { + compatible = "nxp,tspc"; + reg = <0x2c4000 0xc4>; + status = "disabled"; + }; + + virt_wrapper: virt-wrapper@2a8000 { + compatible = "nxp,virt-wrapper"; + reg = <0x2a8000 0x124>; + status = "disabled"; + }; + + wkpu: wkpu@2b4000 { + compatible = "nxp,wkpu"; + reg = <0x2b4000 0x90>; + interrupts = <83 0>; + status = "disabled"; + }; + + xbic_axbs: xbic@204000 { + compatible = "nxp,xbic"; + reg = <0x204000 0x2c>; + status = "disabled"; + }; + + xbic_axbs_edma: xbic@404000 { + compatible = "nxp,xbic"; + reg = <0x404000 0x2c>; + status = "disabled"; + }; + + xbic_axbs_peri: xbic@208000 { + compatible = "nxp,xbic"; + reg = <0x208000 0x2c>; + status = "disabled"; + }; + + xbic_axbs_tcm: xbic@400000 { + compatible = "nxp,xbic"; + reg = <0x400000 0x2c>; + status = "disabled"; + }; + + xrdc: xrdc@278000 { + compatible = "nxp,xrdc"; + reg = <0x278000 0x248c>; + status = "disabled"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index e95c01fc1840a..4b88cae0ced77 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -983,6 +983,48 @@ nxp,rx-dma-channel = <3>; status = "disabled"; }; + + micfil: micfil@10c000 { + compatible = "nxp,micfil"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <48 0>; + reg = <0x10c000 0x1000>; + clocks = <&syscon MCUX_MICFIL_CLK>; + status = "disabled"; + quality-mode = <1>; + cic-decimation-rate = <0>; + fifo-watermark = <15>; + sample-rate = <16000>; + + channel0: micfil-channel@0 { + reg = <0>; + status = "disabled"; + dc-remover-cutoff-freq = <2>; + decimation-filter-gain = <4>; + }; + + channel1: micfil-channel@1 { + reg = <1>; + status = "disabled"; + dc-remover-cutoff-freq = <2>; + decimation-filter-gain = <4>; + }; + + channel2: micfil-channel@2 { + reg = <2>; + status = "disabled"; + dc-remover-cutoff-freq = <2>; + decimation-filter-gain = <4>; + }; + + channel3: micfil-channel@3 { + reg = <3>; + status = "disabled"; + dc-remover-cutoff-freq = <2>; + decimation-filter-gain = <4>; + }; + }; }; &systick { diff --git a/dts/arm/nxp/nxp_mcxw23x_common.dtsi b/dts/arm/nxp/nxp_mcxw23x_common.dtsi index a1adcffaf8514..d70b192daa574 100644 --- a/dts/arm/nxp/nxp_mcxw23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw23x_common.dtsi @@ -64,6 +64,10 @@ }; }; +&systick { + status = "disabled"; +}; + &peripheral { #address-cells = <1>; #size-cells = <1>; @@ -89,8 +93,8 @@ flash0: flash@0 { compatible = "soc-nv-flash"; reg = <0x0 DT_SIZE_K(1016)>; - erase-block-size = <512>; - write-block-size = <512>; + erase-block-size = ; + write-block-size = <16>; }; flash_reserved: flash@fe000 { @@ -231,12 +235,21 @@ #pwm-cells = <3>; }; + os_timer: timers@2d000 { + compatible = "nxp,os-timer"; + reg = <0x2d000 0x1000>; + interrupts = <38 1>; + status = "disabled"; + }; + flexcomm0: flexcomm@86000 { compatible = "nxp,lpc-flexcomm"; reg = <0x86000 0x1000>; interrupts = <14 1>; clocks = <&syscon MCUX_FLEXCOMM0_CLK>; resets = <&reset NXP_SYSCON_RESET(1, 11)>; + dmas = <&dma0 4 &dma0 5>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -246,6 +259,8 @@ interrupts = <15 1>; clocks = <&syscon MCUX_FLEXCOMM1_CLK>; resets = <&reset NXP_SYSCON_RESET(1, 12)>; + dmas = <&dma0 6 &dma0 7>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -255,6 +270,8 @@ interrupts = <16 1>; clocks = <&syscon MCUX_FLEXCOMM2_CLK>; resets = <&reset NXP_SYSCON_RESET(1, 13)>; + dmas = <&dma0 8 &dma0 9>; + dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/dts/arm/realtek/ec/rts5912.dtsi b/dts/arm/realtek/ec/rts5912.dtsi index 13daf81625df3..f1a517d79ff97 100644 --- a/dts/arm/realtek/ec/rts5912.dtsi +++ b/dts/arm/realtek/ec/rts5912.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include / { cpus { @@ -167,6 +168,7 @@ espi0: espi0@400b1000 { compatible = "realtek,rts5912-espi"; + cs-gpios = ; status = "disabled"; reg = <0x400b1000 0x200 /* espi target */ diff --git a/dts/arm/renesas/ra/ra8/r7ka8p1xf.dtsi b/dts/arm/renesas/ra/ra8/r7ka8p1xf.dtsi index 92530eed96074..6f7a3e5a2d66e 100644 --- a/dts/arm/renesas/ra/ra8/r7ka8p1xf.dtsi +++ b/dts/arm/renesas/ra/ra8/r7ka8p1xf.dtsi @@ -8,6 +8,17 @@ #include / { + soc { + npu0: npu@40140000 { + compatible = "renesas,ra-npu"; + reg = <0x40140000 0x1000>; + clocks = <&npuclk MSTPA 16>; + secure-enable; + privilege-enable; + status = "disabled"; + }; + }; + clocks: clocks { #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi index 10fd7985a5036..67cbefd4f0a74 100644 --- a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi +++ b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi @@ -1259,6 +1259,70 @@ }; }; + spi0: spi@80003000 { + compatible = "renesas,rz-spi"; + reg = <0x80003000 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <0>; + clk-src = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@80003400 { + compatible = "renesas,rz-spi"; + reg = <0x80003400 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <1>; + clk-src = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@80003800 { + compatible = "renesas,rz-spi"; + reg = <0x80003800 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <2>; + clk-src = <2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@81002000 { + compatible = "renesas,rz-spi"; + reg = <0x81002000 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <3>; + clk-src = <3>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + wdt0: watchdog@80042000 { compatible = "renesas,rz-wdt"; reg = <0x80042000 0x1000>; @@ -1266,5 +1330,25 @@ interrupts = ; status = "disabled"; }; + + xspi0: xspi@80220000 { + compatible = "renesas,rz-xspi"; + reg = <0x80220000 0x1000>; + interrupts = , + ; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + + xspi1: xspi@80221000 { + compatible = "renesas,rz-xspi"; + reg = <0x80221000 0x1000>; + interrupts = , + ; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi index f436cec154058..353e907fd21d0 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi @@ -1263,6 +1263,70 @@ }; }; + spi0: spi@80003000 { + compatible = "renesas,rz-spi"; + reg = <0x80003000 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <0>; + clk-src = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@80003400 { + compatible = "renesas,rz-spi"; + reg = <0x80003400 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <1>; + clk-src = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@80003800 { + compatible = "renesas,rz-spi"; + reg = <0x80003800 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <2>; + clk-src = <2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@81002000 { + compatible = "renesas,rz-spi"; + reg = <0x81002000 0x74>; + interrupts = , + , + , + , + ; + interrupt-names = "rxi", "txi", "idle", "eri", "tei"; + channel = <3>; + clk-src = <3>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + wdt0: watchdog@80042000 { compatible = "renesas,rz-wdt"; reg = <0x80042000 0x1000>; @@ -1270,5 +1334,26 @@ interrupts = ; status = "disabled"; }; + + xspi0: xspi@80220000 { + compatible = "renesas,rz-xspi"; + reg = <0x80220000 0x1000>; + interrupts = , + ; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + + xspi1: xspi@80221000 { + compatible = "renesas,rz-xspi"; + reg = <0x80221000 0x1000>; + interrupts = , + ; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi index b48319f8839c2..d8d3e7e8e96a7 100644 --- a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { compatible = "renesas,r9a07g054"; @@ -641,6 +642,26 @@ }; }; + dma0: dma@41800000 { /* Secure DMA */ + compatible = "renesas,rz-dma"; + reg = <0x41800000 0x800>, <0x41810000 0x20>; + reg-names = "reg_main", "ext"; + interrupts = <108 1>, <109 1>, <110 1>, <111 1>, + <112 1>, <113 1>, <114 1>, <115 1>, + <116 1>, <117 1>, <118 1>, <119 1>, + <120 1>, <121 1>, <122 1>, <123 1>, + <124 1>; /* DMAERR1 */ + interrupt-names = "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15", + "err1"; + dma-channels = <16>; + #dma-cells = <2>; + dma-buf-addr-alignment = <4>; + status = "disabled"; + }; + scif0: serial@4004b800 { compatible = "renesas,rz-scif-uart"; channel = <0>; @@ -1018,6 +1039,39 @@ status = "disabled"; }; + spi0: spi@4004ac00 { + compatible = "renesas,rz-rspi"; + reg = <0x4004ac00 DT_SIZE_K(1)>; + interrupts = <413 1>, <414 1>, <415 1>; + interrupt-names = "rx", "tx", "error"; + channel = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@4004b000 { + compatible = "renesas,rz-rspi"; + reg = <0x4004b000 DT_SIZE_K(1)>; + interrupts = <416 1>, <417 1>, <418 1>; + interrupt-names = "rx", "tx", "error"; + channel = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@4004b400 { + compatible = "renesas,rz-rspi"; + reg = <0x4004b400 DT_SIZE_K(1)>; + interrupts = <419 1>, <420 1>, <421 1>; + interrupt-names = "rx", "tx", "error"; + channel = <2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + gtm0: gtm@42801000 { compatible = "renesas,rz-gtm"; reg = <0x42801000 0x400>; diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index 1db4c3f8d1619..72ea7f7855ce1 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -11,6 +11,7 @@ / { chosen { + silabs,sleeptimer = &sysrtc0; zephyr,sram = &sram0; zephyr,entropy = &rng0; zephyr,flash = &flash0; @@ -309,6 +310,8 @@ clocks = <&clock0 SIWX91X_CLK_DMA0>; #dma-cells = <1>; dma-channels = <32>; + power-domains = <&siwx91x_soc_pd>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -323,6 +326,8 @@ silabs,sram-region = <&sram_dma1>; #dma-cells = <1>; dma-channels = <12>; + power-domains = <&siwx91x_soc_pd>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -359,8 +364,8 @@ status = "disabled"; }; - sysrtc0: stimer0: sysrtc@24048c00 { - compatible = "silabs,gecko-stimer"; + sysrtc0: sysrtc@24048c00 { + compatible = "silabs,sysrtc"; reg = <0x24048c00 0x78>; interrupts = <22 0>; interrupt-names = "sysrtc"; @@ -377,6 +382,8 @@ interrupts = <46 0>; interrupt-names = "gspi"; clocks = <&clock0 SIWX91X_CLK_GSPI>; + power-domains = <&siwx91x_soc_pd>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; diff --git a/dts/arm/silabs/xg21/xg21.dtsi b/dts/arm/silabs/xg21/xg21.dtsi index 8356421e8a780..5bdfed4857cf0 100644 --- a/dts/arm/silabs/xg21/xg21.dtsi +++ b/dts/arm/silabs/xg21/xg21.dtsi @@ -16,6 +16,7 @@ / { chosen { + silabs,sleeptimer = &rtcc0; zephyr,entropy = &se; zephyr,flash-controller = &msc; }; @@ -448,8 +449,8 @@ status = "disabled"; }; - rtcc0: stimer0: rtcc@58000000 { - compatible = "silabs,gecko-stimer"; + rtcc0: rtcc@58000000 { + compatible = "silabs,rtcc"; reg = <0x58000000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_RTCCCLK>; diff --git a/dts/arm/silabs/xg22/xg22.dtsi b/dts/arm/silabs/xg22/xg22.dtsi index 0177e3f85dd54..0b2873ff5ed7b 100644 --- a/dts/arm/silabs/xg22/xg22.dtsi +++ b/dts/arm/silabs/xg22/xg22.dtsi @@ -15,6 +15,7 @@ / { chosen { + silabs,sleeptimer = &rtcc0; zephyr,entropy = &trng; zephyr,flash-controller = &msc; }; @@ -491,8 +492,8 @@ status = "disabled"; }; - rtcc0: stimer0: rtcc@58000000 { - compatible = "silabs,gecko-stimer"; + rtcc0: rtcc@58000000 { + compatible = "silabs,rtcc"; reg = <0x58000000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_RTCC CLOCK_BRANCH_RTCCCLK>; diff --git a/dts/arm/silabs/xg23/xg23.dtsi b/dts/arm/silabs/xg23/xg23.dtsi index 93bc1006d6f6b..9d29801be79a9 100644 --- a/dts/arm/silabs/xg23/xg23.dtsi +++ b/dts/arm/silabs/xg23/xg23.dtsi @@ -15,6 +15,7 @@ / { chosen { + silabs,sleeptimer = &sysrtc0; zephyr,entropy = &se; zephyr,flash-controller = &msc; }; @@ -511,8 +512,8 @@ status = "disabled"; }; - sysrtc0: stimer0: sysrtc@500a8000 { - compatible = "silabs,gecko-stimer"; + sysrtc0: sysrtc@500a8000 { + compatible = "silabs,sysrtc"; reg = <0x500a8000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_SYSRTC0 CLOCK_BRANCH_SYSRTCCLK>; diff --git a/dts/arm/silabs/xg24/xg24.dtsi b/dts/arm/silabs/xg24/xg24.dtsi index da17df1f25f3b..9b31a8b42c8aa 100644 --- a/dts/arm/silabs/xg24/xg24.dtsi +++ b/dts/arm/silabs/xg24/xg24.dtsi @@ -15,6 +15,7 @@ / { chosen { + silabs,sleeptimer = &sysrtc0; zephyr,entropy = &se; zephyr,flash-controller = &msc; }; @@ -494,8 +495,8 @@ status = "disabled"; }; - sysrtc0: stimer0: sysrtc@500a8000 { - compatible = "silabs,gecko-stimer"; + sysrtc0: sysrtc@500a8000 { + compatible = "silabs,sysrtc"; reg = <0x500a8000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_SYSRTC0 CLOCK_BRANCH_SYSRTCCLK>; diff --git a/dts/arm/silabs/xg27/xg27.dtsi b/dts/arm/silabs/xg27/xg27.dtsi index 1f97b67cd50ea..f479fbd8a2521 100644 --- a/dts/arm/silabs/xg27/xg27.dtsi +++ b/dts/arm/silabs/xg27/xg27.dtsi @@ -15,6 +15,7 @@ / { chosen { + silabs,sleeptimer = &rtcc0; zephyr,entropy = &trng; zephyr,flash-controller = &msc; }; @@ -491,8 +492,8 @@ status = "disabled"; }; - rtcc0: stimer0: rtcc@58000000 { - compatible = "silabs,gecko-stimer"; + rtcc0: rtcc@58000000 { + compatible = "silabs,rtcc"; reg = <0x58000000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_RTCC CLOCK_BRANCH_RTCCCLK>; diff --git a/dts/arm/silabs/xg28/xg28.dtsi b/dts/arm/silabs/xg28/xg28.dtsi index 92a188f1acbd0..6f9863472bebe 100644 --- a/dts/arm/silabs/xg28/xg28.dtsi +++ b/dts/arm/silabs/xg28/xg28.dtsi @@ -15,6 +15,7 @@ / { chosen { + silabs,sleeptimer = &sysrtc0; zephyr,entropy = &se; zephyr,flash-controller = &msc; }; @@ -511,8 +512,8 @@ status = "disabled"; }; - sysrtc0: stimer0: sysrtc@500a8000 { - compatible = "silabs,gecko-stimer"; + sysrtc0: sysrtc@500a8000 { + compatible = "silabs,sysrtc"; reg = <0x500a8000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_SYSRTC0 CLOCK_BRANCH_SYSRTCCLK>; diff --git a/dts/arm/silabs/xg29/xg29.dtsi b/dts/arm/silabs/xg29/xg29.dtsi index 17eb20f2a765a..93a5cb4bb28d3 100644 --- a/dts/arm/silabs/xg29/xg29.dtsi +++ b/dts/arm/silabs/xg29/xg29.dtsi @@ -14,6 +14,7 @@ / { chosen { + silabs,sleeptimer = &rtcc0; zephyr,entropy = &se; zephyr,flash-controller = &msc; }; @@ -505,8 +506,8 @@ status = "disabled"; }; - rtcc0: stimer0: rtcc@58000000 { - compatible = "silabs,gecko-stimer"; + rtcc0: rtcc@58000000 { + compatible = "silabs,rtcc"; reg = <0x58000000 0x4000>; clock-frequency = <32768>; clocks = <&cmu CLOCK_RTCC CLOCK_BRANCH_RTCCCLK>; diff --git a/dts/arm/st/c0/stm32c0.dtsi b/dts/arm/st/c0/stm32c0.dtsi index 2a8a4f101cb5d..5941dace1b751 100644 --- a/dts/arm/st/c0/stm32c0.dtsi +++ b/dts/arm/st/c0/stm32c0.dtsi @@ -69,6 +69,7 @@ #include #include #include +#include / { chosen { @@ -186,7 +187,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40021800 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/c0/stm32c011X6.dtsi b/dts/arm/st/c0/stm32c011X6.dtsi index d5be6b7e7d81a..5c6eea42802d6 100644 --- a/dts/arm/st/c0/stm32c011X6.dtsi +++ b/dts/arm/st/c0/stm32c011X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c031X6.dtsi b/dts/arm/st/c0/stm32c031X6.dtsi index 817118aef2a88..588b3db09a5ad 100644 --- a/dts/arm/st/c0/stm32c031X6.dtsi +++ b/dts/arm/st/c0/stm32c031X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c051X6.dtsi b/dts/arm/st/c0/stm32c051X6.dtsi index 2acdb7a883b84..1b6497e646d1f 100644 --- a/dts/arm/st/c0/stm32c051X6.dtsi +++ b/dts/arm/st/c0/stm32c051X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c051X8.dtsi b/dts/arm/st/c0/stm32c051X8.dtsi index a2fbaf164b696..c065bb63decdc 100644 --- a/dts/arm/st/c0/stm32c051X8.dtsi +++ b/dts/arm/st/c0/stm32c051X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c071X8.dtsi b/dts/arm/st/c0/stm32c071X8.dtsi index 0a9d4001f5d6a..7ef7b785539cf 100644 --- a/dts/arm/st/c0/stm32c071X8.dtsi +++ b/dts/arm/st/c0/stm32c071X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c071Xb.dtsi b/dts/arm/st/c0/stm32c071Xb.dtsi index 909b588d1dc88..03d5e93c022e1 100644 --- a/dts/arm/st/c0/stm32c071Xb.dtsi +++ b/dts/arm/st/c0/stm32c071Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c091Xb.dtsi b/dts/arm/st/c0/stm32c091Xb.dtsi index d1cd06a0eca21..915968a6d2d73 100644 --- a/dts/arm/st/c0/stm32c091Xb.dtsi +++ b/dts/arm/st/c0/stm32c091Xb.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c091Xc.dtsi b/dts/arm/st/c0/stm32c091Xc.dtsi index 4b1a595b0e238..7be153cf28945 100644 --- a/dts/arm/st/c0/stm32c091Xc.dtsi +++ b/dts/arm/st/c0/stm32c091Xc.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c092Xb.dtsi b/dts/arm/st/c0/stm32c092Xb.dtsi index 889f658029f14..b2ebfae968bc9 100644 --- a/dts/arm/st/c0/stm32c092Xb.dtsi +++ b/dts/arm/st/c0/stm32c092Xb.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/c0/stm32c092Xc.dtsi b/dts/arm/st/c0/stm32c092Xc.dtsi index e814ddb4be968..4e86d6e81ab97 100644 --- a/dts/arm/st/c0/stm32c092Xc.dtsi +++ b/dts/arm/st/c0/stm32c092Xc.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f0.dtsi b/dts/arm/st/f0/stm32f0.dtsi index 3a411f35545cc..bc855c7a4581a 100644 --- a/dts/arm/st/f0/stm32f0.dtsi +++ b/dts/arm/st/f0/stm32f0.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include / { chosen { @@ -116,7 +117,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/f0/stm32f030X4.dtsi b/dts/arm/st/f0/stm32f030X4.dtsi index a38ece02f0fb6..d04d2f4b7d8e7 100644 --- a/dts/arm/st/f0/stm32f030X4.dtsi +++ b/dts/arm/st/f0/stm32f030X4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f030X6.dtsi b/dts/arm/st/f0/stm32f030X6.dtsi index 2050c8523be94..16c6d57748dd5 100644 --- a/dts/arm/st/f0/stm32f030X6.dtsi +++ b/dts/arm/st/f0/stm32f030X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { @@ -20,4 +19,3 @@ }; }; }; - diff --git a/dts/arm/st/f0/stm32f030X8.dtsi b/dts/arm/st/f0/stm32f030X8.dtsi index f0fe64e254a05..c5d316ec92dfa 100644 --- a/dts/arm/st/f0/stm32f030X8.dtsi +++ b/dts/arm/st/f0/stm32f030X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f030Xc.dtsi b/dts/arm/st/f0/stm32f030Xc.dtsi index 53cf999a74b5f..8fb5e0f8b8391 100644 --- a/dts/arm/st/f0/stm32f030Xc.dtsi +++ b/dts/arm/st/f0/stm32f030Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f031X6.dtsi b/dts/arm/st/f0/stm32f031X6.dtsi index 373437a18716d..a0c7b02dd3466 100644 --- a/dts/arm/st/f0/stm32f031X6.dtsi +++ b/dts/arm/st/f0/stm32f031X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f042X6.dtsi b/dts/arm/st/f0/stm32f042X6.dtsi index 905c7737cd0df..1e8b63beaef68 100644 --- a/dts/arm/st/f0/stm32f042X6.dtsi +++ b/dts/arm/st/f0/stm32f042X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f051X8.dtsi b/dts/arm/st/f0/stm32f051X8.dtsi index 0b2e8a8af499e..24ee5888a4080 100644 --- a/dts/arm/st/f0/stm32f051X8.dtsi +++ b/dts/arm/st/f0/stm32f051X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f070Xb.dtsi b/dts/arm/st/f0/stm32f070Xb.dtsi index e8226c43ac4dd..9a42e1985025e 100644 --- a/dts/arm/st/f0/stm32f070Xb.dtsi +++ b/dts/arm/st/f0/stm32f070Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f072X8.dtsi b/dts/arm/st/f0/stm32f072X8.dtsi index 66669041b911d..a8101ae7b0ff1 100644 --- a/dts/arm/st/f0/stm32f072X8.dtsi +++ b/dts/arm/st/f0/stm32f072X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f072Xb.dtsi b/dts/arm/st/f0/stm32f072Xb.dtsi index 2327558183509..8b33d68bfaaf9 100644 --- a/dts/arm/st/f0/stm32f072Xb.dtsi +++ b/dts/arm/st/f0/stm32f072Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f091Xc.dtsi b/dts/arm/st/f0/stm32f091Xc.dtsi index a840f078c09c1..b47404100f5c7 100644 --- a/dts/arm/st/f0/stm32f091Xc.dtsi +++ b/dts/arm/st/f0/stm32f091Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f0/stm32f098Xc.dtsi b/dts/arm/st/f0/stm32f098Xc.dtsi index d1028a6920584..6dd1376bd1b40 100644 --- a/dts/arm/st/f0/stm32f098Xc.dtsi +++ b/dts/arm/st/f0/stm32f098Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f1.dtsi b/dts/arm/st/f1/stm32f1.dtsi index 5744dcfa3c939..8f562d2f20277 100644 --- a/dts/arm/st/f1/stm32f1.dtsi +++ b/dts/arm/st/f1/stm32f1.dtsi @@ -18,6 +18,7 @@ #include #include #include +#include / { chosen { @@ -136,7 +137,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; num-lines = <32>; interrupts = <6 0>, <7 0>, <8 0>, <9 0>, diff --git a/dts/arm/st/f1/stm32f100Xb.dtsi b/dts/arm/st/f1/stm32f100Xb.dtsi index b0a99a9187ea5..36b9ee57e295a 100644 --- a/dts/arm/st/f1/stm32f100Xb.dtsi +++ b/dts/arm/st/f1/stm32f100Xb.dtsi @@ -6,7 +6,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f100Xe.dtsi b/dts/arm/st/f1/stm32f100Xe.dtsi index 67a85ef347806..d6fc036c34af9 100644 --- a/dts/arm/st/f1/stm32f100Xe.dtsi +++ b/dts/arm/st/f1/stm32f100Xe.dtsi @@ -6,7 +6,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f103X8.dtsi b/dts/arm/st/f1/stm32f103X8.dtsi index 055c97ab269cd..874043f8dd1a0 100644 --- a/dts/arm/st/f1/stm32f103X8.dtsi +++ b/dts/arm/st/f1/stm32f103X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f103Xb.dtsi b/dts/arm/st/f1/stm32f103Xb.dtsi index 7c95f608cc95f..c07233ce48a8d 100644 --- a/dts/arm/st/f1/stm32f103Xb.dtsi +++ b/dts/arm/st/f1/stm32f103Xb.dtsi @@ -7,7 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f103Xc.dtsi b/dts/arm/st/f1/stm32f103Xc.dtsi index 518d243fe62b5..cab9915dc640a 100644 --- a/dts/arm/st/f1/stm32f103Xc.dtsi +++ b/dts/arm/st/f1/stm32f103Xc.dtsi @@ -7,7 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/f1/stm32f103Xd.dtsi b/dts/arm/st/f1/stm32f103Xd.dtsi index 2c3935473ed78..5f35c663d1ae7 100644 --- a/dts/arm/st/f1/stm32f103Xd.dtsi +++ b/dts/arm/st/f1/stm32f103Xd.dtsi @@ -7,7 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f103Xe.dtsi b/dts/arm/st/f1/stm32f103Xe.dtsi index 18c0dcc83ff2b..21d8915b59f3f 100644 --- a/dts/arm/st/f1/stm32f103Xe.dtsi +++ b/dts/arm/st/f1/stm32f103Xe.dtsi @@ -7,7 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f103Xg.dtsi b/dts/arm/st/f1/stm32f103Xg.dtsi index 484286fb2bbce..89544b7d86b71 100644 --- a/dts/arm/st/f1/stm32f103Xg.dtsi +++ b/dts/arm/st/f1/stm32f103Xg.dtsi @@ -6,7 +6,6 @@ * where 'x' is replaced for specific SoCs like {R,V,Z} */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f105Xb.dtsi b/dts/arm/st/f1/stm32f105Xb.dtsi index 7db805c8a5f5e..6a535504323a8 100644 --- a/dts/arm/st/f1/stm32f105Xb.dtsi +++ b/dts/arm/st/f1/stm32f105Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f105Xc.dtsi b/dts/arm/st/f1/stm32f105Xc.dtsi index e2151b445485c..43fc52663ed80 100644 --- a/dts/arm/st/f1/stm32f105Xc.dtsi +++ b/dts/arm/st/f1/stm32f105Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f1/stm32f107Xc.dtsi b/dts/arm/st/f1/stm32f107Xc.dtsi index ea7ad2e491ccd..6d5795d552b01 100644 --- a/dts/arm/st/f1/stm32f107Xc.dtsi +++ b/dts/arm/st/f1/stm32f107Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index 8e2b67ab92b8f..1cdf6ad01b41e 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -18,6 +18,7 @@ #include #include #include +#include / { chosen { @@ -109,7 +110,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40013c00 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 14)>; num-lines = <32>; diff --git a/dts/arm/st/f2/stm32f205Xe.dtsi b/dts/arm/st/f2/stm32f205Xe.dtsi index 2a2723a3ca1d5..c02ac24b92ad8 100644 --- a/dts/arm/st/f2/stm32f205Xe.dtsi +++ b/dts/arm/st/f2/stm32f205Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f2/stm32f207Xg.dtsi b/dts/arm/st/f2/stm32f207Xg.dtsi index 4dfbbbd1c1e0f..68c132c9bf3f7 100644 --- a/dts/arm/st/f2/stm32f207Xg.dtsi +++ b/dts/arm/st/f2/stm32f207Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f3/stm32f3.dtsi b/dts/arm/st/f3/stm32f3.dtsi index c86a70889f62d..025db8459434d 100644 --- a/dts/arm/st/f3/stm32f3.dtsi +++ b/dts/arm/st/f3/stm32f3.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include / { chosen { @@ -110,7 +111,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/f3/stm32f302X8.dtsi b/dts/arm/st/f3/stm32f302X8.dtsi index 003a2e055024e..ba3fe3dbe1bbf 100644 --- a/dts/arm/st/f3/stm32f302X8.dtsi +++ b/dts/arm/st/f3/stm32f302X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f3/stm32f302Xc.dtsi b/dts/arm/st/f3/stm32f302Xc.dtsi index 44742e388684f..d4040966288c1 100644 --- a/dts/arm/st/f3/stm32f302Xc.dtsi +++ b/dts/arm/st/f3/stm32f302Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/f3/stm32f303X8.dtsi b/dts/arm/st/f3/stm32f303X8.dtsi index 17ea1cdd1d18c..3395b9470a03c 100644 --- a/dts/arm/st/f3/stm32f303X8.dtsi +++ b/dts/arm/st/f3/stm32f303X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f3/stm32f303Xb.dtsi b/dts/arm/st/f3/stm32f303Xb.dtsi index a017c5279a42b..91cda7cb429ad 100644 --- a/dts/arm/st/f3/stm32f303Xb.dtsi +++ b/dts/arm/st/f3/stm32f303Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/f3/stm32f303Xc.dtsi b/dts/arm/st/f3/stm32f303Xc.dtsi index 76131f723490c..1a7708707121e 100644 --- a/dts/arm/st/f3/stm32f303Xc.dtsi +++ b/dts/arm/st/f3/stm32f303Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/f3/stm32f303Xe.dtsi b/dts/arm/st/f3/stm32f303Xe.dtsi index 683b7cc9bed00..bc5b4d9cd6afe 100644 --- a/dts/arm/st/f3/stm32f303Xe.dtsi +++ b/dts/arm/st/f3/stm32f303Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/f3/stm32f334X8.dtsi b/dts/arm/st/f3/stm32f334X8.dtsi index caf654d77e5a9..827d6e0504d5e 100644 --- a/dts/arm/st/f3/stm32f334X8.dtsi +++ b/dts/arm/st/f3/stm32f334X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f3/stm32f373Xc.dtsi b/dts/arm/st/f3/stm32f373Xc.dtsi index f9898820755d5..07c4d52241b73 100644 --- a/dts/arm/st/f3/stm32f373Xc.dtsi +++ b/dts/arm/st/f3/stm32f373Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index b4736ff54b089..1018c1eb74c71 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { chosen { @@ -140,7 +141,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40013c00 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 14)>; num-lines = <32>; diff --git a/dts/arm/st/f4/stm32f401Xc.dtsi b/dts/arm/st/f4/stm32f401Xc.dtsi index 3d733a124ae01..84f415451ab79 100644 --- a/dts/arm/st/f4/stm32f401Xc.dtsi +++ b/dts/arm/st/f4/stm32f401Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f401Xd.dtsi b/dts/arm/st/f4/stm32f401Xd.dtsi index b15480221f466..f26e9047ed4d0 100644 --- a/dts/arm/st/f4/stm32f401Xd.dtsi +++ b/dts/arm/st/f4/stm32f401Xd.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f401Xe.dtsi b/dts/arm/st/f4/stm32f401Xe.dtsi index 087bcb9469a73..6fe6405a0d10a 100644 --- a/dts/arm/st/f4/stm32f401Xe.dtsi +++ b/dts/arm/st/f4/stm32f401Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f405Xg.dtsi b/dts/arm/st/f4/stm32f405Xg.dtsi index 20ba8184ee02c..368640e2752d3 100644 --- a/dts/arm/st/f4/stm32f405Xg.dtsi +++ b/dts/arm/st/f4/stm32f405Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f407Xe.dtsi b/dts/arm/st/f4/stm32f407Xe.dtsi index 0d11257f2e3f5..95f4e8ced6c51 100644 --- a/dts/arm/st/f4/stm32f407Xe.dtsi +++ b/dts/arm/st/f4/stm32f407Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f407Xg.dtsi b/dts/arm/st/f4/stm32f407Xg.dtsi index c2b861a13f5ed..1e5005ff0859c 100644 --- a/dts/arm/st/f4/stm32f407Xg.dtsi +++ b/dts/arm/st/f4/stm32f407Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f410Xb.dtsi b/dts/arm/st/f4/stm32f410Xb.dtsi index 820a67a23d0d0..c7488bb14f3bb 100644 --- a/dts/arm/st/f4/stm32f410Xb.dtsi +++ b/dts/arm/st/f4/stm32f410Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &sdmmc1; diff --git a/dts/arm/st/f4/stm32f411Xe.dtsi b/dts/arm/st/f4/stm32f411Xe.dtsi index bc9e8b2c2e5c9..9ecaf5e1e79a2 100644 --- a/dts/arm/st/f4/stm32f411Xe.dtsi +++ b/dts/arm/st/f4/stm32f411Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f412Xe.dtsi b/dts/arm/st/f4/stm32f412Xe.dtsi index 764ba77d5550d..16443ecdef0eb 100644 --- a/dts/arm/st/f4/stm32f412Xe.dtsi +++ b/dts/arm/st/f4/stm32f412Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f412Xg.dtsi b/dts/arm/st/f4/stm32f412Xg.dtsi index a6958857dbc4f..9e6d243fc0022 100644 --- a/dts/arm/st/f4/stm32f412Xg.dtsi +++ b/dts/arm/st/f4/stm32f412Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f413.dtsi b/dts/arm/st/f4/stm32f413.dtsi index 4cfe6a4587c8a..a410152e7a263 100644 --- a/dts/arm/st/f4/stm32f413.dtsi +++ b/dts/arm/st/f4/stm32f413.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Florian Vaussard, HEIG-VD + * Copyright (c) 2025 Mario Paja * * SPDX-License-Identifier: Apache-2.0 */ @@ -80,5 +81,27 @@ clocks = <&rcc STM32_CLOCK(APB1, 27)>; status = "disabled"; }; + + sai1_a: sai1@40015804 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015804 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 1 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; + + sai1_b: sai1@40015824 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015824 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 5 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/st/f4/stm32f413Xg.dtsi b/dts/arm/st/f4/stm32f413Xg.dtsi index 62a8029fc4883..80af1a3e822a4 100644 --- a/dts/arm/st/f4/stm32f413Xg.dtsi +++ b/dts/arm/st/f4/stm32f413Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f413Xh.dtsi b/dts/arm/st/f4/stm32f413Xh.dtsi index 6e79b06b78411..63c733f98b5d1 100644 --- a/dts/arm/st/f4/stm32f413Xh.dtsi +++ b/dts/arm/st/f4/stm32f413Xh.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f415Rg.dtsi b/dts/arm/st/f4/stm32f415Rg.dtsi index feed35472961e..4f430d88037a7 100644 --- a/dts/arm/st/f4/stm32f415Rg.dtsi +++ b/dts/arm/st/f4/stm32f415Rg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f417Xe.dtsi b/dts/arm/st/f4/stm32f417Xe.dtsi index 2f0bfdbde11b2..aab4fc20deaf7 100644 --- a/dts/arm/st/f4/stm32f417Xe.dtsi +++ b/dts/arm/st/f4/stm32f417Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f417Xg.dtsi b/dts/arm/st/f4/stm32f417Xg.dtsi index 0c8e3a00b9f7f..c272f7b235f41 100644 --- a/dts/arm/st/f4/stm32f417Xg.dtsi +++ b/dts/arm/st/f4/stm32f417Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f423Xg.dtsi b/dts/arm/st/f4/stm32f423Xg.dtsi index 768c0bea023c3..18f2bac697fcc 100644 --- a/dts/arm/st/f4/stm32f423Xg.dtsi +++ b/dts/arm/st/f4/stm32f423Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f423Xh.dtsi b/dts/arm/st/f4/stm32f423Xh.dtsi index 2b2eaa7f1cb3b..6c0332312a26e 100644 --- a/dts/arm/st/f4/stm32f423Xh.dtsi +++ b/dts/arm/st/f4/stm32f423Xh.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f427.dtsi b/dts/arm/st/f4/stm32f427.dtsi index 4baf3a1f8317e..0ce973cc21228 100644 --- a/dts/arm/st/f4/stm32f427.dtsi +++ b/dts/arm/st/f4/stm32f427.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Linaro Limited + * Copyright (c) 2025 Mario Paja * * SPDX-License-Identifier: Apache-2.0 */ @@ -111,6 +112,28 @@ status = "disabled"; }; }; + + sai1_a: sai1@40015804 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015804 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 1 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; + + sai1_b: sai1@40015824 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015824 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 5 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; }; die_temp: dietemp { diff --git a/dts/arm/st/f4/stm32f427Xi.dtsi b/dts/arm/st/f4/stm32f427Xi.dtsi index 150607a93bc5e..fd5264e8fd414 100644 --- a/dts/arm/st/f4/stm32f427Xi.dtsi +++ b/dts/arm/st/f4/stm32f427Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f427vi.dtsi b/dts/arm/st/f4/stm32f427vi.dtsi index 06b198a79ef1e..2355bc1603b95 100644 --- a/dts/arm/st/f4/stm32f427vi.dtsi +++ b/dts/arm/st/f4/stm32f427vi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { @@ -26,4 +25,3 @@ }; }; }; - diff --git a/dts/arm/st/f4/stm32f429Xi.dtsi b/dts/arm/st/f4/stm32f429Xi.dtsi index 02cad584de72b..eee3f6d04c9c6 100644 --- a/dts/arm/st/f4/stm32f429Xi.dtsi +++ b/dts/arm/st/f4/stm32f429Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f429vi.dtsi b/dts/arm/st/f4/stm32f429vi.dtsi index b1fd97809e396..3acbf5e0c9838 100644 --- a/dts/arm/st/f4/stm32f429vi.dtsi +++ b/dts/arm/st/f4/stm32f429vi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { @@ -26,4 +25,3 @@ }; }; }; - diff --git a/dts/arm/st/f4/stm32f437Xi.dtsi b/dts/arm/st/f4/stm32f437Xi.dtsi index 23bb97bb8e39e..c64a2e90fa64f 100644 --- a/dts/arm/st/f4/stm32f437Xi.dtsi +++ b/dts/arm/st/f4/stm32f437Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f439Xi.dtsi b/dts/arm/st/f4/stm32f439Xi.dtsi index cc1c6a1276ddf..1dc2f756c7585 100644 --- a/dts/arm/st/f4/stm32f439Xi.dtsi +++ b/dts/arm/st/f4/stm32f439Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f439vi.dtsi b/dts/arm/st/f4/stm32f439vi.dtsi index 837a6cac9d9ec..3c5bd4c99fcf5 100644 --- a/dts/arm/st/f4/stm32f439vi.dtsi +++ b/dts/arm/st/f4/stm32f439vi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f446.dtsi b/dts/arm/st/f4/stm32f446.dtsi index fb5ec329579b4..2ed9145bc09d4 100644 --- a/dts/arm/st/f4/stm32f446.dtsi +++ b/dts/arm/st/f4/stm32f446.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Philémon Jaermann + * Copyright (c) 2025 Mario Paja * * SPDX-License-Identifier: Apache-2.0 */ @@ -169,6 +170,28 @@ status = "disabled"; }; }; + + sai1_a: sai1@40015804 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015804 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 1 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; + + sai1_b: sai1@40015824 { + compatible = "st,stm32-sai"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40015824 0x20>; + clocks = <&rcc STM32_CLOCK(APB2, 22)>; + dmas = <&dma2 5 0 (STM32_DMA_MODE_NORMAL | STM32_DMA_PRIORITY_HIGH | + STM32_DMA_16BITS) 0>; + status = "disabled"; + }; }; die_temp: dietemp { diff --git a/dts/arm/st/f4/stm32f446Xe.dtsi b/dts/arm/st/f4/stm32f446Xe.dtsi index e1c9929ef4d40..5138835338d84 100644 --- a/dts/arm/st/f4/stm32f446Xe.dtsi +++ b/dts/arm/st/f4/stm32f446Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f469Xi.dtsi b/dts/arm/st/f4/stm32f469Xi.dtsi index 87d327d0969f9..3172e37e776eb 100644 --- a/dts/arm/st/f4/stm32f469Xi.dtsi +++ b/dts/arm/st/f4/stm32f469Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f4/stm32f479Xi.dtsi b/dts/arm/st/f4/stm32f479Xi.dtsi index 42eb8c07afe86..4f7db423c8c2e 100644 --- a/dts/arm/st/f4/stm32f479Xi.dtsi +++ b/dts/arm/st/f4/stm32f479Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index ba613c7580b48..b203b93271127 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -21,6 +21,7 @@ #include #include #include +#include / { chosen { @@ -154,7 +155,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40013c00 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 14)>; num-lines = <32>; diff --git a/dts/arm/st/f7/stm32f722Xe.dtsi b/dts/arm/st/f7/stm32f722Xe.dtsi index 79491e4008b0a..5c0e1a1917a48 100644 --- a/dts/arm/st/f7/stm32f722Xe.dtsi +++ b/dts/arm/st/f7/stm32f722Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f723Xe.dtsi b/dts/arm/st/f7/stm32f723Xe.dtsi index 2a7adcd801653..3a22dee1fdca9 100644 --- a/dts/arm/st/f7/stm32f723Xe.dtsi +++ b/dts/arm/st/f7/stm32f723Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f745Xe.dtsi b/dts/arm/st/f7/stm32f745Xe.dtsi index d46f619b2eb70..34d833650bfb7 100644 --- a/dts/arm/st/f7/stm32f745Xe.dtsi +++ b/dts/arm/st/f7/stm32f745Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f745Xg.dtsi b/dts/arm/st/f7/stm32f745Xg.dtsi index 89f3cb466caac..9775527ed794d 100644 --- a/dts/arm/st/f7/stm32f745Xg.dtsi +++ b/dts/arm/st/f7/stm32f745Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f746Xg.dtsi b/dts/arm/st/f7/stm32f746Xg.dtsi index e9257195aa48a..326649657da6e 100644 --- a/dts/arm/st/f7/stm32f746Xg.dtsi +++ b/dts/arm/st/f7/stm32f746Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f750X8.dtsi b/dts/arm/st/f7/stm32f750X8.dtsi index c1e079365da3a..287b99caf18f0 100644 --- a/dts/arm/st/f7/stm32f750X8.dtsi +++ b/dts/arm/st/f7/stm32f750X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f756Xg.dtsi b/dts/arm/st/f7/stm32f756Xg.dtsi index 439b9e7921623..cdde4571c09bf 100644 --- a/dts/arm/st/f7/stm32f756Xg.dtsi +++ b/dts/arm/st/f7/stm32f756Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f765Xg.dtsi b/dts/arm/st/f7/stm32f765Xg.dtsi index 92705145f9a87..d87bda12c69f8 100644 --- a/dts/arm/st/f7/stm32f765Xg.dtsi +++ b/dts/arm/st/f7/stm32f765Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f765Xi.dtsi b/dts/arm/st/f7/stm32f765Xi.dtsi index aad756a60b54f..725ac5a551b56 100644 --- a/dts/arm/st/f7/stm32f765Xi.dtsi +++ b/dts/arm/st/f7/stm32f765Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f767Xi.dtsi b/dts/arm/st/f7/stm32f767Xi.dtsi index c61f223167c80..01d46149bbf47 100644 --- a/dts/arm/st/f7/stm32f767Xi.dtsi +++ b/dts/arm/st/f7/stm32f767Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/f7/stm32f769Xi.dtsi b/dts/arm/st/f7/stm32f769Xi.dtsi index b298165cfb048..3a23c6ab89ff6 100644 --- a/dts/arm/st/f7/stm32f769Xi.dtsi +++ b/dts/arm/st/f7/stm32f769Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index 48d7c55e3d959..28aec6252811b 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -21,6 +21,7 @@ #include #include #include +#include / { chosen { @@ -144,7 +145,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40021800 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/g0/stm32g030X6.dtsi b/dts/arm/st/g0/stm32g030X6.dtsi index d3ac3daf5e6b1..628318b878ccc 100644 --- a/dts/arm/st/g0/stm32g030X6.dtsi +++ b/dts/arm/st/g0/stm32g030X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g030X8.dtsi b/dts/arm/st/g0/stm32g030X8.dtsi index 595584f038228..01eba1a85a52f 100644 --- a/dts/arm/st/g0/stm32g030X8.dtsi +++ b/dts/arm/st/g0/stm32g030X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g031X4.dtsi b/dts/arm/st/g0/stm32g031X4.dtsi index 67d983af816fa..509d7bbb1a21e 100644 --- a/dts/arm/st/g0/stm32g031X4.dtsi +++ b/dts/arm/st/g0/stm32g031X4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g031X6.dtsi b/dts/arm/st/g0/stm32g031X6.dtsi index 10e31f3e1f1b6..573d46f380ebf 100644 --- a/dts/arm/st/g0/stm32g031X6.dtsi +++ b/dts/arm/st/g0/stm32g031X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g031X8.dtsi b/dts/arm/st/g0/stm32g031X8.dtsi index c9fba2028254c..0db744777e437 100644 --- a/dts/arm/st/g0/stm32g031X8.dtsi +++ b/dts/arm/st/g0/stm32g031X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g041X6.dtsi b/dts/arm/st/g0/stm32g041X6.dtsi index d0af1d89d483d..8aed947a94346 100644 --- a/dts/arm/st/g0/stm32g041X6.dtsi +++ b/dts/arm/st/g0/stm32g041X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g041X8.dtsi b/dts/arm/st/g0/stm32g041X8.dtsi index 5c23293d4dc12..9bc433df54b41 100644 --- a/dts/arm/st/g0/stm32g041X8.dtsi +++ b/dts/arm/st/g0/stm32g041X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g050X6.dtsi b/dts/arm/st/g0/stm32g050X6.dtsi index bcb5aecb0977d..94abcd0ea5ff9 100644 --- a/dts/arm/st/g0/stm32g050X6.dtsi +++ b/dts/arm/st/g0/stm32g050X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g050X8.dtsi b/dts/arm/st/g0/stm32g050X8.dtsi index 906332c5d42d7..92a635630a4d1 100644 --- a/dts/arm/st/g0/stm32g050X8.dtsi +++ b/dts/arm/st/g0/stm32g050X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g051X6.dtsi b/dts/arm/st/g0/stm32g051X6.dtsi index 7a84fb6d98433..7c76c640f4df8 100644 --- a/dts/arm/st/g0/stm32g051X6.dtsi +++ b/dts/arm/st/g0/stm32g051X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g051X8.dtsi b/dts/arm/st/g0/stm32g051X8.dtsi index 20df94c4532d2..b2dd1a362a0a9 100644 --- a/dts/arm/st/g0/stm32g051X8.dtsi +++ b/dts/arm/st/g0/stm32g051X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g061X6.dtsi b/dts/arm/st/g0/stm32g061X6.dtsi index 3c1268dfa8c38..e7e7478a37626 100644 --- a/dts/arm/st/g0/stm32g061X6.dtsi +++ b/dts/arm/st/g0/stm32g061X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g061X8.dtsi b/dts/arm/st/g0/stm32g061X8.dtsi index d8d6f5fb0b5df..3a4ebf20b3956 100644 --- a/dts/arm/st/g0/stm32g061X8.dtsi +++ b/dts/arm/st/g0/stm32g061X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g070Xb.dtsi b/dts/arm/st/g0/stm32g070Xb.dtsi index c40b31341864d..6729272b4c7f7 100644 --- a/dts/arm/st/g0/stm32g070Xb.dtsi +++ b/dts/arm/st/g0/stm32g070Xb.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g071X8.dtsi b/dts/arm/st/g0/stm32g071X8.dtsi index 4694a445fbcdd..4bb6648794ac0 100644 --- a/dts/arm/st/g0/stm32g071X8.dtsi +++ b/dts/arm/st/g0/stm32g071X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g071Xb.dtsi b/dts/arm/st/g0/stm32g071Xb.dtsi index 3e437d6bc3c1b..67b9143dd650c 100644 --- a/dts/arm/st/g0/stm32g071Xb.dtsi +++ b/dts/arm/st/g0/stm32g071Xb.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { @@ -20,4 +19,4 @@ }; }; }; -}; \ No newline at end of file +}; diff --git a/dts/arm/st/g0/stm32g081Xb.dtsi b/dts/arm/st/g0/stm32g081Xb.dtsi index 075d8dec25056..88dbeb397f8db 100644 --- a/dts/arm/st/g0/stm32g081Xb.dtsi +++ b/dts/arm/st/g0/stm32g081Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0b0Xe.dtsi b/dts/arm/st/g0/stm32g0b0Xe.dtsi index 2c604b4e215cc..00d28cfdc576a 100644 --- a/dts/arm/st/g0/stm32g0b0Xe.dtsi +++ b/dts/arm/st/g0/stm32g0b0Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0b1Xb.dtsi b/dts/arm/st/g0/stm32g0b1Xb.dtsi index b7903e6615329..c118df530c0e1 100644 --- a/dts/arm/st/g0/stm32g0b1Xb.dtsi +++ b/dts/arm/st/g0/stm32g0b1Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0b1Xc.dtsi b/dts/arm/st/g0/stm32g0b1Xc.dtsi index 1164d9706fbdb..47b957aced2dc 100644 --- a/dts/arm/st/g0/stm32g0b1Xc.dtsi +++ b/dts/arm/st/g0/stm32g0b1Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0b1Xe.dtsi b/dts/arm/st/g0/stm32g0b1Xe.dtsi index 08875cf1af977..45157fb6a6fdf 100644 --- a/dts/arm/st/g0/stm32g0b1Xe.dtsi +++ b/dts/arm/st/g0/stm32g0b1Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0c1Xc.dtsi b/dts/arm/st/g0/stm32g0c1Xc.dtsi index 9e5dbdeb16c63..e56eecf7d1705 100644 --- a/dts/arm/st/g0/stm32g0c1Xc.dtsi +++ b/dts/arm/st/g0/stm32g0c1Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g0/stm32g0c1Xe.dtsi b/dts/arm/st/g0/stm32g0c1Xe.dtsi index b097fa5aae683..56a7b0867e918 100644 --- a/dts/arm/st/g0/stm32g0c1Xe.dtsi +++ b/dts/arm/st/g0/stm32g0c1Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index c34462a25fb17..f8301c5283019 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { chosen { @@ -196,7 +197,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <64>; diff --git a/dts/arm/st/g4/stm32g431X6.dtsi b/dts/arm/st/g4/stm32g431X6.dtsi index 88763de8c639d..94eca168376d8 100644 --- a/dts/arm/st/g4/stm32g431X6.dtsi +++ b/dts/arm/st/g4/stm32g431X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g431X8.dtsi b/dts/arm/st/g4/stm32g431X8.dtsi index 2ffcae57da153..68fb7fdd56a3e 100644 --- a/dts/arm/st/g4/stm32g431X8.dtsi +++ b/dts/arm/st/g4/stm32g431X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g431Xb.dtsi b/dts/arm/st/g4/stm32g431Xb.dtsi index b47afad2ca2db..3412dfb962659 100644 --- a/dts/arm/st/g4/stm32g431Xb.dtsi +++ b/dts/arm/st/g4/stm32g431Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g441Xb.dtsi b/dts/arm/st/g4/stm32g441Xb.dtsi index e5e2a2a1fbbab..e559fc9b15968 100644 --- a/dts/arm/st/g4/stm32g441Xb.dtsi +++ b/dts/arm/st/g4/stm32g441Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g473Xb.dtsi b/dts/arm/st/g4/stm32g473Xb.dtsi index dba276e056396..914efb344f7ac 100644 --- a/dts/arm/st/g4/stm32g473Xb.dtsi +++ b/dts/arm/st/g4/stm32g473Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g473Xc.dtsi b/dts/arm/st/g4/stm32g473Xc.dtsi index 61c30f4b7f1ec..041fcc6a4421d 100644 --- a/dts/arm/st/g4/stm32g473Xc.dtsi +++ b/dts/arm/st/g4/stm32g473Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g473Xe.dtsi b/dts/arm/st/g4/stm32g473Xe.dtsi index 454f2efbe87e2..dfe364ad607fa 100644 --- a/dts/arm/st/g4/stm32g473Xe.dtsi +++ b/dts/arm/st/g4/stm32g473Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g474Xb.dtsi b/dts/arm/st/g4/stm32g474Xb.dtsi index f66a70f01373f..aedf1c4dece70 100644 --- a/dts/arm/st/g4/stm32g474Xb.dtsi +++ b/dts/arm/st/g4/stm32g474Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g474Xc.dtsi b/dts/arm/st/g4/stm32g474Xc.dtsi index e9c6f9b2a8ea4..4dcc96193806f 100644 --- a/dts/arm/st/g4/stm32g474Xc.dtsi +++ b/dts/arm/st/g4/stm32g474Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g474Xe.dtsi b/dts/arm/st/g4/stm32g474Xe.dtsi index a8512d56f3085..cca44161b1f35 100644 --- a/dts/arm/st/g4/stm32g474Xe.dtsi +++ b/dts/arm/st/g4/stm32g474Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g483Xe.dtsi b/dts/arm/st/g4/stm32g483Xe.dtsi index 296f8c1562c8c..b077e15ae6c45 100644 --- a/dts/arm/st/g4/stm32g483Xe.dtsi +++ b/dts/arm/st/g4/stm32g483Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g484Xe.dtsi b/dts/arm/st/g4/stm32g484Xe.dtsi index 49f5edcc80746..94610912094e3 100644 --- a/dts/arm/st/g4/stm32g484Xe.dtsi +++ b/dts/arm/st/g4/stm32g484Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g491Xc.dtsi b/dts/arm/st/g4/stm32g491Xc.dtsi index 07f6f6260cdb1..2698e01e796f5 100644 --- a/dts/arm/st/g4/stm32g491Xc.dtsi +++ b/dts/arm/st/g4/stm32g491Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g491Xe.dtsi b/dts/arm/st/g4/stm32g491Xe.dtsi index 96e5730dcca17..da61ce9fc2056 100644 --- a/dts/arm/st/g4/stm32g491Xe.dtsi +++ b/dts/arm/st/g4/stm32g491Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/g4/stm32g4a1Xe.dtsi b/dts/arm/st/g4/stm32g4a1Xe.dtsi index 8e318ea95c019..32056eb61dd81 100644 --- a/dts/arm/st/g4/stm32g4a1Xe.dtsi +++ b/dts/arm/st/g4/stm32g4a1Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include &sram0 { diff --git a/dts/arm/st/h5/stm32h5.dtsi b/dts/arm/st/h5/stm32h5.dtsi index a40802b2e8af8..25f1db85e8a31 100644 --- a/dts/arm/st/h5/stm32h5.dtsi +++ b/dts/arm/st/h5/stm32h5.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include / { chosen { @@ -162,7 +163,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x44022000 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 1)>; num-lines = <64>; diff --git a/dts/arm/st/h5/stm32h503Xb.dtsi b/dts/arm/st/h5/stm32h503Xb.dtsi index 22fc4d042dfcc..ccdda3a20bbf7 100644 --- a/dts/arm/st/h5/stm32h503Xb.dtsi +++ b/dts/arm/st/h5/stm32h503Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h5/stm32h523Xe.dtsi b/dts/arm/st/h5/stm32h523Xe.dtsi index fc122088d298c..4d1137a6431bc 100644 --- a/dts/arm/st/h5/stm32h523Xe.dtsi +++ b/dts/arm/st/h5/stm32h523Xe.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h5/stm32h533Xe.dtsi b/dts/arm/st/h5/stm32h533Xe.dtsi index 7b3b530f6a7ef..f09a43622b38e 100644 --- a/dts/arm/st/h5/stm32h533Xe.dtsi +++ b/dts/arm/st/h5/stm32h533Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index 065cc6a927781..3e8ff990e9728 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -8,7 +8,6 @@ #include /* keep both header files for compatibility */ #include -#include / { clocks { diff --git a/dts/arm/st/h5/stm32h562Xg.dtsi b/dts/arm/st/h5/stm32h562Xg.dtsi index 969c61d5d9c7f..caf9948001d4f 100644 --- a/dts/arm/st/h5/stm32h562Xg.dtsi +++ b/dts/arm/st/h5/stm32h562Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h5/stm32h563Xi.dtsi b/dts/arm/st/h5/stm32h563Xi.dtsi index d6908b65e8ef1..31f385209853a 100644 --- a/dts/arm/st/h5/stm32h563Xi.dtsi +++ b/dts/arm/st/h5/stm32h563Xi.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h5/stm32h573Xi.dtsi b/dts/arm/st/h5/stm32h573Xi.dtsi index 1a61321a82aaa..88be6598780bf 100644 --- a/dts/arm/st/h5/stm32h573Xi.dtsi +++ b/dts/arm/st/h5/stm32h573Xi.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 1ff9e1aa5892c..a4549f6ba024f 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -23,6 +23,7 @@ #include #include #include +#include / { chosen { @@ -167,7 +168,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x58000000 0x400>; clocks = <&rcc STM32_CLOCK(APB4, 1)>; num-lines = <96>; diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index 961e634bbe1ae..466c0d5b513ad 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include diff --git a/dts/arm/st/h7/stm32h723Xe.dtsi b/dts/arm/st/h7/stm32h723Xe.dtsi index 99c6f2f81f2c8..a13253945c9c5 100644 --- a/dts/arm/st/h7/stm32h723Xe.dtsi +++ b/dts/arm/st/h7/stm32h723Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h723Xg.dtsi b/dts/arm/st/h7/stm32h723Xg.dtsi index 9f18bebfd3795..e094c72e323c3 100644 --- a/dts/arm/st/h7/stm32h723Xg.dtsi +++ b/dts/arm/st/h7/stm32h723Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h725Xe.dtsi b/dts/arm/st/h7/stm32h725Xe.dtsi index 947588898d082..6225bda7fc19c 100644 --- a/dts/arm/st/h7/stm32h725Xe.dtsi +++ b/dts/arm/st/h7/stm32h725Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h725Xg.dtsi b/dts/arm/st/h7/stm32h725Xg.dtsi index 46528b1d2489f..c510798a0b6c2 100644 --- a/dts/arm/st/h7/stm32h725Xg.dtsi +++ b/dts/arm/st/h7/stm32h725Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h730Xb.dtsi b/dts/arm/st/h7/stm32h730Xb.dtsi index 48f67f1331c13..b41a10398da97 100644 --- a/dts/arm/st/h7/stm32h730Xb.dtsi +++ b/dts/arm/st/h7/stm32h730Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h735Xg.dtsi b/dts/arm/st/h7/stm32h735Xg.dtsi index d2644a2d0ca9b..5472079e10481 100644 --- a/dts/arm/st/h7/stm32h735Xg.dtsi +++ b/dts/arm/st/h7/stm32h735Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h742Xg.dtsi b/dts/arm/st/h7/stm32h742Xg.dtsi index 72ba15dd7b08e..fd32aa842b4cc 100644 --- a/dts/arm/st/h7/stm32h742Xg.dtsi +++ b/dts/arm/st/h7/stm32h742Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h742Xi.dtsi b/dts/arm/st/h7/stm32h742Xi.dtsi index f00aad5be1c3b..55da5315021ac 100644 --- a/dts/arm/st/h7/stm32h742Xi.dtsi +++ b/dts/arm/st/h7/stm32h742Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h743Xg.dtsi b/dts/arm/st/h7/stm32h743Xg.dtsi index d90a2e01512e6..06dce761b41e3 100644 --- a/dts/arm/st/h7/stm32h743Xg.dtsi +++ b/dts/arm/st/h7/stm32h743Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h743Xi.dtsi b/dts/arm/st/h7/stm32h743Xi.dtsi index 490185ae2a588..9ab3ef625b3f2 100644 --- a/dts/arm/st/h7/stm32h743Xi.dtsi +++ b/dts/arm/st/h7/stm32h743Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h745Xi_m4.dtsi b/dts/arm/st/h7/stm32h745Xi_m4.dtsi index 8ad4e0f871e75..087241ccb7c26 100644 --- a/dts/arm/st/h7/stm32h745Xi_m4.dtsi +++ b/dts/arm/st/h7/stm32h745Xi_m4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash0; diff --git a/dts/arm/st/h7/stm32h745Xi_m7.dtsi b/dts/arm/st/h7/stm32h745Xi_m7.dtsi index 0e79c0150f352..a529f9e392ad7 100644 --- a/dts/arm/st/h7/stm32h745Xi_m7.dtsi +++ b/dts/arm/st/h7/stm32h745Xi_m7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash1; diff --git a/dts/arm/st/h7/stm32h747Xi_m4.dtsi b/dts/arm/st/h7/stm32h747Xi_m4.dtsi index e8a77592bf96c..6c45ff6882329 100644 --- a/dts/arm/st/h7/stm32h747Xi_m4.dtsi +++ b/dts/arm/st/h7/stm32h747Xi_m4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash0; diff --git a/dts/arm/st/h7/stm32h747Xi_m7.dtsi b/dts/arm/st/h7/stm32h747Xi_m7.dtsi index bc7791dbf8865..13f0d42c504c4 100644 --- a/dts/arm/st/h7/stm32h747Xi_m7.dtsi +++ b/dts/arm/st/h7/stm32h747Xi_m7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash1; diff --git a/dts/arm/st/h7/stm32h750Xb.dtsi b/dts/arm/st/h7/stm32h750Xb.dtsi index 7d77cca87ff8f..89e18cb6eeaf3 100644 --- a/dts/arm/st/h7/stm32h750Xb.dtsi +++ b/dts/arm/st/h7/stm32h750Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h753Xi.dtsi b/dts/arm/st/h7/stm32h753Xi.dtsi index 39e68e90a953f..ee41aab66338b 100644 --- a/dts/arm/st/h7/stm32h753Xi.dtsi +++ b/dts/arm/st/h7/stm32h753Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h755Xi_m4.dtsi b/dts/arm/st/h7/stm32h755Xi_m4.dtsi index 81d3d3da2fc8b..d1317b117f4f4 100644 --- a/dts/arm/st/h7/stm32h755Xi_m4.dtsi +++ b/dts/arm/st/h7/stm32h755Xi_m4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash0; diff --git a/dts/arm/st/h7/stm32h755Xi_m7.dtsi b/dts/arm/st/h7/stm32h755Xi_m7.dtsi index 47d80cb178741..3f2b99e27f924 100644 --- a/dts/arm/st/h7/stm32h755Xi_m7.dtsi +++ b/dts/arm/st/h7/stm32h755Xi_m7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash1; diff --git a/dts/arm/st/h7/stm32h757Xi_m4.dtsi b/dts/arm/st/h7/stm32h757Xi_m4.dtsi index 0d9909a83c664..8f11d7d922d29 100644 --- a/dts/arm/st/h7/stm32h757Xi_m4.dtsi +++ b/dts/arm/st/h7/stm32h757Xi_m4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash0; diff --git a/dts/arm/st/h7/stm32h757Xi_m7.dtsi b/dts/arm/st/h7/stm32h757Xi_m7.dtsi index bf23d7687b3fb..180a10a325e98 100644 --- a/dts/arm/st/h7/stm32h757Xi_m7.dtsi +++ b/dts/arm/st/h7/stm32h757Xi_m7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &flash1; diff --git a/dts/arm/st/h7/stm32h7a3Xi.dtsi b/dts/arm/st/h7/stm32h7a3Xi.dtsi index 6502bf5be15ba..36f136750f033 100644 --- a/dts/arm/st/h7/stm32h7a3Xi.dtsi +++ b/dts/arm/st/h7/stm32h7a3Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h7b0.dtsi b/dts/arm/st/h7/stm32h7b0.dtsi index 556b1fa2e7823..8b039fab4b77b 100644 --- a/dts/arm/st/h7/stm32h7b0.dtsi +++ b/dts/arm/st/h7/stm32h7b0.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /* diff --git a/dts/arm/st/h7/stm32h7b0Xb.dtsi b/dts/arm/st/h7/stm32h7b0Xb.dtsi index 9136d8058cdcd..d851668c536ce 100644 --- a/dts/arm/st/h7/stm32h7b0Xb.dtsi +++ b/dts/arm/st/h7/stm32h7b0Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7/stm32h7b3.dtsi b/dts/arm/st/h7/stm32h7b3.dtsi index f8b583b9d751e..c9fefc9dc99ca 100644 --- a/dts/arm/st/h7/stm32h7b3.dtsi +++ b/dts/arm/st/h7/stm32h7b3.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /* diff --git a/dts/arm/st/h7/stm32h7b3Xi.dtsi b/dts/arm/st/h7/stm32h7b3Xi.dtsi index 7f15bd91f5f65..7257aad0fa96b 100644 --- a/dts/arm/st/h7/stm32h7b3Xi.dtsi +++ b/dts/arm/st/h7/stm32h7b3Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7rs/stm32h7r3.dtsi b/dts/arm/st/h7rs/stm32h7r3.dtsi index 1e18970f134d6..58740b4fc79d4 100644 --- a/dts/arm/st/h7rs/stm32h7r3.dtsi +++ b/dts/arm/st/h7rs/stm32h7r3.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7rs/stm32h7r3X8.dtsi b/dts/arm/st/h7rs/stm32h7r3X8.dtsi index 77e5f728e9499..a6e18c4019e7f 100644 --- a/dts/arm/st/h7rs/stm32h7r3X8.dtsi +++ b/dts/arm/st/h7rs/stm32h7r3X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7rs/stm32h7r7.dtsi b/dts/arm/st/h7rs/stm32h7r7.dtsi index bdc347798c8ca..715cb6eafdd24 100644 --- a/dts/arm/st/h7rs/stm32h7r7.dtsi +++ b/dts/arm/st/h7rs/stm32h7r7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /* diff --git a/dts/arm/st/h7rs/stm32h7r7X8.dtsi b/dts/arm/st/h7rs/stm32h7r7X8.dtsi index 11ac37be01f31..fa233f17513d8 100644 --- a/dts/arm/st/h7rs/stm32h7r7X8.dtsi +++ b/dts/arm/st/h7rs/stm32h7r7X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index 15be4b8c3c18d..313706e57297d 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -19,6 +19,7 @@ #include #include #include +#include /* * STM32H7RS line contains has many common peripherals with STM32H7. @@ -60,6 +61,7 @@ reg = <0x30000000 DT_SIZE_K(16)>; compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "SRAM1"; + zephyr,memory-attr = ; }; /* System data RAM accessible over AHB bus: SRAM2 in D2 domain */ @@ -67,6 +69,11 @@ compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x30004000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAM2"; + /* Disable SRAM2 by default to avoid unintended access. + * To enable it, explicitly define zephyr,memory-attr + * to configure MPU attributes. + */ + status = "disabled"; }; dtcm: memory@20000000 { @@ -209,7 +216,7 @@ compatible = "st,stm32h7rs-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x58000000 0x400>; clocks = <&rcc STM32_CLOCK(APB4, 1)>; /* SBS for interrupt */ diff --git a/dts/arm/st/h7rs/stm32h7s3.dtsi b/dts/arm/st/h7rs/stm32h7s3.dtsi index f1d490266b7dd..3fd358c1d60ab 100644 --- a/dts/arm/st/h7rs/stm32h7s3.dtsi +++ b/dts/arm/st/h7rs/stm32h7s3.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /* diff --git a/dts/arm/st/h7rs/stm32h7s3X8.dtsi b/dts/arm/st/h7rs/stm32h7s3X8.dtsi index bd450eb04824b..7e28014171fb0 100644 --- a/dts/arm/st/h7rs/stm32h7s3X8.dtsi +++ b/dts/arm/st/h7rs/stm32h7s3X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/h7rs/stm32h7s7.dtsi b/dts/arm/st/h7rs/stm32h7s7.dtsi index 7566df2cfe9c8..7d949d84bdca2 100644 --- a/dts/arm/st/h7rs/stm32h7s7.dtsi +++ b/dts/arm/st/h7rs/stm32h7s7.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /* diff --git a/dts/arm/st/h7rs/stm32h7s7X8.dtsi b/dts/arm/st/h7rs/stm32h7s7X8.dtsi index aa4b805793801..78d0890ee1d14 100644 --- a/dts/arm/st/h7rs/stm32h7s7X8.dtsi +++ b/dts/arm/st/h7rs/stm32h7s7X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l0.dtsi b/dts/arm/st/l0/stm32l0.dtsi index ef3003d46dbf6..985de6324e0b0 100644 --- a/dts/arm/st/l0/stm32l0.dtsi +++ b/dts/arm/st/l0/stm32l0.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include / { chosen { @@ -144,7 +145,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/l0/stm32l010X4.dtsi b/dts/arm/st/l0/stm32l010X4.dtsi index e9cfbca6d040a..fa823b934ebcd 100644 --- a/dts/arm/st/l0/stm32l010X4.dtsi +++ b/dts/arm/st/l0/stm32l010X4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l010X6.dtsi b/dts/arm/st/l0/stm32l010X6.dtsi index 94fd9694a2fdd..1b5762fef583b 100644 --- a/dts/arm/st/l0/stm32l010X6.dtsi +++ b/dts/arm/st/l0/stm32l010X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l010X8.dtsi b/dts/arm/st/l0/stm32l010X8.dtsi index 2084b779767d7..0996c32d88746 100644 --- a/dts/arm/st/l0/stm32l010X8.dtsi +++ b/dts/arm/st/l0/stm32l010X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l010Xb.dtsi b/dts/arm/st/l0/stm32l010Xb.dtsi index 16911c6efdd13..b44f88ec480a7 100644 --- a/dts/arm/st/l0/stm32l010Xb.dtsi +++ b/dts/arm/st/l0/stm32l010Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l011X4.dtsi b/dts/arm/st/l0/stm32l011X4.dtsi index 1ed58b1dc2ffe..ae4b3631204ef 100644 --- a/dts/arm/st/l0/stm32l011X4.dtsi +++ b/dts/arm/st/l0/stm32l011X4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l031X6.dtsi b/dts/arm/st/l0/stm32l031X6.dtsi index 80bea705c5f71..3d204e1fd823e 100644 --- a/dts/arm/st/l0/stm32l031X6.dtsi +++ b/dts/arm/st/l0/stm32l031X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l051X6.dtsi b/dts/arm/st/l0/stm32l051X6.dtsi index 5dff4e3e00834..d8ee80fd64389 100644 --- a/dts/arm/st/l0/stm32l051X6.dtsi +++ b/dts/arm/st/l0/stm32l051X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l051X8.dtsi b/dts/arm/st/l0/stm32l051X8.dtsi index 34fb63d97cd28..56b74a1cdea3a 100644 --- a/dts/arm/st/l0/stm32l051X8.dtsi +++ b/dts/arm/st/l0/stm32l051X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { @@ -20,4 +19,3 @@ }; }; }; - diff --git a/dts/arm/st/l0/stm32l053X8.dtsi b/dts/arm/st/l0/stm32l053X8.dtsi index 52f9dade965c5..2f797f079e287 100644 --- a/dts/arm/st/l0/stm32l053X8.dtsi +++ b/dts/arm/st/l0/stm32l053X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l071X8.dtsi b/dts/arm/st/l0/stm32l071X8.dtsi index 4f0fe482c0fee..4c791cda9fa34 100644 --- a/dts/arm/st/l0/stm32l071X8.dtsi +++ b/dts/arm/st/l0/stm32l071X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l071Xb.dtsi b/dts/arm/st/l0/stm32l071Xb.dtsi index 83e4efcc24da9..b2747cd49eccd 100644 --- a/dts/arm/st/l0/stm32l071Xb.dtsi +++ b/dts/arm/st/l0/stm32l071Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l071Xz.dtsi b/dts/arm/st/l0/stm32l071Xz.dtsi index 78566a5d62b1d..e9d425dc7e9ff 100644 --- a/dts/arm/st/l0/stm32l071Xz.dtsi +++ b/dts/arm/st/l0/stm32l071Xz.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l072Xz.dtsi b/dts/arm/st/l0/stm32l072Xz.dtsi index e30ac5d3d1e7b..38b14c4fa6121 100644 --- a/dts/arm/st/l0/stm32l072Xz.dtsi +++ b/dts/arm/st/l0/stm32l072Xz.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l073Xz.dtsi b/dts/arm/st/l0/stm32l073Xz.dtsi index 27f6a57fe79be..7b57194ecd6c2 100644 --- a/dts/arm/st/l0/stm32l073Xz.dtsi +++ b/dts/arm/st/l0/stm32l073Xz.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l081Xz.dtsi b/dts/arm/st/l0/stm32l081Xz.dtsi index d6f28ceecceb4..f76f31da7bb35 100644 --- a/dts/arm/st/l0/stm32l081Xz.dtsi +++ b/dts/arm/st/l0/stm32l081Xz.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l0/stm32l083Xz.dtsi b/dts/arm/st/l0/stm32l083Xz.dtsi index 0166c972c0dde..31b412284db38 100644 --- a/dts/arm/st/l0/stm32l083Xz.dtsi +++ b/dts/arm/st/l0/stm32l083Xz.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l1/stm32l1.dtsi b/dts/arm/st/l1/stm32l1.dtsi index f39e36e0ea853..92a32695fae5b 100644 --- a/dts/arm/st/l1/stm32l1.dtsi +++ b/dts/arm/st/l1/stm32l1.dtsi @@ -19,6 +19,7 @@ #include #include #include +#include / { chosen { @@ -290,7 +291,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/l1/stm32l100Xb.dtsi b/dts/arm/st/l1/stm32l100Xb.dtsi index db0a128bdf588..65f48486dd4ea 100644 --- a/dts/arm/st/l1/stm32l100Xb.dtsi +++ b/dts/arm/st/l1/stm32l100Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l1/stm32l151X8-a.dtsi b/dts/arm/st/l1/stm32l151X8-a.dtsi index 90a7e59eecf33..dca7ae0840d06 100644 --- a/dts/arm/st/l1/stm32l151X8-a.dtsi +++ b/dts/arm/st/l1/stm32l151X8-a.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l1/stm32l151Xb-a.dtsi b/dts/arm/st/l1/stm32l151Xb-a.dtsi index 8c06bec299cd5..24e971e04d945 100644 --- a/dts/arm/st/l1/stm32l151Xb-a.dtsi +++ b/dts/arm/st/l1/stm32l151Xb-a.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l1/stm32l151Xb.dtsi b/dts/arm/st/l1/stm32l151Xb.dtsi index b98578b315145..eed574245e284 100644 --- a/dts/arm/st/l1/stm32l151Xb.dtsi +++ b/dts/arm/st/l1/stm32l151Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l1/stm32l151Xc.dtsi b/dts/arm/st/l1/stm32l151Xc.dtsi index a5fbb0fb93396..210f29b63b841 100644 --- a/dts/arm/st/l1/stm32l151Xc.dtsi +++ b/dts/arm/st/l1/stm32l151Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/l1/stm32l152Xc.dtsi b/dts/arm/st/l1/stm32l152Xc.dtsi index 8665396ccf743..227b85127dcba 100644 --- a/dts/arm/st/l1/stm32l152Xc.dtsi +++ b/dts/arm/st/l1/stm32l152Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/l1/stm32l152Xe.dtsi b/dts/arm/st/l1/stm32l152Xe.dtsi index 09187903342ea..92cb29ef00182 100644 --- a/dts/arm/st/l1/stm32l152Xe.dtsi +++ b/dts/arm/st/l1/stm32l152Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index 025bb3279b51a..f1a87034f1817 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { chosen { @@ -158,7 +159,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40010400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <64>; diff --git a/dts/arm/st/l4/stm32l412X8.dtsi b/dts/arm/st/l4/stm32l412X8.dtsi index 9c66aa8ed6889..3114dc989025d 100644 --- a/dts/arm/st/l4/stm32l412X8.dtsi +++ b/dts/arm/st/l4/stm32l412X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l412XB.dtsi b/dts/arm/st/l4/stm32l412XB.dtsi index 438e15a254731..00ddd72f10338 100644 --- a/dts/arm/st/l4/stm32l412XB.dtsi +++ b/dts/arm/st/l4/stm32l412XB.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l422Xb.dtsi b/dts/arm/st/l4/stm32l422Xb.dtsi index 3284865f70d22..87c769364a3ba 100644 --- a/dts/arm/st/l4/stm32l422Xb.dtsi +++ b/dts/arm/st/l4/stm32l422Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l431Xb.dtsi b/dts/arm/st/l4/stm32l431Xb.dtsi index 75331215ea7d7..c423260da60c9 100644 --- a/dts/arm/st/l4/stm32l431Xb.dtsi +++ b/dts/arm/st/l4/stm32l431Xb.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l431Xc.dtsi b/dts/arm/st/l4/stm32l431Xc.dtsi index c1c382504e597..3ff9140a21312 100644 --- a/dts/arm/st/l4/stm32l431Xc.dtsi +++ b/dts/arm/st/l4/stm32l431Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l432Xc.dtsi b/dts/arm/st/l4/stm32l432Xc.dtsi index 59b6e23cb438d..eb59936d0ded1 100644 --- a/dts/arm/st/l4/stm32l432Xc.dtsi +++ b/dts/arm/st/l4/stm32l432Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l433Xb.dtsi b/dts/arm/st/l4/stm32l433Xb.dtsi index 0c0a1044ac66d..7736a011bc049 100644 --- a/dts/arm/st/l4/stm32l433Xb.dtsi +++ b/dts/arm/st/l4/stm32l433Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l433Xc.dtsi b/dts/arm/st/l4/stm32l433Xc.dtsi index 8dc414720ef2b..280b7c216b674 100644 --- a/dts/arm/st/l4/stm32l433Xc.dtsi +++ b/dts/arm/st/l4/stm32l433Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l451Xc.dtsi b/dts/arm/st/l4/stm32l451Xc.dtsi index 1eaeaf76a5caa..38809bed88a8b 100644 --- a/dts/arm/st/l4/stm32l451Xc.dtsi +++ b/dts/arm/st/l4/stm32l451Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l451Xe.dtsi b/dts/arm/st/l4/stm32l451Xe.dtsi index e9eccfa6f9a12..139dfe520cc29 100644 --- a/dts/arm/st/l4/stm32l451Xe.dtsi +++ b/dts/arm/st/l4/stm32l451Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l452Xc.dtsi b/dts/arm/st/l4/stm32l452Xc.dtsi index 8b35e5442d2fc..8416bb2e16d87 100644 --- a/dts/arm/st/l4/stm32l452Xc.dtsi +++ b/dts/arm/st/l4/stm32l452Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l452Xe.dtsi b/dts/arm/st/l4/stm32l452Xe.dtsi index 619cbb72c2265..1ea24fff3aeb4 100644 --- a/dts/arm/st/l4/stm32l452Xe.dtsi +++ b/dts/arm/st/l4/stm32l452Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l462Xe.dtsi b/dts/arm/st/l4/stm32l462Xe.dtsi index d73342bb408b4..0fc5996d6fde9 100644 --- a/dts/arm/st/l4/stm32l462Xe.dtsi +++ b/dts/arm/st/l4/stm32l462Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l471Xg.dtsi b/dts/arm/st/l4/stm32l471Xg.dtsi index 91ee767080517..18a00366f4870 100644 --- a/dts/arm/st/l4/stm32l471Xg.dtsi +++ b/dts/arm/st/l4/stm32l471Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l475Xe.dtsi b/dts/arm/st/l4/stm32l475Xe.dtsi index 2c99d3c4b3d21..703db40b9ba37 100644 --- a/dts/arm/st/l4/stm32l475Xe.dtsi +++ b/dts/arm/st/l4/stm32l475Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l475Xg.dtsi b/dts/arm/st/l4/stm32l475Xg.dtsi index a4d959a841c48..49f66535319ac 100644 --- a/dts/arm/st/l4/stm32l475Xg.dtsi +++ b/dts/arm/st/l4/stm32l475Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l476Xg.dtsi b/dts/arm/st/l4/stm32l476Xg.dtsi index 4ed441f715978..f5b02f4f3e9f2 100644 --- a/dts/arm/st/l4/stm32l476Xg.dtsi +++ b/dts/arm/st/l4/stm32l476Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l486Xg.dtsi b/dts/arm/st/l4/stm32l486Xg.dtsi index b3b01dc1cb0ad..99da8f147854d 100644 --- a/dts/arm/st/l4/stm32l486Xg.dtsi +++ b/dts/arm/st/l4/stm32l486Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l496Xe.dtsi b/dts/arm/st/l4/stm32l496Xe.dtsi index 030b17453bf51..b1dce6479344c 100644 --- a/dts/arm/st/l4/stm32l496Xe.dtsi +++ b/dts/arm/st/l4/stm32l496Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l496Xg.dtsi b/dts/arm/st/l4/stm32l496Xg.dtsi index 935f98c392967..786f55035f668 100644 --- a/dts/arm/st/l4/stm32l496Xg.dtsi +++ b/dts/arm/st/l4/stm32l496Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l4a6Xg.dtsi b/dts/arm/st/l4/stm32l4a6Xg.dtsi index 8c5f033100c89..111e83ecd0e0c 100644 --- a/dts/arm/st/l4/stm32l4a6Xg.dtsi +++ b/dts/arm/st/l4/stm32l4a6Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l4p5.dtsi b/dts/arm/st/l4/stm32l4p5.dtsi index 7801a1b43b856..dae55b11d62ce 100644 --- a/dts/arm/st/l4/stm32l4p5.dtsi +++ b/dts/arm/st/l4/stm32l4p5.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include diff --git a/dts/arm/st/l4/stm32l4p5Xi.dtsi b/dts/arm/st/l4/stm32l4p5Xi.dtsi index de4d6e4351bf9..3c865424aeef4 100644 --- a/dts/arm/st/l4/stm32l4p5Xi.dtsi +++ b/dts/arm/st/l4/stm32l4p5Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l4r5.dtsi b/dts/arm/st/l4/stm32l4r5.dtsi index 675562a9cc8b4..edb1be954e23d 100644 --- a/dts/arm/st/l4/stm32l4r5.dtsi +++ b/dts/arm/st/l4/stm32l4r5.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include /delete-node/ &sdmmc2; diff --git a/dts/arm/st/l4/stm32l4r5Xi.dtsi b/dts/arm/st/l4/stm32l4r5Xi.dtsi index b5318d1e40d85..1c599f6c3adc4 100644 --- a/dts/arm/st/l4/stm32l4r5Xi.dtsi +++ b/dts/arm/st/l4/stm32l4r5Xi.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l4r9.dtsi b/dts/arm/st/l4/stm32l4r9.dtsi index 1f89d00f21e0f..6ab7cf4ba4a3f 100644 --- a/dts/arm/st/l4/stm32l4r9.dtsi +++ b/dts/arm/st/l4/stm32l4r9.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include diff --git a/dts/arm/st/l4/stm32l4r9Xi.dtsi b/dts/arm/st/l4/stm32l4r9Xi.dtsi index 82fe423ed12c1..d258cd9fa88ce 100644 --- a/dts/arm/st/l4/stm32l4r9Xi.dtsi +++ b/dts/arm/st/l4/stm32l4r9Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l4/stm32l4s5Xi.dtsi b/dts/arm/st/l4/stm32l4s5Xi.dtsi index 870b1d8c7ac34..da64e29d0b818 100644 --- a/dts/arm/st/l4/stm32l4s5Xi.dtsi +++ b/dts/arm/st/l4/stm32l4s5Xi.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 5bdc447cd360e..e5dd9c38dbac1 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { chosen { @@ -170,6 +171,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; + #address-cells = <0>; reg = <0x4000f400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 0)>; num-lines = <64>; diff --git a/dts/arm/st/l5/stm32l552Xc.dtsi b/dts/arm/st/l5/stm32l552Xc.dtsi index 49747ff65f6b6..56e18b1202f56 100644 --- a/dts/arm/st/l5/stm32l552Xc.dtsi +++ b/dts/arm/st/l5/stm32l552Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l5/stm32l552Xe.dtsi b/dts/arm/st/l5/stm32l552Xe.dtsi index a5634a7319e46..9312656918e4f 100644 --- a/dts/arm/st/l5/stm32l552Xe.dtsi +++ b/dts/arm/st/l5/stm32l552Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/l5/stm32l562Xe.dtsi b/dts/arm/st/l5/stm32l562Xe.dtsi index b0216949a2541..73e11c5b9c605 100644 --- a/dts/arm/st/l5/stm32l562Xe.dtsi +++ b/dts/arm/st/l5/stm32l562Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/mp1/stm32mp157.dtsi b/dts/arm/st/mp1/stm32mp157.dtsi index 76d506ddbc5b6..8ccd29f28a95a 100644 --- a/dts/arm/st/mp1/stm32mp157.dtsi +++ b/dts/arm/st/mp1/stm32mp157.dtsi @@ -70,7 +70,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x5000d000 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 11)>; num-lines = <96>; diff --git a/dts/arm/st/mp13/stm32mp13.dtsi b/dts/arm/st/mp13/stm32mp13.dtsi index 60f69adb126fe..d9a4a8be9552c 100644 --- a/dts/arm/st/mp13/stm32mp13.dtsi +++ b/dts/arm/st/mp13/stm32mp13.dtsi @@ -152,7 +152,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x5000D000 0x400>; clocks = <&rcc STM32_CLOCK(APB3_S, 0)>; num-lines = <96>; diff --git a/dts/arm/st/mp2/stm32mp2_m33.dtsi b/dts/arm/st/mp2/stm32mp2_m33.dtsi index 9bf80bf93e4ac..711e62706f722 100644 --- a/dts/arm/st/mp2/stm32mp2_m33.dtsi +++ b/dts/arm/st/mp2/stm32mp2_m33.dtsi @@ -51,7 +51,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x46230000 DT_SIZE_K(1)>; num-lines = <77>; interrupts = <17 0>, <18 0>, <19 0>, <20 0>, diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index a61a70f7ed366..e3df2576ccfc8 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -18,6 +18,7 @@ #include #include #include +#include / { cpus { @@ -311,7 +312,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x56025000 0x400>; clocks = <&rcc STM32_CLOCK(APB4_2, 0)>; num-lines = <96>; diff --git a/dts/arm/st/n6/stm32n657X0.dtsi b/dts/arm/st/n6/stm32n657X0.dtsi index ab4cb6f326024..24bcd31fa635e 100644 --- a/dts/arm/st/n6/stm32n657X0.dtsi +++ b/dts/arm/st/n6/stm32n657X0.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u0.dtsi b/dts/arm/st/u0/stm32u0.dtsi index a3937f138dc59..54783cec47c0d 100644 --- a/dts/arm/st/u0/stm32u0.dtsi +++ b/dts/arm/st/u0/stm32u0.dtsi @@ -15,6 +15,7 @@ #include #include #include +#include / { chosen { @@ -148,7 +149,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40021800 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 0)>; num-lines = <32>; diff --git a/dts/arm/st/u0/stm32u031X4.dtsi b/dts/arm/st/u0/stm32u031X4.dtsi index e52e8e22b7bd7..93b3f6fe32003 100644 --- a/dts/arm/st/u0/stm32u031X4.dtsi +++ b/dts/arm/st/u0/stm32u031X4.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u031X6.dtsi b/dts/arm/st/u0/stm32u031X6.dtsi index d71acf7f465bd..b9ef115660d38 100644 --- a/dts/arm/st/u0/stm32u031X6.dtsi +++ b/dts/arm/st/u0/stm32u031X6.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u031X8.dtsi b/dts/arm/st/u0/stm32u031X8.dtsi index 6a47d7f8161a8..0257bf5683ae9 100644 --- a/dts/arm/st/u0/stm32u031X8.dtsi +++ b/dts/arm/st/u0/stm32u031X8.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u073X8.dtsi b/dts/arm/st/u0/stm32u073X8.dtsi index d64eb0a55466c..058afe1b21b01 100644 --- a/dts/arm/st/u0/stm32u073X8.dtsi +++ b/dts/arm/st/u0/stm32u073X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u073Xb.dtsi b/dts/arm/st/u0/stm32u073Xb.dtsi index 25d61bd89fcbe..78462ad14e24a 100644 --- a/dts/arm/st/u0/stm32u073Xb.dtsi +++ b/dts/arm/st/u0/stm32u073Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u073Xc.dtsi b/dts/arm/st/u0/stm32u073Xc.dtsi index 196de255dbd8f..cba0775be2fd5 100644 --- a/dts/arm/st/u0/stm32u073Xc.dtsi +++ b/dts/arm/st/u0/stm32u073Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u0/stm32u083Xc.dtsi b/dts/arm/st/u0/stm32u083Xc.dtsi index 3c0586ca8681e..0fc78f3ef442d 100644 --- a/dts/arm/st/u0/stm32u083Xc.dtsi +++ b/dts/arm/st/u0/stm32u083Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u3/stm32u3.dtsi b/dts/arm/st/u3/stm32u3.dtsi index 5f5f97a7747b5..8318ac221d1e8 100644 --- a/dts/arm/st/u3/stm32u3.dtsi +++ b/dts/arm/st/u3/stm32u3.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include / { chosen { @@ -123,7 +124,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x40032000 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 1)>; num-lines = <22>; diff --git a/dts/arm/st/u3/stm32u385Xg.dtsi b/dts/arm/st/u3/stm32u385Xg.dtsi index e10914ffbd642..6367bd21e210f 100644 --- a/dts/arm/st/u3/stm32u385Xg.dtsi +++ b/dts/arm/st/u3/stm32u385Xg.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 3f9106d89ca0e..5d6911698cd92 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -21,6 +21,7 @@ #include #include #include +#include / { chosen { @@ -194,7 +195,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x46022000 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 1)>; num-lines = <32>; diff --git a/dts/arm/st/u5/stm32u535Xb.dtsi b/dts/arm/st/u5/stm32u535Xb.dtsi index b4d0ab0705980..97fcd30dfd177 100644 --- a/dts/arm/st/u5/stm32u535Xb.dtsi +++ b/dts/arm/st/u5/stm32u535Xb.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u535Xc.dtsi b/dts/arm/st/u5/stm32u535Xc.dtsi index 79fc4d6259486..59be842460e39 100644 --- a/dts/arm/st/u5/stm32u535Xc.dtsi +++ b/dts/arm/st/u5/stm32u535Xc.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u535Xe.dtsi b/dts/arm/st/u5/stm32u535Xe.dtsi index 3586d633dbaa9..18ae5dfd34363 100644 --- a/dts/arm/st/u5/stm32u535Xe.dtsi +++ b/dts/arm/st/u5/stm32u535Xe.dtsi @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u545Xe.dtsi b/dts/arm/st/u5/stm32u545Xe.dtsi index e3af68d2ddb01..65722ac82d227 100644 --- a/dts/arm/st/u5/stm32u545Xe.dtsi +++ b/dts/arm/st/u5/stm32u545Xe.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u575Xg.dtsi b/dts/arm/st/u5/stm32u575Xg.dtsi index 110897534d234..a42dc1fb5ab23 100644 --- a/dts/arm/st/u5/stm32u575Xg.dtsi +++ b/dts/arm/st/u5/stm32u575Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u575Xi.dtsi b/dts/arm/st/u5/stm32u575Xi.dtsi index 77223f3e9546f..e063caebb14b0 100644 --- a/dts/arm/st/u5/stm32u575Xi.dtsi +++ b/dts/arm/st/u5/stm32u575Xi.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u585Xi.dtsi b/dts/arm/st/u5/stm32u585Xi.dtsi index fc2dedbf86f62..9153fc5f27428 100644 --- a/dts/arm/st/u5/stm32u585Xi.dtsi +++ b/dts/arm/st/u5/stm32u585Xi.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u595Xi.dtsi b/dts/arm/st/u5/stm32u595Xi.dtsi index 549bcc7df9e59..2c305554f3029 100644 --- a/dts/arm/st/u5/stm32u595Xi.dtsi +++ b/dts/arm/st/u5/stm32u595Xi.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u595Xj.dtsi b/dts/arm/st/u5/stm32u595Xj.dtsi index 97b64bebec0c1..8a5e65f8123e9 100644 --- a/dts/arm/st/u5/stm32u595Xj.dtsi +++ b/dts/arm/st/u5/stm32u595Xj.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u599.dtsi b/dts/arm/st/u5/stm32u599.dtsi index 4cb5fbd902df7..0236903fc16ec 100644 --- a/dts/arm/st/u5/stm32u599.dtsi +++ b/dts/arm/st/u5/stm32u599.dtsi @@ -10,7 +10,6 @@ #include #include #include -#include / { soc { diff --git a/dts/arm/st/u5/stm32u599Xi.dtsi b/dts/arm/st/u5/stm32u599Xi.dtsi index be05acee34481..52e995ada337f 100644 --- a/dts/arm/st/u5/stm32u599Xi.dtsi +++ b/dts/arm/st/u5/stm32u599Xi.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u599Xj.dtsi b/dts/arm/st/u5/stm32u599Xj.dtsi index fb2c69c4397c4..6fbc82dfcb8d6 100644 --- a/dts/arm/st/u5/stm32u599Xj.dtsi +++ b/dts/arm/st/u5/stm32u599Xj.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u5a5Xj.dtsi b/dts/arm/st/u5/stm32u5a5Xj.dtsi index 2a1e265c6f7c4..734119744622e 100644 --- a/dts/arm/st/u5/stm32u5a5Xj.dtsi +++ b/dts/arm/st/u5/stm32u5a5Xj.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u5a9Xj.dtsi b/dts/arm/st/u5/stm32u5a9Xj.dtsi index 7d89265da7747..662589de09148 100644 --- a/dts/arm/st/u5/stm32u5a9Xj.dtsi +++ b/dts/arm/st/u5/stm32u5a9Xj.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/u5/stm32u5g9Xj.dtsi b/dts/arm/st/u5/stm32u5g9Xj.dtsi index f1df71d48eec5..f06c7d388644d 100644 --- a/dts/arm/st/u5/stm32u5g9Xj.dtsi +++ b/dts/arm/st/u5/stm32u5g9Xj.dtsi @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index 2222ef33b82f9..a049374f7035a 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -18,6 +18,7 @@ #include #include #include +#include / { chosen { @@ -178,7 +179,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x58000800 0x400>; num-lines = <64>; interrupts = <6 0>, <7 0>, <8 0>, <9 0>, diff --git a/dts/arm/st/wb/stm32wb55Xg.dtsi b/dts/arm/st/wb/stm32wb55Xg.dtsi index 0e4a2220038cf..27724e5288513 100644 --- a/dts/arm/st/wb/stm32wb55Xg.dtsi +++ b/dts/arm/st/wb/stm32wb55Xg.dtsi @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index 2a543b094faa2..f73f73c418788 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -16,6 +16,7 @@ #include #include #include +#include / { chosen { @@ -225,6 +226,7 @@ compatible = "st,stm32g0-exti", "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; + #address-cells = <0>; reg = <0x46022000 0x400>; clocks = <&rcc STM32_CLOCK(APB7, 1)>; num-lines = <32>; diff --git a/dts/arm/st/wba/stm32wba52Xg.dtsi b/dts/arm/st/wba/stm32wba52Xg.dtsi index ecae645171b4a..e32ede0efdd4a 100644 --- a/dts/arm/st/wba/stm32wba52Xg.dtsi +++ b/dts/arm/st/wba/stm32wba52Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wba/stm32wba55Xg.dtsi b/dts/arm/st/wba/stm32wba55Xg.dtsi index f5c23f031e958..26b44848eccff 100644 --- a/dts/arm/st/wba/stm32wba55Xg.dtsi +++ b/dts/arm/st/wba/stm32wba55Xg.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wba/stm32wba65.dtsi b/dts/arm/st/wba/stm32wba65.dtsi index cd9be8afae588..177d572c8b8bd 100644 --- a/dts/arm/st/wba/stm32wba65.dtsi +++ b/dts/arm/st/wba/stm32wba65.dtsi @@ -77,6 +77,25 @@ #pwm-cells = <3>; }; }; + + usbotg_hs: usb@42040000 { + compatible = "st,stm32-otghs"; + reg = <0x42040000 DT_SIZE_K(128)>; + interrupts = <76 0>; + interrupt-names = "otghs"; + num-bidir-endpoints = <9>; + ram-size = <4096>; + clocks = <&rcc STM32_CLOCK(AHB2, 14)>; + phys = <&otghs_phy>; + status = "disabled"; + }; + }; + + otghs_phy: otghs_phy { + compatible = "st,stm32u5-otghs-phy"; + clocks = <&rcc STM32_CLOCK(AHB2, 15)>; + #phy-cells = <0>; + status = "disabled"; }; /* diff --git a/dts/arm/st/wba/stm32wba65Xi.dtsi b/dts/arm/st/wba/stm32wba65Xi.dtsi index 422ae59aa3bdd..c348c81f339d5 100644 --- a/dts/arm/st/wba/stm32wba65Xi.dtsi +++ b/dts/arm/st/wba/stm32wba65Xi.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index 3f5fd71368f53..a81aa26db4492 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include / { chosen { @@ -150,7 +151,7 @@ compatible = "st,stm32-exti"; interrupt-controller; #interrupt-cells = <1>; - #address-cells = <1>; + #address-cells = <0>; reg = <0x58000800 0x400>; clocks = <&rcc STM32_CLOCK(APB0, 8)>; num-lines = <64>; diff --git a/dts/arm/st/wl/stm32wl54Xc.dtsi b/dts/arm/st/wl/stm32wl54Xc.dtsi index a7c64b9a9dccf..bb50ec471b321 100644 --- a/dts/arm/st/wl/stm32wl54Xc.dtsi +++ b/dts/arm/st/wl/stm32wl54Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wl55Xc.dtsi b/dts/arm/st/wl/stm32wl55Xc.dtsi index 7c32ca481ae68..573e5758507b4 100644 --- a/dts/arm/st/wl/stm32wl55Xc.dtsi +++ b/dts/arm/st/wl/stm32wl55Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle4X8.dtsi b/dts/arm/st/wl/stm32wle4X8.dtsi index 925c00a5021a2..70a6fec56f13f 100644 --- a/dts/arm/st/wl/stm32wle4X8.dtsi +++ b/dts/arm/st/wl/stm32wle4X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle4Xb.dtsi b/dts/arm/st/wl/stm32wle4Xb.dtsi index 95679802821e0..b5823308ce192 100644 --- a/dts/arm/st/wl/stm32wle4Xb.dtsi +++ b/dts/arm/st/wl/stm32wle4Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle4Xc.dtsi b/dts/arm/st/wl/stm32wle4Xc.dtsi index 2b47872d42723..5920be01c4584 100644 --- a/dts/arm/st/wl/stm32wle4Xc.dtsi +++ b/dts/arm/st/wl/stm32wle4Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle5X8.dtsi b/dts/arm/st/wl/stm32wle5X8.dtsi index 925c00a5021a2..70a6fec56f13f 100644 --- a/dts/arm/st/wl/stm32wle5X8.dtsi +++ b/dts/arm/st/wl/stm32wle5X8.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle5Xb.dtsi b/dts/arm/st/wl/stm32wle5Xb.dtsi index 95679802821e0..b5823308ce192 100644 --- a/dts/arm/st/wl/stm32wle5Xb.dtsi +++ b/dts/arm/st/wl/stm32wle5Xb.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm/st/wl/stm32wle5Xc.dtsi b/dts/arm/st/wl/stm32wle5Xc.dtsi index 2b47872d42723..5920be01c4584 100644 --- a/dts/arm/st/wl/stm32wle5Xc.dtsi +++ b/dts/arm/st/wl/stm32wle5Xc.dtsi @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include / { diff --git a/dts/arm64/nxp/nxp_mimx9131.dtsi b/dts/arm64/nxp/nxp_mimx9131.dtsi index 5bb1e158401b5..37a0850b489e5 100644 --- a/dts/arm64/nxp/nxp_mimx9131.dtsi +++ b/dts/arm64/nxp/nxp_mimx9131.dtsi @@ -240,6 +240,32 @@ status = "disabled"; }; + usdhc1: usdhc@42850000 { + compatible = "nxp,imx-usdhc"; + reg = <0x42850000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_USDHC1_CLK 0 0>; + max-current-330 = <1020>; + max-current-180 = <1020>; + max-bus-freq = <208000000>; + min-bus-freq = <400000>; + status = "disabled"; + }; + + usdhc2: usdhc@42860000 { + compatible = "nxp,imx-usdhc"; + reg = <0x42860000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_USDHC2_CLK 0 0>; + max-current-330 = <1020>; + max-current-180 = <1020>; + max-bus-freq = <208000000>; + min-bus-freq = <400000>; + status = "disabled"; + }; + tpm1: tpm@44310000 { compatible = "nxp,tpm-timer"; reg = <0x44310000 DT_SIZE_K(64)>; diff --git a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi index 92c02faa1b00f..a50ceb37ee9ee 100644 --- a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi +++ b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi @@ -855,6 +855,44 @@ status = "disabled"; }; + spi0: spi@1004ac00 { + compatible = "renesas,rz-rspi"; + reg = <0x1004ac00 DT_SIZE_K(1)>; + interrupts = , + , + ; + interrupt-names = "rx", "tx", "error"; + channel = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@1004b000 { + compatible = "renesas,rz-rspi"; + reg = <0x1004b000 DT_SIZE_K(1)>; + interrupts = , + , + ; + interrupt-names = "rx", "tx", "error"; + channel = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@1004b400 { + compatible = "renesas,rz-rspi"; + reg = <0x1004b400 DT_SIZE_K(1)>; + interrupts = , + , + ; + interrupt-names = "rx", "tx", "error"; + channel = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + gtm0: gtm@12801000 { compatible = "renesas,rz-gtm"; reg = <0x12801000 0x400>; @@ -919,5 +957,14 @@ clock-freq = ; status = "disabled"; }; + + spibsc: spibsc@10060000 { + compatible = "renesas,rz-spibsc"; + reg = <0x10060000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + }; }; diff --git a/dts/bindings/adc/infineon,hppass-sar-adc.yaml b/dts/bindings/adc/infineon,hppass-sar-adc.yaml new file mode 100644 index 0000000000000..7e073d891ff00 --- /dev/null +++ b/dts/bindings/adc/infineon,hppass-sar-adc.yaml @@ -0,0 +1,77 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +title: PSOC C3 HPPASS SAR ADC + +description: | + Infineon PSOC C3 HPPASS SAR ADC + + The HPPASS (High Performance Programmable Analog Sub-System) SAR ADC + provides high-resolution analog-to-digital conversion capabilities + for the PSOC C3 family of microcontrollers. + + Each ADC channel corresponds to a dedicated analog input pin, except for + the last four sampler inputs which are muxed. See the device datasheet for + pin assignments and mux options. + + Dependency: This ADC node must be a child of the HPPASS analog subsystem + node ("infineon,hppass-analog"), which provides clock, power, and reference + resources. + +compatible: "infineon,hppass-sar-adc" + +include: adc-controller.yaml + +properties: + reg: + required: true + description: Base address of the HPPASS SAR ADC registers + + interrupts: + required: true + description: Interrupt configuration for the HPPASS SAR ADC + + "#io-channel-cells": + const: 1 + description: Number of cells in an io-channel specifier + + clock-frequency: + type: int + description: | + ADC clock frequency in Hz. If not specified, the driver will use + the default clock configuration. + + vref-mv: + type: int + default: 3300 + description: | + Internal reference voltage in millivolts. + + offset-cal: + type: boolean + description: + Enables Self-Calibration for offset correction within the ADC. If left disabled, + the factory calibration for offset correction will be used. + + gain-cal: + type: boolean + description: | + Enables Self-Calibration for gain within the ADC. If left disabled, + the factory calibration for gain will be used. + + linear-cal: + type: boolean + description: | + Enables Self-Calibration for linearity correction within the ADC. If left disabled, + the factory calibration for linearity will be used. + + ref-internal-source: + type: boolean + description: | + Selects whether the ADC uses internal (true) or external (false) reference. + External reference recommended for best performance. + +io-channel-cells: + - input diff --git a/dts/bindings/arm/renesas,ra-npu.yaml b/dts/bindings/arm/renesas,ra-npu.yaml new file mode 100644 index 0000000000000..1604c0bb918d8 --- /dev/null +++ b/dts/bindings/arm/renesas,ra-npu.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA frontend of Arm Ethos-U NPU + +compatible: "renesas,ra-npu" + +include: "arm,ethos-u.yaml" + +properties: + clocks: + required: true + + interrupt-names: + required: true + enum: + - "npu-irq" diff --git a/dts/bindings/audio/nxp,pdm.yaml b/dts/bindings/audio/nxp,pdm.yaml new file mode 100644 index 0000000000000..715665bfb49e2 --- /dev/null +++ b/dts/bindings/audio/nxp,pdm.yaml @@ -0,0 +1,87 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP PDM Microphone Interface (MICFIL) + +compatible: "nxp,micfil" + +include: + - base.yaml + - pinctrl-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + quality-mode: + type: int + enum: [0, 1, 4, 5, 6, 7] + default: 0 + description: | + Decimation filter quality mode. + 0 = Medium, default value, PoR reset value of register + 1 = High + 4 = VeryLow2 + 5 = VeryLow1 + 6 = VeryLow0 + 7 = Low + + cic-decimation-rate: + type: int + description: | + CIC filter decimation rate setting, + range is SoC specific, may [0, 15] or [8, 31] + The final OSR = (16 - cic-decimation-rate) + CIC decimation rate = 2 * OSR; If HQ, VLQ0 mode. + CIC decimation rate = OSR; If other modes. + 0: CIC oversampling rate = 0, default value, PoR reset value + 1: CIC oversampling rate = 1 + ... + 15: CIC oversampling rate = 15 + + fifo-watermark: + type: int + description: | + FIFO watermark level (implementation defined, typically 7), + range is SoC specific, may [0, 7] or [0, 15]. + Default is PoR reset value of register. + + sample-rate: + type: int + enum: [8000, 12000, 16000, 24000, 32000, 48000, 96000] + description: | + Sample rate in Hz. + +child-binding: + description: | + NXP MICFIL channel. Can be used to configure DC remover cutoff frequency and gain + include: + - name: base.yaml + property-allowlist: + - reg + properties: + reg: + required: true + dc-remover-cutoff-freq: + type: int + enum: [0, 1, 2, 3] + default: 0 + description: | + DC remover cutoff frequency in Hz + 0: 20Hz (FS=48KHz), default value, PoR reset value + 1: 13.3Hz (FS=48KHz) + 2: 40Hz (FS=48KHz) + 3: DC remover is bypassed + + decimation-filter-gain: + type: int + default: 0 + description: | + Decimation filter gain setting, range: [0, 15]. + Default is PoR reset value of register. diff --git a/dts/bindings/clock/nxp,firc.yaml b/dts/bindings/clock/nxp,firc.yaml new file mode 100644 index 0000000000000..ca57df3a55238 --- /dev/null +++ b/dts/bindings/clock/nxp,firc.yaml @@ -0,0 +1,18 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Fast internal RC oscillator + +compatible: "nxp,firc" + +include: [base.yaml] + +properties: + reg: + required: true + + firc-div: + required: true + type: string + description: FIRC_DIV_SEL + enum: ["NULL", "DivBy2", "DivBy16", "UnDiv"] diff --git a/dts/bindings/clock/nxp,fxosc.yaml b/dts/bindings/clock/nxp,fxosc.yaml new file mode 100644 index 0000000000000..9362d431bf197 --- /dev/null +++ b/dts/bindings/clock/nxp,fxosc.yaml @@ -0,0 +1,33 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Fast external crystal oscillator + +compatible: "nxp,fxosc" + +include: [base.yaml] + +properties: + reg: + required: true + + freq: + required: true + type: int + description: FXOSC output clock frequency in Hz + + workmode: + required: true + type: string + description: FXOSC work mode setting + enum: ["crystal", "bypass"] + + delay: + required: true + type: int + description: FXOSC startup delay in counts + + overdrive: + required: true + type: int + description: FXOSC overdrive protection setting diff --git a/dts/bindings/clock/nxp,mc-cgm.yaml b/dts/bindings/clock/nxp,mc-cgm.yaml new file mode 100644 index 0000000000000..0a53a94d82a59 --- /dev/null +++ b/dts/bindings/clock/nxp,mc-cgm.yaml @@ -0,0 +1,65 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Glitchless clock switching Clock Generation module + +compatible: "nxp,mc-cgm" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + max-ido-change: + required: true + type: int + description: | + Maximum variation of current per time (mA/microsec) - max allowable + IDD change is determined by the user's power supply design. + + step-duration: + required: true + type: int + description: Step duration of each PCFS step (time per step in us). + + clk-src-freq: + required: true + type: int + description: | + Frequency of the clock source from which ramp-down and to which ramp-up are processed. + + mux-0-dc-0-div: + type: int + description: MUX_0_DC_0 divider setting + + mux-0-dc-1-div: + type: int + description: MUX_0_DC_1 divider setting + + mux-0-dc-2-div: + type: int + description: MUX_0_DC_2 divider setting + + mux-0-dc-3-div: + type: int + description: MUX_0_DC_3 divider setting + + mux-0-dc-4-div: + type: int + description: MUX_0_DC_4 divider setting + + mux-0-dc-5-div: + type: int + description: MUX_0_DC_5 divider setting + + mux-0-dc-6-div: + type: int + description: MUX_0_DC_6 divider setting + + "#clock-cells": + type: int + const: 1 + +clock-cells: + - name diff --git a/dts/bindings/clock/nxp,plldig.yaml b/dts/bindings/clock/nxp,plldig.yaml new file mode 100644 index 0000000000000..23d17e87050d8 --- /dev/null +++ b/dts/bindings/clock/nxp,plldig.yaml @@ -0,0 +1,61 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Phase-locked loop + +compatible: "nxp,plldig" + +include: [base.yaml] + +properties: + reg: + required: true + + workmode: + required: true + type: string + description: PLL work mode setting + enum: ["Integer", "Fractional", "SSCG"] + + prediv: + required: true + type: int + description: Input Clock Predivider + + postdiv: + required: true + type: int + description: VCO clock post divider for driving the PHI output clock. + + multiplier: + required: true + type: int + description: Multiplication factor applied to the reference frequency + + fracloopdiv: + required: true + type: int + description: Numerator Of Fractional Loop Division Factor. + Value should less than 18432. + + stepsize: + required: true + type: int + description: For SSCG mode. Frequency Modulation Step Size + + stepnum: + required: true + type: int + description: | + For SSCG mode. Number Of Steps Of Modulation Period Or Frequency Modulation + + accuracy: + required: true + type: string + description: PLL unlock accuracy + enum: ["Accuracy9", "Accuracy17", "Accuracy33", "Accuracy5"] + + outdiv: + required: true + type: array + description: PLL Output Divider diff --git a/dts/bindings/counter/microchip,tcc-g1.yaml b/dts/bindings/counter/microchip,tcc-g1.yaml new file mode 100644 index 0000000000000..5c53351550861 --- /dev/null +++ b/dts/bindings/counter/microchip,tcc-g1.yaml @@ -0,0 +1,73 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Microchip TCC G1 timer counter peripheral. + +description: | + Microchip TCC G1 timer counter peripheral. + + This peripheral is used for generating PWM signals. + This compatible string is to be used for the following peripherals: + - module name="TCC" id="U2213" version="3.1.0" + +compatible: "microchip,tcc-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. + required: true + + prescaler: + type: int + description: | + Timer prescaler values. + + The prescaler divides the input clock frequency to + achieve the desired timer frequency. + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 64 + - 256 + - 1024 + + channels: + type: int + required: true + description: | + This specifies the maximum number of channels available for the peripheral instance. + + max-bit-width: + type: int + required: true + description: | + Maximum bit width supported by the 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. + enum: + - 16 + - 24 diff --git a/dts/bindings/dma/bflb,dma.yaml b/dts/bindings/dma/bflb,dma.yaml new file mode 100644 index 0000000000000..4aa94a196e2d1 --- /dev/null +++ b/dts/bindings/dma/bflb,dma.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2025 MASSDRIVER EI +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bouffalo Lab DMA + + BFLB platforms support 4 (BL60x and BL61x) to 8 (BL70x) independent DMA channels. + Every channel is capable of memory-to-memory, memory-to-peripheral, peripheral-to-memory and + peripheral-to-peripheral access. + All channels support 8, 16, and 32 bit width memory access. + Each channel can be triggered by independent peripheral hardware or software. + +compatible: "bflb,dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + dma-channels: + required: true + + "#dma-cells": + const: 1 + +dma-cells: + - channel diff --git a/dts/bindings/espi/realtek,rts5912-espi.yaml b/dts/bindings/espi/realtek,rts5912-espi.yaml index 18198cdfbc868..76044596710a8 100644 --- a/dts/bindings/espi/realtek,rts5912-espi.yaml +++ b/dts/bindings/espi/realtek,rts5912-espi.yaml @@ -17,3 +17,12 @@ properties: pinctrl-names: required: true + + cs-gpios: + description: | + select the cs pin to support the espi wakeup + and it is required when CONFIG_PM is enabled. + please check include/zephyr/dt-bindings/gpio/realtek-gpio.h + For example: + cs-gpios = ; + type: phandle-array diff --git a/dts/bindings/ethernet/phy/adi,adin1100-phy.yaml b/dts/bindings/ethernet/phy/adi,adin1100-phy.yaml index c8613bcb90212..c3cfe7e044dc0 100644 --- a/dts/bindings/ethernet/phy/adi,adin1100-phy.yaml +++ b/dts/bindings/ethernet/phy/adi,adin1100-phy.yaml @@ -7,3 +7,8 @@ description: ADIN1100 PHY compatible: "adi,adin1100-phy" include: adi,adin2111-phy.yaml + +properties: + reset-gpios: + type: phandle-array + description: GPIO connected to PHY reset signal pin. Reset is active low. diff --git a/dts/bindings/flash_controller/nxp,kinetis-ftfc.yaml b/dts/bindings/flash_controller/nxp,kinetis-ftfc.yaml new file mode 100644 index 0000000000000..4c539864cb9a7 --- /dev/null +++ b/dts/bindings/flash_controller/nxp,kinetis-ftfc.yaml @@ -0,0 +1,22 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP Kinetis Flash Memory Module C (FTFC) + +compatible: "nxp,kinetis-ftfc" + +include: flash-controller.yaml + +properties: + fsec: + type: int + description: | + Configures the reset value of the FSEC register, which includes + backdoor key access, mass erase, factory access, and flash security + options. + + fopt: + type: int + description: | + Configures the reset value of the FOPT register, which includes boot, + NMI, and EzPort options. diff --git a/dts/bindings/flash_controller/renesas,rz-qspi-spibsc.yaml b/dts/bindings/flash_controller/renesas,rz-qspi-spibsc.yaml new file mode 100644 index 0000000000000..2c20187b4bacc --- /dev/null +++ b/dts/bindings/flash_controller/renesas,rz-qspi-spibsc.yaml @@ -0,0 +1,36 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Renesas RZ SPIBSC NOR FLASH supporting the JEDEC CFI interface + + Representation of a serial flash on a quadspi bus: + + at25ql128a: qspi-nor-flash@20000000 { + compatible = "renesas,rz-qspi-spibsc"; + reg = <0x20000000 DT_SIZE_M(16)>; /* 128 Mbits */ + write-block-size = <1>; + erase-block-size = <4096>; + status = "okay"; + }; + +compatible: "renesas,rz-qspi-spibsc" + +include: ["flash-controller.yaml", "jedec,jesd216.yaml"] + +on-bus: qspi + +properties: + reg: + required: true + description: Flash Memory base address and size in bytes + + erase-block-size: + type: int + default: 4096 + description: Address alignment required by flash erase operations + + write-block-size: + type: int + default: 1 + description: Address alignment required by flash write operations diff --git a/dts/bindings/flash_controller/renesas,rz-qspi-xspi.yaml b/dts/bindings/flash_controller/renesas,rz-qspi-xspi.yaml new file mode 100644 index 0000000000000..6cc10e282a843 --- /dev/null +++ b/dts/bindings/flash_controller/renesas,rz-qspi-xspi.yaml @@ -0,0 +1,36 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Renesas RZ XSPI NOR FLASH supporting the JEDEC CFI interface + + Representation of a serial flash on a quadspi bus: + + mx25u51245g: qspi-nor-flash@60000000 { + compatible = "renesas,rz-qspi-xspi"; + reg = <0x60000000 DT_SIZE_M(64)>; /* 512 Mbits */ + write-block-size = <1>; + erase-block-size = <4096>; + status = "okay"; + }; + +compatible: "renesas,rz-qspi-xspi" + +include: ["flash-controller.yaml", "jedec,jesd216.yaml"] + +on-bus: qspi + +properties: + reg: + required: true + description: Flash Memory base address and size in bytes + + erase-block-size: + type: int + default: 4096 + description: Address alignment required by flash erase operations + + write-block-size: + type: int + default: 1 + description: Address alignment required by flash write operations diff --git a/dts/bindings/fuel-gauge/adi,ltc2959.yaml b/dts/bindings/fuel-gauge/adi,ltc2959.yaml new file mode 100644 index 0000000000000..61f3e3cc80848 --- /dev/null +++ b/dts/bindings/fuel-gauge/adi,ltc2959.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Nathan Winslow +# SPDX-License-Identifier: Apache-2.0 + +description: | + Analog Devices LTC2959 ultra-low-power battery fuel gauge. + +compatible: "adi,ltc2959" + +include: [base.yaml, i2c-device.yaml, fuel-gauge.yaml] + +properties: + reg: + required: true + + rsense-milliohms: + type: int + required: true + description: | + Sensor resistor value in milliohms. Connected to SENSEP or SENSEN on the IC. + NOTE: The datasheet uses a default value of 50 milliOhm diff --git a/dts/bindings/gnss/zephyr,gnss-emul.yaml b/dts/bindings/gnss/zephyr,gnss-emul.yaml index eb7d9eec8acc3..10c4659dc0785 100644 --- a/dts/bindings/gnss/zephyr,gnss-emul.yaml +++ b/dts/bindings/gnss/zephyr,gnss-emul.yaml @@ -4,3 +4,5 @@ description: Zephyr emulated GNSS device compatible: "zephyr,gnss-emul" + +include: base.yaml diff --git a/dts/bindings/gpio/microchip,mec5-gpio.yaml b/dts/bindings/gpio/microchip,mec5-gpio.yaml index d9ae269a5d708..da82c417e01db 100644 --- a/dts/bindings/gpio/microchip,mec5-gpio.yaml +++ b/dts/bindings/gpio/microchip,mec5-gpio.yaml @@ -5,7 +5,7 @@ description: Microchip MEC5 GPIO compatible: "microchip,mec5-gpio" -include: [gpio-controller.yaml, base.yaml] +include: ["gpio-controller.yaml", "base.yaml", "microchip,dmec-ecia-girq.yaml"] properties: reg: diff --git a/dts/bindings/mfd/nxp,sc18is606.yaml b/dts/bindings/mfd/nxp,sc18is606.yaml new file mode 100644 index 0000000000000..5f0e75cd9cbed --- /dev/null +++ b/dts/bindings/mfd/nxp,sc18is606.yaml @@ -0,0 +1,49 @@ +description: | + NXP SC18IS606 I2C to SPI/GPIO bridge. + + The SC18IS606 supports both an external SPI and GPIO controller. + These controllers have to be added to the Device Tree as children, while + the device itself has to be a child of a I2C controller. + Do note that this device only supports 3 SPI devices on the bus. + + An example configuration: + + &i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + + sc18is606: sc18is606 { + compatible = "nxp,sc18is606"; + status = "okay"; + + + spi_ext: sc18is606_spi { + compatible = "nxp,sc18is606-spi"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + +compatible: "nxp,sc18is606" +include: i2c-device.yaml + +properties: + reset-gpios: + type: phandle-array + description: + Driver reset pin of the bridge. + If connected directly to the MCU, this pin should be configured + as active low. + + int-gpios: + type: phandle-array + description: + Driver interrupt pin of the bridge, this allows the driver to ensure + that SPI transactions are done before allowing other transactions. + If connected directly to the MCU, this pin should be configured + as active low. + +bus: nxp,sc18is606 diff --git a/dts/bindings/mtd/jedec,qspi-nor.yaml b/dts/bindings/mtd/jedec,qspi-nor.yaml index 79f5ef2aeb0e4..a3d038c0fbf5a 100644 --- a/dts/bindings/mtd/jedec,qspi-nor.yaml +++ b/dts/bindings/mtd/jedec,qspi-nor.yaml @@ -5,4 +5,6 @@ description: Generic NOR flash on QSPI bus compatible: "jedec,qspi-nor" +on-bus: qspi + include: [base.yaml, "jedec,spi-nor-common.yaml"] diff --git a/dts/bindings/mtd/sifli,sf32lb-mpi-qspi-nor.yaml b/dts/bindings/mtd/sifli,sf32lb-mpi-qspi-nor.yaml index 6a81106aa4924..a70e742fd721e 100644 --- a/dts/bindings/mtd/sifli,sf32lb-mpi-qspi-nor.yaml +++ b/dts/bindings/mtd/sifli,sf32lb-mpi-qspi-nor.yaml @@ -7,6 +7,8 @@ compatible: "sifli,sf32lb-mpi-qspi-nor" include: base.yaml +bus: qspi + properties: reg: required: true diff --git a/dts/bindings/pinctrl/nxp,mcxe31x-siul2-pinctrl.yaml b/dts/bindings/pinctrl/nxp,mcxe31x-siul2-pinctrl.yaml new file mode 100644 index 0000000000000..43b24d7b3c780 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,mcxe31x-siul2-pinctrl.yaml @@ -0,0 +1,115 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP SIUL2 Pin Controller for MCXE31X SoCs + + The NXP SIUL2 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 UART0, modify the 'pinctrl' from your + board or application devicetree overlay as follows: + + /* Include the SoC package header containing the predefined pins definitions */ + #include + + &pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + output-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + }; + + The 'uart0_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 UART0 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: + + &uart0 { + pinctrl-0 = <&uart0_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). + +compatible: "nxp,mcxe31x-siul2-pinctrl" + +include: base.yaml + +child-binding: + description: NXP SIUL2 pin controller pin group. + child-binding: + description: NXP SIUL2 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 macros from the SoC package header. These macros + encode 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/dts/bindings/pwm/microchip,tcc-g1-pwm.yaml b/dts/bindings/pwm/microchip,tcc-g1-pwm.yaml new file mode 100644 index 0000000000000..b02f32fd3019e --- /dev/null +++ b/dts/bindings/pwm/microchip,tcc-g1-pwm.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Microchip G1 TCC pwm driver. + +description: | + Microchip TCC pwm driver. + + This driver is used for configuring + and managing TCC (Timer/ Counter for Control Applications) + peripheral in Microchip microcontrollers. This peripherals + support creating PWM signals. The supported peripherals are + as follows: + - module name="TCC" id="U2213" version="3.1.0" + +compatible: "microchip,tcc-g1-pwm" + +include: + - base.yaml + - pwm-controller.yaml + - microchip,tcc-g1.yaml + - pinctrl-device.yaml + +properties: + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - polarity diff --git a/dts/bindings/qspi/renesas,rz-spibsc.yaml b/dts/bindings/qspi/renesas,rz-spibsc.yaml new file mode 100644 index 0000000000000..c3053a0fa9874 --- /dev/null +++ b/dts/bindings/qspi/renesas,rz-spibsc.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ SPIBSC + +compatible: "renesas,rz-spibsc" + +include: [base.yaml, pinctrl-device.yaml] + +bus: qspi + +properties: + reg: + required: true diff --git a/dts/bindings/qspi/renesas,rz-xspi.yaml b/dts/bindings/qspi/renesas,rz-xspi.yaml new file mode 100644 index 0000000000000..27f7e6d9e8acf --- /dev/null +++ b/dts/bindings/qspi/renesas,rz-xspi.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ XSPI + +compatible: "renesas,rz-xspi" + +include: [base.yaml, pinctrl-device.yaml] + +bus: qspi + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/dts/bindings/reset/microchip,rstc-g1-reset.yaml b/dts/bindings/reset/microchip,rstc-g1-reset.yaml new file mode 100644 index 0000000000000..34575e5859164 --- /dev/null +++ b/dts/bindings/reset/microchip,rstc-g1-reset.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Microchip RSTC Reset driver + +description: | + Microchip RSTC Reset driver bindings. + + Group g1 RSTC Reset driver supports following hardware peripherals: + - module name="RSTC" id="U2239" version="4.0.0" + +include: base.yaml + +compatible: "microchip,rstc-g1-reset" + +properties: + reg: + required: true + description: | + Base address and size of the RSTC register block. diff --git a/dts/bindings/rtc/silabs,rtcc.yaml b/dts/bindings/rtc/silabs,rtcc.yaml new file mode 100644 index 0000000000000..a5eb71689fce3 --- /dev/null +++ b/dts/bindings/rtc/silabs,rtcc.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Silicon Labs Series 2 RTCC (Real Time Clock with Capture) + +description: | + The Real Time Clock with Capture (RTCC) is a 32-bit counter kept running down to energy mode EM3. + It can be used as an EM2/3 wakeup source as well as a timekeeping counter during low energy mode. + +compatible: "silabs,rtcc" + +include: rtc.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/rtc/silabs,sysrtc.yaml b/dts/bindings/rtc/silabs,sysrtc.yaml new file mode 100644 index 0000000000000..7391c733d9ea7 --- /dev/null +++ b/dts/bindings/rtc/silabs,sysrtc.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Silicon Labs Series 2 SYSRTC (System Real Time Clock) + +description: | + The SYSRTC (System Real Time Counter) is a 32-bit counter kept running down to energy mode EM3. + It can be used as a sleep timer / wakeup source as well as a timekeeping counter during low energy + modes. Multiple groups of capture / compare registers are available to different cores in the + system, allowing the peripheral and time base to be shared across cores and save energy. + +compatible: "silabs,sysrtc" + +include: rtc.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/sensor/bosch,bmi08x-accel.yaml b/dts/bindings/sensor/bosch,bmi08x-accel.yaml index 2bd311df0f532..3aa9c85014268 100644 --- a/dts/bindings/sensor/bosch,bmi08x-accel.yaml +++ b/dts/bindings/sensor/bosch,bmi08x-accel.yaml @@ -82,3 +82,8 @@ properties: description: | Enables data sync if defined. This is to point to the bmi08x-gyro definition that is within the same IC as the bmi08x-accel. + + fifo-watermark: + type: int + description: | + FIFO Watermark in number of samples. Ranges between 1 and 99 diff --git a/dts/bindings/sensor/bosch,bmi08x-gyro.yaml b/dts/bindings/sensor/bosch,bmi08x-gyro.yaml index 0a3086d8417c7..7ffb1ecbe23a3 100644 --- a/dts/bindings/sensor/bosch,bmi08x-gyro.yaml +++ b/dts/bindings/sensor/bosch,bmi08x-gyro.yaml @@ -60,3 +60,8 @@ properties: type: boolean description: | Enables data sync if defined. Must be set if bmi08x-accel data-sync is set as well. + + fifo-watermark: + type: int + description: | + FIFO Watermark in number of frames. Ranges between 1 and 99 diff --git a/dts/bindings/sensor/maxim,max32664c.yml b/dts/bindings/sensor/maxim,max32664c.yml new file mode 100644 index 0000000000000..3f8c36c77499f --- /dev/null +++ b/dts/bindings/sensor/maxim,max32664c.yml @@ -0,0 +1,159 @@ +title: | + MAX32664 biometric sensor hub + +description: | + The MAX32664 is a ultra-low power biometric sensor hub. + + NOTES: + This driver is primarily written to work with a MAX86141. Other sensors can be + used but they are untested! The driver supports up to two photodetectors (PDs) + and three LEDs fix. It requires a specific LED + configuration for the MAX86141. + LED1 -> Green + LED2 -> IR + LED3 -> Red + The LEDs can be changed manually but this may require changes in the driver. + + This driver is tested with Sensor Hub firmware 30.13.31 and an external + Accelerometer (e.g. LIS2DH12). + + See more info at: + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX32664.pdf + +compatible: "maxim,max32664c" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + reset-gpios: + type: phandle-array + required: true + description: + External System Reset (Active-Low) Input. + + mfio-gpios: + type: phandle-array + required: true + description: + MFIO asserts low as an output when the sensor hub needs to + communication with the host; MFIO acts as an input and when held + low during a reset, the sensor hub enters bootloader mode. + + use-max86141: + type: boolean + description: + Use the MAX86141 as the AFE for the MAX32664C. This is the + default and recommended configuration. The driver is optimized for + this sensor. + + use-max86161: + type: boolean + description: + Use the MAX86161 as the AFE for the MAX32664C. + + motion-time: + type: int + default: 200 + description: + Sensor Hub configuration - Motion activation time in milliseconds. + The default corresponds to Table 12 in the HR and SpO2 User guide. + + motion-threshold: + type: int + default: 500 + description: + Sensor Hub configuration - Motion activation time in milli-g. + The default corresponds to Table 12 in the HR and SpO2 User guide. + + report-period: + type: int + default: 1 + description: + Sensor Hub configuration - Set the samples report period (e.g., a value + of 25 means a samples report is generated once every 25 samples). + The default corresponds to Table 16 in the HR and SpO2 User guide. + + spo2-calib: + type: array + default: [0xFFE69196, 0x000CB735, 0x00989680] + description: + Algorithm configuration - SpO2 calibration coefficients. + The default corresponds to Table 12 in the HR and SpO2 User guide. + + min-integration-time: + type: int + default: 14 + enum: + - 14 + - 29 + - 58 + - 117 + description: + Algorithm configuration - Minimum integration time in microseconds. + The default corresponds to Table 11 in the HR and SpO2 User guide. + + min-sampling-rate: + type: int + default: 50 + enum: + - 25 + - 50 + - 100 + - 200 + - 400 + description: + Algorithm configuration - Minimum sampling rate (samples per second) + and averaging (samples). + The default corresponds to Table 11 in the HR and SpO2 User guide. + + max-integration-time: + type: int + default: 117 + enum: + - 14 + - 29 + - 58 + - 117 + description: + Algorithm configuration - Maximum integration time in microseconds. + The default corresponds to Table 11 in the HR and SpO2 User guide. + + max-sampling-rate: + type: int + default: 100 + enum: + - 25 + - 50 + - 100 + - 200 + - 400 + description: + Algorithm configuration - Maximum sampling rate (samples per second) + and averaging (samples). + The default corresponds to Table 11 in the HR and SpO2 User guide. + + led-current: + type: uint8-array + default: [0x7F, 0x7F, 0x7F] + description: + Initial LED current configuration in bits. Please check the datasheet + of the attached AFE to determine the appropriate values. + The current can also be changed later by the firmware. + Index 0 corresponds to LED1, index 1 to LED2, and index 2 to LED3. + The default corresponds to Table 5 in the HR and SpO2 User guide. + + hr-config: + type: uint8-array + default: [0x00, 0x01] + description: + Algorithm configuration - LED and PD configuration for the heartrate measurement. + The first entry configures channel 1, the second channel 2. + The default corresponds to Table 15 in the HR and SpO2 User guide. + + spo2-config: + type: uint8-array + default: [0x10, 0x20] + description: + Algorithm configuration - LED and PD configuration for the SpO2 measurement. + The first entry configures the IR channel, the second the red channel. + The default corresponds to Table 15 in the HR and SpO2 User guide. diff --git a/dts/bindings/sensor/omron,2smpb-02e.yaml b/dts/bindings/sensor/omron,2smpb-02e.yaml new file mode 100644 index 0000000000000..5c02c9e8f881a --- /dev/null +++ b/dts/bindings/sensor/omron,2smpb-02e.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 CATIE +# SPDX-License-Identifier: Apache-2.0 + +description: | + Omron 2SMPB-02E digital barometric pressure sensor. + +compatible: "omron,2smpb-02e" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/dts/bindings/sensor/ti,ina226.yaml b/dts/bindings/sensor/ti,ina226.yaml index 137dca397013d..81c5d194b058e 100644 --- a/dts/bindings/sensor/ti,ina226.yaml +++ b/dts/bindings/sensor/ti,ina226.yaml @@ -2,10 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 description: | - TI INA226 Bidirectional Current and Power Monitor. - The file should be included in the - DeviceTree as it provides macros that can be used for initializing the - configuration registers. + TI INA226 Bidirectional Current and Power Monitor. + The file should be included in the + DeviceTree as it provides macros that can be used for initializing the + configuration registers. compatible: "ti,ina226" @@ -47,6 +47,7 @@ properties: - "Shunt Voltage, Triggered" - "Bus Voltage, Triggered" - "Shunt and Bus, Triggered" + - "Power-Down (or Shutdown)_2" - "Shunt Voltage, Continuous" - "Bus Voltage, Continuous" - "Shunt and Bus, Continuous" diff --git a/dts/bindings/sensor/vishay,veml6046.yaml b/dts/bindings/sensor/vishay,veml6046.yaml new file mode 100644 index 0000000000000..473c131c62792 --- /dev/null +++ b/dts/bindings/sensor/vishay,veml6046.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Andreas Klinger +# SPDX-License-Identifier: Apache-2.0 + +description: | + Vishay VEML6046 RGBIR color sensor with I2C interface. + See: https://www.vishay.com/docs/80173/veml6046x00.pdf + +compatible: "vishay,veml6046" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/dts/bindings/serial/microchip,mec5-uart.yaml b/dts/bindings/serial/microchip,mec5-uart.yaml index d37c196d046bc..701ec588db5bb 100644 --- a/dts/bindings/serial/microchip,mec5-uart.yaml +++ b/dts/bindings/serial/microchip,mec5-uart.yaml @@ -5,7 +5,7 @@ description: Microchip MEC5 UART compatible: "microchip,mec5-uart" -include: [uart-controller.yaml, pinctrl-device.yaml] +include: [uart-controller.yaml, pinctrl-device.yaml, "microchip,dmec-ecia-girq.yaml"] properties: reg: diff --git a/dts/bindings/spi/microchip,mec5-qspi.yaml b/dts/bindings/spi/microchip,mec5-qspi.yaml index b7cff7fb8d9bf..01adeadbfd4b6 100644 --- a/dts/bindings/spi/microchip,mec5-qspi.yaml +++ b/dts/bindings/spi/microchip,mec5-qspi.yaml @@ -5,7 +5,7 @@ description: Microchip MEC5 series QSPI controller compatible: "microchip,mec5-qspi" -include: [spi-controller.yaml, pinctrl-device.yaml] +include: ["spi-controller.yaml", "pinctrl-device.yaml", "microchip,dmec-ecia-girq.yaml"] properties: reg: diff --git a/dts/bindings/spi/nxp,sc18is606-spi.yaml b/dts/bindings/spi/nxp,sc18is606-spi.yaml new file mode 100644 index 0000000000000..4c28e17120510 --- /dev/null +++ b/dts/bindings/spi/nxp,sc18is606-spi.yaml @@ -0,0 +1,30 @@ +description: | + SPI device through NXP SC18IS606 I2C to SPI Bridge. + +compatible: "nxp,sc18is606-spi" +include: spi-controller.yaml +properties: + frequency: + type: int + default: 1875 + enum: + - 1875 + - 455 + - 115 + - 58 + + description: SPI Clock frequency in KHz + + spi-mode: + type: int + default: 0 + enum: + - 0 + - 1 + - 2 + - 3 + + description: SPI mode CPOL and CPHA combination + + +on-bus: nxp,sc18is606 diff --git a/dts/bindings/spi/renesas,rz-spi.yaml b/dts/bindings/spi/renesas,rz-spi.yaml new file mode 100644 index 0000000000000..ebf23d8b265d3 --- /dev/null +++ b/dts/bindings/spi/renesas,rz-spi.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: RENESAS RZ SPI + +compatible: "renesas,rz-spi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + interrupt-names: + required: true + + channel: + type: int + required: true + + clk-src: + type: int + required: true + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + description: | + Select clock source supplied to calculate bitrate + - 0: SPI0ASYNCCLK + - 1: SPI1ASYNCCLK + - 2: SPI2ASYNCCLK + - 3: SPI3ASYNCCLK + - 4: PCLKM diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index f9b987895f8c0..b8d71c51eef6f 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -122,6 +122,7 @@ calaosystems CALAO Systems SAS calxeda Calxeda canaan Canaan, Inc. caninos Caninos Loucos Program +canis Canis Automotive Labs capella Capella Microsystems, Inc cascoda Cascoda, Ltd. catalyst Catalyst Semiconductor, Inc. diff --git a/dts/bindings/video/st,mipid02.yaml b/dts/bindings/video/st,mipid02.yaml index b78d0df0c2b5a..55d53ea7d0d84 100644 --- a/dts/bindings/video/st,mipid02.yaml +++ b/dts/bindings/video/st,mipid02.yaml @@ -1,7 +1,11 @@ # Copyright (c) 2025 STMicroelectronics. # SPDX-License-Identifier: Apache-2.0 -description: MIPID02 CSI to DVP interface bridge +title: MIPID02 CSI to DVP interface bridge + +description: | + The MIPID02 allows connecting a DVP sensor to a CSI-2–enabled + camera receiver. compatible: "st,mipid02" diff --git a/dts/bindings/video/st,stm32-dcmi.yaml b/dts/bindings/video/st,stm32-dcmi.yaml index 41da6c7659f9a..291a452ae44c3 100644 --- a/dts/bindings/video/st,stm32-dcmi.yaml +++ b/dts/bindings/video/st,stm32-dcmi.yaml @@ -4,8 +4,11 @@ # SPDX-License-Identifier: Apache-2.0 # +title: STM32 DCMI (Digital Camera Memory Interface) + description: | - STM32 Digital Camera Memory Interface (DCMI). + The STM32 DCMI (Digital Camera Memory Interface) allows + capturing data via a parallel interface (DVP). Example of node configuration at board level: diff --git a/dts/bindings/video/st,stm32-dcmipp.yaml b/dts/bindings/video/st,stm32-dcmipp.yaml index 7aaaa8521e0c7..088227f3d3cf5 100644 --- a/dts/bindings/video/st,stm32-dcmipp.yaml +++ b/dts/bindings/video/st,stm32-dcmipp.yaml @@ -4,8 +4,14 @@ # SPDX-License-Identifier: Apache-2.0 # +title: STM32 DCMIPP (Digital Camera Memory Interface Pixel Processor) + description: | - STM32 Digital Camera Memory Interface Pixel Processor (DCMIPP). + The STM32 DCMIPP (Digital Camera Memory Interface Pixel Processor) supports, + depending on the platform, data capture from either parallel (DVP) or + CSI-2 interfaces. It integrates up to three processing pipelines capable of + performing frame operations, including one pipeline with ISP functionality + enabled. Example of node configuration at board level: diff --git a/dts/bindings/video/st,stm32-jpeg.yaml b/dts/bindings/video/st,stm32-jpeg.yaml index b2549f26a3204..8b5ebebb932b2 100644 --- a/dts/bindings/video/st,stm32-jpeg.yaml +++ b/dts/bindings/video/st,stm32-jpeg.yaml @@ -4,9 +4,9 @@ # SPDX-License-Identifier: Apache-2.0 # -description: | - STM32 JPEG HW Codec. +title: STM32 JPEG HW Codec +description: | The STM32 JPEG HW codec can decode JPEG compressed frames and encode uncompressed frames to the JPEG format. diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index 3b2e018232eb0..65d6ba11982cd 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -187,6 +187,16 @@ interrupt-parent = <&clic>; }; + dma0: dma@4000c000 { + compatible = "bflb,dma"; + reg = <0x4000c000 0x1000>; + #dma-cells = <1>; + dma-channels = <4>; + + interrupts = <31 0>; + interrupt-parent = <&clic>; + }; + retram: memory@40010000 { compatible = "mmio-sram"; reg = <0x40010000 DT_SIZE_K(4)>; diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index b2936b8b901c0..0e6d6ff2dcf39 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -180,6 +180,16 @@ interrupt-parent = <&clic>; }; + dma0: dma@2000c000 { + compatible = "bflb,dma"; + reg = <0x2000c000 0x1000>; + #dma-cells = <1>; + dma-channels = <4>; + + interrupts = <31 1>; + interrupt-parent = <&clic>; + }; + retram: memory@20010000 { compatible = "mmio-sram"; reg = <0x20010000 DT_SIZE_K(4)>; diff --git a/dts/riscv/bflb/bl70x.dtsi b/dts/riscv/bflb/bl70x.dtsi index a80dae7991ec0..3dab3f9cc73a0 100644 --- a/dts/riscv/bflb/bl70x.dtsi +++ b/dts/riscv/bflb/bl70x.dtsi @@ -181,6 +181,16 @@ interrupt-parent = <&clic>; }; + dma0: dma@4000c000 { + compatible = "bflb,dma"; + reg = <0x4000c000 0x1000>; + #dma-cells = <1>; + dma-channels = <8>; + + interrupts = <31 0>; + interrupt-parent = <&clic>; + }; + retram: memory@40010000 { compatible = "mmio-sram"; reg = <0x40010000 DT_SIZE_K(4)>; diff --git a/dts/riscv/riscv32-litex-vexriscv.dtsi b/dts/riscv/riscv32-litex-vexriscv.dtsi index 33f7bd03fc286..c51803ed5ab84 100644 --- a/dts/riscv/riscv32-litex-vexriscv.dtsi +++ b/dts/riscv/riscv32-litex-vexriscv.dtsi @@ -4,18 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - / { #address-cells = <1>; #size-cells = <1>; compatible = "litex,vexriscv", "litex-dev"; model = "litex,vexriscv"; - chosen { - zephyr,entropy = &prbs0; - }; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -36,16 +30,6 @@ compatible = "litex,vexriscv"; ranges; - ctrl0: soc_controller@e0000000 { - compatible = "litex,soc-controller"; - reg = <0xe0000000 0x4 - 0xe0000004 0x4 - 0xe0000008 0x4>; - reg-names = "reset", - "scratch", - "bus_errors"; - }; - intc0: interrupt-controller@bc0 { compatible = "litex,vexriscv-intc0"; #address-cells = <0>; @@ -55,396 +39,5 @@ reg-names = "irq_mask", "irq_pending"; riscv,max-priority = <7>; }; - - uart0: serial@e0001800 { - compatible = "litex,uart"; - interrupt-parent = <&intc0>; - interrupts = <2 10>; - reg = <0xe0001800 0x4 - 0xe0001804 0x4 - 0xe0001808 0x4 - 0xe000180c 0x4 - 0xe0001810 0x4 - 0xe0001814 0x4 - 0xe0001818 0x4 - 0xe000181c 0x4>; - reg-names = "rxtx", - "txfull", - "rxempty", - "ev_status", - "ev_pending", - "ev_enable", - "txempty", - "rxfull"; - status = "disabled"; - }; - - spi0: spi@e0002000 { - compatible = "litex,spi"; - reg = <0xe0002000 0x4 - 0xe0002004 0x4 - 0xe0002008 0x4 - 0xe000200c 0x4 - 0xe0002010 0x4 - 0xe0002014 0x4>; - reg-names = "control", - "status", - "mosi", - "miso", - "cs", - "loopback"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - spi1: spi@e000c000 { - compatible = "litex,spi-litespi"; - interrupt-parent = <&intc0>; - reg = <0xe000c000 0x4>, - <0xe000c004 0x4>, - <0xe000c008 0x4>, - <0xe000c00c 0x4>, - <0xe000c010 0x4>, - <0xe000c014 0x4>, - <0xe000c018 0x4>, - <0xe000c01c 0x4>, - <0xe000c020 0x4>, - <0x60000000 0x1000000>; - reg-names = "phy_clk_divisor", - "mmap_dummy_bits", - "master_cs", - "master_phyconfig", - "master_rxtx", - "master_status", - "master_ev_status", - "master_ev_pending", - "master_ev_enable", - "flash_mmap"; - interrupts = <9 0>; - #address-cells = <1>; - #size-cells = <0>; - - spiflash0: flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <10000000>; - }; - }; - - timer0: timer@e0002800 { - compatible = "litex,timer0"; - interrupt-parent = <&intc0>; - interrupts = <1 0>; - reg = <0xe0002800 0x4 - 0xe0002804 0x4 - 0xe0002808 0x4 - 0xe000280c 0x4 - 0xe0002810 0x4 - 0xe0002814 0x4 - 0xe0002818 0x4 - 0xe000281c 0x4 - 0xe0002820 0x4 - 0xe0002824 0x8>; - reg-names = "load", - "reload", - "en", - "update_value", - "value", - "ev_status", - "ev_pending", - "ev_enable", - "uptime_latch", - "uptime_cycles"; - status = "disabled"; - }; - - wdt0: watchdog@e000d000 { - compatible = "litex,watchdog"; - interrupt-parent = <&intc0>; - reg = <0xe000d000 0x4>, - <0xe000d004 0x4>, - <0xe000d008 0x4>, - <0xe000d00c 0x4>, - <0xe000d010 0x4>, - <0xe000d014 0x4>; - reg-names = "control", - "cycles", - "remaining", - "ev_status", - "ev_pending", - "ev_enable"; - interrupts = <8 15>; - }; - - mdio0: mdio@e0008000 { - compatible = "litex,liteeth-mdio"; - reg = <0xe0008000 0x4>, - <0xe0008004 0x4>, - <0xe0008008 0x4>; - reg-names = "crg_reset", - "mdio_w", - "mdio_r"; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - phy0: ethernet-phy@1 { - compatible = "ethernet-phy"; - reg = <1>; - }; - }; - - eth0: ethernet@e0009800 { - compatible = "litex,liteeth"; - interrupt-parent = <&intc0>; - interrupts = <3 0>; - reg = <0xe0009800 0x4 - 0xe0009804 0x4 - 0xe0009808 0x4 - 0xe000980c 0x4 - 0xe0009810 0x4 - 0xe0009814 0x4 - 0xe0009818 0x4 - 0xe000981c 0x4 - 0xe0009820 0x4 - 0xe0009824 0x4 - 0xe0009828 0x4 - 0xe000982c 0x4 - 0xe0009830 0x4 - 0xe0009834 0x4 - 0xb0000000 0x2000>; - local-mac-address = [10 e2 d5 00 00 02]; - reg-names = "rx_slot", - "rx_length", - "rx_errors", - "rx_ev_status", - "rx_ev_pending", - "rx_ev_enable", - "tx_start", - "tx_ready", - "tx_level", - "tx_slot", - "tx_length", - "tx_ev_status", - "tx_ev_pending", - "tx_ev_enable", - "buffers"; - phy-handle = <&phy0>; - status = "disabled"; - }; - - dna0: dna@e0003800 { - compatible = "litex,dna0"; - /* DNA data is 57-bits long, - * so it requires 8 bytes. - * In LiteX each 32-bit register holds - * only a single byte of meaningful data, - * hence 8 registers. - */ - reg = <0xe0003800 0x20>; - reg-names = "mem"; - status = "disabled"; - }; - - i2c0: i2c@e0005000 { - compatible = "litex,i2c"; - reg = <0xe0005000 0x4 0xe0005004 0x4>; - reg-names = "write", "read"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - i2c1: i2c@e000d800 { - compatible = "litex,litei2c"; - interrupt-parent = <&intc0>; - reg = <0xe000d800 0x4>, - <0xe000d804 0x4>, - <0xe000d808 0x4>, - <0xe000d80c 0x4>, - <0xe000d810 0x4>, - <0xe000d814 0x4>, - <0xe000d818 0x4>, - <0xe000d81c 0x4>, - <0xe000d820 0x4>; - reg-names = "phy_speed_mode", - "master_active", - "master_settings", - "master_addr", - "master_rxtx", - "master_status", - "master_ev_status", - "master_ev_pending", - "master_ev_enable"; - interrupts = <10 0>; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - gpio_out: gpio@e0005800 { - compatible = "litex,gpio"; - reg = <0xe0005800 0x4>; - reg-names = "control"; - ngpios = <4>; - port-is-output; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio_in: gpio@e0006000 { - compatible = "litex,gpio"; - reg = <0xe0006000 0x4 - 0xe0006004 0x4 - 0xe0006008 0x4 - 0xe0006010 0x4 - 0xe0006014 0x4>; - interrupt-parent = <&intc0>; - interrupts = <4 2>; - reg-names = "base", - "irq_mode", - "irq_edge", - "irq_pend", - "irq_en"; - ngpios = <4>; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - }; - - prbs0: prbs@e0006800 { - compatible = "litex,prbs"; - reg = <0xe0006800 0x4>; - reg-names = "status"; - status = "disabled"; - }; - - pwm0: pwm@e0007000 { - compatible = "litex,pwm"; - reg = <0xe0007000 0x4 0xe0007004 0x10 0xe0007014 0x10>; - reg-names = "enable", "width", "period"; - status = "disabled"; - #pwm-cells = <2>; - }; - - i2s_rx: i2s_rx@e000a800 { - compatible = "litex,i2s"; - reg = <0xe000a800 0x4 - 0xe000a804 0x4 - 0xe000a808 0x4 - 0xe000a80c 0x4 - 0xe000a810 0x4 - 0xe000a814 0x4 - 0xb1000000 0x40000>; - interrupt-parent = <&intc0>; - interrupts = <6 2>; - #address-cells = <1>; - #size-cells = <0>; - reg-names = "ev_status", - "ev_pending", - "ev_enable", - "rx_ctl", - "rx_stat", - "rx_conf", - "fifo"; - fifo-depth = <256>; - status = "disabled"; - }; - - i2s_tx: i2s_tx@e000b000 { - compatible = "litex,i2s"; - reg = <0xe000b000 0x4 - 0xe000b004 0x4 - 0xe000b008 0x4 - 0xe000b00c 0x4 - 0xe000b010 0x4 - 0xe000b014 0x4 - 0xb2000000 0x40000>; - interrupt-parent = <&intc0>; - interrupts = <7 2>; - #address-cells = <1>; - #size-cells = <0>; - reg-names = "ev_status", - "ev_pending", - "ev_enable", - "tx_ctl", - "tx_stat", - "tx_conf", - "fifo"; - fifo-depth = <256>; - status = "disabled"; - }; - - clock-outputs { - #address-cells = <1>; - #size-cells = <0>; - - clk0: clock-controller@0 { - #clock-cells = <1>; - reg = <0>; - compatible = "litex,clkout"; - clock-output-names = "CLK_0"; - litex,clock-frequency = <11289600>; - litex,clock-phase = <0>; - litex,clock-duty-num = <1>; - litex,clock-duty-den = <2>; - litex,clock-margin = <1>; - litex,clock-margin-exp = <2>; - status = "disabled"; - }; - - clk1: clock-controller@1 { - #clock-cells = <1>; - reg = <1>; - compatible = "litex,clkout"; - clock-output-names = "CLK_1"; - litex,clock-frequency = <22579200>; - litex,clock-phase = <0>; - litex,clock-duty-num = <1>; - litex,clock-duty-den = <2>; - litex,clock-margin = <1>; - litex,clock-margin-exp = <2>; - status = "disabled"; - }; - }; - - clock0: clock@e0004800 { - compatible = "litex,clk"; - reg = <0xe0004800 0x4 - 0xe0004804 0x4 - 0xe0004808 0x4 - 0xe000480c 0x4 - 0xe0004810 0x4 - 0xe0004814 0x4 - 0xe0004818 0x4 - 0xe000481c 0x4>; - reg-names = "drp_reset", - "drp_locked", - "drp_read", - "drp_write", - "drp_drdy", - "drp_adr", - "drp_dat_w", - "drp_dat_r"; - #clock-cells = <1>; - clocks = <&clk0 0>, <&clk1 1>; - clock-output-names = "CLK_0", "CLK_1"; - litex,lock-timeout = <10>; - litex,drdy-timeout = <10>; - litex,divclk-divide-min = <1>; - litex,divclk-divide-max = <107>; - litex,clkfbout-mult-min = <2>; - litex,clkfbout-mult-max = <65>; - litex,vco-freq-min = <600000000>; - litex,vco-freq-max = <1200000000>; - litex,clkout-divide-min = <1>; - litex,clkout-divide-max = <126>; - litex,vco-margin = <0>; - status = "disabled"; - }; }; }; diff --git a/dts/rx/renesas/rx130-common.dtsi b/dts/rx/renesas/rx130-common.dtsi index d2a0db56c5f18..58463ba4e165f 100644 --- a/dts/rx/renesas/rx130-common.dtsi +++ b/dts/rx/renesas/rx130-common.dtsi @@ -25,8 +25,24 @@ compatible = "renesas,rxv1"; device_type = "cpu"; reg = <0>; + cpu-power-states = <&idle &standby>; status = "okay"; }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <300>; + }; + + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <3000>; + exit-latency-us = <500>; + }; + }; }; icu: interrupt-controller@87000 { diff --git a/dts/vendor/nordic/nrf54lm20a.dtsi b/dts/vendor/nordic/nrf54lm20a.dtsi index 233e4417986a5..7e511c8ff6c68 100644 --- a/dts/vendor/nordic/nrf54lm20a.dtsi +++ b/dts/vendor/nordic/nrf54lm20a.dtsi @@ -96,10 +96,14 @@ #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>; }; +#endif cpuapp_sram: memory@20000000 { compatible = "mmio-sram"; @@ -117,11 +121,19 @@ ranges = <0x0 0x20067c00 DT_SIZE_K(96)>; }; +#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>; ranges = <0x0 0x50000000 0x10000000>; #address-cells = <1>; #size-cells = <1>; +#endif dppic00: dppic@42000 { compatible = "nordic,nrf-dppic"; @@ -212,7 +224,7 @@ usbhs: usbhs@5a000 { compatible = "nordic,nrf-usbhs-nrf54l", "snps,dwc2"; - reg = <0x5a000 0x1000>, <0x50020000 0x1a000>; + reg = <0x5a000 0x1000>, <0x20000 0x1a000>; reg-names = "wrapper", "core"; interrupts = <90 NRF_DEFAULT_IRQ_PRIORITY>; num-in-eps = <16>; @@ -748,12 +760,16 @@ interrupts = <262 NRF_DEFAULT_IRQ_PRIORITY>; }; +#ifdef USE_NON_SECURE_ADDRESS_MAP + /* intentionally empty because WDT30 is hardware fixed to Secure */ +#else wdt30: watchdog@108000 { compatible = "nordic,nrf-wdt"; reg = <0x108000 0x620>; interrupts = <264 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; }; +#endif wdt31: watchdog@109000 { compatible = "nordic,nrf-wdt"; @@ -852,6 +868,15 @@ }; }; + nrf_mpc: memory@50041000 { + compatible = "nordic,nrf-mpc"; + reg = <0x50041000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + override-num = <5>; + override-granularity = <4096>; + }; + cpuapp_ppb: cpuapp-ppb-bus { #address-cells = <1>; #size-cells = <1>; diff --git a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi new file mode 100644 index 0000000000000..954dd8290453f --- /dev/null +++ b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuapp_rram { + /* + * Default NVM layout on NRF54LM20A 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 (1356 KB) + * 0x001D_DD00 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>; + + /* nRF54LM20A has 2036 kB of non-volatile memory (RRAM) but the last + * 96 kB 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(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(1356)>; + }; + + storage_partition: partition@1DD000 { + label = "storage"; + reg = <0x001DD000 DT_SIZE_K(32)>; + }; + }; +}; diff --git a/dts/vendor/nordic/nrf54lm20a_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_partition.dtsi new file mode 100644 index 0000000000000..049f87139d914 --- /dev/null +++ b/dts/vendor/nordic/nrf54lm20a_partition.dtsi @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuapp_rram { + partitions { + compatible = "fixed-partitions"; + #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, so we have ~1940 kB available. + */ + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(922)>; + }; + + slot1_partition: partition@f6800 { + label = "image-1"; + reg = <0xf6800 DT_SIZE_K(922)>; + }; + + storage_partition: partition@1dd000 { + label = "storage"; + reg = <0x1dd000 DT_SIZE_K(32)>; + }; + }; +}; diff --git a/include/zephyr/app_memory/mem_domain.h b/include/zephyr/app_memory/mem_domain.h index 1b97ab4d333ff..977d6b2aaec12 100644 --- a/include/zephyr/app_memory/mem_domain.h +++ b/include/zephyr/app_memory/mem_domain.h @@ -83,8 +83,13 @@ struct k_mem_domain { #endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */ /** partitions in the domain */ struct k_mem_partition partitions[CONFIG_MAX_DOMAIN_PARTITIONS]; - /** Doubly linked list of member threads */ - sys_dlist_t mem_domain_q; +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + /** Doubly linked list of member threads, + * pointer to the thread_mem_domain_node inside + * each thread's memory domain info struct. + */ + sys_dlist_t thread_mem_domain_list; +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ /** number of active partitions in the domain */ uint8_t num_partitions; }; diff --git a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h b/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h similarity index 96% rename from include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h rename to include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h index da958a51e643f..5b52a939d2a77 100644 --- a/include/zephyr/arch/arm/cortex_m/arm_mpu_mem_cfg.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h @@ -4,8 +4,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _ARM_CORTEX_M_MPU_MEM_CFG_H_ -#define _ARM_CORTEX_M_MPU_MEM_CFG_H_ +#ifndef _INCLUDE_ZEPHYR_ARCH_ARM_MPU_MEM_CFG_H_ +#define _INCLUDE_ZEPHYR_ARCH_ARM_MPU_MEM_CFG_H_ #include @@ -119,4 +119,4 @@ #endif /* !ARMV8_M_BASELINE && !ARMV8_M_MAINLINE */ -#endif /* _ARM_CORTEX_M_MPU_MEM_CFG_H_ */ +#endif /* _INCLUDE_ZEPHYR_ARCH_ARM_MPU_MEM_CFG_H_ */ diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 67c3db64e92a1..f07e35e315595 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -1970,6 +1970,18 @@ struct bt_conn_cb { struct bt_conn_remote_info *remote_info); #endif /* defined(CONFIG_BT_REMOTE_INFO) */ +#if defined(CONFIG_BT_POWER_MODE_CONTROL) + /** @brief The connection mode change + * + * This callback notifies the application that the sniff mode has changed + * + * @param conn Connection object. + * @param mode Active/Sniff mode. + * @param interval Sniff interval. + */ + void (*br_mode_changed)(struct bt_conn *conn, uint8_t mode, uint16_t interval); +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ + #if defined(CONFIG_BT_USER_PHY_UPDATE) /** @brief The PHY of the connection has changed. * @@ -2380,8 +2392,8 @@ int bt_le_oob_get_sc_data(struct bt_conn *conn, const struct bt_le_oob_sc_data **oobd_remote); /** - * Special passkey value that can be used to disable a previously - * set fixed passkey. + * DEPRECATED - use @ref BT_PASSKEY_RAND instead. Special passkey value that can be used to disable + * a previously set fixed passkey. */ #define BT_PASSKEY_INVALID 0xffffffff @@ -2393,12 +2405,15 @@ int bt_le_oob_get_sc_data(struct bt_conn *conn, * Sets a fixed passkey to be used for pairing. If set, the * pairing_confirm() callback will be called for all incoming pairings. * + * @deprecated Use @ref BT_PASSKEY_RAND and the app_passkey callback from @ref bt_conn_auth_cb + * instead. + * * @param passkey A valid passkey (0 - 999999) or BT_PASSKEY_INVALID * to disable a previously set fixed passkey. * * @return 0 on success or a negative error code on failure. */ -int bt_passkey_set(unsigned int passkey); +__deprecated int bt_passkey_set(unsigned int passkey); /** Info Structure for OOB pairing */ struct bt_conn_oob_info { @@ -2464,6 +2479,13 @@ struct bt_conn_pairing_feat { }; #endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */ +/** + * Special passkey value that can be used to generate a random passkey when using the + * app_passkey callback from @ref bt_conn_auth_cb. + * + */ +#define BT_PASSKEY_RAND 0xffffffff + /** Authenticated pairing callback structure */ struct bt_conn_auth_cb { #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT) @@ -2663,6 +2685,30 @@ struct bt_conn_auth_cb { */ void (*pincode_entry)(struct bt_conn *conn, bool highsec); #endif + +#if defined(CONFIG_BT_APP_PASSKEY) + /** @brief Allow the application to provide a passkey for pairing. + * + * If implemented, this callback allows the application to provide passkeys for pairing. + * The valid range of passkeys is 0 - 999999. The application shall return the passkey for + * pairing, or BT_PASSKEY_RAND to generate a random passkey. This callback is invoked only + * for the Passkey Entry method as defined in Core Specification Vol. 3, Part H. Which + * device in the pairing is showing the passkey depends on the IO capabilities of the + * device; see Table 2.8 of the Bluetooth Core Specification V6.0, Vol. 3, Part H for more + * details. For the purposes of this table, the device gains the "display" capability when + * this callback is non-NULL. This is irrespective of whether the callback returns a + * specified key or BT_PASSKEY_RAND. + * + * + * @note When using this callback, it is the responsibility of the application to use + * random and unique keys. + * + * @param conn Connection where pairing is currently active. + * @return Passkey for pairing, or BT_PASSKEY_RAND for the Host to generate a random + * passkey. + */ + uint32_t (*app_passkey)(struct bt_conn *conn); +#endif /* CONFIG_BT_APP_PASSKEY */ }; /** Authenticated pairing information callback structure */ @@ -2927,6 +2973,30 @@ int bt_conn_br_switch_role(const struct bt_conn *conn, uint8_t role); */ int bt_conn_br_set_role_switch_enable(const struct bt_conn *conn, bool enable); +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +/** @brief bluetooth conn check and enter sniff mode + * + * This function is used to identify which ACL link connection is to + * be placed in Sniff mode + * + * @param conn bt_conn conn + * @param min_interval Minimum sniff interval. + * @param max_interval Maxmum sniff interval. + * @param attempt Number of Baseband receive slots for sniff attempt. + * @param timeout Number of Baseband receive slots for sniff timeout. + */ +int bt_conn_br_enter_sniff_mode(struct bt_conn *conn, uint16_t min_interval, + uint16_t max_interval, uint16_t attempt, uint16_t timeout); + +/** @brief bluetooth conn check and exit sniff mode + * + * @param conn bt_conn conn + * + * @return Zero for success, non-zero otherwise. + */ +int bt_conn_br_exit_sniff_mode(struct bt_conn *conn); +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 92f51b69a4551..dc238e6fb645e 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -602,6 +602,20 @@ struct bt_hci_cp_write_default_link_policy_settings { uint16_t default_link_policy_settings; } __packed; +#define BT_HCI_OP_SNIFF_MODE BT_OP(BT_OGF_LINK_POLICY, 0x0003) /* 0x0803 */ +struct bt_hci_cp_sniff_mode { + uint16_t handle; + uint16_t max_interval; + uint16_t min_interval; + uint16_t attempt; + uint16_t timeout; +} __packed; + +#define BT_HCI_OP_EXIT_SNIFF_MODE BT_OP(BT_OGF_LINK_POLICY, 0x0004) /* 0x0804 */ +struct bt_hci_cp_exit_sniff_mode { + uint16_t handle; +} __packed; + #define BT_HCI_OP_SET_EVENT_MASK BT_OP(BT_OGF_BASEBAND, 0x0001) /* 0x0c01 */ struct bt_hci_cp_set_event_mask { uint8_t events[8]; @@ -2964,6 +2978,19 @@ struct bt_hci_evt_num_completed_packets { struct bt_hci_handle_count h[0]; } __packed; +/* Current mode */ +#define BT_ACTIVE_MODE 0x00 +#define BT_HOLD_MODE 0x01 +#define BT_SNIFF_MODE 0x02 + +#define BT_HCI_EVT_MODE_CHANGE 0x14 +struct bt_hci_evt_mode_change { + uint8_t status; + uint16_t handle; + uint8_t mode; + uint16_t interval; +} __packed; + #define BT_HCI_EVT_PIN_CODE_REQ 0x16 struct bt_hci_evt_pin_code_req { bt_addr_t bdaddr; diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index c2f548406c86f..015b8887d1143 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -88,7 +88,7 @@ struct hash_ctx { struct hash_pkt { /** Start address of input buffer */ - uint8_t *in_buf; + const uint8_t *in_buf; /** Bytes to be operated upon */ size_t in_len; diff --git a/include/zephyr/drivers/cellular.h b/include/zephyr/drivers/cellular.h index 967d53e89b409..ba78207a340c1 100644 --- a/include/zephyr/drivers/cellular.h +++ b/include/zephyr/drivers/cellular.h @@ -139,6 +139,8 @@ enum cellular_event { CELLULAR_EVENT_MODEM_INFO_CHANGED = BIT(0), /** Cellular network registration status changed */ CELLULAR_EVENT_REGISTRATION_STATUS_CHANGED = BIT(1), + /** Result of a communications link check to the modem */ + CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT = BIT(2), }; /* Opaque bit-mask large enough for all current & future events */ @@ -154,6 +156,11 @@ struct cellular_evt_registration_status { enum cellular_registration_status status; /**< New registration status */ }; +/** Payload for @ref CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT */ +struct cellular_evt_modem_comms_check_result { + bool success; /**< Communications to modem checked successfully */ +}; + /** * @brief Prototype for cellular event callbacks. * diff --git a/include/zephyr/drivers/clock_control/nrf_clock_control.h b/include/zephyr/drivers/clock_control/nrf_clock_control.h index 37fc4a1f1a852..7fa4530a6a048 100644 --- a/include/zephyr/drivers/clock_control/nrf_clock_control.h +++ b/include/zephyr/drivers/clock_control/nrf_clock_control.h @@ -188,6 +188,29 @@ uint32_t z_nrf_clock_bt_ctlr_hf_get_startup_time_us(void); /* Specifies that default precision of the clock is sufficient. */ #define NRF_CLOCK_CONTROL_PRECISION_DEFAULT 0 +/* AUXPLL devicetree takes in raw register values, these are the actual frequencies outputted */ +#define CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_MIN_HZ 80000000 +#define CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_AUDIO_44K1_HZ 11289591 +#define CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_USB24M_HZ 24000000 +#define CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_AUDIO_48K_HZ 12287963 + +/* Internal helper macro to map DT property value to output frequency */ +#define _CLOCK_CONTROL_NRF_AUXPLL_MAP_FREQ(freq_val) \ + ((freq_val) == NRF_AUXPLL_FREQ_DIV_MIN ? \ + CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_MIN_HZ : \ + (freq_val) == NRF_AUXPLL_FREQ_DIV_AUDIO_44K1 ? \ + CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_AUDIO_44K1_HZ : \ + (freq_val) == NRF_AUXPLL_FREQ_DIV_USB24M ? \ + CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_USB24M_HZ : \ + (freq_val) == NRF_AUXPLL_FREQ_DIV_AUDIO_48K ? \ + CLOCK_CONTROL_NRF_AUXPLL_FREQ_OUT_AUDIO_48K_HZ : 0) + +/* Public macro to get output frequency of AUXPLL */ +#define CLOCK_CONTROL_NRF_AUXPLL_GET_FREQ(node) \ + COND_CODE_1(DT_NODE_HAS_PROP(node, nordic_frequency), \ + (_CLOCK_CONTROL_NRF_AUXPLL_MAP_FREQ(DT_PROP(node, nordic_frequency))), \ + (0)) + struct nrf_clock_spec { uint32_t frequency; uint16_t accuracy : 15; diff --git a/include/zephyr/drivers/clock_control/nxp_clock_control.h b/include/zephyr/drivers/clock_control/nxp_clock_control.h new file mode 100644 index 0000000000000..17d6544053ced --- /dev/null +++ b/include/zephyr/drivers/clock_control/nxp_clock_control.h @@ -0,0 +1,53 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROL_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROL_H_ + +#include + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(mc_cgm), nxp_mc_cgm, okay) +#include +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(firc), nxp_firc, okay) +#define NXP_FIRC_DIV DT_ENUM_IDX(DT_NODELABEL(firc), firc_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(fxosc), nxp_fxosc, okay) +#define NXP_FXOSC_FREQ DT_PROP(DT_NODELABEL(fxosc), freq) +#define NXP_FXOSC_WORKMODE \ + (DT_ENUM_IDX(DT_NODELABEL(fxosc), workmode) == 0 ? kFXOSC_ModeCrystal : kFXOSC_ModeBypass) +#define NXP_FXOSC_DELAY DT_PROP(DT_NODELABEL(fxosc), delay) +#define NXP_FXOSC_OVERDRIVE DT_PROP(DT_NODELABEL(fxosc), overdrive) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), nxp_plldig, okay) +#define NXP_PLL_WORKMODE DT_ENUM_IDX(DT_NODELABEL(pll), workmode) +#define NXP_PLL_PREDIV DT_PROP(DT_NODELABEL(pll), prediv) +#define NXP_PLL_POSTDIV DT_PROP(DT_NODELABEL(pll), postdiv) +#define NXP_PLL_MULTIPLIER DT_PROP(DT_NODELABEL(pll), multiplier) +#define NXP_PLL_FRACLOOPDIV DT_PROP(DT_NODELABEL(pll), fracloopdiv) +#define NXP_PLL_STEPSIZE DT_PROP(DT_NODELABEL(pll), stepsize) +#define NXP_PLL_STEPNUM DT_PROP(DT_NODELABEL(pll), stepnum) +#define NXP_PLL_ACCURACY DT_ENUM_IDX(DT_NODELABEL(pll), accuracy) +#define NXP_PLL_OUTDIV_POINTER DT_PROP(DT_NODELABEL(pll), outdiv) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(mc_cgm), nxp_mc_cgm, okay) +#define NXP_PLL_MAXIDOCHANGE DT_PROP(DT_NODELABEL(mc_cgm), max_ido_change) +#define NXP_PLL_STEPDURATION DT_PROP(DT_NODELABEL(mc_cgm), step_duration) +#define NXP_PLL_CLKSRCFREQ DT_PROP(DT_NODELABEL(mc_cgm), clk_src_freq) +#define NXP_PLL_MUX_0_DC_0_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_0_div) +#define NXP_PLL_MUX_0_DC_1_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_1_div) +#define NXP_PLL_MUX_0_DC_2_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_2_div) +#define NXP_PLL_MUX_0_DC_3_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_3_div) +#define NXP_PLL_MUX_0_DC_4_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_4_div) +#define NXP_PLL_MUX_0_DC_5_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_5_div) +#define NXP_PLL_MUX_0_DC_6_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_6_div) +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROL_H_ */ diff --git a/include/zephyr/drivers/clock_control/nxp_clock_controller_sources.h b/include/zephyr/drivers/clock_control/nxp_clock_controller_sources.h new file mode 100644 index 0000000000000..e3e4f08927ef5 --- /dev/null +++ b/include/zephyr/drivers/clock_control/nxp_clock_controller_sources.h @@ -0,0 +1,36 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROLLER_SOURCES_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROLLER_SOURCES_H_ + +#include + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(firc), nxp_firc, okay) +#define NXP_FIRC_DIV DT_ENUM_IDX(DT_NODELABEL(firc), firc_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(fxosc), nxp_fxosc, okay) +#define NXP_FXOSC_FREQ DT_PROP(DT_NODELABEL(fxosc), freq) +#define NXP_FXOSC_WORKMODE \ + (DT_ENUM_IDX(DT_NODELABEL(fxosc), workmode) == 0 ? kFXOSC_ModeCrystal : kFXOSC_ModeBypass) +#define NXP_FXOSC_DELAY DT_PROP(DT_NODELABEL(fxosc), delay) +#define NXP_FXOSC_OVERDRIVE DT_PROP(DT_NODELABEL(fxosc), overdrive) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), nxp_plldig, okay) +#define NXP_PLL_WORKMODE DT_ENUM_IDX(DT_NODELABEL(pll), workmode) +#define NXP_PLL_PREDIV DT_PROP(DT_NODELABEL(pll), prediv) +#define NXP_PLL_POSTDIV DT_PROP(DT_NODELABEL(pll), postdiv) +#define NXP_PLL_MULTIPLIER DT_PROP(DT_NODELABEL(pll), multiplier) +#define NXP_PLL_FRACLOOPDIV DT_PROP(DT_NODELABEL(pll), fracloopdiv) +#define NXP_PLL_STEPSIZE DT_PROP(DT_NODELABEL(pll), stepsize) +#define NXP_PLL_STEPNUM DT_PROP(DT_NODELABEL(pll), stepnum) +#define NXP_PLL_ACCURACY DT_ENUM_IDX(DT_NODELABEL(pll), accuracy) +#define NXP_PLL_OUTDIV_POINTER DT_PROP(DT_NODELABEL(pll), outdiv) +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NXP_CLOCK_CONTROLLER_SOURCES_H_ */ diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index f8d19bc69dafa..ca3a35183f41d 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -338,6 +338,22 @@ static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, return ((uint64_t)ticks * USEC_PER_SEC) / z_impl_counter_get_frequency(dev); } +/** + * @brief Function to convert ticks to nanoseconds. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ticks Ticks. + * + * @return Converted nanoseconds. + */ +__syscall uint64_t counter_ticks_to_ns(const struct device *dev, uint32_t ticks); + +static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, + uint32_t ticks) +{ + return ((uint64_t)ticks * NSEC_PER_SEC) / z_impl_counter_get_frequency(dev); +} + /** * @brief Function to retrieve maximum top value that can be set. * diff --git a/include/zephyr/drivers/disk/sdmmc_stm32.h b/include/zephyr/drivers/disk/sdmmc_stm32.h index ed132903d605a..2472aaf3aacc8 100644 --- a/include/zephyr/drivers/disk/sdmmc_stm32.h +++ b/include/zephyr/drivers/disk/sdmmc_stm32.h @@ -28,4 +28,22 @@ */ void stm32_sdmmc_get_card_cid(const struct device *dev, uint32_t cid[4]); +/** + * @brief Get the CSD (Card Specific Data) information from the SD/MMC card. + * + * This function copies the Card Specific Data (CSD) from the internal + * HAL SD/MMC struct populated during device initialization. It does not check + * the current presence or status of the card. If the card was removed after + * initialization (or initialization failed), the returned CSD may be stale or + * all zeroes. + * + * It is the caller's responsibility to verify that the card is present and + * initialized (e.g., by calling @ref disk_access_status) before invoking this + * function. + * + * @param dev Pointer to the device structure representing the SD/MMC card. + * @param csd Pointer to an array where the CSD data will be stored. + */ +void stm32_sdmmc_get_card_csd(const struct device *dev, uint32_t csd[4]); + #endif /* ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ */ diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 9dee971c4df06..fb95d2a116b10 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -111,6 +111,26 @@ enum fuel_gauge_prop_type { FUEL_GAUGE_STATE_OF_CHARGE_ALARM, /** Low Cell Voltage Alarm (uV)*/ FUEL_GAUGE_LOW_VOLTAGE_ALARM, + /** High Cell Voltage Alarm (uV)*/ + FUEL_GAUGE_HIGH_VOLTAGE_ALARM, + /** Low Cell Current Alarm (uA)*/ + FUEL_GAUGE_LOW_CURRENT_ALARM, + /** High Cell Current Alarm (uA)*/ + FUEL_GAUGE_HIGH_CURRENT_ALARM, + /** Low Cell Temperature Alarm (dK)*/ + FUEL_GAUGE_LOW_TEMPERATURE_ALARM, + /** High Cell Temperature Alarm (dK)*/ + FUEL_GAUGE_HIGH_TEMPERATURE_ALARM, + /** Low GPIO Voltage Alarm (uV)*/ + FUEL_GAUGE_LOW_GPIO_ALARM, + /** High GPIO Voltage Alarm (uV)*/ + FUEL_GAUGE_HIGH_GPIO_ALARM, + /** GPIO Voltage (uV)*/ + FUEL_GAUGE_GPIO_VOLTAGE, + /** ADC Mode (flags) */ + FUEL_GAUGE_ADC_MODE, + /** Coulomb Counter Config (flags)*/ + FUEL_GAUGE_CC_CONFIG, /** Reserved to demark end of common fuel gauge properties */ FUEL_GAUGE_COMMON_COUNT, @@ -195,6 +215,26 @@ union fuel_gauge_prop_val { uint8_t state_of_charge_alarm; /** FUEL_GAUGE_LOW_VOLTAGE_ALARM */ uint32_t low_voltage_alarm; + /** FUEL_GAUGE_HIGH_VOLTAGE_ALARM */ + uint32_t high_voltage_alarm; + /** FUEL_GAUGE_LOW_CURRENT_ALARM */ + int32_t low_current_alarm; + /** FUEL_GAUGE_HIGH_CURRENT_ALARM */ + int32_t high_current_alarm; + /** FUEL_GAUGE_LOW_TEMPERATURE_ALARM */ + uint16_t low_temperature_alarm; + /** FUEL_GAUGE_HIGH_TEMPERATURE_ALARM */ + uint16_t high_temperature_alarm; + /** FUEL_GAUGE_GPIO_VOLTAGE*/ + int32_t gpio_voltage; + /** FUEL_GAUGE_LOW_GPIO_ALARM */ + int32_t low_gpio_alarm; + /** FUEL_GAUGE_HIGH_GPIO_ALARM */ + int32_t high_gpio_alarm; + /** FUEL_GAUGE_ADC_MODE */ + uint8_t adc_mode; + /** FUEL_GAUGE_CC_CONFIG */ + uint8_t cc_config; }; /** diff --git a/include/zephyr/drivers/gnss/gnss_emul.h b/include/zephyr/drivers/gnss/gnss_emul.h new file mode 100644 index 0000000000000..4416ce26cfed6 --- /dev/null +++ b/include/zephyr/drivers/gnss/gnss_emul.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 Embeint Pty Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GNSS_GNSS_EMUL_H_ +#define ZEPHYR_DRIVERS_GNSS_GNSS_EMUL_H_ + +#include + +#include +#include + +/** + * @brief Clear all internal GNSS data of the emulator + * + * @param dev GNSS emulator device + */ +void gnss_emul_clear_data(const struct device *dev); + +/** + * @brief Set the internal GNSS data of the emulator + * + * @param dev GNSS emulator device + * @param nav Updated navigation state + * @param info Updated GNSS fix information + * @param boot_realtime_ms Unix timestamp associated with system boot + */ +void gnss_emul_set_data(const struct device *dev, const struct navigation_data *nav, + const struct gnss_info *info, int64_t boot_realtime_ms); + +/** + * @brief Retrieve the last configured fix rate, regardless of PM state + * + * @param dev GNSS emulator device + * @param fix_interval_ms Output fix interval + * + * @retval 0 On success + */ +int gnss_emul_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms); + +/** + * @brief Retrieve the last configured navigation mode, regardless of PM state + * + * @param dev GNSS emulator device + * @param mode Output navigation mode + * + * @retval 0 On success + */ +int gnss_emul_get_navigation_mode(const struct device *dev, enum gnss_navigation_mode *mode); + +/** + * @brief Retrieve the last configured systems, regardless of PM state + * + * @param dev GNSS emulator device + * @param systems Output GNSS systems + * + * @retval 0 On success + */ +int gnss_emul_get_enabled_systems(const struct device *dev, gnss_systems_t *systems); + +#endif /* ZEPHYR_DRIVERS_GNSS_GNSS_EMUL_H_ */ diff --git a/include/zephyr/drivers/reset/mchp_reset.h b/include/zephyr/drivers/reset/mchp_reset.h new file mode 100644 index 0000000000000..9c08a48645cdf --- /dev/null +++ b/include/zephyr/drivers/reset/mchp_reset.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file mchp_reset.h + * @brief Microchip Reset header + * + * This header defines the macros for use with the Microchip reset controller driver. + */ + +#ifndef INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RESET_H_ +#define INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RESET_H_ + +#if defined(CONFIG_RESET_MCHP_RSTC_G1) +#include "mchp_rstc_g1.h" +#endif + +#endif /* INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RESET_H_ */ diff --git a/include/zephyr/drivers/reset/mchp_rstc_g1.h b/include/zephyr/drivers/reset/mchp_rstc_g1.h new file mode 100644 index 0000000000000..174fca359c921 --- /dev/null +++ b/include/zephyr/drivers/reset/mchp_rstc_g1.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file mchp_rstc_g1.h + * @brief Microchip RSTC G1 reset controller header + * + * This header includes the Microchip RSTC G1 macro definitions. + */ + +#ifndef INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RSTC_G1_H_ +#define INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RSTC_G1_H_ + +/** + * @enum rstc_g1_rcause + * @brief Reset cause flags for Microchip RSTC G1. + * + * This enumeration defines the possible reset causes as indicated by the + * RSTC_RCAUSE register in the Microchip RSTC G1 reset controller. + */ +enum rstc_g1_rcause { + RSTC_G1_RCAUSE_POR = 0, /* Power-on Reset */ + RSTC_G1_RCAUSE_BOD12 = 1, /* Brown-Out 1.2V Detector Reset */ + RSTC_G1_RCAUSE_BOD33 = 2, /* Brown-Out 3.3V Detector Reset */ + RSTC_G1_RCAUSE_NVM = 3, /* NVM Reset */ + RSTC_G1_RCAUSE_EXT = 4, /* External Reset */ + RSTC_G1_RCAUSE_WDT = 5, /* Watchdog Reset */ + RSTC_G1_RCAUSE_SYST = 6, /* System Reset Request */ + RSTC_G1_RCAUSE_BACKUP = 7 /* Backup Reset */ +}; + +#endif /* INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RSTC_G1_H_ */ diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 2e92f100542f4..1ebd5d255477e 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -489,15 +489,16 @@ static inline bool sensor_chan_spec_eq(struct sensor_chan_spec chan_spec0, */ struct sensor_decoder_api { /** - * @brief Get the number of frames in the current buffer. + * @brief Get the @p frame_count for a specified @p chan_spec from the @p buffer * - * @param[in] buffer The buffer provided on the @ref rtio context. - * @param[in] channel The channel to get the count for - * @param[out] frame_count The number of frames on the buffer (at least 1) - * @return 0 on success - * @return -ENOTSUP if the channel/channel_idx aren't found + * @param[in] buffer The buffer provided via the @ref rtio context + * @param[in] chan_spec The channel specification to count + * @param[out] frame_count The frame count for a specified @p chan_spec + * + * @retval 0 On success + * @retval -EINVAL Invalid channel specification */ - int (*get_frame_count)(const uint8_t *buffer, struct sensor_chan_spec channel, + int (*get_frame_count)(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint16_t *frame_count); /** diff --git a/include/zephyr/drivers/sensor/max32664c.h b/include/zephyr/drivers/sensor/max32664c.h new file mode 100644 index 0000000000000..128f15ead201a --- /dev/null +++ b/include/zephyr/drivers/sensor/max32664c.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2025 Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX32664C_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX32664C_H_ + +#include + +/** @brief Converts a motion time in milli-seconds to the corresponding value for the MAX32664C + * sensor. This macro should be used when configuring the motion based wake up settings for the + * sensor. + */ +#define MAX32664C_MOTION_TIME(ms) ((uint8_t)((ms * 25UL) / 1000)) + +/** @brief Converts a motion threshold in milli-g (Acceleration) to the corresponding value for the + * MAX32664C sensor. This macro should be used when configuring the motion based wake up settings + * for the sensor. + */ +#define MAX32664C_MOTION_THRESHOLD(mg) ((uint8_t)((mg * 16UL) / 1000)) + +/* MAX32664C specific channels */ +enum sensor_channel_max32664c { + /** Heart rate value (bpm) */ + SENSOR_CHAN_MAX32664C_HEARTRATE = SENSOR_CHAN_PRIV_START, + /** SpO2 value (%) */ + SENSOR_CHAN_MAX32664C_BLOOD_OXYGEN_SATURATION, + /** Respiration rate (breaths per minute) */ + SENSOR_CHAN_MAX32664C_RESPIRATION_RATE, + /** Skin contact (1 -> Skin contact, 0, no contact) */ + SENSOR_CHAN_MAX32664C_SKIN_CONTACT, + /** Activity class (index). The reported index is vendor specific. */ + SENSOR_CHAN_MAX32664C_ACTIVITY, + /** Step counter */ + SENSOR_CHAN_MAX32664C_STEP_COUNTER, +}; + +/* MAX32664C specific attributes */ +enum sensor_attribute_max32664c { + /** Gender of the subject being monitored */ + SENSOR_ATTR_MAX32664C_GENDER = SENSOR_ATTR_PRIV_START, + /** Age of the subject being monitored */ + SENSOR_ATTR_MAX32664C_AGE, + /** Weight of the subject being monitored */ + SENSOR_ATTR_MAX32664C_WEIGHT, + /** Height of the subject being monitored */ + SENSOR_ATTR_MAX32664C_HEIGHT, + /** Get / Set the operation mode of a sensor. This can be used to + * switch between different measurement modes when a sensor supports them. + */ + SENSOR_ATTR_MAX32664C_OP_MODE, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Device operating modes for the MAX32664C sensor. + * + * This enum defines the various operating modes that the MAX32664C sensor + * can be configured to. These modes control the sensor's behavior and + * functionality, such as calibration, idle state, raw data output, and + * algorithm-based operations. + */ +enum max32664c_device_mode { + MAX32664C_OP_MODE_IDLE, /**< Idle mode, no algorithm, */ + /**< sensors or wake on motion running */ + MAX32664C_OP_MODE_RAW, /**< Raw output mode */ + /* For hardware testing purposes, the user may choose to start the sensor hub to collect + * raw PPG samples. In this case, the host configures the sensor hub to work in Raw Data + * mode (no algorithm) by enabling the accelerometer and the AFE. + */ + MAX32664C_OP_MODE_ALGO_AEC, /**< Algorithm AEC mode */ + /* Automatic Exposure Control (AEC) is Maxim’s gain control algorithm that is superior to + * AGC. The AEC algorithm optimally maintains the best SNR range and power optimization. The + * targeted SNR range is maintained regardless of skin color or ambient temperature within + * the limits of the LED currents configurations; The AEC dynamically manages the + * appropriate register settings for sampling rate, LED current, pulse width and integration + * time. + */ + MAX32664C_OP_MODE_ALGO_AEC_EXT, /**< Algorithm with extended reports */ + MAX32664C_OP_MODE_ALGO_AGC, /**< Algorithm AGC mode */ + /* In this mode, the wearable algorithm suite (SpO2 and WHRM) is enabled and the R value, + * SpO2, SpO2 confidence level, heart rate, heart rate confidence level, RR value, and + * activity class are reported. Furthermore, automatic gain control (AGC) is enabled. + * Because AGC is a subset of AEC functionality, to enable AGC, AEC still needs to be + * enabled. However, automatic calculation of target PD should be turned off, and the + * desired level of AGC target PD current is set by the user. The user may change the + * algorithm to the desired configuration mode. If signal quality is poor, the user may need + * to adjust the AGC settings to maintain optimal performance. If signal quality is low, a + * LowSNR flag will be set. Excessive motion is also reported with a flag. + */ + MAX32664C_OP_MODE_ALGO_AGC_EXT, /**< Algorithm AGC with extended reports */ + MAX32664C_OP_MODE_SCD, /**< SCD only mode */ + MAX32664C_OP_MODE_WAKE_ON_MOTION, /**< Wake on motion mode */ + MAX32664C_OP_MODE_EXIT_WAKE_ON_MOTION, /**< Exit wake on motion mode */ + MAX32664C_OP_MODE_STOP_ALGO, /**< Stop the current algorithm */ +}; + +/** @brief Algorithm modes for the MAX32664C sensor. + * + * This enum defines the various algorithm modes supported by the MAX32664C sensor. + * These modes determine the type of data processing performed by the sensor, + * such as continuous heart rate monitoring, SpO2 calculation, or activity tracking. + */ +enum max32664c_algo_mode { + MAX32664C_ALGO_MODE_CONT_HR_CONT_SPO2, + MAX32664C_ALGO_MODE_CONT_HR_SHOT_SPO2, + MAX32664C_ALGO_MODE_CONT_HRM, + /* NOTE: These algorithm modes are untested */ + /*MAX32664C_ALGO_MODE_SAMPLED_HRM,*/ + /*MAX32664C_ALGO_MODE_SAMPLED_HRM_SHOT_SPO2,*/ + /*MAX32664C_ALGO_MODE_ACTIVITY_TRACK,*/ + /*MAX32664C_ALGO_MODE_SAMPLED_HRM_FAST_SPO2 = 7,*/ +}; + +/** @brief Gender settings for the MAX32664C sensor. + * + * This enum defines the supported gender settings for the MAX32664C sensor. + */ +enum max32664c_algo_gender { + MAX32664_ALGO_GENDER_MALE, + MAX32664_ALGO_GENDER_FEMALE, +}; + +/** @brief Activity classes for the MAX32664C sensor. + * + * This enum defines the supported activity classes for the MAX32664C sensor. + */ +enum max32664c_algo_activity { + MAX32664C_ALGO_ACTIVITY_REST, + MAX32664C_ALGO_ACTIVITY_OTHER, + MAX32664C_ALGO_ACTIVITY_WALK, + MAX32664C_ALGO_ACTIVITY_RUN, + MAX32664C_ALGO_ACTIVITY_BIKE, +}; + +/** @brief Data structure for external accelerometer data. + * + * This structure is used to represent the accelerometer data that can be + * collected from an external accelerometer and then fed into the MAX32664C + * sensor hub. It contains the x, y, and z acceleration values. + * This structure is only used when the external accelerometer is enabled. + */ +struct max32664c_acc_data_t { + int16_t x; + int16_t y; + int16_t z; +} __packed; + +#ifdef CONFIG_MAX32664C_USE_FIRMWARE_LOADER +/** @brief Enter the bootloader mode and run a firmware update. + * @param dev Pointer to device + * @param firmware Pointer to firmware data + * @param size Size of the firmware + * @return 0 when successful + */ +int max32664c_bl_enter(const struct device *dev, const uint8_t *firmware, uint32_t size); + +/** @brief Leave the bootloader and enter the application mode. + * @param dev Pointer to device + * @return 0 when successful + */ +int max32664c_bl_leave(const struct device *dev); +#endif /* CONFIG_MAX32664C_USE_FIRMWARE_LOADER */ + +#ifdef CONFIG_MAX32664C_USE_EXTERNAL_ACC +/** @brief Fill the FIFO buffer with accelerometer data + * NOTE: This function supports up to 16 samples and it must be called + * periodically to provide accelerometer data to the MAX32664C! + * @param dev Pointer to device + * @param data Pointer to the accelerometer data structure + * @param length Number of samples to fill + * @return 0 when successful + */ +int max32664c_acc_fill_fifo(const struct device *dev, struct max32664c_acc_data_t *data, + uint8_t length); +#endif /* CONFIG_MAX32664C_USE_EXTERNAL_ACC*/ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX32664C_H_ */ diff --git a/include/zephyr/drivers/sensor/veml6031.h b/include/zephyr/drivers/sensor/veml6031.h index 8d9ee6874f01e..65808d5a79739 100644 --- a/include/zephyr/drivers/sensor/veml6031.h +++ b/include/zephyr/drivers/sensor/veml6031.h @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + /** * @file * @brief Header file for extended sensor API of VEML6031 sensor @@ -24,25 +26,6 @@ extern "C" { #endif -/** - * @brief VEML6031 integration time options for ambient light measurements. - * - * Possible values for @ref SENSOR_ATTR_VEML6031_IT custom attribute. - */ -enum veml6031_it { - VEML6031_IT_3_125, /**< 3.125 ms */ - VEML6031_IT_6_25, /**< 6.25 ms */ - VEML6031_IT_12_5, /**< 12.5 ms */ - VEML6031_IT_25, /**< 25 ms */ - VEML6031_IT_50, /**< 50 ms */ - VEML6031_IT_100, /**< 100 ms */ - VEML6031_IT_200, /**< 200 ms */ - VEML6031_IT_400, /**< 400 ms */ - /** @cond INTERNAL_HIDDEN */ - VEML6031_IT_COUNT, - /** @endcond */ -}; - /** * @brief VEML6031 size options for ambient light measurements. * @@ -56,31 +39,6 @@ enum veml6031_div4 { /** @endcond */ }; -/** - * @brief VEML6031 gain options for ambient light measurements. - */ -enum veml6031_gain { - VEML6031_GAIN_1 = 0x00, /**< 1x gain */ - VEML6031_GAIN_2 = 0x01, /**< 2x gain */ - VEML6031_GAIN_0_66 = 0x02, /**< 0.66x gain */ - VEML6031_GAIN_0_5 = 0x03, /**< 0.5x gain */ - /** @cond INTERNAL_HIDDEN */ - VEML6031_GAIN_COUNT = 4, - /** @endcond */ -}; - -/** - * @brief VEML6031 ALS interrupt persistence protect number options. - * - * Possible values for @ref SENSOR_ATTR_VEML6031_PERS custom attribute. - */ -enum veml6031_pers { - VEML6031_PERS_1 = 0x00, /**< 1 measurement */ - VEML6031_PERS_2 = 0x01, /**< 2 measurements */ - VEML6031_PERS_4 = 0x02, /**< 4 measurements */ - VEML6031_PERS_8 = 0x03, /**< 8 measurements */ -}; - /** * @brief Custom sensor attributes for VEML6031 sensor. * diff --git a/include/zephyr/drivers/sensor/veml6046.h b/include/zephyr/drivers/sensor/veml6046.h new file mode 100644 index 0000000000000..f8c8d39305994 --- /dev/null +++ b/include/zephyr/drivers/sensor/veml6046.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025 Andreas Klinger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/** + * @file + * @brief Header file for extended sensor API of VEML6046 sensor. + * @ingroup veml6046_interface + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML6046_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML6046_H_ + +/** + * @defgroup veml6046_interface VEML6046 + * @ingroup sensor_interface_ext + * @brief Vishay VEML6046 RGBIR Sensor + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief VEML6046 size options for light measurements. + * + * Possible values for @ref SENSOR_ATTR_VEML6046_PDD custom attribute. + */ +enum veml6046_pdd { + VEML6046_SIZE_2_2 = 0x00, /**< 2/2 photodiode size */ + VEML6046_SIZE_1_2 = 0x01, /**< 1/2 photodiode size */ + /** @cond INTERNAL_HIDDEN */ + VEML6046_PDD_COUNT = 2, + /** @endcond */ +}; + +/** + * @brief VEML6046 specific sensor attributes. + * + * For high and low threshold window settings (G_THDH_L, G_THDH_H, G_THDL_L and + * G_THDL_H) use the generic attributes @ref SENSOR_ATTR_UPPER_THRESH and + * @ref SENSOR_ATTR_LOWER_THRESH with 16-bit unsigned integer values. Both + * threshold settings are in lux and converted by the driver to a value + * compatible with the sensor. This conversion depends on the current gain, + * integration time and effective photodiode size settings. So a change in + * gain, integration time or effective photodiode size usually requires an + * update of threshold window settings. To get the correct threshold values + * into the sensor update the thresholds -after- a change of gain or + * integration time. + * + * When the sensor goes into saturation @c -E2BIG is returned. This happens + * when the maximum value @c 0xFFFF is returned as raw ALS value. In this case + * it's up to the user to reduce one or more of the following attributes to + * come back into the optimal measurement range of the sensor: + * @ref SENSOR_ATTR_VEML6046_GAIN (gain) + * @ref SENSOR_ATTR_VEML6046_IT (integration time) + * @ref SENSOR_ATTR_VEML6046_PDD (effective photodiode size) + */ +enum sensor_attribute_veml6046 { + /** + * @brief Integration time setting for measurements (IT). + * + * Use enum veml6046_it for attribute values. + */ + SENSOR_ATTR_VEML6046_IT = SENSOR_ATTR_PRIV_START, + /** + * @brief Effective photodiode size (PDD) + * + * Use enum veml6046_pdd for attribute values. + */ + SENSOR_ATTR_VEML6046_PDD, + /** + * @brief Gain setting for measurements (GAIN). + * + * Use enum veml6046_gain for attribute values. + */ + SENSOR_ATTR_VEML6046_GAIN, + /** + * @brief Persistence protect number setting (PERS). + * + * Use enum veml6046_pers for attribute values. + */ + SENSOR_ATTR_VEML6046_PERS, +}; + +/** + * @brief VEML6046 specific sensor channels. + */ +enum sensor_channel_veml6046 { + /** + * @brief Channel for raw red sensor values. + * + * This channel represents the raw measurement counts provided by the + * sensor register. It is useful for estimating good values for + * integration time, effective photodiode size and gain attributes in + * fetch and get mode. + * + * For future implementations with triggers it can also be used to + * estimate the threshold window attributes for the sensor interrupt + * handling. + * + * It cannot be fetched directly. Instead, this channel's value is + * fetched implicitly using @ref SENSOR_CHAN_RED. + * Trying to call sensor_channel_fetch_chan with this enumerator + * as an argument will result in a @c -ENOTSUP. + */ + SENSOR_CHAN_VEML6046_RED_RAW_COUNTS = SENSOR_CHAN_PRIV_START, + + /** + * @brief Channel for green sensor values. + * + * This channel is the raw green channel count output of the sensor. + * About fetching the same as for + * @ref SENSOR_CHAN_VEML6046_RED_RAW_COUNTS applies. + */ + SENSOR_CHAN_VEML6046_GREEN_RAW_COUNTS, + + /** + * @brief Channel for blue sensor values. + * + * This channel is the raw blue channel count output of the sensor. + * About fetching the same as for + * @ref SENSOR_CHAN_VEML6046_RED_RAW_COUNTS applies. + */ + SENSOR_CHAN_VEML6046_BLUE_RAW_COUNTS, + + /** + * @brief Channel for IR sensor values. + * + * This channel is the raw IR channel count output of the sensor. About + * fetching the same as for + * @ref SENSOR_CHAN_VEML6046_RED_RAW_COUNTS applies. + */ + SENSOR_CHAN_VEML6046_IR_RAW_COUNTS, +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML6046_H_ */ diff --git a/include/zephyr/drivers/sensor/veml60xx-common.h b/include/zephyr/drivers/sensor/veml60xx-common.h new file mode 100644 index 0000000000000..0a9aea8dea99f --- /dev/null +++ b/include/zephyr/drivers/sensor/veml60xx-common.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2025 Andreas Klinger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Header file for extended sensor API of VEML60xx sensor family + * @ingroup veml60xx_interface + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML60XX_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML60XX_H_ + +/** + * @defgroup veml60xx_interface VEML60XX + * @ingroup sensor_interface_ext + * @brief Vishay VEML60xx sensor family common attributes + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief VEML60xx integration time options for ambient light measurements. + * + * Possible values for @ref SENSOR_ATTR_VEML6031_IT and + * @ref SENSOR_ATTR_VEML6046_IT custom attribute. + */ +enum veml60xx_it { + VEML60XX_IT_3_125, /**< 3.125 ms */ + VEML60XX_IT_6_25, /**< 6.25 ms */ + VEML60XX_IT_12_5, /**< 12.5 ms */ + VEML60XX_IT_25, /**< 25 ms */ + VEML60XX_IT_50, /**< 50 ms */ + VEML60XX_IT_100, /**< 100 ms */ + VEML60XX_IT_200, /**< 200 ms */ + VEML60XX_IT_400, /**< 400 ms */ + /** @cond INTERNAL_HIDDEN */ + VEML60XX_IT_COUNT, + /** @endcond */ +}; + +/* + * @brief VEML60xx integration time struct. + */ +struct veml60xx_it_data { + enum veml60xx_it num; + uint8_t val; + int us; +}; + +/* + * @brief VEML60xx integration time setting values. + * + * The enumerators of enum veml60xx_it provide indices into this array to get + * the related value for the ALS_IT configuration bits. + */ +static const struct veml60xx_it_data veml60xx_it_values[VEML60XX_IT_COUNT] = { + {VEML60XX_IT_3_125, 0x00, 3125}, /* 3.125 - 0b0000 */ + {VEML60XX_IT_6_25, 0x01, 6250}, /* 6.25 - 0b0001 */ + {VEML60XX_IT_12_5, 0x02, 12500}, /* 12.5 - 0b0010 */ + {VEML60XX_IT_25, 0x03, 25000}, /* 25 - 0b0011 */ + {VEML60XX_IT_50, 0x04, 50000}, /* 50 - 0b0100 */ + {VEML60XX_IT_100, 0x05, 100000}, /* 100 - 0b0101 */ + {VEML60XX_IT_200, 0x06, 200000}, /* 200 - 0b0110 */ + {VEML60XX_IT_400, 0x07, 400000}, /* 400 - 0b0111 */ +}; +/** + * @brief VEML60xx gain options for ambient light measurements. + */ +enum veml60xx_gain { + VEML60XX_GAIN_1 = 0x00, /**< 1x gain */ + VEML60XX_GAIN_2 = 0x01, /**< 2x gain */ + VEML60XX_GAIN_0_66 = 0x02, /**< 0.66x gain */ + VEML60XX_GAIN_0_5 = 0x03, /**< 0.5x gain */ + /** @cond INTERNAL_HIDDEN */ + VEML60XX_GAIN_COUNT = 4, + /** @endcond */ +}; + +/** + * @brief VEML60xx ALS interrupt persistence protect number options. + * + * Possible values for @ref SENSOR_ATTR_VEML6031_PERS and + * @ref SENSOR_ATTR_VEML6046_PERS custom attribute. + */ +enum veml60xx_pers { + VEML60XX_PERS_1 = 0x00, /**< 1 measurement */ + VEML60XX_PERS_2 = 0x01, /**< 2 measurements */ + VEML60XX_PERS_4 = 0x02, /**< 4 measurements */ + VEML60XX_PERS_8 = 0x03, /**< 8 measurements */ +}; + + +static inline bool veml60xx_gain_in_range(int32_t gain) +{ + return (gain >= VEML60XX_GAIN_1) && (gain <= VEML60XX_GAIN_0_5); +} + +static inline bool veml60xx_it_in_range(int32_t it) +{ + return (it >= VEML60XX_IT_3_125) && (it <= VEML60XX_IT_400); +} + +static inline bool veml60xx_pers_in_range(int32_t pers) +{ + return (pers >= VEML60XX_PERS_1) && (pers <= VEML60XX_PERS_8); +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_VEML60XX_H_ */ diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index 285c63703a23c..d9c4217357d9c 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -136,4 +136,6 @@ #define MCUX_ELS_CLK MCUX_LPC_CLK_ID(0x19, 0x0) +#define MCUX_MICFIL_CLK MCUX_LPC_CLK_ID(0x20, 0x00) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ diff --git a/include/zephyr/dt-bindings/clock/microchip_sam_pmc.h b/include/zephyr/dt-bindings/clock/microchip_sam_pmc.h index 0656f3de97162..a2e2fa94051df 100644 --- a/include/zephyr/dt-bindings/clock/microchip_sam_pmc.h +++ b/include/zephyr/dt-bindings/clock/microchip_sam_pmc.h @@ -33,4 +33,9 @@ #define UTMI2 1 #define UTMI3 2 +/* SAMA7D65 */ +#define PMC_LVDSPLL (PMC_MAIN + 12) +#define PMC_MCK3 (PMC_MAIN + 20) +#define PMC_MCK5 (PMC_MAIN + 21) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MICROCHIP_SAM_PMC_H_ */ diff --git a/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h b/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h new file mode 100644 index 0000000000000..6debb6a21bc8c --- /dev/null +++ b/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h @@ -0,0 +1,113 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_MC_CGM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_MC_CGM_H_ + +/* Define a set of macros related to NXP mc_cgm IP configuration parameter */ +#define NXP_PLL_MAXIDOCHANGE DT_PROP(DT_NODELABEL(mc_cgm), max_ido_change) +#define NXP_PLL_STEPDURATION DT_PROP(DT_NODELABEL(mc_cgm), step_duration) +#define NXP_PLL_CLKSRCFREQ DT_PROP(DT_NODELABEL(mc_cgm), clk_src_freq) +#define NXP_PLL_MUX_0_DC_0_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_0_div) +#define NXP_PLL_MUX_0_DC_1_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_1_div) +#define NXP_PLL_MUX_0_DC_2_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_2_div) +#define NXP_PLL_MUX_0_DC_3_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_3_div) +#define NXP_PLL_MUX_0_DC_4_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_4_div) +#define NXP_PLL_MUX_0_DC_5_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_5_div) +#define NXP_PLL_MUX_0_DC_6_DIV DT_PROP(DT_NODELABEL(mc_cgm), mux_0_dc_6_div) + +/* Note- clock identifiers in this file must be unique, + * as the driver uses them in a switch case + */ + +#define MCUX_MC_CGM_CLK_ID(high, low) ((high << 8) | (low)) + +/* These IDs are used within SOC macros, and thus cannot be defined + * using the standard MCUX_MC_CGM_CLK_ID form + */ +/* --------------------- System layer clock --------------------- */ +#define MCUX_CORESYS_CLK MCUX_MC_CGM_CLK_ID(0x00, 0x00) +#define MCUX_AIPSPLAT_CLK MCUX_MC_CGM_CLK_ID(0x01, 0x00) +#define MCUX_AIPSSLOW_CLK MCUX_MC_CGM_CLK_ID(0x02, 0x00) +#define MCUX_HSE_CLK MCUX_MC_CGM_CLK_ID(0x03, 0x00) +#define MCUX_DCM_CLK MCUX_MC_CGM_CLK_ID(0x04, 0x00) +#define MCUX_LBIST_CLK MCUX_MC_CGM_CLK_ID(0x05, 0x00) +#define MCUX_QSPI_CLK MCUX_MC_CGM_CLK_ID(0x06, 0x00) + +/* --------------------- MC_CGM clock --------------------- */ +#define MCUX_FIRC_CLK MCUX_MC_CGM_CLK_ID(0x10, 0x00) +#define MCUX_SIRC_CLK MCUX_MC_CGM_CLK_ID(0x11, 0x00) +#define MCUX_FXOSC_CLK MCUX_MC_CGM_CLK_ID(0x12, 0x00) +#define MCUX_SXOSC_CLK MCUX_MC_CGM_CLK_ID(0x13, 0x00) +#define MCUX_PLLPHI0_CLK MCUX_MC_CGM_CLK_ID(0x14, 0x00) +#define MCUX_PLLPHI1_CLK MCUX_MC_CGM_CLK_ID(0x14, 0x01) + +/* --------------------- Peripheral clock --------------------- */ +#define MCUX_ADC0_CLK MCUX_MC_CGM_CLK_ID(0x20, 0x00) +#define MCUX_ADC1_CLK MCUX_MC_CGM_CLK_ID(0x20, 0x01) +#define MCUX_ADC2_CLK MCUX_MC_CGM_CLK_ID(0x20, 0x02) + +#define MCUX_BCTU_CLK MCUX_MC_CGM_CLK_ID(0x21, 0x00) + +#define MCUX_CMP0_CLK MCUX_MC_CGM_CLK_ID(0x22, 0x00) +#define MCUX_CMP1_CLK MCUX_MC_CGM_CLK_ID(0x22, 0x01) +#define MCUX_CMP2_CLK MCUX_MC_CGM_CLK_ID(0x22, 0x02) + +#define MCUX_EMIOS_CLK MCUX_MC_CGM_CLK_ID(0x23, 0x00) + +#define MCUX_FLEXCAN0_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x00) +#define MCUX_FLEXCAN1_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x01) +#define MCUX_FLEXCAN2_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x02) +#define MCUX_FLEXCAN3_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x03) +#define MCUX_FLEXCAN4_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x04) +#define MCUX_FLEXCAN5_CLK MCUX_MC_CGM_CLK_ID(0x24, 0x05) + +#define MCUX_FLEXIO_CLK MCUX_MC_CGM_CLK_ID(0x25, 0x00) + +#define MCUX_LPI2C0_CLK MCUX_MC_CGM_CLK_ID(0x26, 0x00) +#define MCUX_LPI2C1_CLK MCUX_MC_CGM_CLK_ID(0x26, 0x01) + +#define MCUX_LPSPI0_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x00) +#define MCUX_LPSPI1_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x01) +#define MCUX_LPSPI2_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x02) +#define MCUX_LPSPI3_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x03) +#define MCUX_LPSPI4_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x04) +#define MCUX_LPSPI5_CLK MCUX_MC_CGM_CLK_ID(0x27, 0x05) + +#define MCUX_LPUART0_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x00) +#define MCUX_LPUART1_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x01) +#define MCUX_LPUART2_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x02) +#define MCUX_LPUART3_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x03) +#define MCUX_LPUART4_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x04) +#define MCUX_LPUART5_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x05) +#define MCUX_LPUART6_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x06) +#define MCUX_LPUART7_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x07) +#define MCUX_LPUART8_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x08) +#define MCUX_LPUART9_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x09) +#define MCUX_LPUART10_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0A) +#define MCUX_LPUART11_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0B) +#define MCUX_LPUART12_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0C) +#define MCUX_LPUART13_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0D) +#define MCUX_LPUART14_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0E) +#define MCUX_LPUART15_CLK MCUX_MC_CGM_CLK_ID(0x28, 0x0F) + +#define MCUX_PIT0_CLK MCUX_MC_CGM_CLK_ID(0x29, 0x00) +#define MCUX_PIT1_CLK MCUX_MC_CGM_CLK_ID(0x29, 0x01) +#define MCUX_PIT2_CLK MCUX_MC_CGM_CLK_ID(0x29, 0x02) + +#define MCUX_SAI0_CLK MCUX_MC_CGM_CLK_ID(0x2A, 0x00) +#define MCUX_SAI1_CLK MCUX_MC_CGM_CLK_ID(0x2A, 0x01) + +#define MCUX_STM0_CLK MCUX_MC_CGM_CLK_ID(0x2B, 0x00) +#define MCUX_STM1_CLK MCUX_MC_CGM_CLK_ID(0x2B, 0x01) + +/* --------------------- Partition 2 clock --------------------- */ +#define MCUX_QSPISF_CLK MCUX_MC_CGM_CLK_ID(0x2C, 0x00) +#define MCUX_EMACRX_CLK MCUX_MC_CGM_CLK_ID(0x2C, 0x01) +#define MCUX_EMACTX_CLK MCUX_MC_CGM_CLK_ID(0x2C, 0x02) +#define MCUX_EMACTS_CLK MCUX_MC_CGM_CLK_ID(0x2C, 0x03) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_MC_CGM_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wba_clock.h b/include/zephyr/dt-bindings/clock/stm32wba_clock.h index f1ae4be8fcc15..82deec11ee256 100644 --- a/include/zephyr/dt-bindings/clock/stm32wba_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wba_clock.h @@ -70,6 +70,7 @@ #define TIMIC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, CCIPR1_REG) /** CCIPR2 devices */ #define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR2_REG) +#define OTGHS_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR2_REG) /** CCIPR3 devices */ #define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR3_REG) #define SPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 3, CCIPR3_REG) diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 43721f1249534..db7713d6d407d 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -178,8 +178,10 @@ typedef struct _thread_stack_info _thread_stack_info_t; #if defined(CONFIG_USERSPACE) struct _mem_domain_info { +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST /** memory domain queue node */ - sys_dnode_t mem_domain_q_node; + sys_dnode_t thread_mem_domain_node; +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ /** memory domain of the thread */ struct k_mem_domain *mem_domain; }; diff --git a/include/zephyr/net/net_core.h b/include/zephyr/net/net_core.h index 505683eb139b3..cedc2686ff7ec 100644 --- a/include/zephyr/net/net_core.h +++ b/include/zephyr/net/net_core.h @@ -181,6 +181,18 @@ static inline int net_send_data(struct net_pkt *pkt) #define NET_TC_COUNT 0 #endif /* CONFIG_NET_TC_TX_COUNT && CONFIG_NET_TC_RX_COUNT */ +#if CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO +#define NET_TC_TX_EFFECTIVE_COUNT (NET_TC_TX_COUNT + 1) +#else +#define NET_TC_TX_EFFECTIVE_COUNT NET_TC_TX_COUNT +#endif + +#if CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO +#define NET_TC_RX_EFFECTIVE_COUNT (NET_TC_RX_COUNT + 1) +#else +#define NET_TC_RX_EFFECTIVE_COUNT NET_TC_RX_COUNT +#endif + /** * @brief Registration information for a given L3 handler. Note that * the layer number (L3) just refers to something that is on top diff --git a/include/zephyr/net/net_pkt_filter.h b/include/zephyr/net/net_pkt_filter.h index 1ee42e51b70ef..44c43c3d52bdd 100644 --- a/include/zephyr/net/net_pkt_filter.h +++ b/include/zephyr/net/net_pkt_filter.h @@ -85,10 +85,11 @@ struct npf_test { /** @brief filter rule structure */ struct npf_rule { - sys_snode_t node; /**< Slist rule list node */ - enum net_verdict result; /**< result if all tests pass */ - uint32_t nb_tests; /**< number of tests for this rule */ - struct npf_test *tests[]; /**< pointers to @ref npf_test instances */ + sys_snode_t node; /**< Slist rule list node */ + enum net_verdict result; /**< result if all tests pass */ + enum net_priority priority; /**< priority in case of NET_CONTINUE */ + uint32_t nb_tests; /**< number of tests for this rule */ + struct npf_test *tests[]; /**< pointers to @ref npf_test instances */ }; /** @brief Default rule list termination for accepting a packet */ @@ -242,6 +243,14 @@ bool npf_remove_all_rules(struct npf_rule_list *rules); .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 /** @} */ diff --git a/include/zephyr/pmci/mctp/mctp_usb.h b/include/zephyr/pmci/mctp/mctp_usb.h new file mode 100644 index 0000000000000..06771f6a60a0f --- /dev/null +++ b/include/zephyr/pmci/mctp/mctp_usb.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_MCTP_USB_H_ +#define ZEPHYR_MCTP_USB_H_ + +#include +#include + +/* MCTP class subclass options */ +#define USBD_MCTP_SUBCLASS_MANAGEMENT_CONTROLLER 0 +#define USBD_MCTP_SUBCLASS_MANAGED_DEVICE_ENDPOINT 0 +#define USBD_MCTP_SUBCLASS_HOST_INTERFACE_ENDPOINT 1 + +/* MCTP class protocol options */ +#define USBD_MCTP_PROTOCOL_1_X 1 +#define USBD_MCTP_PROTOCOL_2_X 2 + +/* Binding-specific defines, internal use */ +#define MCTP_USB_HEADER_SIZE 4 +#define MCTP_USB_MAX_PACKET_LENGTH 255 + +/** + * @brief An MCTP binding for Zephyr's USB device stack + */ +struct mctp_binding_usb { + /** @cond INTERNAL_HIDDEN */ + struct mctp_binding binding; + struct usbd_class_data *usb_class_data; + uint8_t tx_buf[MCTP_USB_HEADER_SIZE + MCTP_USB_MAX_PACKET_LENGTH]; + struct k_sem tx_lock; + struct mctp_pktbuf *rx_pkt; + uint8_t rx_data_idx; + enum { + STATE_WAIT_HDR_DMTF0, + STATE_WAIT_HDR_DMTF1, + STATE_WAIT_HDR_RSVD0, + STATE_WAIT_HDR_LEN, + STATE_DATA + } rx_state; + /** @endcond INTERNAL_HIDDEN */ +}; + +struct mctp_usb_class_inst { + uint8_t sublcass; + uint8_t mctp_protocol; + struct mctp_binding_usb *mctp_binding; +}; + +/** @cond INTERNAL_HIDDEN */ +int mctp_usb_start(struct mctp_binding *binding); +int mctp_usb_tx(struct mctp_binding *binding, struct mctp_pktbuf *pkt); +/** @endcond INTERNAL_HIDDEN */ + +/** + * @brief Define a MCTP bus binding for USB + * + * @param _name Symbolic name of the bus binding variable + * @param _subclass MCTP subclass used in the USB interfce descriptor + * @param _protocol MCTP protocol used in the USB interface descriptor + */ +#define MCTP_USB_DEFINE(_name, _subclass, _protocol) \ + struct mctp_binding_usb _name = { \ + .binding = { \ + .name = STRINGIFY(_name), \ + .version = 1, \ + .pkt_size = MCTP_PACKET_SIZE(MCTP_USB_MAX_PACKET_LENGTH), \ + .pkt_header = 0, \ + .pkt_trailer = 0, \ + .start = mctp_usb_start, \ + .tx = mctp_usb_tx \ + }, \ + .usb_class_data = NULL, \ + .rx_pkt = NULL, \ + .rx_data_idx = 0, \ + .rx_state = STATE_WAIT_HDR_DMTF0 \ + }; \ + \ + const STRUCT_SECTION_ITERABLE(mctp_usb_class_inst, mctp_usb_class_inst_##_name) = { \ + .sublcass = _subclass, \ + .mctp_protocol = _protocol, \ + .mctp_binding = &_name, \ + }; + +#endif /* ZEPHYR_MCTP_USB_H_ */ diff --git a/include/zephyr/cpu_load/cpu_load.h b/include/zephyr/sys/cpu_load.h similarity index 100% rename from include/zephyr/cpu_load/cpu_load.h rename to include/zephyr/sys/cpu_load.h diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index d4153828fbb2d..676c0dc3a3745 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -245,7 +245,7 @@ struct zvfs_pollfd { __syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); struct zvfs_fd_set { - uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; + uint32_t bitset[DIV_ROUND_UP(ZVFS_OPEN_SIZE, 32)]; }; /** @brief Number of file descriptors which can be added @ref zvfs_fd_set */ diff --git a/include/zephyr/sys/util_macro.h b/include/zephyr/sys/util_macro.h index c8901e21454ae..c8bc264dce0cd 100644 --- a/include/zephyr/sys/util_macro.h +++ b/include/zephyr/sys/util_macro.h @@ -388,7 +388,7 @@ extern "C" { * * @return Nth argument. */ -#define GET_ARG_N(N, ...) Z_GET_ARG_##N(__VA_ARGS__) +#define GET_ARG_N(N, ...) UTIL_CAT(Z_GET_ARG_, N)(__VA_ARGS__) /** * @brief Strips n first arguments from the argument list. @@ -398,7 +398,7 @@ extern "C" { * * @return argument list without N first arguments. */ -#define GET_ARGS_LESS_N(N, ...) Z_GET_ARGS_LESS_##N(__VA_ARGS__) +#define GET_ARGS_LESS_N(N, ...) UTIL_CAT(Z_GET_ARGS_LESS_, N)(__VA_ARGS__) /** * @brief Like a || b, but does evaluation and diff --git a/include/zephyr/usb/usb_ch9.h b/include/zephyr/usb/usb_ch9.h index 0c4a3ac06086a..67af0047cc11c 100644 --- a/include/zephyr/usb/usb_ch9.h +++ b/include/zephyr/usb/usb_ch9.h @@ -267,6 +267,7 @@ struct usb_association_descriptor { #define USB_BCC_MASS_STORAGE 0x08 #define USB_BCC_CDC_DATA 0x0A #define USB_BCC_VIDEO 0x0E +#define USB_BCC_MCTP 0x14 #define USB_BCC_WIRELESS_CONTROLLER 0xE0 #define USB_BCC_MISCELLANEOUS 0xEF #define USB_BCC_APPLICATION 0xFE diff --git a/kernel/Kconfig.mem_domain b/kernel/Kconfig.mem_domain index ddf8a4cc57a6d..03d6e1239261c 100644 --- a/kernel/Kconfig.mem_domain +++ b/kernel/Kconfig.mem_domain @@ -76,4 +76,13 @@ config MEM_DOMAIN_ISOLATED_STACKS Regardless of this settings, threads cannot access the stacks of threads outside of their domains. +config MEM_DOMAIN_HAS_THREAD_LIST + bool + help + If enabled, there is a doubly linked list in each memory domain + struct to keep track of the threads associated with this + particular memory domain. + + This is selected by architecture needing this to function. + endmenu diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index 16b337acf011d..dc1cfe01126a1 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -113,7 +113,10 @@ int k_mem_domain_init(struct k_mem_domain *domain, uint8_t num_parts, domain->num_partitions = 0U; (void)memset(domain->partitions, 0, sizeof(domain->partitions)); - sys_dlist_init(&domain->mem_domain_q); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_init(&domain->thread_mem_domain_list); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ #ifdef CONFIG_ARCH_MEM_DOMAIN_DATA ret = arch_mem_domain_init(domain); @@ -265,8 +268,12 @@ static int add_thread_locked(struct k_mem_domain *domain, __ASSERT_NO_MSG(thread != NULL); LOG_DBG("add thread %p to domain %p\n", thread, domain); - sys_dlist_append(&domain->mem_domain_q, - &thread->mem_domain_info.mem_domain_q_node); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_append(&domain->thread_mem_domain_list, + &thread->mem_domain_info.thread_mem_domain_node); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ + thread->mem_domain_info.mem_domain = domain; #ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API @@ -283,7 +290,10 @@ static int remove_thread_locked(struct k_thread *thread) __ASSERT_NO_MSG(thread != NULL); LOG_DBG("remove thread %p from memory domain %p\n", thread, thread->mem_domain_info.mem_domain); - sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_remove(&thread->mem_domain_info.thread_mem_domain_node); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ #ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API ret = arch_mem_domain_thread_remove(thread); diff --git a/kernel/mmu.c b/kernel/mmu.c index 322fc61c5c0b0..e730ca3203f99 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -1503,7 +1503,7 @@ int k_mem_page_frame_evict(uintptr_t phys) do_backing_store_page_out(location); } #ifdef CONFIG_DEMAND_PAGING_ALLOW_IRQ - k_spin_unlock(&z_mm_lock, key); + key = k_spin_lock(&z_mm_lock); #endif /* CONFIG_DEMAND_PAGING_ALLOW_IRQ */ page_frame_free_locked(pf); out: diff --git a/kernel/usage.c b/kernel/usage.c index ad40e3ffd48a0..86ba6aa4d850e 100644 --- a/kernel/usage.c +++ b/kernel/usage.c @@ -125,10 +125,9 @@ void z_sched_cpu_usage(uint8_t cpu_id, struct k_thread_runtime_stats *stats) struct _cpu *cpu; key = k_spin_lock(&usage_lock); - cpu = _current_cpu; - + cpu = &_kernel.cpus[cpu_id]; - if (&_kernel.cpus[cpu_id] == cpu) { + if (cpu == _current_cpu) { uint32_t now = usage_now(); uint32_t cycles = now - cpu->usage0; diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index c8c56d7e07281..c1be6613ab039 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -13,6 +13,36 @@ 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 + set(final_fd_size ${CONFIG_ZVFS_OPEN_MAX}) + endif() +endif() + +zephyr_compile_definitions(ZVFS_OPEN_SIZE=${final_fd_size}) + zephyr_sources_ifdef(CONFIG_FDTABLE fdtable.c) zephyr_syscall_header_ifdef(CONFIG_FDTABLE ${ZEPHYR_BASE}/include/zephyr/sys/fdtable.h @@ -20,6 +50,7 @@ zephyr_syscall_header_ifdef(CONFIG_FDTABLE zephyr_sources_ifdef(CONFIG_CBPRINTF_COMPLETE cbprintf_complete.c) zephyr_sources_ifdef(CONFIG_CBPRINTF_NANO cbprintf_nano.c) +add_subdirectory_ifdef(CONFIG_CPU_LOAD_METRIC cpu_load) if(NOT CONFIG_PICOLIBC) zephyr_sources(cbprintf.c) diff --git a/lib/os/Kconfig b/lib/os/Kconfig index bca940023c6e5..ece806dcdea43 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -12,13 +12,27 @@ config FDTABLE config ZVFS_OPEN_MAX int "Maximum number of open file descriptors" - default 24 if NRF70_ENABLE_DUAL_VIF - default 16 if WIFI_NM_WPA_SUPPLICANT - default 16 if POSIX_API - default 4 + default 0 help Maximum number of open file descriptors, this includes - files, sockets, special devices, etc. + files, sockets, special devices, etc. If subsystems + specify ZVFS_OPEN_ADD_SIZE_* options, these will be added together + and the sum will be compared to the ZVFS_OPEN_MAX value. + If the sum is greater than the ZVFS_OPEN_MAX option (even if this + has the default 0 value), then the actual file descriptor count will be + rounded up to the sum of the individual requirements (unless the + ZVFS_OPEN_IGNORE_MIN option is enabled). If the final value, after + considering both this option as well as sum of the custom + requirements, ends up being zero, then no file descriptors will be + available. + +config ZVFS_OPEN_IGNORE_MIN + bool "Ignore the minimum fd count requirement" + help + This option can be set to force setting a smaller file descriptor + count than what's specified by enabled subsystems. This can be useful + when optimizing memory usage and a more precise minimum fd count + is known for a given application. config PRINTK_SYNC bool "Serialize printk() calls" @@ -137,5 +151,6 @@ config POWEROFF rsource "Kconfig.cbprintf" rsource "zvfs/Kconfig" +rsource "cpu_load/Kconfig" endmenu diff --git a/subsys/cpu_load/CMakeLists.txt b/lib/os/cpu_load/CMakeLists.txt similarity index 100% rename from subsys/cpu_load/CMakeLists.txt rename to lib/os/cpu_load/CMakeLists.txt diff --git a/subsys/cpu_load/Kconfig b/lib/os/cpu_load/Kconfig similarity index 87% rename from subsys/cpu_load/Kconfig rename to lib/os/cpu_load/Kconfig index 7772a6695e717..4941cf8b1a47e 100644 --- a/subsys/cpu_load/Kconfig +++ b/lib/os/cpu_load/Kconfig @@ -3,14 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig CPU_LOAD_METRIC - bool "CPU Load Subsystem" + bool "CPU Load Metric" select EXPERIMENTAL select THREAD_RUNTIME_STATS select SCHED_THREAD_USAGE select SCHED_THREAD_USAGE_ALL select SCHED_THREAD_USAGE_AUTO_ENABLE help - CPU Load subsystem + Tracking of CPU load statistics. if CPU_LOAD_METRIC diff --git a/subsys/cpu_load/cpu_load.c b/lib/os/cpu_load/cpu_load.c similarity index 100% rename from subsys/cpu_load/cpu_load.c rename to lib/os/cpu_load/cpu_load.c diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index be53627efca7b..25b27eca38070 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -39,10 +39,10 @@ struct fd_entry { #if defined(CONFIG_POSIX_DEVICE_IO) static const struct fd_op_vtable stdinout_fd_op_vtable; -BUILD_ASSERT(CONFIG_ZVFS_OPEN_MAX >= 3, "CONFIG_ZVFS_OPEN_MAX >= 3 for CONFIG_POSIX_DEVICE_IO"); +BUILD_ASSERT(ZVFS_OPEN_SIZE >= 3, "ZVFS_OPEN_SIZE >= 3 for CONFIG_POSIX_DEVICE_IO"); #endif /* defined(CONFIG_POSIX_DEVICE_IO) */ -static struct fd_entry fdtable[CONFIG_ZVFS_OPEN_MAX] = { +static struct fd_entry fdtable[ZVFS_OPEN_SIZE] = { #if defined(CONFIG_POSIX_DEVICE_IO) /* * Predefine entries for stdin/stdout/stderr. diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 416ccf74a6218..f7d035abe8543 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -45,12 +45,17 @@ config POSIX_DEVICE_IO_ALIAS_WRITE endif # POSIX_DEVICE_IO +# Allocate fd for stdin, stdout and stderr +config ZVFS_OPEN_ADD_SIZE_POSIX + int "Amount of file descriptors used by Posix" + default 3 + config POSIX_OPEN_MAX int - default ZVFS_OPEN_MAX + default ZVFS_OPEN_ADD_SIZE_POSIX help The maximum number of files that a process can have open at one time. This option is not - directly user-configurable but can be adjusted via CONFIG_ZVFS_OPEN_MAX. + directly user-configurable but can be adjusted via CONFIG_ZVFS_OPEN_ADD_SIZE_POSIX. For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 90ddd3a8d5b20..290294dfdab91 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -347,11 +347,26 @@ config USE_RZ_FSP_CMTW help Enable RZ FSP CMTW driver +config USE_RZ_FSP_SPI + bool + help + Enable RZ FSP SPI driver + config USE_RZ_FSP_WDT bool help Enable RZ FSP WDT driver +config USE_RZ_FSP_QSPI_XSPI + bool + help + Enable RZ FSP QSPI XSPI driver + +config USE_RZ_FSP_QSPI_SPIBSC + bool + help + Enable RZ FSP QSPI SPIBSC driver + endif config HAS_RENESAS_RX_RDP @@ -411,4 +426,11 @@ config USE_RX_RDP_LVD help Enable RX RDP LVD driver +config USE_RX_RDP_LPC + bool + default y + depends on PM + help + Enable RX RDP LPC driver + endif # HAS_RENESAS_RX_RDP diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index dd400d5ef3b00..ac5eb53d7fc00 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -70,6 +70,10 @@ if(CONFIG_SOC_FAMILY_INFINEON_EDGE) add_subdirectory(mtb-dsl-pse8xxgp) endif() +if(CONFIG_SOC_SERIES_PSC3) + add_subdirectory(zephyr-ifx-cycfg) +endif() + ## Add Wi-Fi assets for AIROC devices if (CONFIG_WIFI_AIROC) add_subdirectory(whd-expansion) diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index 2b54d74265bd4..dd6a637cc6a49 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -14,10 +14,20 @@ config USE_INFINEON_ADC help Enable Analog-to-Digital Converter (ADC) HAL module driver for Infineon devices +config USE_INFINEON_HPPASS_SAR_ADC + bool + help + Enable Infineon HPPASS SAR ADC PDL library support + +config USE_INFINEON_HPPASS_ANALOG + bool + help + Enable Infineon HPPASS Analog PDL library support + config USE_INFINEON_DMA bool help - Enable ADC HAL module driver for Infineon devices + Enable DMA HAL module driver for Infineon devices config USE_INFINEON_I2C bool diff --git a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt index bbe29ceda3085..feaa7d88799b6 100644 --- a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt +++ b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt @@ -56,6 +56,11 @@ else() zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${pdl_drv_dir}/source/cy_sar.c) endif() +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_HPPASS_SAR_ADC ${pdl_drv_dir}/source/cy_hppass_sar.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_HPPASS_SAR_ADC ${pdl_drv_dir}/source/cy_hppass.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_HPPASS_SAR_ADC ${pdl_drv_dir}/source/cy_hppass_csg.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_HPPASS_SAR_ADC ${pdl_drv_dir}/source/cy_hppass_ac.c) + if(CONFIG_USE_INFINEON_TRNG) zephyr_library_sources(${pdl_drv_dir}/source/cy_crypto.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_crypto_core_trng_v1.c) diff --git a/modules/hal_infineon/mtb-template-cat1/CMakeLists.txt b/modules/hal_infineon/mtb-template-cat1/CMakeLists.txt index 08f203f053db3..0807e415d78f3 100644 --- a/modules/hal_infineon/mtb-template-cat1/CMakeLists.txt +++ b/modules/hal_infineon/mtb-template-cat1/CMakeLists.txt @@ -47,14 +47,10 @@ if(CONFIG_SOC_FAMILY_INFINEON_EDGE) zephyr_include_directories(${edge_dir}/devices/include) zephyr_library_sources(${edge_dir}/system_edge.c) - if(CONFIG_BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M33) - zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M33 - ${edge_dir}/COMPONENT_CM33/COMPONENT_SECURE_DEVICE/s_system_pse84.c) - zephyr_include_directories(${edge_dir}/COMPONENT_CM33/COMPONENT_SECURE_DEVICE) - else() - zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M33 - ${edge_dir}/COMPONENT_CM33/COMPONENT_NON_SECURE_DEVICE/ns_system_pse84.c) - endif() - zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M55 - ${edge_dir}/COMPONENT_CM55/COMPONENT_NON_SECURE_DEVICE/ns_system_pse84.c) + zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M33 + ${edge_dir}/COMPONENT_CM33/COMPONENT_SECURE_DEVICE/s_system_pse84.c) + zephyr_include_directories_ifdef(CONFIG_CPU_CORTEX_M33 + ${edge_dir}/COMPONENT_CM33/COMPONENT_SECURE_DEVICE) + zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M55 + ${edge_dir}/COMPONENT_CM55/COMPONENT_NON_SECURE_DEVICE/ns_system_pse84.c) endif() diff --git a/modules/hal_infineon/zephyr-ifx-cycfg/CMakeLists.txt b/modules/hal_infineon/zephyr-ifx-cycfg/CMakeLists.txt index 7884d5d65e52c..d9c3849958df3 100644 --- a/modules/hal_infineon/zephyr-ifx-cycfg/CMakeLists.txt +++ b/modules/hal_infineon/zephyr-ifx-cycfg/CMakeLists.txt @@ -9,3 +9,11 @@ if(CONFIG_SOC_FAMILY_INFINEON_EDGE) zephyr_include_directories(${zephyr_ifx_cycfg_dir}) zephyr_library_sources(${zephyr_ifx_cycfg_dir}/cycfg_qspi_memslot.c) endif() + +if(CONFIG_SOC_SERIES_PSC3) + set(zephyr_ifx_cycfg_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/zephyr-ifx-cycfg/soc_psc3) + + zephyr_include_directories(${zephyr_ifx_cycfg_dir}) + zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_HPPASS_SAR_ADC ${zephyr_ifx_cycfg_dir}/ifx_hppass_analog.c) + zephyr_library_sources(${zephyr_ifx_cycfg_dir}/ifx_cycfg_init.c) +endif() diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index b9e8fd3b2da79..7d53f570a897e 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -8,7 +8,8 @@ config HAS_MCUX bool depends on SOC_FAMILY_KINETIS || SOC_FAMILY_NXP_IMX || SOC_FAMILY_LPC || \ SOC_FAMILY_NXP_S32 || SOC_FAMILY_NXP_IMXRT || SOC_FAMILY_NXP_RW || \ - SOC_FAMILY_MCXN || SOC_FAMILY_MCXA || SOC_FAMILY_MCXW || SOC_FAMILY_MCXC + SOC_FAMILY_MCXN || SOC_FAMILY_MCXA || SOC_FAMILY_MCXW || SOC_FAMILY_MCXC || \ + SOC_FAMILY_MCXE if HAS_MCUX 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 3d6f4879362d6..338326f1b7d82 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -228,7 +228,7 @@ if(CONFIG_SOC_MCXW716C OR CONFIG_SOC_MCXW727C OR CONFIG_SOC_MCXN947 OR CONFIG_SO set_variable_ifdef(CONFIG_SOC_FLASH_MCUX CONFIG_MCUX_COMPONENT_driver.flash_k4) endif() -if(CONFIG_SOC_FAMILY_MCXW OR CONFIG_SOC_MCXN547) +if(CONFIG_SOC_MCXW716C OR CONFIG_SOC_MCXW727C OR CONFIG_SOC_MCXN547) if(CONFIG_DMA) zephyr_include_directories(${MCUX_SDK_NG_DIR}/drivers/trgmux) set_variable_ifdef(CONFIG_MBOX_NXP_IMX_MU CONFIG_MCUX_COMPONENT_driver.mu) diff --git a/modules/hal_silabs/gecko/Kconfig b/modules/hal_silabs/gecko/Kconfig index 12c74f17c16ac..f04f07ce35013 100644 --- a/modules/hal_silabs/gecko/Kconfig +++ b/modules/hal_silabs/gecko/Kconfig @@ -12,4 +12,108 @@ config SILABS_GECKO_RAIL_MULTIPROTOCOL coexistence and arbitration between multiple wireless protocols (for example, Bluetooth LE and a proprietary 2.4 GHz stack) on Gecko SoCs. +config SOC_GECKO_CMU + bool + help + Set if the clock management unit (CMU) HAL module is used. + +config SOC_GECKO_BURTC + bool + help + Set if the Back-Up Real Time Counter (BURTC) HAL module is used. + +config SOC_GECKO_CORE + bool + default y + help + Set if the Core interrupt handling (CORE) HAL module is used. + +config SOC_GECKO_ADC + bool + help + Set if the Analog to Digital Converter (ADC) HAL module is used. + +config SOC_GECKO_CRYOTIMER + bool + help + Set if the Ultra Low Energy Timer/Counter (CRYOTIMER) HAL module is used. + +config SOC_GECKO_EMU + bool + help + Set if the Energy Management Unit (EMU) HAL module is used. + +config SOC_GECKO_GPIO + bool + help + Set if the General Purpose Input/Output (GPIO) HAL module is used. + +config SOC_GECKO_I2C + bool + help + Set if the Inter-Integrated Circuit Interface (I2C) HAL module is used. + +config SOC_GECKO_LETIMER + bool + help + Set if the Low Energy Timer (LETIMER) HAL module is used. + +config SOC_GECKO_LEUART + bool + help + Set if the Low Energy Universal Asynchronous Receiver/Transmitter (LEUART) + HAL module is used. + +config SOC_GECKO_MSC + bool + help + Set if the Memory System Controller (MSC) HAL module is used. + +config SOC_GECKO_PRS + bool + help + Set if the Peripheral Reflex System (PRS) HAL module is used. + +config SOC_GECKO_RMU + bool + help + Set if the Reset Management Unit (RMU) HAL module is used. + +config SOC_GECKO_RTC + bool + help + Set if the Real Time Counter (RTC) HAL module is used. + +config SOC_GECKO_RTCC + bool + help + Set if the Real Time Counter and Calendar (RTCC) HAL module is used. + +config SOC_GECKO_TIMER + bool + help + Set if the Timer/Counter (TIMER) HAL module is used. + +config SOC_GECKO_USART + bool + help + Set if the Universal Synchronous Asynchronous Receiver/Transmitter (USART) + HAL module is used. + +config SOC_GECKO_EUSART + bool + help + Set if the Extended Universal Synchronous Asynchronous Receiver/Transmitter (EUSART) + HAL module is used. + +config SOC_GECKO_WDOG + bool + help + Set if the Watchdog Timer (WDOG) HAL module is used. + +config SOC_GECKO_TRNG + bool + help + Set if the SoC has a True Random Number Generator (TRNG) module. + endmenu diff --git a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt index 0c5aae2e48cec..68f3bf0fc8716 100644 --- a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt +++ b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt @@ -170,12 +170,12 @@ zephyr_include_directories( ${SERVICE_DIR}/udelay/inc ${SECURITY_DIR}/sl_component/sl_protocol_crypto/src ${SECURITY_DIR}/sl_component/sli_crypto/inc + ${SECURITY_DIR}/sl_component/sli_psec_osal/inc ${BOARD_DIR} ) zephyr_compile_definitions( ${SILABS_DEVICE_PART_NUMBER} - SL_CODE_COMPONENT_CLOCK_MANAGER=clock_manager SL_CODE_COMPONENT_DEVICE_PERIPHERAL=peripheral SL_CODE_COMPONENT_HAL_COMMON=hal_common SL_CODE_COMPONENT_SYSTEM=system @@ -184,10 +184,6 @@ zephyr_compile_definitions( zephyr_library_sources( ${DEVICE_DIR}/SiliconLabs/${SILABS_DEVICE_FAMILY}/Source/system_${CONFIG_SOC_SERIES}.c ${EMLIB_DIR}/src/em_system.c - ${SERVICE_DIR}/clock_manager/src/sl_clock_manager.c - ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_hal_s2.c - ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init.c - ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init_hal_s2.c ${SERVICE_DIR}/device_manager/devices/sl_device_peripheral_hal_efr32xg${SILABS_DEVICE_FAMILY_NUMBER}.c ${SERVICE_DIR}/device_manager/src/sl_device_clock.c ${SERVICE_DIR}/device_manager/src/sl_device_gpio.c @@ -202,7 +198,7 @@ if(NOT SILABS_DEVICE_FAMILY_NUMBER EQUAL "21") endif() # Sleeptimer -if(CONFIG_SOC_SILABS_SLEEPTIMER) +if(CONFIG_SILABS_SISDK_SLEEPTIMER) zephyr_library_sources( ${PERIPHERAL_DIR}/src/sl_hal_sysrtc.c ${SERVICE_DIR}/sleeptimer/src/sl_sleeptimer_hal_rtcc.c @@ -216,24 +212,37 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER) ) endif() +# Clock Manager +if(CONFIG_SILABS_SISDK_CLOCK_MANAGER) + zephyr_library_sources( + ${EMLIB_DIR}/src/em_cmu.c + ${SERVICE_DIR}/clock_manager/src/sl_clock_manager.c + ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_hal_s2.c + ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init.c + ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init_hal_s2.c + ) + zephyr_compile_definitions( + SL_CODE_COMPONENT_CLOCK_MANAGER=clock_manager + ) +endif() + zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_SYSTEM ${PERIPHERAL_DIR}/src/sl_hal_system.c) #Keep em_iadc.c for compatibility for now. Not used anymore. zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_IADC ${EMLIB_DIR}/src/em_iadc.c) zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_IADC ${PERIPHERAL_DIR}/src/sl_hal_iadc.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_BURTC ${EMLIB_DIR}/src/em_burtc.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CMU ${EMLIB_DIR}/src/em_cmu.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_BURTC ${EMLIB_DIR}/src/em_burtc.c) # Device Init -if(CONFIG_SOC_GECKO_DEV_INIT) +if(CONFIG_SILABS_SISDK_DEVICE_INIT) zephyr_library_sources_ifdef(CONFIG_DT_HAS_SILABS_SERIES2_DCDC_ENABLED ${SERVICE_DIR}/device_init/src/sl_device_init_dcdc_s2.c ) endif() # Power Manager -if(CONFIG_SOC_GECKO_PM_BACKEND_PMGR) +if(CONFIG_SILABS_SISDK_POWER_MANAGER) zephyr_library_sources( ${SERVICE_DIR}/power_manager/src/common/sl_power_manager_common.c ${SERVICE_DIR}/power_manager/src/common/sl_power_manager_em4.c @@ -244,13 +253,13 @@ if(CONFIG_SOC_GECKO_PM_BACKEND_PMGR) SL_CATALOG_POWER_MANAGER_PRESENT SL_CODE_COMPONENT_POWER_MANAGER=power_manager ) - zephyr_compile_definitions_ifdef(CONFIG_SOC_GECKO_RTCC + zephyr_compile_definitions_ifdef(CONFIG_SILABS_SISDK_RTCC SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT ) endif() # HFXO Manager -if(CONFIG_SOC_SILABS_HFXO_MANAGER) +if(CONFIG_SILABS_SISDK_HFXO_MANAGER) zephyr_library_sources( ${SERVICE_DIR}/hfxo_manager/src/sl_hfxo_manager.c ${SERVICE_DIR}/hfxo_manager/src/sl_hfxo_manager_hal_s2.c @@ -260,19 +269,19 @@ if(CONFIG_SOC_SILABS_HFXO_MANAGER) ) endif() -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_DEV_INIT ${COMMON_DIR}/src/sl_slist.c) -if(CONFIG_SOC_GECKO_CORE) - zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CORE +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_SLIST ${COMMON_DIR}/src/sl_slist.c) + +if(CONFIG_SILABS_SISDK_CORE) + zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_CORE ${COMMON_DIR}/src/sl_core_cortexm.c ) zephyr_compile_definitions( SL_CODE_COMPONENT_CORE=core ) endif() -zephyr_library_sources_ifdef(CONFIG_SOC_SILABS_ACMP ${EMLIB_DIR}/src/em_acmp.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CRYOTIMER ${EMLIB_DIR}/src/em_cryotimer.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_EMU ${EMLIB_DIR}/src/em_emu.c) -if(CONFIG_SOC_GECKO_GPIO) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_ACMP ${EMLIB_DIR}/src/em_acmp.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_EMU ${EMLIB_DIR}/src/em_emu.c) +if(CONFIG_SILABS_SISDK_GPIO) zephyr_library_sources( ${EMLIB_DIR}/src/em_gpio.c ${DRIVER_DIR}/gpio/src/sl_gpio.c @@ -306,33 +315,31 @@ zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_LETIMER ${PERIPHERAL_DIR}/src zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_TIMER ${PERIPHERAL_DIR}/src/sl_hal_timer.c) zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_VDAC ${PERIPHERAL_DIR}/src/sl_hal_vdac.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LDMA ${EMDRV_DIR}/dmadrv/src/dmadrv.c) - -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_I2C ${EMLIB_DIR}/src/em_i2c.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LEUART ${EMLIB_DIR}/src/em_leuart.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_MSC ${EMLIB_DIR}/src/em_msc.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LDMA ${EMLIB_DIR}/src/em_ldma.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_PRS ${EMLIB_DIR}/src/em_prs.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_RMU ${EMLIB_DIR}/src/em_rmu.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_RTC ${EMLIB_DIR}/src/em_rtc.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_RTCC ${EMLIB_DIR}/src/em_rtcc.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_EUSART ${EMLIB_DIR}/src/em_eusart.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_USART ${EMLIB_DIR}/src/em_usart.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_WDOG ${EMLIB_DIR}/src/em_wdog.c) - -zephyr_include_directories_ifdef(CONFIG_SOC_GECKO_SE +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_LDMA + ${EMDRV_DIR}/dmadrv/src/dmadrv.c + ${EMLIB_DIR}/src/em_ldma.c +) + +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_MSC ${EMLIB_DIR}/src/em_msc.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_PRS ${EMLIB_DIR}/src/em_prs.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_RMU ${EMLIB_DIR}/src/em_rmu.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_RTCC ${EMLIB_DIR}/src/em_rtcc.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_EUSART ${EMLIB_DIR}/src/em_eusart.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_USART ${EMLIB_DIR}/src/em_usart.c) +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_WDOG ${EMLIB_DIR}/src/em_wdog.c) + +zephyr_include_directories_ifdef(CONFIG_SILABS_SISDK_SE ${SECURITY_DIR}/sl_component/se_manager/src ${SECURITY_DIR}/sl_component/se_manager/inc - ${SECURITY_DIR}/sl_component/sli_psec_osal/inc ) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_SE +zephyr_library_sources_ifdef(CONFIG_SILABS_SISDK_SE ${SECURITY_DIR}/sl_component/se_manager/src/sl_se_manager.c ${SECURITY_DIR}/sl_component/se_manager/src/sl_se_manager_util.c ${SECURITY_DIR}/sl_component/se_manager/src/sli_se_manager_mailbox.c ) -zephyr_compile_definitions_ifdef(CONFIG_SOC_GECKO_SE +zephyr_compile_definitions_ifdef(CONFIG_SILABS_SISDK_SE SL_CODE_COMPONENT_SE_MANAGER=se_manager SL_CODE_COMPONENT_PSEC_OSAL=psec_osal ) diff --git a/modules/hal_silabs/simplicity_sdk/Kconfig b/modules/hal_silabs/simplicity_sdk/Kconfig index 16ba4cb33c813..3ad364481296e 100644 --- a/modules/hal_silabs/simplicity_sdk/Kconfig +++ b/modules/hal_silabs/simplicity_sdk/Kconfig @@ -4,12 +4,26 @@ menu "SiSDK configuration" depends on HAS_SILABS_SISDK +# Peripherals + +config SILABS_SISDK_ACMP + bool "Peripheral HAL for ACMP" + +config SILABS_SISDK_BURTC + bool "Peripheral HAL for BURTC" + +config SILABS_SISDK_CORE + bool "Peripheral HAL for CORE" + +config SILABS_SISDK_EMU + bool "Peripheral HAL for EMU" + +config SILABS_SISDK_EUSART + bool "Peripheral HAL for EUSART" + config SILABS_SISDK_GPIO bool "Peripheral HAL for GPIO" -config SILABS_SISDK_SYSTEM - bool "Peripheral HAL for SYSTEM (device info)" - config SILABS_SISDK_I2C bool "Peripheral HAL for I2C" @@ -17,15 +31,82 @@ config SILABS_SISDK_IADC bool "Peripheral HAL for IADC" select SILABS_SISDK_SYSTEM +config SILABS_SISDK_LDMA + bool "Peripheral HAL for LDMA" + config SILABS_SISDK_LETIMER bool "Peripheral HAL for LETIMER" +config SILABS_SISDK_MSC + bool "Peripheral HAL for MSC" + +config SILABS_SISDK_PRS + bool "Peripheral HAL for PRS" + +config SILABS_SISDK_RMU + bool "Peripheral HAL for RMU" + +config SILABS_SISDK_RTCC + bool "Peripheral HAL for RTCC" + +config SILABS_SISDK_SE + bool "Peripheral HAL for SE (Secure Engine)" + +config SILABS_SISDK_SYSTEM + bool "Peripheral HAL for SYSTEM (device info)" + config SILABS_SISDK_TIMER bool "Peripheral HAL for TIMER" +config SILABS_SISDK_USART + bool "Peripheral HAL for USART" + config SILABS_SISDK_VDAC bool "Peripheral HAL for VDAC" +config SILABS_SISDK_WDOG + bool "Peripheral HAL for WDOG" + +# Utilities + +config SILABS_SISDK_SLIST + bool + +# Services + +config SILABS_SISDK_CLOCK_MANAGER + bool "Clock Manager service" + help + Set if the Clock Manager HAL module is used. + +config SILABS_SISDK_DEVICE_INIT + bool "Device Init service" + select SILABS_SISDK_EMU + help + Use the device initialization routines from the device_init service + in Silicon Labs HAL. + +config SILABS_SISDK_HFXO_MANAGER + bool "HFXO Manager service" + help + Set if the HFXO Manager HAL module is used. + +config SILABS_SISDK_POWER_MANAGER + bool "Power Manager service" + select SILABS_SISDK_EMU + select SILABS_SISDK_SLIST + help + Set if the Power Manager HAL module is used. + +config SILABS_SISDK_SLEEPTIMER + bool "Sleeptimer service" + select SILABS_SISDK_PRS + select SILABS_SISDK_RTCC if $(dt_nodelabel_enabled,rtcc0) + help + Set if the Sleeptimer HAL module is used. + +# Radio + config SILABS_SISDK_RAIL_PA_CURVE_HEADER string "RAIL PA custom curve header file" default "pa_curves_efr32.h" diff --git a/modules/hal_silabs/wiseconnect/CMakeLists.txt b/modules/hal_silabs/wiseconnect/CMakeLists.txt index 1edfb7e76d410..ffd7a5847df9f 100644 --- a/modules/hal_silabs/wiseconnect/CMakeLists.txt +++ b/modules/hal_silabs/wiseconnect/CMakeLists.txt @@ -200,7 +200,7 @@ if(CONFIG_SILABS_SIWX91X_NWP) zephyr_include_directories(.) endif() # CONFIG_SILABS_SIWX91X_NWP -if(CONFIG_SOC_SILABS_SLEEPTIMER) +if(CONFIG_SILABS_SISDK_SLEEPTIMER) zephyr_include_directories( ${SISDK_DIR}/platform/service/sleeptimer/inc ${SISDK_DIR}/platform/service/sleeptimer/src @@ -216,7 +216,7 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER) SL_CODE_COMPONENT_SLEEPTIMER=sleeptimer SL_CODE_COMPONENT_HAL_SYSRTC=hal_sysrtc ) -endif() # CONFIG_SOC_SILABS_SLEEPTIMER +endif() # CONFIG_SILABS_SISDK_SLEEPTIMER if(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR) zephyr_library_sources( diff --git a/modules/hal_silabs/wiseconnect/Kconfig b/modules/hal_silabs/wiseconnect/Kconfig new file mode 100644 index 0000000000000..61c111206bea9 --- /dev/null +++ b/modules/hal_silabs/wiseconnect/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +menu "WiSeConnect configuration" + depends on HAS_SILABS_WISECONNECT + +config SILABS_SISDK_SLEEPTIMER + bool "Sleeptimer service" + help + Set if the Sleeptimer HAL module is used. + +endmenu diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index d6ddc3eeaec77..581745d352185 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -24,6 +24,10 @@ config WIFI_NM_WPA_SUPPLICANT if WIFI_NM_WPA_SUPPLICANT +config ZVFS_OPEN_ADD_SIZE_WIFI_NM_WPA_SUPPLICANT + int "Number of socket descriptors needed by hostap" + default 12 + config WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP bool "Use Zephyr kernel heap for Wi-Fi driver" default y diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index ed749d3351ff3..c1ee6d14e0dd7 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -1740,7 +1740,9 @@ int supplicant_reg_domain(const struct device *dev, } if (IS_ENABLED(CONFIG_WIFI_NM_HOSTAPD_AP)) { - if (!hostapd_ap_reg_domain(dev, reg_domain)) { + const struct device *dev2 = net_if_get_device(net_if_get_wifi_sap()); + + if (!hostapd_ap_reg_domain(dev2, reg_domain)) { goto out; } } diff --git a/modules/nrf_wifi/Kconfig b/modules/nrf_wifi/Kconfig index 655fce838e50a..518a068d7139c 100644 --- a/modules/nrf_wifi/Kconfig +++ b/modules/nrf_wifi/Kconfig @@ -4,4 +4,8 @@ config ZEPHYR_NRF_WIFI_MODULE bool +config ZVFS_OPEN_ADD_SIZE_NRF70_ENABLE_DUAL_VIF + int "Number of socket descriptors needed by nrf wifi driver" + default 8 + source "modules/nrf_wifi/bus/Kconfig" diff --git a/modules/openthread/platform/mdns_socket.c b/modules/openthread/platform/mdns_socket.c index 59e0c204315fd..71abb3150c3ba 100644 --- a/modules/openthread/platform/mdns_socket.c +++ b/modules/openthread/platform/mdns_socket.c @@ -35,6 +35,7 @@ static int mdns_sock_v4 = -1; #endif /* CONFIG_NET_IPV4 */ static struct otInstance *ot_instance_ptr; static uint32_t ail_iface_index; +static bool mdns_socket_is_enabled; static otError mdns_socket_init_v6(uint32_t ail_iface_idx); #if defined(CONFIG_NET_IPV4) @@ -87,10 +88,13 @@ static otError set_listening_enable(otInstance *instance, bool enable, uint32_t #if defined(CONFIG_NET_IPV4) SuccessOrExit(error = mdns_socket_init_v4(ail_iface_idx)); #endif /* CONFIG_NET_IPV4 */ + mdns_socket_is_enabled = true; + mdns_plat_monitor_interface(net_if_get_by_index(ail_iface_idx)); ExitNow(); } SuccessOrExit(error = mdns_socket_deinit()); + mdns_socket_is_enabled = false; exit: return error; @@ -389,6 +393,10 @@ void mdns_plat_monitor_interface(struct net_if *ail_iface) otIp6Address ip6_addr = {0}; struct net_if_addr *unicast = NULL; + VerifyOrExit(mdns_socket_is_enabled); + + net_if_lock(ail_iface); + otPlatMdnsHandleHostAddressRemoveAll(ot_instance_ptr, ail_iface_index); ipv6 = ail_iface->config.ip.ipv6; @@ -422,4 +430,8 @@ void mdns_plat_monitor_interface(struct net_if *ail_iface) ail_iface_index); } #endif /* CONFIG_NET_IPV4 && CONFIG_NET_IPV4_MAPPING_TO_IPV6 */ + + net_if_unlock(ail_iface); +exit: + return; } diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 9a951e8f77a18..7014ed0f24043 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -563,6 +563,7 @@ #ifdef CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER #define OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE 1 +#define OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF 1 #endif /* CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER */ #endif /* OPENTHREAD_CORE_ZEPHYR_CONFIG_H_ */ diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 59337875e9c67..a366fbb50bdab 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -251,7 +251,7 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DTFM_PLATFORM_NXP_HAL_FILE_PATH=${TFM_PLATFORM_NXP_HAL_FILE_PATH}) endif() - if(CONFIG_BOARD_MAX32657EVKIT_MAX32657_NS) + 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}) endif() diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 39232b88fb9e8..6c3ac64487f2e 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -25,12 +25,13 @@ config TFM_BOARD default "stm/stm32wba65i_dk" if BOARD_NUCLEO_WBA65RI || BOARD_STM32WBA65I_DK1 default "arm/musca_b1" if BOARD_V2M_MUSCA_B1 default "arm/musca_s1" if BOARD_V2M_MUSCA_S1 - default "adi/max32657" if BOARD_MAX32657EVKIT_MAX32657_NS + default "adi/max32657" if BOARD_MAX32657EVKIT_MAX32657_NS || BOARD_MAX32658EVKIT_MAX32658_NS default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf9160" if SOC_NRF9160 default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf9120" if SOC_NRF9120 default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf5340_cpuapp" if SOC_NRF5340_CPUAPP 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 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/nrf54lm20a_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/CMakeLists.txt new file mode 100644 index 0000000000000..c926ace19c8f2 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# 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/nrf54lm20a nrf54lm20a) + +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/nrf54lm20dk_nrf54lm20a_cpuapp/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR} +) diff --git a/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/config.cmake new file mode 100644 index 0000000000000..4b1e3ab5e97c4 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/config.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2025, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_SOC_VARIANT nrf54lm20a CACHE STRING "nRF SoC Variant") + +include(${PLATFORM_PATH}/common/nrf54lm20a/config.cmake) diff --git a/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/cpuarch.cmake b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/cpuarch.cmake new file mode 100644 index 0000000000000..1766b89f99647 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf54lm20a_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/nrf54lm20a/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp/ns/cpuarch_ns.cmake new file mode 100644 index 0000000000000..cec0a5536dd33 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf54lm20a_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/nrf54lm20a/cpuarch.cmake) diff --git a/samples/basic/blinky/README.rst b/samples/basic/blinky/README.rst index ec23fe5403f14..a67a4b71116d9 100644 --- a/samples/basic/blinky/README.rst +++ b/samples/basic/blinky/README.rst @@ -78,8 +78,8 @@ To add support for your board, add something like this to your devicetree: }; The above sets your board's ``led0`` alias to use pin 13 on GPIO controller -``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when -the pin is set to its high state, and off when the pin is in its low state. +``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_LOW` mean the LED is on when +the pin is set to its low state, and off when the pin is in its high state. Tips: diff --git a/samples/boards/microchip/mec172xevb_assy6906/rom_api/src/main.c b/samples/boards/microchip/mec172xevb_assy6906/rom_api/src/main.c index 9fe0fbc5a4d8e..0c3fcce0d8f9d 100644 --- a/samples/boards/microchip/mec172xevb_assy6906/rom_api/src/main.c +++ b/samples/boards/microchip/mec172xevb_assy6906/rom_api/src/main.c @@ -441,7 +441,7 @@ static int test_zephyr_hash_chunk_block_size(const struct hash_tp *htbl, size_t /* SHA algorithms block sizes are powers of 2 */ updatesz = msgsz & ~(blocksz - 1u); printf(" Update size is %d\n", updatesz); - zhash_pkt.in_buf = (uint8_t *)msgptr; + zhash_pkt.in_buf = msgptr; zhash_pkt.in_len = updatesz; zhash_pkt.out_buf = digest; zhash_pkt.ctx = &zhash_ctx; @@ -459,7 +459,7 @@ static int test_zephyr_hash_chunk_block_size(const struct hash_tp *htbl, size_t printf(" Final size is %u\n", msgsz); - zhash_pkt.in_buf = (uint8_t *)msgptr; + zhash_pkt.in_buf = msgptr; zhash_pkt.in_len = msgsz; zhash_pkt.out_buf = digest; zhash_pkt.ctx = &zhash_ctx; @@ -536,7 +536,7 @@ static int test_zephyr_hash_chunk(const struct hash_tp *htbl, size_t nentries, s while (chunksz && ((msgsz - total_updatesz) > chunksz)) { chunk_cnt++; - zhash_pkt.in_buf = (uint8_t *)msgptr; + zhash_pkt.in_buf = msgptr; zhash_pkt.in_len = updatesz; zhash_pkt.out_buf = digest; zhash_pkt.ctx = &zhash_ctx; @@ -553,7 +553,7 @@ static int test_zephyr_hash_chunk(const struct hash_tp *htbl, size_t nentries, s } remsz = msgsz - total_updatesz; - zhash_pkt.in_buf = (uint8_t *)msgptr; + zhash_pkt.in_buf = msgptr; zhash_pkt.in_len = remsz; zhash_pkt.out_buf = digest; zhash_pkt.ctx = &zhash_ctx; diff --git a/samples/drivers/adc/adc_dt/boards/kit_psc3m5_evk.overlay b/samples/drivers/adc/adc_dt/boards/kit_psc3m5_evk.overlay new file mode 100644 index 0000000000000..1a2618f827e61 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 1>, <&adc0 2>, <&adc0 12>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; /* child channels */ + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@12 { + reg = <12>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/samples/drivers/adc/adc_dt/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/drivers/adc/adc_dt/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to samples/drivers/adc/adc_dt/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index ec22c4e2a4596..9167b2d2c5015 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -45,11 +45,11 @@ tests: - slwrb4180a - xg27_rb4194a - xg29_rb4412a - - raytac_an54l15q_db/nrf54l15/cpuapp - frdm_mcxa346 - frdm_mcxa266 - frdm_mcxa366 - s32k148_evb + - raytac_an54lq_db_15/nrf54l15/cpuapp integration_platforms: - nucleo_l073rz - nrf52840dk/nrf52840 diff --git a/samples/drivers/adc/adc_sequence/boards/kit_psc3m5_evk.overlay b/samples/drivers/adc/adc_sequence/boards/kit_psc3m5_evk.overlay new file mode 100644 index 0000000000000..acc6ff50ad20e --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + adc0 = &adc0; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; /* child channels */ + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@12 { + reg = <12>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/samples/drivers/adc/adc_sequence/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/drivers/adc/adc_sequence/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to samples/drivers/adc/adc_sequence/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index cdfafef91cd32..52f1971664ecb 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -24,7 +24,6 @@ tests: - nrf54l15dk/nrf54l15/cpuapp - nrf54lm20dk/nrf54lm20a/cpuapp - ophelia4ev/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuapp - ucans32k1sic - s32k148_evb - frdm_mcxc242 @@ -32,6 +31,7 @@ tests: - slwrb4180a - xg27_rb4194a - xg29_rb4412a + - raytac_an54lq_db_15/nrf54l15/cpuapp integration_platforms: - nrf52840dk/nrf52840 sample.drivers.adc.adc_sequence.8bit: diff --git a/samples/drivers/clock_control_litex/README.rst b/samples/drivers/clock_control_litex/README.rst index c32ecb27767f6..1d29f7e14730a 100644 --- a/samples/drivers/clock_control_litex/README.rst +++ b/samples/drivers/clock_control_litex/README.rst @@ -20,19 +20,19 @@ Configuration ************* Basic configuration of the driver, including default settings for clock outputs, is held in Device Tree clock control nodes. -.. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi +.. literalinclude:: ../../../boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts :language: dts :start-at: clk0: clock-controller@0 { :end-at: }; :dedent: -.. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi +.. literalinclude:: ../../../boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts :language: dts :start-at: clk1: clock-controller@1 { :end-at: }; :dedent: -.. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi +.. literalinclude:: ../../../boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts :language: dts :start-at: clock0: clock@e0004800 { :end-at: }; diff --git a/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.conf b/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.conf index fa7f7f5603d7e..444b842b8f930 100644 --- a/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.conf +++ b/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.conf @@ -8,5 +8,8 @@ CONFIG_SAMPLE_FREQ=16000 CONFIG_I2S_INIT_BUFFERS=1 CONFIG_USE_CODEC_CLOCK=y CONFIG_USE_DMIC=n +CONFIG_USE_DMIC=y CONFIG_DMIC_CHANNELS=1 CONFIG_EXTRA_BLOCKS=10 +CONFIG_SAMPLE_WIDTH=32 +CONFIG_BYTES_PER_SAMPLE=4 diff --git a/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.overlay b/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.overlay index ce71fb5ed380c..e6f4e0e140cbf 100644 --- a/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.overlay +++ b/samples/drivers/i2s/i2s_codec/boards/frdm_mcxn236.overlay @@ -18,3 +18,13 @@ &sai1 { mclk-output; }; + +dmic_dev: &micfil { + channel0: micfil-channel@0 { + status = "okay"; + }; + + channel1: micfil-channel@1 { + status = "okay"; + }; +}; diff --git a/samples/drivers/i2s/output/boards/nucleo_f429zi.conf b/samples/drivers/i2s/output/boards/nucleo_f429zi.conf new file mode 100644 index 0000000000000..4f3f73a1e06a5 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_f429zi.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=4192 diff --git a/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay b/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay new file mode 100644 index 0000000000000..edb91c5bbc090 --- /dev/null +++ b/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Mario Paja + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2s-tx = &sai1_b; + }; +}; + +/* 43.836KHz (-0.37% Error) */ +&pllsai{ + div-m = <8>; + mul-n = <101>; + div-q = <9>; + div-divq = <1>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&sai1_b { + pinctrl-0 = <&sai1_mclk_b_pf7 &sai1_sd_b_pe3 &sai1_fs_b_pf9 &sai1_sck_b_pf8>; + pinctrl-names = "default"; + status = "okay"; + mclk-enable; + mclk-divider = "div-256"; + dma-names = "tx"; +}; + +&dma2 { + status = "okay"; +}; diff --git a/samples/drivers/jesd216/src/main.c b/samples/drivers/jesd216/src/main.c index 249b6374b55a8..0d7ec299655ca 100644 --- a/samples/drivers/jesd216/src/main.c +++ b/samples/drivers/jesd216/src/main.c @@ -34,6 +34,10 @@ #define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_ospi_b_nor) #elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_qspi_nor) #define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_qspi_nor) +#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_qspi_xspi) +#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_rz_qspi_xspi) +#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_qspi_spibsc) +#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_rz_qspi_spibsc) #elif DT_HAS_COMPAT_STATUS_OKAY(sifli_sf32lb_mpi_qspi_nor) #define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(sifli_sf32lb_mpi_qspi_nor) #else diff --git a/samples/drivers/spi_bitbang/boards/rza3ul_smarc.conf b/samples/drivers/spi_bitbang/boards/rza3ul_smarc.conf new file mode 100644 index 0000000000000..91c3c15b37d1e --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rza3ul_smarc.conf @@ -0,0 +1 @@ +CONFIG_GPIO=y diff --git a/samples/drivers/spi_bitbang/boards/rza3ul_smarc.overlay b/samples/drivers/spi_bitbang/boards/rza3ul_smarc.overlay new file mode 100644 index 0000000000000..f842150309a0c --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rza3ul_smarc.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +spibb0: &spi0 { + cs-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; diff --git a/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf b/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf new file mode 100644 index 0000000000000..bec1bd2a12d91 --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf @@ -0,0 +1,2 @@ +CONFIG_GPIO=y +CONFIG_NO_OPTIMIZATIONS=y diff --git a/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay b/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay new file mode 100644 index 0000000000000..b48068b7596a5 --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +spibb0: &spi2 { + cs-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; diff --git a/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf b/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf new file mode 100644 index 0000000000000..1dd585f098f05 --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf @@ -0,0 +1,3 @@ +CONFIG_GPIO=y +CONFIG_SPI_RENESAS_RZ_RSPI_DMAC=n +CONFIG_NO_OPTIMIZATIONS=y diff --git a/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay b/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay new file mode 100644 index 0000000000000..f6c0e135c335a --- /dev/null +++ b/samples/drivers/spi_bitbang/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +spibb0: &spi1 { + cs-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; diff --git a/samples/drivers/spi_flash/src/main.c b/samples/drivers/spi_flash/src/main.c index 07adf7739becc..2fd493338420e 100644 --- a/samples/drivers/spi_flash/src/main.c +++ b/samples/drivers/spi_flash/src/main.c @@ -38,7 +38,8 @@ #if defined(CONFIG_FLASH_STM32_OSPI) || defined(CONFIG_FLASH_STM32_QSPI) || \ defined(CONFIG_FLASH_STM32_XSPI) || defined(CONFIG_FLASH_RENESAS_RA_OSPI_B) || \ - defined(CONFIG_FLASH_RENESAS_RA_QSPI) + defined(CONFIG_FLASH_RENESAS_RA_QSPI) || defined(CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI) || \ + defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) #define SPI_FLASH_MULTI_SECTOR_TEST #endif @@ -58,6 +59,10 @@ #define SPI_FLASH_COMPAT renesas_ra_ospi_b_nor #elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_qspi_nor) #define SPI_FLASH_COMPAT renesas_ra_qspi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_qspi_xspi) +#define SPI_FLASH_COMPAT renesas_rz_qspi_xspi +#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_qspi_spibsc) +#define SPI_FLASH_COMPAT renesas_rz_qspi_spibsc #else #define SPI_FLASH_COMPAT invalid #endif diff --git a/samples/drivers/video/tcpserversink/prj.conf b/samples/drivers/video/tcpserversink/prj.conf index a49aa3de90ff3..d7c140b6aae2b 100644 --- a/samples/drivers/video/tcpserversink/prj.conf +++ b/samples/drivers/video/tcpserversink/prj.conf @@ -3,7 +3,6 @@ CONFIG_NETWORKING=y CONFIG_NET_TCP=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=6 CONFIG_POSIX_API=y # Kernel options diff --git a/samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuflpr.overlay b/samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr.overlay similarity index 100% rename from samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuflpr.overlay rename to samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr.overlay diff --git a/samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.overlay b/samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.overlay similarity index 100% rename from samples/drivers/watchdog/boards/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.overlay rename to samples/drivers/watchdog/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.overlay diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index 0eb51a0e93c22..09276e644d6a9 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -26,12 +26,13 @@ tests: - panb611evb/nrf54l15/cpuapp/ns - panb611evb/nrf54l15/cpuflpr - panb611evb/nrf54l15/cpuflpr/xip + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l15/cpuapp/ns - bl54l15u_dvk/nrf54l15/cpuapp/ns - - raytac_an54l15q_db/nrf54l15/cpuapp/ns + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns sample.drivers.watchdog.stm32_wwdg: extra_args: DTC_OVERLAY_FILE=boards/stm32_wwdg.overlay filter: dt_compat_enabled("st,stm32-window-watchdog") diff --git a/samples/modules/canopennode/prj_no_storage.conf b/samples/modules/canopennode/prj_no_storage.conf index 2d0ec6b37963c..b296e8c083202 100644 --- a/samples/modules/canopennode/prj_no_storage.conf +++ b/samples/modules/canopennode/prj_no_storage.conf @@ -9,5 +9,6 @@ CONFIG_CAN_MAX_FILTER=13 CONFIG_CANOPEN=y CONFIG_CANOPENNODE_SYNC_THREAD=y CONFIG_CANOPENNODE_LEDS=y +CONFIG_CANOPENNODE_PROGRAM_DOWNLOAD=n CONFIG_REBOOT=y diff --git a/samples/modules/tflite-micro/tflm_ethosu/Kconfig b/samples/modules/tflite-micro/tflm_ethosu/Kconfig index 3e976735b4d81..32357d58ec0f8 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/Kconfig +++ b/samples/modules/tflite-micro/tflm_ethosu/Kconfig @@ -9,7 +9,7 @@ config TAINT_BLOBS_TFLM config TAINT_BLOBS_TFLM_ETHOSU bool "Choose Vela-compiled model targeting Ethos-U" default y - depends on ETHOS_U_ARM || ETHOS_U_NUMAKER + depends on ETHOS_U_ARM || ETHOS_U_NUMAKER || ETHOS_U_RENESAS select TAINT_BLOBS_TFLM source "Kconfig.zephyr" diff --git a/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm33.overlay b/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm33.overlay new file mode 100644 index 0000000000000..98c38a8cb7180 --- /dev/null +++ b/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm33.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&npu0 { + interrupts = <95 1>; + interrupt-names = "npu-irq"; + status = "okay"; +}; diff --git a/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay b/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay new file mode 100644 index 0000000000000..98c38a8cb7180 --- /dev/null +++ b/samples/modules/tflite-micro/tflm_ethosu/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&npu0 { + interrupts = <95 1>; + interrupt-names = "npu-irq"; + status = "okay"; +}; diff --git a/samples/modules/thrift/hello/client/prj.conf b/samples/modules/thrift/hello/client/prj.conf index 3c3cfcdbbe8e1..dea85eac5e0ca 100644 --- a/samples/modules/thrift/hello/client/prj.conf +++ b/samples/modules/thrift/hello/client/prj.conf @@ -28,7 +28,6 @@ CONFIG_NET_TCP=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONNECTION_MANAGER=y # Kernel options @@ -59,10 +58,6 @@ CONFIG_NET_CONFIG_NEED_IPV4=y CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" -# Number of socket descriptors might need adjusting -# if there are more than 1 handlers defined. -CONFIG_ZVFS_OPEN_MAX=16 - # Some platforms require relatively large stack sizes. # This can be tuned per-board. CONFIG_MAIN_STACK_SIZE=8192 diff --git a/samples/modules/thrift/hello/server/prj.conf b/samples/modules/thrift/hello/server/prj.conf index 78b009fb3e285..e8f3044415f8a 100644 --- a/samples/modules/thrift/hello/server/prj.conf +++ b/samples/modules/thrift/hello/server/prj.conf @@ -50,10 +50,6 @@ CONFIG_NET_CONFIG_NEED_IPV4=y CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" -# Number of socket descriptors might need adjusting -# if there are more than 1 handlers defined. -CONFIG_ZVFS_OPEN_MAX=16 - # Some platforms require relatively large stack sizes. # This can be tuned per-board. CONFIG_MAIN_STACK_SIZE=8192 diff --git a/samples/net/common/Kconfig b/samples/net/common/Kconfig index ceed53efa8692..ee55cdacfccb2 100644 --- a/samples/net/common/Kconfig +++ b/samples/net/common/Kconfig @@ -50,3 +50,8 @@ config NET_SAMPLE_COMMON_TUNNEL_MY_ADDR depends on NET_L2_IPIP help The value depends on your network setup. + +# Generic way to allocate enough sockets for the application +config ZVFS_OPEN_ADD_SIZE_NET_SAMPLE + int "Amount of sockets needed by the networking sample" + default 0 diff --git a/samples/net/dns_resolve/prj.conf b/samples/net/dns_resolve/prj.conf index de837ae082889..16d77bdaace76 100644 --- a/samples/net/dns_resolve/prj.conf +++ b/samples/net/dns_resolve/prj.conf @@ -15,7 +15,6 @@ CONFIG_NET_IPV4=y CONFIG_NET_DHCPV4=n CONFIG_ZVFS_POLL_MAX=5 -CONFIG_ZVFS_OPEN_MAX=5 # Enable the DNS resolver CONFIG_DNS_RESOLVER=y diff --git a/samples/net/dsa/prj.conf b/samples/net/dsa/prj.conf index 02d94378f822a..f7f00d5eb8e77 100644 --- a/samples/net/dsa/prj.conf +++ b/samples/net/dsa/prj.conf @@ -18,7 +18,6 @@ CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=5 CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5 CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1 CONFIG_NET_MAX_CONTEXTS=4 -CONFIG_ZVFS_OPEN_MAX=4 CONFIG_ZVFS_POLL_MAX=4 CONFIG_NET_MAX_CONN=4 diff --git a/samples/net/lwm2m_client/Kconfig b/samples/net/lwm2m_client/Kconfig index 7952bf39b1887..d9b8b427b8797 100644 --- a/samples/net/lwm2m_client/Kconfig +++ b/samples/net/lwm2m_client/Kconfig @@ -52,4 +52,5 @@ config NET_SAMPLE_LWM2M_WAIT_DNS Make sure we get DNS server addresses from the network before considering the connection to be up. +source "samples/net/common/Kconfig" source "Kconfig.zephyr" diff --git a/samples/net/lwm2m_client/boards/native_sim.conf b/samples/net/lwm2m_client/boards/native_sim.conf index 8ac063ecc3164..f5607d22b9f69 100644 --- a/samples/net/lwm2m_client/boards/native_sim.conf +++ b/samples/net/lwm2m_client/boards/native_sim.conf @@ -4,4 +4,4 @@ CONFIG_DNS_SERVER1="192.0.2.2" CONFIG_LWM2M_DNS_SUPPORT=y CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_HEAP_MEM_POOL_SIZE=32768 -CONFIG_ZVFS_OPEN_MAX=16 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=16 diff --git a/samples/net/mqtt_sn_publisher/prj.conf b/samples/net/mqtt_sn_publisher/prj.conf index d3f62bcd387f6..c943a391f3986 100644 --- a/samples/net/mqtt_sn_publisher/prj.conf +++ b/samples/net/mqtt_sn_publisher/prj.conf @@ -4,7 +4,6 @@ CONFIG_NET_UDP=y CONFIG_NET_IPV4=y CONFIG_NET_IPV6=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONNECTION_MANAGER=y # Kernel options diff --git a/samples/net/openthread/border_router/prj.conf b/samples/net/openthread/border_router/prj.conf index c5482c4b434fd..ff1447fa885a4 100644 --- a/samples/net/openthread/border_router/prj.conf +++ b/samples/net/openthread/border_router/prj.conf @@ -16,7 +16,6 @@ CONFIG_NET_ROUTE_MCAST=y CONFIG_NET_SOCKETS_SERVICE=y CONFIG_NET_CONTEXT_RECV_PKTINFO=y CONFIG_NET_CONTEXT_RECV_HOPLIMIT=y -CONFIG_ZVFS_POLL_MAX=15 CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE=12288 CONFIG_NET_MAX_CONN=12 CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=2048 @@ -72,10 +71,6 @@ CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IF_MAX_IPV4_COUNT=2 CONFIG_NET_IF_MAX_IPV6_COUNT=6 -# Number of socket descriptors might need adjusting -# if there are more than 1 handlers defined. -CONFIG_ZVFS_OPEN_MAX=15 - # DNS resolver required by DNS upstream resolver CONFIG_DNS_RESOLVER=y CONFIG_DNS_RESOLVER_PACKET_FORWARDING=y diff --git a/samples/net/pkt_filter/prj.conf b/samples/net/pkt_filter/prj.conf index 1ec1c27ef7feb..151fa6d730092 100644 --- a/samples/net/pkt_filter/prj.conf +++ b/samples/net/pkt_filter/prj.conf @@ -51,4 +51,16 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # Logging CONFIG_LOG=y +CONFIG_LOG_MODE_DEFERRED=y CONFIG_LOG_BUFFER_SIZE=4096 + +# VLAN settings. We will have two VLANs in this sample. +CONFIG_NET_VLAN=y +CONFIG_NET_VLAN_COUNT=2 +CONFIG_NET_IF_MAX_IPV4_COUNT=3 +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 diff --git a/samples/net/pkt_filter/src/main.c b/samples/net/pkt_filter/src/main.c index d88a29436bed5..81600995b5a2b 100644 --- a/samples/net/pkt_filter/src/main.c +++ b/samples/net/pkt_filter/src/main.c @@ -26,27 +26,38 @@ static NPF_IFACE_MATCH(match_iface_vlan1, NULL); static NPF_IFACE_MATCH(match_iface_vlan2, NULL); static NPF_IFACE_MATCH(match_iface_eth, NULL); -/* Allow all traffic to Ethernet interface, drop VLAN traffic except - * couple of exceptions for IPv4 and IPv6 - */ -static NPF_RULE(eth_iface_rule, NET_OK, match_iface_eth); - +/* Match ethernet packets for the precision time protocol (PTP) */ +static NPF_ETH_TYPE_MATCH(match_ptype_ptp, NET_ETH_PTYPE_PTP); +/* Match ethernet packets for the virtual local area network (VLAN) */ +static NPF_ETH_TYPE_MATCH(match_ptype_vlan, NET_ETH_PTYPE_VLAN); /* Match max size rule */ -static NPF_SIZE_MAX(maxsize_200, 200); -static NPF_ETH_VLAN_TYPE_MATCH(ipv4_packet1, NET_ETH_PTYPE_IP); -static NPF_RULE(small_ipv4_pkt, NET_OK, ipv4_packet1, maxsize_200, - match_iface_vlan1); - +static NPF_SIZE_MAX(match_smaller_200, 200); /* Match min size rule */ -static NPF_SIZE_MIN(minsize_100, 100); -static NPF_ETH_VLAN_TYPE_MATCH(ipv4_packet2, NET_ETH_PTYPE_IP); -static NPF_RULE(large_ipv4_pkt, NET_OK, ipv4_packet2, minsize_100, - match_iface_vlan2); +static NPF_SIZE_MIN(match_bigger_100, 100); +/* Match virtual internet protocol traffic */ +static NPF_ETH_VLAN_TYPE_MATCH(match_ipv4_vlan, NET_ETH_PTYPE_IP); +/* Match virtual address resolution protocol (ARP) traffic */ +static NPF_ETH_VLAN_TYPE_MATCH(match_arp_vlan, NET_ETH_PTYPE_ARP); -/* Allow ARP for VLAN interface */ -static NPF_ETH_VLAN_TYPE_MATCH(arp_packet, NET_ETH_PTYPE_ARP); -static NPF_RULE(arp_pkt_vlan1, NET_OK, arp_packet, match_iface_vlan1); -static NPF_RULE(arp_pkt_vlan2, NET_OK, arp_packet, match_iface_vlan2); +/* Allow all traffic to Ethernet interface */ +static NPF_RULE(eth_iface_rule, NET_OK, match_iface_eth); +/* Maximal priority for ptp traffic */ +static NPF_PRIORITY(eth_priority_ptp, NET_PRIORITY_NC, match_iface_eth, match_ptype_ptp); +/* Prioritize VLAN traffic on Ethernet interface */ +static NPF_PRIORITY(eth_priority_vlan, NET_PRIORITY_EE, match_iface_eth, match_ptype_vlan); +/* Deprioritize all other traffic */ +static NPF_PRIORITY(eth_priority_default, NET_PRIORITY_BK, match_iface_eth); + +/* Allow only small ipv4 packets to the first VLAN interface */ +static NPF_RULE(small_ipv4_pkt, NET_OK, match_iface_vlan1, match_ipv4_vlan, match_smaller_200); +/* Allow only ipv4 packets of minimum size to the second VLAN interface */ +static NPF_RULE(large_ipv4_pkt, NET_OK, match_iface_vlan2, match_ipv4_vlan, match_bigger_100); +/* Allow ARP for both VLAN interfaces */ +static NPF_RULE(arp_pkt_vlan1, NET_OK, match_iface_vlan1, match_arp_vlan); +static NPF_RULE(arp_pkt_vlan2, NET_OK, match_iface_vlan2, match_arp_vlan); +/* But give ARP the lowest priority */ +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); static void iface_cb(struct net_if *iface, void *user_data) { @@ -106,7 +117,15 @@ static void init_app(void) * optional interfaces (if VLAN is enabled). * We allow all traffic to the Ethernet interface, but have * filters for the VLAN interfaces. + * + * 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); /* We allow small IPv4 packets to the VLAN interface 1 */ npf_append_recv_rule(&small_ipv4_pkt); @@ -117,10 +136,8 @@ static void init_app(void) /* We allow all traffic to the Ethernet interface */ npf_append_recv_rule(ð_iface_rule); - /* We allow ARP traffic to the VLAN 1 interface */ + /* We allow ARP traffic to both VLAN interfaces */ npf_append_recv_rule(&arp_pkt_vlan1); - - /* We allow ARP traffic to the VLAN 2 interface */ npf_append_recv_rule(&arp_pkt_vlan2); /* The remaining packets that do not match are dropped */ diff --git a/samples/net/prometheus/prj.conf b/samples/net/prometheus/prj.conf index b863915a8386c..2f9aee94c6e7e 100644 --- a/samples/net/prometheus/prj.conf +++ b/samples/net/prometheus/prj.conf @@ -5,13 +5,11 @@ CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y -CONFIG_ZVFS_OPEN_MAX=32 CONFIG_POSIX_API=y CONFIG_FDTABLE=y CONFIG_NET_SOCKETS_POLL_MAX=32 CONFIG_REQUIRES_FULL_LIBC=y CONFIG_HEAP_MEM_POOL_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=32 # Prometheus CONFIG_PROMETHEUS=y diff --git a/samples/net/qos/QoS.rst b/samples/net/qos/QoS.rst new file mode 100644 index 0000000000000..3acc7e4171104 --- /dev/null +++ b/samples/net/qos/QoS.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: QoS + :name: Quality of Service + :show-listing: + + These samples demonstrate packet filters for Quality of Service (QoS). diff --git a/samples/net/qos/ethernet/CMakeLists.txt b/samples/net/qos/ethernet/CMakeLists.txt new file mode 100644 index 0000000000000..def810f0dc0ae --- /dev/null +++ b/samples/net/qos/ethernet/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ethernet_qos_demo) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/net/qos/ethernet/README.rst b/samples/net/qos/ethernet/README.rst new file mode 100644 index 0000000000000..5add0ce727e7c --- /dev/null +++ b/samples/net/qos/ethernet/README.rst @@ -0,0 +1,142 @@ +.. zephyr:code-sample:: quality-of-service + :name: Quality of Service + :relevant-api: ethernet + + Implements a demo of quality of service on the ethernet layer. + +Overview +******** + +The purpose of this sample is to show quality-of-service (QoS) on the ethernet layer. + +Building and Running +******************** + +Build like this: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/qos/ethernet + :board: + :goals: build + :compact: + +This sample only works with the native simulator. After the sample starts, it +fakes incoming network packets on a fake network interface and prints +statistics about it. + +Run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/qos/ethernet + :host-os: unix + :board: native_sim + :goals: run + :compact: + + +Statistics (With Quality of Service Filtering) +********************************************** + +c (x) := command service for priority x (high means higher priority) + +e (x) := echo service for priority x (high means higher priority) + ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| work us | c(7) | e(7) | c(6) | e(6) | c(5) | e(5) | c(4) | e(4) | c(3) | e(3) | c(2) | e(2) | c(1) | e(1) | c(0) | e(0) | ++=========+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+ +| 800 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 850 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 99 | 53 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 900 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 35 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 950 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 2 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1000 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 99 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 9 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1200 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 75 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1300 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 10 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1400 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 99 | 29 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1600 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1800 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 2000 | 100 | 100 | 100 | 100 | 100 | 100 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 3000 | 100 | 100 | 100 | 100 | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 4000 | 100 | 100 | 99 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 5000 | 100 | 100 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 6000 | 100 | 100 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 7000 | 100 | 85 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 8000 | 100 | 49 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 9000 | 100 | 22 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 10000 | 99 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 15000 | 44 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ + + +Statistics (No Quality of Service Filtering) +********************************************** + +c (x) := command service for priority x (high means higher priority) + +e (x) := echo service for priority x (high means higher priority) + ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| work us | c(7) | e(7) | c(6) | e(6) | c(5) | e(5) | c(4) | e(4) | c(3) | e(3) | c(2) | e(2) | c(1) | e(1) | c(0) | e(0) | ++=========+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+======+ +| 800 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 850 | 100 | 53 | 100 | 99 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 900 | 100 | 1 | 100 | 23 | 100 | 99 | 100 | 99 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 950 | 100 | 1 | 100 | 1 | 100 | 7 | 100 | 99 | 100 | 99 | 100 | 99 | 100 | 99 | 100 | 100 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1000 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 98 | 100 | 99 | 100 | 99 | 100 | 99 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1100 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 19 | 100 | 97 | 100 | 97 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1200 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 1 | 100 | 59 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1300 | 39 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1400 | 1 | 0 | 99 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1600 | 1 | 0 | 1 | 0 | 99 | 0 | 99 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 1800 | 1 | 0 | 1 | 0 | 12 | 0 | 99 | 0 | 99 | 0 | 100 | 0 | 100 | 0 | 100 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 2000 | 1 | 0 | 1 | 0 | 1 | 0 | 99 | 0 | 99 | 0 | 99 | 0 | 99 | 0 | 100 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 3000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 98 | 0 | 98 | 0 | 99 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 4000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 97 | 0 | 98 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 5000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 96 | 0 | 97 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 6000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 33 | 0 | 96 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 7000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 95 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 8000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 94 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 9000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 93 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 10000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 92 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ +| 15000 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 30 | 0 | ++---------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ diff --git a/samples/net/qos/ethernet/prj.conf b/samples/net/qos/ethernet/prj.conf new file mode 100644 index 0000000000000..7719c937ff446 --- /dev/null +++ b/samples/net/qos/ethernet/prj.conf @@ -0,0 +1,33 @@ +# Networking config +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=n +CONFIG_NET_IF_MAX_IPV4_COUNT=2 +CONFIG_NET_RX_DEFAULT_PRIORITY=7 +CONFIG_NET_TX_DEFAULT_PRIORITY=7 + +# Logging +CONFIG_LOG=y +CONFIG_NET_LOG=y +CONFIG_LOG_THREAD_ID_PREFIX=y +CONFIG_THREAD_NAME=y + +# Network buffers +CONFIG_NET_PKT_RX_COUNT=128 +CONFIG_NET_BUF_RX_COUNT=1800 +CONFIG_NET_PKT_TX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=900 + +# Network traffic class queues +CONFIG_NET_TC_THREAD_PRIO_CUSTOM=y +CONFIG_NET_TC_TX_THREAD_BASE_PRIO=16 +CONFIG_NET_TC_TX_THREAD_PRIO_SPREAD=2 +CONFIG_NET_TC_RX_THREAD_BASE_PRIO=15 +CONFIG_NET_TC_RX_THREAD_PRIO_SPREAD=2 +CONFIG_NET_TC_THREAD_PREEMPTIVE=y +CONFIG_NET_TC_RX_COUNT=8 +CONFIG_NET_TC_TX_COUNT=8 +CONFIG_NET_TC_LOG_LEVEL_DBG=y + +# Network Packet filters +CONFIG_NET_PKT_FILTER=y diff --git a/samples/net/qos/ethernet/sample.yaml b/samples/net/qos/ethernet/sample.yaml new file mode 100644 index 0000000000000..626c76483d153 --- /dev/null +++ b/samples/net/qos/ethernet/sample.yaml @@ -0,0 +1,15 @@ +sample: + description: demo of quality of service for ethernet layer + name: quality_of_service +common: + harness: net +tests: + sample.net.Qos: + tags: + - net + - socket + platform_allow: + - native_sim + - native_sim/native/64 + integration_platforms: + - native_sim diff --git a/samples/net/qos/ethernet/src/main.c b/samples/net/qos/ethernet/src/main.c new file mode 100644 index 0000000000000..a6d9a3756d845 --- /dev/null +++ b/samples/net/qos/ethernet/src/main.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2025 The Zephyr Contributors. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(qos_ethernet); + +#define NET_ETH_PTYPE_123 123 +#define NET_ETH_PTYPE_124 124 +#define NET_ETH_PTYPE_125 125 +#define NET_ETH_PTYPE_126 126 +#define NET_ETH_PTYPE_127 127 +#define NET_ETH_PTYPE_128 128 +#define NET_ETH_PTYPE_129 129 +#define NET_ETH_PTYPE_130 130 + +#define SINGLE_RUN_DEADLINE K_MSEC(2000) + +#define MTU 1500 + +enum service_type { + SERVICE_TYPE_COMMAND, + SERVICE_TYPE_ECHO, +}; + +struct net_if_fake_data { + uint8_t mac[sizeof(struct net_eth_addr)]; + struct net_linkaddr ll_addr; +}; + +struct statistics { + unsigned int service_123_count; + unsigned int service_124_count; + unsigned int service_125_count; + unsigned int service_126_count; + unsigned int service_127_count; + unsigned int service_128_count; + unsigned int service_129_count; + unsigned int service_130_count; + unsigned int echo_123_count; + unsigned int echo_124_count; + unsigned int echo_125_count; + unsigned int echo_126_count; + unsigned int echo_127_count; + unsigned int echo_128_count; + unsigned int echo_129_count; + unsigned int echo_130_count; +}; + +static K_SEM_DEFINE(service_123_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_124_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_125_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_126_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_127_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_128_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_129_received, 0, UINT_MAX); +static K_SEM_DEFINE(service_130_received, 0, UINT_MAX); + +static K_SEM_DEFINE(echo_123_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_124_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_125_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_126_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_127_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_128_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_129_send, 0, UINT_MAX); +static K_SEM_DEFINE(echo_130_send, 0, UINT_MAX); + +static NPF_ETH_TYPE_MATCH(npf_123, NET_ETH_PTYPE_123); +static NPF_ETH_TYPE_MATCH(npf_124, NET_ETH_PTYPE_124); +static NPF_ETH_TYPE_MATCH(npf_125, NET_ETH_PTYPE_125); +static NPF_ETH_TYPE_MATCH(npf_126, NET_ETH_PTYPE_126); +static NPF_ETH_TYPE_MATCH(npf_127, NET_ETH_PTYPE_127); +static NPF_ETH_TYPE_MATCH(npf_128, NET_ETH_PTYPE_128); +static NPF_ETH_TYPE_MATCH(npf_129, NET_ETH_PTYPE_129); +static NPF_ETH_TYPE_MATCH(npf_130, NET_ETH_PTYPE_130); + +static NPF_PRIORITY(priority_rule_123, NET_PRIORITY_BK, npf_123); +static NPF_PRIORITY(priority_rule_124, NET_PRIORITY_BE, npf_124); +static NPF_PRIORITY(priority_rule_125, NET_PRIORITY_EE, npf_125); +static NPF_PRIORITY(priority_rule_126, NET_PRIORITY_CA, npf_126); +static NPF_PRIORITY(priority_rule_127, NET_PRIORITY_VI, npf_127); +static NPF_PRIORITY(priority_rule_128, NET_PRIORITY_VO, npf_128); +static NPF_PRIORITY(priority_rule_129, NET_PRIORITY_IC, npf_129); +static NPF_PRIORITY(priority_rule_130, NET_PRIORITY_NC, npf_130); + +static uint32_t simulated_work_time; /* data race ! */ + +int net_fake_dev_init(const struct device *dev) +{ + return 0; +} + +static void copy_mac_to(char destination[static 6]) +{ + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + /* taken from arp test */ + destination[0] = 0x00; + destination[1] = 0x00; + destination[2] = 0x5E; + destination[3] = 0x00; + destination[4] = 0x53; + destination[5] = 0x3B; +} + +static void net_iface_init(struct net_if *iface) +{ + const struct device *device = net_if_get_device(iface); + struct net_if_fake_data *context = device->data; + + if (context->mac[2] == 0x00) { + copy_mac_to(context->mac); + } + + net_if_set_link_addr(iface, context->mac, sizeof(context->mac), NET_LINK_ETHERNET); +} + +static int net_if_fake_send(const struct device *dev, struct net_pkt *pkt) +{ + LOG_INF("sending service %u, pkt %p", net_pkt_ll_proto_type(pkt), pkt); + + posix_cpu_hold(simulated_work_time); + + switch (net_pkt_ll_proto_type(pkt)) { + case NET_ETH_PTYPE_123: + k_sem_give(&echo_123_send); + break; + case NET_ETH_PTYPE_124: + k_sem_give(&echo_124_send); + break; + case NET_ETH_PTYPE_125: + k_sem_give(&echo_125_send); + break; + case NET_ETH_PTYPE_126: + k_sem_give(&echo_126_send); + break; + case NET_ETH_PTYPE_127: + k_sem_give(&echo_127_send); + break; + case NET_ETH_PTYPE_128: + k_sem_give(&echo_128_send); + break; + case NET_ETH_PTYPE_129: + k_sem_give(&echo_129_send); + break; + case NET_ETH_PTYPE_130: + k_sem_give(&echo_130_send); + break; + default: /* nothing to do */ + break; + } + net_pkt_unref(pkt); + return 0; +} + +static const struct ethernet_api net_if_api = { + .iface_api.init = net_iface_init, + .send = net_if_fake_send, +}; + +static struct net_if_fake_data context; + +#define _ETH_L2_LAYER ETHERNET_L2 +#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2) + +NET_DEVICE_INIT(net_if_fake, "net_if_fake", net_fake_dev_init, NULL, &context, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &net_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, + MTU); + +static void try_recv_data(struct net_if *iface, uint16_t ptype, enum service_type service_type) +{ + int res; + struct net_pkt *pkt = NULL; + + char src[6] = {6, 7, 8, 9, 10, 11}; + char dest[6]; + + copy_mac_to(dest); + + pkt = net_pkt_rx_alloc_with_buffer(iface, MTU, AF_UNSPEC, 0, K_NO_WAIT); + if (pkt == NULL) { + return; + } + + if (net_pkt_write(pkt, dest, ARRAY_SIZE(dest))) { + goto error; + } + if (net_pkt_write(pkt, src, ARRAY_SIZE(src))) { + goto error; + } + if (net_pkt_write_be16(pkt, ptype)) { + goto error; + } + if (net_pkt_write_u8(pkt, service_type)) { + goto error; + } + + res = net_recv_data(net_pkt_iface(pkt), pkt); + if (res < 0) { + LOG_ERR("Failed to enqueue frame into RX queue: %d", res); + goto error; + } + + return; + +error: + net_pkt_unref(pkt); +} + +struct statistics single_run_with_simulated_work(struct net_if *iface, uint32_t work) +{ + k_timepoint_t deadline = sys_timepoint_calc(SINGLE_RUN_DEADLINE); + + simulated_work_time = work; + + k_sem_reset(&service_123_received); + k_sem_reset(&service_124_received); + k_sem_reset(&service_125_received); + k_sem_reset(&service_126_received); + k_sem_reset(&service_127_received); + k_sem_reset(&service_128_received); + k_sem_reset(&service_129_received); + k_sem_reset(&service_130_received); + k_sem_reset(&echo_123_send); + k_sem_reset(&echo_124_send); + k_sem_reset(&echo_125_send); + k_sem_reset(&echo_126_send); + k_sem_reset(&echo_127_send); + k_sem_reset(&echo_128_send); + k_sem_reset(&echo_129_send); + k_sem_reset(&echo_130_send); + + while (!sys_timepoint_expired(deadline)) { + /*every tick try receive a packet of each type*/ + try_recv_data(iface, NET_ETH_PTYPE_123, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_123, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_124, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_124, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_125, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_125, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_126, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_126, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_127, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_127, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_128, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_128, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_129, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_129, SERVICE_TYPE_COMMAND); + try_recv_data(iface, NET_ETH_PTYPE_130, SERVICE_TYPE_ECHO); + try_recv_data(iface, NET_ETH_PTYPE_130, SERVICE_TYPE_COMMAND); + k_sleep(K_TICKS(1)); + } + + return (struct statistics){ + .service_123_count = k_sem_count_get(&service_123_received), + .service_124_count = k_sem_count_get(&service_124_received), + .service_125_count = k_sem_count_get(&service_125_received), + .service_126_count = k_sem_count_get(&service_126_received), + .service_127_count = k_sem_count_get(&service_127_received), + .service_128_count = k_sem_count_get(&service_128_received), + .service_129_count = k_sem_count_get(&service_129_received), + .service_130_count = k_sem_count_get(&service_130_received), + .echo_123_count = k_sem_count_get(&echo_123_send), + .echo_124_count = k_sem_count_get(&echo_124_send), + .echo_125_count = k_sem_count_get(&echo_125_send), + .echo_126_count = k_sem_count_get(&echo_126_send), + .echo_127_count = k_sem_count_get(&echo_127_send), + .echo_128_count = k_sem_count_get(&echo_128_send), + .echo_129_count = k_sem_count_get(&echo_129_send), + .echo_130_count = k_sem_count_get(&echo_130_send), + }; +} + +void print_result(const char *msg, size_t cnt, uint32_t simulated_work_times[static cnt], + struct statistics stats[static cnt]) +{ + LOG_INF("--- Statistics (%s) ---", msg); + LOG_INF("c (x) := command service for priority x (high means higher priority)"); + LOG_INF("e (x) := echo service for priority x (high means higher priority)"); + LOG_INF("+---------+------+------+------+------+------+------+------+------+------+------+-" + "-----+------+------+------+------+------+"); + LOG_INF("| work us | c(7) | e(7) | c(6) | e(6) | c(5) | e(5) | c(4) | e(4) | c(3) | e(3) | " + "c(2) | e(2) | c(1) | e(1) | c(0) | e(0) |"); + LOG_INF("+=========+======+======+======+======+======+======+======+======+======+======+=" + "=====+======+======+======+======+======+"); + for (size_t i = 0; i < cnt; ++i) { + LOG_INF("| %7u | %4d | %4d | %4d | %4d | %4d | %4d | %4d | %4d | %4d | %4d | %4d | " + "%4d | %4d | %4d | %4d | %4d |", + simulated_work_times[i], stats[i].service_130_count, + stats[i].echo_130_count, stats[i].service_129_count, + stats[i].echo_129_count, stats[i].service_128_count, + stats[i].echo_128_count, stats[i].service_127_count, + stats[i].echo_127_count, stats[i].service_126_count, + stats[i].echo_126_count, stats[i].service_125_count, + stats[i].echo_125_count, stats[i].service_124_count, + stats[i].echo_124_count, stats[i].service_123_count, + stats[i].echo_123_count); + LOG_INF("+---------+------+------+------+------+------+------+------+------+------+" + "------+------+------+------+------+------+------+"); + } +} + +int main(int argc, char **argv) +{ + struct net_if *iface = NULL; + uint32_t simulated_work_times[] = { + 800, 850, 900, 950, 1000, 1100, 1200, 1300, 1400, 1600, 1800, + 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 15000, + }; + struct statistics stats_no_filter[ARRAY_SIZE(simulated_work_times)]; + struct statistics stats_with_filter[ARRAY_SIZE(simulated_work_times)]; + + iface = net_if_lookup_by_dev(DEVICE_GET(net_if_fake)); + if (iface == NULL) { + LOG_ERR("No device"); + return 1; + } + + for (size_t i = 0; i < ARRAY_SIZE(simulated_work_times); ++i) { + stats_no_filter[i] = single_run_with_simulated_work(iface, simulated_work_times[i]); + k_msleep(200); + print_result("In Progress", i + 1, simulated_work_times, stats_no_filter); + /* let simulation settle down */ + k_msleep(800); + } + + npf_append_recv_rule(&priority_rule_123); + npf_append_recv_rule(&priority_rule_124); + npf_append_recv_rule(&priority_rule_125); + npf_append_recv_rule(&priority_rule_126); + npf_append_recv_rule(&priority_rule_127); + npf_append_recv_rule(&priority_rule_128); + npf_append_recv_rule(&priority_rule_129); + npf_append_recv_rule(&priority_rule_130); + npf_append_recv_rule(&npf_default_ok); + + for (size_t i = 0; i < ARRAY_SIZE(simulated_work_times); ++i) { + stats_with_filter[i] = + single_run_with_simulated_work(iface, simulated_work_times[i]); + k_msleep(1000); + print_result("In Progress", i + 1, simulated_work_times, stats_with_filter); + /* let simulation settle down */ + k_msleep(2000); + } + + k_msleep(4000); + print_result("No Quality of Service Filtering", ARRAY_SIZE(simulated_work_times), + simulated_work_times, stats_no_filter); + print_result("With Quality of Service Filtering", ARRAY_SIZE(simulated_work_times), + simulated_work_times, stats_with_filter); + + return 0; +} + +static enum net_verdict l2_service(struct net_if *iface, uint16_t ptype, struct net_pkt *pkt) +{ + struct net_pkt *echo_reply; + uint8_t type; + const char *service_type; + + net_pkt_cursor_init(pkt); + net_pkt_read_u8(pkt, &type); + service_type = (type == SERVICE_TYPE_ECHO) ? "echo" : "command"; + + LOG_INF("handler for %s-service %d, iface %p, ptype %u, pkt %p", service_type, + net_pkt_ll_proto_type(pkt), iface, ptype, pkt); + + posix_cpu_hold(simulated_work_time); + + if (type == SERVICE_TYPE_ECHO) { + echo_reply = net_pkt_alloc_with_buffer(iface, 12, AF_UNSPEC, 0, K_NO_WAIT); + if (echo_reply) { + net_pkt_set_ll_proto_type(echo_reply, net_pkt_ll_proto_type(pkt)); + net_pkt_set_priority(echo_reply, net_pkt_priority(pkt)); + if (net_if_try_send_data(iface, echo_reply, K_NO_WAIT) != NET_OK) { + net_pkt_unref(echo_reply); + } + } + net_pkt_unref(pkt); + return NET_OK; + } + + switch (net_pkt_ll_proto_type(pkt)) { + case NET_ETH_PTYPE_123: + k_sem_give(&service_123_received); + break; + case NET_ETH_PTYPE_124: + k_sem_give(&service_124_received); + break; + case NET_ETH_PTYPE_125: + k_sem_give(&service_125_received); + break; + case NET_ETH_PTYPE_126: + k_sem_give(&service_126_received); + break; + case NET_ETH_PTYPE_127: + k_sem_give(&service_127_received); + break; + case NET_ETH_PTYPE_128: + k_sem_give(&service_128_received); + break; + case NET_ETH_PTYPE_129: + k_sem_give(&service_129_received); + break; + case NET_ETH_PTYPE_130: + k_sem_give(&service_130_received); + break; + default: /* nothing to do */ + break; + } + net_pkt_unref(pkt); + return NET_OK; +} + +ETH_NET_L3_REGISTER(service_123, NET_ETH_PTYPE_123, l2_service); +ETH_NET_L3_REGISTER(service_124, NET_ETH_PTYPE_124, l2_service); +ETH_NET_L3_REGISTER(service_125, NET_ETH_PTYPE_125, l2_service); +ETH_NET_L3_REGISTER(service_126, NET_ETH_PTYPE_126, l2_service); +ETH_NET_L3_REGISTER(service_127, NET_ETH_PTYPE_127, l2_service); +ETH_NET_L3_REGISTER(service_128, NET_ETH_PTYPE_128, l2_service); +ETH_NET_L3_REGISTER(service_129, NET_ETH_PTYPE_129, l2_service); +ETH_NET_L3_REGISTER(service_130, NET_ETH_PTYPE_130, l2_service); diff --git a/samples/net/sockets/dumb_http_server_mt/prj.conf b/samples/net/sockets/dumb_http_server_mt/prj.conf index 7b802e6e8b482..77ec17c7c7e00 100644 --- a/samples/net/sockets/dumb_http_server_mt/prj.conf +++ b/samples/net/sockets/dumb_http_server_mt/prj.conf @@ -2,7 +2,6 @@ CONFIG_TEST_RANDOM_GENERATOR=y # POSIX options -CONFIG_ZVFS_OPEN_MAX=20 CONFIG_POSIX_API=y # Networking config diff --git a/samples/net/sockets/echo_client/Kconfig b/samples/net/sockets/echo_client/Kconfig index 851189b1454a7..5fe58b8f062ea 100644 --- a/samples/net/sockets/echo_client/Kconfig +++ b/samples/net/sockets/echo_client/Kconfig @@ -58,4 +58,5 @@ config NET_SAMPLE_SEND_ITERATIONS Send sample data this many times before exiting. A value of zero means that the sample application is run forever. +source "samples/net/common/Kconfig" source "Kconfig.zephyr" diff --git a/samples/net/sockets/echo_client/overlay-tls.conf b/samples/net/sockets/echo_client/overlay-tls.conf index c807e9a1c9580..90cc5aea2b211 100644 --- a/samples/net/sockets/echo_client/overlay-tls.conf +++ b/samples/net/sockets/echo_client/overlay-tls.conf @@ -13,4 +13,4 @@ CONFIG_NET_SOCKETS_SOCKOPT_TLS=y CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 CONFIG_NET_SOCKETS_ENABLE_DTLS=y CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH=2048 -CONFIG_ZVFS_OPEN_MAX=12 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=9 diff --git a/samples/net/sockets/echo_server/overlay-tls.conf b/samples/net/sockets/echo_server/overlay-tls.conf index f2351c0ecc86b..3ec1b7dc82329 100644 --- a/samples/net/sockets/echo_server/overlay-tls.conf +++ b/samples/net/sockets/echo_server/overlay-tls.conf @@ -14,4 +14,4 @@ CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 CONFIG_NET_SOCKETS_ENABLE_DTLS=y CONFIG_NET_SOCKETS_DTLS_TIMEOUT=30000 CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH=2048 -CONFIG_ZVFS_OPEN_MAX=20 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=16 diff --git a/samples/net/sockets/echo_server/overlay-ws-console.conf b/samples/net/sockets/echo_server/overlay-ws-console.conf index 84bbed81d4f86..c8b990cfcee1e 100644 --- a/samples/net/sockets/echo_server/overlay-ws-console.conf +++ b/samples/net/sockets/echo_server/overlay-ws-console.conf @@ -9,4 +9,4 @@ CONFIG_NET_SOCKETS_POLL_MAX=32 CONFIG_NET_MAX_CONN=32 CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=32 CONFIG_ZVFS_EVENTFD_MAX=10 -CONFIG_ZVFS_OPEN_MAX=32 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=24 diff --git a/samples/net/sockets/echo_server/prj.conf b/samples/net/sockets/echo_server/prj.conf index 6038f6bb1083a..d233af340652e 100644 --- a/samples/net/sockets/echo_server/prj.conf +++ b/samples/net/sockets/echo_server/prj.conf @@ -47,7 +47,7 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # Number of socket descriptors might need adjusting # if there are more than 1 handlers defined. -CONFIG_ZVFS_OPEN_MAX=12 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=8 # How many client can connect to echo-server simultaneously CONFIG_NET_SAMPLE_NUM_HANDLERS=1 diff --git a/samples/net/sockets/http_server/Kconfig b/samples/net/sockets/http_server/Kconfig index 07d5b26e52d5e..017c0ab8d75db 100644 --- a/samples/net/sockets/http_server/Kconfig +++ b/samples/net/sockets/http_server/Kconfig @@ -76,4 +76,5 @@ if USB_DEVICE_STACK_NEXT source "samples/subsys/usb/common/Kconfig.sample_usbd" endif +source "samples/net/common/Kconfig" source "Kconfig.zephyr" diff --git a/samples/net/sockets/http_server/prj.conf b/samples/net/sockets/http_server/prj.conf index 5cfe2a04ad297..9f9e3f5885576 100644 --- a/samples/net/sockets/http_server/prj.conf +++ b/samples/net/sockets/http_server/prj.conf @@ -6,7 +6,7 @@ CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y -CONFIG_ZVFS_OPEN_MAX=32 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET_SAMPLE=24 CONFIG_POSIX_API=y CONFIG_FDTABLE=y CONFIG_ZVFS_POLL_MAX=32 diff --git a/samples/net/sockets/net_mgmt/prj.conf b/samples/net/sockets/net_mgmt/prj.conf index 72f32e1f58f88..854419e60d4cd 100644 --- a/samples/net/sockets/net_mgmt/prj.conf +++ b/samples/net/sockets/net_mgmt/prj.conf @@ -6,7 +6,6 @@ CONFIG_NET_IPV6=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_SOCKETS_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y diff --git a/samples/net/sockets/packet/prj.conf b/samples/net/sockets/packet/prj.conf index 555e824bf5880..254248f10129a 100644 --- a/samples/net/sockets/packet/prj.conf +++ b/samples/net/sockets/packet/prj.conf @@ -7,7 +7,6 @@ CONFIG_NET_IPV4=n CONFIG_NET_MAX_CONTEXTS=10 CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONTEXT_RCVTIMEO=y CONFIG_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y diff --git a/samples/net/zperf/prj.conf b/samples/net/zperf/prj.conf index 129260a113ac7..8889a1ccc4407 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_ZVFS_OPEN_MAX=12 CONFIG_POSIX_API=y CONFIG_INIT_STACKS=y diff --git a/samples/sensor/max32664c/CMakeLists.txt b/samples/sensor/max32664c/CMakeLists.txt new file mode 100644 index 0000000000000..4992762f91cdf --- /dev/null +++ b/samples/sensor/max32664c/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(max32664c) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/sensor/max32664c/README.rst b/samples/sensor/max32664c/README.rst new file mode 100644 index 0000000000000..0c25e003f3928 --- /dev/null +++ b/samples/sensor/max32664c/README.rst @@ -0,0 +1,49 @@ +.. zephyr:code-sample:: max32664c + :name: MAX32664C + MAX86141 Sensor Hub + :relevant-api: sensor_interface + +Get health data from a MAX32664C and a MAX86141 sensor (polling mode). + +NOTE: This example requires sensor hub firmware 30.13.31! + +Overview +******** + +This sample measures the heart rate and the blood oxygen saturation on a wrist. +It uses the MAX32664C sensor to control the MAX86141 sensor. + +Requirements +************ + +This sample uses the MAX32664 sensor controlled using the I2C30 interface at +the nRF54L15-DK board. + +References +********** + +- MAX32664C: https://www.analog.com/en/products/max32664.html + +Building and Running +******************** + +This project outputs sensor data to the console. It requires a MAX32664C +sensor to be connected to the desired board. An additional MAX86141 sensor +must be connected to the MAX32664C to provide the sensor data for the algorithms. + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/max32664c/ + :goals: build flash + +Sample Output +============= + +.. code-block:: console + + [00:00:00.000,000] sensor: MAX32664C: Initializing... + [00:00:01.600,000] sensor: MAX32664C: Initialization complete. + [00:00:01.600,000] sensor: MAX32664C: HR: 75 bpm + [00:00:01.600,100] sensor: MAX32664C: HR Confidence: 98 + [00:00:02.600,000] sensor: MAX32664C: HR: 76 bpm + [00:00:02.600,100] sensor: MAX32664C: HR Confidence: 97 + [00:00:03.600,000] sensor: MAX32664C: HR: 74 bpm + [00:00:03.600,100] sensor: MAX32664C: HR Confidence: 98 diff --git a/samples/sensor/max32664c/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/samples/sensor/max32664c/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 0000000000000..92d64ae965303 --- /dev/null +++ b/samples/sensor/max32664c/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c30_default: i2c30_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c30_sleep: i2c30_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + aliases { + sensor = &biometric_hub; + }; +}; + +&i2c30 { + compatible = "nordic,nrf-twim"; + status = "okay"; + clock-frequency = ; + + // Flash buffer size is needed for the I2C bootloader to flash the firmware + zephyr,flash-buf-max-size = <8250>; + + pinctrl-0 = <&i2c30_default>; + pinctrl-1 = <&i2c30_sleep>; + pinctrl-names = "default", "sleep"; + + biometric_hub: max32664c@55 { + compatible = "maxim,max32664c"; + reg = <0x55>; + status = "okay"; + reset-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + mfio-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + use-max86141; + }; +}; + +&dppic10 { + status = "okay"; +}; + +&ppib11 { + status = "okay"; +}; + +&ppib21 { + status = "okay"; +}; + +&dppic20 { + status = "okay"; +}; + +&ppib22 { + status = "okay"; +}; + +&ppib30 { + status = "okay"; +}; + +&dppic30 { + status = "okay"; +}; diff --git a/samples/sensor/max32664c/prj.conf b/samples/sensor/max32664c/prj.conf new file mode 100644 index 0000000000000..653e8d1b0cf5a --- /dev/null +++ b/samples/sensor/max32664c/prj.conf @@ -0,0 +1,7 @@ +CONFIG_I2C=y +CONFIG_SENSOR=y + +CONFIG_LOG=y +CONFIG_LOG_PRINTK=y + +CONFIG_HEAP_MEM_POOL_SIZE=16384 diff --git a/samples/sensor/max32664c/sample.yaml b/samples/sensor/max32664c/sample.yaml new file mode 100644 index 0000000000000..e515826752305 --- /dev/null +++ b/samples/sensor/max32664c/sample.yaml @@ -0,0 +1,15 @@ +sample: + name: MAX32664C heart rate monitor sample +tests: + sample.sensor.max32664c: + harness: sensor + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + tags: + - sensors + - heart rate + filter: dt_compat_enabled("maxim,max32664c") + depends_on: + - i2c diff --git a/samples/sensor/max32664c/src/main.c b/samples/sensor/max32664c/src/main.c new file mode 100644 index 0000000000000..96a32cb7b7a9a --- /dev/null +++ b/samples/sensor/max32664c/src/main.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Daniel Kampert + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +static const struct device *const sensor_hub = DEVICE_DT_GET(DT_ALIAS(sensor)); + +LOG_MODULE_REGISTER(main, LOG_LEVEL_INF); + +static void update(void) +{ + struct sensor_value value; + + sensor_sample_fetch(sensor_hub); + sensor_attr_get(sensor_hub, SENSOR_CHAN_MAX32664C_HEARTRATE, SENSOR_ATTR_MAX32664C_OP_MODE, + &value); + if (value.val1 == MAX32664C_OP_MODE_RAW) { + struct sensor_value x; + struct sensor_value y; + struct sensor_value z; + + if (sensor_channel_get(sensor_hub, SENSOR_CHAN_ACCEL_X, &x) || + sensor_channel_get(sensor_hub, SENSOR_CHAN_ACCEL_Y, &y) || + sensor_channel_get(sensor_hub, SENSOR_CHAN_ACCEL_Z, &z)) { + LOG_ERR("Failed to get accelerometer data"); + return; + } + + LOG_INF("\tx: %i", x.val1); + LOG_INF("\ty: %i", y.val1); + LOG_INF("\tz: %i", z.val1); + } else if (value.val1 == MAX32664C_OP_MODE_ALGO_AEC) { + struct sensor_value hr; + + if (sensor_channel_get(sensor_hub, SENSOR_CHAN_MAX32664C_HEARTRATE, &hr)) { + LOG_ERR("Failed to get heart rate data"); + return; + } + + LOG_INF("HR: %u bpm", hr.val1); + LOG_INF("HR Confidence: %u", hr.val2); + } else { + LOG_WRN("Operation mode not implemented: %u", value.val1); + } +} + +int main(void) +{ + struct sensor_value value; + + if (!device_is_ready(sensor_hub)) { + LOG_ERR("Sensor hub not ready!"); + return -1; + } + + LOG_INF("Sensor hub ready"); + + value.val1 = MAX32664C_OP_MODE_ALGO_AEC; + value.val2 = MAX32664C_ALGO_MODE_CONT_HRM; + sensor_attr_set(sensor_hub, SENSOR_CHAN_MAX32664C_HEARTRATE, SENSOR_ATTR_MAX32664C_OP_MODE, + &value); + + while (1) { + update(); + k_msleep(1000); + } + + return 0; +} diff --git a/samples/sensor/pressure_polling/sample.yaml b/samples/sensor/pressure_polling/sample.yaml index c063b12562c1b..7459ba0b9e44b 100644 --- a/samples/sensor/pressure_polling/sample.yaml +++ b/samples/sensor/pressure_polling/sample.yaml @@ -8,7 +8,9 @@ tests: integration_platforms: - nrf52dk/nrf52832 - adafruit_qt_py_rp2040/rp2040 # adafruit_dps310 shield + - adafruit_feather_rp2040/rp2040 # adafruit_lps22 shield - mikroe_clicker_ra4m1/r7fa4m1ab3cfm # mikroe_pressure_3_click shield extra_args: - platform:adafruit_qt_py_rp2040/rp2040:SHIELD="adafruit_dps310" + - platform:adafruit_feather_rp2040/rp2040:SHIELD="adafruit_lps22" - platform:mikroe_clicker_ra4m1/r7fa4m1ab3cfm:SHIELD="mikroe_pressure_3_click" diff --git a/samples/sensor/veml6031/src/main.c b/samples/sensor/veml6031/src/main.c index 97239aa32a05d..06168918f9bf9 100644 --- a/samples/sensor/veml6031/src/main.c +++ b/samples/sensor/veml6031/src/main.c @@ -65,9 +65,9 @@ static void read_with_all_attr(const struct device *dev) { int it, div4, gain; - for (it = VEML6031_IT_3_125; it <= VEML6031_IT_400; it++) { + for (it = VEML60XX_IT_3_125; it <= VEML60XX_IT_400; it++) { for (div4 = VEML6031_SIZE_4_4; div4 <= VEML6031_SIZE_1_4; div4++) { - for (gain = VEML6031_GAIN_1; gain <= VEML6031_GAIN_0_5; gain++) { + for (gain = VEML60XX_GAIN_1; gain <= VEML60XX_GAIN_0_5; gain++) { read_with_attr(dev, it, div4, gain); } } diff --git a/samples/sensor/veml6046/CMakeLists.txt b/samples/sensor/veml6046/CMakeLists.txt new file mode 100644 index 0000000000000..4aa3e0a7b7408 --- /dev/null +++ b/samples/sensor/veml6046/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(veml6046) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/sensor/veml6046/README.rst b/samples/sensor/veml6046/README.rst new file mode 100644 index 0000000000000..12f34edfc1759 --- /dev/null +++ b/samples/sensor/veml6046/README.rst @@ -0,0 +1,61 @@ +.. zephyr:code-sample:: veml6046 + :name: VEML6046 RGBIR Color Sensor + :relevant-api: sensor_interface + + Get red, green, blue and IR light data from a VEML6046 sensor (polling + mode). + +Overview +******** + + This sample measures the red, green, blue and IR light for all possible + combinations of sensor attributes. They are: + + - integration time + - effective photodiode size + - gain + + These attributes can be used to put the sensor in an optimal working area. + When the light value reaches the maximum raw value (0xFFFF), an error is + returned to indicate the out of bounds situation to the user program. + With this program the raw value is also printed out together with the + attributes to be able to select good attribute values. + Interrupt and trigger modes are not supported so far, but planned for future + development. + +Requirements +************ + + This sample uses the VEML6046 sensor controlled using the I2C-2 interface of + the Olimex-STM32-E407 board on Feather connector pins PF0 and PF1. + +References +********** + + - VEML6046: https://www.vishay.com/docs/80173/veml6046x00.pdf + - Application note: https://www.vishay.com/docs/80410/designingveml6046x00.pdf + +Building and Running +******************** + + This project outputs sensor data to the console. It requires a VEML6046 + sensor to be connected to the desired board. + + .. zephyr-app-commands:: + :zephyr-app: samples/sensor/veml6046/ + :goals: build flash + :board: olimex_stm32_e407 + + +Sample Output +============= + + .. code-block:: console + + Test all attributes for a good guess of attribute usage away of saturation. + Red: 68 lx ( 51) green: 68 lx ( 84) blue: 68 lx ( 51) IR: 68 lx ( 27) it: 0 pdd: 0 gain: 0 -- + Red: 121 lx ( 181) green: 121 lx ( 347) blue: 121 lx ( 240) IR: 121 lx ( 53) it: 0 pdd: 0 gain: 1 -- + Red: 215 lx ( 106) green: 215 lx ( 226) blue: 215 lx ( 160) IR: 215 lx ( 19) it: 0 pdd: 0 gain: 2 -- + Red: 201 lx ( 75) green: 201 lx ( 156) blue: 201 lx ( 112) IR: 201 lx ( 14) it: 0 pdd: 0 gain: 3 -- + [...] + Test finished. diff --git a/samples/sensor/veml6046/boards/olimex_stm32_e407.overlay b/samples/sensor/veml6046/boards/olimex_stm32_e407.overlay new file mode 100644 index 0000000000000..1960223382389 --- /dev/null +++ b/samples/sensor/veml6046/boards/olimex_stm32_e407.overlay @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Andreas Klinger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c2_sda_pf0: i2c2_sda_pf0 { + pinmux = < 0xa04 >; + bias-pull-up; + drive-open-drain; + }; + i2c2_scl_pf1: i2c2_scl_pf1 { + pinmux = < 0xa24 >; + bias-pull-up; + drive-open-drain; + }; +}; + +&i2c2 { + pinctrl-0 = < &i2c2_scl_pf1 &i2c2_sda_pf0 >; + pinctrl-names = "default"; + status = "okay"; + + rgbir: rgbir@29 { + compatible = "vishay,veml6046"; + reg = <0x29>; + }; +}; diff --git a/samples/sensor/veml6046/prj.conf b/samples/sensor/veml6046/prj.conf new file mode 100644 index 0000000000000..42fcd3c973bcb --- /dev/null +++ b/samples/sensor/veml6046/prj.conf @@ -0,0 +1 @@ +CONFIG_SENSOR=y diff --git a/samples/sensor/veml6046/sample.yaml b/samples/sensor/veml6046/sample.yaml new file mode 100644 index 0000000000000..fe2704301b11c --- /dev/null +++ b/samples/sensor/veml6046/sample.yaml @@ -0,0 +1,10 @@ +sample: + name: VEML6046 Sensor Sample +tests: + sample.sensor.veml6046: + harness: sensor + platform_allow: olimex_stm32_e407 + integration_platforms: + - olimex_stm32_e407 + tags: sensors + filter: dt_compat_enabled("vishay,veml6046") diff --git a/samples/sensor/veml6046/src/main.c b/samples/sensor/veml6046/src/main.c new file mode 100644 index 0000000000000..7ac637e37f798 --- /dev/null +++ b/samples/sensor/veml6046/src/main.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2025 Andreas Klinger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include +#include + +#include + +static void read_with_attr(const struct device *dev, int it, int pdd, int gain) +{ + int ret; + struct sensor_value red, green, blue, ir; + struct sensor_value red_raw, green_raw, blue_raw, ir_raw; + struct sensor_value sen; + char result[10]; + + sen.val2 = 0; + + sen.val1 = it; + ret = sensor_attr_set(dev, SENSOR_CHAN_LIGHT, + (enum sensor_attribute)SENSOR_ATTR_VEML6046_IT, &sen); + if (ret) { + printf("Failed to set it attribute ret: %d\n", ret); + } + sen.val1 = pdd; + ret = sensor_attr_set(dev, SENSOR_CHAN_LIGHT, + (enum sensor_attribute)SENSOR_ATTR_VEML6046_PDD, &sen); + if (ret) { + printf("Failed to set pdd attribute ret: %d\n", ret); + } + sen.val1 = gain; + ret = sensor_attr_set(dev, SENSOR_CHAN_LIGHT, + (enum sensor_attribute)SENSOR_ATTR_VEML6046_GAIN, &sen); + if (ret) { + printf("Failed to set gain attribute ret: %d\n", ret); + } + + ret = sensor_sample_fetch(dev); + if ((ret < 0) && (ret != -E2BIG)) { + printf("sample update error. ret: %d\n", ret); + } + + sensor_channel_get(dev, SENSOR_CHAN_RED, &red); + sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_VEML6046_RED_RAW_COUNTS, + &red_raw); + + sensor_channel_get(dev, SENSOR_CHAN_GREEN, &green); + sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_VEML6046_GREEN_RAW_COUNTS, + &green_raw); + + sensor_channel_get(dev, SENSOR_CHAN_BLUE, &blue); + sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_VEML6046_BLUE_RAW_COUNTS, + &blue_raw); + + sensor_channel_get(dev, SENSOR_CHAN_IR, &ir); + sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_VEML6046_IR_RAW_COUNTS, + &ir_raw); + + if (ret == -E2BIG) { + snprintf(result, sizeof(result), "OVERFLOW"); + } else if (ret) { + snprintf(result, sizeof(result), "ERROR"); + } else { + snprintf(result, sizeof(result), ""); + } + + printf("Red: %6d lx (%6d) green: %6d lx (%6d) " + "blue: %6d lx (%6d) IR: %6d lx (%6d) " + " it: %d pdd: %d gain: %d -- %s\n", + red.val1, red_raw.val1, + green.val1, green_raw.val1, + blue.val1, blue_raw.val1, + ir.val1, ir_raw.val1, + it, pdd, gain, + result); +} + +static void read_with_all_attr(const struct device *dev) +{ + for (int it = VEML60XX_IT_3_125; it <= VEML60XX_IT_400; it++) { + for (int pdd = VEML6046_SIZE_2_2; pdd <= VEML6046_SIZE_1_2; pdd++) { + for (int gain = VEML60XX_GAIN_1; gain <= VEML60XX_GAIN_0_5; gain++) { + read_with_attr(dev, it, pdd, gain); + } + } + } +} + +int main(void) +{ + const struct device *const veml = DEVICE_DT_GET(DT_NODELABEL(rgbir)); + + if (!device_is_ready(veml)) { + printk("sensor: device not ready.\n"); + return 0; + } + + printf("Test all attributes for a good guess of attribute usage away of saturation.\n"); + read_with_all_attr(veml); + printf("Test finished.\n"); + + return 0; +} diff --git a/samples/shields/x_nucleo_iks01a1/sample.yaml b/samples/shields/x_nucleo_iks01a1/sample.yaml index 841977cfb643b..d370dfa9a4b5c 100644 --- a/samples/shields/x_nucleo_iks01a1/sample.yaml +++ b/samples/shields/x_nucleo_iks01a1/sample.yaml @@ -4,6 +4,7 @@ tests: sample.shields.x_nucleo_iks01a1: platform_exclude: - disco_l475_iot1 + - frdm_rw612 - pan1781_evb - pan1782_evb harness: shield diff --git a/samples/shields/x_nucleo_iks01a2/standard/sample.yaml b/samples/shields/x_nucleo_iks01a2/standard/sample.yaml index debb544963d43..e0fa2fbafc064 100644 --- a/samples/shields/x_nucleo_iks01a2/standard/sample.yaml +++ b/samples/shields/x_nucleo_iks01a2/standard/sample.yaml @@ -9,6 +9,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - stm32mp157c_dk2 - mimxrt1010_evk diff --git a/samples/shields/x_nucleo_iks01a3/sensorhub/sample.yaml b/samples/shields/x_nucleo_iks01a3/sensorhub/sample.yaml index 1e86a8c5b49cc..2aef91293cd56 100644 --- a/samples/shields/x_nucleo_iks01a3/sensorhub/sample.yaml +++ b/samples/shields/x_nucleo_iks01a3/sensorhub/sample.yaml @@ -9,5 +9,6 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - mimxrt1010_evk diff --git a/samples/shields/x_nucleo_iks01a3/standard/sample.yaml b/samples/shields/x_nucleo_iks01a3/standard/sample.yaml index 296272a8d1ec7..0fef3bce74bbd 100644 --- a/samples/shields/x_nucleo_iks01a3/standard/sample.yaml +++ b/samples/shields/x_nucleo_iks01a3/standard/sample.yaml @@ -11,6 +11,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - pan1781_evb - pan1782_evb diff --git a/samples/shields/x_nucleo_iks02a1/sensorhub/sample.yaml b/samples/shields/x_nucleo_iks02a1/sensorhub/sample.yaml index c822ccc8772eb..06718166b1131 100644 --- a/samples/shields/x_nucleo_iks02a1/sensorhub/sample.yaml +++ b/samples/shields/x_nucleo_iks02a1/sensorhub/sample.yaml @@ -9,6 +9,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - stm32mp157c_dk2 - pan1781_evb diff --git a/samples/shields/x_nucleo_iks02a1/standard/sample.yaml b/samples/shields/x_nucleo_iks02a1/standard/sample.yaml index 1f080e2f0d112..3bcef62146c1c 100644 --- a/samples/shields/x_nucleo_iks02a1/standard/sample.yaml +++ b/samples/shields/x_nucleo_iks02a1/standard/sample.yaml @@ -11,6 +11,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - stm32mp157c_dk2 - pan1781_evb diff --git a/samples/shields/x_nucleo_iks4a1/sensorhub2/sample.yaml b/samples/shields/x_nucleo_iks4a1/sensorhub2/sample.yaml index b52cd282f7bc6..e4cb9864ea027 100644 --- a/samples/shields/x_nucleo_iks4a1/sensorhub2/sample.yaml +++ b/samples/shields/x_nucleo_iks4a1/sensorhub2/sample.yaml @@ -9,6 +9,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - pan1781_evb - pan1782_evb diff --git a/samples/shields/x_nucleo_iks4a1/standard/sample.yaml b/samples/shields/x_nucleo_iks4a1/standard/sample.yaml index a5cffd34361a7..f13fc9c42c966 100644 --- a/samples/shields/x_nucleo_iks4a1/standard/sample.yaml +++ b/samples/shields/x_nucleo_iks4a1/standard/sample.yaml @@ -11,6 +11,7 @@ tests: - arduino_gpio platform_exclude: - disco_l475_iot1 + - frdm_rw612 - lpcxpresso55s16 - mimxrt1010_evk - pan1781_evb diff --git a/samples/subsys/fs/fs_sample/boards/frdm_imx91_mimx9131.conf b/samples/subsys/fs/fs_sample/boards/frdm_imx91_mimx9131.conf new file mode 100644 index 0000000000000..dd98d3df475c9 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/frdm_imx91_mimx9131.conf @@ -0,0 +1 @@ +CONFIG_MAIN_STACK_SIZE=8192 diff --git a/samples/subsys/pmci/mctp/usb_endpoint/CMakeLists.txt b/samples/subsys/pmci/mctp/usb_endpoint/CMakeLists.txt new file mode 100644 index 0000000000000..efbc4cb50f8c6 --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mctp_usb_endpoint) + +include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/subsys/pmci/mctp/usb_endpoint/Kconfig b/samples/subsys/pmci/mctp/usb_endpoint/Kconfig new file mode 100644 index 0000000000000..96c5455894806 --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Source common USB sample options used to initialize new experimental USB +# device stack. The scope of these options is limited to USB samples in project +# tree, you cannot use them in your own application. +source "samples/subsys/usb/common/Kconfig.sample_usbd" + +source "Kconfig.zephyr" diff --git a/samples/subsys/pmci/mctp/usb_endpoint/README.rst b/samples/subsys/pmci/mctp/usb_endpoint/README.rst new file mode 100644 index 0000000000000..54569a87bd988 --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/README.rst @@ -0,0 +1,56 @@ +.. zephyr:code-sample:: mctp-usb-endpoint + :name: MCTP USB Endpoint Node Sample + :relevant-api: usbd_api + + Create an MCTP endpoint node using the USB device interface. + +Overview +******** +Sets up an MCTP endpoint node that listens for messages from the MCTP bus owner with EID 20. +Responds with "Hello, bus owner" message. + +Requirements +************ +A board and SoC that provide support for USB device capability (either FS or HS, though DMTF spec +specifies only HS). Testing requires a USB host that has the ability to enumerate the MCTP interface +and interact with the board using the MCTP protocol. An easy way to do this is a Python script. + +An example script to test this interface is provided with this sample application. To run the +script, you must first install pyusb. + +.. code-block:: console + + pip install requirements.txt + python usb_host_tester.py + +If the test is successful, you will see the following output from the script: + +.. code-block:: console + + Sending message with size smaller than USB FS MPS (<64b) + Received: b'\x1a\xb4\x00\x15\x01\x14\n\xc0Hello, bus owner\x00' + Sending message spanning two USB FS packets (>64b) + Received: b'\x1a\xb4\x00\x15\x01\x14\n\xc0Hello, bus owner\x00' + Sending message with two MCTP messages in a single USB FS packet + Received: b'\x1a\xb4\x00\x15\x01\x14\n\xc0Hello, bus owner\x00' + Received: b'\x1a\xb4\x00\x15\x01\x14\n\xc0Hello, bus owner\x00' + +Wiring +****** +Connect a USB cable between the host (likely a PC) and the board. The type of cable (mini, micro, +type C) depends on the host and board connectors. + +Building and Running +******************** + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/pmci/mctp/usb_endpoint + :host-os: unix + :board: frdm_mcxn947_mcxn947_cpu0 + :goals: run + :compact: + +References +********** + +`MCTP Base Specification 2019 `_ diff --git a/samples/subsys/pmci/mctp/usb_endpoint/prj.conf b/samples/subsys/pmci/mctp/usb_endpoint/prj.conf new file mode 100644 index 0000000000000..c76567f1412e6 --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/prj.conf @@ -0,0 +1,10 @@ +CONFIG_USB_DEVICE_STACK_NEXT=y + +CONFIG_MCTP=y +CONFIG_MCTP_USB=y + +CONFIG_LOG=y +CONFIG_MCTP_LOG_LEVEL_ERR=y +CONFIG_UDC_DRIVER_LOG_LEVEL_ERR=y +CONFIG_USBD_LOG_LEVEL_ERR=y +CONFIG_UDC_DRIVER_LOG_LEVEL_ERR=y diff --git a/samples/subsys/pmci/mctp/usb_endpoint/requirements.txt b/samples/subsys/pmci/mctp/usb_endpoint/requirements.txt new file mode 100644 index 0000000000000..feec2b980afdb --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/requirements.txt @@ -0,0 +1,2 @@ +# Needed to run USB host test script. +pyusb diff --git a/samples/subsys/pmci/mctp/usb_endpoint/src/main.c b/samples/subsys/pmci/mctp/usb_endpoint/src/main.c new file mode 100644 index 0000000000000..178fbce47ffdb --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/src/main.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mctp_endpoint); + +#define SELF_ID 10 +#define BUS_OWNER_ID 20 + +K_SEM_DEFINE(mctp_rx, 0, 1); +MCTP_USB_DEFINE(mctp0, USBD_MCTP_SUBCLASS_MANAGED_DEVICE_ENDPOINT, USBD_MCTP_PROTOCOL_1_X); + +static struct mctp *mctp_ctx; +static bool usb_configured; + +static void sample_msg_cb(struct usbd_context *const ctx, const struct usbd_msg *msg) +{ + LOG_INF("USBD message: %s", usbd_msg_type_string(msg->type)); + + if (msg->type == USBD_MSG_CONFIGURATION) { + usb_configured = true; + } +} + +static int enable_usb_device_next(void) +{ + static struct usbd_context *mctp_poc_usbd; + int err; + + mctp_poc_usbd = sample_usbd_init_device(sample_msg_cb); + if (mctp_poc_usbd == NULL) { + LOG_ERR("Failed to initialize USB device"); + return -ENODEV; + } + + if (!usbd_can_detect_vbus(mctp_poc_usbd)) { + err = usbd_enable(mctp_poc_usbd); + if (err) { + LOG_ERR("Failed to enable device support"); + return err; + } + } + + LOG_INF("USB device support enabled"); + + return 0; +} + +static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, + size_t len) +{ + switch (eid) { + case BUS_OWNER_ID: { + LOG_INF("Received MCTP message \"%s\" from EID %d", (char *)msg, eid); + k_sem_give(&mctp_rx); + break; + } + default: { + LOG_INF("Unknown endpoint %d", eid); + break; + } + } +} + +int main(void) +{ + LOG_INF("MCTP Endpoint EID: %d on %s", SELF_ID, CONFIG_BOARD_TARGET); + + int ret = enable_usb_device_next(); + + if (ret != 0) { + LOG_ERR("Failed to enable USB device support"); + return 0; + } + + while (!usb_configured) { + k_msleep(5); + } + + mctp_set_alloc_ops(malloc, free, realloc); + mctp_ctx = mctp_init(); + __ASSERT_NO_MSG(mctp_ctx != NULL); + + mctp_register_bus(mctp_ctx, &mctp0.binding, SELF_ID); + mctp_set_rx_all(mctp_ctx, rx_message, NULL); + + while (1) { + k_sem_take(&mctp_rx, K_FOREVER); + mctp_message_tx(mctp_ctx, BUS_OWNER_ID, false, 0, "Hello, bus owner", + sizeof("Hello, bus owner")); + } + + return 0; +} diff --git a/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py b/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py new file mode 100644 index 0000000000000..6931002f9e7a0 --- /dev/null +++ b/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +import usb.core +import usb.util + + +class USBDevice: + def __init__(self, vid, pid): + self.vid = vid + self.pid = pid + self.device = None + self.endpoint_in = None + self.endpoint_out = None + self.interface = None + + def connect(self): + # Find the device + self.device = usb.core.find(idVendor=self.vid, idProduct=self.pid) + if self.device is None: + raise ValueError( + "Device not found. Make sure the board running the MCTP USB endpoint \ + sample is connected." + ) + + # Set the active configuration + self.device.set_configuration() + cfg = self.device.get_active_configuration() + self.interface = cfg[(0, 0)] + + # Claim the interface + usb.util.claim_interface(self.device, self.interface.bInterfaceNumber) + + # Find bulk IN and OUT endpoints + for ep in self.interface: + if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_IN: + self.endpoint_in = ep + elif usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_OUT: + self.endpoint_out = ep + + if not self.endpoint_in or not self.endpoint_out: + raise ValueError("Bulk IN/OUT endpoints not found") + + # Print descriptor information (for debug purposes) + for cfg in self.device: + print(cfg) + + def send_data(self, data): + if not self.endpoint_out: + raise RuntimeError("OUT endpoint not initialized") + self.endpoint_out.write(data) + + def receive_data(self, size=64, timeout=1000): + if not self.endpoint_in: + raise RuntimeError("IN endpoint not initialized") + return self.endpoint_in.read(size, timeout) + + def disconnect(self): + usb.util.release_interface(self.device, self.interface.bInterfaceNumber) + usb.util.dispose_resources(self.device) + + +if __name__ == "__main__": + usb_dev = USBDevice(0x2FE3, 0x0001) + try: + usb_dev.connect() + + 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' + ) + 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'\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' + ) + response = usb_dev.receive_data() + print("Received:", bytes(response)) + + 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'\x2c\x20\x32\x00' + ) + response = usb_dev.receive_data() + print("Received:", bytes(response)) + response = usb_dev.receive_data() + print("Received:", bytes(response)) + + finally: + usb_dev.disconnect() diff --git a/samples/subsys/usb/testusb/README.rst b/samples/subsys/usb/testusb/README.rst index 52a124e05e6fc..3dcaa79a3714a 100644 --- a/samples/subsys/usb/testusb/README.rst +++ b/samples/subsys/usb/testusb/README.rst @@ -25,7 +25,8 @@ To run USB tests: $ sudo modprobe usbtest vendor=0x2fe3 product=0x0009 - The ``usbtest`` module should claim the device: + By checking the kernel diagnostic messages, you should see that the ``usbtest`` + module has claimed the device: .. code-block:: console @@ -39,6 +40,18 @@ To run USB tests: [21746.306153] usbtest 9-1:1.0: Generic USB device [21746.306156] usbtest 9-1:1.0: full-speed {control} tests + .. note:: + The kernel diagnostic messages can be displayed using a command such as + ``journalctl -k -n 20`` or ``dmesg`` (these commands may need to be + executed as root - e.g., ``sudo dmesg``). + + The first line of the diagnostic messages above contains two important + pieces of information that will be needed later on: + + * The USB bus number: ``9`` in ``usb 9-1: [...]`` + + * The device under testing (DUT)'s USB device number: ``16`` in ``USB device number 16`` + #. Use the ``testusb`` tool in ``linux/tools/usb`` inside Linux kernel source directory to start the tests. @@ -49,17 +62,45 @@ To run USB tests: /dev/bus/usb/009/016 test 9, 4.994475 secs /dev/bus/usb/009/016 test 10, 11.990054 secs -#. To run all the tests the Zephyr's VID / PID should be inserted to USB - driver id table. The method for loading the ``usbtest`` driver for our - device is described here: https://lwn.net/Articles/160944/. + .. note:: + In this command, replace ``009`` and ``016`` with the USB bus number and + DUT's device number, respectively, as found in the debugging messages on + your host. Do not forget to pad with zeros. - Since we use the "Gadget Zero" interface we specify reference device - ``0525:a4a0``. +#. The Linux ``usbtest`` driver does not support this Zephyr sample's VID/PID + so we cannot run all the tests by default. To run all the tests, we can use + the feature described in the `"Dynamic USB device IDs" LWN.net article`_ to + write one of the supported VID/PID pair to the ``new_id`` sysfs attribute + of our device. Since the sample implements an interface similar to the + "Gadget Zero" interface, we specify reference device ``0525:a4a0``. .. code-block:: console $ sudo sh -c "echo 0x2fe3 0x0009 0 0x0525 0xa4a0 > /sys/bus/usb/drivers/usbtest/new_id" + .. note:: + This step can be performed right after loading the ``usbtest`` module instead. + Otherwise, you may have to disconnect and reconnect the DUT in order for the + Gadget Zero interface to become enabled. + + Once this step has been performed, the kernel diagnostic messages upon connecting + the DUT should be similar to the following: + + .. code-block:: + + [100458.667241] usb 3-5.3.1: new full-speed USB device number 38 using xhci_hcd + [100458.761743] usb 3-5.3.1: New USB device found, idVendor=2fe3, idProduct=0009, bcdDevice= 4.02 + [100458.761750] usb 3-5.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [100458.761753] usb 3-5.3.1: Product: Zephyr testusb sample + [100458.761755] usb 3-5.3.1: Manufacturer: Zephyr Project + [100458.761757] usb 3-5.3.1: SerialNumber: 2034354E32365007003C001C + [100458.773785] usbtest 3-5.3.1:1.0: Linux gadget zero + [100458.773791] usbtest 3-5.3.1:1.0: full-speed {control in/out bulk-in bulk-out} tests (+alt) + [100458.773858] usbtest 3-5.3.1:1.1: Linux gadget zero + [100458.773859] usbtest 3-5.3.1:1.1: full-speed {control in/out int-in int-out} tests (+alt) + [100458.773914] usbtest 3-5.3.1:1.2: Linux gadget zero + [100458.773916] usbtest 3-5.3.1:1.2: full-speed {control in/out iso-in iso-out} tests (+alt) + #. Use the ``testusb`` tool in ``linux/tools/usb`` inside Linux kernel source directory to start the tests. @@ -90,3 +131,6 @@ To run USB tests: /dev/bus/usb/009/017 test 27, 56.911052 secs /dev/bus/usb/009/017 test 28, 34.163089 secs /dev/bus/usb/009/017 test 29, 3.983999 secs + +.. _"Dynamic USB device IDs" LWN.net article: + https://lwn.net/Articles/160944/ diff --git a/samples/subsys/zbus/benchmark/README.rst b/samples/subsys/zbus/benchmark/README.rst index 2db3e7d23ff3c..5fb9c52feeaba 100644 --- a/samples/subsys/zbus/benchmark/README.rst +++ b/samples/subsys/zbus/benchmark/README.rst @@ -11,7 +11,7 @@ Building and Running ******************** .. zephyr-app-commands:: - :zephyr-app: samples/subsys/zbus/dyn_channel + :zephyr-app: samples/subsys/zbus/benchmark :host-os: unix :board: qemu_cortex_m3 :gen-args: -DCONFIG_BM_MESSAGE_SIZE=512 -DCONFIG_BM_ONE_TO=1 -DCONFIG_BM_LISTENERS=y diff --git a/samples/subsys/zbus/benchmark/sample.yaml b/samples/subsys/zbus/benchmark/sample.yaml index cba42f5c8b988..3be3650ef7679 100644 --- a/samples/subsys/zbus/benchmark/sample.yaml +++ b/samples/subsys/zbus/benchmark/sample.yaml @@ -46,7 +46,10 @@ tests: sample.zbus.benchmark_sync: tags: zbus min_ram: 16 - filter: CONFIG_SYS_CLOCK_EXISTS and not (CONFIG_ARCH_POSIX and not CONFIG_BOARD_NATIVE_SIM) + filter: >- + CONFIG_SYS_CLOCK_EXISTS and + not (CONFIG_ARCH_POSIX and not CONFIG_BOARD_NATIVE_SIM) and + not CONFIG_SMP harness: console harness_config: type: multi_line diff --git a/samples/subsys/zbus/msg_subscriber/sample.yaml b/samples/subsys/zbus/msg_subscriber/sample.yaml index 1664f93931ded..236298bc7461a 100644 --- a/samples/subsys/zbus/msg_subscriber/sample.yaml +++ b/samples/subsys/zbus/msg_subscriber/sample.yaml @@ -274,6 +274,7 @@ tests: integration_platforms: - qemu_x86 sample.zbus.msg_subscriber_dynamic_isolated_too_small: + filter: not CONFIG_SMP harness: console extra_configs: - CONFIG_ZBUS_LOG_LEVEL_DBG=y @@ -385,6 +386,7 @@ tests: integration_platforms: - qemu_x86 sample.zbus.msg_subscriber_static_isolated_too_small: + filter: not CONFIG_SMP harness: console extra_configs: - CONFIG_ZBUS_LOG_LEVEL_DBG=y diff --git a/samples/sysbuild/hello_world/Kconfig.sysbuild b/samples/sysbuild/hello_world/Kconfig.sysbuild index 53ed4507b7605..5204e7d6f6458 100644 --- a/samples/sysbuild/hello_world/Kconfig.sysbuild +++ b/samples/sysbuild/hello_world/Kconfig.sysbuild @@ -3,5 +3,34 @@ source "$(ZEPHYR_BASE)/share/sysbuild/Kconfig" +choice REMOTE_NRF54H20_CORE + prompt "Remote nRF54h20 core" + default REMOTE_NRF54H20_CPUFLPR_CORE + depends on SOC_NRF54H20_CPUAPP + +config REMOTE_NRF54H20_CPUFLPR_CORE + bool "flpr core" + +config REMOTE_NRF54H20_CPUFLPR_XIP_CORE + bool "flpr/xip core" + +config REMOTE_NRF54H20_CPUPPR_CORE + bool "ppr core" + +config REMOTE_NRF54H20_CPUPPR_XIP_CORE + bool "ppr/xip core" + +config REMOTE_NRF54H20_CPURAD_CORE + bool "cpurad" + +endchoice + config REMOTE_BOARD - string "The board used for remote target" + string + default "$(BOARD)/nrf5340/cpunet" if SOC_NRF5340_CPUAPP + default "$(BOARD)/nrf54l15/cpuflpr" if SOC_NRF54L15_CPUAPP + default "$(BOARD)/nrf54h20/cpurad" if SOC_NRF54H20_CPUAPP && REMOTE_NRF54H20_CPURAD_CORE + default "$(BOARD)/nrf54h20/cpuppr" if SOC_NRF54H20_CPUAPP && REMOTE_NRF54H20_CPUPPR_CORE + default "$(BOARD)/nrf54h20/cpuppr/xip" if SOC_NRF54H20_CPUAPP && REMOTE_NRF54H20_CPUPPR_XIP_CORE + default "$(BOARD)/nrf54h20/cpuflpr" if SOC_NRF54H20_CPUAPP && REMOTE_NRF54H20_CPUFLPR_CORE + default "$(BOARD)/nrf54h20/cpuflpr/xip" if SOC_NRF54H20_CPUAPP && REMOTE_NRF54H20_CPUFLPR_XIP_CORE diff --git a/samples/sysbuild/hello_world/sample.yaml b/samples/sysbuild/hello_world/sample.yaml index 86eeea479c6f8..eaff50bb68e1d 100644 --- a/samples/sysbuild/hello_world/sample.yaml +++ b/samples/sysbuild/hello_world/sample.yaml @@ -17,14 +17,13 @@ tests: - nrf5340dk/nrf5340/cpuapp integration_platforms: - nrf5340dk/nrf5340/cpuapp - extra_args: SB_CONF_FILE=sysbuild/nrf5340dk_nrf5340_cpunet.conf sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpurad: platform_allow: - nrf54h20dk/nrf54h20/cpuapp integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf + - SB_CONFIG_REMOTE_NRF54H20_CPURAD_CORE=y - hello_world_CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpuppr: platform_allow: @@ -32,7 +31,7 @@ tests: integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpuppr.conf + - SB_CONFIG_REMOTE_NRF54H20_CPUPPR_CORE=y - hello_world_SNIPPET=nordic-ppr sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpuppr_xip: platform_allow: @@ -40,17 +39,20 @@ tests: integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpuppr_xip.conf + - SB_CONFIG_REMOTE_NRF54H20_CPUPPR_XIP_CORE=y - hello_world_SNIPPET=nordic-ppr-xip - sample.sysbuild.hello_world.nrf54l15dk_nrf54l15_cpuflpr: + sample.sysbuild.hello_world.nrf54l15_cpuflpr: platform_allow: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp + - bl54l15_dvk/nrf54l15/cpuapp + - bl54l15u_dvk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp + - bl54l15_dvk/nrf54l15/cpuapp + - bl54l15u_dvk/nrf54l15/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54l15dk_nrf54l15_cpuflpr.conf - hello_world_SNIPPET=nordic-flpr sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpuflpr: platform_allow: @@ -58,7 +60,7 @@ tests: integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpuflpr.conf + - SB_CONFIG_REMOTE_NRF54H20_CPUFLPR_CORE=y - hello_world_SNIPPET=nordic-flpr sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpuflpr_xip: platform_allow: @@ -66,21 +68,5 @@ tests: integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: - - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpuflpr_xip.conf + - SB_CONFIG_REMOTE_NRF54H20_CPUFLPR_XIP_CORE=y - hello_world_SNIPPET=nordic-flpr-xip - sample.sysbuild.hello_world.bl54l15_dvk_nrf54l15_cpuflpr: - platform_allow: - - bl54l15_dvk/nrf54l15/cpuapp - integration_platforms: - - bl54l15_dvk/nrf54l15/cpuapp - extra_args: - - SB_CONF_FILE=sysbuild/bl54l15_dvk_nrf54l15_cpuflpr.conf - - hello_world_SNIPPET=nordic-flpr - sample.sysbuild.hello_world.bl54l15u_dvk_nrf54l15_cpuflpr: - platform_allow: - - bl54l15u_dvk/nrf54l15/cpuapp - integration_platforms: - - bl54l15u_dvk/nrf54l15/cpuapp - extra_args: - - SB_CONF_FILE=sysbuild/bl54l15u_dvk_nrf54l15_cpuflpr.conf - - hello_world_SNIPPET=nordic-flpr diff --git a/samples/sysbuild/hello_world/sysbuild.cmake b/samples/sysbuild/hello_world/sysbuild.cmake index c7c2615c665ac..fa0599c6a6214 100644 --- a/samples/sysbuild/hello_world/sysbuild.cmake +++ b/samples/sysbuild/hello_world/sysbuild.cmake @@ -1,15 +1,14 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") - message(FATAL_ERROR "REMOTE_BOARD must be set to a valid board name") -endif() - -ExternalZephyrProject_Add( - APPLICATION remote - SOURCE_DIR ${APP_DIR}/remote - BOARD ${SB_CONFIG_REMOTE_BOARD} -) +if(DEFINED SB_CONFIG_REMOTE_BOARD) + ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_REMOTE_BOARD} + BOARD_REVISION ${BOARD_REVISION} + ) -add_dependencies(${DEFAULT_IMAGE} remote) -sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} remote) + add_dependencies(${DEFAULT_IMAGE} remote) + sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} remote) +endif() diff --git a/samples/sysbuild/hello_world/sysbuild/bl54l15_dvk_nrf54l15_cpuflpr.conf b/samples/sysbuild/hello_world/sysbuild/bl54l15_dvk_nrf54l15_cpuflpr.conf deleted file mode 100644 index e801448406715..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/bl54l15_dvk_nrf54l15_cpuflpr.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# Copyright (c) 2025 Ezurio LLC -# -# SPDX-License-Identifier: Apache-2.0 - -SB_CONFIG_REMOTE_BOARD="bl54l15_dvk/nrf54l15/cpuflpr" diff --git a/samples/sysbuild/hello_world/sysbuild/bl54l15u_dvk_nrf54l15_cpuflpr.conf b/samples/sysbuild/hello_world/sysbuild/bl54l15u_dvk_nrf54l15_cpuflpr.conf deleted file mode 100644 index 927961f56e307..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/bl54l15u_dvk_nrf54l15_cpuflpr.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# Copyright (c) 2025 Ezurio LLC -# -# SPDX-License-Identifier: Apache-2.0 - -SB_CONFIG_REMOTE_BOARD="bl54l15u_dvk/nrf54l15/cpuflpr" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf5340dk_nrf5340_cpunet.conf b/samples/sysbuild/hello_world/sysbuild/nrf5340dk_nrf5340_cpunet.conf deleted file mode 100644 index b8ae05d4ef6fa..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf5340dk_nrf5340_cpunet.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf5340dk/nrf5340/cpunet" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr.conf deleted file mode 100644 index 1f67cc417982a..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpuflpr" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr_xip.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr_xip.conf deleted file mode 100644 index 0d827be9a1bbc..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuflpr_xip.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpuflpr/xip" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr.conf deleted file mode 100644 index f50bc8553a011..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpuppr" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr_xip.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr_xip.conf deleted file mode 100644 index 270c92c09a4f3..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpuppr_xip.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpuppr/xip" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index dd863e78d9933..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpurad" diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54l15dk_nrf54l15_cpuflpr.conf b/samples/sysbuild/hello_world/sysbuild/nrf54l15dk_nrf54l15_cpuflpr.conf deleted file mode 100644 index 203dc628f47d6..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54l15dk_nrf54l15_cpuflpr.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54l15dk/nrf54l15/cpuflpr" diff --git a/samples/tfm_integration/config_build/sample.yaml b/samples/tfm_integration/config_build/sample.yaml index 3c46c148f7bab..55c4e2348081f 100644 --- a/samples/tfm_integration/config_build/sample.yaml +++ b/samples/tfm_integration/config_build/sample.yaml @@ -10,6 +10,7 @@ common: - nrf9160dk/nrf9160/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - bl5340_dvk/nrf5340/cpuapp/ns integration_platforms: - nrf5340dk/nrf5340/cpuapp/ns diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index 390efa24fb7e1..154d91b23f312 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -35,6 +35,7 @@ tests: - mps2/an521/cpu0/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns extra_configs: - CONFIG_TFM_BL2=n harness: console diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 025c3f085ab86..0e5431da861f3 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1275,6 +1275,8 @@ def check_no_undef_outside_kconfig(self, kconf): "GEN_UICR_PROTECTEDMEM_SIZE_BYTES", "GEN_UICR_SECONDARY", "GEN_UICR_SECONDARY_GENERATE_PERIPHCONF", + "GEN_UICR_SECONDARY_PROCESSOR_APPLICATION", + "GEN_UICR_SECONDARY_PROCESSOR_RADIOCORE", "GEN_UICR_SECONDARY_PROCESSOR_VALUE", "GEN_UICR_SECONDARY_PROTECTEDMEM", "GEN_UICR_SECONDARY_PROTECTEDMEM_SIZE_BYTES", @@ -1288,10 +1290,14 @@ def check_no_undef_outside_kconfig(self, kconf): "GEN_UICR_SECONDARY_WDTSTART", "GEN_UICR_SECONDARY_WDTSTART_CRV", "GEN_UICR_SECONDARY_WDTSTART_INSTANCE_CODE", + "GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT0", + "GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT1", "GEN_UICR_SECURESTORAGE", "GEN_UICR_WDTSTART", "GEN_UICR_WDTSTART_CRV", "GEN_UICR_WDTSTART_INSTANCE_CODE", + "GEN_UICR_WDTSTART_INSTANCE_WDT0", + "GEN_UICR_WDTSTART_INSTANCE_WDT1", "HEAP_MEM_POOL_ADD_SIZE_", # Used as an option matching prefix "HUGETLBFS", # Linux, in boards/xtensa/intel_adsp_cavs25/doc "IAR_BUFFERED_WRITE", @@ -1370,6 +1376,7 @@ def check_no_undef_outside_kconfig(self, kconf): "ZEPHYR_TRY_MASS_ERASE", # MCUBoot setting described in sysbuild # documentation "ZTEST_FAIL_TEST_", # regex in tests/ztest/fail/CMakeLists.txt + "ZVFS_OPEN_ADD_SIZE_", # Used as an option matching prefix # zephyr-keep-sorted-stop } diff --git a/scripts/coredump/gdbstubs/arch/arm_cortex_m.py b/scripts/coredump/gdbstubs/arch/arm_cortex_m.py index 02cdac598ff9b..3a7f1cbd91fb7 100644 --- a/scripts/coredump/gdbstubs/arch/arm_cortex_m.py +++ b/scripts/coredump/gdbstubs/arch/arm_cortex_m.py @@ -115,8 +115,13 @@ def handle_register_single_read_packet(self, pkt): def handle_register_single_write_packet(self, pkt): pkt_str = pkt.decode("ascii") - reg = int(pkt_str[1:pkt_str.index('=')], 16) - self.registers[reg] = int.from_bytes(binascii.unhexlify(pkt[3:]), byteorder = 'little') + separator_index = pkt_str.index('=') + + if separator_index < 0: + 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.put_gdb_packet(b'+') def arch_supports_thread_operations(self): diff --git a/scripts/kconfig/kconfig.py b/scripts/kconfig/kconfig.py index 4e4e08631798e..ddc98e7bd9a93 100755 --- a/scripts/kconfig/kconfig.py +++ b/scripts/kconfig/kconfig.py @@ -16,7 +16,9 @@ # Also does various checks (most via Kconfiglib warnings). import argparse +import json import os +import pickle import re import sys import textwrap @@ -29,7 +31,9 @@ OR, TRI_TO_STR, TRISTATE, + TYPE_TO_STR, Kconfig, + Symbol, expr_str, expr_value, split_expr, @@ -132,6 +136,13 @@ def main(): print(kconf.write_config(args.config_out)) print(kconf.write_autoconf(args.header_out)) + # Write value origin information for the merged configuration + trace_data = collect_trace_data(kconf) + with open(args.config_out + '-trace.pickle', 'wb') as f: + pickle.dump(trace_data, f) + with open(args.config_out + '-trace.json', 'w') as f: + json.dump(trace_data, f, indent=2) + # Write the list of parsed Kconfig files to a file write_kconfig_filenames(kconf, args.kconfig_list_out) @@ -286,6 +297,44 @@ def promptless(sym): return not any(node.prompt for node in sym.nodes) +def collect_trace_data(kconf): + """ + Collects trace data for all symbols in 'kconf'. The output is currently a + list of 6-tuples with one entry per symbol definition, with the following + layout: + + (name, visibility, type, value, kind, location) + + where the first 4 entries are the string representation of the symbol's + properties, and 'kind' and 'location' are taken from its 'origin' + attribute. + """ + + # NOTE: this data is used by scripts/kconfig/traceconfig.py and the tests + # under tests/kconfig/tracing. Make sure to keep them aligned if the + # format changes in any way. + + trace_data = [] + for node in kconf.node_iter(True): + item = node.item + if not isinstance(item, Symbol): + continue + + origin = item.origin + if origin is None: + continue + + name = kconf.config_prefix + item.name + kind, loc = origin + value = None if kind == "unset" else item.str_value + + trace_entry = (name, TRI_TO_STR[item.visibility], + TYPE_TO_STR[item.type], value, kind, loc) + trace_data.append(trace_entry) + + return trace_data + + def write_kconfig_filenames(kconf, kconfig_list_path): # Writes a sorted list with the absolute paths of all parsed Kconfig files # to 'kconfig_list_path'. The paths are realpath()'d, and duplicates are diff --git a/scripts/kconfig/kconfiglib.py b/scripts/kconfig/kconfiglib.py index a2e0755048d51..316a4c4e40f4f 100644 --- a/scripts/kconfig/kconfiglib.py +++ b/scripts/kconfig/kconfiglib.py @@ -503,9 +503,9 @@ def my_other_fn(kconf, name, arg_1, arg_2, ...): is None, there is no upper limit to the number of arguments. Passing an invalid number of arguments will generate a KconfigError exception. -Functions can access the current parsing location as kconf.filename/linenr. -Accessing other fields of the Kconfig object is not safe. See the warning -below. +Functions can access the current parsing location as kconf.loc, or individually +as kconf.filename/linenr. Accessing other fields of the Kconfig object is not +safe. See the warning below. Keep in mind that for a variable defined like 'foo = $(fn)', 'fn' will be called only when 'foo' is expanded. If 'fn' uses the parsing location and the @@ -851,6 +851,7 @@ class Kconfig(object): "_readline", "filename", "linenr", + "loc", "_include_path", "_filestack", "_line", @@ -1050,8 +1051,7 @@ def _init(self, filename, warn, warn_to_stderr, encoding): self.top_node.prompt = ("Main menu", self.y) self.top_node.parent = None self.top_node.dep = self.y - self.top_node.filename = filename - self.top_node.linenr = 1 + self.top_node.loc = (filename, 1) self.top_node.include_path = () # Parse the Kconfig files @@ -1137,7 +1137,7 @@ def defconfig_filename(self): See the class documentation. """ if self.defconfig_list: - for filename, cond in self.defconfig_list.defaults: + for filename, cond, _ in self.defconfig_list.defaults: if expr_value(cond): try: with self._open_config(filename.str_value) as f: @@ -1270,13 +1270,14 @@ def _load_config(self, filename, replace): for linenr, line in enumerate(f, 1): # The C tools ignore trailing whitespace line = line.rstrip() + loc = (filename, linenr) match = set_match(line) if match: name, val = match.groups() sym = get_sym(name) if not sym or not sym.nodes: - self._undef_assign(name, val, filename, linenr) + self._undef_assign(name, val, loc) continue if sym.orig_type in _BOOL_TRISTATE: @@ -1289,8 +1290,7 @@ def _load_config(self, filename, replace): self._warn("'{}' is not a valid value for the {} " "symbol {}. Assignment ignored." .format(val, TYPE_TO_STR[sym.orig_type], - sym.name_and_loc), - filename, linenr) + sym.name_and_loc), loc) continue val = val[0] @@ -1305,19 +1305,17 @@ def _load_config(self, filename, replace): TRI_TO_STR[prev_mode] != val: self._warn("both m and y assigned to symbols " - "within the same choice", - filename, linenr) + "within the same choice", loc) # Set the choice's mode - sym.choice.set_value(val) + sym.choice.set_value(val, loc) elif sym.orig_type is STRING: match = _conf_string_match(val) if not match: self._warn("malformed string literal in " "assignment to {}. Assignment ignored." - .format(sym.name_and_loc), - filename, linenr) + .format(sym.name_and_loc), loc) continue val = unescape(match.group(1)) @@ -1331,15 +1329,14 @@ def _load_config(self, filename, replace): # rstrip()'d, so blank lines show up as "" here. if line and not line.lstrip().startswith("#"): self._warn("ignoring malformed line '{}'" - .format(line), - filename, linenr) + .format(line), loc) continue name = match.group(1) sym = get_sym(name) if not sym or not sym.nodes: - self._undef_assign(name, "n", filename, linenr) + self._undef_assign(name, "n", loc) continue if sym.orig_type not in _BOOL_TRISTATE: @@ -1350,9 +1347,9 @@ def _load_config(self, filename, replace): # Done parsing the assignment. Set the value. if sym._was_set: - self._assigned_twice(sym, val, filename, linenr) + self._assigned_twice(sym, val, loc) - sym.set_value(val) + sym.set_value(val, loc) if replace: # If we're replacing the configuration, unset the symbols that @@ -1366,16 +1363,16 @@ def _load_config(self, filename, replace): if not choice._was_set: choice.unset_value() - def _undef_assign(self, name, val, filename, linenr): + def _undef_assign(self, name, val, loc): # Called for assignments to undefined symbols during .config loading self.missing_syms.append((name, val)) if self.warn_assign_undef: self._warn( "attempt to assign the value '{}' to the undefined symbol {}" - .format(val, name), filename, linenr) + .format(val, name), loc) - def _assigned_twice(self, sym, new_val, filename, linenr): + def _assigned_twice(self, sym, new_val, loc): # Called when a symbol is assigned more than once in a .config file # Use strings for bool/tristate user values in the warning @@ -1389,9 +1386,9 @@ def _assigned_twice(self, sym, new_val, filename, linenr): if user_val == new_val: if self.warn_assign_redun: - self._warn(msg, filename, linenr) + self._warn(msg, loc) elif self.warn_assign_override: - self._warn(msg, filename, linenr) + self._warn(msg, loc) def load_allconfig(self, filename): """ @@ -2233,6 +2230,8 @@ def _next_line(self): line = line[:-2] + self._readline() self.linenr += 1 + self.loc = (self.filename, self.linenr) + self._tokens = self._tokenize(line) # Initialize to 1 instead of 0 to factor out code from _parse_block() # and _parse_props(). They immediately fetch self._tokens[0]. @@ -2254,6 +2253,7 @@ def _line_after_help(self, line): line = line[:-2] + self._readline() self.linenr += 1 + self.loc = (self.filename, self.linenr) self._tokens = self._tokenize(line) self._reuse_tokens = True @@ -2426,8 +2426,7 @@ def _tokenize(self, s): if token is not _T_CHOICE: self._warn("style: quotes recommended around '{}' in '{}'" - .format(name, self._line.strip()), - self.filename, self.linenr) + .format(name, self._line.strip()), self.loc) token = name i = match.end() @@ -2935,8 +2934,7 @@ def _parse_block(self, end_token, parent, prev): node.is_configdefault = t0 is _T_CONFIGDEFAULT node.prompt = node.help = node.list = None node.parent = parent - node.filename = self.filename - node.linenr = self.linenr + node.loc = self.loc node.include_path = self._include_path sym.nodes.append(node) @@ -3031,8 +3029,7 @@ def _parse_block(self, end_token, parent, prev): node.prompt = (self._expect_str_and_eol(), self.y) node.visibility = self.y node.parent = parent - node.filename = self.filename - node.linenr = self.linenr + node.loc = self.loc node.include_path = self._include_path self.menus.append(node) @@ -3051,8 +3048,7 @@ def _parse_block(self, end_token, parent, prev): node.prompt = (self._expect_str_and_eol(), self.y) node.list = None node.parent = parent - node.filename = self.filename - node.linenr = self.linenr + node.loc = self.loc node.include_path = self._include_path self.comments.append(node) @@ -3083,8 +3079,7 @@ def _parse_block(self, end_token, parent, prev): node.is_menuconfig = True node.prompt = node.help = None node.parent = parent - node.filename = self.filename - node.linenr = self.linenr + node.loc = self.loc node.include_path = self._include_path choice.nodes.append(node) @@ -3175,7 +3170,7 @@ def _parse_props(self, node): self._parse_error("only symbols can select") node.selects.append((self._expect_nonconst_sym(), - self._parse_cond())) + self._parse_cond(), self.loc)) elif t0 is None: # Blank line @@ -3183,26 +3178,26 @@ def _parse_props(self, node): elif t0 is _T_DEFAULT: node.defaults.append((self._parse_expr(False), - self._parse_cond())) + self._parse_cond(), self.loc)) elif t0 in _DEF_TOKEN_TO_TYPE: self._set_type(node.item, _DEF_TOKEN_TO_TYPE[t0]) node.defaults.append((self._parse_expr(False), - self._parse_cond())) + self._parse_cond(), self.loc)) elif t0 is _T_PROMPT: self._parse_prompt(node) elif t0 is _T_RANGE: node.ranges.append((self._expect_sym(), self._expect_sym(), - self._parse_cond())) + self._parse_cond(), self.loc)) elif t0 is _T_IMPLY: if node.item.__class__ is not Symbol: self._parse_error("only symbols can imply") node.implies.append((self._expect_nonconst_sym(), - self._parse_cond())) + self._parse_cond(), self.loc)) elif t0 is _T_VISIBLE: if not self._check_token(_T_IF): @@ -3222,12 +3217,12 @@ def _parse_props(self, node): if env_var in os.environ: node.defaults.append( (self._lookup_const_sym(os.environ[env_var]), - self.y)) + self.y, "env[{}]".format(env_var))) else: self._warn("{1} has 'option env=\"{0}\"', " "but the environment variable {0} is not " "set".format(node.item.name, env_var), - self.filename, self.linenr) + self.loc) if env_var != node.item.name: self._warn("Kconfiglib expands environment variables " @@ -3237,7 +3232,7 @@ def _parse_props(self, node): "rename {} to {} (so that the symbol name " "matches the environment variable name)." .format(node.item.name, env_var), - self.filename, self.linenr) + self.loc) elif self._check_token(_T_DEFCONFIG_LIST): if not self.defconfig_list: @@ -3247,7 +3242,7 @@ def _parse_props(self, node): "symbols ({0} and {1}). Only {0} will be " "used.".format(self.defconfig_list.name, node.item.name), - self.filename, self.linenr) + self.loc) elif self._check_token(_T_MODULES): # To reduce warning spam, only warn if 'option modules' is @@ -3263,8 +3258,7 @@ def _parse_props(self, node): "Kconfiglib just assumes the symbol name " "MODULES, like older versions of the C " "implementation did when 'option modules' " - "wasn't used.", - self.filename, self.linenr) + "wasn't used.", self.loc) elif self._check_token(_T_ALLNOCONFIG_Y): if node.item.__class__ is not Symbol: @@ -3499,7 +3493,7 @@ def _build_dep(self): depend_on(sym, node.prompt[1]) # The default values and their conditions - for value, cond in sym.defaults: + for value, cond, _ in sym.defaults: depend_on(sym, value) depend_on(sym, cond) @@ -3508,7 +3502,7 @@ def _build_dep(self): depend_on(sym, sym.weak_rev_dep) # The ranges along with their conditions - for low, high, cond in sym.ranges: + for low, high, cond, _ in sym.ranges: depend_on(sym, low) depend_on(sym, high) depend_on(sym, cond) @@ -3534,7 +3528,7 @@ def _build_dep(self): depend_on(choice, node.prompt[1]) # The default symbol conditions - for _, cond in choice.defaults: + for _, cond, _ in choice.defaults: depend_on(choice, cond) def _add_choice_deps(self): @@ -3579,7 +3573,7 @@ def _finalize_sym(self, sym): # Add the defaults to the node, with the requirement that # direct dependencies are respected. The original order # of the default statements between nodes is preserved. - default = (d[0], self._make_and(sym.direct_dep, d[1])) + default = (d[0], self._make_and(sym.direct_dep, d[1]), d[2]) sym.defaults.insert(inserted + idx, default) inserted += 1 @@ -3690,23 +3684,23 @@ def _propagate_deps(self, node, visible_if): # Propagate dependencies to defaults if cur.defaults: - cur.defaults = [(default, self._make_and(cond, dep)) - for default, cond in cur.defaults] + cur.defaults = [(default, self._make_and(cond, dep), loc) + for default, cond, loc in cur.defaults] # Propagate dependencies to ranges if cur.ranges: - cur.ranges = [(low, high, self._make_and(cond, dep)) - for low, high, cond in cur.ranges] + cur.ranges = [(low, high, self._make_and(cond, dep), loc) + for low, high, cond, loc in cur.ranges] # Propagate dependencies to selects if cur.selects: - cur.selects = [(target, self._make_and(cond, dep)) - for target, cond in cur.selects] + cur.selects = [(target, self._make_and(cond, dep), loc) + for target, cond, loc in cur.selects] # Propagate dependencies to implies if cur.implies: - cur.implies = [(target, self._make_and(cond, dep)) - for target, cond in cur.implies] + cur.implies = [(target, self._make_and(cond, dep), loc) + for target, cond, loc in cur.implies] elif cur.prompt: # Not a symbol/choice # Propagate dependencies to the prompt. 'visible if' is only @@ -3745,14 +3739,14 @@ def _add_props_to_sym(self, node): sym.implies += node.implies # Modify the reverse dependencies of the selected symbol - for target, cond in node.selects: + for target, cond, _ in node.selects: target.rev_dep = self._make_or( target.rev_dep, self._make_and(sym, cond)) # Modify the weak reverse dependencies of the implied # symbol - for target, cond in node.implies: + for target, cond, _ in node.implies: target.weak_rev_dep = self._make_or( target.weak_rev_dep, self._make_and(sym, cond)) @@ -3781,7 +3775,7 @@ def num_ok(sym, type_): # A helper function could be factored out here, but keep it # speedy/straightforward - for target_sym, _ in sym.selects: + for target_sym, _, _ in sym.selects: if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: self._warn("{} selects the {} symbol {}, which is not " "bool or tristate" @@ -3789,7 +3783,7 @@ def num_ok(sym, type_): TYPE_TO_STR[target_sym.orig_type], target_sym.name_and_loc)) - for target_sym, _ in sym.implies: + for target_sym, _, _ in sym.implies: if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: self._warn("{} implies the {} symbol {}, which is not " "bool or tristate" @@ -3798,7 +3792,7 @@ def num_ok(sym, type_): target_sym.name_and_loc)) elif sym.orig_type: # STRING/INT/HEX - for default, _ in sym.defaults: + for default, _, _ in sym.defaults: if default.__class__ is not Symbol: raise KconfigError( "the {} symbol {} has a malformed default {} -- " @@ -3840,7 +3834,7 @@ def num_ok(sym, type_): .format(TYPE_TO_STR[sym.orig_type], sym.name_and_loc)) else: - for low, high, _ in sym.ranges: + for low, high, _, _ in sym.ranges: if not num_ok(low, sym.orig_type) or \ not num_ok(high, sym.orig_type): @@ -3878,7 +3872,7 @@ def warn_select_imply(sym, expr, expr_type): else: self._warn(choice.name_and_loc + " defined without a prompt") - for default, _ in choice.defaults: + for default, _, _ in choice.defaults: if default.__class__ is not Symbol: raise KconfigError( "{} has a malformed default {}" @@ -4001,18 +3995,18 @@ def is_num(s): for node in self.node_iter(): if sym in node.referenced: msg += "\n\n- Referenced at {}:{}:\n\n{}" \ - .format(node.filename, node.linenr, node) + .format(node.loc[0], node.loc[1], node) self._warn(msg) - def _warn(self, msg, filename=None, linenr=None): + def _warn(self, msg, loc=None): # For printing general warnings if not self.warn: return msg = "warning: " + msg - if filename is not None: - msg = "{}:{}: {}".format(filename, linenr, msg) + if loc is not None: + msg = "{}:{}: {}".format(loc[0], loc[1], msg) self.warnings.append(msg) if self.warn_to_stderr: @@ -4119,6 +4113,24 @@ class Symbol(object): The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See the module documentation for an overview of symbol values and visibility. + origin: + A (kind, loc) tuple containing information about how and where a symbol's + final value is derived, or None if the symbol is hidden from the + configuration and can't be given a value. + + There can be 5 kinds of origins of a symbol's value: + - "assign", when it was set by the user (via CONFIG_xx=y) + - "default", when it was set by a 'default' property + - "select", when it was set by a 'select' statement on another symbol + - "imply", when it was set by an 'imply' statement on another symbol + - "unset", when none of the above applied + The location can be either: + - None, if the value is unset, has an implicit default, or no location + was provided in set_value(); + - a (filename, linenr) tuple, if the value was set by a single line; + - a list of strings describing the conditions that resulted in the + value being set, in case of reverse dependencies (select and imply). + config_string: The .config assignment string that would get written out for the symbol by Kconfig.write_config(). Returns the empty string if no .config @@ -4160,13 +4172,17 @@ class Symbol(object): most symbols. Undefined and constant symbols have an empty nodes list. Symbols defined in multiple locations get one node for each location. + user_loc: + A (filename, linenr) tuple indicating where the user value was set, or + None if the user hasn't set a value. + choice: Holds the parent Choice for choice symbols, and None for non-choice symbols. Doubles as a flag for whether a symbol is a choice symbol. defaults: - List of (default, cond) tuples for the symbol's 'default' properties. For - example, 'default A && B if C || D' is represented as + List of (default, cond, loc) tuples for the symbol's 'default' + properties. For example, 'default A && B if C || D' is represented as ((AND, A, B), (OR, C, D)). If no condition was given, 'cond' is self.kconfig.y. @@ -4174,9 +4190,9 @@ class Symbol(object): 'default' conditions. selects: - List of (symbol, cond) tuples for the symbol's 'select' properties. For - example, 'select A if B && C' is represented as (A, (AND, B, C)). If no - condition was given, 'cond' is self.kconfig.y. + List of (symbol, cond, loc) tuples for the symbol's 'select' properties. + For example, 'select A if B && C' is represented as (A, (AND, B, C)). If + no condition was given, 'cond' is self.kconfig.y. Note that 'depends on' and parent dependencies are propagated to 'select' conditions. @@ -4185,9 +4201,9 @@ class Symbol(object): Like 'selects', for imply. ranges: - List of (low, high, cond) tuples for the symbol's 'range' properties. For - example, 'range 1 2 if A' is represented as (1, 2, A). If there is no - condition, 'cond' is self.kconfig.y. + List of (low, high, cond, loc) tuples for the symbol's 'range' + properties. For example, 'range 1 2 if A' is represented as (1, 2, A). If + there is no condition, 'cond' is self.kconfig.y. Note that 'depends on' and parent dependencies are propagated to 'range' conditions. @@ -4283,6 +4299,7 @@ class Symbol(object): "_cached_vis", "_dependents", "_old_val", + "_origin", "_visited", "_was_set", "_write_to_conf", @@ -4301,6 +4318,7 @@ class Symbol(object): "ranges", "rev_dep", "selects", + "user_loc", "user_value", "weak_rev_dep", ) @@ -4343,6 +4361,7 @@ def str_value(self): return self.name val = "" + self._origin = None # Warning: See Symbol._rec_invalidate(), and note that this is a hidden # function call (property magic) vis = self.visibility @@ -4358,7 +4377,7 @@ def str_value(self): base = _TYPE_TO_BASE[self.orig_type] # Check if a range is in effect - for low_expr, high_expr, cond in self.ranges: + for low_expr, high_expr, cond, _ in self.ranges: if expr_value(cond): has_active_range = True @@ -4394,6 +4413,7 @@ def str_value(self): # specified in the assignment (with or without "0x", etc.) val = self.user_value use_defaults = False + self._origin = _T_CONFIG, self.user_loc if use_defaults: # No user value or invalid user value. Look at defaults. @@ -4401,11 +4421,12 @@ def str_value(self): # Used to implement the warning below has_default = False - for sym, cond in self.defaults: + for sym, cond, loc in self.defaults: if expr_value(cond): has_default = self._write_to_conf = True val = sym.str_value + self._origin = _T_DEFAULT, loc if _is_base_n(val, base): val_num = int(val, base) @@ -4415,6 +4436,7 @@ def str_value(self): break else: val_num = 0 # strtoll() on empty string + self._origin = _T_DEFAULT, None # This clamping procedure runs even if there's no default if has_active_range: @@ -4444,12 +4466,14 @@ def str_value(self): if vis and self.user_value is not None: # If the symbol is visible and has a user value, use that val = self.user_value + self._origin = _T_CONFIG, self.user_loc else: # Otherwise, look at defaults - for sym, cond in self.defaults: + for sym, cond, loc in self.defaults: if expr_value(cond): val = sym.str_value self._write_to_conf = True + self._origin = _T_DEFAULT, loc break # env_var corresponds to SYMBOL_AUTO in the C implementation, and is @@ -4495,17 +4519,19 @@ def tri_value(self): if vis and self.user_value is not None: # If the symbol is visible and has a user value, use that val = min(self.user_value, vis) + self._origin = _T_CONFIG, self.user_loc else: # Otherwise, look at defaults and weak reverse dependencies # (implies) - for default, cond in self.defaults: + for default, cond, loc in self.defaults: dep_val = expr_value(cond) if dep_val: val = min(expr_value(default), dep_val) if val: self._write_to_conf = True + self._origin = _T_DEFAULT, loc break # Weak reverse dependencies are only considered if our @@ -4514,6 +4540,7 @@ def tri_value(self): if dep_val and expr_value(self.direct_dep): val = max(dep_val, val) self._write_to_conf = True + self._origin = _T_IMPLY, None # expanded later # Reverse (select-related) dependencies take precedence dep_val = expr_value(self.rev_dep) @@ -4523,6 +4550,7 @@ def tri_value(self): val = max(dep_val, val) self._write_to_conf = True + self._origin = _T_SELECT, None # expanded later # m is promoted to y for (1) bool symbols and (2) symbols with a # weak_rev_dep (from imply) of y @@ -4535,6 +4563,8 @@ def tri_value(self): # the visibility of choice symbols, so it's sufficient to just # check the visibility of the choice symbols themselves. val = 2 if self.choice.selection is self else 0 + self._origin = self.choice._origin \ + if self.choice.selection is self else None elif vis and self.user_value: # Visible choice symbol in m-mode choice, with set non-0 user value @@ -4561,6 +4591,38 @@ def visibility(self): self._cached_vis = _visibility(self) return self._cached_vis + @property + def origin(self): + """ + See the class documentation. + """ + # Reading 'str_value' computes _write_to_conf and _origin. + _ = self.str_value + if not self._write_to_conf: + return None + + if not self._origin: + return (KIND_TO_STR[UNKNOWN], None) + + kind, loc = self._origin + + if kind == _T_SELECT: + # calculate subexpressions that contribute to the value + loc = [ expr_str(subexpr) + for subexpr in split_expr(self.rev_dep, OR) + if expr_value(subexpr) ] + elif kind == _T_IMPLY: + # calculate subexpressions that contribute to the value + loc = [ expr_str(subexpr) + for subexpr in split_expr(self.weak_rev_dep, OR) + if expr_value(subexpr) ] + elif isinstance(loc, tuple) and not os.path.isabs(loc[0]): + # convert filename to absolute + fn, ln = loc + loc = os.path.abspath(os.path.join(self.kconfig.srctree, fn)), ln + + return (KIND_TO_STR[kind], loc) + @property def config_string(self): """ @@ -4594,7 +4656,7 @@ def name_and_loc(self): """ return self.name + " " + _locs(self) - def set_value(self, value): + def set_value(self, value, loc=None): """ Sets the user value of the symbol. @@ -4627,6 +4689,9 @@ def set_value(self, value): Symbol.user_value. Kconfiglib will print a warning by default for invalid assignments, and set_value() will return False. + loc: + A (filename, linenr) tuple indicating where the value was set. + Returns True if the value is valid for the type of the symbol, and False otherwise. This only looks at the form of the value. For BOOL and TRISTATE symbols, check the Symbol.assignable attribute to see what @@ -4667,6 +4732,7 @@ def set_value(self, value): return False + self.user_loc = loc self.user_value = value self._was_set = True @@ -4689,6 +4755,7 @@ def unset_value(self): gotten a user value via Kconfig.load_config() or Symbol.set_value(). """ if self.user_value is not None: + self.user_loc = None self.user_value = None self._rec_invalidate_if_has_prompt() @@ -4774,7 +4841,7 @@ def __repr__(self): if self.nodes: for node in self.nodes: - add("{}:{}".format(node.filename, node.linenr)) + add("{}:{}".format(*node.loc)) else: add("constant" if self.is_constant else "undefined") @@ -4833,9 +4900,11 @@ def __init__(self): self.implies = [] self.ranges = [] + self.user_loc = \ self.user_value = \ self.choice = \ self.env_var = \ + self._origin = \ self._cached_str_val = self._cached_tri_val = self._cached_vis = \ self._cached_assignable = None @@ -4965,7 +5034,7 @@ def _str_default(self): # Defaults, selects, and implies do not affect choice symbols if not self.choice: - for default, cond in self.defaults: + for default, cond, _ in self.defaults: cond_val = expr_value(cond) if cond_val: val = min(expr_value(default), cond_val) @@ -4983,7 +5052,7 @@ def _str_default(self): return TRI_TO_STR[val] if self.orig_type: # STRING/INT/HEX - for default, cond in self.defaults: + for default, cond, _ in self.defaults: if expr_value(cond): return default.str_value @@ -5131,6 +5200,10 @@ class Choice(object): WARNING: Do not assign directly to this. It will break things. Call sym.set_value(2) on the choice symbol to be selected instead. + user_loc: + A (filename, linenr) tuple indicating where the user value was set, or + None if the user hasn't set a value. + visibility: See the Symbol class documentation. Acts on the value (mode). @@ -5190,6 +5263,7 @@ class Choice(object): "_cached_selection", "_cached_vis", "_dependents", + "_origin", "_visited", "_was_set", "defaults", @@ -5201,6 +5275,7 @@ class Choice(object): "nodes", "orig_type", "syms", + "user_loc", "user_selection", "user_value", ) @@ -5280,7 +5355,7 @@ def selection(self): self._cached_selection = self._selection() return self._cached_selection - def set_value(self, value): + def set_value(self, value, loc=None): """ Sets the user value (mode) of the choice. Like for Symbol.set_value(), the visibility might truncate the value. Choices without the 'optional' @@ -5315,6 +5390,7 @@ def set_value(self, value): return False + self.user_loc = loc self.user_value = value self._was_set = True self._rec_invalidate() @@ -5327,6 +5403,7 @@ def unset_value(self): the user had never touched the mode or any of the choice symbols. """ if self.user_value is not None or self.user_selection: + self.user_loc = None self.user_value = self.user_selection = None self._rec_invalidate() @@ -5380,7 +5457,7 @@ def __repr__(self): add("optional") for node in self.nodes: - add("{}:{}".format(node.filename, node.linenr)) + add("{}:{}".format(*node.loc)) return "<{}>".format(", ".join(fields)) @@ -5430,6 +5507,7 @@ def __init__(self): self.name = \ self.user_value = self.user_selection = \ + self.user_loc = self._origin = \ self._cached_vis = self._cached_assignable = None self._cached_selection = _NO_CACHED_SELECTION @@ -5471,6 +5549,7 @@ def _selection(self): # Use the user selection if it's visible if self.user_selection and self.user_selection.visibility: + self._origin = _T_CONFIG, self.user_loc return self.user_selection # Otherwise, check if we have a default @@ -5478,20 +5557,23 @@ def _selection(self): def _selection_from_defaults(self): # Check if we have a default - for sym, cond in self.defaults: + for sym, cond, loc in self.defaults: # The default symbol must be visible too if expr_value(cond) and sym.visibility: + self._origin = _T_DEFAULT, loc return sym # Otherwise, pick the first visible symbol, if any for sym in self.syms: if sym.visibility: + self._origin = _T_DEFAULT, None return sym # Couldn't find a selection return None def _invalidate(self): + self.user_loc = self._origin = \ self._cached_vis = self._cached_assignable = None self._cached_selection = _NO_CACHED_SELECTION @@ -5575,7 +5657,8 @@ class MenuNode(object): orig_ranges: These work the like the corresponding attributes without orig_*, but omit any dependencies propagated from 'depends on' and surrounding 'if's (the - direct dependencies, stored in MenuNode.dep). + direct dependencies, stored in MenuNode.dep). These also strip any + location information. One use for this is generating less cluttered documentation, by only showing the direct dependencies in one place. @@ -5630,10 +5713,11 @@ class MenuNode(object): 'is_menuconfig' is just a hint on how to display the menu node. It's ignored internally by Kconfiglib, except when printing symbols. - filename/linenr: - The location where the menu node appears. The filename is relative to - $srctree (or to the current directory if $srctree isn't set), except - absolute paths are used for paths outside $srctree. + loc/filename/linenr: + The location where the menu node appears, as a (filename, linenr) tuple + or as individual properties. The filename is relative to $srctree (or to + the current directory if $srctree isn't set), except absolute paths are + used for paths outside $srctree. include_path: A tuple of (filename, linenr) tuples, giving the locations of the @@ -5649,15 +5733,14 @@ class MenuNode(object): """ __slots__ = ( "dep", - "filename", "help", "include_path", "is_menuconfig", "is_configdefault", "item", "kconfig", - "linenr", "list", + "loc", "next", "parent", "prompt", @@ -5679,6 +5762,20 @@ def __init__(self): self.implies = [] self.ranges = [] + @property + def filename(self): + """ + See the class documentation. + """ + return self.loc[0] + + @property + def linenr(self): + """ + See the class documentation. + """ + return self.loc[1] + @property def orig_prompt(self): """ @@ -5694,7 +5791,7 @@ def orig_defaults(self): See the class documentation. """ return [(default, self._strip_dep(cond)) - for default, cond in self.defaults] + for default, cond, _ in self.defaults] @property def orig_selects(self): @@ -5702,7 +5799,7 @@ def orig_selects(self): See the class documentation. """ return [(select, self._strip_dep(cond)) - for select, cond in self.selects] + for select, cond, _ in self.selects] @property def orig_implies(self): @@ -5710,7 +5807,7 @@ def orig_implies(self): See the class documentation. """ return [(imply, self._strip_dep(cond)) - for imply, cond in self.implies] + for imply, cond, _ in self.implies] @property def orig_ranges(self): @@ -5718,7 +5815,7 @@ def orig_ranges(self): See the class documentation. """ return [(low, high, self._strip_dep(cond)) - for low, high, cond in self.ranges] + for low, high, cond, _ in self.ranges] @property def referenced(self): @@ -5735,19 +5832,19 @@ def referenced(self): if self.item is MENU: res |= expr_items(self.visibility) - for value, cond in self.defaults: + for value, cond, _ in self.defaults: res |= expr_items(value) res |= expr_items(cond) - for value, cond in self.selects: + for value, cond, _ in self.selects: res.add(value) res |= expr_items(cond) - for value, cond in self.implies: + for value, cond, _ in self.implies: res.add(value) res |= expr_items(cond) - for low, high, cond in self.ranges: + for low, high, cond, _ in self.ranges: res.add(low) res.add(high) res |= expr_items(cond) @@ -5798,7 +5895,7 @@ def __repr__(self): if self.next: add("has next") - add("{}:{}".format(self.filename, self.linenr)) + add("{}:{}".format(*self.loc)) return "<{}>".format(", ".join(fields)) @@ -6477,7 +6574,7 @@ def _locs(sc): if sc.nodes: return "(defined at {})".format( - ", ".join("{0.filename}:{0.linenr}".format(node) + ", ".join("{}:{}".format(*node.loc) for node in sc.nodes)) return "(undefined)" @@ -6815,7 +6912,7 @@ def _info_fn(kconf, _, msg): def _warning_if_fn(kconf, _, cond, msg): if cond == "y": - kconf._warn(msg, kconf.filename, kconf.linenr) + kconf._warn(msg, kconf.loc) return "" @@ -6845,7 +6942,7 @@ def _shell_fn(kconf, _, command): if stderr: kconf._warn("'{}' wrote to stderr: {}".format( command, "\n".join(stderr.splitlines())), - kconf.filename, kconf.linenr) + kconf.loc) # Universal newlines with splitlines() (to prevent e.g. stray \r's in # command output on Windows), trailing newline removal, and @@ -7158,6 +7255,15 @@ def _shell_fn(kconf, _, command): GREATER_EQUAL, }) +# Origin kinds map +KIND_TO_STR = { + UNKNOWN: "unset", # value not set + _T_CONFIG: "assign", # explicit assignment + _T_DEFAULT: "default", # 'default' statement + _T_SELECT: "select", # 'select' statement + _T_IMPLY: "imply", # 'imply' statement +} + # Helper functions for getting compiled regular expressions, with the needed # matching function returned directly as a small optimization. # diff --git a/scripts/kconfig/traceconfig.py b/scripts/kconfig/traceconfig.py new file mode 100755 index 0000000000000..ca22fb093ea5c --- /dev/null +++ b/scripts/kconfig/traceconfig.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os +import pickle + +from tabulate import tabulate + +KIND_TO_COL = { + "unset": "not set", + "default": "default", + "assign": "assigned", + "select": "selected", + "imply": "implied", +} + + +def source_link(refpath, fn, ln): + if refpath: + fn = os.path.relpath(fn, refpath) + + link_fn = fn + disp_fn = os.path.normpath(fn).replace("../", "").replace("_", "\\_") + + return f"[{disp_fn}:{ln}](<{link_fn}#L{ln}>)" + + +def write_markdown(trace_data, output): + sections = {"user": [], "hidden": [], "unset": []} + + if os.name == "nt": + # relative paths on Windows can't span drives, so don't use them + # generated links will be absolute + refpath = None + else: + refpath = os.path.dirname(os.path.abspath(output)) + + for sym in trace_data: + sym_name, sym_vis, sym_type, sym_value, sym_src, sym_loc = sym + if sym_vis == "n": + section = "hidden" + elif sym_src == "unset": + section = "unset" + else: + section = "user" + + if section == "user": + sym_name = f"`{sym_name}`" + elif section == "hidden": + sym_name = f"`{sym_name}` (h)" + + if sym_type == "string" and sym_value is not None: + sym_value = f'"{sym_value}"'.replace("_", "\\_") + + if isinstance(sym_loc, tuple): + sym_loc = source_link(refpath, *sym_loc) + elif isinstance(sym_loc, list): + sym_loc = " ||
".join(f"`{loc}`" for loc in sym_loc) + sym_loc = sym_loc.replace("|", "\\|") + elif sym_loc is None and sym_src == "default": + sym_loc = "_(implicit)_" + + sym_src = KIND_TO_COL[sym_src] + + sections[section].append((sym_type, sym_name, sym_value, sym_src, sym_loc)) + + lines = [] + add = lines.append + + headers = ["Type", "Name", "Value", "Source", "Location"] + colaligns = ["right", "left", "right", "center", "left"] + + add("\n## Visible symbols\n\n") + add( + tabulate( + sorted(sections["user"], key=lambda x: x[1]), + headers=headers, + tablefmt='pipe', + colalign=colaligns, + ) + ) + + add("\n\n## Invisible symbols\n\n") + add( + tabulate( + sorted(sections["hidden"], key=lambda x: x[1]), + headers=headers, + tablefmt='pipe', + colalign=colaligns, + ) + ) + + add("\n\n## Unset symbols\n\n") + for sym_name in sorted(x[1] for x in sections["unset"]): + add(f" # {sym_name} is not set\n") + + with open(output, "w") as f: + f.writelines(lines) + + +def main(): + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("dotconfig_file", help="Input merged .config file") + parser.add_argument("output_file", help="Output Markdown file") + parser.add_argument("kconfig_file", help="Top-level Kconfig file", nargs="?") + + args = parser.parse_args() + + with open(args.dotconfig_file + '-trace.pickle', 'rb') as f: + trace_data = pickle.load(f) + write_markdown(trace_data, args.output_file) + + +if __name__ == '__main__': + main() diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 0b2b1965cf394..30fa05805ddef 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -170,12 +170,8 @@ def do_add_parser(self, parser_adder): -DEXTRA_DTC_OVERLAY_FILE... cmake arguments: the results are undefined''') - group = parser.add_mutually_exclusive_group() - group.add_argument('--sysbuild', action='store_true', - help='''create multi domain build system''') - group.add_argument('--no-sysbuild', action='store_true', - help='''do not create multi domain build system - (default)''') + group.add_argument('--sysbuild', action=argparse.BooleanOptionalAction, + help='''create multi domain build system or disable it (default)''') group = parser.add_argument_group('pristine builds', PRISTINE_DESCRIPTION) @@ -645,12 +641,12 @@ def _run_cmake(self, board, origin, cmake_opts): cmake_opts.extend(shlex.split(user_args)) config_sysbuild = config_getboolean('sysbuild', False) - if self.args.sysbuild or (config_sysbuild and not self.args.no_sysbuild): + if self.args.sysbuild is True or (config_sysbuild and self.args.sysbuild is not False): cmake_opts.extend([f'-S{SYSBUILD_PROJ_DIR}']) cmake_env = os.environ.copy() cmake_env["APP_DIR"] = str(self.source_dir) else: - # self.args.no_sysbuild == True or config sysbuild False + # self.args.sysbuild == False or config sysbuild False cmake_opts.extend([f'-S{self.source_dir}']) # Invoke CMake from the current working directory using the diff --git a/scripts/west_commands/runners/canopen_program.py b/scripts/west_commands/runners/canopen_program.py index e72b1dbbd6655..a53e05a8e5f71 100644 --- a/scripts/west_commands/runners/canopen_program.py +++ b/scripts/west_commands/runners/canopen_program.py @@ -44,11 +44,6 @@ PROGRAM_CTRL_CLEAR = 0x03 PROGRAM_CTRL_ZEPHYR_CONFIRM = 0x80 -class ToggleAction(argparse.Action): - '''Toggle argument parser''' - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, not option_string.startswith('--no-')) - class CANopenBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for CANopen.''' def __init__(self, cfg, dev_id, can_context=DEFAULT_CAN_CONTEXT, @@ -99,9 +94,7 @@ def do_add_parser(cls, parser): help=f'Python-CAN context to use (default: {DEFAULT_CAN_CONTEXT})') parser.add_argument('--program-number', type=int, default=DEFAULT_PROGRAM_NUMBER, help=f'program number (default: {DEFAULT_PROGRAM_NUMBER})') - parser.add_argument('--confirm', '--no-confirm', - dest='confirm', nargs=0, - action=ToggleAction, + parser.add_argument('--confirm', action=argparse.BooleanOptionalAction, help='confirm after starting? (default: yes)') parser.add_argument('--confirm-only', default=False, action='store_true', help='confirm only, no program download (default: no)') diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index 611848f671cd9..c391788eed3a2 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -377,11 +377,6 @@ def __call__(self, parser, namespace, values, option_string=None): namespace.dt_flash = False -class _ToggleAction(argparse.Action): - - def __call__(self, parser, args, ignored, option): - setattr(args, self.dest, not option.startswith('--no-')) - class DeprecatedAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): @@ -610,14 +605,12 @@ def add_parser(cls, parser): help='path to zephyr.mot' if not caps.file else 'Deprecated, use -f/--file instead.') - parser.add_argument('--erase', '--no-erase', nargs=0, - action=_ToggleAction, + parser.add_argument('--erase', action=argparse.BooleanOptionalAction, help=("mass erase flash before loading, or don't. " "Default action depends on each specific runner." if caps.erase else argparse.SUPPRESS)) - parser.add_argument('--reset', '--no-reset', nargs=0, - action=_ToggleAction, + parser.add_argument('--reset', action=argparse.BooleanOptionalAction, help=("reset device after flashing, or don't. " "Default action depends on each specific runner." if caps.reset else argparse.SUPPRESS)) diff --git a/scripts/west_commands/runners/jlink.py b/scripts/west_commands/runners/jlink.py index 5fa13e19873e2..bb9426ceab86b 100644 --- a/scripts/west_commands/runners/jlink.py +++ b/scripts/west_commands/runners/jlink.py @@ -43,11 +43,6 @@ def is_ip(ip): def is_tunnel(tunnel): return tunnel.startswith("tunnel:") if tunnel else False -class ToggleAction(argparse.Action): - - def __call__(self, parser, args, ignored, option): - setattr(args, self.dest, not option.startswith('--no-')) - class JLinkBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for the J-Link GDB server.''' @@ -194,10 +189,8 @@ def do_add_parser(cls, parser): parser.add_argument('--commander', default=DEFAULT_JLINK_EXE, help=f'''J-Link Commander, default is {DEFAULT_JLINK_EXE}''') - parser.add_argument('--reset-after-load', '--no-reset-after-load', - dest='reset', nargs=0, - action=ToggleAction, - help='obsolete synonym for --reset/--no-reset') + parser.add_argument('--reset-after-load', action=argparse.BooleanOptionalAction, + dest='reset', help='obsolete synonym for --reset/--no-reset') parser.add_argument('--rtt-client', default='JLinkRTTClient', help='RTT client, default is JLinkRTTClient') parser.add_argument('--rtt-port', default=DEFAULT_JLINK_RTT_PORT, diff --git a/scripts/west_commands/sign.py b/scripts/west_commands/sign.py index c6fa273138e5a..c2416f3d4b300 100644 --- a/scripts/west_commands/sign.py +++ b/scripts/west_commands/sign.py @@ -101,12 +101,6 @@ [1]: https://www.silabs.com/documents/public/user-guides/ug574-siwx917-soc-manufacturing-utility-user-guide.pdf ''' -class ToggleAction(argparse.Action): - - def __call__(self, parser, args, ignored, option): - setattr(args, self.dest, not option.startswith('--no-')) - - class Sign(Forceable): def __init__(self): super(Sign, self).__init__( @@ -147,8 +141,7 @@ def do_add_parser(self, parser_adder): # bin file options group = parser.add_argument_group('binary (.bin) file options') - group.add_argument('--bin', '--no-bin', dest='gen_bin', nargs=0, - action=ToggleAction, + group.add_argument('--bin', dest='gen_bin', action=argparse.BooleanOptionalAction, help='''produce a signed .bin file? (default: yes, if supported and unsigned bin exists)''') @@ -159,8 +152,7 @@ def do_add_parser(self, parser_adder): # hex file options group = parser.add_argument_group('Intel HEX (.hex) file options') - group.add_argument('--hex', '--no-hex', dest='gen_hex', nargs=0, - action=ToggleAction, + group.add_argument('--hex', dest='gen_hex', action=argparse.BooleanOptionalAction, help='''produce a signed .hex file? (default: yes, if supported and unsigned hex exists)''') diff --git a/snippets/wifi/wifi-ip/wifi-ip.conf b/snippets/wifi/wifi-ip/wifi-ip.conf index 788715d59b701..cc4dbd175c6e8 100644 --- a/snippets/wifi/wifi-ip/wifi-ip.conf +++ b/snippets/wifi/wifi-ip/wifi-ip.conf @@ -5,7 +5,7 @@ CONFIG_WIFI_NM_WPA_SUPPLICANT=y # Make sure there is enough resources for supplicant and most of the samples CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=24 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_MAX_CONN=10 CONFIG_ZVFS_POLL_MAX=10 diff --git a/snippets/wifi/wifi-ipv4/wifi-ipv4.conf b/snippets/wifi/wifi-ipv4/wifi-ipv4.conf index 89feb091ad351..83684f28b65fa 100644 --- a/snippets/wifi/wifi-ipv4/wifi-ipv4.conf +++ b/snippets/wifi/wifi-ipv4/wifi-ipv4.conf @@ -5,7 +5,7 @@ CONFIG_WIFI_NM_WPA_SUPPLICANT=y # Make sure there is enough resources for supplicant and most of the samples CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=24 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_MAX_CONN=10 CONFIG_ZVFS_POLL_MAX=10 diff --git a/snippets/wifi/wifi-ipv6/wifi-ipv6.conf b/snippets/wifi/wifi-ipv6/wifi-ipv6.conf index f4ea1214ece17..df546df978d10 100644 --- a/snippets/wifi/wifi-ipv6/wifi-ipv6.conf +++ b/snippets/wifi/wifi-ipv6/wifi-ipv6.conf @@ -5,7 +5,7 @@ CONFIG_WIFI_NM_WPA_SUPPLICANT=y # Make sure there is enough resources for supplicant and most of the samples CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=24 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_MAX_CONN=10 CONFIG_ZVFS_POLL_MAX=10 diff --git a/soc/adi/max32/Kconfig.soc b/soc/adi/max32/Kconfig.soc index e4b2347ca0218..7bd66bf2cc70e 100644 --- a/soc/adi/max32/Kconfig.soc +++ b/soc/adi/max32/Kconfig.soc @@ -33,6 +33,10 @@ config SOC_MAX32657 bool select SOC_FAMILY_MAX32_M33 +config SOC_MAX32658 + bool + select SOC_MAX32657 + config SOC_MAX32660 bool select SOC_FAMILY_MAX32_M4 @@ -97,6 +101,7 @@ config SOC default "max32650" if SOC_MAX32650 default "max32655" if SOC_MAX32655 default "max32657" if SOC_MAX32657 + default "max32658" if SOC_MAX32658 default "max32660" if SOC_MAX32660 default "max32662" if SOC_MAX32662 default "max32666" if SOC_MAX32666 diff --git a/soc/adi/max32/mpu_regions.c b/soc/adi/max32/mpu_regions.c index fd5c56a47e3b4..020b5cf19126f 100644 --- a/soc/adi/max32/mpu_regions.c +++ b/soc/adi/max32/mpu_regions.c @@ -6,7 +6,7 @@ #include #include -#include +#include /* * Define noncacheable flash region attributes using noncacheable SRAM memory diff --git a/soc/adi/max32/soc.yml b/soc/adi/max32/soc.yml index 1a4b7c2568d38..270c8c28dfb39 100644 --- a/soc/adi/max32/soc.yml +++ b/soc/adi/max32/soc.yml @@ -9,6 +9,7 @@ family: cpuclusters: - name: m4 - name: max32657 + - name: max32658 - name: max32660 - name: max32662 - name: max32666 diff --git a/soc/andestech/ae350/Kconfig b/soc/andestech/ae350/Kconfig index da4cc0193889c..031bc0756c717 100644 --- a/soc/andestech/ae350/Kconfig +++ b/soc/andestech/ae350/Kconfig @@ -19,7 +19,6 @@ config SOC_SERIES_ANDES_AE350 select CPU_HAS_ANDES_PMA select RISCV_SOC_CONTEXT_SAVE if RISCV_CUSTOM_CSR_ANDES_HWDSP select RISCV_SOC_CONTEXT_SAVE if RISCV_CUSTOM_CSR_ANDES_PFT - select ATOMIC_OPERATIONS_BUILTIN select SOC_EARLY_INIT_HOOK if RISCV_CUSTOM_CSR_ANDES_PMA select SOC_PER_CORE_INIT_HOOK if RISCV_CUSTOM_CSR_ANDES_PMA imply XIP diff --git a/soc/egis/et171/Kconfig b/soc/egis/et171/Kconfig index 2d78bc2d8bfc6..88ec3b2d11fac 100644 --- a/soc/egis/et171/Kconfig +++ b/soc/egis/et171/Kconfig @@ -13,7 +13,6 @@ config SOC_EGIS_ET171 select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - select ATOMIC_OPERATIONS_BUILTIN select CPU_HAS_FPU select CPU_HAS_DCACHE select CPU_HAS_ICACHE diff --git a/soc/infineon/cat1b/cyw20829/mpu_regions.c b/soc/infineon/cat1b/cyw20829/mpu_regions.c index 6ee6078def26f..36313f9481f4b 100644 --- a/soc/infineon/cat1b/cyw20829/mpu_regions.c +++ b/soc/infineon/cat1b/cyw20829/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define BOOTSTRAP_SAHB_RAM_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(sram_bootstrap_sahb)) #define BOOTSTRAP_CBUS_RAM_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(sram_bootstrap_cbus)) diff --git a/soc/infineon/cat1b/psc3/CMakeLists.txt b/soc/infineon/cat1b/psc3/CMakeLists.txt index b97d1ccfb14b4..0251e3ebc7eca 100644 --- a/soc/infineon/cat1b/psc3/CMakeLists.txt +++ b/soc/infineon/cat1b/psc3/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_sources(soc.c) zephyr_include_directories(.) +zephyr_linker_sources(NOINIT noinit.ld) # CAT1B family defines zephyr_compile_definitions_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1 CY_USING_HAL) diff --git a/soc/infineon/cat1b/psc3/Kconfig b/soc/infineon/cat1b/psc3/Kconfig index 7913c201046b9..8ca1975b8e214 100644 --- a/soc/infineon/cat1b/psc3/Kconfig +++ b/soc/infineon/cat1b/psc3/Kconfig @@ -28,3 +28,4 @@ config SOC_SERIES_PSC3 select CPU_CORTEX_M_HAS_CMSE select SOC_EARLY_INIT_HOOK select CPU_CORTEX_M33 + select NOINIT_SNIPPET_FIRST diff --git a/soc/infineon/cat1b/psc3/noinit.ld b/soc/infineon/cat1b/psc3/noinit.ld new file mode 100644 index 0000000000000..3f206e782cb30 --- /dev/null +++ b/soc/infineon/cat1b/psc3/noinit.ld @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* The boot ROM in this device uses the first 8k of SRAM while running. Applications like + * tests\drivers\watchdog\wdt_basic_api expect that variables placed in noint memory will retain + * there value through a reset. This means that the noinit memory region must be located after + * the first 8k of SRAM. The line below is added to the noinit linker section to ensure that. + * It must be used in conjunction with the NOINIT_SNIPPET_FIRST configuration option that has + * been added to the Kconfig file. + */ +. = MAX(ABSOLUTE(.), 0x34002000); diff --git a/soc/infineon/cat1b/psc3/soc.c b/soc/infineon/cat1b/psc3/soc.c index 3676eb0d6b02c..aa0fea00d8018 100644 --- a/soc/infineon/cat1b/psc3/soc.c +++ b/soc/infineon/cat1b/psc3/soc.c @@ -5,16 +5,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include - -#include -#include -#include "cy_pdl.h" +#include void soc_early_init_hook(void) { - /* Initializes the system */ - SystemInit(); + ifx_cycfg_init(); } diff --git a/soc/infineon/edge/pse84/CMakeLists.txt b/soc/infineon/edge/pse84/CMakeLists.txt index 53d390c49b263..527b42bbdb20a 100644 --- a/soc/infineon/edge/pse84/CMakeLists.txt +++ b/soc/infineon/edge/pse84/CMakeLists.txt @@ -40,7 +40,7 @@ endif() zephyr_include_directories(security_config) zephyr_sources(security_config/pse84_boot.c) -if(CONFIG_BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M55 AND CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) +if(CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) zephyr_sources_ifdef(CONFIG_CPU_CORTEX_M55 mpu_regions.c) endif() @@ -51,7 +51,7 @@ if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "armclang") endif() # Add sections -if(CONFIG_BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M33) +if(CONFIG_CPU_CORTEX_M33) zephyr_linker_sources(SECTIONS shared_mem_sec.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") else() diff --git a/soc/infineon/edge/pse84/mpu_regions.c b/soc/infineon/edge/pse84/mpu_regions.c index 137245c4b30f7..b4d285e4e341b 100644 --- a/soc/infineon/edge/pse84/mpu_regions.c +++ b/soc/infineon/edge/pse84/mpu_regions.c @@ -6,7 +6,7 @@ */ #include -#include +#include /* We are expected to give *CONFIG_SIZE* in KB, but REGION_ATTR * expects bytes, so we multiply by 1024 to convert. diff --git a/soc/intel/intel_adsp/Kconfig b/soc/intel/intel_adsp/Kconfig index 7523f167fad2e..9987a54c01f9a 100644 --- a/soc/intel/intel_adsp/Kconfig +++ b/soc/intel/intel_adsp/Kconfig @@ -33,6 +33,13 @@ config INTEL_ADSP_SIM_NO_SECONDARY_CORE_FLOW endif # INTEL_ADSP_SIM +config INTEL_ADSP_FWREADY_MSG + bool "Send firmware ready message to host" + default y if INTEL_ADSP_SIM + help + Send a firmware ready message to the host once the system is up + and running. + config INTEL_ADSP_IPC bool "Driver for the host IPC interrupt delivery" select DEPRECATED diff --git a/soc/intel/intel_adsp/Kconfig.defconfig b/soc/intel/intel_adsp/Kconfig.defconfig index 1d8312e7fb6ce..313ab14931293 100644 --- a/soc/intel/intel_adsp/Kconfig.defconfig +++ b/soc/intel/intel_adsp/Kconfig.defconfig @@ -36,7 +36,7 @@ endif # XTENSA_RPO_CACHE config CONSOLE def_bool y -if CONSOLE +if CONSOLE && !SIMULATOR_XTENSA config WINSTREAM_CONSOLE def_bool y endif diff --git a/soc/intel/intel_adsp/ace/CMakeLists.txt b/soc/intel/intel_adsp/ace/CMakeLists.txt index fdc0519da69dd..306746a8f9b30 100644 --- a/soc/intel/intel_adsp/ace/CMakeLists.txt +++ b/soc/intel/intel_adsp/ace/CMakeLists.txt @@ -33,3 +33,7 @@ if (CONFIG_XTENSA_MMU) endif() set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") + +if (CONFIG_INTEL_ADSP_FWREADY_MSG) + zephyr_library_sources(fw_ready.c) +endif() diff --git a/soc/intel/intel_adsp/ace/Kconfig b/soc/intel/intel_adsp/ace/Kconfig index cdd2749915d3b..a7e225923aa4e 100644 --- a/soc/intel/intel_adsp/ace/Kconfig +++ b/soc/intel/intel_adsp/ace/Kconfig @@ -53,3 +53,12 @@ config SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS help Specify the number of NOPs in Intel Audio DSP specific arch_spin_relax(). + +config SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID + bool "Add CPU ID to offset NOPs" + depends on SOC_SERIES_INTEL_ADSP_ACE_CUSTOM_MORE_SPIN_RELAX_NOPS + help + Add CPU ID to the number of NOPs in arch_spin_relax(). + This is to add some variations to the loop for each CPU to + further avoid them hitting the RCW transactions at the same + time. diff --git a/soc/intel/intel_adsp/ace/fw_ready.c b/soc/intel/intel_adsp/ace/fw_ready.c new file mode 100644 index 0000000000000..c2bf1087d1d09 --- /dev/null +++ b/soc/intel/intel_adsp/ace/fw_ready.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +struct ipc_hdr { + uint32_t size; /**< size of structure */ +} __packed __aligned(4); + +struct ipc_cmd_hdr { + uint32_t size; /**< size of structure */ + uint32_t cmd; /**< SOF_IPC_GLB_ + cmd */ +} __packed __aligned(4); + +struct ipc_fw_version { + struct ipc_hdr hdr; + uint16_t major; + uint16_t minor; + uint16_t micro; + uint16_t build; + uint8_t date[12]; + uint8_t time[10]; + uint8_t tag[6]; + uint32_t abi_version; + uint32_t src_hash; + uint32_t reserved[3]; +} __packed __aligned(4); + +struct ipc_fw_ready { + struct ipc_cmd_hdr hdr; + uint32_t dspbox_offset; + uint32_t hostbox_offset; + uint32_t dspbox_size; + uint32_t hostbox_size; + struct ipc_fw_version version; + uint64_t flags; + uint32_t reserved[4]; +} __packed __aligned(4); + +static const struct ipc_fw_ready ready + Z_GENERIC_DOT_SECTION(fw_ready) __used = { + .hdr = { + .cmd = (0x7U << 28), /* SOF_IPC_FW_READY */ + .size = sizeof(struct ipc_fw_ready), + }, + + .version = { + .hdr.size = sizeof(struct ipc_fw_version), + .micro = 0, + .minor = 0, + .major = 0, + + .build = 0xBEEF, + .date = __DATE__, + .time = __TIME__, + + .tag = "zephyr", + .abi_version = 0, + .src_hash = 0, + }, + + .flags = 0, +}; + +#define IPC4_NOTIFY_FW_READY 8 + +#define IPC4_GLB_NOTIFICATION 27 + +#define IPC4_GLB_NOTIFY_DIR_MASK BIT(29) +#define IPC4_REPLY_STATUS_MASK 0xFFFFFF +#define IPC4_GLB_NOTIFY_TYPE_SHIFT 16 +#define IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT 24 + +#define IPC4_FW_READY \ + (((IPC4_NOTIFY_FW_READY) << (IPC4_GLB_NOTIFY_TYPE_SHIFT)) |\ + ((IPC4_GLB_NOTIFICATION) << (IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT))) + +#define SRAM_SW_REG_BASE (L2_SRAM_BASE + 0x4000) +#define SRAM_SW_REG_SIZE 0x1000 + +#define SRAM_OUTBOX_BASE (SRAM_SW_REG_BASE + SRAM_SW_REG_SIZE) +#define SRAM_OUTBOX_SIZE 0x1000 + +int notify_host_boot_complete(void) +{ + memcpy((void *)SRAM_OUTBOX_BASE, &ready, sizeof(ready)); + + sys_cache_data_flush_range((void *)SRAM_OUTBOX_BASE, SRAM_OUTBOX_SIZE); + + intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, + IPC4_FW_READY, 0); + + return 0; +} + +SYS_INIT(notify_host_boot_complete, POST_KERNEL, 0); diff --git a/soc/intel/intel_adsp/ace/spin_relax.c b/soc/intel/intel_adsp/ace/spin_relax.c index 073deb5a6d07d..0abf94398db1b 100644 --- a/soc/intel/intel_adsp/ace/spin_relax.c +++ b/soc/intel/intel_adsp/ace/spin_relax.c @@ -9,13 +9,20 @@ #include #include +#include + #ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS void arch_spin_relax(void) { register uint32_t remaining = CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS; +#if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID) + remaining += arch_proc_id(); +#endif /* CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID */ + while (remaining > 0) { -#if (CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS % 4) == 0 +#if !defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID) && \ + (CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS % 4) == 0 remaining -= 4; /* diff --git a/soc/microchip/mec/common/CMakeLists.txt b/soc/microchip/mec/common/CMakeLists.txt index 0669a09cbe295..3cc731329d1ff 100644 --- a/soc/microchip/mec/common/CMakeLists.txt +++ b/soc/microchip/mec/common/CMakeLists.txt @@ -1,6 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) +zephyr_library_sources(soc_ecia.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MEC172X soc_i2c.c ) diff --git a/soc/microchip/mec/common/soc_cmn_init.c b/soc/microchip/mec/common/soc_cmn_init.c index bff1bf22a2a35..ffb55dd9567a4 100644 --- a/soc/microchip/mec/common/soc_cmn_init.c +++ b/soc/microchip/mec/common/soc_cmn_init.c @@ -8,7 +8,6 @@ #include #include #include -#include #include static void mec5_soc_init_debug_interface(void) @@ -35,7 +34,7 @@ static void mec5_soc_init_debug_interface(void) int mec5_soc_common_init(void) { mec5_soc_init_debug_interface(); - mec_hal_ecia_init(MEC5_ECIA_DIRECT_BITMAP, 1, 0); + 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_ecia.c b/soc/microchip/mec/common/soc_ecia.c new file mode 100644 index 0000000000000..e7b00e2d3c0ff --- /dev/null +++ b/soc/microchip/mec/common/soc_ecia.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "soc_ecia.h" + +/* EC Subsystem */ +#define MCHP_XEC_ECS_REG_BASE (mem_addr_t) DT_REG_ADDR(DT_NODELABEL(ecs)) +#define MCHP_XEC_ECS_ICR_OFS 0x18u +#define MCHP_XEC_ECS_ICR_DM_EN_POS 0 /* direct mode enable */ + +/* EC Interrupt Aggregator. It is not real interrupt controller. */ +#define MCHP_XEC_ECIA_REG_BASE (mem_addr_t) DT_REG_ADDR(DT_NODELABEL(ecia)) +#define MCHP_XEC_ECIA_GIRQ_SIZE 20u /* 5 32-bit registers */ +#define MCHP_XEC_ECIA_GIRQ_ALL_MSK GENMASK(MCHP_MEC_ECIA_GIRQ_LAST, MCHP_MEC_ECIA_GIRQ_FIRST) +#define MCHP_XEC_ECIA_GIRQ_DIRECT_MSK (GENMASK(21, 13) | BIT(23)) +#define MCHP_XEC_ECIA_GIRQ_AGGR_MSK (GENMASK(12, 8) | BIT(22) | GENMASK(26, 24)) + +#define MCHP_XEC_ECIA_ZGIRQ_OFS(zgirq) ((uint32_t)(zgirq) * MCHP_XEC_ECIA_GIRQ_SIZE) +#define MCHP_XEC_ECIA_GIRQ_OFS(girq) \ + MCHP_XEC_ECIA_ZGIRQ_OFS((uint32_t)(girq) - MCHP_MEC_ECIA_GIRQ_FIRST) + +#define MCHP_XEC_ECIA_GIRQ_SRC_OFS 0 +#define MCHP_XEC_ECIA_GIRQ_ENSET_OFS 4u +#define MCHP_XEC_ECIA_GIRQ_RESULT_OFS 8u +#define MCHP_XEC_ECIA_GIRQ_ENCLR_OFS 12u +/* offset 16 (0x10) is reserved read-only 0 */ + +/* aggregated enable set/clear registers */ +#define MCHP_XEC_ECIA_AGGR_ENSET_OFS 0x200u /* r/w1s */ +#define MCHP_XEC_ECIA_AGGR_ENCLR_OFS 0x204u /* r/w1c */ +#define MCHP_XEC_ECIA_AGGR_ACTV_OFS 0x208u /* read-only */ + +#define MCHP_XEC_ECIA_GIRQ_REG_OFS(girq, regofs) \ + (MCHP_XEC_ECIA_ZGIRQ_OFS((uint32_t)(girq) - MCHP_MEC_ECIA_GIRQ_FIRST) + (uint32_t)regofs) + +#define MCHP_XEC_ECIA_GIRQ_SRC_REG_OFS(girq) \ + MCHP_XEC_ECIA_GIRQ_REG_OFS(girq, MCHP_XEC_ECIA_GIRQ_SRC_OFS) + +#define MCHP_XEC_ECIA_GIRQ_ENSET_REG_OFS(girq) \ + MCHP_XEC_ECIA_GIRQ_REG_OFS(girq, MCHP_XEC_ECIA_GIRQ_ENSET_OFS) + +#define MCHP_XEC_ECIA_GIRQ_RESULT_REG_OFS(girq) \ + MCHP_XEC_ECIA_GIRQ_REG_OFS(girq, MCHP_XEC_ECIA_GIRQ_RESULT_OFS) + +#define MCHP_XEC_ECIA_GIRQ_ENCLR_REG_OFS(girq) \ + MCHP_XEC_ECIA_GIRQ_REG_OFS(girq, MCHP_XEC_ECIA_GIRQ_ENCLR_OFS) + +int soc_ecia_init(uint32_t aggr_girq_bm, uint32_t direct_girq_bm, uint32_t flags) +{ + mem_addr_t ecia_base = MCHP_XEC_ECIA_REG_BASE; + mem_addr_t ecs_base = MCHP_XEC_ECS_REG_BASE; + uint32_t amsk = 0, dmsk = 0, bm = 0, girq = 0, raddr = 0; + + amsk = aggr_girq_bm & MCHP_XEC_ECIA_GIRQ_AGGR_MSK; + dmsk = direct_girq_bm & MCHP_XEC_ECIA_GIRQ_DIRECT_MSK; + + bm = aggr_girq_bm | direct_girq_bm; + while (bm != 0) { + girq = find_lsb_set(bm) - 1u; + + raddr = ecia_base + MCHP_XEC_ECIA_GIRQ_OFS(girq); + + if ((flags & MCHP_MEC_ECIA_INIT_CLR_ENABLES) != 0) { /* clear enables? */ + sys_write32(UINT32_MAX, raddr + MCHP_XEC_ECIA_GIRQ_ENCLR_OFS); + } + + if ((flags & MCHP_MEC_ECIA_INIT_CLR_STATUS) != 0) { /* clear status */ + sys_write32(UINT32_MAX, raddr + MCHP_XEC_ECIA_GIRQ_SRC_OFS); + } + + bm &= (uint32_t)~BIT(girq); + } + + sys_write32(UINT32_MAX, ecia_base + MCHP_XEC_ECIA_AGGR_ENCLR_OFS); + sys_write32(amsk, ecia_base + MCHP_XEC_ECIA_AGGR_ENSET_OFS); + + if (dmsk != 0) { + sys_set_bit(ecs_base + MCHP_XEC_ECS_ICR_OFS, MCHP_XEC_ECS_ICR_DM_EN_POS); + } else { + sys_clear_bit(ecs_base + MCHP_XEC_ECS_ICR_OFS, MCHP_XEC_ECS_ICR_DM_EN_POS); + } + + return 0; +} + +int soc_ecia_girq_ctrl_bm(uint8_t girq, uint32_t bitmap, uint8_t enable) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if ((girq < MCHP_MEC_ECIA_GIRQ_FIRST) || (girq > MCHP_MEC_ECIA_GIRQ_LAST)) { + return -EINVAL; + } + + raddr += MCHP_XEC_ECIA_GIRQ_OFS(girq); + + if (enable != 0) { + raddr += MCHP_XEC_ECIA_GIRQ_ENSET_OFS; + } else { + raddr += MCHP_XEC_ECIA_GIRQ_ENCLR_OFS; + } + + sys_write32(bitmap, raddr); + + return 0; +} + +int soc_ecia_girq_ctrl(uint8_t girq, uint8_t srcpos, uint8_t enable) +{ + uint32_t bitmap = BIT(srcpos); + + return soc_ecia_girq_ctrl_bm(girq, bitmap, enable); +} + +uint32_t soc_ecia_girq_get_enable_bm(uint8_t girq) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if ((girq < MCHP_MEC_ECIA_GIRQ_FIRST) || (girq > MCHP_MEC_ECIA_GIRQ_LAST)) { + return 0; + } + + raddr += MCHP_XEC_ECIA_GIRQ_ENSET_REG_OFS(girq); + + return sys_read32(raddr); +} + +int soc_ecia_girq_status_clear_bm(uint8_t girq, uint32_t bitmap) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if ((girq < MCHP_MEC_ECIA_GIRQ_FIRST) || (girq > MCHP_MEC_ECIA_GIRQ_LAST)) { + return -EINVAL; + } + + raddr += MCHP_XEC_ECIA_GIRQ_SRC_REG_OFS(girq); + + sys_write32(bitmap, raddr); + + return 0; +} + +int soc_ecia_girq_status_clear(uint8_t girq, uint8_t srcpos) +{ + uint32_t bitmap = BIT(srcpos); + + return soc_ecia_girq_status_clear_bm(girq, bitmap); +} + +int soc_ecia_girq_status(uint8_t girq, uint32_t *status) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if ((girq < MCHP_MEC_ECIA_GIRQ_FIRST) || (girq > MCHP_MEC_ECIA_GIRQ_LAST)) { + return -EINVAL; + } + + raddr += MCHP_XEC_ECIA_GIRQ_SRC_REG_OFS(girq); + + if (status != NULL) { + *status = sys_read32(raddr); + } + + return 0; +} + +int soc_ecia_girq_result(uint8_t girq, uint32_t *result) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if ((girq < MCHP_MEC_ECIA_GIRQ_FIRST) || (girq > MCHP_MEC_ECIA_GIRQ_LAST)) { + return -EINVAL; + } + + raddr += MCHP_XEC_ECIA_GIRQ_RESULT_REG_OFS(girq); + + if (result != NULL) { + *result = sys_read32(raddr); + } + + return 0; +} + +int soc_ecia_girq_is_result(uint8_t girq, uint32_t bitmap) +{ + uint32_t result = 0; + + if (soc_ecia_girq_result(girq, &result) != 0) { + return 0; + } + + return (result & bitmap); +} + +int soc_ecia_girq_aggr_ctrl_bm(uint32_t girq_bitmap, uint8_t enable) +{ + mem_addr_t raddr = MCHP_XEC_ECIA_REG_BASE; + + if (enable != 0) { + raddr += MCHP_XEC_ECIA_AGGR_ENSET_OFS; + } else { + raddr += MCHP_XEC_ECIA_AGGR_ENCLR_OFS; + } + + sys_write32(girq_bitmap, raddr); + + return 0; +} + +int soc_ecia_girq_aggr_ctrl(uint8_t girq, uint8_t enable) +{ + uint32_t girq_bitmap = BIT(girq); + + return soc_ecia_girq_aggr_ctrl_bm(girq_bitmap, enable); +} diff --git a/soc/microchip/mec/common/soc_ecia.h b/soc/microchip/mec/common/soc_ecia.h new file mode 100644 index 0000000000000..c137033c4e39b --- /dev/null +++ b/soc/microchip/mec/common/soc_ecia.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Microchip XEC MCU family EC Interrupt Aggregator support. + * + */ + +#ifndef _MICROCHIP_MEC_SOC_ECIA_H_ +#define _MICROCHIP_MEC_SOC_ECIA_H_ + +#include +#include +#include + +/* zero based GIRQ numbering. 19 total GIRQ units in the aggregator */ +#define MCHP_MEC_ECIA_ZGIRQ_MAX 19 + +/* Historically, GIRQ's have been numbered starting with 8 */ +#define MCHP_MEC_ECIA_GIRQ_FIRST 8 +#define MCHP_MEC_ECIA_GIRQ_LAST 26 + +/* MEC ECIA GIRQ's are numbered 8 - 26 for historical reasons. + * GIRQ's 8 - 12, 22, 24 - 26 interrupt sources are only connected to the GIRQ source bits. + * GIRQ's 13 - 21, and 23 result bits can be connected to the NVIC. + */ +#define MCHP_MEC_ECIA_GIRQ_ALL_BM GENMASK(26, 8) +#define MCHP_MEC_ECIA_GIRQ_AGGR_ONLY_BM (GENMASK(12, 8) | BIT(22) | GENMASK(26, 24)) +#define MCHP_MEC_ECIA_GIRQ_DIRECT_CAP_BM (GENMASK(21, 13) | BIT(23)) + +enum mchp_mec_ecia_girq { + MCHP_MEC_ECIA_GIRQ8 = MCHP_MEC_ECIA_GIRQ_FIRST, + MCHP_MEC_ECIA_GIRQ9, + MCHP_MEC_ECIA_GIRQ10, + MCHP_MEC_ECIA_GIRQ11, + MCHP_MEC_ECIA_GIRQ12, + MCHP_MEC_ECIA_GIRQ13, + MCHP_MEC_ECIA_GIRQ14, + MCHP_MEC_ECIA_GIRQ15, + MCHP_MEC_ECIA_GIRQ16, + MCHP_MEC_ECIA_GIRQ17, + MCHP_MEC_ECIA_GIRQ18, + MCHP_MEC_ECIA_GIRQ19, + MCHP_MEC_ECIA_GIRQ20, + MCHP_MEC_ECIA_GIRQ21, + MCHP_MEC_ECIA_GIRQ22, + MCHP_MEC_ECIA_GIRQ23, + MCHP_MEC_ECIA_GIRQ24, + MCHP_MEC_ECIA_GIRQ25, + MCHP_MEC_ECIA_GIRQ26, + MCHP_MEC_ECIA_GIRQ_MAX, +}; + +#define MCHP_MEC_ECIA_INIT_CLR_ENABLES 0x01u +#define MCHP_MEC_ECIA_INIT_CLR_STATUS 0x02u + +int soc_ecia_init(uint32_t aggr_girq_bm, uint32_t direct_girq_bm, uint32_t flags); + +int soc_ecia_girq_ctrl_bm(uint8_t girq, uint32_t bitmap, uint8_t enable); +int soc_ecia_girq_ctrl(uint8_t girq, uint8_t srcpos, uint8_t enable); + +uint32_t soc_ecia_girq_get_enable_bm(uint8_t girq); + +int soc_ecia_girq_status_clear_bm(uint8_t girq, uint32_t bitmap); +int soc_ecia_girq_status_clear(uint8_t girq, uint8_t srcpos); + +int soc_ecia_girq_status(uint8_t girq, uint32_t *status); +int soc_ecia_girq_result(uint8_t girq, uint32_t *result); +int soc_ecia_girq_is_result(uint8_t girq, uint32_t bitmap); + +int soc_ecia_girq_aggr_ctrl_bm(uint32_t girq_bitmap, uint8_t enable); +int soc_ecia_girq_aggr_ctrl(uint8_t girq, uint8_t enable); + +#endif /* _MICROCHIP_MEC_SOC_ECIA_H_ */ diff --git a/soc/microchip/mec/common/soc_mmcr.h b/soc/microchip/mec/common/soc_mmcr.h new file mode 100644 index 0000000000000..8b0c07cbb65fb --- /dev/null +++ b/soc/microchip/mec/common/soc_mmcr.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Microchip MEC MCU family memory mapped control register access + * + */ + +#ifndef _SOC_MICROCHIP_MEC_COMMON_MMCR_H_ +#define _SOC_MICROCHIP_MEC_COMMON_MMCR_H_ + +#include /* mem_addr_t definition */ + +/* Zephyr only provides 32-bit version of these routines. We need these for memory + * mapped control registers located on 16 and 8 bit address boundaries. + */ + +static ALWAYS_INLINE void soc_set_bit8(mem_addr_t addr, unsigned int bit) +{ + uint8_t temp = *(volatile uint8_t *)addr; + + *(volatile uint8_t *)addr = temp | (1U << bit); +} + +static ALWAYS_INLINE void soc_clear_bit8(mem_addr_t addr, unsigned int bit) +{ + uint8_t temp = *(volatile uint8_t *)addr; + + *(volatile uint8_t *)addr = temp & ~(1U << bit); +} + +static ALWAYS_INLINE int soc_test_bit8(mem_addr_t addr, unsigned int bit) +{ + uint8_t temp = *(volatile uint8_t *)addr; + + return temp & (1U << bit); +} + +static ALWAYS_INLINE void soc_set_bits8(mem_addr_t addr, unsigned int mask) +{ + uint8_t temp = *(volatile uint8_t *)addr; + + *(volatile uint8_t *)addr = temp | mask; +} + +static ALWAYS_INLINE void soc_clear_bits8(mem_addr_t addr, unsigned int mask) +{ + uint8_t temp = *(volatile uint8_t *)addr; + + *(volatile uint8_t *)addr = temp & ~mask; +} + +static ALWAYS_INLINE int soc_test_and_set_bit8(mem_addr_t addr, unsigned int bit) +{ + int ret; + + ret = soc_test_bit8(addr, bit); + soc_set_bit8(addr, bit); + + return ret; +} + +static ALWAYS_INLINE int soc_test_and_clear_bit8(mem_addr_t addr, unsigned int bit) +{ + int ret; + + ret = soc_test_bit8(addr, bit); + soc_clear_bit8(addr, bit); + + return ret; +} + +static ALWAYS_INLINE void soc_set_bit16(mem_addr_t addr, unsigned int bit) +{ + uint16_t temp = *(volatile uint16_t *)addr; + + *(volatile uint16_t *)addr = temp | (1U << bit); +} + +static ALWAYS_INLINE void soc_clear_bit16(mem_addr_t addr, unsigned int bit) +{ + uint16_t temp = *(volatile uint16_t *)addr; + + *(volatile uint16_t *)addr = temp & ~(1U << bit); +} + +static ALWAYS_INLINE int soc_test_bit16(mem_addr_t addr, unsigned int bit) +{ + uint16_t temp = *(volatile uint16_t *)addr; + + return temp & (1U << bit); +} + +static ALWAYS_INLINE void soc_set_bits16(mem_addr_t addr, unsigned int mask) +{ + uint16_t temp = *(volatile uint16_t *)addr; + + *(volatile uint16_t *)addr = temp | mask; +} + +static ALWAYS_INLINE void soc_clear_bits16(mem_addr_t addr, unsigned int mask) +{ + uint16_t temp = *(volatile uint16_t *)addr; + + *(volatile uint16_t *)addr = temp & ~mask; +} + +static ALWAYS_INLINE int soc_test_and_set_bit16(mem_addr_t addr, unsigned int bit) +{ + int ret; + + ret = soc_test_bit16(addr, bit); + soc_set_bit16(addr, bit); + + return ret; +} + +static ALWAYS_INLINE int soc_test_and_clear_bit16(mem_addr_t addr, unsigned int bit) +{ + int ret; + + ret = soc_test_bit16(addr, bit); + soc_clear_bit16(addr, bit); + + return ret; +} + +#endif /* SOC_MICROCHIP_MEC_COMMON_MMCR_H_ */ diff --git a/soc/microchip/mec/mec15xx/soc.c b/soc/microchip/mec/mec15xx/soc.c index df21dde363ed2..5c312f73e9abb 100644 --- a/soc/microchip/mec/mec15xx/soc.c +++ b/soc/microchip/mec/mec15xx/soc.c @@ -12,41 +12,6 @@ #include #include -/* - * Initialize MEC1501 EC Interrupt Aggregator (ECIA) and external NVIC - * inputs. - */ -static int soc_ecia_init(void) -{ - GIRQ_Type *pg; - uint32_t n; - - mchp_pcr_periph_slp_ctrl(PCR_ECIA, MCHP_PCR_SLEEP_DIS); - - ECS_REGS->INTR_CTRL |= MCHP_ECS_ICTRL_DIRECT_EN; - - /* gate off all aggregated outputs */ - ECIA_REGS->BLK_EN_CLR = 0xFFFFFFFFul; - /* gate on GIRQ's that are aggregated only */ - ECIA_REGS->BLK_EN_SET = MCHP_ECIA_AGGR_BITMAP; - - /* Clear all GIRQn source enables and source status */ - pg = &ECIA_REGS->GIRQ08; - for (n = MCHP_FIRST_GIRQ; n <= MCHP_LAST_GIRQ; n++) { - pg->EN_CLR = 0xFFFFFFFFul; - pg->SRC = 0xFFFFFFFFul; - pg++; - } - - /* Clear all external NVIC enables and pending status */ - for (n = 0u; n < MCHP_NUM_NVIC_REGS; n++) { - NVIC->ICER[n] = 0xFFFFFFFFul; - NVIC->ICPR[n] = 0xFFFFFFFFul; - } - - return 0; -} - static void configure_debug_interface(void) { /* No debug support */ @@ -75,11 +40,12 @@ void soc_early_init_hook(void) { uint32_t isave; - isave = __get_PRIMASK(); __disable_irq(); - soc_ecia_init(); + configure_debug_interface(); + + soc_ecia_init(MCHP_MEC_ECIA_GIRQ_AGGR_ONLY_BM, MCHP_MEC_ECIA_GIRQ_DIRECT_CAP_BM, 0); /* Configure GPIO bank before usage * VTR1 is not configurable @@ -89,8 +55,6 @@ void soc_early_init_hook(void) ECS_REGS->GPIO_BANK_PWR |= MCHP_ECS_VTR3_LVL_18; #endif - configure_debug_interface(); - if (!isave) { __enable_irq(); } diff --git a/soc/microchip/mec/mec15xx/soc.h b/soc/microchip/mec/mec15xx/soc.h index f13a5d5291653..21a349620edd8 100644 --- a/soc/microchip/mec/mec15xx/soc.h +++ b/soc/microchip/mec/mec15xx/soc.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __MEC_SOC_H -#define __MEC_SOC_H +#ifndef __SOC_MICROCHIP_MEC_MEC15XX_SOC_H +#define __SOC_MICROCHIP_MEC_MEC15XX_SOC_H #define SYSCLK_DEFAULT_IOSC_HZ MHZ(48) @@ -15,16 +15,18 @@ #include "regaccess.h" /* common SoC API */ -#include "../common/soc_dt.h" -#include "../common/soc_gpio.h" -#include "../common/soc_pcr.h" -#include "../common/soc_pins.h" -#include "../common/soc_espi_channels.h" -#include "soc_espi_saf_v1.h" +#include +#include +#include +#include +#include +#include +#include /* common peripheral register defines */ -#include "../common/reg/mec_gpio.h" +#include -#endif +#include "soc_espi_saf_v1.h" #endif +#endif diff --git a/soc/microchip/mec/mec172x/soc.c b/soc/microchip/mec/mec172x/soc.c index 6b000f957b0c8..7960025622f83 100644 --- a/soc/microchip/mec/mec172x/soc.c +++ b/soc/microchip/mec/mec172x/soc.c @@ -40,6 +40,6 @@ static void configure_debug_interface(void) void soc_early_init_hook(void) { - configure_debug_interface(); + soc_ecia_init(MCHP_MEC_ECIA_GIRQ_AGGR_ONLY_BM, MCHP_MEC_ECIA_GIRQ_DIRECT_CAP_BM, 0); } diff --git a/soc/microchip/mec/mec172x/soc.h b/soc/microchip/mec/mec172x/soc.h index 19afc4e920a96..a48ef2bda52b0 100644 --- a/soc/microchip/mec/mec172x/soc.h +++ b/soc/microchip/mec/mec172x/soc.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __MEC_SOC_H -#define __MEC_SOC_H +#ifndef __SOC_MICROCHIP_MEC_MEC172X_SOC_H +#define __SOC_MICROCHIP_MEC_MEC172X_SOC_H #ifndef _ASMLANGUAGE @@ -246,7 +246,7 @@ typedef enum { #include -/* chip specific register defines */ +/* local chip specific register defines */ #include "reg/mec172x_defs.h" #include "reg/mec172x_ecia.h" #include "reg/mec172x_ecs.h" @@ -262,33 +262,34 @@ typedef enum { #include "reg/mec172x_emi.h" /* common peripheral register defines */ -#include "../common/reg/mec_acpi_ec.h" -#include "../common/reg/mec_adc.h" -#include "../common/reg/mec_global_cfg.h" -#include "../common/reg/mec_kbc.h" -#include "../common/reg/mec_keyscan.h" -#include "../common/reg/mec_peci.h" -#include "../common/reg/mec_ps2.h" -#include "../common/reg/mec_pwm.h" -#include "../common/reg/mec_tach.h" -#include "../common/reg/mec_tfdp.h" -#include "../common/reg/mec_timers.h" -#include "../common/reg/mec_uart.h" -#include "../common/reg/mec_vci.h" -#include "../common/reg/mec_wdt.h" -#include "../common/reg/mec_gpio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* common SoC API */ -#include "../common/soc_dt.h" -#include "../common/soc_gpio.h" -#include "../common/soc_pcr.h" -#include "../common/soc_pins.h" -#include "../common/soc_espi_channels.h" -#include "../common/soc_i2c.h" +#include +#include +#include +#include +#include +#include +#include +#include /* MEC172x SAF V2 */ #include "soc_espi_saf_v2.h" #endif - #endif diff --git a/soc/microchip/mec/mec174x/soc.h b/soc/microchip/mec/mec174x/soc.h index b0a2a46eef83a..2d24e6ed263a6 100644 --- a/soc/microchip/mec/mec174x/soc.h +++ b/soc/microchip/mec/mec174x/soc.h @@ -4,22 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __MEC5_SOC_H -#define __MEC5_SOC_H +#ifndef __SOC_MICROCHIP_MEC_MEC174X_SOC_H +#define __SOC_MICROCHIP_MEC_MEC174X_SOC_H #define SYSCLK_DEFAULT_IOSC_HZ MHZ(96) #ifndef _ASMLANGUAGE -#include "device_mec5.h" +#include /* common SoC API */ -#include "soc_dt.h" -#include "soc_espi_channels.h" -#include "soc_gpio.h" -#include "soc_pcr.h" -#include "soc_pins.h" +#include +#include +#include +#include +#include +#include +#include #endif - #endif diff --git a/soc/microchip/mec/mec175x/soc.h b/soc/microchip/mec/mec175x/soc.h index b0a2a46eef83a..9b03fc925e6e0 100644 --- a/soc/microchip/mec/mec175x/soc.h +++ b/soc/microchip/mec/mec175x/soc.h @@ -4,22 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __MEC5_SOC_H -#define __MEC5_SOC_H +#ifndef __SOC_MICROCHIP_MEC_MEC175X_SOC_H +#define __SOC_MICROCHIP_MEC_MEC175X_SOC_H #define SYSCLK_DEFAULT_IOSC_HZ MHZ(96) #ifndef _ASMLANGUAGE -#include "device_mec5.h" +#include /* common SoC API */ -#include "soc_dt.h" -#include "soc_espi_channels.h" -#include "soc_gpio.h" -#include "soc_pcr.h" -#include "soc_pins.h" +#include +#include +#include +#include +#include +#include +#include #endif - #endif diff --git a/soc/microchip/mec/mech172x/soc.h b/soc/microchip/mec/mech172x/soc.h index b0a2a46eef83a..9c482be784a7a 100644 --- a/soc/microchip/mec/mech172x/soc.h +++ b/soc/microchip/mec/mech172x/soc.h @@ -4,22 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __MEC5_SOC_H -#define __MEC5_SOC_H +#ifndef __SOC_MICROCHIP_MEC_MECH172X_SOC_H +#define __SOC_MICROCHIP_MEC_MECH172X_SOC_H #define SYSCLK_DEFAULT_IOSC_HZ MHZ(96) #ifndef _ASMLANGUAGE -#include "device_mec5.h" +#include /* common SoC API */ -#include "soc_dt.h" -#include "soc_espi_channels.h" -#include "soc_gpio.h" -#include "soc_pcr.h" -#include "soc_pins.h" +#include +#include +#include +#include +#include +#include +#include #endif - #endif diff --git a/soc/microchip/pic32c/pic32cz_ca/CMakeLists.txt b/soc/microchip/pic32c/pic32cz_ca/CMakeLists.txt new file mode 100644 index 0000000000000..e01d600d17e54 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${SOC_SERIES}) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/microchip/pic32c/pic32cz_ca/Kconfig b/soc/microchip/pic32c/pic32cz_ca/Kconfig new file mode 100644 index 0000000000000..a295acedd0be2 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_PIC32CZ_CA + select ARM + select MICROCHIP_PIC32C + select CPU_CORTEX_M7 + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU_DOUBLE_PRECISION + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select INIT_ARCH_HW_AT_BOOT + select HAS_SWO + select XIP + select HAS_POWEROFF diff --git a/soc/microchip/pic32c/pic32cz_ca/Kconfig.defconfig b/soc/microchip/pic32c/pic32cz_ca/Kconfig.defconfig new file mode 100644 index 0000000000000..b2ba9a7d3e1ec --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MICROCHIP_PIC32CZ_CA + +config NUM_IRQS + default 240 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +endif # SOC_FAMILY_MICROCHIP_PIC32CZ_CA diff --git a/soc/microchip/pic32c/pic32cz_ca/Kconfig.soc b/soc/microchip/pic32c/pic32cz_ca/Kconfig.soc new file mode 100644 index 0000000000000..945639b777ec5 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_PIC32CZ_CA + bool + +config SOC_FAMILY + default "microchip_pic32cz_ca" if SOC_FAMILY_MICROCHIP_PIC32CZ_CA + +rsource "*/Kconfig.soc" diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/Kconfig.soc b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/Kconfig.soc new file mode 100644 index 0000000000000..51de482bf882c --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/Kconfig.soc @@ -0,0 +1,73 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CZ_CA80 + bool + select SOC_FAMILY_MICROCHIP_PIC32CZ_CA + help + Enable support for Microchip PIC32CZ CA80 Cortex-M7 microcontrollers. + +config SOC_SERIES + default "pic32cz_ca80" if SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ2051CA80100 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ2051CA80144 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ2051CA80176 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ2051CA80208 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ4010CA80100 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ4010CA80144 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ4010CA80176 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ4010CA80208 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ8110CA80100 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ8110CA80144 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ8110CA80176 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC_PIC32CZ8110CA80208 + bool + select SOC_SERIES_PIC32CZ_CA80 + +config SOC + default "pic32cz2051ca80100" if SOC_PIC32CZ2051CA80100 + default "pic32cz2051ca80144" if SOC_PIC32CZ2051CA80144 + default "pic32cz2051ca80176" if SOC_PIC32CZ2051CA80176 + default "pic32cz2051ca80208" if SOC_PIC32CZ2051CA80208 + default "pic32cz4010ca80100" if SOC_PIC32CZ4010CA80100 + default "pic32cz4010ca80144" if SOC_PIC32CZ4010CA80144 + default "pic32cz4010ca80176" if SOC_PIC32CZ4010CA80176 + default "pic32cz4010ca80208" if SOC_PIC32CZ4010CA80208 + default "pic32cz8110ca80100" if SOC_PIC32CZ8110CA80100 + default "pic32cz8110ca80144" if SOC_PIC32CZ8110CA80144 + default "pic32cz8110ca80176" if SOC_PIC32CZ8110CA80176 + default "pic32cz8110ca80208" if SOC_PIC32CZ8110CA80208 diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/soc.h b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/soc.h new file mode 100644 index 0000000000000..6b35483c83037 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca80/soc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_MICROCHIP_PIC32CZ_CA80_SOC_H_ +#define SOC_MICROCHIP_PIC32CZ_CA80_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#if defined(CONFIG_SOC_PIC32CZ2051CA80100) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA80144) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA80176) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA80208) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA80100) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA80144) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA80176) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA80208) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA80100) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA80144) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA80176) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA80208) +#include +#else +#error "Library does not support the specified device." +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* SOC_MICROCHIP_PIC32CZ_CA80_SOC_H_ */ diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/Kconfig.soc b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/Kconfig.soc new file mode 100644 index 0000000000000..13caeaf7f75a4 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/Kconfig.soc @@ -0,0 +1,73 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CZ_CA90 + bool + select SOC_FAMILY_MICROCHIP_PIC32CZ_CA + help + Enable support for Microchip PIC32CZ CA90 Cortex-M7 microcontrollers. + +config SOC_SERIES + default "pic32cz_ca90" if SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ2051CA90100 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ2051CA90144 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ2051CA90176 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ2051CA90208 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ4010CA90100 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ4010CA90144 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ4010CA90176 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ4010CA90208 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ8110CA90100 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ8110CA90144 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ8110CA90176 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC_PIC32CZ8110CA90208 + bool + select SOC_SERIES_PIC32CZ_CA90 + +config SOC + default "pic32cz2051ca90100" if SOC_PIC32CZ2051CA90100 + default "pic32cz2051ca90144" if SOC_PIC32CZ2051CA90144 + default "pic32cz2051ca90176" if SOC_PIC32CZ2051CA90176 + default "pic32cz2051ca90208" if SOC_PIC32CZ2051CA90208 + default "pic32cz4010ca90100" if SOC_PIC32CZ4010CA90100 + default "pic32cz4010ca90144" if SOC_PIC32CZ4010CA90144 + default "pic32cz4010ca90176" if SOC_PIC32CZ4010CA90176 + default "pic32cz4010ca90208" if SOC_PIC32CZ4010CA90208 + default "pic32cz8110ca90100" if SOC_PIC32CZ8110CA90100 + default "pic32cz8110ca90144" if SOC_PIC32CZ8110CA90144 + default "pic32cz8110ca90176" if SOC_PIC32CZ8110CA90176 + default "pic32cz8110ca90208" if SOC_PIC32CZ8110CA90208 diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/soc.h b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/soc.h new file mode 100644 index 0000000000000..1db0748b46794 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca90/soc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_MICROCHIP_PIC32CZ_CA90_SOC_H_ +#define SOC_MICROCHIP_PIC32CZ_CA90_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#if defined(CONFIG_SOC_PIC32CZ2051CA90100) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA90144) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA90176) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA90208) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA90100) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA90144) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA90176) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA90208) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA90100) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA90144) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA90176) +#include +#elif defined(CONFIG_SOC_PIC32CZ8110CA90208) +#include +#else +#error "Library does not support the specified device." +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* SOC_MICROCHIP_PIC32CZ_CA90_SOC_H_ */ diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/Kconfig.soc b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/Kconfig.soc new file mode 100644 index 0000000000000..d6a59d595e372 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/Kconfig.soc @@ -0,0 +1,48 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CZ_CA91 + bool + select SOC_FAMILY_MICROCHIP_PIC32CZ_CA + help + Enable support for Microchip PIC32CZ CA91 Cortex-M7 microcontrollers. + +config SOC_SERIES + default "pic32cz_ca91" if SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ2051CA91100 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ2051CA91144 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ2051CA91176 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ4010CA91100 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ4010CA91144 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ4010CA91176 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC_PIC32CZ4010CA91208 + bool + select SOC_SERIES_PIC32CZ_CA91 + +config SOC + default "pic32cz2051ca91100" if SOC_PIC32CZ2051CA91100 + default "pic32cz2051ca91144" if SOC_PIC32CZ2051CA91144 + default "pic32cz2051ca91176" if SOC_PIC32CZ2051CA91176 + default "pic32cz4010ca91100" if SOC_PIC32CZ4010CA91100 + default "pic32cz4010ca91144" if SOC_PIC32CZ4010CA91144 + default "pic32cz4010ca91176" if SOC_PIC32CZ4010CA91176 + default "pic32cz4010ca91208" if SOC_PIC32CZ4010CA91208 diff --git a/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/soc.h b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/soc.h new file mode 100644 index 0000000000000..f5e9829da6d1d --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/pic32cz_ca91/soc.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_MICROCHIP_PIC32CZ_CA91_SOC_H_ +#define SOC_MICROCHIP_PIC32CZ_CA91_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#if defined(CONFIG_SOC_PIC32CZ2051CA91100) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA91144) +#include +#elif defined(CONFIG_SOC_PIC32CZ2051CA91176) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA91100) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA91144) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA91176) +#include +#elif defined(CONFIG_SOC_PIC32CZ4010CA91208) +#include +#else +#error "Library does not support the specified device." +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* SOC_MICROCHIP_PIC32CZ_CA91_SOC_H_ */ diff --git a/soc/microchip/pic32c/pic32cz_ca/soc.yml b/soc/microchip/pic32c/pic32cz_ca/soc.yml new file mode 100644 index 0000000000000..f3b620c660b54 --- /dev/null +++ b/soc/microchip/pic32c/pic32cz_ca/soc.yml @@ -0,0 +1,43 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +family: +- name: microchip_pic32cz_ca + series: + - name: pic32cz_ca80 + socs: + - name: pic32cz2051ca80100 + - name: pic32cz2051ca80144 + - name: pic32cz2051ca80176 + - name: pic32cz2051ca80208 + - name: pic32cz4010ca80100 + - name: pic32cz4010ca80144 + - name: pic32cz4010ca80176 + - name: pic32cz4010ca80208 + - name: pic32cz8110ca80100 + - name: pic32cz8110ca80144 + - name: pic32cz8110ca80176 + - name: pic32cz8110ca80208 + - name: pic32cz_ca90 + socs: + - name: pic32cz2051ca90100 + - name: pic32cz2051ca90144 + - name: pic32cz2051ca90176 + - name: pic32cz2051ca90208 + - name: pic32cz4010ca90100 + - name: pic32cz4010ca90144 + - name: pic32cz4010ca90176 + - name: pic32cz4010ca90208 + - name: pic32cz8110ca90100 + - name: pic32cz8110ca90144 + - name: pic32cz8110ca90176 + - name: pic32cz8110ca90208 + - name: pic32cz_ca91 + socs: + - name: pic32cz2051ca91100 + - name: pic32cz2051ca91144 + - name: pic32cz2051ca91176 + - name: pic32cz4010ca91100 + - name: pic32cz4010ca91144 + - name: pic32cz4010ca91176 + - name: pic32cz4010ca91208 diff --git a/soc/microchip/sam/common/CMakeLists.txt b/soc/microchip/sam/common/CMakeLists.txt index bbb4727fdf383..50d11f5d75504 100644 --- a/soc/microchip/sam/common/CMakeLists.txt +++ b/soc/microchip/sam/common/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_sources(clk-peripheral.c) zephyr_sources(clk-programmable.c) zephyr_sources(clk-sam9x60-pll.c) zephyr_sources(clk-system.c) -zephyr_sources(clk-utmi.c) +zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMA7G5 clk-utmi.c) zephyr_sources(pmc.c) +zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMA7D6 sama7d65.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMA7G5 sama7g5.c) diff --git a/soc/microchip/sam/common/clk-generated.c b/soc/microchip/sam/common/clk-generated.c index e8452cc6bd6e4..4c6c5ae201046 100644 --- a/soc/microchip/sam/common/clk-generated.c +++ b/soc/microchip/sam/common/clk-generated.c @@ -29,7 +29,7 @@ struct clk_generated { #define to_clk_generated(ptr) CONTAINER_OF(ptr, struct clk_generated, clk) -static struct clk_generated clocks_gck[ID_PERIPH_MAX]; +static struct clk_generated clocks_gck[SOC_NUM_CLOCK_GENERATED]; static uint32_t clocks_gck_idx; static int clk_generated_on(const struct device *dev, clock_control_subsys_t sys) diff --git a/soc/microchip/sam/common/clk-master.c b/soc/microchip/sam/common/clk-master.c index f721ea466a03b..a56099a4e97eb 100644 --- a/soc/microchip/sam/common/clk-master.c +++ b/soc/microchip/sam/common/clk-master.c @@ -19,7 +19,7 @@ LOG_MODULE_REGISTER(clk_mck, CONFIG_CLOCK_CONTROL_LOG_LEVEL); #define PMC_MCR_CSS_SHIFT 16 -#define MASTER_MAX_ID 4 +#define MASTER_MAX_ID (SOC_NUM_CLOCK_MASTER - 1) #define to_clk_master(ptr) CONTAINER_OF(ptr, struct clk_master, clk) @@ -38,7 +38,7 @@ struct clk_master { uint8_t div; }; -static struct clk_master clocks_master[5]; +static struct clk_master clocks_master[SOC_NUM_CLOCK_MASTER]; static uint32_t clocks_master_idx; static inline bool clk_master_ready(struct clk_master *master) diff --git a/soc/microchip/sam/common/clk-peripheral.c b/soc/microchip/sam/common/clk-peripheral.c index 2fdc1117d340f..094c37d613c69 100644 --- a/soc/microchip/sam/common/clk-peripheral.c +++ b/soc/microchip/sam/common/clk-peripheral.c @@ -25,7 +25,7 @@ struct clk_peripheral { const struct clk_pcr_layout *layout; }; -static struct clk_peripheral clocks_periph[72]; +static struct clk_peripheral clocks_periph[SOC_NUM_CLOCK_PERIPHERAL]; static uint32_t clocks_periph_idx; #define to_clk_peripheral(ptr) CONTAINER_OF(ptr, struct clk_peripheral, clk) diff --git a/soc/microchip/sam/common/clk-programmable.c b/soc/microchip/sam/common/clk-programmable.c index fb17512c2e1a6..bbac3badb4c0a 100644 --- a/soc/microchip/sam/common/clk-programmable.c +++ b/soc/microchip/sam/common/clk-programmable.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -25,6 +26,7 @@ struct clk_programmable { uint8_t num_parents; uint8_t parent; const struct clk_programmable_layout *layout; + char name[8]; }; #define to_clk_programmable(ptr) CONTAINER_OF(ptr, struct clk_programmable, clk) @@ -79,7 +81,7 @@ static DEVICE_API(clock_control, programmable_api) = { .get_rate = clk_programmable_get_rate, }; -int clk_register_programmable(pmc_registers_t *const pmc, const char *name, +int clk_register_programmable(pmc_registers_t *const pmc, const struct device **parents, uint8_t num_parents, uint8_t id, const struct clk_programmable_layout *layout, @@ -102,9 +104,10 @@ int clk_register_programmable(pmc_registers_t *const pmc, const char *name, } memcpy(prog->parents, parents, sizeof(struct device *) * num_parents); + snprintf(prog->name, sizeof(prog->name), "prog%d", id); *clk = &prog->clk; - (*clk)->name = name; + (*clk)->name = prog->name; (*clk)->api = &programmable_api; prog->num_parents = num_parents; prog->id = id; diff --git a/soc/microchip/sam/common/clk-sam9x60-pll.c b/soc/microchip/sam/common/clk-sam9x60-pll.c index 0a3a00d50a792..bd3d65d100200 100644 --- a/soc/microchip/sam/common/clk-sam9x60-pll.c +++ b/soc/microchip/sam/common/clk-sam9x60-pll.c @@ -46,7 +46,7 @@ LOG_MODULE_REGISTER(clk_pll, CONFIG_CLOCK_CONTROL_LOG_LEVEL); q * n_ + r * n_ / d_; \ }) -#define PLL_MAX_ID 7 +#define PLL_MAX_ID SOC_NUM_CLOCK_PLL_FRAC struct sam9x60_pll_core { pmc_registers_t *pmc; @@ -73,10 +73,10 @@ struct sam9x60_div { #define to_sam9x60_frac(ptr) CONTAINER_OF(ptr, struct sam9x60_frac, core) #define to_sam9x60_div(ptr) CONTAINER_OF(ptr, struct sam9x60_div, core) -static struct sam9x60_frac clocks_frac[7]; +static struct sam9x60_frac clocks_frac[SOC_NUM_CLOCK_PLL_FRAC]; static uint32_t clocks_frac_idx; -static struct sam9x60_div clocks_div[8]; +static struct sam9x60_div clocks_div[SOC_NUM_CLOCK_PLL_DIV]; static uint32_t clocks_div_idx; static inline bool sam9x60_pll_ready(pmc_registers_t *pmc, int id) diff --git a/soc/microchip/sam/common/clk-system.c b/soc/microchip/sam/common/clk-system.c index 453408a31935c..d300a8ce66a7d 100644 --- a/soc/microchip/sam/common/clk-system.c +++ b/soc/microchip/sam/common/clk-system.c @@ -25,7 +25,7 @@ struct clk_system { uint8_t id; }; -static struct clk_system clocks_sys[8]; +static struct clk_system clocks_sys[SOC_NUM_CLOCK_SYSTEM]; static uint32_t clocks_sys_idx; static inline int is_pck(int id) diff --git a/soc/microchip/sam/common/pmc.h b/soc/microchip/sam/common/pmc.h index a46238f509ed1..72112c5185d30 100644 --- a/soc/microchip/sam/common/pmc.h +++ b/soc/microchip/sam/common/pmc.h @@ -68,6 +68,7 @@ struct clk_pll_characteristics { uint16_t *icpll; uint8_t *out; uint8_t upll : 1; + uint32_t acr; }; struct clk_programmable_layout { @@ -168,7 +169,7 @@ int sam9x60_clk_register_frac_pll(pmc_registers_t *const pmc, struct k_spinlock const struct clk_pll_characteristics *characteristics, const struct clk_pll_layout *layout, struct device **clk); -int clk_register_programmable(pmc_registers_t *const pmc, const char *name, +int clk_register_programmable(pmc_registers_t *const pmc, const struct device **parents, uint8_t num_parents, uint8_t id, const struct clk_programmable_layout *layout, diff --git a/soc/microchip/sam/common/sama7d65.c b/soc/microchip/sam/common/sama7d65.c new file mode 100644 index 0000000000000..094f836752958 --- /dev/null +++ b/soc/microchip/sam/common/sama7d65.c @@ -0,0 +1,1382 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(pmc_setup, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1) + +#define SAMA7D65_INIT_TABLE(_table, _count) \ + do { \ + uint8_t _i; \ + for (_i = 0; _i < (_count); _i++) { \ + (_table)[_i] = _i; \ + } \ + } while (0) + +#define SAMA7D65_FILL_TABLE(_to, _from, _count) \ + do { \ + uint8_t _i; \ + for (_i = 0; _i < (_count); _i++) { \ + (_to)[_i] = (_from)[_i]; \ + } \ + } while (0) + +static struct k_spinlock pmc_pll_lock; +static struct k_spinlock pmc_mck0_lock; +static struct k_spinlock pmc_mckX_lock; +static struct k_spinlock pmc_pcr_lock; + +/* + * PLL clocks identifiers + * @PLL_ID_CPU: CPU PLL identifier + * @PLL_ID_SYS: System PLL identifier + * @PLL_ID_DDR: DDR PLL identifier + * @PLL_ID_IMG: Image subsystem PLL identifier + * @PLL_ID_BAUD: Baud PLL identifier + * @PLL_ID_AUDIO: Audio PLL identifier + * @PLL_ID_ETH: Ethernet PLL identifier + * @PLL_ID_LVDS: LVDS PLL identifier + * @PLL_ID_USB: USB PLL identifier + */ +enum pll_ids { + PLL_ID_CPU, + PLL_ID_SYS, + PLL_ID_DDR, + PLL_ID_GPU, + PLL_ID_BAUD, + PLL_ID_AUDIO, + PLL_ID_ETH, + PLL_ID_LVDS, + PLL_ID_USB, + PLL_ID_MAX, +}; + +/* + * PLL component identifier + * @PLL_COMPID_FRAC: Fractional PLL component identifier + * @PLL_COMPID_DIV0: 1st PLL divider component identifier + * @PLL_COMPID_DIV1: 2nd PLL divider component identifier + */ +enum pll_component_id { + PLL_COMPID_FRAC, + PLL_COMPID_DIV0, + PLL_COMPID_DIV1, +}; + +/* + * PLL type identifiers + * @PLL_TYPE_FRAC: fractional PLL identifier + * @PLL_TYPE_DIV: divider PLL identifier + */ +enum pll_type { + PLL_TYPE_FRAC, + PLL_TYPE_DIV, +}; + +/* Layout for fractional PLLs. */ +static const struct clk_pll_layout pll_layout_frac = { + .mul_mask = GENMASK(31, 24), + .frac_mask = GENMASK(21, 0), + .mul_shift = 24, + .frac_shift = 0, +}; + +/* Layout for DIVPMC dividers. */ +static const struct clk_pll_layout pll_layout_divpmc = { + .div_mask = GENMASK(7, 0), + .endiv_mask = BIT(29), + .div_shift = 0, + .endiv_shift = 29, +}; + +/* Layout for DIVIO dividers. */ +static const struct clk_pll_layout pll_layout_divio = { + .div_mask = GENMASK(19, 12), + .endiv_mask = BIT(30), + .div_shift = 12, + .endiv_shift = 30, +}; + +/* + * CPU PLL output range. + * Notice: The upper limit has been setup to 1000000002 due to hardware + * block which cannot output exactly 1GHz. + */ +static const struct clk_range cpu_pll_outputs[] = { + { .min = 2343750, .max = 1000000002 }, +}; + +/* PLL output range. */ +static const struct clk_range pll_outputs[] = { + { .min = 2343750, .max = 1200000000 }, +}; + +/* + * Min: fCOREPLLCK = 600 MHz, PMC_PLL_CTRL0.DIVPMC = 255 + * Max: fCOREPLLCK = 800 MHz, PMC_PLL_CTRL0.DIVPMC = 0 + */ +static const struct clk_range lvdspll_outputs[] = { + { .min = 16406250, .max = 800000000 }, +}; + +static const struct clk_range upll_outputs[] = { + { .min = 480000000, .max = 480000000 }, +}; + +/* Fractional PLL core output range. */ +static const struct clk_range core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +static const struct clk_range lvdspll_core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +static const struct clk_range upll_core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +/* CPU PLL characteristics. */ +static const struct clk_pll_characteristics cpu_pll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(cpu_pll_outputs), + .output = cpu_pll_outputs, + .core_output = core_outputs, + .acr = 0x00070010, +}; + +/* PLL characteristics. */ +static const struct clk_pll_characteristics pll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(pll_outputs), + .output = pll_outputs, + .core_output = core_outputs, + .acr = 0x00070010, +}; + +static const struct clk_pll_characteristics lvdspll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(lvdspll_outputs), + .output = lvdspll_outputs, + .core_output = lvdspll_core_outputs, + .acr = 0x00070010, +}; + +static const struct clk_pll_characteristics upll_characteristics = { + .input = { .min = 20000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(upll_outputs), + .output = upll_outputs, + .core_output = upll_core_outputs, + .acr = 0x12020010, + .upll = true, +}; + +/* + * SAMA7D65 PLL possible parents + * @SAMA7D65_PLL_PARENT_MAINCK: MAINCK is PLL a parent + * @SAMA7D65_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent + * @SAMA7D65_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers) + */ +enum sama7d65_pll_parent { + SAMA7D65_PLL_PARENT_MAINCK, + SAMA7D65_PLL_PARENT_MAIN_XTAL, + SAMA7D65_PLL_PARENT_FRACCK, +}; + +/* + * PLL clocks description + * @n: clock name + * @p: clock parent + * @l: clock layout + * @c: clock characteristics + * @hw: pointer to clk_hw + * @t: clock type + * @f: clock flags + * @p: clock parent + * @eid: export index in sama7d65->chws[] array + * @safe_div: intermediate divider need to be set on PRE_RATE_CHANGE + * notification + */ +static struct sama7d65_pll { + const char *n; + const struct clk_pll_layout *l; + const struct clk_pll_characteristics *c; + struct device *clk; + unsigned long f; + enum sama7d65_pll_parent p; + uint8_t t; + uint8_t eid; + uint8_t safe_div; +} sama7d65_plls[][PLL_ID_MAX] = { + [PLL_ID_CPU] = { + [PLL_COMPID_FRAC] = { + .n = "cpupll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &cpu_pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "cpupll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &cpu_pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_CPUPLL, + /* + * Safe div=15 should be safe even for switching b/w 1GHz and + * 90MHz (frac pll might go up to 1.2GHz). + */ + .safe_div = 15, + }, + }, + + [PLL_ID_SYS] = { + [PLL_COMPID_FRAC] = { + .n = "syspll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "syspll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_SYSPLL, + }, + }, + + [PLL_ID_DDR] = { + [PLL_COMPID_FRAC] = { + .n = "ddrpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "ddrpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + }, + }, + + [PLL_ID_GPU] = { + [PLL_COMPID_FRAC] = { + .n = "gpupll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "gpupll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + }, + }, + + [PLL_ID_BAUD] = { + [PLL_COMPID_FRAC] = { + .n = "baudpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "baudpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_BAUDPLL, + }, + }, + + [PLL_ID_AUDIO] = { + [PLL_COMPID_FRAC] = { + .n = "audiopll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "audiopll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_AUDIOPMCPLL, + }, + + [PLL_COMPID_DIV1] = { + .n = "audiopll_diviock", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divio, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_AUDIOIOPLL, + }, + }, + + [PLL_ID_ETH] = { + [PLL_COMPID_FRAC] = { + .n = "ethpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "ethpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_ETHPLL, + }, + }, + + [PLL_ID_LVDS] = { + [PLL_COMPID_FRAC] = { + .n = "lvdspll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &lvdspll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "lvdspll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &lvdspll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_LVDSPLL, + }, + }, + + [PLL_ID_USB] = { + [PLL_COMPID_FRAC] = { + .n = "usbpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &upll_characteristics, + .t = PLL_TYPE_FRAC, + }, + + [PLL_COMPID_DIV0] = { + .n = "usbpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &upll_characteristics, + .t = PLL_TYPE_DIV, + .eid = PMC_UTMI, + }, + }, +}; + +/* Used to create an array entry identifying a PLL by its components. */ +#define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp} + +/* + * Master clock (MCK[1..4]) description + * @n: clock name + * @ep_chg_chg_id: index in parents array that specifies the changeable + * @ep: extra parents names array (entry formed by PLL components + * identifiers (see enum pll_component_id)) + * @hw: pointer to clk_hw + * parent + * @ep_count: extra parents count + * @ep_mux_table: mux table for extra parents + * @id: clock id + * @eid: export index in sama7d65->chws[] array + * @c: true if clock is critical and cannot be disabled + */ +static struct { + const char *n; + struct { + int pll_id; + int pll_compid; + } ep[4]; + struct device *clk; + int ep_chg_id; + uint8_t ep_count; + uint8_t ep_mux_table[4]; + uint8_t id; + uint8_t eid; + uint8_t c; +} sama7d65_mckx[] = { + { .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */ + { .n = "mck1", + .id = 1, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK1, + .c = 1, }, + + { .n = "mck2", + .id = 2, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), }, + .ep_mux_table = { 5, 6, }, + .ep_count = 2, + .ep_chg_id = INT_MIN, + .c = 1, }, + + { .n = "mck3", + .id = 3, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), }, + .ep_mux_table = { 5, 6, }, + .ep_count = 2, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK3, + .c = 1, }, + + { .n = "mck4", + .id = 4, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .c = 1,}, + + { .n = "mck5", + .id = 5, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK5, + .c = 1,}, + + { .n = "mck6", + .id = 6, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, + .c = 1,}, + + { .n = "mck7", + .id = 7, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1,}, + + { .n = "mck8", + .id = 8, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1,}, + + { .n = "mck9", + .id = 9, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, }, +}; + +/* + * System clock description + * @n: clock name + * @p: clock parent name + * @id: clock id + */ +static const struct { + const char *n; + const char *p; + uint8_t id; +} sama7d65_systemck[] = { + { .n = "pck0", .p = "prog0", .id = 8, }, + { .n = "pck1", .p = "prog1", .id = 9, }, + { .n = "pck2", .p = "prog2", .id = 10, }, + { .n = "pck3", .p = "prog3", .id = 11, }, + { .n = "pck4", .p = "prog4", .id = 12, }, + { .n = "pck5", .p = "prog5", .id = 13, }, + { .n = "pck6", .p = "prog6", .id = 14, }, + { .n = "pck7", .p = "prog7", .id = 15, }, +}; + +/* Mux table for programmable clocks. */ +static uint32_t sama7d65_prog_mux_table[] = { 0, 1, 2, 5, 7, 8, 9, 10, 12,}; + +/* + * Peripheral clock parent hw identifier (used to index in sama7d65_mckx[]) + * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0 + * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1 + * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2 + * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3 + * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4 + * @PCK_PARENT_HW_MCK5: pck parent hw identifier is MCK5 + * @PCK_PARENT_HW_MCK6: pck parent hw identifier is MCK6 + * @PCK_PARENT_HW_MCK7: pck parent hw identifier is MCK7 + * @PCK_PARENT_HW_MCK8: pck parent hw identifier is MCK8 + * @PCK_PARENT_HW_MCK9: pck parent hw identifier is MCK9 + * @PCK_PARENT_HW_MAX: max identifier + */ +enum sama7d65_pck_parent_hw_id { + PCK_PARENT_HW_MCK0, + PCK_PARENT_HW_MCK1, + PCK_PARENT_HW_MCK2, + PCK_PARENT_HW_MCK3, + PCK_PARENT_HW_MCK4, + PCK_PARENT_HW_MCK5, + PCK_PARENT_HW_MCK6, + PCK_PARENT_HW_MCK7, + PCK_PARENT_HW_MCK8, + PCK_PARENT_HW_MCK9, + PCK_PARENT_HW_MAX, +}; + +/* + * Peripheral clock description + * @n: clock name + * @p: clock parent hw id + * @r: clock range values + * @id: clock id + * @chgp: index in parent array of the changeable parent + */ +static struct { + const char *n; + enum sama7d65_pck_parent_hw_id p; + struct clk_range r; + uint8_t chgp; + uint8_t id; +} sama7d65_periphck[] = { + { .n = "pioA_clk", .p = PCK_PARENT_HW_MCK0, .id = 10, }, + { .n = "securam_clk", .p = PCK_PARENT_HW_MCK0, .id = 17, }, + { .n = "sfr_clk", .p = PCK_PARENT_HW_MCK7, .id = 18, }, + { .n = "hsmc_clk", .p = PCK_PARENT_HW_MCK5, .id = 20, }, + { .n = "xdmac0_clk", .p = PCK_PARENT_HW_MCK6, .id = 21, }, + { .n = "xdmac1_clk", .p = PCK_PARENT_HW_MCK6, .id = 22, }, + { .n = "xdmac2_clk", .p = PCK_PARENT_HW_MCK1, .id = 23, }, + { .n = "acc_clk", .p = PCK_PARENT_HW_MCK7, .id = 24, }, + { .n = "aes_clk", .p = PCK_PARENT_HW_MCK6, .id = 26, }, + { .n = "tzaesbasc_clk", .p = PCK_PARENT_HW_MCK8, .id = 27, }, + { .n = "asrc_clk", .p = PCK_PARENT_HW_MCK9, .id = 29, .r = { .max = 200000000, }, }, + { .n = "cpkcc_clk", .p = PCK_PARENT_HW_MCK0, .id = 30, }, + { .n = "eic_clk", .p = PCK_PARENT_HW_MCK7, .id = 33, }, + { .n = "flex0_clk", .p = PCK_PARENT_HW_MCK7, .id = 34, }, + { .n = "flex1_clk", .p = PCK_PARENT_HW_MCK7, .id = 35, }, + { .n = "flex2_clk", .p = PCK_PARENT_HW_MCK7, .id = 36, }, + { .n = "flex3_clk", .p = PCK_PARENT_HW_MCK7, .id = 37, }, + { .n = "flex4_clk", .p = PCK_PARENT_HW_MCK8, .id = 38, }, + { .n = "flex5_clk", .p = PCK_PARENT_HW_MCK8, .id = 39, }, + { .n = "flex6_clk", .p = PCK_PARENT_HW_MCK8, .id = 40, }, + { .n = "flex7_clk", .p = PCK_PARENT_HW_MCK8, .id = 41, }, + { .n = "flex8_clk", .p = PCK_PARENT_HW_MCK9, .id = 42, }, + { .n = "flex9_clk", .p = PCK_PARENT_HW_MCK9, .id = 43, }, + { .n = "flex10_clk", .p = PCK_PARENT_HW_MCK9, .id = 44, }, + { .n = "gmac0_clk", .p = PCK_PARENT_HW_MCK6, .id = 46, }, + { .n = "gmac1_clk", .p = PCK_PARENT_HW_MCK6, .id = 47, }, + { .n = "gmac0_tsu_clk", .p = PCK_PARENT_HW_MCK1, .id = 49, }, + { .n = "gmac1_tsu_clk", .p = PCK_PARENT_HW_MCK1, .id = 50, }, + { .n = "icm_clk", .p = PCK_PARENT_HW_MCK5, .id = 53, }, + { .n = "i2smcc0_clk", .p = PCK_PARENT_HW_MCK9, .id = 54, .r = { .max = 200000000, }, }, + { .n = "i2smcc1_clk", .p = PCK_PARENT_HW_MCK9, .id = 55, .r = { .max = 200000000, }, }, + { .n = "lcd_clk", .p = PCK_PARENT_HW_MCK3, .id = 56, }, + { .n = "matrix_clk", .p = PCK_PARENT_HW_MCK5, .id = 57, }, + { .n = "mcan0_clk", .p = PCK_PARENT_HW_MCK5, .id = 58, .r = { .max = 200000000, }, }, + { .n = "mcan1_clk", .p = PCK_PARENT_HW_MCK5, .id = 59, .r = { .max = 200000000, }, }, + { .n = "mcan2_clk", .p = PCK_PARENT_HW_MCK5, .id = 60, .r = { .max = 200000000, }, }, + { .n = "mcan3_clk", .p = PCK_PARENT_HW_MCK5, .id = 61, .r = { .max = 200000000, }, }, + { .n = "mcan4_clk", .p = PCK_PARENT_HW_MCK5, .id = 62, .r = { .max = 200000000, }, }, + { .n = "pdmc0_clk", .p = PCK_PARENT_HW_MCK9, .id = 64, .r = { .max = 200000000, }, }, + { .n = "pdmc1_clk", .p = PCK_PARENT_HW_MCK9, .id = 65, .r = { .max = 200000000, }, }, + { .n = "pit64b0_clk", .p = PCK_PARENT_HW_MCK7, .id = 66, }, + { .n = "pit64b1_clk", .p = PCK_PARENT_HW_MCK7, .id = 67, }, + { .n = "pit64b2_clk", .p = PCK_PARENT_HW_MCK7, .id = 68, }, + { .n = "pit64b3_clk", .p = PCK_PARENT_HW_MCK8, .id = 69, }, + { .n = "pit64b4_clk", .p = PCK_PARENT_HW_MCK8, .id = 70, }, + { .n = "pit64b5_clk", .p = PCK_PARENT_HW_MCK8, .id = 71, }, + { .n = "pwm_clk", .p = PCK_PARENT_HW_MCK7, .id = 72, }, + { .n = "qspi0_clk", .p = PCK_PARENT_HW_MCK5, .id = 73, }, + { .n = "qspi1_clk", .p = PCK_PARENT_HW_MCK5, .id = 74, }, + { .n = "sdmmc0_clk", .p = PCK_PARENT_HW_MCK1, .id = 75, }, + { .n = "sdmmc1_clk", .p = PCK_PARENT_HW_MCK1, .id = 76, }, + { .n = "sdmmc2_clk", .p = PCK_PARENT_HW_MCK1, .id = 77, }, + { .n = "sha_clk", .p = PCK_PARENT_HW_MCK6, .id = 78, }, + { .n = "spdifrx_clk", .p = PCK_PARENT_HW_MCK9, .id = 79, .r = { .max = 200000000, }, }, + { .n = "spdiftx_clk", .p = PCK_PARENT_HW_MCK9, .id = 80, .r = { .max = 200000000, }, }, + { .n = "ssc0_clk", .p = PCK_PARENT_HW_MCK7, .id = 81, .r = { .max = 200000000, }, }, + { .n = "ssc1_clk", .p = PCK_PARENT_HW_MCK8, .id = 82, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch0_clk", .p = PCK_PARENT_HW_MCK8, .id = 83, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch1_clk", .p = PCK_PARENT_HW_MCK8, .id = 84, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch2_clk", .p = PCK_PARENT_HW_MCK8, .id = 85, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch0_clk", .p = PCK_PARENT_HW_MCK5, .id = 86, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch1_clk", .p = PCK_PARENT_HW_MCK5, .id = 87, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch2_clk", .p = PCK_PARENT_HW_MCK5, .id = 88, .r = { .max = 200000000, }, }, + { .n = "tcpca_clk", .p = PCK_PARENT_HW_MCK5, .id = 89, }, + { .n = "tcpcb_clk", .p = PCK_PARENT_HW_MCK5, .id = 90, }, + { .n = "tdes_clk", .p = PCK_PARENT_HW_MCK6, .id = 91, }, + { .n = "trng_clk", .p = PCK_PARENT_HW_MCK6, .id = 92, }, + { .n = "udphsa_clk", .p = PCK_PARENT_HW_MCK5, .id = 99, }, + { .n = "udphsb_clk", .p = PCK_PARENT_HW_MCK5, .id = 100, }, + { .n = "uhphs_clk", .p = PCK_PARENT_HW_MCK5, .id = 101, }, + { .n = "dsi_clk", .p = PCK_PARENT_HW_MCK3, .id = 103, }, + { .n = "lvdsc_clk", .p = PCK_PARENT_HW_MCK3, .id = 104, }, +}; + +/* + * Generic clock description + * @n: clock name + * @pp: PLL parents (entry formed by PLL components identifiers + * (see enum pll_component_id)) + * @pp_mux_table: PLL parents mux table + * @r: clock output range + * @pp_chg_id: id in parent array of changeable PLL parent + * @pp_count: PLL parents count + * @id: clock id + */ +static const struct { + const char *n; + struct { + int pll_id; + int pll_compid; + } pp[8]; + const char pp_mux_table[8]; + struct clk_range r; + int pp_chg_id; + uint8_t pp_count; + uint8_t id; +} sama7d65_gck[] = { + { .n = "adc_gclk", + .id = 25, + .r = { .max = 100000000, }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 8, 9, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "asrc_gclk", + .id = 29, + .r = { .max = 200000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex0_gclk", + .id = 34, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex1_gclk", + .id = 35, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex2_gclk", + .id = 36, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex3_gclk", + .id = 37, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex4_gclk", + .id = 38, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex5_gclk", + .id = 39, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex6_gclk", + .id = 40, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex7_gclk", + .id = 41, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex8_gclk", + .id = 42, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex9_gclk", + .id = 43, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex10_gclk", + .id = 44, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "gmac0_gclk", + .id = 46, + .r = { .max = 125000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "gmac1_gclk", + .id = 47, + .r = { .max = 125000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "gmac0_tsu_gclk", + .id = 49, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {10, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "gmac1_tsu_gclk", + .id = 50, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "i2smcc0_gclk", + .id = 54, + .r = { .max = 100000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "i2smcc1_gclk", + .id = 55, + .r = { .max = 100000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "lcdc_gclk", + .id = 56, + .r = { .max = 90000000 }, + .pp_count = 0, + .pp_chg_id = INT_MIN, + }, + + { .n = "mcan0_gclk", + .id = 58, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan1_gclk", + .id = 59, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan2_gclk", + .id = 60, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan3_gclk", + .id = 61, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan4_gclk", + .id = 62, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "pdmc0_gclk", + .id = 64, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9 }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "pdmc1_gclk", + .id = 65, + .r = { .max = 80000000, }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b0_gclk", + .id = 66, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b1_gclk", + .id = 67, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b2_gclk", + .id = 68, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b3_gclk", + .id = 69, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b4_gclk", + .id = 70, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b5_gclk", + .id = 71, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "qspi0_gclk", + .id = 73, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "qspi1_gclk", + .id = 74, + .r = { .max = 266000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "sdmmc0_gclk", + .id = 75, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10, }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "sdmmc1_gclk", + .id = 76, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10, }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "sdmmc2_gclk", + .id = 77, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10 }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "spdifrx_gclk", + .id = 79, + .r = { .max = 150000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "spdiftx_gclk", + .id = 80, + .r = { .max = 25000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "tcb0_ch0_gclk", + .id = 83, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "tcb1_ch0_gclk", + .id = 86, + .r = { .max = 67000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "DSI_gclk", + .id = 103, + .r = {.max = 27000000}, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .pp_mux_table = {5}, + .pp_count = 1, + .pp_chg_id = INT_MIN,}, + + { .n = "I3CC_gclk", + .id = 105, + .r = {.max = 125000000}, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN,}, +}; + +/* MCK0 characteristics. */ +static const struct clk_master_characteristics mck0_characteristics = { + .output = {.min = 32768, .max = 200000000}, + .divisors = {1, 2, 4, 3, 5}, + .have_div3_pres = 1, +}; + +/* MCK0 layout. */ +static const struct clk_master_layout mck0_layout = { + .mask = 0x773, + .pres_shift = 4, + .offset = 0x28, +}; + +/* Programmable clock layout. */ +static const struct clk_programmable_layout programmable_layout = { + .pres_mask = 0xff, + .pres_shift = 8, + .css_mask = 0x1f, + .have_slck_mck = 0, + .is_pres_direct = 1, +}; + +/* Peripheral clock layout. */ +static const struct clk_pcr_layout sama7d65_pcr_layout = { + .offset = 0x88, + .cmd = BIT(31), + .gckcss_mask = GENMASK(12, 8), + .pid_mask = GENMASK(6, 0), +}; + +enum clock_count { + CLK_CNT_SYSTEM = 15 + 1, + CLK_CNT_PERIPH = 104 + 1, + CLK_CNT_GCK = 105 + 1, +}; + +static struct device *pmc_table[PMC_MCK5 + 1 + CLK_CNT_SYSTEM + CLK_CNT_PERIPH + CLK_CNT_GCK + + SOC_NUM_CLOCK_PROGRAMMABLE]; + +static int sam_pmc_register_pll(const struct device *dev, struct pmc_data *sama7d65_pmc) +{ + const struct sam_pmc_cfg *cfg = dev->config; + void *const regmap = cfg->reg; + struct device *clk; + int ret, i, j; + + for (i = 0; i < PLL_ID_MAX; i++) { + for (j = 0; j < 3; j++) { + const struct device *parent_hw; + + if (!sama7d65_plls[i][j].n) { + continue; + } + + switch (sama7d65_plls[i][j].t) { + case PLL_TYPE_FRAC: + switch (sama7d65_plls[i][j].p) { + case SAMA7D65_PLL_PARENT_MAINCK: + parent_hw = sama7d65_pmc->chws[PMC_MAIN]; + break; + case SAMA7D65_PLL_PARENT_MAIN_XTAL: + parent_hw = cfg->main_xtal; + break; + default: + /* Should not happen. */ + parent_hw = NULL; + break; + } + + ret = sam9x60_clk_register_frac_pll(regmap, + &pmc_pll_lock, + sama7d65_plls[i][j].n, + parent_hw, i, + sama7d65_plls[i][j].c, + sama7d65_plls[i][j].l, + &clk); + break; + + case PLL_TYPE_DIV: + ret = sam9x60_clk_register_div_pll(regmap, + &pmc_pll_lock, + sama7d65_plls[i][j].n, + sama7d65_plls[i][0].clk, i, + sama7d65_plls[i][j].c, + sama7d65_plls[i][j].l, + &clk); + break; + + default: + continue; + } + + if (ret) { + LOG_ERR("Register clock %s failed.", sama7d65_plls[i][j].n); + return ret; + } + + sama7d65_plls[i][j].clk = clk; + if (sama7d65_plls[i][j].eid) { + sama7d65_pmc->chws[sama7d65_plls[i][j].eid] = clk; + } + } + } + + return 0; +} + +static int sam_pmc_register_mckx(const struct device *dev, struct pmc_data *sama7d65_pmc) +{ + const struct sam_pmc_cfg *cfg = dev->config; + const struct device *parents[10]; + void *const regmap = cfg->reg; + uint32_t mux_table[8]; + struct device *clk; + int ret = 0; + int i, j; + + ret = clk_register_master_div(regmap, "mck0", sama7d65_plls[PLL_ID_CPU][1].clk, + &mck0_layout, &mck0_characteristics, &pmc_mck0_lock, 5, &clk); + if (ret) { + LOG_ERR("Register MCK0 clock failed."); + return ret; + } + sama7d65_mckx[PCK_PARENT_HW_MCK0].clk = sama7d65_pmc->chws[PMC_MCK] = clk; + + parents[0] = cfg->md_slck; + parents[1] = cfg->td_slck; + parents[2] = sama7d65_pmc->chws[PMC_MAIN]; + for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7d65_mckx); i++) { + uint8_t num_parents = 3 + sama7d65_mckx[i].ep_count; + struct device *tmp_parent_hws[8]; + + if (num_parents > ARRAY_SIZE(mux_table)) { + LOG_ERR("Array for mux table not enough"); + return -ENOMEM; + } + + SAMA7D65_INIT_TABLE(mux_table, 3); + SAMA7D65_FILL_TABLE(&mux_table[3], sama7d65_mckx[i].ep_mux_table, + sama7d65_mckx[i].ep_count); + for (j = 0; j < sama7d65_mckx[i].ep_count; j++) { + uint8_t pll_id = sama7d65_mckx[i].ep[j].pll_id; + uint8_t pll_compid = sama7d65_mckx[i].ep[j].pll_compid; + + tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].clk; + } + SAMA7D65_FILL_TABLE(&parents[3], tmp_parent_hws, sama7d65_mckx[i].ep_count); + + ret = clk_register_master(regmap, sama7d65_mckx[i].n, num_parents, parents, + mux_table, &pmc_mckX_lock, sama7d65_mckx[i].id, &clk); + if (ret) { + LOG_ERR("Register MCK%d clock failed.", i); + return ret; + } + + sama7d65_mckx[i].clk = clk; + if (sama7d65_mckx[i].eid) { + sama7d65_pmc->chws[sama7d65_mckx[i].eid] = clk; + } + } + + return 0; +} + +static int sam_pmc_register_generated(const struct device *dev, struct pmc_data *sama7d65_pmc) +{ + const struct sam_pmc_cfg *cfg = dev->config; + const struct device *parents[10]; + void *const regmap = cfg->reg; + uint32_t mux_table[8]; + struct device *clk; + int ret = 0; + int i, j; + + parents[0] = cfg->md_slck; + parents[1] = cfg->td_slck; + parents[2] = sama7d65_pmc->chws[PMC_MAIN]; + parents[3] = sama7d65_pmc->chws[PMC_MCK1]; + for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) { + uint8_t num_parents = 4 + sama7d65_gck[i].pp_count; + struct device *tmp_parent_hws[8]; + + if (num_parents > ARRAY_SIZE(mux_table)) { + LOG_ERR("Array for mux table not enough"); + return -ENOMEM; + } + + SAMA7D65_INIT_TABLE(mux_table, 4); + SAMA7D65_FILL_TABLE(&mux_table[4], sama7d65_gck[i].pp_mux_table, + sama7d65_gck[i].pp_count); + for (j = 0; j < sama7d65_gck[i].pp_count; j++) { + uint8_t pll_id = sama7d65_gck[i].pp[j].pll_id; + uint8_t pll_compid = sama7d65_gck[i].pp[j].pll_compid; + + tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].clk; + } + SAMA7D65_FILL_TABLE(&parents[4], tmp_parent_hws, sama7d65_gck[i].pp_count); + + ret = clk_register_generated(regmap, &pmc_pcr_lock, + &sama7d65_pcr_layout, + sama7d65_gck[i].n, + parents, mux_table, + num_parents, + sama7d65_gck[i].id, + &sama7d65_gck[i].r, + sama7d65_gck[i].pp_chg_id, &clk); + if (ret) { + LOG_ERR("Register generated clock failed."); + return ret; + } + sama7d65_pmc->ghws[sama7d65_gck[i].id] = clk; + } + + return 0; +} + +void sam_pmc_setup(const struct device *dev) +{ + const struct sam_pmc_cfg *cfg = dev->config; + struct sam_pmc_data *data = dev->data; + const struct device *main_xtal = cfg->main_xtal; + const struct device *td_slck = cfg->td_slck; + const struct device *md_slck = cfg->md_slck; + + void *const regmap = cfg->reg; + const struct device *parents[10]; + struct pmc_data *sama7d65_pmc; + struct device *clk, *main_rc, *main_osc; + + uint32_t rate, bypass; + int ret, i; + + if (!td_slck || !md_slck || !main_xtal || !regmap) { + LOG_ERR("Incorrect parameters."); + return; + } + + if (CLK_CNT_SYSTEM != nck(sama7d65_systemck) || + CLK_CNT_PERIPH != nck(sama7d65_periphck) || + CLK_CNT_GCK != nck(sama7d65_gck)) { + LOG_ERR("Incorrect definitions could make array for pmc clocks not enough"); + return; + } + + sama7d65_pmc = pmc_data_allocate(PMC_MCK5 + 1, nck(sama7d65_systemck), + nck(sama7d65_periphck), nck(sama7d65_gck), + SOC_NUM_CLOCK_PROGRAMMABLE, &pmc_table[0]); + if (!sama7d65_pmc) { + LOG_ERR("allocate PMC data failed."); + return; + } + data->pmc = sama7d65_pmc; + + ret = clk_register_main_rc_osc(regmap, "main_rc_osc", MHZ(12), &main_rc); + if (ret) { + LOG_ERR("Register clock main_rc_osc failed."); + return; + } + + if (clock_control_get_rate(main_xtal, NULL, &rate)) { + LOG_ERR("get clock rate of main_xtal failed."); + return; + } + + bypass = 0; + ret = clk_register_main_osc(regmap, "main_osc", bypass, rate, &main_osc); + if (ret) { + LOG_ERR("Register clock main_osc failed."); + return; + } + + parents[0] = main_rc; + parents[1] = main_osc; + ret = clk_register_main(regmap, "mainck", parents, 2, &clk); + if (ret) { + LOG_ERR("Register clock mainck failed."); + return; + } + + sama7d65_pmc->chws[PMC_MAIN] = clk; + + ret = sam_pmc_register_pll(dev, sama7d65_pmc); + if (ret) { + return; + } + + ret = sam_pmc_register_mckx(dev, sama7d65_pmc); + if (ret) { + return; + } + + parents[0] = md_slck; + parents[1] = td_slck; + parents[2] = sama7d65_pmc->chws[PMC_MAIN]; + parents[3] = sama7d65_plls[PLL_ID_SYS][PLL_COMPID_DIV0].clk; + parents[4] = sama7d65_plls[PLL_ID_DDR][PLL_COMPID_DIV0].clk; + parents[5] = sama7d65_plls[PLL_ID_GPU][PLL_COMPID_DIV0].clk; + parents[6] = sama7d65_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].clk; + parents[7] = sama7d65_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].clk; + parents[8] = sama7d65_plls[PLL_ID_ETH][PLL_COMPID_DIV0].clk; + for (i = 0; i < 8; i++) { + ret = clk_register_programmable(regmap, parents, 9, i, &programmable_layout, + sama7d65_prog_mux_table, &clk); + if (ret) { + LOG_ERR("Register programmable clock %d failed.", i); + return; + } + + sama7d65_pmc->pchws[i] = clk; + } + + for (i = 0; i < ARRAY_SIZE(sama7d65_systemck); i++) { + ret = clk_register_system(regmap, sama7d65_systemck[i].n, + sama7d65_pmc->pchws[i], + sama7d65_systemck[i].id, &clk); + if (ret) { + LOG_ERR("Register system clock %d failed.", i); + return; + } + + sama7d65_pmc->shws[sama7d65_systemck[i].id] = clk; + } + + for (i = 0; i < ARRAY_SIZE(sama7d65_periphck); i++) { + clk = sama7d65_mckx[sama7d65_periphck[i].p].clk; + ret = clk_register_peripheral(regmap, &pmc_pcr_lock, + &sama7d65_pcr_layout, + sama7d65_periphck[i].n, + clk, + sama7d65_periphck[i].id, + &sama7d65_periphck[i].r, + &clk); + if (ret) { + LOG_ERR("Register peripheral clock failed."); + return; + } + sama7d65_pmc->phws[sama7d65_periphck[i].id] = clk; + } + + ret = sam_pmc_register_generated(dev, sama7d65_pmc); + if (ret) { + return; + } + + LOG_DBG("Register PMC clocks successfully."); +} diff --git a/soc/microchip/sam/common/sama7g5.c b/soc/microchip/sam/common/sama7g5.c index dbcb0a07d096e..1bf28fe1f882d 100644 --- a/soc/microchip/sam/common/sama7g5.c +++ b/soc/microchip/sam/common/sama7g5.c @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -1154,11 +1153,7 @@ void sam_pmc_setup(const struct device *dev) parents[7] = sama7g5_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].clk; parents[8] = sama7g5_plls[PLL_ID_ETH][PLL_COMPID_DIV0].clk; for (i = 0; i < 8; i++) { - char name[6]; - - snprintf(name, sizeof(name), "prog%d", i); - - ret = clk_register_programmable(regmap, name, parents, + ret = clk_register_programmable(regmap, parents, 9, i, &programmable_layout, sama7g5_prog_mux_table, &clk); diff --git a/soc/microchip/sam/sama7/CMakeLists.txt b/soc/microchip/sam/sama7/CMakeLists.txt new file mode 100644 index 0000000000000..7f08aa1b33ac6 --- /dev/null +++ b/soc/microchip/sam/sama7/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +add_subdirectory(${SOC_SERIES}) + +add_subdirectory(../common ${CMAKE_BINARY_DIR}/common) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/microchip/sam/sama7/Kconfig b/soc/microchip/sam/sama7/Kconfig new file mode 100644 index 0000000000000..f7fe8649c0497 --- /dev/null +++ b/soc/microchip/sam/sama7/Kconfig @@ -0,0 +1,10 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_FAMILY_MICROCHIP_SAMA7 + select MICROCHIP_SAM + select ARM + select CPU_CORTEX_A7 + select MMU diff --git a/soc/microchip/sam/sama7/Kconfig.defconfig b/soc/microchip/sam/sama7/Kconfig.defconfig new file mode 100644 index 0000000000000..99b0bf81148c1 --- /dev/null +++ b/soc/microchip/sam/sama7/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_FAMILY_MICROCHIP_SAMA7 + +configdefault SOC_EARLY_INIT_HOOK + default y + +configdefault CLOCK_CONTROL + default y + +endif # SOC_FAMILY_MICROCHIP_SAMA7 + +rsource "*/Kconfig.defconfig" diff --git a/soc/microchip/sam/sama7/Kconfig.soc b/soc/microchip/sam/sama7/Kconfig.soc new file mode 100644 index 0000000000000..352678952dacb --- /dev/null +++ b/soc/microchip/sam/sama7/Kconfig.soc @@ -0,0 +1,14 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_FAMILY_MICROCHIP_SAMA7 + bool + help + Enable support for Microchip SAMA7 Cortex-A Microprocessors. + +config SOC_FAMILY + default "microchip_sama7" if SOC_FAMILY_MICROCHIP_SAMA7 + +rsource "*/Kconfig.soc" diff --git a/soc/microchip/sam/sama7/sama7d6/CMakeLists.txt b/soc/microchip/sam/sama7/sama7d6/CMakeLists.txt new file mode 100644 index 0000000000000..8d91aceb1f3a8 --- /dev/null +++ b/soc/microchip/sam/sama7/sama7d6/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_sources(soc.c) +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/microchip/sam/sama7/sama7d6/Kconfig.defconfig b/soc/microchip/sam/sama7/sama7d6/Kconfig.defconfig new file mode 100644 index 0000000000000..1d7b758263ad7 --- /dev/null +++ b/soc/microchip/sam/sama7/sama7d6/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_SERIES_SAMA7D6 + +configdefault NUM_IRQS + default 189 + +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/soc/timer@e1800000,clock-frequency) + +endif # SOC_SERIES_SAMA7D6 diff --git a/soc/microchip/sam/sama7/sama7d6/Kconfig.soc b/soc/microchip/sam/sama7/sama7d6/Kconfig.soc new file mode 100644 index 0000000000000..fcbfe636d879d --- /dev/null +++ b/soc/microchip/sam/sama7/sama7d6/Kconfig.soc @@ -0,0 +1,45 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_SERIES_SAMA7D6 + bool + select SOC_FAMILY_MICROCHIP_SAMA7 + help + Enable support for Microchip SAMA7D6 Cortex-A Microprocessors. + +config SOC_SERIES + default "sama7d6" if SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65 + bool + select SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65D1G + bool + select SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65D1GN2 + bool + select SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65D2G + bool + select SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65D2GN8 + bool + select SOC_SERIES_SAMA7D6 + +config SOC_SAMA7D65D5M + bool + select SOC_SERIES_SAMA7D6 + +config SOC + default "sama7d65" if SOC_SAMA7D65 + default "sama7d65d1g" if SOC_SAMA7D65D1G + default "sama7d65d1gn2" if SOC_SAMA7D65D1GN2 + default "sama7d65d2g" if SOC_SAMA7D65D2G + default "sama7d65d2gn8" if SOC_SAMA7D65D2GN8 + default "sama7d65d5m" if SOC_SAMA7D65D5M diff --git a/soc/microchip/sam/sama7/sama7d6/soc.c b/soc/microchip/sam/sama7/sama7d6/soc.c new file mode 100644 index 0000000000000..39339f362ba67 --- /dev/null +++ b/soc/microchip/sam/sama7/sama7d6/soc.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include + +#define MMU_REGION_FLEXCOM_DEFN(idx, n) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flx##n)), \ + (MMU_REGION_FLAT_ENTRY("flexcom"#n, FLEXCOM##n##_BASE_ADDRESS, 0x4000, \ + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W),), \ + ()) + +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), + + FOR_EACH_IDX(MMU_REGION_FLEXCOM_DEFN, (), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + + MMU_REGION_FLAT_ENTRY("gic", GIC_DISTRIBUTOR_BASE, 0x1100, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pioa", PIO_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pit64b0", PIT64B0_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), + + MMU_REGION_FLAT_ENTRY("sckc", SCKC_BASE_ADDRESS, 0x4, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; + +void relocate_vector_table(void) +{ + write_vbar(CONFIG_KERNEL_VM_BASE); +} + +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(20 - 1) | PMC_PCR_GCLKCSS_MCK1 | + PMC_PCR_PID(ID_PIT64B0); +} diff --git a/soc/microchip/sam/sama7/sama7d6/soc.h b/soc/microchip/sam/sama7/sama7d6/soc.h new file mode 100644 index 0000000000000..11926a924306e --- /dev/null +++ b/soc/microchip/sam/sama7/sama7d6/soc.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_MICROCHIP_SAMA7D6_SOC__H_ +#define _SOC_MICROCHIP_SAMA7D6_SOC__H_ + +#ifndef _ASMLANGUAGE + +#include + +#if defined(CONFIG_SOC_SAMA7D65) + #include +#elif defined(CONFIG_SOC_SAMA7D65D1G) + #include +#elif defined(CONFIG_SOC_SAMA7D65D1GN2) + #include +#elif defined(CONFIG_SOC_SAMA7D65D2G) + #include +#elif defined(CONFIG_SOC_SAMA7D65D2GN8) + #include +#elif defined(CONFIG_SOC_SAMA7D65D5M) + #include +#else + #error Library does not support the specified device +#endif + +#endif /* _ASMLANGUAGE */ + +/* number of clocks registered */ +#define SOC_NUM_CLOCK_PLL_FRAC 9 +#define SOC_NUM_CLOCK_PLL_DIV (SOC_NUM_CLOCK_PLL_FRAC + 1) /* AUDIO PLL: DIVPMC, DIVIO */ +#define SOC_NUM_CLOCK_MASTER 10 /* MCK 0 ~ 9 */ +#define SOC_NUM_CLOCK_PROGRAMMABLE 8 /* MCK 0 ~ 7 */ +#define SOC_NUM_CLOCK_SYSTEM 8 /* PCK 0 ~ 7 */ +#define SOC_NUM_CLOCK_PERIPHERAL 72 +#define SOC_NUM_CLOCK_GENERATED 44 + +#endif /* _SOC_MICROCHIP_SAMA7D6_SOC__H_ */ diff --git a/soc/microchip/sam/sama7/soc.yml b/soc/microchip/sam/sama7/soc.yml new file mode 100644 index 0000000000000..96b42ac83c86b --- /dev/null +++ b/soc/microchip/sam/sama7/soc.yml @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +family: +- name: microchip_sama7 + series: + - name: sama7d6 + socs: + - name: sama7d65 + - name: sama7d65d1g + - name: sama7d65d1gn2 + - name: sama7d65d2g + - name: sama7d65d2gn8 + - name: sama7d65d5m diff --git a/soc/microchip/sam/sama7g5/Kconfig.defconfig b/soc/microchip/sam/sama7g5/Kconfig.defconfig index dd102f1621cc6..067cabe8f301f 100644 --- a/soc/microchip/sam/sama7g5/Kconfig.defconfig +++ b/soc/microchip/sam/sama7g5/Kconfig.defconfig @@ -14,4 +14,7 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config MMU default y +config CACHE_MANAGEMENT + default y + endif # SOC_SERIES_SAMA7G5 diff --git a/soc/microchip/sam/sama7g5/soc.c b/soc/microchip/sam/sama7g5/soc.c index e468b6fc33635..005300968f051 100644 --- a/soc/microchip/sam/sama7g5/soc.c +++ b/soc/microchip/sam/sama7g5/soc.c @@ -15,6 +15,11 @@ MT_STRONGLY_ORDERED | MPERM_R | MPERM_W),), \ ()) +#define MMU_REGION_XDMAC_DEFN(idx, n) \ + IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dma##n)), \ + (MMU_REGION_FLAT_ENTRY("xdmac"#n, XDMAC##n##_BASE_ADDRESS, 0x4000, \ + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W),)) + 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), @@ -49,6 +54,8 @@ static const struct arm_mmu_region mmu_regions[] = { IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(trng)), (MMU_REGION_FLAT_ENTRY("trng", TRNG_BASE_ADDRESS, 0x100, MT_STRONGLY_ORDERED | MPERM_R | MPERM_W),)) + + FOR_EACH_IDX(MMU_REGION_XDMAC_DEFN, (), 0, 1, 2) }; const struct arm_mmu_config mmu_config = { diff --git a/soc/microchip/sam/sama7g5/soc.h b/soc/microchip/sam/sama7g5/soc.h index cdacd1592f9d4..bc2c93b57e1e7 100644 --- a/soc/microchip/sam/sama7g5/soc.h +++ b/soc/microchip/sam/sama7g5/soc.h @@ -13,4 +13,13 @@ #include "sam.h" +/* number of clocks registered */ +#define SOC_NUM_CLOCK_PLL_FRAC 7 +#define SOC_NUM_CLOCK_PLL_DIV (SOC_NUM_CLOCK_PLL_FRAC + 1) /* AUDIO PLL: DIVPMC, DIVIO */ +#define SOC_NUM_CLOCK_MASTER 5 /* MCK 0 ~ 4 */ +#define SOC_NUM_CLOCK_PROGRAMMABLE 8 /* MCK 0 ~ 7 */ +#define SOC_NUM_CLOCK_SYSTEM 8 /* PCK 0 ~ 7 */ +#define SOC_NUM_CLOCK_PERIPHERAL 72 +#define SOC_NUM_CLOCK_GENERATED 46 + #endif /* __SAMA7G5_SOC__H_ */ diff --git a/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c b/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c index a9e8b3de7a912..65814c347d710 100644 --- a/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c +++ b/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c @@ -5,7 +5,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) diff --git a/soc/nuvoton/npcx/common/npckn/include/reg_def.h b/soc/nuvoton/npcx/common/npckn/include/reg_def.h index 3ab3ef85cb181..313ac130ce690 100644 --- a/soc/nuvoton/npcx/common/npckn/include/reg_def.h +++ b/soc/nuvoton/npcx/common/npckn/include/reg_def.h @@ -1490,20 +1490,15 @@ struct ps2_reg { #define NPCX_PSCON_IDB FIELD(4, 3) #define NPCX_PSCON_WPUED 7 -#define NPCX_PSOSIG_WDAT0 0 -#define NPCX_PSOSIG_WDAT1 1 -#define NPCX_PSOSIG_WDAT2 2 -#define NPCX_PSOSIG_CLK0 3 -#define NPCX_PSOSIG_CLK1 4 -#define NPCX_PSOSIG_CLK2 5 -#define NPCX_PSOSIG_WDAT3 6 -#define NPCX_PSOSIG_CLK3 7 -#define NPCX_PSOSIG_CLK(n) (((n) < 3) ? ((n) + 3) : 7) -#define NPCX_PSOSIG_WDAT(n) (((n) < 3) ? ((n) + 0) : 6) -#define NPCX_PSOSIG_CLK_MASK_ALL \ - (BIT(NPCX_PSOSIG_CLK0) | \ - BIT(NPCX_PSOSIG_CLK1) | \ - BIT(NPCX_PSOSIG_CLK2) | \ +#define NPCX_PSOSIG_WDAT2 1 +#define NPCX_PSOSIG_WDAT3 2 +#define NPCX_PSOSIG_CLK2 4 +#define NPCX_PSOSIG_CLK3 5 +#define NPCX_PSOSIG_CLK(n) (((n) == 2) ? NPCX_PSOSIG_CLK2 : \ + NPCX_PSOSIG_CLK3) +#define NPCX_PSOSIG_WDAT(n) (((n) == 2) ? NPCX_PSOSIG_WDAT2 : \ + NPCX_PSOSIG_WDAT3) +#define NPCX_PSOSIG_CLK_MASK_ALL (BIT(NPCX_PSOSIG_CLK2) | \ BIT(NPCX_PSOSIG_CLK3)) #define NPCX_PSIEN_SOTIE 0 diff --git a/soc/nuvoton/npcx/npcx7/mpu_regions.c b/soc/nuvoton/npcx/npcx7/mpu_regions.c index e9d4c07330588..da8199eceb8db 100644 --- a/soc/nuvoton/npcx/npcx7/mpu_regions.c +++ b/soc/nuvoton/npcx/npcx7/mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("FLASH_0_0", diff --git a/soc/nuvoton/numaker/m55m1x/mpu_regions.c b/soc/nuvoton/numaker/m55m1x/mpu_regions.c index 33e59b71fba18..ecf2a0a4651e8 100644 --- a/soc/nuvoton/numaker/m55m1x/mpu_regions.c +++ b/soc/nuvoton/numaker/m55m1x/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("FLASH", diff --git a/soc/nxp/imx/imx7d/soc.c b/soc/nxp/imx/imx7d/soc.c index 7b98389762533..6f7f0b6ed23a8 100644 --- a/soc/nxp/imx/imx7d/soc.c +++ b/soc/nxp/imx/imx7d/soc.c @@ -84,6 +84,21 @@ static void nxp_mcimx7_gpio_config(void) static void nxp_mcimx7_uart_config(void) { +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart1)) + /* We need to grasp board uart exclusively */ + RDC_SetPdapAccess(RDC, rdcPdapUart1, RDC_DT_VAL(uart1), false, false); + /* Select clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, ccmRootUart1, ccmRootmuxUartOsc24m, 0, 0); + /* Enable uart clock */ + CCM_EnableRoot(CCM, ccmRootUart1); + /* + * IC Limitation + * M4 stop will cause A7 UART lose functionality + * So we need UART clock all the time + */ + CCM_ControlGate(CCM, ccmCcgrGateUart1, ccmClockNeededAll); +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart2)) /* We need to grasp board uart exclusively */ RDC_SetPdapAccess(RDC, rdcPdapUart2, RDC_DT_VAL(uart2), false, false); @@ -99,6 +114,51 @@ static void nxp_mcimx7_uart_config(void) CCM_ControlGate(CCM, ccmCcgrGateUart2, ccmClockNeededAll); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart3)) + /* We need to grasp board uart exclusively */ + RDC_SetPdapAccess(RDC, rdcPdapUart3, RDC_DT_VAL(uart3), false, false); + /* Select clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, ccmRootUart3, ccmRootmuxUartOsc24m, 0, 0); + /* Enable uart clock */ + CCM_EnableRoot(CCM, ccmRootUart3); + /* + * IC Limitation + * M4 stop will cause A7 UART lose functionality + * So we need UART clock all the time + */ + CCM_ControlGate(CCM, ccmCcgrGateUart3, ccmClockNeededAll); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart4)) + /* We need to grasp board uart exclusively */ + RDC_SetPdapAccess(RDC, rdcPdapUart4, RDC_DT_VAL(uart4), false, false); + /* Select clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, ccmRootUart4, ccmRootmuxUartOsc24m, 0, 0); + /* Enable uart clock */ + CCM_EnableRoot(CCM, ccmRootUart4); + /* + * IC Limitation + * M4 stop will cause A7 UART lose functionality + * So we need UART clock all the time + */ + CCM_ControlGate(CCM, ccmCcgrGateUart4, ccmClockNeededAll); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart5)) + /* We need to grasp board uart exclusively */ + RDC_SetPdapAccess(RDC, rdcPdapUart5, RDC_DT_VAL(uart5), false, false); + /* Select clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, ccmRootUart5, ccmRootmuxUartOsc24m, 0, 0); + /* Enable uart clock */ + CCM_EnableRoot(CCM, ccmRootUart5); + /* + * IC Limitation + * M4 stop will cause A7 UART lose functionality + * So we need UART clock all the time + */ + CCM_ControlGate(CCM, ccmCcgrGateUart5, ccmClockNeededAll); +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart6)) /* We need to grasp board uart exclusively */ RDC_SetPdapAccess(RDC, rdcPdapUart6, RDC_DT_VAL(uart6), false, false); @@ -113,6 +173,21 @@ static void nxp_mcimx7_uart_config(void) */ CCM_ControlGate(CCM, ccmCcgrGateUart6, ccmClockNeededAll); #endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart7)) + /* We need to grasp board uart exclusively */ + RDC_SetPdapAccess(RDC, rdcPdapUart7, RDC_DT_VAL(uart7), false, false); + /* Select clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, ccmRootUart7, ccmRootmuxUartOsc24m, 0, 0); + /* Enable uart clock */ + CCM_EnableRoot(CCM, ccmRootUart7); + /* + * IC Limitation + * M4 stop will cause A7 UART lose functionality + * So we need UART clock all the time + */ + CCM_ControlGate(CCM, ccmCcgrGateUart7, ccmClockNeededAll); +#endif } #endif /* CONFIG_UART_IMX */ diff --git a/soc/nxp/imx/imx8m/m7/mpu_regions.c b/soc/nxp/imx/imx8m/m7/mpu_regions.c index ed7deb8575abf..c7ca883882f73 100644 --- a/soc/nxp/imx/imx8m/m7/mpu_regions.c +++ b/soc/nxp/imx/imx8m/m7/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include #define REGION_MASK_BASE_ADDRESS 0x00000000U #define REGION_ITCM_BASE_ADDRESS 0x00000000U diff --git a/soc/nxp/imx/imx9/imx91/soc.h b/soc/nxp/imx/imx9/imx91/soc.h new file mode 100644 index 0000000000000..c899f64d7d525 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/soc.h @@ -0,0 +1,16 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_NXP_IMX_IMX91_SOC_H_ +#define _SOC_NXP_IMX_IMX91_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC_NXP_IMX_IMX91_SOC_H_ */ diff --git a/soc/nxp/imxrt/mpu_regions.c b/soc/nxp/imxrt/mpu_regions.c index 51ce490eff1d8..8a017dadaf174 100644 --- a/soc/nxp/imxrt/mpu_regions.c +++ b/soc/nxp/imxrt/mpu_regions.c @@ -7,7 +7,7 @@ #define SDRAM_BASE_ADDR 0x80000000 #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ diff --git a/soc/nxp/lpc/lpc55xxx/Kconfig b/soc/nxp/lpc/lpc55xxx/Kconfig index 3d92329c0b346..5e4124f5e6418 100644 --- a/soc/nxp/lpc/lpc55xxx/Kconfig +++ b/soc/nxp/lpc/lpc55xxx/Kconfig @@ -3,6 +3,7 @@ config SOC_SERIES_LPC55XXX select HAS_MCUX + select HAS_SWO select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_DWT select SOC_RESET_HOOK diff --git a/soc/nxp/lpc/lpc55xxx/soc.c b/soc/nxp/lpc/lpc55xxx/soc.c index 235aeb96bc21c..648dc45c7f070 100644 --- a/soc/nxp/lpc/lpc55xxx/soc.c +++ b/soc/nxp/lpc/lpc55xxx/soc.c @@ -433,6 +433,12 @@ DT_FOREACH_STATUS_OKAY(nxp_ctimer_pwm, CTIMER_CLOCK_SETUP) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(opamp2)) POWER_DisablePD(kPDRUNCFG_PD_OPAMP2); #endif + +#ifdef CONFIG_LOG_BACKEND_SWO + CLOCK_AttachClk(kTRACE_DIV_to_TRACE); + CLOCK_SetClkDiv(kCLOCK_DivArmTrClkDiv, 1U, true); +#endif + } /** diff --git a/soc/nxp/mcx/mcxa/Kconfig b/soc/nxp/mcx/mcxa/Kconfig index af34d311ebaad..df1092cda6a0a 100644 --- a/soc/nxp/mcx/mcxa/Kconfig +++ b/soc/nxp/mcx/mcxa/Kconfig @@ -40,3 +40,10 @@ config SOC_MCXA366 select CPU_HAS_FPU select ARMV8_M_DSP select HAS_MCUX_CACHE + +config SOC_MCXA344 + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select ARMV8_M_DSP + select HAS_MCUX_CACHE diff --git a/soc/nxp/mcx/mcxa/Kconfig.defconfig b/soc/nxp/mcx/mcxa/Kconfig.defconfig index 04d2950e1d50e..0d2b2496654df 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxa/Kconfig.defconfig @@ -7,6 +7,9 @@ config CORTEX_M_SYSTICK default n if (MCUX_LPTMR_TIMER || MCUX_OS_TIMER) config NUM_IRQS + default 80 if SOC_MCXA153 + default 89 if SOC_MCXA156 + default 122 if (SOC_MCXA346 || SOC_MCXA266 || SOC_MCXA366) 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 1928fe2e42d3b..549204be406ef 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.soc +++ b/soc/nxp/mcx/mcxa/Kconfig.soc @@ -27,12 +27,17 @@ config SOC_MCXA366 bool select SOC_FAMILY_MCXA +config SOC_MCXA344 + bool + select SOC_FAMILY_MCXA + config SOC default "mcxa153" if SOC_MCXA153 default "mcxa156" if SOC_MCXA156 default "mcxa346" if SOC_MCXA346 default "mcxa266" if SOC_MCXA266 default "mcxa366" if SOC_MCXA366 + default "mcxa344" if SOC_MCXA344 config SOC_PART_NUMBER_MCXA153VFM bool @@ -91,6 +96,18 @@ config SOC_PART_NUMBER_MCXA366VLH config SOC_PART_NUMBER_MCXA366VPN bool +config SOC_PART_NUMBER_MCXA344VFM + bool + +config SOC_PART_NUMBER_MCXA344VLF + bool + +config SOC_PART_NUMBER_MCXA344VLH + bool + +config SOC_PART_NUMBER_MCXA344VLL + bool + config SOC_PART_NUMBER default "MCXA153VFM" if SOC_PART_NUMBER_MCXA153VFM default "MCXA153VFT" if SOC_PART_NUMBER_MCXA153VFT @@ -111,3 +128,7 @@ 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 "MCXA344VFM" if SOC_PART_NUMBER_MCXA344VFM + default "MCXA344VLF" if SOC_PART_NUMBER_MCXA344VLF + default "MCXA344VLH" if SOC_PART_NUMBER_MCXA344VLH + default "MCXA344VLL" if SOC_PART_NUMBER_MCXA344VLL diff --git a/soc/nxp/mcx/mcxe/CMakeLists.txt b/soc/nxp/mcx/mcxe/CMakeLists.txt new file mode 100644 index 0000000000000..e85ff1f432d20 --- /dev/null +++ b/soc/nxp/mcx/mcxe/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/nxp/mcx/mcxe/Kconfig b/soc/nxp/mcx/mcxe/Kconfig new file mode 100644 index 0000000000000..d3f147cb36f12 --- /dev/null +++ b/soc/nxp/mcx/mcxe/Kconfig @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MCXE + +rsource "*/Kconfig" + +endif # SOC_FAMILY_MCXE diff --git a/soc/nxp/mcx/mcxe/Kconfig.defconfig b/soc/nxp/mcx/mcxe/Kconfig.defconfig new file mode 100644 index 0000000000000..d7a6613d4a183 --- /dev/null +++ b/soc/nxp/mcx/mcxe/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MCXE + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_MCXE diff --git a/soc/nxp/mcx/mcxe/Kconfig.soc b/soc/nxp/mcx/mcxe/Kconfig.soc new file mode 100644 index 0000000000000..f1755af7e2c54 --- /dev/null +++ b/soc/nxp/mcx/mcxe/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MCXE + bool + +config SOC_FAMILY + default "mcxe" if SOC_FAMILY_MCXE + +rsource "*/Kconfig.soc" diff --git a/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt b/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt new file mode 100644 index 0000000000000..e01a54ecc0abb --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_MCXE_FLASH_CONFIG flash_configuration.c) + +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + +zephyr_linker_sources_ifdef(CONFIG_MCXE_FLASH_CONFIG + ROM_START + SORT_KEY 0x400 + flash_config.ld + ) + +# 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) diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig new file mode 100644 index 0000000000000..f40f2ff28a4bb --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig @@ -0,0 +1,37 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXE24X + select ARM + select CPU_CORTEX_M4 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_FPU + select HAS_MCUX + select CLOCK_CONTROL + select SOC_RESET_HOOK + +if SOC_SERIES_MCXE24X + +config MCXE_FLASH_CONFIG + bool "MCXE flash configuration field" + default y if XIP && !BOOTLOADER_MCUBOOT + help + Include the 16-byte flash configuration field that stores default + protection settings (loaded on reset) and security information that + allows the MCU to restrict access to the FTFC module. + +config WDOG_ENABLE_AT_BOOT + bool "Keep watchdog timer enabled at boot" + help + Leave SOC watchdog timer enabled at boot. The specific timeout + and clock configuration of the watchdog at boot is SOC dependent. + Note: if the watchdog timer is enabled at boot, the user will + need to configure the watchdog using z_arm_watchdog_init, as + the SOC requires watchdog configuration before initial expiration + +# Enable watchdog configuration function if watchdog is left enabled at boot +config WDOG_INIT + bool + default WDOG_ENABLE_AT_BOOT + +endif # SOC_SERIES_MCXE24X diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.defconfig b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.defconfig new file mode 100644 index 0000000000000..a044901f3e401 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.defconfig @@ -0,0 +1,22 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_MCXE24X + +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 + +config NUM_IRQS + default 146 + +config CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS + default y + +config GPIO + default y + +endif # SOC_SERIES_MCXE24X diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.soc b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.soc new file mode 100644 index 0000000000000..6ef5787598afc --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig.soc @@ -0,0 +1,60 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXE24X + bool + select SOC_FAMILY_MCXE + +config SOC_SERIES + default "mcxe24x" if SOC_SERIES_MCXE24X + +config SOC_MCXE245 + bool + select SOC_SERIES_MCXE24X + +config SOC_MCXE246 + bool + select SOC_SERIES_MCXE24X + +config SOC_MCXE247 + bool + select SOC_SERIES_MCXE24X + +config SOC + default "mcxe245" if SOC_MCXE245 + default "mcxe246" if SOC_MCXE246 + default "mcxe247" if SOC_MCXE247 + +config SOC_PART_NUMBER_MCXE245VLF + bool + +config SOC_PART_NUMBER_MCXE245VLH + bool + +config SOC_PART_NUMBER_MCXE245VLL + bool + +config SOC_PART_NUMBER_MCXE246VLH + bool + +config SOC_PART_NUMBER_MCXE246VLL + bool + +config SOC_PART_NUMBER_MCXE246VLQ + bool + +config SOC_PART_NUMBER_MCXE247VLL + bool + +config SOC_PART_NUMBER_MCXE247VLQ + bool + +config SOC_PART_NUMBER + default "MCXE245VLF" if SOC_PART_NUMBER_MCXE245VLF + default "MCXE245VLH" if SOC_PART_NUMBER_MCXE245VLH + default "MCXE245VLL" if SOC_PART_NUMBER_MCXE245VLL + default "MCXE246VLH" if SOC_PART_NUMBER_MCXE246VLH + default "MCXE246VLL" if SOC_PART_NUMBER_MCXE246VLL + default "MCXE246VLQ" if SOC_PART_NUMBER_MCXE246VLQ + default "MCXE247VLL" if SOC_PART_NUMBER_MCXE247VLL + default "MCXE247VLQ" if SOC_PART_NUMBER_MCXE247VLQ diff --git a/soc/nxp/mcx/mcxe/mcxe24x/flash_config.ld b/soc/nxp/mcx/mcxe/mcxe24x/flash_config.ld new file mode 100644 index 0000000000000..40f44c772d1c9 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/flash_config.ld @@ -0,0 +1,9 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +. = 0x400; +KEEP(*(.kinetis_flash_config)) +KEEP(*(".kinetis_flash_config.*")) diff --git a/soc/nxp/mcx/mcxe/mcxe24x/flash_configuration.c b/soc/nxp/mcx/mcxe/mcxe24x/flash_configuration.c new file mode 100644 index 0000000000000..3cd74b93e5b48 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/flash_configuration.c @@ -0,0 +1,44 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +uint8_t __kinetis_flash_config_section __kinetis_flash_config[] = { + /* Backdoor Comparison Key */ + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + + /* Program flash protection; 1 bit/region - 0=protected, 1=unprotected + */ + 0xFF, + 0xFF, + 0xFF, + 0xFF, + + /* Flash security register (FSEC) enables/disables backdoor key access, + * mass erase, factory access, and flash security + */ + DT_PROP_OR(DT_NODELABEL(ftfc), fsec, 0xFE), + + /* Flash nonvolatile option register (FOPT) enables/disables NMI, + * EzPort, and boot options + */ + DT_PROP_OR(DT_NODELABEL(ftfc), fopt, 0xFF), + + /* EEPROM protection register (FEPROT) */ + 0xFF, + + /* Data flash protection register (FDPROT) */ + 0XFF, +}; diff --git a/soc/nxp/mcx/mcxe/mcxe24x/pinctrl_soc.h b/soc/nxp/mcx/mcxe/mcxe24x/pinctrl_soc.h new file mode 100644 index 0000000000000..a6904bc354685 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/pinctrl_soc.h @@ -0,0 +1,7 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/nxp/mcx/mcxe/mcxe24x/soc.c b/soc/nxp/mcx/mcxe/mcxe24x/soc.c new file mode 100644 index 0000000000000..8d70ec28a0143 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/soc.c @@ -0,0 +1,20 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_SOC_RESET_HOOK + +void soc_reset_hook(void) +{ + SystemInit(); +} + +#endif /* CONFIG_SOC_RESET_HOOK */ diff --git a/soc/nxp/mcx/mcxe/mcxe24x/soc.h b/soc/nxp/mcx/mcxe/mcxe24x/soc.h new file mode 100644 index 0000000000000..9722ad2cc811c --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe24x/soc.h @@ -0,0 +1,21 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#include +#include + +#define PORT_MUX_GPIO kPORT_MuxAsGpio /* GPIO setting for the Port Mux Register */ + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC__H_ */ diff --git a/soc/nxp/mcx/mcxe/mcxe31x/CMakeLists.txt b/soc/nxp/mcx/mcxe/mcxe31x/CMakeLists.txt new file mode 100644 index 0000000000000..a3943a2491824 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_sources(sram_config.c) +zephyr_include_directories(.) + +zephyr_library_sources_ifdef(CONFIG_SOC_RESET_HOOK mcxe31x_soc_initialization.S) + +zephyr_linker_sources_ifdef(CONFIG_BOARD_NXP_MCXE31X_BOOT_HEADER + ROM_START SORT_KEY 0 boot_header.ld) + +zephyr_linker_sources(SECTIONS itcm.ld) +zephyr_code_relocate(FILES sram_config.c LOCATION ${CONFIG_SRAM_CONFIG_RELOCATE_MEM}_TEXT) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/mcx/mcxe/mcxe31x/Kconfig b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig new file mode 100644 index 0000000000000..d5e653105f7e2 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig @@ -0,0 +1,56 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXE31X + select CPU_CORTEX_M7 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select ARM + select CLOCK_CONTROL + select HAS_MCUX + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select SOC_RESET_HOOK + select SOC_EARLY_INIT_HOOK + select CODE_DATA_RELOCATION + +if SOC_SERIES_MCXE31X + +if CODE_DATA_RELOCATION + +config SRAM_CONFIG_RELOCATE_MEM + string + default "ITCM" + help + Select memory to relocate sram_config.c code + +endif # CODE_DATA_RELOCATION + +config SOC_NXP_MCXE31X_BOOT_HEADER + bool + help + Enable boot header configuration for NXP MCXE31X SoC. + This should be selected by boards that need boot header support. + +if SOC_NXP_MCXE31X_BOOT_HEADER + +config BOOT_HEADER_OFFSET + hex "Flash config data offset" + default 0x0 + help + The flash config offset provides the boot ROM with the on-board + flash type and parameters. The boot ROM requires a fixed flash config + offset for FlexSPI device. + +config IMAGE_VECTOR_TABLE_OFFSET + hex "Image vector table offset" + default 0x1000 + help + The Image Vector Table (IVT) provides the boot ROM with pointers to + the application entry point and device configuration data. The boot + ROM requires a fixed IVT offset for each type of boot device. + +endif # SOC_NXP_MCXE31X_BOOT_HEADER + +endif # SOC_SERIES_MCXE31X diff --git a/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.defconfig b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.defconfig new file mode 100644 index 0000000000000..2e00f0115b1a8 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_MCXE31X + +config NUM_IRQS + default 240 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK + +config CORTEX_M_SYSTICK + default n if (MCUX_LPTMR_TIMER || MCUX_OS_TIMER) + +config ROM_START_OFFSET + default 0x1000 + +endif # SOC_SERIES_MCXE31X diff --git a/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.soc b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.soc new file mode 100644 index 0000000000000..8e6caff06622f --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/Kconfig.soc @@ -0,0 +1,68 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXE31X + bool + select SOC_FAMILY_MCXE + +config SOC_SERIES + default "mcxe31x" if SOC_SERIES_MCXE31X + +config SOC_MCXE315 + bool + select SOC_SERIES_MCXE31X + +config SOC_MCXE316 + bool + select SOC_SERIES_MCXE31X + +config SOC_MCXE317 + bool + select SOC_SERIES_MCXE31X + +config SOC_MCXE31B + bool + select SOC_SERIES_MCXE31X + +config SOC + default "mcxe315" if SOC_MCXE315 + default "mcxe316" if SOC_MCXE316 + default "mcxe317" if SOC_MCXE317 + default "mcxe31b" if SOC_MCXE31B + +config SOC_PART_NUMBER_MCXE315MLF + bool + select SOC_MCXE315 + +config SOC_PART_NUMBER_MCXE315MPA + bool + select SOC_MCXE315 + +config SOC_PART_NUMBER_MCXE316MLF + bool + select SOC_MCXE316 + +config SOC_PART_NUMBER_MCXE316MPA + bool + select SOC_MCXE316 + +config SOC_PART_NUMBER_MCXE317MPA + bool + select SOC_MCXE317 + +config SOC_PART_NUMBER_MCXE317MPB + bool + select SOC_MCXE317 + +config SOC_PART_NUMBER_MCXE31BMPB + bool + select SOC_MCXE31B + +config SOC_PART_NUMBER + default "MCXE315MLF" if SOC_PART_NUMBER_MCXE315MLF + default "MCXE315MPA" if SOC_PART_NUMBER_MCXE315MPA + default "MCXE316MLF" if SOC_PART_NUMBER_MCXE316MLF + default "MCXE316MPA" if SOC_PART_NUMBER_MCXE316MPA + default "MCXE317MPA" if SOC_PART_NUMBER_MCXE317MPA + default "MCXE317MPB" if SOC_PART_NUMBER_MCXE317MPB + default "MCXE31BMPB" if SOC_PART_NUMBER_MCXE31BMPB diff --git a/soc/nxp/mcx/mcxe/mcxe31x/boot_header.ld b/soc/nxp/mcx/mcxe/mcxe31x/boot_header.ld new file mode 100644 index 0000000000000..129d7db81af3c --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/boot_header.ld @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +. += CONFIG_BOOT_HEADER_OFFSET - (. - __rom_start_address); +KEEP(*(.boot_header)) diff --git a/soc/nxp/mcx/mcxe/mcxe31x/itcm.ld b/soc/nxp/mcx/mcxe/mcxe31x/itcm.ld new file mode 100644 index 0000000000000..a3bc678710315 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/itcm.ld @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.itcm_text,,) +{ + . = ALIGN(4); + _itcm_text_start = .; + KEEP(*(.itcm_text)) + _itcm_text_end = .; +} GROUP_LINK_IN(ITCM) diff --git a/soc/nxp/mcx/mcxe/mcxe31x/mcxe31x_soc_initialization.S b/soc/nxp/mcx/mcxe/mcxe31x/mcxe31x_soc_initialization.S new file mode 100644 index 0000000000000..44f3617569de8 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/mcxe31x_soc_initialization.S @@ -0,0 +1,115 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define MC_RGM_BASE DT_REG_ADDR(DT_NODELABEL(mc_rgm)) +#define MC_RGM_DES 0x0 +#define MC_RGM_FES 0x8 + +_ASM_FILE_PROLOGUE + +GTEXT(soc_reset_hook) + +SECTION_FUNC(TEXT, soc_reset_hook) + + /* + * On destructive reset, SRAM and TCM memories must be initialized to a known value using a + * 64-bit master before 32-bit masters 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. + */ + + /* If we come from a destructive reset, then ignore functional reset flags */ + ldr r1, =MC_RGM_BASE + ldr r2, [r1, MC_RGM_DES] + cmp r2, 0x0 + bne ECC_INIT + ldr r2, [r1, MC_RGM_FES] + cmp r2, 0x0 + bne ECC_END + +ECC_INIT: + ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) + ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) + + subs r2, #1 + + ble SRAM_LOOP_END + + movs r0, 0 + movs r3, 0 + +SRAM_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge SRAM_LOOP + +SRAM_LOOP_END: + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) + + ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) + ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) + + subs r2, #1 + +ITCM_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge ITCM_LOOP +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) + + ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) + ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) + + subs r2, #1 + +DTCM_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge DTCM_LOOP +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(itcm1), okay) + + ldr r1, = DT_REG_ADDR(DT_NODELABEL(itcm1)) + ldr r2, = DT_REG_SIZE(DT_NODELABEL(itcm1)) + + subs r2, #1 + +ITCM1_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge ITCM1_LOOP +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(dtcm1), okay) + + ldr r1, = DT_REG_ADDR(DT_NODELABEL(dtcm1)) + ldr r2, = DT_REG_SIZE(DT_NODELABEL(dtcm1)) + + subs r2, #1 + +DTCM1_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge DTCM1_LOOP +#endif + +ECC_END: + /* save lr value to r4 */ + mov r4, lr + /* Jump to SystemInit function*/ + bl SystemInit + mov lr, r4 + bx lr diff --git a/soc/nxp/mcx/mcxe/mcxe31x/pinctrl_soc.h b/soc/nxp/mcx/mcxe/mcxe31x/pinctrl_soc.h new file mode 100644 index 0000000000000..9f1b56c5d9d68 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/pinctrl_soc.h @@ -0,0 +1,32 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_NXP_MCXE31X_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_NXP_MCXE31X_PINCTRL_SOC_H_ + +#include +#include +#include + +#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_MCXE31X_PINCTRL_SOC_H_ */ diff --git a/soc/nxp/mcx/mcxe/mcxe31x/soc.c b/soc/nxp/mcx/mcxe/mcxe31x/soc.c new file mode 100644 index 0000000000000..c7a2ebeddbd22 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/soc.c @@ -0,0 +1,40 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for nxp_mcxe platform + * + * This module provides routines to initialize and support board-level + * hardware for the nxp_mcxe platform. + */ + +#include +#include +#include +#include +#include "soc.h" + +/** + * + * @brief Perform basic hardware initialization + * + * Initialize the interrupt controller device drivers. + * Also initialize the counter device driver, if required. + * + * @return 0 + */ +void soc_early_init_hook(void) +{ +#ifdef CONFIG_SOC_MCXE31B + enable_sram_extra_latency(true); +#else + enable_sram_extra_latency(false); +#endif + /* Enable I/DCache */ + sys_cache_instr_enable(); + sys_cache_data_enable(); +} diff --git a/soc/nxp/mcx/mcxe/mcxe31x/soc.h b/soc/nxp/mcx/mcxe/mcxe31x/soc.h new file mode 100644 index 0000000000000..b8f35cb7aa46e --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/soc.h @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#ifndef _ASMLANGUAGE + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void enable_sram_extra_latency(bool en); + +#ifdef __cplusplus +} +#endif + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC__H_ */ diff --git a/soc/nxp/mcx/mcxe/mcxe31x/sram_config.c b/soc/nxp/mcx/mcxe/mcxe31x/sram_config.c new file mode 100644 index 0000000000000..c3f01a48911a3 --- /dev/null +++ b/soc/nxp/mcx/mcxe/mcxe31x/sram_config.c @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "fsl_common.h" + +/* Don't access system RAM when configuring PRAM FT_DIS. */ +void enable_sram_extra_latency(bool en) +{ + if (en) { + /* Configure SRAM read wait states. */ + PRAMC_0->PRCR1 |= PRAMC_PRCR1_FT_DIS_MASK; +#if defined(PRAMC_1) + PRAMC_1->PRCR1 |= PRAMC_PRCR1_FT_DIS_MASK; +#endif + } else { + PRAMC_0->PRCR1 &= ~PRAMC_PRCR1_FT_DIS_MASK; +#if defined(PRAMC_1) + PRAMC_1->PRCR1 &= ~PRAMC_PRCR1_FT_DIS_MASK; +#endif + } +} diff --git a/soc/nxp/mcx/mcxn/Kconfig.defconfig b/soc/nxp/mcx/mcxn/Kconfig.defconfig index 777acbf757d5e..ed99e7651973f 100644 --- a/soc/nxp/mcx/mcxn/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxn/Kconfig.defconfig @@ -10,7 +10,7 @@ config MFD default y if DT_HAS_NXP_LP_FLEXCOMM_ENABLED config NUM_IRQS - default 155 + default 156 config ROM_START_OFFSET default 0x400 if BOOTLOADER_MCUBOOT diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig index ecf76e22c7157..3b260c2abb4fd 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig @@ -4,12 +4,16 @@ if SOC_SERIES_MCXW2XX +config CORTEX_M_SYSTICK + default n if MCUX_OS_TIMER + config NUM_IRQS default 63 DT_SYSCLK_PATH := $(dt_nodelabel_path,sysclk) config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 if MCUX_OS_TIMER default $(dt_node_int_prop_int,$(DT_SYSCLK_PATH),clock-frequency) if CORTEX_M_SYSTICK # Set to the minimal size of data which can be written. diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c index 8e91dcec8338b..5e57268f2e040 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c +++ b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c @@ -96,6 +96,12 @@ __weak void clock_init(void) DT_FOREACH_STATUS_OKAY(nxp_ctimer_pwm, CTIMER_CLOCK_SETUP) 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 */ + PMC->OSTIMERr &= ~PMC_OSTIMER_OSTIMERCLKSEL_MASK; + PMC->OSTIMERr |= OSTIMERCLKSEL_FRO_1MHz << PMC_OSTIMER_OSTIMERCLKSEL_SHIFT; +#endif } #ifdef CONFIG_SOC_RESET_HOOK diff --git a/soc/nxp/mcx/soc.yml b/soc/nxp/mcx/soc.yml index 23bce577c193a..de513776a4c8e 100644 --- a/soc/nxp/mcx/soc.yml +++ b/soc/nxp/mcx/soc.yml @@ -16,6 +16,21 @@ family: - name: mcxc142 - name: mcxc242 - name: mcxc444 +- name: mcxe + series: + - name: mcxe24x + socs: + - name: mcxe245 + - name: mcxe246 + - name: mcxe247 +- name: mcxe + series: + - name: mcxe31x + socs: + - name: mcxe315 + - name: mcxe316 + - name: mcxe317 + - name: mcxe31b - name: mcxa socs: - name: mcxa153 @@ -23,6 +38,7 @@ family: - name: mcxa346 - name: mcxa266 - name: mcxa366 + - name: mcxa344 - name: mcxw series: - name: mcxw2xx @@ -70,6 +86,8 @@ runners: - mcxw716c - qualifiers: - mcxw236 + - qualifiers: + - mcxa344 '--reset': - run: last runners: @@ -102,3 +120,5 @@ runners: - mcxw716c - qualifiers: - mcxw236 + - qualifiers: + - mcxa344 diff --git a/soc/nxp/s32/s32k3/mpu_regions.c b/soc/nxp/s32/s32k3/mpu_regions.c index 948e28bcab7ea..10e9de27b3b0b 100644 --- a/soc/nxp/s32/s32k3/mpu_regions.c +++ b/soc/nxp/s32/s32k3/mpu_regions.c @@ -6,7 +6,7 @@ #include #include -#include +#include #if !defined(CONFIG_XIP) extern char _rom_attr[]; diff --git a/soc/renesas/ra/ra8p1/Kconfig.defconfig b/soc/renesas/ra/ra8p1/Kconfig.defconfig index 27ef391a9080a..23e976fd3002c 100644 --- a/soc/renesas/ra/ra8p1/Kconfig.defconfig +++ b/soc/renesas/ra/ra8p1/Kconfig.defconfig @@ -39,4 +39,12 @@ config DCACHE config CACHE_MANAGEMENT default n +if ETHOS_U + +choice ETHOS_U_NPU_CONFIG + default ETHOS_U55_256 +endchoice + +endif # ETHOS_U + endif # SOC_SERIES_RA8P1 diff --git a/soc/renesas/rx/rx130/CMakeLists.txt b/soc/renesas/rx/rx130/CMakeLists.txt index 44936565508f6..1a707b29571fc 100644 --- a/soc/renesas/rx/rx130/CMakeLists.txt +++ b/soc/renesas/rx/rx130/CMakeLists.txt @@ -11,3 +11,7 @@ zephyr_linker_sources(SECTIONS ofsm.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/rx/linker.ld CACHE INTERNAL "") + +zephyr_sources_ifdef(CONFIG_PM + power.c +) diff --git a/soc/renesas/rx/rx130/Kconfig b/soc/renesas/rx/rx130/Kconfig index 66f481b78cf8a..161a2071447ea 100644 --- a/soc/renesas/rx/rx130/Kconfig +++ b/soc/renesas/rx/rx130/Kconfig @@ -9,6 +9,7 @@ config SOC_SERIES_RX130 select HAS_RENESAS_RX_RDP select CLOCK_CONTROL select SOC_EARLY_INIT_HOOK + select HAS_PM if SOC_SERIES_RX130 if WDT_RENESAS_RX_IWDT_AUTO_START_MODE diff --git a/soc/renesas/rx/rx130/power.c b/soc/renesas/rx/rx130/power.c new file mode 100644 index 0000000000000..56fb9f76560b2 --- /dev/null +++ b/soc/renesas/rx/rx130/power.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_RENESAS_RX_DTC +#include +#endif + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +#ifdef CONFIG_RENESAS_RX_DTC +static const struct device *const dtc = DEVICE_DT_GET(DT_NODELABEL(dtc)); +#endif + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + int err = 0; + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + err = R_LPC_LowPowerModeConfigure(LPC_LP_SLEEP); + if (err) { + LOG_DBG("LPC config failed %d", err); + } + err = R_LPC_LowPowerModeActivate(FIT_NO_FUNC); + if (err) { + LOG_DBG("LPC active failed %d", err); + } + break; + case PM_STATE_STANDBY: +#ifdef CONFIG_RENESAS_RX_DTC + err = dtc_renesas_rx_off(dtc); + if (err) { + LOG_DBG("turn off module DTC failed %d", err); + } +#endif + err = R_LPC_LowPowerModeConfigure(LPC_LP_DEEP_SLEEP); + if (err) { + LOG_DBG("LPC config failed %d", err); + } + err = R_LPC_LowPowerModeActivate(FIT_NO_FUNC); + if (err) { + LOG_DBG("LPC active failed %d", err); + } + break; + default: + LOG_DBG("Unsupported power state %u", state); + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + if (state == PM_STATE_STANDBY) { +#ifdef CONFIG_RENESAS_RX_DTC + int err = dtc_renesas_rx_on(dtc); + + if (err) { + LOG_DBG("turn off module DTC failed %d", err); + } +#endif + } +} diff --git a/soc/renesas/rz/rza3ul/mmu_regions.c b/soc/renesas/rz/rza3ul/mmu_regions.c index 3f07572e5804a..20c39e69dd7af 100644 --- a/soc/renesas/rz/rza3ul/mmu_regions.c +++ b/soc/renesas/rz/rza3ul/mmu_regions.c @@ -10,6 +10,10 @@ static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_FLAT_ENTRY("IO_REG", 0x10000000, 0x10000000, MT_DEVICE_nGnRnE | MT_RW | MT_DEFAULT_SECURE_STATE), + MMU_REGION_FLAT_ENTRY("SPI Multi Area", 0x20000000, 0x10000000, + MT_NORMAL | MT_RW | MT_DEFAULT_SECURE_STATE), + MMU_REGION_FLAT_ENTRY("SRAM", 0x00000000, 0x00200000, + MT_NORMAL | MT_RW | MT_DEFAULT_SECURE_STATE), }; const struct arm_mmu_config mmu_config = { diff --git a/soc/renesas/rz/rza3ul/sections.ld b/soc/renesas/rz/rza3ul/sections.ld index bdc29c67e39d2..ad475214f901f 100644 --- a/soc/renesas/rz/rza3ul/sections.ld +++ b/soc/renesas/rz/rza3ul/sections.ld @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -SECTION_PROLOGUE(.header, CONFIG_FLASH_BASE_ADDRESS,) +SECTION_PROLOGUE(.header, CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET,) { QUAD(__start) QUAD(0xFFFFFFFFFFFFFFFF-__start) diff --git a/soc/renode/cortex_r8_virtual/arm_mpu_regions.c b/soc/renode/cortex_r8_virtual/arm_mpu_regions.c index 6a9ea54ed352c..6325a7957d3c8 100644 --- a/soc/renode/cortex_r8_virtual/arm_mpu_regions.c +++ b/soc/renode/cortex_r8_virtual/arm_mpu_regions.c @@ -6,7 +6,7 @@ */ #include -#include +#include extern const uint32_t __rom_region_start; extern const uint32_t __rom_region_mpu_size_bits; diff --git a/soc/silabs/Kconfig b/soc/silabs/Kconfig index 1bc6ca673f993..b752b3a4b9712 100644 --- a/soc/silabs/Kconfig +++ b/soc/silabs/Kconfig @@ -4,163 +4,33 @@ rsource "*/Kconfig" -if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 +if SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 -config SOC_GECKO_BURTC - bool - help - Set if the Back-Up Real Time Counter (BURTC) HAL module is used. - -config SOC_GECKO_CORE - bool - default y - help - Set if the Core interrupt handling (CORE) HAL module is used. - -config SOC_SILABS_ACMP - bool - help - Set if the Analog comparator (ACMP) HAL module is used. - -config SOC_GECKO_ADC - bool - help - Set if the Analog to Digital Converter (ADC) HAL module is used. - -config SOC_GECKO_IADC - bool - help - Set if the Incremental Analog to Digital Converter (IADC) HAL module is used. - -config SOC_GECKO_CRYOTIMER - bool - help - Set if the Ultra Low Energy Timer/Counter (CRYOTIMER) HAL module is used. - -config SOC_GECKO_EMU - bool - help - Set if the Energy Management Unit (EMU) HAL module is used. - -config SOC_GECKO_GPIO - bool - help - Set if the General Purpose Input/Output (GPIO) HAL module is used. - -config SOC_GECKO_I2C - bool - help - Set if the Inter-Integrated Circuit Interface (I2C) HAL module is used. - -config SOC_GECKO_LETIMER - bool - help - Set if the Low Energy Timer (LETIMER) HAL module is used. - -config SOC_GECKO_LEUART - bool - help - Set if the Low Energy Universal Asynchronous Receiver/Transmitter (LEUART) - HAL module is used. - -config SOC_GECKO_LDMA - bool - help - Set if the Linked Direct Memory Access (LDMA) HAL module is used. - -config SOC_GECKO_MSC - bool - help - Set if the Memory System Controller (MSC) HAL module is used. - -config SOC_GECKO_PRS - bool - help - Set if the Peripheral Reflex System (PRS) HAL module is used. - -config SOC_GECKO_RMU - bool - help - Set if the Reset Management Unit (RMU) HAL module is used. - -config SOC_GECKO_RTC - bool - help - Set if the Real Time Counter (RTC) HAL module is used. - -config SOC_GECKO_RTCC - bool - help - Set if the Real Time Counter and Calendar (RTCC) HAL module is used. - -config SOC_GECKO_SE - bool - help - Set if the Secure Element (SE) HAL module is used. - -config SOC_GECKO_TIMER - bool - help - Set if the Timer/Counter (TIMER) HAL module is used. - -config SOC_GECKO_USART - bool - help - Set if the Universal Synchronous Asynchronous Receiver/Transmitter (USART) - HAL module is used. - -config SOC_GECKO_EUSART - bool - help - Set if the Extended Universal Synchronous Asynchronous Receiver/Transmitter (EUSART) - HAL module is used. - -config SOC_GECKO_WDOG - bool - help - Set if the Watchdog Timer (WDOG) HAL module is used. - -config SOC_GECKO_TRNG - bool - help - Set if the SoC has a True Random Number Generator (TRNG) module. - -config SOC_SILABS_SLEEPTIMER - bool - select SOC_GECKO_PRS - select SOC_GECKO_RTCC if SOC_FAMILY_SILABS_S2 && $(dt_nodelabel_enabled,rtcc0) - help - Set if the Sleeptimer HAL module is used. - -config SOC_SILABS_HFXO_MANAGER +config SOC_GECKO_HAS_RADIO bool - default y if PM && $(dt_nodelabel_enabled,sysrtc0) && $(dt_nodelabel_enabled,hfxo) help - Set if the HFXO Manager HAL module is used. - -if PM + If enabled, indicates that the SoC has a Radio PHY. -config SOC_GECKO_PM_BACKEND_PMGR - bool - depends on SOC_GECKO_DEV_INIT - default y if SOC_FAMILY_SILABS_S2 +config SOC_GECKO_USE_RAIL + bool "Use RAIL (Radio Abstraction Interface Layer)" + depends on SOC_GECKO_HAS_RADIO help - Implement PM using sl_power_manager service from Gecko SDK + RAIL (Radio Abstraction Interface Layer) is a library needed to use the EFR radio + hardware. This option enable the proper set of features to allow to properly compile + with the RAIL blob. -config SOC_GECKO_PM_BACKEND_EMU - bool - default y if !SOC_GECKO_PM_BACKEND_PMGR +config SOC_GECKO_CUSTOM_RADIO_PHY + bool "Use RAIL for custom radio phy packet sending and receiving" + depends on SOC_GECKO_HAS_RADIO + select SOC_GECKO_USE_RAIL help - Implement PM using direct calls to EMU driver in emlib + If enabled, RAIL can be used for user generated custom radio phy + management, sending and receiving packets on radio phy. User has + to provide the radio_config.c and radio_config.h files for the phy. -config SOC_SILABS_PM_LOW_INTERRUPT_LATENCY - bool "Low interrupt latency mode" - default y if SOC_GECKO_PM_BACKEND_PMGR - help - Enabling low interrupt latency allows interrupts to be executed - before the high frequency clock is restored after sleep. +endif # SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 -endif # PM +if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 config SOC_GECKO_EMU_DCDC bool "SoC DC/DC regulator" @@ -187,35 +57,6 @@ choice SOC_GECKO_EMU_DCDC_MODE bool "Bypass" endchoice -config CRYPTO_ACC_GECKO_TRNG - bool - help - Enable Entropy driver based on the CRYPTO_ACC module for Silicon Labs - Gecko chips. - -config SOC_GECKO_DEV_INIT - bool - help - Use the device initialization routines from the device_init service - in Silicon Labs HAL. These routines initialize and tune HFXOs, - configures DPLLs and manages the Energy Management Unit. - - Disabling these services may negatively impact counter and timer - routines in Silabs SoCs. - -config COUNTER_GECKO_STIMER - bool - help - Enable counter driver based on the Sleep Timer driver for Silicon Labs - Gecko chips. - -config SOC_GECKO_CMU - bool - help - Set if the clock management unit (CMU) is present in the SoC. - -if SOC_GECKO_CMU && (SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1) - config CMU_NEED_LFXO bool help @@ -269,8 +110,6 @@ config CMU_HFRCO_FREQ the bootloader already configured it properly or the device's default clock source should be used with it's default configuration. -endif # SOC_GECKO_CMU - config SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION bool help @@ -295,26 +134,4 @@ config SOC_GECKO_HAS_HFRCO_FREQRANGE If disabled, indicates that configuration of HFRCO frequency for corresponding SOC is not supported via this field. This is the case for e.g. efm32hg, efm32wg series. -config SOC_GECKO_HAS_RADIO - bool - help - If enabled, indicates that the SoC has a Radio PHY. - -config SOC_GECKO_USE_RAIL - bool "Use RAIL (Radio Abstraction Interface Layer)" - depends on SOC_GECKO_HAS_RADIO - help - RAIL (Radio Abstraction Interface Layer) is a library needed to use the EFR radio - hardware. This option enable the proper set of features to allow to properly compile - with the RAIL blob. - -config SOC_GECKO_CUSTOM_RADIO_PHY - bool "Use RAIL for custom radio phy packet sending and receiving" - depends on SOC_GECKO_HAS_RADIO - select SOC_GECKO_USE_RAIL - help - If enabled, RAIL can be used for user generated custom radio phy - management, sending and receiving packets on radio phy. User has - to provide the radio_config.c and radio_config.h files for the phy. - -endif # SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 +endif # SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 diff --git a/soc/silabs/Kconfig.defconfig b/soc/silabs/Kconfig.defconfig index a2cf6b7b26dc4..8e08c1667331f 100644 --- a/soc/silabs/Kconfig.defconfig +++ b/soc/silabs/Kconfig.defconfig @@ -3,7 +3,7 @@ rsource "*/Kconfig.defconfig" -if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 +if SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 config SOC_GECKO_EMU default y @@ -13,22 +13,4 @@ config SOC_GECKO_EMU config CORTEX_M_SYSTICK default n if GECKO_BURTC_TIMER -# With sl_power_manager, pm_state_set()'s stack footrpting is noticeably -# large, especially with logs enabled. Since it is called from IDLE task, -# its stack size has to be increased -config IDLE_STACK_SIZE - default 512 if SOC_GECKO_PM_BACKEND_PMGR - -configdefault NUM_METAIRQ_PRIORITIES - default 1 if BT_SILABS_EFR32 - -if BT_LONG_WQ -configdefault BT_LONG_WQ_STACK_SIZE - # Hidden config item. We require a slightly larger stack than the - # default values are. As of this writing, we have a bit less than - # 200 bytes of headroom for future increases here, before we hit - # the limit again. - default 1600 if BT_ECC -endif - endif diff --git a/soc/silabs/common/CMakeLists.txt b/soc/silabs/common/CMakeLists.txt index e19ac55906181..3782f46ccf5d7 100644 --- a/soc/silabs/common/CMakeLists.txt +++ b/soc/silabs/common/CMakeLists.txt @@ -2,10 +2,12 @@ if(CONFIG_SOC_FAMILY_SILABS_S0 OR CONFIG_SOC_FAMILY_SILABS_S1) zephyr_sources(soc.c) + zephyr_sources_ifdef(CONFIG_PM soc_power.c) endif() -zephyr_sources_ifdef(CONFIG_SOC_GECKO_PM_BACKEND_EMU soc_power.c) -zephyr_sources_ifdef(CONFIG_SOC_GECKO_PM_BACKEND_PMGR soc_power_pmgr.c) +if(CONFIG_SOC_FAMILY_SILABS_S2) + zephyr_sources_ifdef(CONFIG_PM soc_power_pmgr.c) +endif() zephyr_include_directories(.) diff --git a/soc/silabs/silabs_s2/Kconfig b/soc/silabs/silabs_s2/Kconfig index c617183644a14..4f03a01b339ae 100644 --- a/soc/silabs/silabs_s2/Kconfig +++ b/soc/silabs/silabs_s2/Kconfig @@ -23,6 +23,21 @@ config SOC_SILABS_IMAGE_PROPERTIES verify the application. If Gecko bootloader is used, the Zephyr application image also needs the data structure. +config CRYPTO_ACC_GECKO_TRNG + bool + help + Enable Entropy driver based on the CRYPTO_ACC module for Silicon Labs + Gecko chips. + +if PM +config SOC_SILABS_PM_LOW_INTERRUPT_LATENCY + bool "Low interrupt latency mode" + default y + help + Enabling low interrupt latency allows interrupts to be executed + before the high frequency clock is restored after sleep. +endif + rsource "*/Kconfig" config ARM_SECURE_FIRMWARE diff --git a/soc/silabs/silabs_s2/Kconfig.defconfig b/soc/silabs/silabs_s2/Kconfig.defconfig index 339b1df67783c..32f6fbc214ce9 100644 --- a/soc/silabs/silabs_s2/Kconfig.defconfig +++ b/soc/silabs/silabs_s2/Kconfig.defconfig @@ -33,4 +33,28 @@ configdefault ZERO_LATENCY_IRQS configdefault ZERO_LATENCY_LEVELS default 2 +configdefault SILABS_SISDK_HFXO_MANAGER + default y if PM && $(dt_nodelabel_enabled,sysrtc0) && $(dt_nodelabel_enabled,hfxo) + +configdefault SILABS_SISDK_POWER_MANAGER + default y if PM + +# With sl_power_manager, pm_state_set()'s stack footprint is noticeably +# large, especially with logs enabled. Since it is called from IDLE task, +# its stack size has to be increased +configdefault IDLE_STACK_SIZE + default 512 if PM + +configdefault NUM_METAIRQ_PRIORITIES + default 1 if BT_SILABS_EFR32 + +if BT_LONG_WQ +configdefault BT_LONG_WQ_STACK_SIZE + # Hidden config item. We require a slightly larger stack than the + # default values are. As of this writing, we have a bit less than + # 200 bytes of headroom for future increases here, before we hit + # the limit again. + default 1600 if BT_ECC +endif + endif diff --git a/soc/silabs/silabs_s2/soc.c b/soc/silabs/silabs_s2/soc.c index 95d6c78c58282..f9af455d8452b 100644 --- a/soc/silabs/silabs_s2/soc.c +++ b/soc/silabs/silabs_s2/soc.c @@ -34,7 +34,7 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); -#if defined(CONFIG_SOC_SILABS_HFXO_MANAGER) +#if defined(CONFIG_SILABS_SISDK_HFXO_MANAGER) Z_ISR_DECLARE_DIRECT(DT_IRQ(DT_NODELABEL(hfxo), irq), 0, sl_hfxo_manager_irq_handler); #endif @@ -48,7 +48,7 @@ void soc_early_init_hook(void) } sl_clock_manager_init(); - if (IS_ENABLED(CONFIG_SOC_SILABS_HFXO_MANAGER)) { + if (IS_ENABLED(CONFIG_SILABS_SISDK_HFXO_MANAGER)) { sl_hfxo_manager_init_hardware(); sl_hfxo_manager_init(); } diff --git a/soc/silabs/silabs_s2/xg21/Kconfig b/soc/silabs/silabs_s2/xg21/Kconfig index eb393c3c7d1b9..23ceb71eb2ea3 100644 --- a/soc/silabs/silabs_s2/xg21/Kconfig +++ b/soc/silabs/silabs_s2/xg21/Kconfig @@ -3,20 +3,19 @@ config SOC_SILABS_XG21 select ARM - select CPU_CORTEX_M33 - select CPU_CORTEX_M_HAS_DWT - select ARMV8_M_DSP select ARM_TRUSTZONE_M - select CPU_HAS_FPU + select ARMV8_M_DSP + select CPU_CORTEX_M_HAS_DWT + select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU - select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_EMU - select SOC_GECKO_GPIO - select SOC_GECKO_DEV_INIT - select SOC_GECKO_SE + select CPU_HAS_FPU select HAS_PM + select HAS_SWO + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32MG21 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg22/Kconfig b/soc/silabs/silabs_s2/xg22/Kconfig index 3d8fc9d6a3ba6..9de819b5fac28 100644 --- a/soc/silabs/silabs_s2/xg22/Kconfig +++ b/soc/silabs/silabs_s2/xg22/Kconfig @@ -3,20 +3,18 @@ config SOC_SILABS_XG22 select ARM - select ARMV8_M_DSP select ARM_TRUSTZONE_M + select ARMV8_M_DSP select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU - select HAS_SWO - select SOC_GECKO_GPIO - select SOC_GECKO_CMU - select SOC_GECKO_EMU - select SOC_GECKO_CORE - select SOC_GECKO_DEV_INIT - select SOC_GECKO_SE select HAS_PM + select HAS_SWO + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32BG22 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg23/Kconfig b/soc/silabs/silabs_s2/xg23/Kconfig index d52bff007194c..45181d163dd24 100644 --- a/soc/silabs/silabs_s2/xg23/Kconfig +++ b/soc/silabs/silabs_s2/xg23/Kconfig @@ -3,21 +3,19 @@ config SOC_SILABS_XG23 select ARM - select ARMV8_M_DSP select ARM_TRUSTZONE_M - select CPU_CORTEX_M33 + select ARMV8_M_DSP select CPU_CORTEX_M_HAS_DWT + select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU select HAS_PM select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_CORE - select SOC_GECKO_DEV_INIT - select SOC_GECKO_EMU - select SOC_GECKO_GPIO - select SOC_GECKO_SE + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32ZG23 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg24/Kconfig b/soc/silabs/silabs_s2/xg24/Kconfig index e42474c1d4857..952afdbb91df6 100644 --- a/soc/silabs/silabs_s2/xg24/Kconfig +++ b/soc/silabs/silabs_s2/xg24/Kconfig @@ -5,20 +5,19 @@ config SOC_SILABS_XG24 select ARM + select ARM_TRUSTZONE_M + select ARMV8_M_DSP + select CPU_CORTEX_M_HAS_DWT select CPU_CORTEX_M33 - select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU - select CPU_CORTEX_M_HAS_DWT - select ARMV8_M_DSP - select ARM_TRUSTZONE_M - select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_EMU - select SOC_GECKO_GPIO - select SOC_GECKO_DEV_INIT - select SOC_GECKO_SE + select CPU_HAS_FPU select HAS_PM + select HAS_SWO + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32MG24 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg27/Kconfig b/soc/silabs/silabs_s2/xg27/Kconfig index 0e277ab26d40d..e9c30461807e4 100644 --- a/soc/silabs/silabs_s2/xg27/Kconfig +++ b/soc/silabs/silabs_s2/xg27/Kconfig @@ -3,20 +3,18 @@ config SOC_SILABS_XG27 select ARM - select ARMV8_M_DSP select ARM_TRUSTZONE_M + select ARMV8_M_DSP select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU - select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_GPIO - select SOC_GECKO_CORE - select SOC_GECKO_DEV_INIT - select SOC_GECKO_EMU - select SOC_GECKO_SE select HAS_PM + select HAS_SWO + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32BG27 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg28/Kconfig b/soc/silabs/silabs_s2/xg28/Kconfig index 397a62e8ccc93..214ea020ed6d9 100644 --- a/soc/silabs/silabs_s2/xg28/Kconfig +++ b/soc/silabs/silabs_s2/xg28/Kconfig @@ -3,21 +3,19 @@ config SOC_SILABS_XG28 select ARM - select ARMV8_M_DSP select ARM_TRUSTZONE_M - select CPU_CORTEX_M33 + select ARMV8_M_DSP select CPU_CORTEX_M_HAS_DWT + select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU select HAS_PM select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_CORE - select SOC_GECKO_DEV_INIT - select SOC_GECKO_EMU - select SOC_GECKO_GPIO - select SOC_GECKO_SE + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32ZG28 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg29/Kconfig b/soc/silabs/silabs_s2/xg29/Kconfig index 58fe9f42a7de3..c462750cb3b90 100644 --- a/soc/silabs/silabs_s2/xg29/Kconfig +++ b/soc/silabs/silabs_s2/xg29/Kconfig @@ -3,20 +3,19 @@ config SOC_SILABS_XG29 select ARM + select ARM_TRUSTZONE_M + select ARMV8_M_DSP + select CPU_CORTEX_M_HAS_DWT select CPU_CORTEX_M33 - select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU - select CPU_CORTEX_M_HAS_DWT - select ARMV8_M_DSP - select ARM_TRUSTZONE_M - select HAS_SWO - select SOC_GECKO_CMU - select SOC_GECKO_EMU - select SOC_GECKO_GPIO - select SOC_GECKO_DEV_INIT - select SOC_GECKO_SE + select CPU_HAS_FPU select HAS_PM + select HAS_SWO + select SILABS_SISDK_CLOCK_MANAGER + select SILABS_SISDK_CORE + select SILABS_SISDK_DEVICE_INIT + select SILABS_SISDK_GPIO config SOC_SERIES_EFR32BG29 select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_siwx91x/Kconfig b/soc/silabs/silabs_siwx91x/Kconfig index 7deef76782dc8..4c2d53557cfb6 100644 --- a/soc/silabs/silabs_siwx91x/Kconfig +++ b/soc/silabs/silabs_siwx91x/Kconfig @@ -15,11 +15,6 @@ if SOC_FAMILY_SILABS_SIWX91X rsource "*/Kconfig" -config SOC_SILABS_SLEEPTIMER - bool - help - The Sleeptimer HAL module is used for SIWX91X. - config SILABS_SIWX91X_NWP bool "Silabs Network Coprocessor" depends on DT_HAS_SILABS_SIWX91X_NWP_ENABLED diff --git a/soc/st/stm32/stm32h7rsx/mpu_regions.c b/soc/st/stm32/stm32h7rsx/mpu_regions.c index 72995b85216e6..35dfce848cded 100644 --- a/soc/st/stm32/stm32h7rsx/mpu_regions.c +++ b/soc/st/stm32/stm32h7rsx/mpu_regions.c @@ -8,7 +8,7 @@ #include #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { /* Use first region to prevent speculative access in entire memory space */ diff --git a/soc/st/stm32/stm32h7x/mpu_regions.c b/soc/st/stm32/stm32h7x/mpu_regions.c index f77018d36caed..73eab5f1d7ad8 100644 --- a/soc/st/stm32/stm32h7x/mpu_regions.c +++ b/soc/st/stm32/stm32h7x/mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("FLASH", CONFIG_FLASH_BASE_ADDRESS, diff --git a/soc/ti/k3/am6x/r5/arm_mpu_regions.c b/soc/ti/k3/am6x/r5/arm_mpu_regions.c index 495224a0597b3..7b4357a4f39f6 100644 --- a/soc/ti/k3/am6x/r5/arm_mpu_regions.c +++ b/soc/ti/k3/am6x/r5/arm_mpu_regions.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include diff --git a/soc/xlnx/zynqmp/arm_mpu_regions.c b/soc/xlnx/zynqmp/arm_mpu_regions.c index 73fc8bdb073dc..57a3a2f07153b 100644 --- a/soc/xlnx/zynqmp/arm_mpu_regions.c +++ b/soc/xlnx/zynqmp/arm_mpu_regions.c @@ -5,7 +5,7 @@ */ #include -#include +#include extern const uint32_t __rom_region_start; extern const uint32_t __rom_region_mpu_size_bits; diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index 756214ad752d4..979fb92f5f442 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -41,7 +41,6 @@ add_subdirectory_ifdef(CONFIG_BINDESC bindesc) add_subdirectory_ifdef(CONFIG_BT bluetooth) add_subdirectory_ifdef(CONFIG_CONSOLE_SUBSYS console) add_subdirectory_ifdef(CONFIG_CPU_FREQ cpu_freq) -add_subdirectory_ifdef(CONFIG_CPU_LOAD_METRIC cpu_load) add_subdirectory_ifdef(CONFIG_CRC crc) add_subdirectory_ifdef(CONFIG_DAP dap) add_subdirectory_ifdef(CONFIG_DEMAND_PAGING demand_paging) diff --git a/subsys/Kconfig b/subsys/Kconfig index f35a0d1c90680..380c0e5d94439 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -12,7 +12,6 @@ source "subsys/bluetooth/Kconfig" source "subsys/canbus/Kconfig" source "subsys/console/Kconfig" source "subsys/cpu_freq/Kconfig" -source "subsys/cpu_load/Kconfig" source "subsys/crc/Kconfig" source "subsys/dap/Kconfig" source "subsys/debug/Kconfig" diff --git a/subsys/bluetooth/audio/bap_base.c b/subsys/bluetooth/audio/bap_base.c index 37d1f72b35e8c..4a7a08acbb7f5 100644 --- a/subsys/bluetooth/audio/bap_base.c +++ b/subsys/bluetooth/audio/bap_base.c @@ -101,6 +101,74 @@ static bool check_pull_ltv(struct net_buf_simple *net_buf) return true; } +static struct bt_bap_base_subgroup *base_pull_subgroup(struct net_buf_simple *net_buf, + uint8_t index) +{ + struct bt_bap_base_subgroup *subgroup = (struct bt_bap_base_subgroup *)net_buf->data; + uint8_t bis_count; + + if (net_buf->len < sizeof(bis_count)) { + LOG_DBG("Invalid BASE length when pulling bis_count: %u", net_buf->size); + + return NULL; + } + + bis_count = base_pull_bis_count(net_buf); + if (!IN_RANGE(bis_count, 1U, BT_ISO_MAX_GROUP_ISO_COUNT)) { + LOG_DBG("Subgroup[%u]: Invalid BIS count: %u", index, bis_count); + + return NULL; + } + + if (net_buf->len < BASE_CODEC_ID_SIZE) { + LOG_DBG("Invalid BASE length when pulling codec: %u", net_buf->size); + + return NULL; + } + + base_pull_codec_id(net_buf, NULL); + + /* Pull CC */ + if (!check_pull_ltv(net_buf)) { + LOG_DBG("Invalid BASE length when pulling CC LTV: %u", net_buf->size); + + return NULL; + } + + /* Pull meta */ + if (!check_pull_ltv(net_buf)) { + LOG_DBG("Invalid BASE length when pulling meta LTV: %u", net_buf->size); + + return NULL; + } + + for (uint8_t i = 0U; i < bis_count; i++) { + uint8_t bis_index; + + if (net_buf->len < sizeof(bis_index)) { + LOG_DBG("Invalid BASE length when pulling bis_index: %u", net_buf->size); + + return NULL; + } + + bis_index = net_buf_simple_pull_u8(net_buf); + if (!IN_RANGE(bis_index, 1U, BT_ISO_BIS_INDEX_MAX)) { + LOG_DBG("Subgroup[%u]: Invalid BIS index: %u", index, bis_index); + + return NULL; + } + + /* Pull BIS CC data */ + if (!check_pull_ltv(net_buf)) { + LOG_DBG("Invalid BASE length when pulling BIS CC LTV: %u", net_buf->size); + + return NULL; + } + } + + return subgroup; +} + const struct bt_bap_base *bt_bap_base_get_base_from_ad(const struct bt_data *ad) { struct bt_uuid_16 broadcast_uuid; @@ -155,66 +223,13 @@ const struct bt_bap_base *bt_bap_base_get_base_from_ad(const struct bt_data *ad) } for (uint8_t i = 0U; i < subgroup_count; i++) { - uint8_t bis_count; - - if (net_buf.len < sizeof(bis_count)) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } + const struct bt_bap_base_subgroup *subgroup = base_pull_subgroup(&net_buf, i); - bis_count = base_pull_bis_count(&net_buf); - if (!IN_RANGE(bis_count, 1U, BT_ISO_MAX_GROUP_ISO_COUNT)) { - LOG_DBG("Subgroup[%u]: Invalid BIS count: %u", i, bis_count); + if (subgroup == NULL) { + LOG_DBG("Subgroup[%u] is invalid", i); return NULL; } - - if (net_buf.len < BASE_CODEC_ID_SIZE) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } - - base_pull_codec_id(&net_buf, NULL); - - /* Pull CC */ - if (!check_pull_ltv(&net_buf)) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } - - /* Pull meta */ - if (!check_pull_ltv(&net_buf)) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } - - for (uint8_t j = 0U; j < bis_count; j++) { - uint8_t bis_index; - - if (net_buf.len < sizeof(bis_index)) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } - - bis_index = net_buf_simple_pull_u8(&net_buf); - if (!IN_RANGE(bis_index, 1U, BT_ISO_BIS_INDEX_MAX)) { - LOG_DBG("Subgroup[%u]: Invalid BIS index: %u", i, bis_index); - - return NULL; - } - - /* Pull BIS CC data */ - if (!check_pull_ltv(&net_buf)) { - LOG_DBG("Invalid BASE length: %u", ad->data_len); - - return NULL; - } - } } return base; @@ -312,7 +327,6 @@ int bt_bap_base_foreach_subgroup(const struct bt_bap_base *base, void *user_data), void *user_data) { - struct bt_bap_base_subgroup *subgroup; struct net_buf_simple net_buf; uint8_t subgroup_count; @@ -333,32 +347,18 @@ int bt_bap_base_foreach_subgroup(const struct bt_bap_base *base, subgroup_count = net_buf_simple_pull_u8(&net_buf); for (uint8_t i = 0U; i < subgroup_count; i++) { - subgroup = (struct bt_bap_base_subgroup *)net_buf.data; - if (!func(subgroup, user_data)) { - LOG_DBG("user stopped parsing"); + const struct bt_bap_base_subgroup *subgroup = base_pull_subgroup(&net_buf, i); - return -ECANCELED; - } - - /* Parse subgroup data to get next subgroup pointer */ - if (subgroup_count > 1) { /* Only parse data if it isn't the last one */ - uint8_t bis_count; - - bis_count = base_pull_bis_count(&net_buf); - base_pull_codec_id(&net_buf, NULL); - - /* Codec config */ - base_pull_ltv(&net_buf, NULL); + if (subgroup == NULL) { + LOG_DBG("Subgroup[%u] is invalid", i); - /* meta */ - base_pull_ltv(&net_buf, NULL); + return -EINVAL; + } - for (uint8_t j = 0U; j < bis_count; j++) { - net_buf_simple_pull_u8(&net_buf); /* index */ + if (!func(subgroup, user_data)) { + LOG_DBG("user stopped parsing"); - /* Codec config */ - base_pull_ltv(&net_buf, NULL); - } + return -ECANCELED; } } diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 0e85437f3def3..df800f6a2bfcd 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -725,12 +725,24 @@ config BT_SMP_USB_HCI_CTLR_WORKAROUND if the keys are distributed over an encrypted link. config BT_FIXED_PASSKEY - bool "Use a fixed passkey for pairing" + bool "Use a fixed passkey for pairing [DEPRECATED]" + select DEPRECATED help + This option is deprecated, use BT_APP_PASSKEY instead. With this option enabled, the application will be able to call the bt_passkey_set() API to set a fixed passkey. If set, the pairing_confirm() callback will be called for all incoming pairings. +config BT_APP_PASSKEY + bool "Allow the application to provide passkeys for pairing" + depends on !BT_FIXED_PASSKEY + help + With this option enabled, the application will be able to provide passkeys for pairing + using the app_passkey() callback. If the application does not provide a passkey, a + random passkey will be generated by the Host. + + WARNING: It is the responsibility of the application to use random and unique keys. + config BT_USE_DEBUG_KEYS bool "Security Manager Debug Mode" help diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index bdf74f47aa84b..77dc28345987f 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -187,11 +187,9 @@ static struct bt_le_ext_adv adv_pool[CONFIG_BT_EXT_ADV_MAX_ADV_SET]; #if defined(CONFIG_BT_EXT_ADV) uint8_t bt_le_ext_adv_get_index(struct bt_le_ext_adv *adv) { - ptrdiff_t index = adv - adv_pool; + __ASSERT(IS_ARRAY_ELEMENT(adv_pool, adv), "Invalid bt_adv pointer"); - __ASSERT(index >= 0 && index < ARRAY_SIZE(adv_pool), - "Invalid bt_adv pointer"); - return (uint8_t)index; + return (uint8_t)ARRAY_INDEX(adv_pool, adv); } static struct bt_le_ext_adv *adv_new(void) @@ -1178,6 +1176,9 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, atomic_set_bit_to(adv->flags, BT_ADV_EXT_ADV, param->options & BT_LE_ADV_OPT_EXT_ADV); + atomic_set_bit_to(adv->flags, BT_ADV_RANDOM_ADDR_UPDATED, + own_addr_type == BT_HCI_OWN_ADDR_RANDOM); + return 0; } @@ -1507,11 +1508,13 @@ int bt_le_ext_adv_start(struct bt_le_ext_adv *adv, if (atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) { if (IS_ENABLED(CONFIG_BT_PRIVACY) && - !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) { + !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) && + !atomic_test_and_clear_bit(adv->flags, BT_ADV_RANDOM_ADDR_UPDATED)) { bt_id_set_adv_private_addr(adv); } } else { - if (!atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) { + if (!atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) && + !atomic_test_and_clear_bit(adv->flags, BT_ADV_RANDOM_ADDR_UPDATED)) { bt_id_set_adv_private_addr(adv); } } diff --git a/subsys/bluetooth/host/classic/Kconfig b/subsys/bluetooth/host/classic/Kconfig index 60252cbcecc84..c771cfdcd043e 100644 --- a/subsys/bluetooth/host/classic/Kconfig +++ b/subsys/bluetooth/host/classic/Kconfig @@ -567,6 +567,13 @@ config BT_DEFAULT_ROLE_SWITCH_ENABLE This option sets the controller's default link policy to enable/disable the role switch. +config BT_POWER_MODE_CONTROL + bool "Bluetooth Power Mode Control(Active/Sniff)" + help + This option enables the power mode control feature. This feature + allows the application to control the power mode of the Bluetooth + controller. + config BT_GOEP bool "Bluetooth GOEP Profile [EXPERIMENTAL]" select BT_RFCOMM diff --git a/subsys/bluetooth/host/classic/br.c b/subsys/bluetooth/host/classic/br.c index 4e9902747381a..cf58fae021048 100644 --- a/subsys/bluetooth/host/classic/br.c +++ b/subsys/bluetooth/host/classic/br.c @@ -710,6 +710,40 @@ void bt_hci_role_change(struct net_buf *buf) bt_conn_unref(conn); } +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +void bt_hci_link_mode_change(struct net_buf *buf) +{ + struct bt_hci_evt_mode_change *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + uint16_t interval = sys_le16_to_cpu(evt->interval); + struct bt_conn *conn; + + conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_BR); + if (!conn) { + LOG_ERR("Can't find conn for handle 0x%x", handle); + return; + } + + if (conn->state != BT_CONN_CONNECTED) { + LOG_ERR("Invalid state %d", conn->state); + bt_conn_unref(conn); + return; + } + + if (evt->status) { + LOG_ERR("Error %d, type %d", evt->status, conn->type); + bt_conn_unref(conn); + return; + } + + LOG_DBG("hdl 0x%x mode %d intervel %d", handle, evt->mode, interval); + + conn->br.mode = evt->mode; + bt_conn_notify_mode_changed(conn, evt->mode, interval); + bt_conn_unref(conn); +} +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ + static int read_ext_features(void) { int i; diff --git a/subsys/bluetooth/host/classic/shell/bredr.c b/subsys/bluetooth/host/classic/shell/bredr.c index e21f64f2de381..dcb268749f371 100644 --- a/subsys/bluetooth/host/classic/shell/bredr.c +++ b/subsys/bluetooth/host/classic/shell/bredr.c @@ -1469,6 +1469,54 @@ static int cmd_set_role_switchable(const struct shell *sh, size_t argc, char *ar return 0; } +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +static int cmd_set_sniff_mode(const struct shell *sh, size_t argc, char *argv[]) +{ + const char *action; + int err = 0; + + action = argv[1]; + if (!default_conn) { + shell_print(sh, "Not connected"); + return -ENOEXEC; + } + + if (!strcmp(action, "on")) { + uint16_t min_interval; + uint16_t max_interval; + uint16_t attempt; + uint16_t timeout; + + min_interval = atoi(argv[2]); + max_interval = atoi(argv[3]); + attempt = atoi(argv[4]); + timeout = atoi(argv[5]); + err = bt_conn_br_enter_sniff_mode(default_conn, min_interval, max_interval, attempt, + timeout); + if (err) { + shell_print(sh, "request enter sniff mode, err:%d", err); + } else { + shell_print(sh, + "request enter sniff mode, min_interval:%d, max_interval:%d, " + "attempt:%d, timeout:%d", + min_interval, max_interval, attempt, timeout); + } + } else if (!strcmp(action, "off")) { + err = bt_conn_br_exit_sniff_mode(default_conn); + if (err) { + shell_print(sh, "request enter active mode, err:%d", err); + } else { + shell_print(sh, "request enter active mode success"); + } + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + return 0; +} +#endif + #if defined(CONFIG_BT_L2CAP_CONNLESS) static void connless_recv(struct bt_conn *conn, uint16_t psm, struct net_buf *buf) { @@ -1639,6 +1687,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(br_cmds, SHELL_CMD_ARG(switch-role, NULL, "", cmd_switch_role, 2, 0), SHELL_CMD_ARG(set-role-switchable, NULL, "", cmd_set_role_switchable, 2, 0), +#if defined(CONFIG_BT_POWER_MODE_CONTROL) + SHELL_CMD_ARG(set_sniff_mode, NULL, + " [min_interval] [max_interval] [attempt] [timeout]", + cmd_set_sniff_mode, 2, 4), +#endif SHELL_SUBCMD_SET_END ); diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 9b6c961cfae6f..8d9e12c5463e3 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1546,23 +1546,20 @@ uint8_t bt_conn_index(const struct bt_conn *conn) switch (conn->type) { #if defined(CONFIG_BT_ISO) case BT_CONN_TYPE_ISO: - index = conn - iso_conns; - __ASSERT(index >= 0 && index < ARRAY_SIZE(iso_conns), - "Invalid bt_conn pointer"); + __ASSERT(IS_ARRAY_ELEMENT(iso_conns, conn), "Invalid bt_conn pointer"); + index = ARRAY_INDEX(iso_conns, conn); break; #endif #if defined(CONFIG_BT_CLASSIC) case BT_CONN_TYPE_SCO: - index = conn - sco_conns; - __ASSERT(index >= 0 && index < ARRAY_SIZE(sco_conns), - "Invalid bt_conn pointer"); + __ASSERT(IS_ARRAY_ELEMENT(sco_conns, conn), "Invalid bt_conn pointer"); + index = ARRAY_INDEX(sco_conns, conn); break; #endif default: #if defined(CONFIG_BT_CONN) - index = conn - acl_conns; - __ASSERT(index >= 0 && index < ARRAY_SIZE(acl_conns), - "Invalid bt_conn pointer"); + __ASSERT(IS_ARRAY_ELEMENT(acl_conns, conn), "Invalid bt_conn pointer"); + index = ARRAY_INDEX(acl_conns, conn); #else __ASSERT(false, "Invalid connection type %u", conn->type); #endif /* CONFIG_BT_CONN */ @@ -2465,6 +2462,10 @@ struct bt_conn *bt_conn_add_br(const bt_addr_t *peer) conn->get_and_clear_cb = acl_get_and_clear_cb; conn->has_data = acl_has_data; +#if defined(CONFIG_BT_POWER_MODE_CONTROL) + conn->br.mode = BT_ACTIVE_MODE; +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ + return conn; } #endif /* CONFIG_BT_CLASSIC */ @@ -4363,6 +4364,93 @@ void bt_hci_le_df_cte_req_failed(struct net_buf *buf) } #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +int bt_conn_br_enter_sniff_mode(struct bt_conn *conn, uint16_t min_interval, uint16_t max_interval, + uint16_t attempt, uint16_t timeout) +{ + struct bt_hci_cp_sniff_mode *cp; + struct net_buf *buf; + + if (!bt_conn_is_type(conn, BT_CONN_TYPE_BR)) { + return -EINVAL; + } + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (conn->br.mode == BT_SNIFF_MODE) { + return -EBUSY; + } + + /* Check if the parameters are valid */ + if (min_interval < 0x0006 || min_interval > 0x0540 || max_interval < 0x0006 || + max_interval > 0x0540 || min_interval > max_interval || attempt == 0 || + attempt > 0x01F3 || timeout > 0x0028) { + return -EINVAL; + } + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->max_interval = sys_cpu_to_le16(max_interval); + cp->min_interval = sys_cpu_to_le16(min_interval); + cp->attempt = sys_cpu_to_le16(attempt); + cp->timeout = sys_cpu_to_le16(timeout); + + return bt_hci_cmd_send_sync(BT_HCI_OP_SNIFF_MODE, buf, NULL); +} + +int bt_conn_br_exit_sniff_mode(struct bt_conn *conn) +{ + struct bt_hci_cp_exit_sniff_mode *cp; + struct net_buf *buf; + + if (!bt_conn_is_type(conn, BT_CONN_TYPE_BR)) { + return -EINVAL; + } + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (conn->br.mode == BT_ACTIVE_MODE) { + return -EBUSY; + } + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + + return bt_hci_cmd_send_sync(BT_HCI_OP_EXIT_SNIFF_MODE, buf, NULL); +} + +void bt_conn_notify_mode_changed(struct bt_conn *conn, uint8_t mode, uint16_t interval) +{ + struct bt_conn_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { + if (callback->br_mode_changed) { + callback->br_mode_changed(conn, mode, interval); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { + if (cb->br_mode_changed) { + cb->br_mode_changed(conn, mode, interval); + } + } +} + +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ #endif /* CONFIG_BT_CONN */ #if defined(CONFIG_BT_CONN_TX_NOTIFY_WQ) diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 87393922a93b6..dad6ea9bd5f06 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -155,6 +155,11 @@ struct bt_conn_br { uint8_t features[LMP_MAX_PAGES][8]; struct bt_keys_link_key *link_key; + +#if defined(CONFIG_BT_POWER_MODE_CONTROL) + /* For power mode */ + uint8_t mode; +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ }; struct bt_conn_sco { @@ -540,6 +545,11 @@ void bt_conn_identity_resolved(struct bt_conn *conn); void bt_conn_security_changed(struct bt_conn *conn, uint8_t hci_err, enum bt_security_err err); +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +/* Notify higher layers that connection sniff mode changed */ +void bt_conn_notify_mode_changed(struct bt_conn *conn, uint8_t mode, uint16_t interval); +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ + /* Prepare a PDU to be sent over a connection */ #if defined(CONFIG_NET_BUF_LOG) struct net_buf *bt_conn_create_pdu_timeout_debug(struct net_buf_pool *pool, diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 11db5a820c29e..d1c6c44d932d9 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3083,6 +3083,10 @@ static const struct event_handler normal_events[] = { sizeof(struct bt_hci_evt_remote_ext_features)), EVENT_HANDLER(BT_HCI_EVT_ROLE_CHANGE, bt_hci_role_change, sizeof(struct bt_hci_evt_role_change)), +#if defined(CONFIG_BT_POWER_MODE_CONTROL) + EVENT_HANDLER(BT_HCI_EVT_MODE_CHANGE, bt_hci_link_mode_change, + sizeof(struct bt_hci_evt_mode_change)), +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ EVENT_HANDLER(BT_HCI_EVT_SYNC_CONN_COMPLETE, bt_hci_synchronous_conn_complete, sizeof(struct bt_hci_evt_sync_conn_complete)), #endif /* CONFIG_BT_CLASSIC */ diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 3d1c87cb3c0bd..b9434e88c12a0 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -116,6 +116,10 @@ enum { BT_ADV_PARAMS_SET, /* Advertising data has been set in the controller. */ BT_ADV_DATA_SET, + /* Advertising random address has been updated in the controller before + * enabling advertising. + */ + BT_ADV_RANDOM_ADDR_UPDATED, /* Advertising random address pending to be set in the controller. */ BT_ADV_RANDOM_ADDR_PENDING, /* The private random address of the advertiser is valid for this cycle @@ -559,6 +563,9 @@ void bt_hci_remote_name_request_complete(struct net_buf *buf); void bt_hci_read_remote_features_complete(struct net_buf *buf); void bt_hci_read_remote_ext_features_complete(struct net_buf *buf); void bt_hci_role_change(struct net_buf *buf); +#if defined(CONFIG_BT_POWER_MODE_CONTROL) +void bt_hci_link_mode_change(struct net_buf *buf); +#endif /* CONFIG_BT_POWER_MODE_CONTROL */ void bt_hci_synchronous_conn_complete(struct net_buf *buf); void bt_hci_le_df_connection_iq_report(struct net_buf *buf); diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index b154729438a0f..bffc5fd907f2e 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1841,11 +1841,10 @@ 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) { - ptrdiff_t index = per_adv_sync - per_adv_sync_pool; - - __ASSERT(index >= 0 && ARRAY_SIZE(per_adv_sync_pool) > index, + __ASSERT(IS_ARRAY_ELEMENT(per_adv_sync_pool, per_adv_sync), "Invalid per_adv_sync pointer"); - return (uint8_t)index; + + return (uint8_t)ARRAY_INDEX(per_adv_sync_pool, per_adv_sync); } struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_index(uint8_t index) diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index a09afe4e3e5cb..816b6549853b0 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -4421,6 +4421,15 @@ static void br_bond_deleted(const bt_addr_t *peer) } #endif /* CONFIG_BT_CLASSIC */ +#if defined(CONFIG_BT_APP_PASSKEY) +static uint32_t app_passkey = BT_PASSKEY_RAND; + +static uint32_t auth_app_passkey(struct bt_conn *conn) +{ + return app_passkey; +} +#endif /* CONFIG_BT_APP_PASSKEY */ + static struct bt_conn_auth_cb auth_cb_display = { .passkey_display = auth_passkey_display, #if defined(CONFIG_BT_PASSKEY_KEYPRESS) @@ -4437,6 +4446,9 @@ static struct bt_conn_auth_cb auth_cb_display = { #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT) .pairing_accept = pairing_accept, #endif +#if defined(CONFIG_BT_APP_PASSKEY) + .app_passkey = auth_app_passkey, +#endif }; static struct bt_conn_auth_cb auth_cb_display_yes_no = { @@ -4445,6 +4457,9 @@ static struct bt_conn_auth_cb auth_cb_display_yes_no = { .passkey_confirm = auth_passkey_confirm, #if defined(CONFIG_BT_CLASSIC) .pincode_entry = auth_pincode_entry, +#endif +#if defined(CONFIG_BT_APP_PASSKEY) + .app_passkey = auth_app_passkey, #endif .oob_data_request = NULL, .cancel = auth_cancel, @@ -4460,6 +4475,9 @@ static struct bt_conn_auth_cb auth_cb_input = { .passkey_confirm = NULL, #if defined(CONFIG_BT_CLASSIC) .pincode_entry = auth_pincode_entry, +#endif +#if defined(CONFIG_BT_APP_PASSKEY) + .app_passkey = auth_app_passkey, #endif .oob_data_request = NULL, .cancel = auth_cancel, @@ -4472,6 +4490,9 @@ static struct bt_conn_auth_cb auth_cb_input = { static struct bt_conn_auth_cb auth_cb_confirm = { #if defined(CONFIG_BT_CLASSIC) .pincode_entry = auth_pincode_entry, +#endif +#if defined(CONFIG_BT_APP_PASSKEY) + .app_passkey = auth_app_passkey, #endif .oob_data_request = NULL, .cancel = auth_cancel, @@ -4487,6 +4508,9 @@ static struct bt_conn_auth_cb auth_cb_all = { .passkey_confirm = auth_passkey_confirm, #if defined(CONFIG_BT_CLASSIC) .pincode_entry = auth_pincode_entry, +#endif +#if defined(CONFIG_BT_APP_PASSKEY) + .app_passkey = auth_app_passkey, #endif .oob_data_request = auth_pairing_oob_data_request, .cancel = auth_cancel, @@ -4703,16 +4727,15 @@ static int cmd_fal_connect(const struct shell *sh, size_t argc, char *argv[]) #endif /* CONFIG_BT_CENTRAL */ #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */ -#if defined(CONFIG_BT_FIXED_PASSKEY) -static int cmd_fixed_passkey(const struct shell *sh, - size_t argc, char *argv[]) +#if defined(CONFIG_BT_APP_PASSKEY) +static int cmd_app_passkey(const struct shell *sh, + size_t argc, char *argv[]) { - unsigned int passkey; - int err; + uint32_t passkey; if (argc < 2) { - bt_passkey_set(BT_PASSKEY_INVALID); - shell_print(sh, "Fixed passkey cleared"); + app_passkey = BT_PASSKEY_RAND; + shell_print(sh, "App passkey cleared"); return 0; } @@ -4722,14 +4745,12 @@ static int cmd_fixed_passkey(const struct shell *sh, return -ENOEXEC; } - err = bt_passkey_set(passkey); - if (err) { - shell_print(sh, "Setting fixed passkey failed (err %d)", err); - } + app_passkey = passkey; + shell_print(sh, "App passkey set to %06u", passkey); - return err; + return 0; } -#endif +#endif /* CONFIG_BT_APP_PASSKEY */ static int cmd_auth_passkey(const struct shell *sh, size_t argc, char *argv[]) @@ -5340,10 +5361,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds, cmd_fal_connect, 2, 3), #endif /* CONFIG_BT_CENTRAL */ #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */ -#if defined(CONFIG_BT_FIXED_PASSKEY) - SHELL_CMD_ARG(fixed-passkey, NULL, "[passkey]", cmd_fixed_passkey, +#if defined(CONFIG_BT_APP_PASSKEY) + SHELL_CMD_ARG(app-passkey, NULL, "[passkey]", cmd_app_passkey, 1, 1), -#endif +#endif /* CONFIG_BT_APP_PASSKEY */ #endif /* CONFIG_BT_SMP || CONFIG_BT_CLASSIC) */ #endif /* CONFIG_BT_CONN */ diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 702e6fc0d215e..b935c61d2a36a 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -222,10 +222,10 @@ struct bt_smp { atomic_t bondable; }; -static unsigned int fixed_passkey = BT_PASSKEY_INVALID; +static unsigned int fixed_passkey = BT_PASSKEY_RAND; #define DISPLAY_FIXED(smp) (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && \ - fixed_passkey != BT_PASSKEY_INVALID && \ + fixed_passkey != BT_PASSKEY_RAND && \ (smp)->method == PASSKEY_DISPLAY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) @@ -363,9 +363,21 @@ static uint8_t get_io_capa(struct bt_smp *smp) return BT_SMP_IO_DISPLAY_YESNO; } +#if defined(CONFIG_BT_APP_PASSKEY) + /* Implementation of the app_passkey cb implies that the application can "know" the passkey + * without actually having a display, thus earning the "display" capability. + */ + if (smp_auth_cb->app_passkey) { + if (smp_auth_cb->passkey_entry) { + return BT_SMP_IO_KEYBOARD_DISPLAY; + } + + return BT_SMP_IO_DISPLAY_ONLY; + } +#endif /* CONFIG_BT_APP_PASSKEY */ + if (smp_auth_cb->passkey_entry) { - if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && - fixed_passkey != BT_PASSKEY_INVALID) { + if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) { return BT_SMP_IO_KEYBOARD_DISPLAY; } else { return BT_SMP_IO_KEYBOARD_ONLY; @@ -377,8 +389,7 @@ static uint8_t get_io_capa(struct bt_smp *smp) } no_callbacks: - if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && - fixed_passkey != BT_PASSKEY_INVALID) { + if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) { return BT_SMP_IO_DISPLAY_ONLY; } else { return BT_SMP_IO_NO_INPUT_OUTPUT; @@ -2475,7 +2486,6 @@ static uint8_t legacy_request_tk(struct bt_smp *smp) struct bt_conn *conn = smp->chan.chan.conn; const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp); struct bt_keys *keys; - uint32_t passkey; /* * Fail if we have keys that are stronger than keys that will be @@ -2503,11 +2513,25 @@ static uint8_t legacy_request_tk(struct bt_smp *smp) } break; - case PASSKEY_DISPLAY: - if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && - fixed_passkey != BT_PASSKEY_INVALID) { + case PASSKEY_DISPLAY: { + uint32_t passkey; + + if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) { passkey = fixed_passkey; - } else { +#if defined(CONFIG_BT_APP_PASSKEY) + } else if (smp_auth_cb && smp_auth_cb->app_passkey) { + passkey = smp_auth_cb->app_passkey(conn); + + if (passkey != BT_PASSKEY_RAND && passkey > 999999) { + LOG_WRN("App-provided passkey is out of valid range: %u", passkey); + return BT_SMP_ERR_UNSPECIFIED; + } +#endif /* CONFIG_BT_APP_PASSKEY */ + } else { + passkey = BT_PASSKEY_RAND; + } + + if (passkey == BT_PASSKEY_RAND) { if (bt_rand(&passkey, sizeof(passkey))) { return BT_SMP_ERR_UNSPECIFIED; } @@ -2527,6 +2551,7 @@ static uint8_t legacy_request_tk(struct bt_smp *smp) sys_put_le32(passkey, smp->tk); break; + } case PASSKEY_INPUT: atomic_set_bit(smp->flags, SMP_FLAG_USER); smp_auth_cb->passkey_entry(conn); @@ -4429,18 +4454,32 @@ __maybe_unused static uint8_t display_passkey(struct bt_smp *smp) { struct bt_conn *conn = smp->chan.chan.conn; const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp); + uint32_t passkey = BT_PASSKEY_RAND; - if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && - fixed_passkey != BT_PASSKEY_INVALID) { - smp->passkey = fixed_passkey; - } else { - if (bt_rand(&smp->passkey, sizeof(smp->passkey))) { + if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) { + passkey = fixed_passkey; + } + +#if defined(CONFIG_BT_APP_PASSKEY) + if (smp_auth_cb && smp_auth_cb->app_passkey) { + passkey = smp_auth_cb->app_passkey(conn); + + if (passkey != BT_PASSKEY_RAND && passkey > 999999) { + LOG_WRN("App-provided passkey is out of valid range: %u", passkey); + return BT_SMP_ERR_UNSPECIFIED; + } + } +#endif /* CONFIG_BT_APP_PASSKEY */ + + if (passkey == BT_PASSKEY_RAND) { + if (bt_rand(&passkey, sizeof(passkey))) { return BT_SMP_ERR_UNSPECIFIED; } - smp->passkey %= 1000000; + passkey %= 1000000; } + smp->passkey = passkey; smp->passkey_round = 0U; if (smp_auth_cb && smp_auth_cb->passkey_display) { @@ -6172,8 +6211,8 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn) #if defined(CONFIG_BT_FIXED_PASSKEY) int bt_passkey_set(unsigned int passkey) { - if (passkey == BT_PASSKEY_INVALID) { - fixed_passkey = BT_PASSKEY_INVALID; + if (passkey == BT_PASSKEY_INVALID || passkey == BT_PASSKEY_RAND) { + fixed_passkey = BT_PASSKEY_RAND; return 0; } diff --git a/subsys/cpu_freq/policies/on_demand/on_demand.c b/subsys/cpu_freq/policies/on_demand/on_demand.c index 41b9b733eabad..1cc1cdec78d62 100644 --- a/subsys/cpu_freq/policies/on_demand/on_demand.c +++ b/subsys/cpu_freq/policies/on_demand/on_demand.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include LOG_MODULE_REGISTER(cpu_freq_policy_on_demand, CONFIG_CPU_FREQ_LOG_LEVEL); diff --git a/subsys/mgmt/hawkbit/Kconfig b/subsys/mgmt/hawkbit/Kconfig index ce0fd7c160f3e..962cb5262a7d7 100644 --- a/subsys/mgmt/hawkbit/Kconfig +++ b/subsys/mgmt/hawkbit/Kconfig @@ -15,6 +15,8 @@ menuconfig HAWKBIT depends on BOOTLOADER_MCUBOOT depends on SMF depends on SMF_ANCESTOR_SUPPORT + depends on !MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP + depends on !MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT select MPU_ALLOW_FLASH_WRITE select IMG_ENABLE_IMAGE_CHECK select IMG_ERASE_PROGRESSIVELY @@ -258,6 +260,21 @@ config HAWKBIT_SAVE_PROGRESS_INTERVAL Set the interval (in percent) that the hawkBit update download progress will be saved. 0 means that the progress will be saved every time a new chunk is downloaded. +config HAWKBIT_CONFIRM_IMG_ON_INIT + bool "Confirm boot image at hawkBit init" + default y + help + Automatically confirm current boot image at hawkBit initialization. + Application shall handle image confirmation when set to false. + +config HAWKBIT_ERASE_SECOND_SLOT_ON_CONFIRM + bool "Erase second slot after confirming boot image" + default y + depends on HAWKBIT_CONFIRM_IMG_ON_INIT + help + Erase the second image slot partition contents after confirming current boot image + at hawkBit init. + module = HAWKBIT module-str = Log Level for hawkbit module-help = Enables logging for hawkBit code. diff --git a/subsys/mgmt/hawkbit/hawkbit.c b/subsys/mgmt/hawkbit/hawkbit.c index 69a75d44efff9..1452836dc7a92 100644 --- a/subsys/mgmt/hawkbit/hawkbit.c +++ b/subsys/mgmt/hawkbit/hawkbit.c @@ -910,7 +910,8 @@ int hawkbit_init(void) image_ok = boot_is_img_confirmed(); LOG_INF("Current image is%s confirmed", image_ok ? "" : " not"); - if (!image_ok) { + + if (IS_ENABLED(CONFIG_HAWKBIT_CONFIRM_IMG_ON_INIT) && !image_ok) { ret = boot_write_img_confirmed(); if (ret < 0) { LOG_ERR("Failed to confirm current image: %d", ret); @@ -918,10 +919,13 @@ int hawkbit_init(void) } LOG_DBG("Marked current image as OK"); - ret = boot_erase_img_bank(flash_img_get_upload_slot()); - if (ret < 0) { - LOG_ERR("Failed to erase second slot: %d", ret); - return ret; + + if (IS_ENABLED(CONFIG_HAWKBIT_ERASE_SECOND_SLOT_ON_CONFIRM)) { + ret = boot_erase_img_bank(flash_img_get_upload_slot()); + if (ret < 0) { + LOG_ERR("Failed to erase second slot: %d", ret); + return ret; + } } hawkbit_event_raise(HAWKBIT_EVENT_CONFIRMED_CURRENT_IMAGE); diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt index 234d6693972f7..a8d819652f51b 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt @@ -15,7 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32 src/fs_mgm zephyr_library_sources_ifdef(CONFIG_MCUMGR_GRP_FS_HASH_SHA256 src/fs_mgmt_hash_checksum_sha256.c) if(CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH AND CONFIG_MCUMGR_GRP_FS_HASH_SHA256) - if(CONFIG_MBEDTLS_SHA256) + if(CONFIG_MBEDTLS) zephyr_library_link_libraries(mbedTLS) endif() endif() diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig index 5be0ab44efd38..edac04c4f6c62 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig @@ -125,8 +125,8 @@ config MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32 config MCUMGR_GRP_FS_HASH_SHA256 bool "SHA256 hash support" - depends on BUILD_WITH_TFM || MBEDTLS_SHA256 - select PSA_WANT_ALG_SHA_256 if BUILD_WITH_TFM + select PSA_CRYPTO + select PSA_WANT_ALG_SHA_256 help Enable SHA256 hash support for MCUmgr. diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt_hash_checksum_sha256.c b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt_hash_checksum_sha256.c index 5005067f38c16..373e17e9ed5a0 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt_hash_checksum_sha256.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt_hash_checksum_sha256.c @@ -13,25 +13,15 @@ #include #include -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT #include -typedef psa_hash_operation_t hash_ctx_t; -#define SUCCESS_VALUE PSA_SUCCESS -#else -#include -typedef mbedtls_sha256_context hash_ctx_t; -#define SUCCESS_VALUE 0 - -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ - -#define SHA256_DIGEST_SIZE 32 +#define SHA256_DIGEST_SIZE PSA_HASH_LENGTH(PSA_ALG_SHA_256) /* The API that the different hash implementations provide further down. */ -static int hash_setup(hash_ctx_t *); -static int hash_update(hash_ctx_t *, const uint8_t *input, size_t ilen); -static int hash_finish(hash_ctx_t *, uint8_t *output); -static void hash_teardown(hash_ctx_t *); +static int hash_setup(psa_hash_operation_t *); +static int hash_update(psa_hash_operation_t *, const uint8_t *input, size_t ilen); +static int hash_finish(psa_hash_operation_t *, uint8_t *output); +static void hash_teardown(psa_hash_operation_t *); static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output, size_t *out_len, size_t len) @@ -40,13 +30,13 @@ static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output, ssize_t bytes_read = 0; size_t read_size = CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE; uint8_t buffer[CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE]; - hash_ctx_t hash_ctx; + psa_hash_operation_t hash_ctx; /* Clear variables prior to calculation */ *out_len = 0; memset(output, 0, SHA256_DIGEST_SIZE); - if (hash_setup(&hash_ctx) != SUCCESS_VALUE) { + if (hash_setup(&hash_ctx) != PSA_SUCCESS) { goto teardown; } @@ -63,7 +53,7 @@ static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output, /* Failed to read file data */ goto teardown; } else if (bytes_read > 0) { - if (hash_update(&hash_ctx, buffer, bytes_read) != SUCCESS_VALUE) { + if (hash_update(&hash_ctx, buffer, bytes_read) != PSA_SUCCESS) { goto teardown; } @@ -72,7 +62,7 @@ static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output, } while (bytes_read > 0 && *out_len < len); /* Finalise SHA256 hash calculation and store output in provided output buffer */ - if (hash_finish(&hash_ctx, output) == SUCCESS_VALUE) { + if (hash_finish(&hash_ctx, output) == PSA_SUCCESS) { rc = 0; } @@ -99,8 +89,6 @@ void fs_mgmt_hash_checksum_unregister_sha256(void) fs_mgmt_hash_checksum_unregister_group(&sha256); } -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT - static int hash_setup(psa_hash_operation_t *ctx) { *ctx = psa_hash_operation_init(); @@ -120,25 +108,3 @@ static void hash_teardown(psa_hash_operation_t *ctx) { psa_hash_abort(ctx); } - -#else - -static int hash_setup(mbedtls_sha256_context *ctx) -{ - mbedtls_sha256_init(ctx); - return mbedtls_sha256_starts(ctx, false); -} -static int hash_update(mbedtls_sha256_context *ctx, const uint8_t *input, size_t ilen) -{ - return mbedtls_sha256_update(ctx, input, ilen); -} -static int hash_finish(mbedtls_sha256_context *ctx, uint8_t *output) -{ - return mbedtls_sha256_finish(ctx, output); -} -static void hash_teardown(mbedtls_sha256_context *ctx) -{ - mbedtls_sha256_free(ctx); -} - -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 463e1220e2e9d..1748f3013254e 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -294,6 +294,23 @@ config NET_TC_THREAD_PRIO_CUSTOM Customise net threads priority by each. if NET_TC_THREAD_PRIO_CUSTOM + +config NET_TC_TX_THREAD_PRIO_SPREAD + int "Transmit traffic class thread priority spread" + default 1 + range 1 255 + help + Transmit traffic class threads priority will increase/decrease + by this step. They will be separated by this many levels. + +config NET_TC_RX_THREAD_PRIO_SPREAD + int "Receive traffic class thread priority spread" + default 1 + range 1 255 + help + Receive traffic class threads priority will increase/decrease + by this step. They will be separated by this many levels. + config NET_TC_TX_THREAD_BASE_PRIO int "Transmit traffic class base thread priority" default 0 @@ -509,6 +526,10 @@ config NET_MAX_CONTEXTS is used when listening or sending network traffic. This is very similar as one could call a network socket in some other systems. +config ZVFS_OPEN_ADD_SIZE_NET + int "Number of network sockets to allocate" + default NET_MAX_CONTEXTS + config NET_CONTEXT_NET_PKT_POOL bool "Net_buf TX pool / context" default y if NET_TCP && NET_6LO diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index eb9437ccb95dc..533255a6318e5 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -507,9 +507,7 @@ static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt) #if NET_TC_RX_COUNT > 1 NET_DBG("TC %d with prio %d pkt %p", tc, prio, pkt); #endif - - if ((IS_ENABLED(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO) && - prio >= NET_PRIORITY_CA) || NET_TC_RX_COUNT == 0) { + if (net_tc_rx_is_immediate(tc, prio)) { net_process_rx_packet(pkt); } else { if (net_tc_submit_to_rx_queue(tc, pkt) != NET_OK) { diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index af13143d74b19..7fd784f87424c 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -366,10 +366,8 @@ void net_if_try_queue_tx(struct net_if *iface, struct net_pkt *pkt, k_timeout_t * the driver. Also if there are no TX queue/thread, push the packet * directly to the driver. */ - if ((IS_ENABLED(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO) && - prio >= NET_PRIORITY_CA) || NET_TC_TX_COUNT == 0) { + if (net_tc_tx_is_immediate(tc, prio)) { net_pkt_set_tx_stats_tick(pkt, k_cycle_get_32()); - net_if_tx(net_pkt_iface(pkt), pkt); } else { if (net_tc_try_submit_to_tx_queue(tc, pkt, timeout) != NET_OK) { diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 5ee27093deda1..624f61d889349 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef CONFIG_NET_MGMT_EVENT_INFO @@ -208,6 +209,26 @@ static inline void net_tc_rx_init(void) { } enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt, k_timeout_t timeout); extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt); +extern int net_tc_tx_thread_priority(int tc); +extern int net_tc_rx_thread_priority(int tc); +static inline bool net_tc_tx_is_immediate(int tc, int prio) +{ + ARG_UNUSED(prio); + bool high_prio = (tc == NET_TC_TX_EFFECTIVE_COUNT - 1); + bool skipping = IS_ENABLED(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO); + bool no_queues = (0 == NET_TC_TX_COUNT); + + return no_queues || (high_prio && skipping); +} +static inline bool net_tc_rx_is_immediate(int tc, int prio) +{ + ARG_UNUSED(prio); + bool high_prio = (tc == NET_TC_RX_EFFECTIVE_COUNT - 1); + bool skipping = IS_ENABLED(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO); + bool no_queues = (0 == NET_TC_RX_COUNT); + + return no_queues || (high_prio && skipping); +} extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt); char *net_sprint_addr(sa_family_t af, const void *addr); diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index 15a928ffcd3ee..fad0150563aec 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -18,9 +18,6 @@ LOG_MODULE_REGISTER(net_tc, CONFIG_NET_TC_LOG_LEVEL); #include "net_stats.h" #include "net_tc_mapping.h" -#define TC_RX_PSEUDO_QUEUE (COND_CODE_1(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO, (1), (0))) -#define NET_TC_RX_EFFECTIVE_COUNT (NET_TC_RX_COUNT + TC_RX_PSEUDO_QUEUE) - #if NET_TC_RX_EFFECTIVE_COUNT > 1 #define NET_TC_RX_SLOTS (CONFIG_NET_PKT_RX_COUNT / NET_TC_RX_EFFECTIVE_COUNT) BUILD_ASSERT(NET_TC_RX_SLOTS > 0, @@ -29,8 +26,6 @@ BUILD_ASSERT(NET_TC_RX_SLOTS > 0, "CONFIG_NET_TC_RX_COUNT or disable CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO"); #endif -#define TC_TX_PSEUDO_QUEUE (COND_CODE_1(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO, (1), (0))) -#define NET_TC_TX_EFFECTIVE_COUNT (NET_TC_TX_COUNT + TC_TX_PSEUDO_QUEUE) #if NET_TC_TX_EFFECTIVE_COUNT > 1 #define NET_TC_TX_SLOTS (CONFIG_NET_PKT_TX_COUNT / NET_TC_TX_EFFECTIVE_COUNT) @@ -120,6 +115,8 @@ enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt) int net_tx_priority2tc(enum net_priority prio) { #if NET_TC_TX_COUNT > 0 + static const uint8_t tx_prio2tc_map[] = PRIORITY2TC_TX; + if (prio > NET_PRIORITY_NC) { /* Use default value suggested in 802.1Q */ prio = NET_PRIORITY_BE; @@ -136,6 +133,8 @@ int net_tx_priority2tc(enum net_priority prio) int net_rx_priority2tc(enum net_priority prio) { #if NET_TC_RX_COUNT > 0 + static const uint8_t rx_prio2tc_map[] = PRIORITY2TC_RX; + if (prio > NET_PRIORITY_NC) { /* Use default value suggested in 802.1Q */ prio = NET_PRIORITY_BE; @@ -151,89 +150,58 @@ int net_rx_priority2tc(enum net_priority prio) #if defined(CONFIG_NET_TC_THREAD_PRIO_CUSTOM) #define BASE_PRIO_TX CONFIG_NET_TC_TX_THREAD_BASE_PRIO +#define PRIO_SPREAD_TX CONFIG_NET_TC_TX_THREAD_PRIO_SPREAD #elif defined(CONFIG_NET_TC_THREAD_COOPERATIVE) #define BASE_PRIO_TX (CONFIG_NET_TC_NUM_PRIORITIES - 1) +#define PRIO_SPREAD_TX 1 +BUILD_ASSERT(NET_TC_TX_COUNT <= CONFIG_NUM_COOP_PRIORITIES, "Too many traffic classes"); #else #define BASE_PRIO_TX (CONFIG_NET_TC_TX_COUNT - 1) +#define PRIO_SPREAD_TX 1 #endif -#define PRIO_TX(i, _) (BASE_PRIO_TX - i) - #if defined(CONFIG_NET_TC_THREAD_PRIO_CUSTOM) #define BASE_PRIO_RX CONFIG_NET_TC_RX_THREAD_BASE_PRIO +#define PRIO_SPREAD_RX CONFIG_NET_TC_RX_THREAD_PRIO_SPREAD #elif defined(CONFIG_NET_TC_THREAD_COOPERATIVE) #define BASE_PRIO_RX (CONFIG_NET_TC_NUM_PRIORITIES - 1) +#define PRIO_SPREAD_RX 1 +BUILD_ASSERT(NET_TC_RX_COUNT <= CONFIG_NUM_COOP_PRIORITIES, "Too many traffic classes"); #else #define BASE_PRIO_RX (CONFIG_NET_TC_RX_COUNT - 1) +#define PRIO_SPREAD_RX 1 #endif -#define PRIO_RX(i, _) (BASE_PRIO_RX - i) - -#if NET_TC_TX_COUNT > 0 -/* Convert traffic class to thread priority */ -static uint8_t tx_tc2thread(uint8_t tc) +int net_tc_tx_thread_priority(int tc) { - /* Initial implementation just maps the traffic class to certain queue. - * If there are less queues than classes, then map them into - * some specific queue. - * - * Lower value in this table means higher thread priority. The - * value is used as a parameter to K_PRIO_COOP() or K_PRIO_PREEMPT() - * which converts it to actual thread priority. - * - * Higher traffic class value means higher priority queue. This means - * that thread_priorities[7] value should contain the highest priority - * for the TX queue handling thread. - * - * For example, if NET_TC_TX_COUNT = 8, which is the maximum number of - * traffic classes, then this priority array will contain following - * values if preemptive priorities are used: - * 7, 6, 5, 4, 3, 2, 1, 0 - * and - * 14, 13, 12, 11, 10, 9, 8, 7 - * if cooperative priorities are used. - * - * Then these will be converted to following thread priorities if - * CONFIG_NET_TC_THREAD_COOPERATIVE is enabled: - * -1, -2, -3, -4, -5, -6, -7, -8 - * - * and if CONFIG_NET_TC_THREAD_PREEMPTIVE is enabled, following thread - * priorities are used: - * 7, 6, 5, 4, 3, 2, 1, 0 - * - * This means that the lowest traffic class 1, will have the lowest - * cooperative priority -1 for coop priorities and 7 for preemptive - * priority. - */ - static const uint8_t thread_priorities[] = { - LISTIFY(NET_TC_TX_COUNT, PRIO_TX, (,)) - }; - - BUILD_ASSERT(NET_TC_TX_COUNT <= CONFIG_NUM_COOP_PRIORITIES, - "Too many traffic classes"); - - NET_ASSERT(tc < ARRAY_SIZE(thread_priorities)); - - return thread_priorities[tc]; + int priority; + int thread_priority; + + BUILD_ASSERT(BASE_PRIO_TX >= PRIO_SPREAD_TX * (NET_TC_TX_COUNT - 1)); + NET_ASSERT(tc >= 0 && tc < NET_TC_TX_COUNT); + thread_priority = BASE_PRIO_TX - PRIO_SPREAD_TX * tc; + + priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? + K_PRIO_COOP(thread_priority) : + K_PRIO_PREEMPT(thread_priority); + return priority; } -#endif -#if NET_TC_RX_COUNT > 0 -/* Convert traffic class to thread priority */ -static uint8_t rx_tc2thread(uint8_t tc) +int net_tc_rx_thread_priority(int tc) { - static const uint8_t thread_priorities[] = { - LISTIFY(NET_TC_RX_COUNT, PRIO_RX, (,)) - }; + int priority; + int thread_priority; - BUILD_ASSERT(NET_TC_RX_COUNT <= CONFIG_NUM_COOP_PRIORITIES, - "Too many traffic classes"); + BUILD_ASSERT(BASE_PRIO_RX >= PRIO_SPREAD_RX * (NET_TC_RX_COUNT - 1)); + NET_ASSERT(tc >= 0 && tc < NET_TC_RX_COUNT); + thread_priority = BASE_PRIO_RX - PRIO_SPREAD_RX * tc; - NET_ASSERT(tc < ARRAY_SIZE(thread_priorities)); - - return thread_priorities[tc]; + priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? + K_PRIO_COOP(thread_priority) : + K_PRIO_PREEMPT(thread_priority); + return priority; } -#endif + #if defined(CONFIG_NET_STATISTICS) /* Fixup the traffic class statistics so that "net stats" shell command will @@ -358,23 +326,12 @@ void net_tc_tx_init(void) #endif for (i = 0; i < NET_TC_TX_COUNT; i++) { - uint8_t thread_priority; - int priority; k_tid_t tid; + int priority = net_tc_tx_thread_priority(i); - thread_priority = tx_tc2thread(i); - - priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? - K_PRIO_COOP(thread_priority) : - K_PRIO_PREEMPT(thread_priority); - - NET_DBG("[%d] Starting TX handler %p stack size %zd " - "prio %d %s(%d)", i, + NET_DBG("[%d] Starting TX handler %p stack size %zd prio %d", i, &tx_classes[i].handler, K_KERNEL_STACK_SIZEOF(tx_stack[i]), - thread_priority, - IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? - "coop" : "preempt", priority); k_fifo_init(&tx_classes[i].fifo); @@ -426,23 +383,13 @@ void net_tc_rx_init(void) #endif for (i = 0; i < NET_TC_RX_COUNT; i++) { - uint8_t thread_priority; - int priority; k_tid_t tid; + int priority = net_tc_rx_thread_priority(i); - thread_priority = rx_tc2thread(i); - - priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? - K_PRIO_COOP(thread_priority) : - K_PRIO_PREEMPT(thread_priority); - NET_DBG("[%d] Starting RX handler %p stack size %zd " - "prio %d %s(%d)", i, + NET_DBG("[%d] Starting RX handler %p stack size %zd prio %d", i, &rx_classes[i].handler, K_KERNEL_STACK_SIZEOF(rx_stack[i]), - thread_priority, - IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ? - "coop" : "preempt", priority); k_fifo_init(&rx_classes[i].fifo); diff --git a/subsys/net/ip/net_tc_mapping.h b/subsys/net/ip/net_tc_mapping.h index c5ac0febbeed9..7fc53e4d97fdb 100644 --- a/subsys/net/ip/net_tc_mapping.h +++ b/subsys/net/ip/net_tc_mapping.h @@ -13,7 +13,7 @@ #ifndef __TC_MAPPING_H #define __TC_MAPPING_H -#include +#include "zephyr/net/net_core.h" /* All the maps below use priorities and indexes, below is the list of them * according to 802.1Q - table I-2. @@ -29,122 +29,99 @@ * 7 (highest) NC Network control */ -/* Helper macros used to generate the map to use */ -#define PRIORITY2TC_GEN_INNER(TYPE, COUNT) priority2tc_ ## TYPE ## _ ## COUNT -#define PRIORITY2TC_GEN(TYPE, COUNT) PRIORITY2TC_GEN_INNER(TYPE, COUNT) - -#if defined(CONFIG_NET_TC_MAPPING_STRICT) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for * implementations that do not support the credit-based shaper transmission * selection algorithm. * Ref: 802.1Q - chapter 8.6.6 - table 8-4 */ +#if defined(CONFIG_NET_TC_MAPPING_STRICT) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 0, 0, 1, 1, 1, 1} +#define PRIORITY2TC_3 {0, 0, 0, 0, 1, 1, 2, 2} +#define PRIORITY2TC_4 {0, 0, 1, 1, 2, 2, 3, 3} +#define PRIORITY2TC_5 {0, 0, 1, 1, 2, 2, 3, 4} +#define PRIORITY2TC_6 {1, 0, 2, 2, 3, 3, 4, 5} +#define PRIORITY2TC_7 {1, 0, 2, 3, 4, 4, 5, 6} +#define PRIORITY2TC_8 {1, 0, 2, 3, 4, 5, 6, 7} -#if NET_TC_TX_COUNT == 1 || NET_TC_RX_COUNT == 1 -static const uint8_t priority2tc_strict_1[] = {0, 0, 0, 0, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_strict_2[] = {0, 0, 0, 0, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_strict_3[] = {0, 0, 0, 0, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_strict_4[] = {0, 0, 1, 1, 2, 2, 3, 3}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_strict_5[] = {0, 0, 1, 1, 2, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_strict_6[] = {1, 0, 2, 2, 3, 3, 4, 5}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_strict_7[] = {1, 0, 2, 3, 4, 4, 5, 6}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_strict_8[] = {1, 0, 2, 3, 4, 5, 6, 7}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(strict, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(strict, NET_TC_RX_COUNT); -#endif - -#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_A_AND_B) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for a system that * supports SR (Stream Reservation) class A and SR class B. * Ref: 802.1Q - chapter 34.5 - table 34-1 */ +#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_A_AND_B) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 1, 1, 0, 0, 0, 0} +#define PRIORITY2TC_3 {0, 0, 1, 2, 0, 0, 0, 0} +#define PRIORITY2TC_4 {0, 0, 2, 3, 1, 1, 1, 1} +#define PRIORITY2TC_5 {0, 0, 3, 4, 1, 1, 2, 2} +#define PRIORITY2TC_6 {0, 0, 4, 5, 1, 1, 2, 3} +#define PRIORITY2TC_7 {0, 0, 5, 6, 1, 2, 3, 4} +#define PRIORITY2TC_8 {1, 0, 6, 7, 2, 3, 4, 5} -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_sr_ab_2[] = {0, 0, 1, 1, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_sr_ab_3[] = {0, 0, 1, 2, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_sr_ab_4[] = {0, 0, 2, 3, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_sr_ab_5[] = {0, 0, 3, 4, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_sr_ab_6[] = {0, 0, 4, 5, 1, 1, 2, 3}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_sr_ab_7[] = {0, 0, 5, 6, 1, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_sr_ab_8[] = {1, 0, 6, 7, 2, 3, 4, 5}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(sr_ab, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(sr_ab, NET_TC_RX_COUNT); -#endif - -#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_B_ONLY) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for a system that * supports SR (Stream Reservation) class B only. * Ref: 802.1Q - chapter 34.5 - table 34-2 */ - -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_sr_b_2[] = {0, 0, 1, 0, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_sr_b_3[] = {0, 0, 2, 0, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_sr_b_4[] = {0, 0, 3, 0, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_sr_b_5[] = {0, 0, 4, 1, 2, 2, 3, 3}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_sr_b_6[] = {0, 0, 5, 1, 2, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_sr_b_7[] = {1, 0, 6, 2, 3, 3, 4, 5}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_sr_b_8[] = {1, 0, 7, 2, 3, 4, 5, 6}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(sr_b, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(sr_b, NET_TC_RX_COUNT); -#endif - +#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_B_ONLY) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 1, 0, 0, 0, 0, 0} +#define PRIORITY2TC_3 {0, 0, 2, 0, 1, 1, 1, 1} +#define PRIORITY2TC_4 {0, 0, 3, 0, 1, 1, 2, 2} +#define PRIORITY2TC_5 {0, 0, 4, 1, 2, 2, 3, 3} +#define PRIORITY2TC_6 {0, 0, 5, 1, 2, 2, 3, 4} +#define PRIORITY2TC_7 {1, 0, 6, 2, 3, 3, 4, 5} +#define PRIORITY2TC_8 {1, 0, 7, 2, 3, 4, 5, 6} +#endif + + +#if NET_TC_TX_EFFECTIVE_COUNT == 0 +#elif NET_TC_TX_EFFECTIVE_COUNT == 1 +#define PRIORITY2TC_TX PRIORITY2TC_1 +#elif NET_TC_TX_EFFECTIVE_COUNT == 2 +#define PRIORITY2TC_TX PRIORITY2TC_2 +#elif NET_TC_TX_EFFECTIVE_COUNT == 3 +#define PRIORITY2TC_TX PRIORITY2TC_3 +#elif NET_TC_TX_EFFECTIVE_COUNT == 4 +#define PRIORITY2TC_TX PRIORITY2TC_4 +#elif NET_TC_TX_EFFECTIVE_COUNT == 5 +#define PRIORITY2TC_TX PRIORITY2TC_5 +#elif NET_TC_TX_EFFECTIVE_COUNT == 6 +#define PRIORITY2TC_TX PRIORITY2TC_6 +#elif NET_TC_TX_EFFECTIVE_COUNT == 7 +#define PRIORITY2TC_TX PRIORITY2TC_7 +#elif NET_TC_TX_EFFECTIVE_COUNT == 8 +#define PRIORITY2TC_TX PRIORITY2TC_8 +#else +BUILD_ASSERT(false, "Too many effective tx traffic class queues, either reduce " + "CONFIG_NET_TC_TX_COUNT or disable " + "CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO"); +#endif + + +#if NET_TC_RX_EFFECTIVE_COUNT == 0 +#elif NET_TC_RX_EFFECTIVE_COUNT == 1 +#define PRIORITY2TC_RX PRIORITY2TC_1 +#elif NET_TC_RX_EFFECTIVE_COUNT == 2 +#define PRIORITY2TC_RX PRIORITY2TC_2 +#elif NET_TC_RX_EFFECTIVE_COUNT == 3 +#define PRIORITY2TC_RX PRIORITY2TC_3 +#elif NET_TC_RX_EFFECTIVE_COUNT == 4 +#define PRIORITY2TC_RX PRIORITY2TC_4 +#elif NET_TC_RX_EFFECTIVE_COUNT == 5 +#define PRIORITY2TC_RX PRIORITY2TC_5 +#elif NET_TC_RX_EFFECTIVE_COUNT == 6 +#define PRIORITY2TC_RX PRIORITY2TC_6 +#elif NET_TC_RX_EFFECTIVE_COUNT == 7 +#define PRIORITY2TC_RX PRIORITY2TC_7 +#elif NET_TC_RX_EFFECTIVE_COUNT == 8 +#define PRIORITY2TC_RX PRIORITY2TC_8 +#else +BUILD_ASSERT(false, "Too many effective rx traffic class queues, either reduce " + "CONFIG_NET_TC_RX_COUNT or disable " + "CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO"); #endif #endif /* __TC_MAPPING_H */ diff --git a/subsys/net/l2/openthread/openthread_border_router.c b/subsys/net/l2/openthread/openthread_border_router.c index dde38376ac5cd..8a21f0d35ca64 100644 --- a/subsys/net/l2/openthread/openthread_border_router.c +++ b/subsys/net/l2/openthread/openthread_border_router.c @@ -33,9 +33,9 @@ #include static struct net_mgmt_event_callback ail_net_event_connection_cb; -static struct net_mgmt_event_callback ail_net_event_address_cb; +static struct net_mgmt_event_callback ail_net_event_ipv6_addr_cb; #if defined(CONFIG_NET_IPV4) -static struct net_mgmt_event_callback ail_net_event_ipv4_addr_add_cb; +static struct net_mgmt_event_callback ail_net_event_ipv4_addr_cb; #endif /* CONFIG_NET_IPV4 */ static uint32_t ail_iface_index; static struct net_if *ail_iface_ptr; @@ -234,15 +234,14 @@ static void ail_connection_handler(struct net_mgmt_event_callback *cb, uint64_t mdns_plat_monitor_interface(iface); } -static void ail_address_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, +static void ail_ipv6_address_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface) { if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { return; } - if ((mgmt_event & (NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL | - NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IPV4_ADDR_DEL)) != mgmt_event) { + if ((mgmt_event & (NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL)) != mgmt_event) { return; } @@ -257,13 +256,15 @@ static void ail_ipv4_address_event_handler(struct net_mgmt_event_callback *cb, u return; } - if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) { + if ((mgmt_event & (NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IPV4_ADDR_DEL)) != mgmt_event) { return; } - struct openthread_context *ot_context = openthread_get_default_context(); + if (mgmt_event == NET_EVENT_IPV4_ADDR_ADD) { + struct openthread_context *ot_context = openthread_get_default_context(); - openthread_start_border_router_services(ot_context->iface, iface); + openthread_start_border_router_services(ot_context->iface, iface); + } mdns_plat_monitor_interface(iface); } @@ -318,15 +319,14 @@ void openthread_border_router_init(struct openthread_context *ot_ctx) net_mgmt_init_event_callback(&ail_net_event_connection_cb, ail_connection_handler, NET_EVENT_IF_UP | NET_EVENT_IF_DOWN); net_mgmt_add_event_callback(&ail_net_event_connection_cb); - net_mgmt_init_event_callback(&ail_net_event_address_cb, ail_address_event_handler, - NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL | - NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IPV4_ADDR_DEL); - net_mgmt_add_event_callback(&ail_net_event_address_cb); + net_mgmt_init_event_callback(&ail_net_event_ipv6_addr_cb, ail_ipv6_address_event_handler, + NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL); + net_mgmt_add_event_callback(&ail_net_event_ipv6_addr_cb); #if defined(CONFIG_NET_IPV4) - net_mgmt_init_event_callback(&ail_net_event_ipv4_addr_add_cb, + net_mgmt_init_event_callback(&ail_net_event_ipv4_addr_cb, ail_ipv4_address_event_handler, NET_EVENT_IPV4_ADDR_ADD); - net_mgmt_add_event_callback(&ail_net_event_ipv4_addr_add_cb); + net_mgmt_add_event_callback(&ail_net_event_ipv4_addr_cb); #endif /* CONFIG_NET_IPV4 */ openthread_set_bbr_multicast_listener_cb(ot_bbr_multicast_listener_handler, (void *)ot_ctx); (void)infra_if_start_icmp6_listener(); diff --git a/subsys/net/lib/dns/dispatcher.c b/subsys/net/lib/dns/dispatcher.c index fcaf7682fb584..9c71bc6353d8b 100644 --- a/subsys/net/lib/dns/dispatcher.c +++ b/subsys/net/lib/dns/dispatcher.c @@ -31,7 +31,7 @@ NET_BUF_POOL_DEFINE(dns_msg_pool, DNS_RESOLVER_BUF_CTR, static struct socket_dispatch_table { struct dns_socket_dispatcher *ctx; -} dispatch_table[CONFIG_ZVFS_OPEN_MAX]; +} dispatch_table[ZVFS_OPEN_SIZE]; static int dns_dispatch(struct dns_socket_dispatcher *dispatcher, int sock, struct sockaddr *addr, size_t addrlen, diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn_transport_udp.c b/subsys/net/lib/mqtt_sn/mqtt_sn_transport_udp.c index cca6788fafb10..630aa24f03354 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn_transport_udp.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn_transport_udp.c @@ -213,7 +213,7 @@ static ssize_t tp_udp_recvfrom(struct mqtt_sn_client *client, void *buffer, size struct mqtt_sn_transport_udp *udp = UDP_TRANSPORT(client->transport); int rc; struct sockaddr *srcaddr = src_addr; - socklen_t addrlen_local; + socklen_t addrlen_local = *addrlen; rc = zsock_recvfrom(udp->sock, buffer, length, 0, src_addr, &addrlen_local); LOG_DBG("recv %d", rc); diff --git a/subsys/net/lib/shell/dns.c b/subsys/net/lib/shell/dns.c index 53838952c95da..b29562218e194 100644 --- a/subsys/net/lib/shell/dns.c +++ b/subsys/net/lib/shell/dns.c @@ -494,7 +494,7 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[] port = info.ai_srv.port; snprintf(query, sizeof(query), "%.*s", - info.ai_srv.targetlen, + (int)info.ai_srv.targetlen, info.ai_srv.target); /* diff --git a/subsys/net/lib/shell/filter.c b/subsys/net/lib/shell/filter.c index c8ff95c78527f..4e9e948714c7f 100644 --- a/subsys/net/lib/shell/filter.c +++ b/subsys/net/lib/shell/filter.c @@ -56,9 +56,33 @@ static void rule_cb(struct npf_rule *rule, enum npf_rule_type type, void *user_d struct net_shell_user_data *data = user_data; const struct shell *sh = data->sh; int *count = data->user_data; + uint8_t tc; + int thread_prio; + + PR("[%2d] %-10s %-8s ", + (*count) + 1, rule_type2str(type), verdict2str(rule->result)); + + if (rule->result == NET_CONTINUE && type == NPF_RULE_TYPE_SEND) { + tc = net_tx_priority2tc(rule->priority); + if (net_tc_tx_is_immediate(tc, rule->priority)) { + PR("%8d %5d SKIP ", rule->priority, tc); + } else { + thread_prio = net_tc_tx_thread_priority(tc); + PR("%8d %5d %11d ", rule->priority, tc, thread_prio); + } + } else if (rule->result == NET_CONTINUE) { + tc = net_rx_priority2tc(rule->priority); + if (net_tc_rx_is_immediate(tc, rule->priority)) { + PR("%8d %5d SKIP ", rule->priority, tc); + } else { + thread_prio = net_tc_rx_thread_priority(tc); + PR("%8d %5d %11d ", rule->priority, tc, thread_prio); + } + } else { + PR(" N/A N/A N/A "); + } - PR("[%2d] %-10s %-7s %-5d", - (*count) + 1, rule_type2str(type), verdict2str(rule->result), rule->nb_tests); + PR("%-5d", rule->nb_tests); for (int i = 0; i < rule->nb_tests; i++) { /* Allocate room for storing two full IPv4/6 addresses */ @@ -89,7 +113,7 @@ static int cmd_net_filter(const struct shell *sh, size_t argc, char *argv[]) struct net_shell_user_data user_data; int count = 0; - PR("Rule %-10s Verdict Tests\n", "Type"); + PR("Rule %-10s Verdict Pkt-Prio Queue Thread-Prio Tests\n", "Type"); user_data.sh = sh; user_data.user_data = &count; diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index bce60ee7276e6..e857dd83a5f2f 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -215,6 +215,11 @@ config NET_SOCKETS_TLS_MAX_CONTEXTS "This variable specifies maximum number of TLS/DTLS contexts that can be allocated at the same time." +config ZVFS_OPEN_ADD_SIZE_TLS + int "Number of TLS network sockets to allocate" + default NET_SOCKETS_TLS_MAX_CONTEXTS if NET_SOCKETS_SOCKOPT_TLS + default 0 + config NET_SOCKETS_TLS_MAX_CREDENTIALS int "Maximum number of TLS/DTLS credentials per socket" default 4 diff --git a/subsys/net/lib/sockets/socket_obj_core.c b/subsys/net/lib/sockets/socket_obj_core.c index 76ef0927a0a1b..7138b63fcdd42 100644 --- a/subsys/net/lib/sockets/socket_obj_core.c +++ b/subsys/net/lib/sockets/socket_obj_core.c @@ -20,8 +20,8 @@ static K_MUTEX_DEFINE(sock_obj_mutex); /* Allocate some extra socket objects so that we can track * closed sockets and get some historical statistics. */ -static struct sock_obj sock_objects[CONFIG_ZVFS_OPEN_MAX * 2] = { - [0 ... ((CONFIG_ZVFS_OPEN_MAX * 2) - 1)] = { +static struct sock_obj sock_objects[ZVFS_OPEN_SIZE * 2] = { + [0 ... ((ZVFS_OPEN_SIZE * 2) - 1)] = { .fd = -1, .init_done = false, } diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 695af67164685..2ccca60a34df5 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1552,7 +1552,6 @@ static int tls_check_psk(struct tls_credential *psk) #endif } -/* TODO add decent logs */ static int tls_check_credentials(const sec_tag_t *sec_tags, int sec_tag_count) { int err = 0; diff --git a/subsys/net/pkt_filter/base.c b/subsys/net/pkt_filter/base.c index 289a55e9d604e..6785cb215d4c6 100644 --- a/subsys/net/pkt_filter/base.c +++ b/subsys/net/pkt_filter/base.c @@ -114,6 +114,10 @@ static enum net_verdict evaluate(sys_slist_t *rule_head, struct net_pkt *pkt) SYS_SLIST_FOR_EACH_CONTAINER(rule_head, rule, node) { if (apply_tests(rule, pkt) == true) { + if (rule->result == NET_CONTINUE) { + net_pkt_set_priority(pkt, rule->priority); + continue; + } return rule->result; } } diff --git a/subsys/pmci/mctp/CMakeLists.txt b/subsys/pmci/mctp/CMakeLists.txt index aa32c208f00c9..43e77180e80e3 100644 --- a/subsys/pmci/mctp/CMakeLists.txt +++ b/subsys/pmci/mctp/CMakeLists.txt @@ -3,3 +3,5 @@ zephyr_library_sources(mctp_memory.c) zephyr_library_sources_ifdef(CONFIG_MCTP_UART mctp_uart.c) zephyr_library_sources_ifdef(CONFIG_MCTP_I2C_GPIO_CONTROLLER mctp_i2c_gpio_controller.c) zephyr_library_sources_ifdef(CONFIG_MCTP_I2C_GPIO_TARGET mctp_i2c_gpio_target.c) +zephyr_library_sources_ifdef(CONFIG_MCTP_USB mctp_usb.c) +zephyr_linker_sources_ifdef(CONFIG_MCTP_USB SECTIONS mctp_usb.ld) diff --git a/subsys/pmci/mctp/Kconfig b/subsys/pmci/mctp/Kconfig index 1d70ccc7b240d..1f5c8c21572f0 100644 --- a/subsys/pmci/mctp/Kconfig +++ b/subsys/pmci/mctp/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2024 Intel Corporation +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 menuconfig MCTP @@ -42,9 +43,16 @@ config MCTP_I2C_GPIO_TARGET Build the MCTP I2C+GPIO target binding to use MCTP over Zephyr's I2C target interface and GPIO to signal writes to the bus controller. +config MCTP_USB + bool "MCTP USB Binding" + depends on USB_DEVICE_STACK_NEXT + help + Build the MCTP USB binding to use MCTP over Zephyr's USB device interface. module = MCTP module-str = MCTP source "subsys/logging/Kconfig.template.log_config" +rsource "Kconfig.usb" + endif diff --git a/subsys/pmci/mctp/Kconfig.usb b/subsys/pmci/mctp/Kconfig.usb new file mode 100644 index 0000000000000..00eb16cdfa4a2 --- /dev/null +++ b/subsys/pmci/mctp/Kconfig.usb @@ -0,0 +1,18 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if MCTP_USB + +config MCTP_USB_TX_TIMEOUT + int "MCTP USB transmit timeout (ms)" + default 1000 + help + Set the MCTP USB transmit timeout, in milliseconds. + +module = MCTP_USB_CLASS +module-str = mctp usb class +default-count = 1 + +source "subsys/usb/device_next/class/Kconfig.template.instances_count" + +endif diff --git a/subsys/pmci/mctp/mctp_usb.c b/subsys/pmci/mctp/mctp_usb.c new file mode 100644 index 0000000000000..ef2a4a4c5c4df --- /dev/null +++ b/subsys/pmci/mctp/mctp_usb.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mctp_usb, CONFIG_MCTP_LOG_LEVEL); + +#include "libmctp-alloc.h" + +#define MCTP_USB_DMTF_0 0x1A +#define MCTP_USB_DMTF_1 0xB4 + +#define MCTP_USB_ENABLED 0 +#define MCTP_USB_NUM_INSTANCES CONFIG_MCTP_USB_CLASS_INSTANCES_COUNT + +UDC_BUF_POOL_DEFINE(mctp_usb_ep_pool, MCTP_USB_NUM_INSTANCES * 2, USBD_MAX_BULK_MPS, + sizeof(struct udc_buf_info), NULL); + +struct mctp_usb_class_desc { + struct usb_if_descriptor if0; + struct usb_ep_descriptor if0_fs_out_ep; + struct usb_ep_descriptor if0_fs_in_ep; + struct usb_ep_descriptor if0_hs_out_ep; + struct usb_ep_descriptor if0_hs_in_ep; + struct usb_desc_header nil_desc; +}; + +struct mctp_usb_class_ctx { + struct usbd_class_data *class_data; + struct mctp_usb_class_desc *const desc; + const struct usb_desc_header **const fs_desc; + const struct usb_desc_header **const hs_desc; + struct mctp_usb_class_inst *inst; + uint8_t inst_idx; + struct net_buf *out_net_buf; + uint8_t out_buf[USBD_MAX_BULK_MPS]; + struct k_work out_work; + atomic_t state; +}; + +static struct net_buf *mctp_usb_class_buf_alloc(const uint8_t ep) +{ + struct net_buf *buf = NULL; + struct udc_buf_info *bi; + + buf = net_buf_alloc(&mctp_usb_ep_pool, K_NO_WAIT); + if (!buf) { + return NULL; + } + + bi = udc_get_buf_info(buf); + bi->ep = ep; + + return buf; +} + +static uint8_t mctp_usb_class_get_bulk_in(struct usbd_class_data *const c_data) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + +#if USBD_SUPPORTS_HIGH_SPEED + if (usbd_bus_speed(usbd_class_get_ctx(ctx->class_data)) == USBD_SPEED_HS) { + return ctx->desc->if0_hs_in_ep.bEndpointAddress; + } +#endif + + return ctx->desc->if0_fs_in_ep.bEndpointAddress; +} + +static uint8_t mctp_usb_class_get_bulk_out(struct usbd_class_data *const c_data) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + +#if USBD_SUPPORTS_HIGH_SPEED + if (usbd_bus_speed(usbd_class_get_ctx(ctx->class_data)) == USBD_SPEED_HS) { + return ctx->desc->if0_hs_out_ep.bEndpointAddress; + } +#endif + + return ctx->desc->if0_fs_out_ep.bEndpointAddress; +} + +static void mctp_usb_reset_rx_state(struct mctp_binding_usb *usb) +{ + if (usb->rx_pkt != NULL) { + mctp_pktbuf_free(usb->rx_pkt); + } + + usb->rx_data_idx = 0; + usb->rx_state = STATE_WAIT_HDR_DMTF0; +} + +int mctp_usb_tx(struct mctp_binding *binding, struct mctp_pktbuf *pkt) +{ + struct mctp_binding_usb *usb = CONTAINER_OF(binding, struct mctp_binding_usb, binding); + struct usbd_class_data *c_data = usb->usb_class_data; + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + size_t len = mctp_pktbuf_size(pkt); + struct net_buf *buf = NULL; + int err; + + if (!atomic_test_bit(&ctx->state, MCTP_USB_ENABLED)) { + return -EPERM; + } + + if (len > MCTP_USB_MAX_PACKET_LENGTH) { + return -E2BIG; + } + + err = k_sem_take(&usb->tx_lock, K_MSEC(CONFIG_MCTP_USB_TX_TIMEOUT)); + if (err != 0) { + LOG_ERR("Semaphore could not be obtained"); + return err; + } + + 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; + + memcpy((void *)&usb->tx_buf[MCTP_USB_HEADER_SIZE], pkt->data, len); + + LOG_HEXDUMP_DBG(usb->tx_buf, len + MCTP_USB_HEADER_SIZE, "buf = "); + + if (usb->usb_class_data == NULL) { + LOG_ERR("MCTP instance not found"); + return -ENODEV; + } + + buf = mctp_usb_class_buf_alloc(mctp_usb_class_get_bulk_in(c_data)); + if (buf == NULL) { + k_sem_give(&usb->tx_lock); + LOG_ERR("Failed to allocate IN buffer"); + return -ENOMEM; + } + + net_buf_add_mem(buf, usb->tx_buf, len + MCTP_USB_HEADER_SIZE); + + err = usbd_ep_enqueue(c_data, buf); + if (err) { + k_sem_give(&usb->tx_lock); + LOG_ERR("Failed to enqueue IN buffer"); + net_buf_unref(buf); + return err; + } + + return 0; +} + +int mctp_usb_start(struct mctp_binding *binding) +{ + struct mctp_binding_usb *usb = CONTAINER_OF(binding, struct mctp_binding_usb, binding); + + k_sem_init(&usb->tx_lock, 1, 1); + mctp_binding_set_tx_enabled(binding, true); + + return 0; +} + +static void mctp_usb_class_out_work(struct k_work *work) +{ + struct mctp_usb_class_ctx *ctx = CONTAINER_OF(work, struct mctp_usb_class_ctx, out_work); + struct net_buf *buf; + size_t buf_size = 0; + + if (!atomic_test_bit(&ctx->state, MCTP_USB_ENABLED)) { + return; + } + + /* Move data from net_buf to our ctx buffer so we can receive another USB packet */ + if (ctx->out_net_buf != NULL) { + buf_size = ctx->out_net_buf->len; + memcpy(ctx->out_buf, ctx->out_net_buf->data, ctx->out_net_buf->len); + + /* Free the current buffer and allocate another for OUT */ + net_buf_unref(ctx->out_net_buf); + } + + buf = mctp_usb_class_buf_alloc(mctp_usb_class_get_bulk_out(ctx->class_data)); + if (buf == NULL) { + LOG_ERR("Failed to allocate OUT buffer"); + return; + } + + if (usbd_ep_enqueue(ctx->class_data, buf)) { + net_buf_unref(buf); + LOG_ERR("Failed to enqueue OUT buffer"); + } + + /* Process the MCTP data */ + struct mctp_binding_usb *usb = (struct mctp_binding_usb *)ctx->inst->mctp_binding; + + LOG_DBG("size=%d", ctx->out_net_buf->len); + LOG_HEXDUMP_DBG(buf, ctx->out_net_buf->len, "buf = "); + + for (int i = 0; i < buf_size; i++) { + switch (usb->rx_state) { + case STATE_WAIT_HDR_DMTF0: { + if (ctx->out_buf[i] == MCTP_USB_DMTF_0) { + usb->rx_state = STATE_WAIT_HDR_DMTF1; + } else { + LOG_ERR("Invalid DMTF0 %02X", ctx->out_buf[i]); + return; + } + break; + } + case STATE_WAIT_HDR_DMTF1: { + if (ctx->out_buf[i] == MCTP_USB_DMTF_1) { + usb->rx_state = STATE_WAIT_HDR_RSVD0; + } else { + LOG_ERR("Invalid DMTF1 %02X", ctx->out_buf[i]); + usb->rx_state = STATE_WAIT_HDR_DMTF0; + return; + } + break; + } + case STATE_WAIT_HDR_RSVD0: { + if (ctx->out_buf[i] == 0) { + usb->rx_state = STATE_WAIT_HDR_LEN; + } else { + LOG_ERR("Invalid RSVD0 %02X", ctx->out_buf[i]); + usb->rx_state = STATE_WAIT_HDR_DMTF0; + return; + } + break; + } + case STATE_WAIT_HDR_LEN: { + if (ctx->out_buf[i] > MCTP_USB_MAX_PACKET_LENGTH || ctx->out_buf[i] == 0) { + LOG_ERR("Invalid LEN %02X", ctx->out_buf[i]); + usb->rx_state = STATE_WAIT_HDR_DMTF0; + return; + } + + usb->rx_data_idx = 0; + usb->rx_pkt = mctp_pktbuf_alloc(&usb->binding, ctx->out_buf[i]); + if (usb->rx_pkt == NULL) { + LOG_ERR("Could not allocate PKT buffer"); + mctp_usb_reset_rx_state(usb); + return; + } + + usb->rx_state = STATE_DATA; + + LOG_DBG("Expecting LEN=%d", (int)ctx->out_buf[i]); + + break; + } + case STATE_DATA: { + usb->rx_pkt->data[usb->rx_data_idx++] = ctx->out_buf[i]; + + if (usb->rx_data_idx == usb->rx_pkt->end) { + LOG_DBG("Packet complete"); + mctp_bus_rx(&usb->binding, usb->rx_pkt); + mctp_usb_reset_rx_state(usb); + } + + break; + } + } + } +} + +static int mctp_usb_class_request(struct usbd_class_data *const c_data, struct net_buf *buf, + int err) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + struct udc_buf_info *bi = udc_get_buf_info(buf); + + LOG_DBG("request for EP 0x%x", bi->ep); + + if (err) { + if (err == -ECONNABORTED) { + LOG_WRN("request ep 0x%02x, len %u cancelled", bi->ep, buf->len); + } else { + LOG_ERR("request ep 0x%02x, len %u failed", bi->ep, buf->len); + } + + goto exit; + } + + if (bi->ep == mctp_usb_class_get_bulk_out(c_data)) { + ctx->out_net_buf = buf; + k_work_submit(&ctx->out_work); + } + + if (bi->ep == mctp_usb_class_get_bulk_in(c_data)) { + k_sem_give(&ctx->inst->mctp_binding->tx_lock); + net_buf_unref(buf); + } + +exit: + return 0; +} + +static void *mctp_usb_class_get_desc(struct usbd_class_data *const c_data, + const enum usbd_speed speed) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { + return ctx->hs_desc; + } + + return ctx->fs_desc; +} + +static void mctp_usb_class_enable(struct usbd_class_data *const c_data) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + + if (!atomic_test_and_set_bit(&ctx->state, MCTP_USB_ENABLED)) { + k_work_submit(&ctx->out_work); + } + + LOG_DBG("Enabled %s", c_data->name); +} + +static void mctp_usb_class_disable(struct usbd_class_data *const c_data) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + + atomic_clear_bit(&ctx->state, MCTP_USB_ENABLED); + + LOG_DBG("Disabled %s", c_data->name); +} + +static int mctp_usb_class_init(struct usbd_class_data *const c_data) +{ + struct mctp_usb_class_ctx *ctx = usbd_class_get_private(c_data); + size_t num_instances = 0; + + STRUCT_SECTION_COUNT(mctp_usb_class_inst, &num_instances); + + if (num_instances != MCTP_USB_NUM_INSTANCES) { + LOG_ERR("The number of application instances (%d) does not match the number " + "specified by CONFIG_MCTP_USB_CLASS_INSTANCES_COUNT (%d)", + num_instances, MCTP_USB_NUM_INSTANCES); + return -EINVAL; + } + + STRUCT_SECTION_GET(mctp_usb_class_inst, ctx->inst_idx, &ctx->inst); + + ctx->class_data = c_data; + ctx->state = 0; + + /* Share USB class data with the binding so that the binding */ + ctx->inst->mctp_binding->usb_class_data = c_data; + + k_work_init(&ctx->out_work, mctp_usb_class_out_work); + + if (ctx->inst->sublcass == USBD_MCTP_SUBCLASS_MANAGEMENT_CONTROLLER || + ctx->inst->sublcass == USBD_MCTP_SUBCLASS_MANAGED_DEVICE_ENDPOINT || + ctx->inst->sublcass == USBD_MCTP_SUBCLASS_HOST_INTERFACE_ENDPOINT) { + ctx->desc->if0.bInterfaceSubClass = ctx->inst->sublcass; + } else { + LOG_ERR("Invalid USB MCTP sublcass"); + return -EINVAL; + } + + if (ctx->inst->mctp_protocol == USBD_MCTP_PROTOCOL_1_X || + ctx->inst->mctp_protocol == USBD_MCTP_PROTOCOL_2_X) { + ctx->desc->if0.bInterfaceProtocol = ctx->inst->mctp_protocol; + } else { + LOG_ERR("Invalid MCTP protocol"); + return -EINVAL; + } + + LOG_DBG("MCTP device %s initialized", ctx->inst->mctp_binding->binding.name); + + return 0; +} + +struct usbd_class_api mctp_usb_class_api = { + .request = mctp_usb_class_request, + .enable = mctp_usb_class_enable, + .disable = mctp_usb_class_disable, + .init = mctp_usb_class_init, + .get_desc = mctp_usb_class_get_desc, +}; + +#define DEFINE_MCTP_USB_CLASS_DESCRIPTORS(n, _) \ + static struct mctp_usb_class_desc mctp_usb_class_desc_##n = { \ + .if0 = { \ + .bLength = sizeof(struct usb_if_descriptor), \ + .bDescriptorType = USB_DESC_INTERFACE, \ + .bInterfaceNumber = 0, \ + .bAlternateSetting = 0, \ + .bNumEndpoints = 2, \ + .bInterfaceClass = USB_BCC_MCTP, \ + .bInterfaceSubClass = 0, \ + .bInterfaceProtocol = 1, \ + .iInterface = 0 \ + }, \ + .if0_fs_out_ep = { \ + .bLength = sizeof(struct usb_ep_descriptor), \ + .bDescriptorType = USB_DESC_ENDPOINT, \ + .bEndpointAddress = 0x01, \ + .bmAttributes = USB_EP_TYPE_BULK, \ + .wMaxPacketSize = sys_cpu_to_le16(64), \ + .bInterval = 1 \ + }, \ + .if0_fs_in_ep = { \ + .bLength = sizeof(struct usb_ep_descriptor), \ + .bDescriptorType = USB_DESC_ENDPOINT, \ + .bEndpointAddress = 0x81, \ + .bmAttributes = USB_EP_TYPE_BULK, \ + .wMaxPacketSize = sys_cpu_to_le16(64), \ + .bInterval = 1 \ + }, \ + .if0_hs_out_ep = { \ + .bLength = sizeof(struct usb_ep_descriptor), \ + .bDescriptorType = USB_DESC_ENDPOINT, \ + .bEndpointAddress = 0x01, \ + .bmAttributes = USB_EP_TYPE_BULK, \ + .wMaxPacketSize = sys_cpu_to_le16(512), \ + .bInterval = 1 \ + }, \ + .if0_hs_in_ep = { \ + .bLength = sizeof(struct usb_ep_descriptor), \ + .bDescriptorType = USB_DESC_ENDPOINT, \ + .bEndpointAddress = 0x81, \ + .bmAttributes = USB_EP_TYPE_BULK, \ + .wMaxPacketSize = sys_cpu_to_le16(512), \ + .bInterval = 1 \ + }, \ + .nil_desc = { \ + .bLength = 0, \ + .bDescriptorType = 0 \ + } \ + }; \ + const static struct usb_desc_header *mctp_usb_class_fs_desc_##n[] = { \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0_fs_in_ep, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0_fs_out_ep, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.nil_desc \ + }; \ + \ + const static struct usb_desc_header *mctp_usb_class_hs_desc_##n[] = { \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0_hs_in_ep, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.if0_hs_out_ep, \ + (struct usb_desc_header *)&mctp_usb_class_desc_##n.nil_desc \ + }; + +#define DEFINE_MCTP_USB_CLASS_DATA(n, _) \ + static struct mctp_usb_class_ctx mctp_usb_class_ctx_##n = { \ + .desc = &mctp_usb_class_desc_##n, \ + .fs_desc = mctp_usb_class_fs_desc_##n, \ + .hs_desc = mctp_usb_class_hs_desc_##n, \ + .inst_idx = n, \ + .out_net_buf = NULL \ + }; \ + \ + USBD_DEFINE_CLASS(mctp_##n, &mctp_usb_class_api, &mctp_usb_class_ctx_##n, NULL); + +LISTIFY(MCTP_USB_NUM_INSTANCES, DEFINE_MCTP_USB_CLASS_DESCRIPTORS, ()) +LISTIFY(MCTP_USB_NUM_INSTANCES, DEFINE_MCTP_USB_CLASS_DATA, ()) diff --git a/subsys/pmci/mctp/mctp_usb.ld b/subsys/pmci/mctp/mctp_usb.ld new file mode 100644 index 0000000000000..fdbe6bfef107d --- /dev/null +++ b/subsys/pmci/mctp/mctp_usb.ld @@ -0,0 +1,3 @@ +#include + +ITERABLE_SECTION_ROM(mctp_usb_class_inst, Z_LINK_ITERABLE_SUBALIGN) diff --git a/tests/arch/arm/arm_user_stack_test/src/main.c b/tests/arch/arm/arm_user_stack_test/src/main.c index ee7e1ed90bbc1..71d9316aec358 100644 --- a/tests/arch/arm/arm_user_stack_test/src/main.c +++ b/tests/arch/arm/arm_user_stack_test/src/main.c @@ -23,8 +23,13 @@ volatile int *const attack_sp = &attack_stack[128]; const int sysno = K_SYSCALL_K_UPTIME_TICKS; k_tid_t low_tid, hi_tid; +struct k_timer timer; +volatile ZTEST_BMEM uint64_t hi_thread_runs, test_completed; + void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *pEsf) { + test_completed = 1; + k_timer_stop(&timer); ztest_test_pass(); k_thread_abort(low_tid); @@ -37,6 +42,24 @@ void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *pEsf) } } +static void timeout_handler(struct k_timer *timer) +{ + if (!test_completed) { + + printf("hi_thread_runs: %lld\n", hi_thread_runs); + /* the timer times out after 120s, + * by then hi_fn would have ran multiple times so + * compare against a random number like 1000 to make sure that + * hi_fn actually ran for a while + */ + if (hi_thread_runs > 1000) { + ztest_test_pass(); + } else { + ztest_test_fail(); + } + } +} + void attack_entry(void) { printf("Call %s from %s\n", __func__, k_is_user_context() ? "user" : "kernel"); @@ -79,11 +102,15 @@ void hi_fn(void *arg1, void *arg2, void *arg3) while (1) { attack_sp[-2] = (int)attack_entry; k_msleep(1); + hi_thread_runs++; } } ZTEST(arm_user_stack_test, test_arm_user_stack_corruption) { + k_timer_init(&timer, timeout_handler, NULL); + k_timer_start(&timer, K_SECONDS(120), K_NO_WAIT); + low_tid = k_thread_create(&th0, stk0, K_THREAD_STACK_SIZEOF(stk0), low_fn, NULL, NULL, NULL, 2, #ifdef CONFIG_FPU_SHARING diff --git a/tests/arch/arm/arm_user_stack_test/testcase.yaml b/tests/arch/arm/arm_user_stack_test/testcase.yaml index 49cd8fd3a00e8..0d7bafb8fa124 100644 --- a/tests/arch/arm/arm_user_stack_test/testcase.yaml +++ b/tests/arch/arm/arm_user_stack_test/testcase.yaml @@ -1,6 +1,7 @@ common: tags: - arm + timeout: 120 tests: arch.arm.user.stack: filter: CONFIG_CPU_CORTEX_M diff --git a/tests/arch/common/interrupt/src/nested_irq.c b/tests/arch/common/interrupt/src/nested_irq.c index e2a9b70ee360e..ca4cebe987881 100644 --- a/tests/arch/common/interrupt/src/nested_irq.c +++ b/tests/arch/common/interrupt/src/nested_irq.c @@ -45,11 +45,13 @@ #endif #elif defined(CONFIG_GIC) /* - * For the platforms that use the ARM GIC, use the SGI (software generated - * interrupt) lines 14 and 15 for testing. + * For platforms that use Arm's GIC, use the SGI (software generated + * interrupt) lines 6 and 7 for testing. + * SGI 0-2 are used by Zephyr for SMP IPIs. + * SGI 8-15 are unaccessible from Non-Secure state. */ -#define IRQ0_LINE 14 -#define IRQ1_LINE 15 +#define IRQ0_LINE 6 +#define IRQ1_LINE 7 /* * Choose lower prio for IRQ0 and higher priority for IRQ1 diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index f4143e31aac3e..dc940c0cc0b5e 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -22,7 +22,7 @@ CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y CONFIG_BT_GATT_AUTO_UPDATE_MTU=y CONFIG_BT_L2CAP_ECRED=y CONFIG_BT_SIGNING=y -CONFIG_BT_FIXED_PASSKEY=y +CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=5 CONFIG_BT_SHELL=y CONFIG_BT_DEVICE_NAME="audio test shell" diff --git a/tests/bluetooth/shell/log.conf b/tests/bluetooth/shell/log.conf index 746a3bbe57021..9068129f01aac 100644 --- a/tests/bluetooth/shell/log.conf +++ b/tests/bluetooth/shell/log.conf @@ -9,7 +9,7 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y CONFIG_BT_SIGNING=y -CONFIG_BT_FIXED_PASSKEY=y +CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/shell/prj.conf b/tests/bluetooth/shell/prj.conf index 85f9ae0072057..54c904e957a87 100644 --- a/tests/bluetooth/shell/prj.conf +++ b/tests/bluetooth/shell/prj.conf @@ -11,7 +11,7 @@ CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y CONFIG_BT_PASSKEY_KEYPRESS=y CONFIG_BT_SIGNING=y -CONFIG_BT_FIXED_PASSKEY=y +CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index fb95e77db8356..f1d4bfd1dfc26 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -626,6 +626,7 @@ struct bt_le_adv_param; struct bt_data; struct bt_le_ext_adv *tester_gap_ext_adv_get(uint8_t ext_adv_idx); struct bt_le_per_adv_sync *tester_gap_padv_get(void); +int tester_gap_clear_adv_instance(struct bt_le_ext_adv *ext_adv); int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len, diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index b60b82ccc83ac..da2a0e87c4d9e 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -601,6 +601,21 @@ static int tester_gap_ext_adv_idx_free_get(void) return -ENOMEM; } +static int tester_gap_ext_adv_idx_get(struct bt_le_ext_adv *ext_adv) +{ + if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { + return -ENOTSUP; + } + + for (int i = 0; i < ARRAY_SIZE(ext_adv_sets); i++) { + if (ext_adv_sets[i] == ext_adv) { + return i; + } + } + + return -EINVAL; +} + int tester_gap_start_ext_adv(struct bt_le_ext_adv *ext_adv) { if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { @@ -645,6 +660,8 @@ int tester_gap_stop_ext_adv(struct bt_le_ext_adv *ext_adv) return -EINVAL; } + tester_gap_clear_adv_instance(ext_adv); + atomic_clear_bit(¤t_settings, BTP_GAP_SETTINGS_ADVERTISING); return 0; @@ -751,6 +768,29 @@ static uint8_t set_bondable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +int tester_gap_clear_adv_instance(struct bt_le_ext_adv *ext_adv) +{ + if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { + return -ENOTSUP; + } + + if (ext_adv == NULL) { + LOG_ERR("Invalid ext_adv"); + return -EINVAL; + } + + int index = tester_gap_ext_adv_idx_get(ext_adv); + + if (index < 0) { + LOG_ERR("Failed to get ext_adv index"); + return -EINVAL; + } + + ext_adv_sets[index] = NULL; + + return 0; +} + int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len, uint32_t *settings, @@ -974,7 +1014,7 @@ static uint8_t stop_advertising(const void *cmd, uint16_t cmd_len, if (IS_ENABLED(CONFIG_BT_EXT_ADV) && atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) { - err = bt_le_ext_adv_stop(gap_ext_adv); + err = tester_gap_stop_ext_adv(gap_ext_adv); } else { err = bt_le_adv_stop(); } diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/central/CMakeLists.txt b/tests/bsim/bluetooth/host/misc/conn_stress/central/CMakeLists.txt index 84c6ff866b1d9..0bdf365cc15fc 100644 --- a/tests/bsim/bluetooth/host/misc/conn_stress/central/CMakeLists.txt +++ b/tests/bsim/bluetooth/host/misc/conn_stress/central/CMakeLists.txt @@ -5,6 +5,9 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(conn_stress_central) +add_subdirectory(${ZEPHYR_BASE}/tests/bsim/babblekit babblekit) +target_link_libraries(app PRIVATE babblekit) + target_sources(app PRIVATE src/main.c ) diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/central/prj.conf b/tests/bsim/bluetooth/host/misc/conn_stress/central/prj.conf index 3255ff8e86f69..9d1fbd3f5a6d3 100644 --- a/tests/bsim/bluetooth/host/misc/conn_stress/central/prj.conf +++ b/tests/bsim/bluetooth/host/misc/conn_stress/central/prj.conf @@ -22,11 +22,6 @@ CONFIG_ASSERT_LEVEL=2 CONFIG_ASSERT_VERBOSE=y CONFIG_ASSERT_ON_ERRORS=y -# TODO: use default 3 -# we get an ATT timeout if 3 -# we get an SMP timeout if 10 -# CONFIG_BT_L2CAP_TX_BUF_COUNT=10 - # deadlock on central with the default. # the problem is that `tx_free` is called from both syswq and btwq in that case. CONFIG_BT_RECV_WORKQ_BT=y 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 7ce3dbfe489d1..e17554c3f7f1d 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2023-2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,6 +30,8 @@ LOG_MODULE_REGISTER(central, LOG_LEVEL_INF); #include "bstests.h" #include "bs_pc_backchannel.h" +#include "babblekit/testcase.h" + #define DEFAULT_CONN_INTERVAL 20 #define PERIPHERAL_DEVICE_NAME "Zephyr Peripheral" #define PERIPHERAL_DEVICE_NAME_LEN (sizeof(PERIPHERAL_DEVICE_NAME) - 1) @@ -50,6 +52,8 @@ BUILD_ASSERT(NOTIFICATION_DATA_LEN <= CHARACTERISTIC_DATA_MAX_LEN); #define PERIPHERAL_SERVICE_UUID BT_UUID_DECLARE_128(PERIPHERAL_SERVICE_UUID_VAL) #define PERIPHERAL_CHARACTERISTIC_UUID BT_UUID_DECLARE_128(PERIPHERAL_CHARACTERISTIC_UUID_VAL) +#define EXPECTED_CONN_CYCLES 1 + static struct bt_uuid_128 vnd_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdea0)); @@ -69,6 +73,7 @@ enum { CONN_INFO_MTU_EXCHANGED, CONN_INFO_DISCOVERING, CONN_INFO_DISCOVER_PAUSED, + CONN_INFO_SUBSCRIPTION_FAILED, CONN_INFO_SUBSCRIBED, /* Total number of flags - must be at the end of the enum */ @@ -89,6 +94,7 @@ struct conn_info { struct bt_gatt_discover_params discover_params; struct bt_gatt_subscribe_params subscribe_params; bt_addr_le_t addr; + atomic_t conn_count; }; static struct conn_info conn_infos[CONFIG_BT_MAX_CONN] = {0}; @@ -208,6 +214,24 @@ static uint8_t notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params return BT_GATT_ITER_CONTINUE; } +static void subscribe_func(struct bt_conn *conn, uint8_t err, + struct bt_gatt_subscribe_params *params) +{ + struct conn_info *conn_info_ref; + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + __ASSERT(!err, "Subscribe failed for addr %s (err %d)", addr, err); + + conn_info_ref = get_conn_info_ref(conn); + __ASSERT_NO_MSG(conn_info_ref); + + atomic_clear_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIPTION_FAILED); + atomic_set_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIBED); + + LOG_DBG("[SUBSCRIBED] addr %s", addr); +} + static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, struct bt_gatt_discover_params *params) { @@ -232,8 +256,6 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at conn_info_ref = get_connected_conn_info_ref(conn); __ASSERT_NO_MSG(conn_info_ref); - atomic_clear_bit(conn_info_ref->flags, CONN_INFO_DISCOVER_PAUSED); - if (conn_info_ref->discover_params.type == BT_GATT_DISCOVER_PRIMARY) { LOG_DBG("Primary Service Found"); memcpy(&conn_info_ref->uuid, @@ -245,6 +267,7 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at err = bt_gatt_discover(conn, &conn_info_ref->discover_params); if (err == -ENOMEM || err == -ENOTCONN) { + atomic_set_bit(conn_info_ref->flags, CONN_INFO_DISCOVER_PAUSED); goto retry; } @@ -260,6 +283,7 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at err = bt_gatt_discover(conn, &conn_info_ref->discover_params); if (err == -ENOMEM || err == -ENOTCONN) { + atomic_set_bit(conn_info_ref->flags, CONN_INFO_DISCOVER_PAUSED); goto retry; } @@ -267,26 +291,19 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at } else { conn_info_ref->subscribe_params.notify = notify_func; + conn_info_ref->subscribe_params.subscribe = subscribe_func; conn_info_ref->subscribe_params.value = BT_GATT_CCC_NOTIFY; conn_info_ref->subscribe_params.ccc_handle = attr->handle; err = bt_gatt_subscribe(conn, &conn_info_ref->subscribe_params); - if (err == -ENOMEM || err == -ENOTCONN) { + if (err == -ENOMEM || err == -ENOTCONN || err == -EALREADY) { + LOG_DBG("Subcription failed (err %d)", err); + atomic_set_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIPTION_FAILED); goto retry; } - if (err != -EALREADY) { - __ASSERT(!err, "Subscribe failed (err %d)", err); - } - __ASSERT_NO_MSG(atomic_test_bit(conn_info_ref->flags, CONN_INFO_DISCOVERING)); __ASSERT_NO_MSG(!atomic_test_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIBED)); - atomic_set_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIBED); - - char addr[BT_ADDR_LE_STR_LEN]; - - bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); - LOG_INF("[SUBSCRIBED] addr %s", addr); } return BT_GATT_ITER_STOP; @@ -295,8 +312,7 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at /* if we're out of buffers or metadata contexts, continue discovery * later. */ - LOG_INF("out of memory/not connected, continuing sub later"); - atomic_set_bit(conn_info_ref->flags, CONN_INFO_DISCOVER_PAUSED); + LOG_INF("out of memory/not connected, continuing sub later (err %d)", err); return BT_GATT_ITER_STOP; } @@ -328,6 +344,17 @@ static bool check_if_peer_connected(const bt_addr_le_t *addr) return false; } +static bool check_if_completed(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(conn_infos); i++) { + if (atomic_get(&conn_infos[i].conn_count) < EXPECTED_CONN_CYCLES) { + return false; + } + } + + return true; +} + static bool parse_ad(struct bt_data *data, void *user_data) { bt_addr_le_t *addr = user_data; @@ -451,6 +478,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) bt_conn_unref(conn); clear_info(conn_info_ref); atomic_dec(&conn_count); + atomic_inc(&conn_info_ref->conn_count); } #if defined(CONFIG_BT_SMP) @@ -564,6 +592,18 @@ static void subscribe_to_service(struct bt_conn *conn, void *data) return; } + /* If subcription attempt failed before (due to most likely lack of TX buffers), + * make a new attempt here. + */ + if (atomic_test_bit(conn_info_ref->flags, CONN_INFO_SUBSCRIPTION_FAILED)) { + err = bt_gatt_subscribe(conn, &conn_info_ref->subscribe_params); + if (err != -ENOMEM) { + __ASSERT(!err, "Subcription failed"); + } else { + return; + } + } + /* start subscription procedure if: * - we haven't started it yet for this conn * - it was suspended due to a lack of resources @@ -602,6 +642,8 @@ static void subscribe_to_service(struct bt_conn *conn, void *data) if (err != -ENOMEM && err != -ENOTCONN) { __ASSERT(!err, "Subscribe failed (err %d)", err); } + + atomic_clear_bit(conn_info_ref->flags, CONN_INFO_DISCOVER_PAUSED); } } @@ -669,7 +711,7 @@ void test_central_main(void) start_scan(); - while (true) { + while (!check_if_completed()) { /* reconnect peripherals when they drop out */ if (atomic_get(&conn_count) < CONFIG_BT_MAX_CONN && !atomic_test_bit(status_flags, DEVICE_IS_SCANNING) && @@ -698,6 +740,8 @@ void test_central_main(void) } k_msleep(10); } + + TEST_PASS("Central tests passed"); } void test_init(void) @@ -705,6 +749,7 @@ void test_init(void) extern enum bst_result_t bst_result; LOG_INF("Initializing Test"); + bst_ticker_set_next_tick_absolute(100*1e6); /* The peripherals determines whether the test passed. */ bst_result = Passed; } @@ -739,12 +784,23 @@ static void test_args(int argc, char **argv) bs_trace_raw(0, "Notification data size : %d\n", notification_size); } +static void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + TEST_FAIL("Test timeout (not passed after %lu seconds)", + (unsigned long)(HW_device_time / USEC_PER_SEC)); + } + + bs_trace_silent_exit(0); +} + static const struct bst_test_instance test_def[] = { { .test_id = "central", .test_descr = "Central Connection Stress", .test_args_f = test_args, .test_pre_init_f = test_init, + .test_tick_f = test_tick, .test_main_f = test_central_main }, BSTEST_END_MARKER diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/CMakeLists.txt b/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/CMakeLists.txt index 3b18f1052925f..eec4a5f36524d 100644 --- a/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/CMakeLists.txt +++ b/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/CMakeLists.txt @@ -5,6 +5,9 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(conn_stress_peripheral) +add_subdirectory(${ZEPHYR_BASE}/tests/bsim/babblekit babblekit) +target_link_libraries(app PRIVATE babblekit) + target_sources(app PRIVATE src/main.c ) 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 b46d52b60d791..d9b56cc6c54f8 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2023-2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,8 @@ LOG_MODULE_REGISTER(peripheral, LOG_LEVEL_INF); #include "bs_pc_backchannel.h" #include "argparse.h" -#define TEST_ROUNDS 10 +#include "babblekit/testcase.h" + #define MIN_NOTIFICATIONS 50 #define NOTIFICATION_DATA_PREFIX "Counter:" @@ -52,6 +53,8 @@ BUILD_ASSERT(NOTIFICATION_DATA_LEN <= CHARACTERISTIC_DATA_MAX_LEN); #define CENTRAL_SERVICE_UUID BT_UUID_DECLARE_128(CENTRAL_SERVICE_UUID_VAL) #define CENTRAL_CHARACTERISTIC_UUID BT_UUID_DECLARE_128(CENTRAL_CHARACTERISTIC_UUID_VAL) +#define EXPECTED_CONN_CYCLES 1 + /* Custom Service Variables */ static struct bt_uuid_128 vnd_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)); @@ -164,7 +167,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) memset(&conn_info, 0x00, sizeof(struct active_conn_info)); - if (rounds >= TEST_ROUNDS) { + if (rounds >= EXPECTED_CONN_CYCLES) { LOG_INF("Number of conn/disconn cycles reached, stopping advertiser..."); bt_le_adv_stop(); @@ -400,7 +403,23 @@ void test_peripheral_main(void) sprintf(name, "per-%d", get_device_nbr()); bt_set_name(name); - err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, NULL, 0, NULL, 0); + struct bt_le_adv_param adv_param = { + .id = BT_ID_DEFAULT, + .sid = 0, + .secondary_max_skip = 0, + .options = BT_LE_ADV_OPT_CONN | BT_LE_ADV_OPT_SCANNABLE, + .interval_min = 0x0020, /* 20 ms */ + .interval_max = 0x0020, /* 20 ms */ + .peer = NULL, + }; + + struct bt_data sd[1]; + + sd[0].type = BT_DATA_NAME_COMPLETE; + sd[0].data_len = sizeof(CONFIG_BT_DEVICE_NAME) - 1; + sd[0].data = CONFIG_BT_DEVICE_NAME; + + err = bt_le_adv_start(&adv_param, sd, 1, sd, 1); if (err) { LOG_ERR("Advertising failed to start (err %d)", err); __ASSERT_NO_MSG(err); @@ -411,7 +430,7 @@ void test_peripheral_main(void) vnd_attr = bt_gatt_find_by_uuid(vnd_svc.attrs, vnd_svc.attr_count, &vnd_enc_uuid.uuid); - while (true) { + for (size_t i = 0; i < EXPECTED_CONN_CYCLES; i++) { LOG_DBG("Waiting for connection from central.."); while (!atomic_test_bit(conn_info.flags, CONN_INFO_CONNECTED)) { k_sleep(K_MSEC(10)); @@ -425,6 +444,7 @@ void test_peripheral_main(void) k_sleep(K_MSEC(10)); } + LOG_DBG("Waiting until MTU exchange.."); while (!atomic_test_bit(conn_info.flags, CONN_INFO_MTU_EXCHANGED)) { k_sleep(K_MSEC(10)); } @@ -453,6 +473,8 @@ void test_peripheral_main(void) } } } + + TEST_PASS("Peripheral tests passed"); } void test_init(void) @@ -460,6 +482,7 @@ void test_init(void) extern enum bst_result_t bst_result; LOG_INF("Initializing Test"); + bst_ticker_set_next_tick_absolute(100*1e6); bst_result = Failed; } @@ -481,12 +504,23 @@ static void test_args(int argc, char **argv) bs_trace_raw(0, "Notification data size : %d\n", notification_size); } +static void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + TEST_FAIL("Test timeout (not passed after %lu seconds)", + (unsigned long)(HW_device_time / USEC_PER_SEC)); + } + + bs_trace_silent_exit(0); +} + static const struct bst_test_instance test_def[] = { { .test_id = "peripheral", .test_descr = "Peripheral Connection Stress", .test_args_f = test_args, .test_pre_init_f = test_init, + .test_tick_f = test_tick, .test_main_f = test_peripheral_main }, BSTEST_END_MARKER diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/scripts/_conn_stress.sh b/tests/bsim/bluetooth/host/misc/conn_stress/scripts/_conn_stress.sh deleted file mode 100755 index 8e1428e44c04b..0000000000000 --- a/tests/bsim/bluetooth/host/misc/conn_stress/scripts/_conn_stress.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2023 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -source ${ZEPHYR_BASE}/tests/bsim/sh_common.source - -simulation_id="conn_stress" -process_ids=""; exit_code=0 - -# We don't use the `Execute` fn from `bsim/sh_common.source` as -# `wait_for_background_jobs` will terminate the script if there's an error, and -# this test will fail often. We still want to run the packet conversion scripts, -# especially if the test was not successful. -function Execute(){ - if [ ! -f $1 ]; then - echo -e "ERR! \e[91m`pwd`/`basename $1` cannot be found (did you forget to\ - compile it?)\e[39m" - exit 1 - fi - timeout 60 $@ & process_ids="$process_ids $!" - - echo "Running $@" -} - -test_path="bsim_bluetooth_host_misc_conn_stress" -bsim_central_exe_name="bs_${BOARD_TS}_${test_path}_central_prj_conf" -bsim_peripheral_exe_name="bs_${BOARD_TS}_${test_path}_peripheral_prj_conf" - -# terminate running simulations (if any) -${BSIM_COMPONENTS_PATH}/common/stop_bsim.sh $simulation_id - -cd ${BSIM_OUT_PATH}/bin - -bsim_args="-RealEncryption=1 -v=2 -s=${simulation_id}" -test_args="-argstest notify_size=220 conn_interval=32" - -nr_of_units=12 - -for device in `seq 1 $nr_of_units`; do - let rs=$device*100 - - Execute "./${bsim_peripheral_exe_name}" ${bsim_args} \ - -d=$device -rs=$rs -testid=peripheral ${test_args} -done - -Execute ./bs_2G4_phy_v1 -dump -v=2 -s=${simulation_id} -D=13 -sim_length=1000e6 & - -Execute "./${bsim_central_exe_name}" ${bsim_args} -d=0 -rs=001 -testid=central ${test_args} - -for process_id in $process_ids; do - wait $process_id || let "exit_code=$?" -done - -for i in `seq -w 0 $nr_of_units`; do - ${BSIM_OUT_PATH}/components/ext_2G4_phy_v1/dump_post_process/csv2pcap -o \ - ${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.pcap \ - ${BSIM_OUT_PATH}/results/${simulation_id}/d_2G4_$i.Tx.csv - - ${BSIM_OUT_PATH}/components/ext_2G4_phy_v1/dump_post_process/csv2pcap -o \ - ${BSIM_OUT_PATH}/results/${simulation_id}/Trace_Rx_$i.pcap \ - ${BSIM_OUT_PATH}/results/${simulation_id}/d_2G4_$i.Rx.csv - - echo "${BSIM_OUT_PATH}/results/${simulation_id}/Trace_$i.pcap" - echo "${BSIM_OUT_PATH}/results/${simulation_id}/Trace_Rx_$i.pcap" -done - -exit $exit_code diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/scripts/conn_stress.sh b/tests/bsim/bluetooth/host/misc/conn_stress/scripts/conn_stress.sh new file mode 100755 index 0000000000000..e1d81ff85ae89 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/conn_stress/scripts/conn_stress.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright (c) 2023-2025 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="conn_stress" + +test_path="tests_bsim_bluetooth_host_misc_conn_stress" +bsim_central_exe_name="bs_${BOARD_TS}_${test_path}_central_prj_conf" +bsim_peripheral_exe_name="bs_${BOARD_TS}_${test_path}_peripheral_prj_conf" +bsim_args="-RealEncryption=1 -v=2 -s=${simulation_id}" +test_args="-argstest notify_size=220 conn_interval=32" + +EXECUTE_TIMEOUT=120 + +cd ${BSIM_OUT_PATH}/bin + +for device in `seq 1 12`; do + let rs=$device*100 + + Execute "./${bsim_peripheral_exe_name}" ${bsim_args} \ + -d=$device -rs=$rs -testid=peripheral ${test_args} +done + +Execute "./${bsim_central_exe_name}" ${bsim_args} -d=0 -rs=1 -testid=central ${test_args} + +Execute ./bs_2G4_phy_v1 -dump -v=2 -s=${simulation_id} -D=13 -sim_length=100e6 + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index f7489f9e8315c..290b4365ef2a1 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -688,7 +688,9 @@ static void test_tx_send_relay(void) net_buf_simple_add_u8(&relay_second->b, 0x02); bt_mesh_adv_send(local, &local_send_cb, NULL); + k_sleep(K_MSEC(1)); bt_mesh_adv_send(relay_first, &relay_first_send_cb, NULL); + k_sleep(K_MSEC(1)); bt_mesh_adv_send(relay_second, &relay_second_send_cb, NULL); bt_mesh_adv_unref(local); diff --git a/tests/drivers/adc/adc_accuracy_test/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/adc/adc_accuracy_test/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from tests/drivers/adc/adc_accuracy_test/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/adc/adc_accuracy_test/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/tests/drivers/adc/adc_api/boards/kit_psc3m5_evk.overlay b/tests/drivers/adc/adc_api/boards/kit_psc3m5_evk.overlay new file mode 100644 index 0000000000000..2ff1c86efdbf7 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 1>, <&adc0 2>, <&adc0 12>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; /* child channels */ + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <12>; + }; + + channel@12 { + reg = <12>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <12>; + }; +}; diff --git a/tests/drivers/adc/adc_api/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/adc/adc_api/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 95% rename from tests/drivers/adc/adc_api/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/adc/adc_api/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay index 5248c25ae7a4a..87707847eeab2 100644 --- a/tests/drivers/adc/adc_api/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay +++ b/tests/drivers/adc/adc_api/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay @@ -6,7 +6,7 @@ / { zephyr,user { - io-channels = <&adc 0>, <&adc 1>, <&adc 2>; + io-channels = <&adc 0>, <&adc 1> , <&adc 2>; }; }; diff --git a/tests/drivers/adc/adc_api/testcase.yaml b/tests/drivers/adc/adc_api/testcase.yaml index 25bcedc3aa7fd..92caafb10ce1e 100644 --- a/tests/drivers/adc/adc_api/testcase.yaml +++ b/tests/drivers/adc/adc_api/testcase.yaml @@ -15,14 +15,16 @@ tests: - panb611evb/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l15/cpuapp/ns - bl54l15u_dvk/nrf54l15/cpuapp/ns - - raytac_an54l15q_db/nrf54l15/cpuapp/ns - rpi_pico/rp2040/mcuboot - rpi_pico/rp2040/w/mcuboot - rpi_pico2/rp2350a/m33/mcuboot - rpi_pico2/rp2350a/m33/w/mcuboot + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns + drivers.adc.b_u585i_iot02a_adc4: extra_args: - platform:b_u585i_iot02a/stm32u585xx:DTC_OVERLAY_FILE="boards/b_u585i_iot02a_adc4.overlay" integration_platforms: diff --git a/tests/drivers/adc/adc_error_cases/Kconfig b/tests/drivers/adc/adc_error_cases/Kconfig new file mode 100644 index 0000000000000..cdd9b443424a7 --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config TEST_ADC_ERROR_CASES_RESOLUTION + int + default 12 if SOC_FAMILY_SILABS_S2 || SOC_SERIES_PSC3 + default 10 diff --git a/tests/drivers/adc/adc_error_cases/boards/kit_psc3m5_evk.overlay b/tests/drivers/adc/adc_error_cases/boards/kit_psc3m5_evk.overlay new file mode 100644 index 0000000000000..5d8e185a1b836 --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + adc = &adc0; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; /* child channels */ + #size-cells = <0>; + + channel@1 { + reg = <1>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; + + channel@12 { + reg = <12>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + }; +}; diff --git a/tests/drivers/adc/adc_error_cases/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/adc/adc_error_cases/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from tests/drivers/adc/adc_error_cases/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/adc/adc_error_cases/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c b/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c index 754d2ad98d7bf..dd6904836d968 100644 --- a/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c +++ b/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c @@ -24,11 +24,7 @@ static const struct adc_channel_cfg valid_channel_cfg = { #endif }; -#if defined(CONFIG_SOC_FAMILY_SILABS_S2) -#define VALID_RESOLUTION 12 -#else -#define VALID_RESOLUTION 10 -#endif +#define VALID_RESOLUTION CONFIG_TEST_ADC_ERROR_CASES_RESOLUTION static const struct adc_sequence valid_seq = { .buffer = m_sample_buffer, diff --git a/tests/drivers/build_all/mfd/app.overlay b/tests/drivers/build_all/mfd/app.overlay index 92e4cd79c003f..4ac98d6bc661a 100644 --- a/tests/drivers/build_all/mfd/app.overlay +++ b/tests/drivers/build_all/mfd/app.overlay @@ -15,6 +15,28 @@ #address-cells = <1>; #size-cells = <1>; + test_i2c: i2c@33335555{ + status = "okay"; + compatible = "vnd,i2c"; + reg = <0x33335555 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + sc18is606: sc18is606@28 { + compatible ="nxp,sc18is606"; + status = "okay"; + reg = <0x28>; + + spi_ext: sc18is606_spi { + compatible = "nxp,sc18is606-spi"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + frequency = <1875>; + }; + }; + }; + test_uart: uart@55556666 { compatible = "vnd,serial"; reg = <0x55556666 0x1000>; diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 27731a13a1d4d..35849732143d6 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -41,6 +41,8 @@ test_i2c_adt7420: adt7420@0 { test_i2c_adxl345: adxl345@1 { compatible = "adi,adxl345"; reg = <0x1>; + int1-gpios = <&test_gpio 0 0>; + fifo-watermark = <1>; }; test_i2c_adxl372: adxl372@2 { @@ -785,6 +787,7 @@ test_i2c_bmi08x_accel: bmi08x@6d { int2-conf-io = <0x17>; accel-hz = "800"; accel-fs = <4>; + fifo-watermark = <1>; }; test_i2c_bmi08x_gyro: bmi08x@6e { @@ -795,6 +798,7 @@ test_i2c_bmi08x_gyro: bmi08x@6e { int3-4-conf-io = <0x01>; gyro-hz = "1000_116"; gyro-fs = <1000>; + fifo-watermark = <1>; }; test_i2c_ist8310: ist8310@6f { @@ -1429,3 +1433,8 @@ test_i2c_hdc302x: hdc302x@be { reg = <0xbe>; int-gpios = <&test_gpio 0 0>; }; + +test_i2c_veml6046: veml6046@bf { + compatible = "vishay,veml6046"; + reg = <0xbf>; +}; diff --git a/tests/drivers/build_all/sensor/sensors_async_api.conf b/tests/drivers/build_all/sensor/sensors_async_api.conf new file mode 100644 index 0000000000000..e465f9af4a420 --- /dev/null +++ b/tests/drivers/build_all/sensor/sensors_async_api.conf @@ -0,0 +1,16 @@ +CONFIG_SENSOR_ASYNC_API=y +CONFIG_ADXL345_STREAM=y +CONFIG_ADXL362_STREAM=y +CONFIG_ADXL367_STREAM=y +CONFIG_ADXL372_STREAM=y +CONFIG_BMA4XX_STREAM=y +CONFIG_BMM350_STREAM=y +CONFIG_PAA3905_STREAM=y +CONFIG_PAT9136_STREAM=y +CONFIG_RM3100_STREAM=y +CONFIG_IIS3DWB_STREAM=y +CONFIG_LSM6DSV16X_STREAM=y +CONFIG_ICM45686_STREAM=y +CONFIG_ICM4268X_STREAM=y +CONFIG_BMI08X_GYRO_STREAM=y +CONFIG_BMI08X_ACCEL_STREAM=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index 80e6b1d08acd8..1aa73779cf18c 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -277,6 +277,7 @@ test_spi_bmi08x_accel: bmi08x@23 { int2-conf-io = <0x17>; accel-hz = "800"; accel-fs = <4>; + fifo-watermark = <1>; }; test_spi_bmi08x_gyro: bmi08x@24 { @@ -288,6 +289,7 @@ test_spi_bmi08x_gyro: bmi08x@24 { int3-4-conf-io = <0x01>; gyro-hz = "1000_116"; gyro-fs = <1000>; + fifo-watermark = <1>; }; test_spi_tmag5170: tmag5170@25 { @@ -479,3 +481,11 @@ test_spi_iis3dwb: iis3dwb@39 { odr = ; filter = ; }; + +test_spi_adxl345: adxl345@3a { + compatible = "adi,adxl345"; + reg = <0x3a>; + spi-max-frequency = <0>; + int1-gpios = <&test_gpio 0 0>; + fifo-watermark = <1>; +}; diff --git a/tests/drivers/build_all/sensor/testcase.yaml b/tests/drivers/build_all/sensor/testcase.yaml index 1786d809d7252..eef3e25d79c47 100644 --- a/tests/drivers/build_all/sensor/testcase.yaml +++ b/tests/drivers/build_all/sensor/testcase.yaml @@ -18,6 +18,8 @@ tests: extra_args: EXTRA_CONF_FILE=sensors_trigger_none.conf;sensors_die_temp.conf drivers.sensor.no_default.build: extra_args: EXTRA_CONF_FILE=sensors_no_default.conf + drivers.sensor.async_api: + extra_args: EXTRA_CONF_FILE=sensors_async_api.conf drivers.sensor.build: tags: sensors extra_args: EXTRA_CONF_FILE=sensors_die_temp.conf diff --git a/tests/drivers/build_all/spi/app.overlay b/tests/drivers/build_all/spi/app.overlay new file mode 100644 index 0000000000000..c55ca99a981a7 --- /dev/null +++ b/tests/drivers/build_all/spi/app.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 tinyvision.ai + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i2c0{ + status = "okay"; + + sc18is606: sc18is606@28 { + compatible ="nxp,sc18is606"; + status = "okay"; + reg = <0x28>; + + spi_ext: sc18is606_spi { + compatible = "nxp,sc18is606-spi"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + frequency = <0>; + }; + }; +}; diff --git a/tests/drivers/build_all/spi/testcase.yaml b/tests/drivers/build_all/spi/testcase.yaml index 5b275c69f1c2a..ce1d8c3a8b5d4 100644 --- a/tests/drivers/build_all/spi/testcase.yaml +++ b/tests/drivers/build_all/spi/testcase.yaml @@ -4,7 +4,7 @@ common: - drivers - spi tests: - drivers.spi.build: + drivers.spi.build.spi_cdns: # will cover drivers without in-tree boards platform_allow: qemu_cortex_m3 tags: spi_cdns diff --git a/tests/drivers/build_all/video/testcase.yaml b/tests/drivers/build_all/video/testcase.yaml index dc8300b6e37a1..cb3e09527d351 100644 --- a/tests/drivers/build_all/video/testcase.yaml +++ b/tests/drivers/build_all/video/testcase.yaml @@ -44,3 +44,10 @@ tests: drivers.video.stm32_venc.build: platform_allow: - stm32n6570_dk/stm32n657xx/sb + extra_configs: + - CONFIG_VIDEO_ENCODER_H264=y + drivers.video.stm32_jpeg.build: + platform_allow: + - stm32n6570_dk/stm32n657xx/sb + extra_configs: + - CONFIG_VIDEO_ENCODER_JPEG=y diff --git a/tests/drivers/clock_control/nrf_clock_control/src/main.c b/tests/drivers/clock_control/nrf_clock_control/src/main.c index 83fdc98ca1934..3612373a867dd 100644 --- a/tests/drivers/clock_control/nrf_clock_control/src/main.c +++ b/tests/drivers/clock_control/nrf_clock_control/src/main.c @@ -162,17 +162,10 @@ static const struct test_clk_context lfclk_test_clk_contexts[] = { #define AUXPLL_NODE DT_INST(0, AUXPLL_COMPAT) #define AUXPLL_FREQ DT_PROP(AUXPLL_NODE, nordic_frequency) -/* Gets selected AUXPLL DIV and selects the expected frequency */ -#if AUXPLL_FREQ == NRF_AUXPLL_FREQUENCY_DIV_MIN -#define AUXPLL_FREQ_OUT 80000000 -#elif AUXPLL_FREQ == NRF_AUXPLL_FREQ_DIV_AUDIO_44K1 -#define AUXPLL_FREQ_OUT 11289591 -#elif AUXPLL_FREQ == NRF_AUXPLL_FREQ_DIV_USB_24M -#define AUXPLL_FREQ_OUT 24000000 -#elif AUXPLL_FREQ == NRF_AUXPLL_FREQ_DIV_AUDIO_48K -#define AUXPLL_FREQ_OUT 12287963 -#else -/*No use case for NRF_AUXPLL_FREQ_DIV_MAX or others yet*/ + +/* Gets expected AUXPLL frequency */ +#define AUXPLL_FREQ_OUT CLOCK_CONTROL_NRF_AUXPLL_GET_FREQ(AUXPLL_NODE) +#if AUXPLL_FREQ_OUT == 0 #error "Unsupported AUXPLL frequency selection" #endif 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 841853d3b7f0f..34406d88a3919 100644 --- a/tests/drivers/counter/counter_basic_api/src/test_counter.c +++ b/tests/drivers/counter/counter_basic_api/src/test_counter.c @@ -94,7 +94,7 @@ static const struct device *const devices[] = { DEVS_FOR_DT_COMPAT(st_stm32_rtc) #endif #ifdef CONFIG_COUNTER_GECKO_STIMER - DEVS_FOR_DT_COMPAT(silabs_gecko_stimer) + DEVICE_DT_GET(DT_CHOSEN(silabs_sleeptimer)), #endif #ifdef CONFIG_COUNTER_NXP_PIT DEVS_FOR_DT_COMPAT(nxp_pit_channel) diff --git a/tests/drivers/flash/common/boards/rza3ul_smarc.conf b/tests/drivers/flash/common/boards/rza3ul_smarc.conf new file mode 100644 index 0000000000000..d8d3631c5d59c --- /dev/null +++ b/tests/drivers/flash/common/boards/rza3ul_smarc.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_TEST_DRIVER_FLASH_SIZE=16777216 diff --git a/tests/drivers/flash/common/boards/rza3ul_smarc.overlay b/tests/drivers/flash/common/boards/rza3ul_smarc.overlay new file mode 100644 index 0000000000000..a427cde3b5aae --- /dev/null +++ b/tests/drivers/flash/common/boards/rza3ul_smarc.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&at25ql128a { + status = "okay"; +}; diff --git a/tests/drivers/flash/common/boards/rzn2l_rsk.conf b/tests/drivers/flash/common/boards/rzn2l_rsk.conf new file mode 100644 index 0000000000000..349d703d783c2 --- /dev/null +++ b/tests/drivers/flash/common/boards/rzn2l_rsk.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_TEST_DRIVER_FLASH_SIZE=67108864 diff --git a/tests/drivers/flash/common/boards/rzn2l_rsk.overlay b/tests/drivers/flash/common/boards/rzn2l_rsk.overlay new file mode 100644 index 0000000000000..bc059c7cb3bf9 --- /dev/null +++ b/tests/drivers/flash/common/boards/rzn2l_rsk.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&mx25u51245g { + status = "okay"; +}; diff --git a/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf b/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf new file mode 100644 index 0000000000000..349d703d783c2 --- /dev/null +++ b/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_TEST_DRIVER_FLASH_SIZE=67108864 diff --git a/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay b/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay new file mode 100644 index 0000000000000..bc059c7cb3bf9 --- /dev/null +++ b/tests/drivers/flash/common/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&mx25u51245g { + status = "okay"; +}; diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index e9d4a1c15bac3..8d9265d0bf361 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -25,6 +25,10 @@ #define TEST_AREA_DEV_NODE DT_INST(0, jedec_mspi_nor) #elif defined(CONFIG_FLASH_RENESAS_RA_QSPI) #define TEST_AREA_DEV_NODE DT_INST(0, renesas_ra_qspi_nor) +#elif defined(CONFIG_FLASH_RENESAS_RZ_QSPI_XSPI) +#define TEST_AREA_DEV_NODE DT_INST(0, renesas_rz_qspi_xspi) +#elif defined(CONFIG_FLASH_RENESAS_RZ_QSPI_SPIBSC) +#define TEST_AREA_DEV_NODE DT_INST(0, renesas_rz_qspi_spibsc) #else #define TEST_AREA storage_partition #endif diff --git a/tests/drivers/fuel_gauge/ltc2959/CMakeLists.txt b/tests/drivers/fuel_gauge/ltc2959/CMakeLists.txt new file mode 100644 index 0000000000000..afc875718de71 --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/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(device) + +target_sources(app PRIVATE src/test_ltc2959.c) diff --git a/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.conf b/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.conf new file mode 100644 index 0000000000000..022a71dd0f0a6 --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y diff --git a/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.overlay b/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.overlay new file mode 100644 index 0000000000000..3a3511ee5bc74 --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/boards/native_sim.overlay @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + */ + +&i2c0 { + ltc2959: ltc2959@63 { + compatible = "adi,ltc2959"; + reg = <0x63>; + rsense-milliohms = <50>; + status = "okay"; + }; +}; diff --git a/tests/drivers/fuel_gauge/ltc2959/prj.conf b/tests/drivers/fuel_gauge/ltc2959/prj.conf new file mode 100644 index 0000000000000..824ffaf7142a3 --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_I2C=y +CONFIG_TEST_USERSPACE=y +CONFIG_LOG=y + +CONFIG_FUEL_GAUGE=y +CONFIG_FUEL_GAUGE_LTC2959=y diff --git a/tests/drivers/fuel_gauge/ltc2959/src/test_ltc2959.c b/tests/drivers/fuel_gauge/ltc2959/src/test_ltc2959.c new file mode 100644 index 0000000000000..49f9aed79169b --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/src/test_ltc2959.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2025 Nathan Winslow + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define LTC_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(adi_ltc2959) +BUILD_ASSERT(DT_NODE_EXISTS(LTC_NODE), "No adi,ltc2959 node in DT for tests"); + +#define RSENSE_MOHMS DT_PROP(LTC_NODE, rsense_milliohms) + +/* Integer LSB sizes (keep tests stable) */ +#define CURRENT_LSB_UA (97500000ULL / ((uint64_t)RSENSE_MOHMS * 32768ULL)) +#define VOLTAGE_MAX_UV (UINT16_MAX * 955U) /* ~955 = 62.6V full scale / 65536 */ + +struct ltc2959_fixture { + const struct device *dev; + const struct fuel_gauge_driver_api *api; +}; + +static void *ltc2959_setup(void) +{ + static ZTEST_DMEM struct ltc2959_fixture fixture; + + fixture.dev = DEVICE_DT_GET_ANY(adi_ltc2959); + k_object_access_all_grant(fixture.dev); + + zassume_true(device_is_ready(fixture.dev), "Fuel Gauge not found"); + + return &fixture; +} + +LOG_MODULE_REGISTER(test_ltc2959, LOG_LEVEL_INF); + +ZTEST_F(ltc2959, test_get_props__returns_ok) +{ + fuel_gauge_prop_t props[] = { + FUEL_GAUGE_STATUS, + FUEL_GAUGE_VOLTAGE, + FUEL_GAUGE_CURRENT, + FUEL_GAUGE_TEMPERATURE, + }; + + union fuel_gauge_prop_val vals[ARRAY_SIZE(props)]; + int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props)); + +#if CONFIG_EMUL + zassert_equal(vals[0].fg_status, 0x01); + zassert_equal(vals[1].voltage, 0x00); + zassert_equal(vals[2].current, 0x00); + zassert_equal(vals[3].temperature, 0x00); +#else + zassert_between_inclusive(vals[0].fg_status, 0, 0xFF); + zassert_between_inclusive(vals[1].voltage, 0, VOLTAGE_MAX_UV); +#endif + zassert_equal(ret, 0, "Getting bad property has a good status."); +} + +ZTEST_F(ltc2959, test_set_get_single_prop) +{ + int ret; + union fuel_gauge_prop_val in = {.low_voltage_alarm = 1200000}; /* 1.2V */ + + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_LOW_VOLTAGE_ALARM, in); + zassert_equal(ret, 0, "set low voltage threshold failed"); + + union fuel_gauge_prop_val out; + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_LOW_VOLTAGE_ALARM, &out); + zassert_equal(ret, 0, "get low voltage threshold failed"); + + /* Allow for register quantization: one LSB ≈ 1.91 mV */ + const int32_t lsb_uv = 62600000 / 32768; /* integer ≈ 1910 */ + int32_t diff = (int32_t)out.low_voltage_alarm - (int32_t)in.low_voltage_alarm; + + zassert_true(diff <= lsb_uv && diff >= -lsb_uv, + "Set/get mismatch: in=%d, out=%d, diff=%d > LSB=%d", (int)in.low_voltage_alarm, + (int)out.low_voltage_alarm, (int)(diff), (int)lsb_uv); + + LOG_INF("in=%d, out=%d, diff=%d > LSB=%d", (int)in.low_voltage_alarm, + (int)out.low_voltage_alarm, (int)(diff), (int)lsb_uv); +} + +ZTEST_F(ltc2959, test_current_threshold_roundtrip) +{ + int ret; + union fuel_gauge_prop_val in, out; + int32_t tol = CURRENT_LSB_UA ? (int32_t)CURRENT_LSB_UA : 100; + + in.high_current_alarm = 123456; /* µA */ + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_HIGH_CURRENT_ALARM, in); + zassert_equal(ret, 0, "set current high threshold failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_HIGH_CURRENT_ALARM, &out); + zassert_equal(ret, 0, "get current high threshold failed (%d)", ret); + + int32_t diff = out.high_current_alarm - in.high_current_alarm; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= tol, "current high threshold mismatch: in=%d out=%d diff=%d tol=%d", + (int)in.high_current_alarm, (int)out.high_current_alarm, (int)diff, (int)tol); + + in.low_current_alarm = -78901; /* µA */ + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_LOW_CURRENT_ALARM, in); + zassert_equal(ret, 0, "set current low threshold failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_LOW_CURRENT_ALARM, &out); + zassert_equal(ret, 0, "get current low threshold failed (%d)", ret); + + diff = out.low_current_alarm - in.low_current_alarm; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= tol, "current low threshold mismatch: in=%d out=%d diff=%d tol=%d", + (int)in.low_current_alarm, (int)out.low_current_alarm, (int)diff, (int)tol); +} + +ZTEST_F(ltc2959, test_temperature_threshold_roundtrip) +{ + int ret; + union fuel_gauge_prop_val in; + union fuel_gauge_prop_val out; + + in.low_temperature_alarm = 3000; + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_LOW_TEMPERATURE_ALARM, in); + zassert_equal(ret, 0, "set temp low threshold failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_LOW_TEMPERATURE_ALARM, &out); + zassert_equal(ret, 0, "get temp low threshold failed (%d)", ret); + int32_t diff = (int32_t)out.low_temperature_alarm - (int32_t)in.low_temperature_alarm; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= 1, "temp low threshold mismatch: in=%u out=%u diff=%d", + in.low_temperature_alarm, out.low_temperature_alarm, (int)diff); + + in.high_temperature_alarm = 3500; + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_HIGH_TEMPERATURE_ALARM, in); + zassert_equal(ret, 0, "set temp high threshold failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_HIGH_TEMPERATURE_ALARM, &out); + zassert_equal(ret, 0, "get temp high threshold failed (%d)", ret); + diff = (int32_t)out.high_temperature_alarm - (int32_t)in.high_temperature_alarm; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= 1, "temp high threshold mismatch: in=%u out=%u diff=%d", + in.high_temperature_alarm, out.high_temperature_alarm, (int)diff); +} + +ZTEST_F(ltc2959, test_adc_mode_roundtrip) +{ + int ret; + union fuel_gauge_prop_val in, out; + + in.adc_mode = 0xC0 | 0x10; /* CONT_VIT + GPIO BIPOLAR */ + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_ADC_MODE, in); + zassert_equal(ret, 0, "set ADC_MODE failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_ADC_MODE, &out); + zassert_equal(ret, 0, "get ADC_MODE failed (%d)", ret); + zassert_equal(out.adc_mode, in.adc_mode, "ADC_MODE mismatch (got 0x%02x)", out.adc_mode); +} + +ZTEST_F(ltc2959, test_remaining_capacity_roundtrip) +{ + int ret; + union fuel_gauge_prop_val in, out; + + in.remaining_capacity = 1234567; /* µAh */ + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_REMAINING_CAPACITY, in); + zassert_equal(ret, 0, "set ACR failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_REMAINING_CAPACITY, &out); + zassert_equal(ret, 0, "get ACR failed (%d)", ret); + + int32_t diff = (int32_t)out.remaining_capacity - (int32_t)in.remaining_capacity; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= 1, "ACR mismatch: in=%d out=%d diff=%d tol=1", + (int)in.remaining_capacity, (int)out.remaining_capacity, (int)diff); +} + +ZTEST_F(ltc2959, test_remaining_capacity_reserved_guard) +{ + int ret; + union fuel_gauge_prop_val in, out; + + /* 0xFFFFFFFF counts ≈ 2,289,000,000 µAh (533 nAh/LSB) */ + in.remaining_capacity = 2289000000U; + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_REMAINING_CAPACITY, in); + zassert_equal(ret, 0, "set ACR near fullscale failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_REMAINING_CAPACITY, &out); + zassert_equal(ret, 0, "get ACR near fullscale failed (%d)", ret); + + /* We expect the driver to write 0xFFFFFFFE instead, so out <= in and close */ + zassert_true(out.remaining_capacity <= in.remaining_capacity, + "ACR guard failed: got larger than requested"); + int32_t diff = (int32_t)in.remaining_capacity - (int32_t)out.remaining_capacity; + + if (diff < 0) { + diff = -diff; + } + + zassert_true(diff <= 1, "ACR guard too lossy: in=%d out=%d |diff|=%d", + (int)in.remaining_capacity, (int)out.remaining_capacity, (int)diff); +} + +ZTEST_F(ltc2959, test_cc_config_sanitized) +{ + int ret; + union fuel_gauge_prop_val in, out; + + in.cc_config = 0xFF; /* try to set everything */ + ret = fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_CC_CONFIG, in); + zassert_equal(ret, 0, "set cc_config failed (%d)", ret); + + ret = fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_CC_CONFIG, &out); + zassert_equal(ret, 0, "get cc_config failed (%d)", ret); + + /* Expect bits 7,6,3 kept; bit 4 forced; others cleared => 0xD8 */ + zassert_equal(out.cc_config, 0xD8, "cc_config not sanitized (got 0x%02X)", out.cc_config); +} + +ZTEST_USER_F(ltc2959, test_get_some_props_failed__returns_bad_status) +{ + fuel_gauge_prop_t props[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_VOLTAGE, + }; + union fuel_gauge_prop_val vals[ARRAY_SIZE(props)]; + + int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props)); + + zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); +} + +ZTEST_F(ltc2959, test_set_some_props_failed__returns_err) +{ + fuel_gauge_prop_t prop_types[] = { + /* First invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Second invalid property */ + FUEL_GAUGE_PROP_MAX, + /* Valid property */ + FUEL_GAUGE_LOW_VOLTAGE_ALARM, + }; + + union fuel_gauge_prop_val props[] = { + /* First invalid property */ + {0}, + /* Second invalid property */ + {0}, + /* Valid property */ + {.voltage = 0}, + }; + + int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)); + + zassert_equal(ret, -ENOTSUP); +} + +ZTEST_SUITE(ltc2959, NULL, ltc2959_setup, NULL, NULL, NULL); diff --git a/tests/drivers/fuel_gauge/ltc2959/testcase.yaml b/tests/drivers/fuel_gauge/ltc2959/testcase.yaml new file mode 100644 index 0000000000000..1f359bb1e893c --- /dev/null +++ b/tests/drivers/fuel_gauge/ltc2959/testcase.yaml @@ -0,0 +1,7 @@ +tests: + drivers.fuel_gauge.ltc2959: + tags: + - fuel_gauge + filter: dt_compat_enabled("adi,ltc2959") + platform_allow: + - native_sim diff --git a/tests/drivers/gnss/gnss_emul/CMakeLists.txt b/tests/drivers/gnss/gnss_emul/CMakeLists.txt new file mode 100644 index 0000000000000..03db665f34ab0 --- /dev/null +++ b/tests/drivers/gnss/gnss_emul/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Embeint Pty Ltd +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(gnss_emul) + +target_sources(app PRIVATE + src/main.c +) diff --git a/tests/drivers/gnss/gnss_emul/app.overlay b/tests/drivers/gnss/gnss_emul/app.overlay new file mode 100644 index 0000000000000..1746d8ccb9486 --- /dev/null +++ b/tests/drivers/gnss/gnss_emul/app.overlay @@ -0,0 +1,17 @@ +/* + * Copyright 2025 Embeint Pty Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + gnss = &gnss; + }; + + gnss: gnss { + compatible = "zephyr,gnss-emul"; + status = "okay"; + zephyr,pm-device-runtime-auto; + }; +}; diff --git a/tests/drivers/gnss/gnss_emul/prj.conf b/tests/drivers/gnss/gnss_emul/prj.conf new file mode 100644 index 0000000000000..dde94f372248d --- /dev/null +++ b/tests/drivers/gnss/gnss_emul/prj.conf @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Embeint Pty Ltd +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_ZTEST_STACK_SIZE=4096 + +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y + +CONFIG_GNSS=y +CONFIG_GNSS_EMUL=y +CONFIG_GNSS_EMUL_MANUAL_UPDATE=y diff --git a/tests/drivers/gnss/gnss_emul/src/main.c b/tests/drivers/gnss/gnss_emul/src/main.c new file mode 100644 index 0000000000000..a76f2c4337880 --- /dev/null +++ b/tests/drivers/gnss/gnss_emul/src/main.c @@ -0,0 +1,161 @@ +/* + * Copyright 2025 Embeint Pty Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include + +static void gnss_data_callback(const struct device *dev, const struct gnss_data *data); + +GNSS_DATA_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)), gnss_data_callback); +static K_SEM_DEFINE(gnss_data_published, 0, 1); +static struct gnss_data gnss_published_data; + +static void expected_pm_state(const struct device *dev, enum pm_device_state expected) +{ + enum pm_device_state state; + + zassert_equal(0, pm_device_state_get(dev, &state)); + zassert_equal(expected, state); +} + +static void gnss_data_callback(const struct device *dev, const struct gnss_data *data) +{ + gnss_published_data = *data; + k_sem_give(&gnss_data_published); +} + +static void print_time(const struct gnss_time *utc) +{ + printk("TIME: %02d/%02d/%02d %02d:%02d:%02d.%03d\n", utc->century_year, utc->month, + utc->month_day, utc->hour, utc->minute, utc->millisecond / 1000, + utc->millisecond % 1000); +} + +ZTEST(gnss_emul, test_config_functions) +{ + const struct device *dev = DEVICE_DT_GET(DT_ALIAS(gnss)); + enum gnss_navigation_mode mode; + gnss_systems_t systems; + uint32_t fix_rate; + + /* Booted into suspend mode */ + expected_pm_state(dev, PM_DEVICE_STATE_SUSPENDED); + + /* Configuration get API functions fail when suspended */ + zassert_equal(-ENODEV, gnss_get_enabled_systems(dev, &systems)); + zassert_equal(-ENODEV, gnss_get_navigation_mode(dev, &mode)); + zassert_equal(-ENODEV, gnss_get_fix_rate(dev, &fix_rate)); + + /* Configuration can be queried when enabled */ + zassert_equal(0, pm_device_runtime_get(dev)); + zassert_equal(0, gnss_set_enabled_systems(dev, GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO)); + zassert_equal(0, gnss_set_navigation_mode(dev, GNSS_NAVIGATION_MODE_HIGH_DYNAMICS)); + zassert_equal(0, gnss_set_fix_rate(dev, 1500)); + + zassert_equal(0, gnss_get_enabled_systems(dev, &systems)); + zassert_equal(0, gnss_get_navigation_mode(dev, &mode)); + zassert_equal(0, gnss_get_fix_rate(dev, &fix_rate)); + zassert_equal(GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO, systems); + zassert_equal(GNSS_NAVIGATION_MODE_HIGH_DYNAMICS, mode); + zassert_equal(1500, fix_rate); + + zassert_equal(0, pm_device_runtime_put(dev)); + + /* Fails again when suspended */ + zassert_equal(-ENODEV, gnss_get_enabled_systems(dev, &systems)); + zassert_equal(-ENODEV, gnss_get_navigation_mode(dev, &mode)); + zassert_equal(-ENODEV, gnss_get_fix_rate(dev, &fix_rate)); + + /* But escape hatches work */ + systems = 0; + mode = 0; + fix_rate = 0; + zassert_equal(0, gnss_emul_get_enabled_systems(dev, &systems)); + zassert_equal(0, gnss_emul_get_navigation_mode(dev, &mode)); + zassert_equal(0, gnss_emul_get_fix_rate(dev, &fix_rate)); + zassert_equal(GNSS_SYSTEM_GPS | GNSS_SYSTEM_GALILEO, systems); + zassert_equal(GNSS_NAVIGATION_MODE_HIGH_DYNAMICS, mode); + zassert_equal(1500, fix_rate); +} + +ZTEST(gnss_emul, test_callback_behaviour) +{ + const struct device *dev = DEVICE_DT_GET(DT_ALIAS(gnss)); + const struct navigation_data nav = { + .latitude = 150000000000, + .longitude = -15199000000, + .altitude = 123456, + }; + const struct gnss_info info = { + .satellites_cnt = 7, + .hdop = 1999, + .geoid_separation = 1000, + .fix_status = GNSS_FIX_STATUS_GNSS_FIX, + .fix_quality = GNSS_FIX_QUALITY_GNSS_SPS, + }; + const struct gnss_time *utc; + uint32_t timestamp; + + /* Booted into suspend mode */ + expected_pm_state(dev, PM_DEVICE_STATE_SUSPENDED); + + /* No data published while suspended */ + zassert_equal(-EAGAIN, k_sem_take(&gnss_data_published, K_SECONDS(5))); + + /* Power up and configure for 1Hz */ + zassert_equal(0, pm_device_runtime_get(dev)); + zassert_equal(0, gnss_set_fix_rate(dev, 1000)); + timestamp = k_uptime_get_32(); + + /* Monitor data for a while */ + for (int i = 0; i < 10; i++) { + zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100))); + zassert_equal(0, gnss_published_data.nav_data.latitude); + zassert_equal(0, gnss_published_data.nav_data.longitude); + zassert_equal(0, gnss_published_data.nav_data.altitude); + zassert_equal(0, gnss_published_data.info.satellites_cnt); + print_time(&gnss_published_data.utc); + } + + /* Set a location, approximately 14th July 2017, 02:40:xx am */ + gnss_emul_set_data(dev, &nav, &info, 1500000000000LL); + for (int i = 0; i < 3; i++) { + utc = &gnss_published_data.utc; + /* Published data should match that configured */ + zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100))); + zassert_mem_equal(&gnss_published_data.nav_data, &nav, sizeof(nav)); + zassert_mem_equal(&gnss_published_data.info, &info, sizeof(info)); + zassert_equal(17, utc->century_year); + zassert_equal(7, utc->month); + zassert_equal(14, utc->month_day); + zassert_equal(2, utc->hour); + zassert_equal(40, utc->minute); + print_time(&gnss_published_data.utc); + } + + /* Reset back to no location */ + gnss_emul_clear_data(dev); + for (int i = 0; i < 5; i++) { + zassert_equal(0, k_sem_take(&gnss_data_published, K_MSEC(1100))); + zassert_equal(0, gnss_published_data.nav_data.latitude); + zassert_equal(0, gnss_published_data.nav_data.longitude); + zassert_equal(0, gnss_published_data.nav_data.altitude); + zassert_equal(0, gnss_published_data.info.satellites_cnt); + print_time(&gnss_published_data.utc); + } + + /* Once again no callbacks once suspended */ + zassert_equal(0, pm_device_runtime_put(dev)); + zassert_equal(-EAGAIN, k_sem_take(&gnss_data_published, K_SECONDS(5))); +} + +ZTEST_SUITE(gnss_emul, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/gnss/gnss_emul/testcase.yaml b/tests/drivers/gnss/gnss_emul/testcase.yaml new file mode 100644 index 0000000000000..f3a5780fd06c3 --- /dev/null +++ b/tests/drivers/gnss/gnss_emul/testcase.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Embeint Pty Ltd +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.gnss.gnss_emul: + platform_allow: + - native_sim + integration_platforms: + - native_sim + tags: + - gnss diff --git a/tests/drivers/gpio/gpio_basic_api/boards/frdm_mcxe31b.overlay b/tests/drivers/gpio/gpio_basic_api/boards/frdm_mcxe31b.overlay new file mode 100644 index 0000000000000..f84a3a74f4304 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/frdm_mcxe31b.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + status = "okay"; + out-gpios = <&arduino_header 0 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL | GPIO_PULL_UP)>; + in-gpios = <&arduino_header 1 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL | GPIO_PULL_UP)>; + }; +}; + +&gpioe_l { + status = "okay"; +}; + +&gpioe_h { + status = "okay"; +}; + +&eirq0_default { + group2 { + pinmux = ; + input-enable; + }; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/testcase.yaml b/tests/drivers/gpio/gpio_basic_api/testcase.yaml index 03de83aaa5d0b..3c927e71213ac 100644 --- a/tests/drivers/gpio/gpio_basic_api/testcase.yaml +++ b/tests/drivers/gpio/gpio_basic_api/testcase.yaml @@ -58,6 +58,8 @@ tests: - frdm_k64f platform_exclude: # below boards are customized + - frdm_mcxe247 + - frdm_mcxe31b - mimxrt595_evk/mimxrt595s/cm33 - mimxrt1020_evk - mimxrt1040_evk @@ -75,6 +77,7 @@ tests: - arduino_gpio filter: dt_compat_enabled("test-gpio-basic-api") and dt_compat_enabled("arduino-header-r3") platform_allow: + - frdm_mcxe31b - mimxrt595_evk/mimxrt595s/cm33 - mimxrt1020_evk - mimxrt1040_evk diff --git a/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay b/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay new file mode 100644 index 0000000000000..9a7568844a39e --- /dev/null +++ b/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sram2 { + zephyr,memory-attr = ; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/mimxrt1180_evk_mimxrt1189_cm33_qtmr.overlay b/tests/drivers/pwm/pwm_api/boards/mimxrt1180_evk_mimxrt1189_cm33_qtmr.overlay new file mode 100644 index 0000000000000..35aa3c5cc1499 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/mimxrt1180_evk_mimxrt1189_cm33_qtmr.overlay @@ -0,0 +1,30 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &qtmr4; + }; +}; + +&pinctrl { + qtmr4_timer0_default: qtmr4 { + group0 { + pinmux = <&iomuxc_gpio_ad_00_qtimer4_timer0>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; +}; + +&qtmr4 { + compatible = "nxp,qtmr-pwm"; + pinctrl-0 = <&qtmr4_timer0_default>; + pinctrl-names = "default"; + #pwm-cells = <3>; + prescaler = <32>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_loopback/Kconfig b/tests/drivers/pwm/pwm_loopback/Kconfig new file mode 100644 index 0000000000000..de8a07138c4f0 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/Kconfig @@ -0,0 +1,23 @@ +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "PWM loopback test" + +config TEST_PWM_PERIOD_NSEC + int "Test PWM period in nanoseconds" + default 100000000 + +config TEST_PWM_PULSE_NSEC + int "Test PWM pulse in nanoseconds" + default 15000000 + +config TEST_PWM_PERIOD_USEC + int "Test PWM period in microseconds" + default 100000 + +config TEST_PWM_PULSE_USEC + int "Test PWM pulse in microseconds" + default 75000 + +source "Kconfig.zephyr" diff --git a/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..bda6fb5c4e018 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,5 @@ +CONFIG_TEST_PWM_PERIOD_NSEC=10000000 +CONFIG_TEST_PWM_PULSE_NSEC=1500000 + +CONFIG_TEST_PWM_PERIOD_USEC=10000 +CONFIG_TEST_PWM_PULSE_USEC=7500 diff --git a/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..3a871d12513cc --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,53 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + qtmr4_timer0_default: qtmr4_timer0_default { + group0 { + pinmux = <&iomuxc_gpio_ad_00_qtimer4_timer0>; + drive-strength = "normal"; + slew-rate = "fast"; + }; + }; + + qtmr5_timer0_default: qtmr5_timer0_default { + group0 { + pinmux = <&iomuxc_gpio_ad_04_qtimer5_timer0>; + drive-strength = "normal"; + slew-rate = "fast"; + }; + }; +}; + +/* To test this sample, connect + * GPIO_AD_00(J45-15) ---> GPIO_AD_04(J45-5) + */ + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&qtmr4 0 0 PWM_POLARITY_NORMAL>, /* GPIO_AD_00, J45 pin 15, out */ + <&qtmr5 0 0 PWM_POLARITY_NORMAL>; /* GPIO_AD_04, J45 pin 5, in */ + }; +}; + +&qtmr4 { + compatible = "nxp,qtmr-pwm"; + pinctrl-0 = <&qtmr4_timer0_default>; + pinctrl-names = "default"; + #pwm-cells = <3>; + prescaler = <128>; + status = "okay"; +}; + +&qtmr5 { + compatible = "nxp,qtmr-pwm"; + pinctrl-0 = <&qtmr5_timer0_default>; + pinctrl-names = "default"; + #pwm-cells = <3>; + prescaler = <128>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_loopback/src/test_pwm_loopback.c b/tests/drivers/pwm/pwm_loopback/src/test_pwm_loopback.c index 73448d018d630..c0a58231f1a80 100644 --- a/tests/drivers/pwm/pwm_loopback/src/test_pwm_loopback.c +++ b/tests/drivers/pwm/pwm_loopback/src/test_pwm_loopback.c @@ -10,11 +10,6 @@ #include "test_pwm_loopback.h" -#define TEST_PWM_PERIOD_NSEC 100000000 -#define TEST_PWM_PULSE_NSEC 15000000 -#define TEST_PWM_PERIOD_USEC 100000 -#define TEST_PWM_PULSE_USEC 75000 - enum test_pwm_unit { TEST_PWM_UNIT_NSEC, TEST_PWM_UNIT_USEC, @@ -107,50 +102,50 @@ static void test_capture(uint32_t period, uint32_t pulse, enum test_pwm_unit uni ZTEST_USER(pwm_loopback, test_pulse_capture) { - test_capture(TEST_PWM_PERIOD_NSEC, TEST_PWM_PULSE_NSEC, + test_capture(CONFIG_TEST_PWM_PERIOD_NSEC, CONFIG_TEST_PWM_PULSE_NSEC, TEST_PWM_UNIT_NSEC, PWM_CAPTURE_TYPE_PULSE | PWM_POLARITY_NORMAL); - test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, + test_capture(CONFIG_TEST_PWM_PERIOD_USEC, CONFIG_TEST_PWM_PULSE_USEC, TEST_PWM_UNIT_USEC, PWM_CAPTURE_TYPE_PULSE | PWM_POLARITY_NORMAL); } ZTEST_USER(pwm_loopback, test_pulse_capture_inverted) { - test_capture(TEST_PWM_PERIOD_NSEC, TEST_PWM_PULSE_NSEC, + test_capture(CONFIG_TEST_PWM_PERIOD_NSEC, CONFIG_TEST_PWM_PULSE_NSEC, TEST_PWM_UNIT_NSEC, PWM_CAPTURE_TYPE_PULSE | PWM_POLARITY_INVERTED); - test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, + test_capture(CONFIG_TEST_PWM_PERIOD_USEC, CONFIG_TEST_PWM_PULSE_USEC, TEST_PWM_UNIT_USEC, PWM_CAPTURE_TYPE_PULSE | PWM_POLARITY_INVERTED); } ZTEST_USER(pwm_loopback, test_period_capture) { - test_capture(TEST_PWM_PERIOD_NSEC, TEST_PWM_PULSE_NSEC, + test_capture(CONFIG_TEST_PWM_PERIOD_NSEC, CONFIG_TEST_PWM_PULSE_NSEC, TEST_PWM_UNIT_NSEC, PWM_CAPTURE_TYPE_PERIOD | PWM_POLARITY_NORMAL); - test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, + test_capture(CONFIG_TEST_PWM_PERIOD_USEC, CONFIG_TEST_PWM_PULSE_USEC, TEST_PWM_UNIT_USEC, PWM_CAPTURE_TYPE_PERIOD | PWM_POLARITY_NORMAL); } ZTEST_USER(pwm_loopback, test_period_capture_inverted) { - test_capture(TEST_PWM_PERIOD_NSEC, TEST_PWM_PULSE_NSEC, + test_capture(CONFIG_TEST_PWM_PERIOD_NSEC, CONFIG_TEST_PWM_PULSE_NSEC, TEST_PWM_UNIT_NSEC, PWM_CAPTURE_TYPE_PERIOD | PWM_POLARITY_INVERTED); - test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, + test_capture(CONFIG_TEST_PWM_PERIOD_USEC, CONFIG_TEST_PWM_PULSE_USEC, TEST_PWM_UNIT_USEC, PWM_CAPTURE_TYPE_PERIOD | PWM_POLARITY_INVERTED); } ZTEST_USER(pwm_loopback, test_pulse_and_period_capture) { - test_capture(TEST_PWM_PERIOD_NSEC, TEST_PWM_PULSE_NSEC, + test_capture(CONFIG_TEST_PWM_PERIOD_NSEC, CONFIG_TEST_PWM_PULSE_NSEC, TEST_PWM_UNIT_NSEC, PWM_CAPTURE_TYPE_BOTH | PWM_POLARITY_NORMAL); - test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, + test_capture(CONFIG_TEST_PWM_PERIOD_USEC, CONFIG_TEST_PWM_PULSE_USEC, TEST_PWM_UNIT_USEC, PWM_CAPTURE_TYPE_BOTH | PWM_POLARITY_NORMAL); } @@ -234,8 +229,8 @@ ZTEST(pwm_loopback, test_continuous_capture) memset(buffer, 0, sizeof(buffer)); k_sem_init(&data.sem, 0, 1); - err = pwm_set(out.dev, out.pwm, PWM_USEC(TEST_PWM_PERIOD_USEC), - PWM_USEC(TEST_PWM_PULSE_USEC), out.flags); + err = pwm_set(out.dev, out.pwm, PWM_USEC(CONFIG_TEST_PWM_PERIOD_USEC), + PWM_USEC(CONFIG_TEST_PWM_PULSE_USEC), out.flags); zassert_equal(err, 0, "failed to set pwm output (err %d)", err); err = pwm_configure_capture(in.dev, in.pwm, @@ -259,7 +254,7 @@ ZTEST(pwm_loopback, test_continuous_capture) err = pwm_enable_capture(in.dev, in.pwm); zassert_equal(err, 0, "failed to enable pwm capture (err %d)", err); - err = k_sem_take(&data.sem, K_USEC(TEST_PWM_PERIOD_USEC * data.buffer_len * 10)); + err = k_sem_take(&data.sem, K_USEC(CONFIG_TEST_PWM_PERIOD_USEC * data.buffer_len * 10)); zassert_equal(err, 0, "pwm capture timed out (err %d)", err); zassert_equal(data.status, 0, "pwm capture failed (err %d)", err); @@ -271,10 +266,12 @@ ZTEST(pwm_loopback, test_continuous_capture) zassert_equal(err, 0, "failed to calculate usec (err %d)", err); if (data.pulse_capture) { - zassert_within(usec, TEST_PWM_PULSE_USEC, TEST_PWM_PULSE_USEC / 100, + zassert_within(usec, CONFIG_TEST_PWM_PULSE_USEC, + CONFIG_TEST_PWM_PULSE_USEC / 100, "pulse capture off by more than 1%%"); } else { - zassert_within(usec, TEST_PWM_PERIOD_USEC, TEST_PWM_PERIOD_USEC / 100, + zassert_within(usec, CONFIG_TEST_PWM_PERIOD_USEC, + CONFIG_TEST_PWM_PERIOD_USEC / 100, "period capture off by more than 1%%"); } } diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.conf b/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.conf new file mode 100644 index 0000000000000..a491c30deaf54 --- /dev/null +++ b/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_RENESAS_RZ_INTERRUPT=y +CONFIG_TESTED_SPI_MODE=1 diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.overlay new file mode 100644 index 0000000000000..2ebcc12027a4b --- /dev/null +++ b/tests/drivers/spi/spi_controller_peripheral/boards/rzn2l_rsk.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ spi2_pins: spi2 { + spi2-pinmux { + pinmux = , /* CK2 */ + , /* MOSI2 */ + ; /* MISO2 */ + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + /omit-if-no-ref/ spi3_pins: spi3 { + spi3-pinmux { + pinmux = , /* CK3 */ + , /* MOSI3 */ + , /* MISO3 */ + ; /* SSL3_0 */ + drive-strength = "high"; + slew-rate = "fast"; + }; + }; +}; + +&gpio3 { + status = "okay"; +}; + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_pins>; + pinctrl-names = "default"; + cs-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + + dut_spi_dt: test-spi-dev@0 { + compatible = "vnd,spi-device"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cs-setup-delay-ns = <180000>; + spi-cs-hold-delay-ns = <180000>; + }; +}; + +dut_spis: &spi3 { + status = "okay"; + pinctrl-0 = <&spi3_pins>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf b/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf new file mode 100644 index 0000000000000..a491c30deaf54 --- /dev/null +++ b/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_RENESAS_RZ_INTERRUPT=y +CONFIG_TESTED_SPI_MODE=1 diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay new file mode 100644 index 0000000000000..e20522dc95e00 --- /dev/null +++ b/tests/drivers/spi/spi_controller_peripheral/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + + /omit-if-no-ref/ spi2_pins: spi2 { + spi2-pinmux { + pinmux = , /* CK2 */ + , /* MOSI2 */ + ; /* MISO2 */ + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + /omit-if-no-ref/ spi3_pins: spi3 { + spi3-pinmux { + pinmux = , /* CK3 */ + , /* MOSI3 */ + , /* MISO3 */ + ; /* SSL3 */ + drive-strength = "high"; + slew-rate = "fast"; + }; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&spi2 { + status = "okay"; + pinctrl-0 = <&spi2_pins>; + pinctrl-names = "default"; + cs-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + + dut_spi_dt: test-spi-dev@0 { + compatible = "vnd,spi-device"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cs-setup-delay-ns = <180000>; + spi-cs-hold-delay-ns = <180000>; + }; +}; + +dut_spis: &spi3 { + status = "okay"; + pinctrl-0 = <&spi3_pins>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.conf b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.conf new file mode 100644 index 0000000000000..0eabab226f59d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.conf @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=9 diff --git a/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.overlay b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.overlay new file mode 100644 index 0000000000000..8a261240b963d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw23.overlay @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Connect J2 pins 6-7 */ +&flexcomm2 { + 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>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/frdm_mcxw71.overlay b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw71.overlay index fa2b906bbd7c3..72cf56a4a8a32 100644 --- a/tests/drivers/spi/spi_loopback/boards/frdm_mcxw71.overlay +++ b/tests/drivers/spi/spi_loopback/boards/frdm_mcxw71.overlay @@ -9,10 +9,17 @@ compatible = "test-spi-loopback-slow"; reg = <0>; spi-max-frequency = <500000>; + spi-cs-setup-delay-ns = <1000>; + spi-cs-hold-delay-ns = <1000>; + spi-interframe-delay-ns = <1000>; }; fast@0 { compatible = "test-spi-loopback-fast"; reg = <0>; spi-max-frequency = <16000000>; + spi-cs-setup-delay-ns = <200>; + spi-cs-hold-delay-ns = <200>; + spi-interframe-delay-ns = <100>; }; + }; diff --git a/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.conf b/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.conf new file mode 100644 index 0000000000000..0eabab226f59d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.conf @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=9 diff --git a/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.overlay new file mode 100644 index 0000000000000..6f29649b8fe39 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/mcxw23_evk.overlay @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Connect J21 pins 3-4 */ +&flexcomm2 { + 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>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/mcxw72_evk_mcxw727c_cpu0.overlay b/tests/drivers/spi/spi_loopback/boards/mcxw72_evk_mcxw727c_cpu0.overlay index baa1ce3c6ed86..9ec47673a5beb 100644 --- a/tests/drivers/spi/spi_loopback/boards/mcxw72_evk_mcxw727c_cpu0.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mcxw72_evk_mcxw727c_cpu0.overlay @@ -9,10 +9,16 @@ compatible = "test-spi-loopback-slow"; reg = <0>; spi-max-frequency = <500000>; + spi-cs-setup-delay-ns = <1000>; + spi-cs-hold-delay-ns = <1000>; + spi-interframe-delay-ns = <1000>; }; fast@0 { compatible = "test-spi-loopback-fast"; reg = <0>; spi-max-frequency = <16000000>; + spi-cs-setup-delay-ns = <200>; + spi-cs-hold-delay-ns = <200>; + spi-interframe-delay-ns = <100>; }; }; diff --git a/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.conf b/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.conf new file mode 100644 index 0000000000000..37ec783b76925 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.conf @@ -0,0 +1,6 @@ +CONFIG_SPI_ASYNC=y +CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT=y +CONFIG_SPI_RTIO=n +CONFIG_SPI_LOOPBACK_MODE_LOOP=n +CONFIG_SPI_LARGE_BUFFER_SIZE=2048 +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=9 diff --git a/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.overlay b/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.overlay new file mode 100644 index 0000000000000..042818f4bc5f9 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rza3ul_smarc.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi0 { + slow@2 { + compatible = "test-spi-loopback-slow"; + reg = <2>; + spi-max-frequency = <500000>; + }; + + fast@2 { + compatible = "test-spi-loopback-fast"; + reg = <2>; + spi-max-frequency = <8333333>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.conf b/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.conf new file mode 100644 index 0000000000000..3de8446aac514 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.conf @@ -0,0 +1,5 @@ +CONFIG_SPI_ASYNC=y +CONFIG_SPI_RENESAS_RZ_INTERRUPT=y +CONFIG_SPI_RTIO=n +CONFIG_SPI_LOOPBACK_MODE_LOOP=n +CONFIG_SPI_LARGE_BUFFER_SIZE=2048 diff --git a/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.overlay b/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.overlay new file mode 100644 index 0000000000000..7cee6555a3cdf --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzn2l_rsk.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi2 { + slow@2 { + compatible = "test-spi-loopback-slow"; + reg = <2>; + spi-max-frequency = <500000>; + }; + + fast@2 { + compatible = "test-spi-loopback-fast"; + reg = <2>; + spi-max-frequency = <2500000>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf b/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf new file mode 100644 index 0000000000000..3de8446aac514 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.conf @@ -0,0 +1,5 @@ +CONFIG_SPI_ASYNC=y +CONFIG_SPI_RENESAS_RZ_INTERRUPT=y +CONFIG_SPI_RTIO=n +CONFIG_SPI_LOOPBACK_MODE_LOOP=n +CONFIG_SPI_LARGE_BUFFER_SIZE=2048 diff --git a/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay b/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay new file mode 100644 index 0000000000000..7cee6555a3cdf --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi2 { + slow@2 { + compatible = "test-spi-loopback-slow"; + reg = <2>; + spi-max-frequency = <500000>; + }; + + fast@2 { + compatible = "test-spi-loopback-fast"; + reg = <2>; + spi-max-frequency = <2500000>; + }; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf b/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf new file mode 100644 index 0000000000000..9396e8b801869 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.conf @@ -0,0 +1,7 @@ +CONFIG_SPI_ASYNC=y +CONFIG_SPI_RENESAS_RZ_RSPI_INTERRUPT=y +CONFIG_SPI_RENESAS_RZ_RSPI_DMAC=n +CONFIG_SPI_RTIO=n +CONFIG_SPI_LOOPBACK_MODE_LOOP=n +CONFIG_SPI_LARGE_BUFFER_SIZE=2048 +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=41 diff --git a/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay b/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay new file mode 100644 index 0000000000000..2be457cc96629 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi1 { + dmas = <&dma0 6 RZ_DMA_PERIPH_TO_MEM>, + <&dma0 5 RZ_DMA_MEM_TO_PERIPH>; + dma-names = "rx", "tx"; + + slow@2 { + compatible = "test-spi-loopback-slow"; + reg = <2>; + spi-max-frequency = <500000>; + }; + + fast@2 { + compatible = "test-spi-loopback-fast"; + reg = <2>; + spi-max-frequency = <8333333>; + }; +}; + +&dma0 { + status = "okay"; + dma-buf-addr-alignment = <1>; +}; diff --git a/tests/drivers/uart/uart_async_api/nxp/dut_lpuart1.overlay b/tests/drivers/uart/uart_async_api/nxp/dut_lpuart1.overlay index f39495eaff84c..e7257cfe798cf 100644 --- a/tests/drivers/uart/uart_async_api/nxp/dut_lpuart1.overlay +++ b/tests/drivers/uart/uart_async_api/nxp/dut_lpuart1.overlay @@ -1,11 +1,12 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * SPDX-License-Identifier: Apache-2.0 */ /* * To test this sample * frdm_mcxa156 connect P3_20 to P3_21 + * frdm_mcxe247 connect J5-3 to J5-4 */ dut: &lpuart1 {}; diff --git a/tests/drivers/uart/uart_async_api/src/test_uart_async.c b/tests/drivers/uart/uart_async_api/src/test_uart_async.c index 936600c96fcbe..14e6395170161 100644 --- a/tests/drivers/uart/uart_async_api/src/test_uart_async.c +++ b/tests/drivers/uart/uart_async_api/src/test_uart_async.c @@ -432,7 +432,7 @@ ZTEST_USER(uart_async_chain_read, test_chained_read) "TX_DONE timeout"); k_msleep(rx_timeout_ms + 10); zassert_equal(rx_data_idx, sizeof(tx_buf), - "Unexpected amount of data received %d exp:%d", + "Unexpected amount of data received %d exp:%zu", rx_data_idx, sizeof(tx_buf)); zassert_equal(memcmp(tx_buf, chained_cpy_buf, sizeof(tx_buf)), 0, "Buffers not equal exp %s, real %s", tx_buf, chained_cpy_buf); @@ -1089,22 +1089,22 @@ static ZTEST_BMEM uint8_t tx_buffer[VAR_LENGTH_TX_BUF_SIZE]; ret = uart_rx_enable(uart_dev, (uint8_t *)&var_length_rx_buf_pool[var_length_buf_rx_pool_idx], buf_len, 2 * USEC_PER_MSEC); - zassert_true(ret == 0, "[buff=%d][tx=%d]Failed to enable RX: %d\n", buf_len, tx_len, ret); + zassert_true(ret == 0, "[buff=%zu][tx=%zu]Failed to enable RX: %d\n", buf_len, tx_len, ret); var_length_buf_rx_pool_idx += buf_len; ret = uart_tx(uart_dev, tx_buffer, tx_len, 100 * USEC_PER_MSEC); - zassert_true(ret == 0, "[buff=%d][tx=%d]Failed to TX: %d\n", buf_len, tx_len, ret); + zassert_true(ret == 0, "[buff=%zu][tx=%zu]Failed to TX: %d\n", buf_len, tx_len, ret); k_msleep(10); uart_rx_disable(uart_dev); zassert_equal(k_sem_take(&rx_disabled, K_MSEC(500)), 0, - "[buff=%d][tx=%d]RX_DISABLED timeout\n", buf_len, tx_len); + "[buff=%zu][tx=%zu]RX_DISABLED timeout\n", buf_len, tx_len); zassert_equal(var_length_buf_rx_idx, tx_len, - "[buff=%d][tx=%d]Wrong number of bytes received, got: %d, expected: %d\n", + "[buff=%zu][tx=%zu]Wrong number of bytes received, got: %zu, expected: %zu\n", buf_len, tx_len, var_length_buf_rx_idx, tx_len); zassert_equal(memcmp((void *)var_length_rx_buf, tx_buffer, tx_len), 0, - "[buff=%d][tx=%d]Buffers not equal\n", buf_len, tx_len); + "[buff=%zu][tx=%zu]Buffers not equal\n", buf_len, tx_len); } ZTEST_USER(uart_async_var_buf_length, test_var_buf_length) diff --git a/tests/drivers/uart/uart_async_api/testcase.yaml b/tests/drivers/uart/uart_async_api/testcase.yaml index 843c03d2a6839..9b3bfcbda552b 100644 --- a/tests/drivers/uart/uart_async_api/testcase.yaml +++ b/tests/drivers/uart/uart_async_api/testcase.yaml @@ -75,6 +75,7 @@ tests: extra_args: - platform:frdm_k82f/mk82f25615:"DTC_OVERLAY_FILE=nxp/dut_lpuart0_loopback.overlay" - platform:frdm_mcxa156/mcxa156:"DTC_OVERLAY_FILE=nxp/dut_lpuart1.overlay" + - platform:frdm_mcxe247/mcxe247:"DTC_OVERLAY_FILE=nxp/dut_lpuart1.overlay" - platform:frdm_mcxa153/mcxa153:"DTC_OVERLAY_FILE=nxp/dut_lpuart2_loopback.overlay;nxp/enable_edma0.overlay" - platform:frdm_mcxa346/mcxa346:"DTC_OVERLAY_FILE=nxp/dut_lpuart3_loopback.overlay;nxp/enable_edma0.overlay" - platform:frdm_mcxa266/mcxa266:"DTC_OVERLAY_FILE=nxp/dut_lpuart3_loopback.overlay;nxp/enable_edma0.overlay" diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuflpr.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuflpr.overlay rename to tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54l15q_db_nrf54l15_cpuflpr_xip.overlay rename to tests/drivers/watchdog/wdt_basic_api/boards/raytac_an54lq_db_15_nrf54l15_cpuflpr_xip.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 84d4ab51b9496..76c37f7be19c0 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -28,12 +28,13 @@ tests: - mimxrt700_evk/mimxrt798s/cm33_cpu1 - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l15/cpuapp/ns - bl54l15u_dvk/nrf54l15/cpuapp/ns - - raytac_an54l15q_db/nrf54l15/cpuapp/ns - frdm_mcxw71 - frdm_mcxw72/mcxw727c/cpu0 + - raytac_an54lq_db_15/nrf54l15/cpuapp/ns 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/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/watchdog/wdt_error_cases/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_error_cases/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/watchdog/wdt_error_cases/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml index 5325d73a88ce6..c48dc0b08bb15 100644 --- a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml +++ b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml @@ -16,13 +16,13 @@ tests: - nrf9280pdk/nrf9280/cpuapp - nrf9280pdk/nrf9280/cpurad - ophelia4ev/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuapp - xg24_rb4187c - xg27_dk2602a + - raytac_an54lq_db_15/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp - - raytac_an54l15q_db/nrf54l15/cpuapp + - raytac_an54lq_db_15/nrf54l15/cpuapp drivers.watchdog.wdt_error_cases_pm: platform_allow: - xg24_rb4187c diff --git a/tests/drivers/watchdog/wdt_variables/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay b/tests/drivers/watchdog/wdt_variables/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_variables/boards/raytac_an54l15q_db_nrf54l15_cpuapp.overlay rename to tests/drivers/watchdog/wdt_variables/boards/raytac_an54lq_db_15_nrf54l15_cpuapp.overlay diff --git a/tests/kconfig/tracing/CMakeLists.txt b/tests/kconfig/tracing/CMakeLists.txt new file mode 100644 index 0000000000000..1a2b1845e5601 --- /dev/null +++ b/tests/kconfig/tracing/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +# will never be created so the check runs every time +set(output_file ${PROJECT_BINARY_DIR}/validate_tracing_output.txt) + +add_custom_command( + COMMENT "Testing Kconfig value origin traces" + OUTPUT ${output_file} + DEPENDS + ${logical_target_for_zephyr_elf} + $<$:native_runner_executable> + COMMAND ${PYTHON_EXECUTABLE} ${APPLICATION_SOURCE_DIR}/validate_tracing.py ${DOTCONFIG} + COMMAND ${WEST} build -t traceconfig +) + +add_custom_target(validate_traces ALL DEPENDS ${output_file}) + +project(check_tracing) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/kconfig/tracing/Kconfig b/tests/kconfig/tracing/Kconfig new file mode 100644 index 0000000000000..86d66a0841bb6 --- /dev/null +++ b/tests/kconfig/tracing/Kconfig @@ -0,0 +1,34 @@ +# Copyright 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +# Note that line numbers in this file are important for test scripts. Ensure +# these match the expectations in validate_srcrefs.py. + +source "Kconfig.zephyr" + +config MAIN_FLAG + bool + +config MAIN_FLAG_DEPENDENCY + bool "Main Feature Dependency" + default y + depends on MAIN_FLAG + +config MAIN_FLAG_SELECT + bool "Main Feature Dependent" + select MAIN_FLAG + +choice MULTIPLE_CHOICES + prompt "Multiple Choice Option" + +config FIRST_CHOICE + bool "First Choice Option" + depends on !MAIN_FLAG + +config SECOND_CHOICE + bool "Second Choice Option" + +endchoice + +config UNSET_FLAG + bool "Disabled Feature" diff --git a/tests/kconfig/tracing/prj.conf b/tests/kconfig/tracing/prj.conf new file mode 100644 index 0000000000000..adfdd05102d91 --- /dev/null +++ b/tests/kconfig/tracing/prj.conf @@ -0,0 +1,7 @@ +# Copyright 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +# Note that line numbers in this file are important for test scripts. Ensure +# these match the expectations in validate_srcrefs.py. + +CONFIG_MAIN_FLAG_SELECT=y diff --git a/tests/kconfig/tracing/src/main.c b/tests/kconfig/tracing/src/main.c new file mode 100644 index 0000000000000..fa3a81d3a960f --- /dev/null +++ b/tests/kconfig/tracing/src/main.c @@ -0,0 +1,10 @@ +/* + * Copyright 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + return 0; +} diff --git a/tests/kconfig/tracing/testcase.yaml b/tests/kconfig/tracing/testcase.yaml new file mode 100644 index 0000000000000..8694d4e3f8fed --- /dev/null +++ b/tests/kconfig/tracing/testcase.yaml @@ -0,0 +1,11 @@ +# Copyright 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +tests: + kconfig.tracing: + build_only: true + platform_allow: + - native_sim + - native_sim/native/64 + integration_platforms: + - native_sim diff --git a/tests/kconfig/tracing/validate_tracing.py b/tests/kconfig/tracing/validate_tracing.py new file mode 100644 index 0000000000000..0de12a12323fe --- /dev/null +++ b/tests/kconfig/tracing/validate_tracing.py @@ -0,0 +1,142 @@ +# Copyright (c) 2025 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +import json +import os +import pickle +import sys + +# fmt: off + +# Indices for the fields in the trace entries +# Keep these in sync with the generation code in scripts/kconfig/kconfig.py! +( + SYM_NAME, + SYM_VIS, + SYM_TYPE, + SYM_VALUE, + SYM_KIND, + SYM_LOC +) = range(6) + +EXPECTED_TRACES = [ + [ + "CONFIG_BOARD", + "n", + "string", + "native_sim", + "default", + [ "zephyr/boards/Kconfig", None ] # only test the file name + ], + [ + "CONFIG_MAIN_FLAG", + "n", + "bool", + "y", + "select", + [ "MAIN_FLAG_SELECT" ] + ], + [ + "CONFIG_MAIN_FLAG_DEPENDENCY", + "y", + "bool", + "y", + "default", + [ "tests/kconfig/tracing/Kconfig", 14 ] + ], + [ + "CONFIG_MAIN_FLAG_SELECT", + "y", + "bool", + "y", + "assign", + [ "tests/kconfig/tracing/prj.conf", 7 ] + ], + [ + "CONFIG_SECOND_CHOICE", + "y", + "bool", + "y", + "default", + None + ], + [ + "CONFIG_UNSET_FLAG", + "y", + "bool", + None, + "unset", + None + ], +] + +# fmt: on + + +def compare_entry(actual, expected): + for field in SYM_NAME, SYM_VIS, SYM_TYPE, SYM_VALUE, SYM_KIND: + if actual[field] != expected[field]: + return False + + if expected[SYM_KIND] in ("imply", "select") or expected[SYM_LOC] is None: + # list of strings or None, compare directly + if actual[SYM_LOC] != expected[SYM_LOC]: + return False + else: + # file reference, trim input path + if not isinstance(actual[SYM_LOC], list | tuple) or len(actual[SYM_LOC]) != 2: + return False + + expected_path, expected_line = expected[SYM_LOC] + actual_path, actual_line = actual[SYM_LOC] + + if not os.path.normpath(actual_path).endswith(expected_path): + return False + + if expected_line is not None and expected_line != actual_line: + return False + + return True + + +def compare_traces(source, actual_list, expected_list): + result = True + for expected in expected_list: + actual = next((sr for sr in actual_list if sr[0] == expected[0]), None) + if not actual: + print(f"Missing value traces for {expected[0]}") + result = False + continue + + if not compare_entry(actual, expected): + print(f"{source}: ERROR: value traces mismatch for {expected[0]}:") + print(" expected:", expected) + print(" actual:", actual) + result = False + continue + + if result: + print(f"{source}: value traces match expected values.") + else: + print(f"{source}: ERROR: Validation failed.") + sys.exit(1) + + +def main(): + if len(sys.argv) != 2: + print("Usage: validate_traces.py ") + sys.exit(1) + + dotconfig = sys.argv[1] + + with open(dotconfig + "-trace.json") as f: + traces = json.load(f) + compare_traces("json", traces, EXPECTED_TRACES) + + with open(dotconfig + "-trace.pickle", 'rb') as f: + traces = pickle.load(f) + compare_traces("pickle", traces, EXPECTED_TRACES) + + +if __name__ == "__main__": + main() diff --git a/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf b/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf b/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf b/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf b/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/modules/thrift/ThriftTest/overlay-tls.conf b/tests/modules/thrift/ThriftTest/overlay-tls.conf index 7676b38883292..1bfda0bc41914 100644 --- a/tests/modules/thrift/ThriftTest/overlay-tls.conf +++ b/tests/modules/thrift/ThriftTest/overlay-tls.conf @@ -8,13 +8,12 @@ CONFIG_THRIFT_SSL_SOCKET=y # # File Descriptor Usage # --------------------- -# stdin, stdout, stderr: 3 # tcp socket (accept): 1 # tls socket (accept): 1 # tcp sockets (client, server): 2 # tls sockets (client, server): 2 # socketpairs for cancellation (accept, client, server): 6 -CONFIG_ZVFS_OPEN_MAX=15 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=12 # TLS configuration CONFIG_MBEDTLS=y diff --git a/tests/modules/thrift/ThriftTest/prj.conf b/tests/modules/thrift/ThriftTest/prj.conf index 4bc7153026a10..a4727acced11c 100755 --- a/tests/modules/thrift/ThriftTest/prj.conf +++ b/tests/modules/thrift/ThriftTest/prj.conf @@ -41,19 +41,6 @@ CONFIG_NET_PKT_TX_COUNT=20 CONFIG_NET_BUF_RX_COUNT=20 CONFIG_NET_PKT_RX_COUNT=20 -# We can get away with using fewer sockets in the non-TLS tests because we use -# TFDServer.cpp for our server and socketpair() for our channel. We do not -# need an accept socket for the server (in contrast to TCP), it only needs 1 -# eventfd for server cancellation, and there are no cancellation sockets -# required because we close them in the testsuite. -# -# File Descriptor Usage -# --------------------- -# stdin, stdout, stderr: 3 -# socketpair for channel: 2 -# eventfd for cancellation: 1 -CONFIG_ZVFS_OPEN_MAX=6 - # Network address config CONFIG_NET_IPV4=y CONFIG_NET_CONFIG_SETTINGS=y diff --git a/tests/net/all/prj.conf b/tests/net/all/prj.conf index b2cb791f7962f..f220a6e9a1143 100644 --- a/tests/net/all/prj.conf +++ b/tests/net/all/prj.conf @@ -353,6 +353,7 @@ CONFIG_NET_SOCKETS_ENABLE_DTLS=y CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_SOCKETS_PACKET=y +CONFIG_ZVFS_OPEN_IGNORE_MIN=y CONFIG_ZVFS_OPEN_MAX=50 CONFIG_ZVFS_POLL_MAX=50 CONFIG_NET_SOCKETS=y diff --git a/tests/net/lib/dns_addremove/prj.conf b/tests/net/lib/dns_addremove/prj.conf index 112794a03da38..b14e5f47e73d5 100644 --- a/tests/net/lib/dns_addremove/prj.conf +++ b/tests/net/lib/dns_addremove/prj.conf @@ -17,5 +17,4 @@ CONFIG_NET_ARP=n CONFIG_PRINTK=y CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=5 CONFIG_ZVFS_POLL_MAX=5 diff --git a/tests/net/lib/dns_dispatcher/prj.conf b/tests/net/lib/dns_dispatcher/prj.conf index 035c73e9b3b6e..af5bf4bb484c3 100644 --- a/tests/net/lib/dns_dispatcher/prj.conf +++ b/tests/net/lib/dns_dispatcher/prj.conf @@ -15,7 +15,7 @@ CONFIG_NET_IPV6=y CONFIG_PRINTK=y CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_ZVFS_OPEN_MAX=10 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=5 CONFIG_ZVFS_POLL_MAX=10 CONFIG_MDNS_RESPONDER=n CONFIG_MDNS_RESOLVER=n diff --git a/tests/net/lib/dns_resolve/prj.conf b/tests/net/lib/dns_resolve/prj.conf index 56518027b8d30..2101f247e757c 100644 --- a/tests/net/lib/dns_resolve/prj.conf +++ b/tests/net/lib/dns_resolve/prj.conf @@ -30,5 +30,4 @@ CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=1344 CONFIG_HEAP_MEM_POOL_SIZE=1024 -CONFIG_ZVFS_OPEN_MAX=9 CONFIG_ZVFS_POLL_MAX=9 diff --git a/tests/net/lib/http_server/core/prj.conf b/tests/net/lib/http_server/core/prj.conf index 0668f13070269..9d032dc348899 100644 --- a/tests/net/lib/http_server/core/prj.conf +++ b/tests/net/lib/http_server/core/prj.conf @@ -7,7 +7,6 @@ CONFIG_POSIX_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_ZVFS_OPEN_MAX=10 CONFIG_REQUIRES_FULL_LIBC=y CONFIG_ZVFS_EVENTFD_MAX=10 CONFIG_NET_MAX_CONTEXTS=10 diff --git a/tests/net/lib/http_server/crime/prj.conf b/tests/net/lib/http_server/crime/prj.conf index 910b89a4c04e2..276466da4163e 100644 --- a/tests/net/lib/http_server/crime/prj.conf +++ b/tests/net/lib/http_server/crime/prj.conf @@ -9,7 +9,6 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST_STACK_SIZE=1024 -CONFIG_ZVFS_OPEN_MAX=10 CONFIG_REQUIRES_FULL_LIBC=y CONFIG_ZVFS_EVENTFD_MAX=10 CONFIG_NET_MAX_CONTEXTS=10 diff --git a/tests/net/lib/http_server/tls/prj.conf b/tests/net/lib/http_server/tls/prj.conf index d8facb4a1d90f..9decd429d2069 100644 --- a/tests/net/lib/http_server/tls/prj.conf +++ b/tests/net/lib/http_server/tls/prj.conf @@ -46,7 +46,6 @@ CONFIG_NET_BUF_RX_COUNT=32 CONFIG_NET_PKT_TX_COUNT=16 CONFIG_NET_PKT_RX_COUNT=16 CONFIG_ZVFS_POLL_MAX=32 -CONFIG_ZVFS_OPEN_MAX=32 CONFIG_REQUIRES_FULL_LIBC=y CONFIG_ZVFS_EVENTFD_MAX=10 CONFIG_NET_MAX_CONTEXTS=10 diff --git a/tests/net/lib/lwm2m/interop/boards/native_sim.conf b/tests/net/lib/lwm2m/interop/boards/native_sim.conf index 3ca97938bd992..1c5feb6afbe35 100644 --- a/tests/net/lib/lwm2m/interop/boards/native_sim.conf +++ b/tests/net/lib/lwm2m/interop/boards/native_sim.conf @@ -8,4 +8,4 @@ CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y CONFIG_ASAN=y CONFIG_NATIVE_EXTRA_CMDLINE_ARGS="--seed-random" CONFIG_HEAP_MEM_POOL_SIZE=32768 -CONFIG_ZVFS_OPEN_MAX=16 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=8 diff --git a/tests/net/lib/mdns_responder/prj.conf b/tests/net/lib/mdns_responder/prj.conf index ecd170c5e510f..7833fef4ab6c8 100644 --- a/tests/net/lib/mdns_responder/prj.conf +++ b/tests/net/lib/mdns_responder/prj.conf @@ -5,7 +5,6 @@ CONFIG_NET_DRIVERS=y CONFIG_NET_LOOPBACK=y CONFIG_NET_IPV4=y CONFIG_NET_IPV6=y -CONFIG_ZVFS_OPEN_MAX=7 CONFIG_ZVFS_POLL_MAX=7 # Network driver config diff --git a/tests/net/pm/prj.conf b/tests/net/pm/prj.conf index 9c838139d9b8e..2c6626660aa91 100644 --- a/tests/net/pm/prj.conf +++ b/tests/net/pm/prj.conf @@ -7,7 +7,6 @@ CONFIG_NET_L2_ETHERNET=n CONFIG_NET_UDP=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=3 CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_NET_LOG=y diff --git a/tests/net/pmtu/prj.conf b/tests/net/pmtu/prj.conf index 1253c5c7c1c85..d075205adc74b 100644 --- a/tests/net/pmtu/prj.conf +++ b/tests/net/pmtu/prj.conf @@ -21,6 +21,5 @@ CONFIG_NET_BUF_TX_COUNT=20 CONFIG_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=32 CONFIG_NET_MAX_CONTEXTS=32 CONFIG_NET_MAX_CONN=32 diff --git a/tests/net/socket/af_packet/prj.conf b/tests/net/socket/af_packet/prj.conf index 342442f9cfc98..ed02e5be4a936 100644 --- a/tests/net/socket/af_packet/prj.conf +++ b/tests/net/socket/af_packet/prj.conf @@ -6,7 +6,6 @@ CONFIG_NET_UDP=y CONFIG_NET_TCP=n CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_PACKET=y -CONFIG_ZVFS_OPEN_MAX=8 CONFIG_NET_IPV6_DAD=n CONFIG_NET_IPV6_MLD=n diff --git a/tests/net/socket/poll/prj.conf b/tests/net/socket/poll/prj.conf index 4a404b96aea24..1c27a6e5b36e8 100644 --- a/tests/net/socket/poll/prj.conf +++ b/tests/net/socket/poll/prj.conf @@ -5,7 +5,7 @@ CONFIG_NET_IPV6=y CONFIG_NET_UDP=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=10 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=5 CONFIG_NET_PKT_TX_COUNT=8 CONFIG_NET_PKT_RX_COUNT=8 CONFIG_NET_MAX_CONN=5 diff --git a/tests/net/socket/reuseaddr_reuseport/prj.conf b/tests/net/socket/reuseaddr_reuseport/prj.conf index f151d25130eb1..513a4114ab4d6 100644 --- a/tests/net/socket/reuseaddr_reuseport/prj.conf +++ b/tests/net/socket/reuseaddr_reuseport/prj.conf @@ -28,7 +28,6 @@ CONFIG_NET_CONTEXT_REUSEPORT=y CONFIG_NET_HOSTNAME_ENABLE=y CONFIG_NET_HOSTNAME="ztest_hostname" -CONFIG_ZVFS_OPEN_MAX=8 CONFIG_NET_MAX_CONN=10 CONFIG_NET_MAX_CONTEXTS=10 diff --git a/tests/net/socket/select/prj.conf b/tests/net/socket/select/prj.conf index 53c0c5de3bf95..49d0d8edd333b 100644 --- a/tests/net/socket/select/prj.conf +++ b/tests/net/socket/select/prj.conf @@ -9,8 +9,13 @@ CONFIG_NET_LOOPBACK=y CONFIG_NET_IPV4=n CONFIG_NET_IPV6=y CONFIG_NET_SOCKETS=y -# Defines fd_set size + +# Defines fd_set size. The test wants to specifically +# check that select bitset size is calculated correctly. +# We want to set the max fd count to 33 so need to ignore +# the min value. CONFIG_ZVFS_OPEN_MAX=33 +CONFIG_ZVFS_OPEN_IGNORE_MIN=y # Network driver config CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/socket/service/prj.conf b/tests/net/socket/service/prj.conf index 151b79e85303b..f2835795342b0 100644 --- a/tests/net/socket/service/prj.conf +++ b/tests/net/socket/service/prj.conf @@ -5,7 +5,7 @@ CONFIG_NET_IPV6=y CONFIG_NET_UDP=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=20 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_PKT_TX_COUNT=8 CONFIG_NET_PKT_RX_COUNT=8 CONFIG_NET_MAX_CONN=5 diff --git a/tests/net/socket/socketpair/prj.conf b/tests/net/socket/socketpair/prj.conf index 314e999680620..8615d581ebc4b 100644 --- a/tests/net/socket/socketpair/prj.conf +++ b/tests/net/socket/socketpair/prj.conf @@ -7,7 +7,7 @@ CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETPAIR=y CONFIG_NET_SOCKETPAIR_BUFFER_SIZE=64 -CONFIG_ZVFS_OPEN_MAX=10 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=5 # Network driver config CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/socket/tcp/prj.conf b/tests/net/socket/tcp/prj.conf index 724e208aa0bed..af9650c4595b2 100644 --- a/tests/net/socket/tcp/prj.conf +++ b/tests/net/socket/tcp/prj.conf @@ -11,7 +11,6 @@ CONFIG_NET_IPV6=y CONFIG_NET_IPV6_ND=n CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=10 CONFIG_NET_MAX_CONTEXTS=10 CONFIG_NET_MAX_CONN=10 diff --git a/tests/net/socket/tcp/src/main.c b/tests/net/socket/tcp/src/main.c index 76a4d62925385..aee0132e9f0cf 100644 --- a/tests/net/socket/tcp/src/main.c +++ b/tests/net/socket/tcp/src/main.c @@ -2665,7 +2665,7 @@ static void after(void *arg) { ARG_UNUSED(arg); - for (int i = 0; i < CONFIG_ZVFS_OPEN_MAX; ++i) { + for (int i = 0; i < ZVFS_OPEN_SIZE; ++i) { (void)zsock_close(i); } } diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 6c4e061e808c0..24058c31dd789 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -20,7 +20,7 @@ CONFIG_TLS_MAX_CREDENTIALS_NUMBER=10 CONFIG_NET_CONTEXT_RCVTIMEO=y CONFIG_NET_CONTEXT_SNDTIMEO=y CONFIG_NET_CONTEXT_RCVBUF=y -CONFIG_ZVFS_OPEN_MAX=20 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 # Keep timings short for the test CONFIG_NET_TCP_TIME_WAIT_DELAY=10 diff --git a/tests/net/socket/tls_ext/prj.conf b/tests/net/socket/tls_ext/prj.conf index 50f764286daa0..ed2b8852ecb1e 100644 --- a/tests/net/socket/tls_ext/prj.conf +++ b/tests/net/socket/tls_ext/prj.conf @@ -31,7 +31,7 @@ CONFIG_NET_BUF_TX_COUNT=64 CONFIG_NET_PKT_TX_COUNT=64 CONFIG_NET_BUF_RX_COUNT=64 CONFIG_NET_PKT_RX_COUNT=64 -CONFIG_ZVFS_OPEN_MAX=10 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=5 # Stack sizes CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/net/socket/udp/prj.conf b/tests/net/socket/udp/prj.conf index ebdbb0d24e73a..c40b5a8b527f7 100644 --- a/tests/net/socket/udp/prj.conf +++ b/tests/net/socket/udp/prj.conf @@ -7,7 +7,7 @@ CONFIG_NET_IPV4=y CONFIG_NET_IPV6=y CONFIG_NET_UDP=y CONFIG_NET_SOCKETS=y -CONFIG_ZVFS_OPEN_MAX=10 +CONFIG_ZVFS_OPEN_ADD_SIZE_NET=5 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 CONFIG_NET_IPV6_DAD=n CONFIG_NET_IPV6_MLD=n diff --git a/tests/net/socket/udp/src/main.c b/tests/net/socket/udp/src/main.c index b4f57ec182546..ca6ed384f7db4 100644 --- a/tests/net/socket/udp/src/main.c +++ b/tests/net/socket/udp/src/main.c @@ -3719,7 +3719,7 @@ static void after(void *arg) { ARG_UNUSED(arg); - for (int i = 0; i < CONFIG_ZVFS_OPEN_MAX; ++i) { + for (int i = 0; i < ZVFS_OPEN_SIZE; ++i) { (void)zsock_close(i); } } diff --git a/tests/posix/fs/prj.conf b/tests/posix/fs/prj.conf index e1501c697ae19..9b04196534602 100644 --- a/tests/posix/fs/prj.conf +++ b/tests/posix/fs/prj.conf @@ -8,3 +8,4 @@ CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=4096 CONFIG_ZTEST_STACK_SIZE=2048 CONFIG_EVENTFD=n +CONFIG_ZVFS_OPEN_ADD_SIZE_POSIX=5 diff --git a/tests/posix/fs/src/test_fs_file.c b/tests/posix/fs/src/test_fs_file.c index 23496c92b8c22..63795e30b2eac 100644 --- a/tests/posix/fs/src/test_fs_file.c +++ b/tests/posix/fs/src/test_fs_file.c @@ -261,7 +261,7 @@ ZTEST(posix_fs_file_test, test_fs_unlink) ZTEST(posix_fs_file_test, test_fs_fd_leak) { const int reps = - MAX(CONFIG_POSIX_OPEN_MAX, CONFIG_ZVFS_OPEN_MAX) + 5; + MAX(CONFIG_POSIX_OPEN_MAX, ZVFS_OPEN_SIZE) + 5; for (int i = 0; i < reps; i++) { if (i > 0) { diff --git a/tests/posix/xsi_realtime/src/shm.c b/tests/posix/xsi_realtime/src/shm.c index 6755798ef5a33..d59273a26fdd2 100644 --- a/tests/posix/xsi_realtime/src/shm.c +++ b/tests/posix/xsi_realtime/src/shm.c @@ -31,10 +31,10 @@ #define OPEN_FLAGS (VALID_FLAGS & ~O_CREAT) /* account for stdin, stdout, stderr */ -#define N (CONFIG_ZVFS_OPEN_MAX - 3) +#define N (ZVFS_OPEN_SIZE - 3) /* we need to have at least 2 shared memory objects */ -BUILD_ASSERT(N >= 2, "CONFIG_ZVFS_OPEN_MAX must be > 4"); +BUILD_ASSERT(N >= 2, "ZVFS_OPEN_SIZE must be > 4"); #define S_TYPEISSHM(st) (((st)->st_mode & ZVFS_MODE_IFMT) == ZVFS_MODE_IFSHM) diff --git a/tests/subsys/mgmt/mcumgr/all_options/prj.conf b/tests/subsys/mgmt/mcumgr/all_options/prj.conf index 3087ce16c3932..695cb6eb5cb43 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/prj.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/prj.conf @@ -4,8 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # CONFIG_ZTEST=y -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_SHA256=y CONFIG_FILE_SYSTEM=y CONFIG_BASE64=y CONFIG_NET_BUF=y diff --git a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/all.conf b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/all.conf index eff5b71007f86..30b59e6f89b03 100644 --- a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/all.conf +++ b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/all.conf @@ -5,5 +5,3 @@ # CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32=y CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_SHA256=y diff --git a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/sha256.conf b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/sha256.conf index 5f85dda370851..31cb2aaeddd24 100644 --- a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/sha256.conf +++ b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/configuration/sha256.conf @@ -5,5 +5,3 @@ # CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32=n CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_SHA256=y diff --git a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf index ef6c180ce9fa9..79878cf464bb2 100644 --- a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf +++ b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/prj.conf @@ -17,3 +17,4 @@ CONFIG_MCUMGR_GRP_FS=y CONFIG_MCUMGR_GRP_FS_FILE_STATUS=n CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH=y CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_CMD=y +CONFIG_MAIN_STACK_SIZE=2048 diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 147b4f813e42c..8c4e71804fe11 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -20,6 +20,7 @@ tests: - max32655fthr/max32655/m4 - max32657evkit/max32657 - max32657evkit/max32657/ns + - max78002evkit/max78002/m4 - imx95_evk/mimx9596/m7 - ek_ra8m1 - ek_ra8d1 diff --git a/tests/subsys/settings/its/testcase.yaml b/tests/subsys/settings/its/testcase.yaml index de11f1ef72643..c63019e634573 100644 --- a/tests/subsys/settings/its/testcase.yaml +++ b/tests/subsys/settings/its/testcase.yaml @@ -10,5 +10,6 @@ tests: - max32657evkit/max32657/ns - nrf5340dk/nrf5340/cpuapp/ns - nrf54l15dk/nrf54l15/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns platform_exclude: - lpcxpresso55s69/lpc55s69/cpu0/ns diff --git a/tests/unit/util/main.c b/tests/unit/util/main.c index 358466f8f9f2e..49295c72a56f9 100644 --- a/tests/unit/util/main.c +++ b/tests/unit/util/main.c @@ -534,20 +534,25 @@ ZTEST(util, test_nested_FOR_EACH) { zassert_equal(a2, 2); } +#define TWO 2 /* to showcase that GET_ARG_N and GET_ARGS_LESS_N also work with macros */ + ZTEST(util, test_GET_ARG_N) { int a = GET_ARG_N(1, 10, 100, 1000); int b = GET_ARG_N(2, 10, 100, 1000); int c = GET_ARG_N(3, 10, 100, 1000); + int d = GET_ARG_N(TWO, 10, 100, 1000); zassert_equal(a, 10); zassert_equal(b, 100); zassert_equal(c, 1000); + zassert_equal(d, 100); } ZTEST(util, test_GET_ARGS_LESS_N) { uint8_t a[] = { GET_ARGS_LESS_N(0, 1, 2, 3) }; uint8_t b[] = { GET_ARGS_LESS_N(1, 1, 2, 3) }; uint8_t c[] = { GET_ARGS_LESS_N(2, 1, 2, 3) }; + uint8_t d[] = { GET_ARGS_LESS_N(TWO, 1, 2, 3) }; zassert_equal(sizeof(a), 3); @@ -557,6 +562,9 @@ ZTEST(util, test_GET_ARGS_LESS_N) { zassert_equal(sizeof(c), 1); zassert_equal(c[0], 3); + + zassert_equal(sizeof(d), 1); + zassert_equal(d[0], 3); } ZTEST(util, test_mixing_GET_ARG_and_FOR_EACH) { diff --git a/west.yml b/west.yml index 0115484ee4e6e..744a097602ba8 100644 --- a/west.yml +++ b/west.yml @@ -165,7 +165,7 @@ manifest: - hal - name: hal_bouffalolab path: modules/hal/bouffalolab - revision: 9f2ab1b6b4e8f0dce589b56ea908dc47b5c62385 + revision: 89df8327276755b5935dc4cc2f2f68e27a8dba3d groups: - hal - name: hal_espressif @@ -226,7 +226,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 5ab2c84af5cbdbc2b1f0a41e08b8f311bd4eafa8 + revision: 8c5505d957db35816f3f2ddc93f6805fd648a90c groups: - hal - name: hal_rpi_pico @@ -369,7 +369,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: 591f37f31a882208e7b1ddb8e053a4bdf72c68ed + revision: 62ad723311da2cac938e2ae88bafe9e815b3b248 path: modules/tee/tf-m/trusted-firmware-m groups: - tee