diff --git a/CODEOWNERS b/CODEOWNERS index 937d4b6539d9906..3ec9727fce25dbb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -71,7 +71,7 @@ /soc/arm64/arm/fvp_aemv8a/ @carlocaione /soc/arm64/intel_socfpga/* @siclim /soc/Kconfig @tejlmand @galak @nashif @nordicjm -/submanifests/* @mbolivar-nordic +/submanifests/* @mbolivar-ampere /arch/x86/ @jhedberg @nashif /arch/nios2/ @nashif /arch/posix/ @aescolar @daor-oti @@ -111,6 +111,7 @@ /boards/arm/cc26x2r1_launchxl/ @bwitherspoon /boards/arm/cc3220sf_launchxl/ @vanti /boards/arm/cy8ckit_062_ble/ @ifyall @npal-cy +/boards/arm/cy8ckit_062s4/ @DaWei8823 /boards/arm/cy8ckit_062_wifi_bt/ @ifyall @npal-cy /boards/arm/cy8cproto_062_4343w/ @ifyall @npal-cy /boards/arm/disco_l475_iot1/ @erwango @@ -166,7 +167,7 @@ /boards/arm/rcar_h3ulcb/ @aaillet @pmarzin /boards/arm/ubx_bmd345eval_nrf52840/ @Navin-Sankar @brec-u-blox /boards/arm/nrf5340_audio_dk_nrf5340 @koffes @alexsven @erikrobstad @rick1082 @gWacey -/boards/common/ @mbolivar-nordic +/boards/common/ @mbolivar-ampere /boards/deprecated.cmake @tejlmand /boards/mips/ @frantony /boards/nios2/ @nashif @@ -215,7 +216,7 @@ /doc/CMakeLists.txt @carlescufi /doc/_scripts/ @carlescufi /doc/connectivity/bluetooth/ @alwa-nordic @jhedberg @Vudentz -/doc/build/dts/ @galak @mbolivar-nordic +/doc/build/dts/ @galak @mbolivar-ampere /doc/build/sysbuild/ @tejlmand @nordicjm /doc/hardware/peripherals/canbus/ @alexanderwachter @henrikbrixandersen /doc/security/ @ceolin @d3zd3z @@ -321,8 +322,8 @@ /drivers/i2c/Kconfig.i2c_emul @sjg20 /drivers/i2c/Kconfig.it8xxx2 @GTLin08 /drivers/i2c/target/*eeprom* @henrikbrixandersen -/drivers/i2c/Kconfig.test @mbolivar-nordic -/drivers/i2c/i2c_test.c @mbolivar-nordic +/drivers/i2c/Kconfig.test @mbolivar-ampere +/drivers/i2c/i2c_test.c @mbolivar-ampere /drivers/i2c/*rcar* @aaillet /drivers/i2s/*litex* @mateusz-holenko @kgugala @pgielda /drivers/i2s/i2s_ll_stm32* @avisconti @@ -353,7 +354,7 @@ /drivers/kscan/*ft5336* @MaureenHelm /drivers/kscan/*ht16k33* @henrikbrixandersen /drivers/led/ @Mani-Sadhasivam -/drivers/led_strip/ @mbolivar-nordic +/drivers/led_strip/ @mbolivar-ampere /drivers/lora/ @Mani-Sadhasivam /drivers/mbox/ @carlocaione /drivers/misc/ @tejlmand @@ -611,7 +612,7 @@ /include/zephyr/drivers/pcie/ @dcpleung /include/zephyr/drivers/hwinfo.h @alexanderwachter /include/zephyr/drivers/led.h @Mani-Sadhasivam -/include/zephyr/drivers/led_strip.h @mbolivar-nordic +/include/zephyr/drivers/led_strip.h @mbolivar-ampere /include/zephyr/drivers/sensor.h @MaureenHelm /include/zephyr/drivers/smbus.h @finikorg /include/zephyr/drivers/spi.h @tbursztyka @@ -769,7 +770,7 @@ /scripts/build/gen_app_partitions.py @dcpleung @nashif scripts/build/gen_image_info.py @tejlmand /scripts/get_maintainer.py @nashif -/scripts/dts/ @mbolivar-nordic @galak +/scripts/dts/ @mbolivar-ampere @galak /scripts/release/ @nashif /scripts/ci/ @nashif /scripts/ci/check_compliance.py @nashif @carlescufi @@ -778,11 +779,11 @@ scripts/build/gen_image_info.py @tejlmand /scripts/build/gen_kobject_list.py @dcpleung @nashif /scripts/build/gen_kobject_placeholders.py @dcpleung /scripts/build/gen_syscalls.py @dcpleung @nashif -/scripts/list_boards.py @mbolivar-nordic +/scripts/list_boards.py @mbolivar-ampere /scripts/build/process_gperf.py @dcpleung @nashif /scripts/build/gen_relocate_app.py @dcpleung /scripts/generate_usb_vif/ @madhurimaparuchuri -/scripts/requirements*.txt @mbolivar-nordic @galak @nashif +/scripts/requirements*.txt @mbolivar-ampere @galak @nashif /scripts/tests/build/test_subfolder_list.py @rmstoi /scripts/tracing/ @nashif /scripts/pylib/twister/ @nashif @@ -790,12 +791,12 @@ scripts/build/gen_image_info.py @tejlmand /scripts/series-push-hook.sh @erwango /scripts/utils/pinctrl_nrf_migrate.py @gmarull /scripts/utils/migrate_mcumgr_kconfigs.py @de-nordic -/scripts/west_commands/ @mbolivar-nordic +/scripts/west_commands/ @mbolivar-ampere /scripts/west_commands/blobs.py @carlescufi /scripts/west_commands/fetchers/ @carlescufi -/scripts/west_commands/runners/gd32isp.py @mbolivar-nordic @nandojve -/scripts/west_commands/tests/test_gd32isp.py @mbolivar-nordic @nandojve -/scripts/west-commands.yml @mbolivar-nordic +/scripts/west_commands/runners/gd32isp.py @mbolivar-ampere @nandojve +/scripts/west_commands/tests/test_gd32isp.py @mbolivar-ampere @nandojve +/scripts/west-commands.yml @mbolivar-ampere /scripts/zephyr_module.py @tejlmand /scripts/build/uf2conv.py @petejohanson /scripts/build/user_wordsize.py @cfriedt diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 15427fa82be847e..b53bac57e734292 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -56,7 +56,7 @@ menu "Build and Link Features" menu "Linker Options" -choice +choice LINKER_ORPHAN_CONFIGURATION prompt "Linker Orphan Section Handling" default LINKER_ORPHAN_SECTION_WARN diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index d37cf5ac4d1c0bb..20b57422135eed7 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -518,7 +518,7 @@ DFU: Devicetree: status: maintained maintainers: - - mbolivar-nordic + - mbolivar-ampere - galak files: - scripts/dts/ @@ -1088,7 +1088,7 @@ Release Notes: "Drivers: LED Strip": status: maintained maintainers: - - mbolivar-nordic + - mbolivar-ampere - simonguinot files: - drivers/led_strip/ @@ -2755,7 +2755,7 @@ VFS: West: status: maintained maintainers: - - mbolivar-nordic + - mbolivar-ampere collaborators: - carlescufi - swinslow diff --git a/arch/posix/core/posix_core.c b/arch/posix/core/posix_core.c index 2492c7d19e482de..89310f11d940fa5 100644 --- a/arch/posix/core/posix_core.c +++ b/arch/posix/core/posix_core.c @@ -48,6 +48,7 @@ #define ERPREFIX PREFIX"error on " #define NO_MEM_ERR PREFIX"Can't allocate memory\n" +#define PC_ENABLE_CANCEL 0 /* See Note.c1 */ #define PC_ALLOC_CHUNK_SIZE 64 #define PC_REUSE_ABORTED_ENTRIES 0 /* tests/kernel/threads/scheduling/schedule_api fails when setting @@ -363,6 +364,10 @@ int posix_new_thread(void *ptr) threads_table[t_slot].thead_cnt = thread_create_count++; threads_table[t_slot].t_status = ptr; + /* + * Note: If you are here due to a valgrind reported memory leak in + * pthread_create() please use the provided valgrind.supp suppression file. + */ PC_SAFE_CALL(pthread_create(&threads_table[t_slot].thread, NULL, posix_thread_starter, @@ -422,6 +427,7 @@ void posix_arch_clean_up(void) terminate = true; +#if (PC_ENABLE_CANCEL) for (int i = 0; i < threads_table_size; i++) { if (threads_table[i].state != USED) { continue; @@ -435,6 +441,7 @@ void posix_arch_clean_up(void) } /* LCOV_EXCL_STOP */ } +#endif free(threads_table); threads_table = NULL; @@ -516,4 +523,17 @@ int posix_arch_get_unique_thread_id(int thread_idx) * Some other code will never or only very rarely trigger and is therefore * excluded with LCOV_EXCL_LINE * + * + * Notes about (memory) cleanup: + * + * Note.c1: + * + * In some very rare cases in very loaded machines, a race in the glibc pthread_cancel() + * seems to be triggered. + * In this, the cancelled thread cleanup overtakes the pthread_cancel() code, and frees the + * pthread structure before pthread_cancel() has finished, resulting in a dereference into already + * free'd memory, and therefore a segfault. + * Calling pthread_cancel() during cleanup is not required beyond preventing a valgrind + * memory leak report (all threads will be canceled immediately on exit). + * Therefore we do not do this, to avoid this very rare crashes. */ diff --git a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts index 0dd6c6e70a41769..df83c6d6ddddd0c 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts +++ b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts @@ -104,7 +104,7 @@ }; }; -&usb0 { +zephyr_udc0: &usb0 { status = "okay"; pinctrl-0 = <&usb_dc_default>; diff --git a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts index 356e804aaa3684c..cc1cb7020626b42 100644 --- a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts +++ b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts @@ -11,7 +11,7 @@ / { model = "Adafruit Feather STM32F405 Express"; - compatible = "st,adafruit_feather_stm32f405", "st,stm32f405"; + compatible = "adafruit,adafruit_feather_stm32f405", "st,stm32f405"; chosen { zephyr,console = &usart3; diff --git a/boards/arm/b_g474e_dpow1/b_g474e_dpow1.dts b/boards/arm/b_g474e_dpow1/b_g474e_dpow1.dts index 81bd492989b968c..734db554969fa49 100644 --- a/boards/arm/b_g474e_dpow1/b_g474e_dpow1.dts +++ b/boards/arm/b_g474e_dpow1/b_g474e_dpow1.dts @@ -63,12 +63,6 @@ }; }; - cpus { - cpu@0 { - cpu-power-states = <&stop0 &stop1>; - }; - }; - aliases { led0 = &blue_led_2; led1 = &orange_led_3; diff --git a/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi b/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi index 9ac10f360e9e9cf..4c85d49440043c1 100644 --- a/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi +++ b/boards/arm/b_u585i_iot02a/b_u585i_iot02a-common.dtsi @@ -71,10 +71,6 @@ apb3-prescaler = <1>; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00000800>, <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; diff --git a/boards/arm/black_f407ve/black_f407ve.dts b/boards/arm/black_f407ve/black_f407ve.dts index 2ae87ca0504259a..5ea58801fdca3eb 100644 --- a/boards/arm/black_f407ve/black_f407ve.dts +++ b/boards/arm/black_f407ve/black_f407ve.dts @@ -10,7 +10,7 @@ / { model = "black_f407ve board"; - compatible = "st,stm32f407"; + compatible = "black-stm32f407"; chosen { zephyr,console = &usart1; diff --git a/boards/arm/cy8ckit_062s4/Kconfig.board b/boards/arm/cy8ckit_062s4/Kconfig.board new file mode 100644 index 000000000000000..ab9cc0284e61485 --- /dev/null +++ b/boards/arm/cy8ckit_062s4/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 David Ullmann +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_062S4_M4 + bool "PSoC 62S4 pioneer kit" + depends on SOC_CY8C6244LQI_S4D92 diff --git a/boards/arm/cy8ckit_062s4/Kconfig.defconfig b/boards/arm/cy8ckit_062s4/Kconfig.defconfig new file mode 100644 index 000000000000000..616fc65bb13055b --- /dev/null +++ b/boards/arm/cy8ckit_062s4/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2023 David Ullmann +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CY8CKIT_062S4_M4 + +config BOARD + default "cy8ckit_062s4_m4" if BOARD_CY8CKIT_062S4_M4 + + +endif #BOARD_CY8CKIT_062S4_M4 diff --git a/boards/arm/cy8ckit_062s4/board.cmake b/boards/arm/cy8ckit_062s4/board.cmake new file mode 100644 index 000000000000000..7d0818b00d182cc --- /dev/null +++ b/boards/arm/cy8ckit_062s4/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2023 David Ullmann +# spdx-license-identifier: apache-2.0 + +board_runner_args(pyocd "--target=cy8c6xxa") +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.dts b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.dts new file mode 100644 index 000000000000000..6695a24a4b88b41 --- /dev/null +++ b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.dts @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 David Ullmann + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Infineon PSoC 62S4 Pioneer Kit"; + compatible ="cypress,psoc6"; + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + }; + + aliases { + led0 = &user_led; + }; + + leds { + compatible = "gpio-leds"; + user_led: led_0 { + label = "LED_0"; + gpios = <&gpio_prt2 5 GPIO_ACTIVE_HIGH>; + }; + + }; + +}; + +&p3_1_scb2_uart_tx { + drive-push-pull; +}; + +&p3_0_scb2_uart_rx { + input-enable; +}; + + +uart2: &scb2 { + compatible = "infineon,cat1-uart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&p3_0_scb2_uart_rx &p3_1_scb2_uart_tx>; + pinctrl-names = "default"; +}; + +&gpio_prt3 { + status = "okay"; +}; + +&gpio_prt2 { + status = "okay"; +}; diff --git a/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml new file mode 100644 index 000000000000000..4cf64830fcf67df --- /dev/null +++ b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4.yaml @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 David Ullmann + +identifier: cy8ckit_062s4_m4 +name: CY8CKIT-062S4 PSoC 62S4 +type: mcu +arch: arm +ram: 128 +flash: 256 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio diff --git a/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4_defconfig b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4_defconfig new file mode 100644 index 000000000000000..1bbb92065f9dae9 --- /dev/null +++ b/boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 David Ullmann + +CONFIG_SOC_SERIES_PSOC_62=y +CONFIG_BOARD_CY8CKIT_062S4_M4=y +CONFIG_SOC_CY8C6244LQI_S4D92=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y + +CONFIG_PINCTRL=y +CONFIG_SOC_PSOC6_CM0P_IMAGE_SLEEP=y + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_XIP=y diff --git a/boards/arm/cy8ckit_062s4/doc/img/cy8ckit_062s4.png b/boards/arm/cy8ckit_062s4/doc/img/cy8ckit_062s4.png new file mode 100644 index 000000000000000..b33384dab51c6bf Binary files /dev/null and b/boards/arm/cy8ckit_062s4/doc/img/cy8ckit_062s4.png differ diff --git a/boards/arm/cy8ckit_062s4/doc/index.rst b/boards/arm/cy8ckit_062s4/doc/index.rst new file mode 100644 index 000000000000000..5027acb63debee4 --- /dev/null +++ b/boards/arm/cy8ckit_062s4/doc/index.rst @@ -0,0 +1,115 @@ +.. _cy8ckit_062s4: + +[INFINEON PSoC 62S4 Pioneer Kit] +################################ + +Overview +******** +The PSOC 62S$ Pioneer kit has a CY8C62x4 MCU, which is an ultra-low-power PSoC device specifically designed for battery-operated analog +sensing applications. It includes a 150-MHz Arm® Cortex®-M4 CPU as the primary application processor, a 100-MHz Arm® Cortex®-M0+ CPU that +supports low-power operations, up to 256 KB Flash and 128 KB SRAM, programmable analog sensing, +CapSense™ touch-sensing, and programmable digital peripherals. + +The board features an onboard +programmer/debugger (KitProg3), a 512-Mbit Quad SPI NOR flash, a micro-B connector for USB device +interface, a thermistor, an ambient light sensor, a 5-segment CapSense™ slider, two CapSense™ buttons, two +user LEDs, and a push button. The board supports operating voltages from 1.8 V to 3.3 V for PSoC™ 6 MCU. + +.. figure::img/cy8ckit_062s4.png + :width: 800px + :align: center + :alt: Board Name + + Board Name (Credit: ) + +Hardware +******** + +`CY8CKIT 062S4 Pioneer Kit Website`_ +`CY8CKIT 062S4 Pioneer Kit Guide`_ +`CY8CKIT 062S4 Pioneer Kit Schematic`_ +`CY8CKIT 062S4 Pioneer Kit Technical Reference Manual`_ +`CY8CKIT 062S4 Pioneer Kit Datasheet`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+-----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+-----------------------+ +| PINCTRL | on-chip | pin control | ++-----------+------------+-----------------------+ +| UART | on-chip | serial port-polling; | ++-----------+------------+-----------------------+ + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/arm/cy8ckit_062s4/cy8ckit_062s4_m4_defconfig`. + +Clock Configuration +=================== + ++-----------+------------+-----------------------+ +| Clock | Source | Output Frequency | ++===========+============+=======================+ +| FLL | IMO | 100.0 MHz | ++-----------+------------+-----------------------+ +| PLL | IMO | 48.0 MHz | ++-----------+------------+-----------------------+ +| CLK_HF0 | CLK_PATH0 | 100.0 MHz | ++-----------+------------+-----------------------+ + +Fetch Binary Blobs +================== + +.. code-block:: console + + west blobs fetch hal_infineon + + +Build and flash hello world sample +********************************** + + +.. code-block:: console + + cd zephyr/samples/hello_world + west build -p auto -b cy8ckit_062s4_m4 --pristine + west flash + picocom /dev/ttyACM0 -b 115200 + +OpenOCD Installation +==================== + +To get the OpenOCD package, it is required that you + +1. Download the software ModusToolbox 3.1. https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolbox +2. Once downloaded add the path to access the Scripts folder provided by ModusToolbox + export PATH=$PATH:/path/to/ModusToolbox/tools_3.1/openocd/scripts +3. Add the OpenOCD executable file's path to west flash/debug. +4. Flash using: west flash --openocd path/to/infineon/openocd/bin/openocd +5. Debug using: west debug --openocd path/to/infineon/openocd/bin/openocd + +References +********** + +.. _CY8CKIT 062S4 Pioneer Kit Guide: + https://www.infineon.com/dgdl/Infineon-CY8CKIT_062S4_PSoC62S4_pioneer_kit_guide-UserManual-v01_00-EN.pdf?fileId=8ac78c8c7e7124d1017e962f98992207 + +.. _CY8CKIT 062S4 Pioneer Kit Website: + https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062s4/?redirId=VL1508&utm_medium=referral&utm_source=cypress&utm_campaign=202110_globe_en_all_integration-dev_kit + +.. _CY8CKIT 062S4 Pioneer Kit Schematic: + https://www.infineon.com/dgdl/Infineon-CY8CKIT-062S4_PSoC_62S4_Pioneer_Kit_Schematic-PCBDesignData-v01_00-EN.pdf?fileId=8ac78c8c7d710014017d7153484d2081 + +.. _CY8CKIT 062S4 Pioneer Kit Technical Reference Manual: + https://www.infineon.com/dgdl/Infineon-PSOC_6_MCU_CY8C61X4CY8C62X4_REGISTERS_TECHNICAL_REFERENCE_MANUAL_(TRM)_PSOC_61_PSOC_62_MCU-AdditionalTechnicalInformation-v03_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0fb34f0627a7 + +.. _CY8CKIT 062S4 Pioneer Kit Datasheet: + https://www.infineon.com/dgdl/Infineon-PSoC_6_MCU_CY8C62X4-DataSheet-v12_00-EN.pdf?fileId=8ac78c8c7ddc01d7017ddd026d585901 diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts index c4f9273383e9b07..86504d2fb1ea732 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts @@ -71,10 +71,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &clk_lsi { status = "okay"; }; diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a-pinctrl.dtsi b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a-pinctrl.dtsi new file mode 100644 index 000000000000000..4fac2b1a8dfa4f9 --- /dev/null +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a-pinctrl.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for usart0 device, default state - operating as UART */ + usart0_default: usart0_default { + group1 { + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi index 8d45639bcb71d71..dc966f6716f6c90 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "efm32pg_stk3402a-pinctrl.dtsi" / { model = "Silicon Labs EFM32PG STK3402A board"; @@ -67,8 +68,8 @@ &usart0 { current-speed = <115200>; - location-rx = ; - location-tx = ; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/boards/arm/efr32_radio/Kconfig.defconfig b/boards/arm/efr32_radio/Kconfig.defconfig index 830a4c90f5fca5b..cf4be7c9dde1907 100644 --- a/boards/arm/efr32_radio/Kconfig.defconfig +++ b/boards/arm/efr32_radio/Kconfig.defconfig @@ -29,6 +29,13 @@ config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + if BT config FPU diff --git a/boards/arm/efr32_thunderboard/Kconfig.defconfig b/boards/arm/efr32_thunderboard/Kconfig.defconfig index 35059d030c84810..d73779fd61a4c1a 100644 --- a/boards/arm/efr32_thunderboard/Kconfig.defconfig +++ b/boards/arm/efr32_thunderboard/Kconfig.defconfig @@ -23,6 +23,13 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + if BT config FPU diff --git a/boards/arm/efr32_thunderboard/thunderboard.dtsi b/boards/arm/efr32_thunderboard/thunderboard.dtsi index 2d36a291a682c96..236e8ec479b01c3 100644 --- a/boards/arm/efr32_thunderboard/thunderboard.dtsi +++ b/boards/arm/efr32_thunderboard/thunderboard.dtsi @@ -62,10 +62,10 @@ &cpu0 { clock-frequency = <76800000>; - /* Enable EM1,2. This means BURTC has to be used as sys_clock - * or the system won't wake up - */ - cpu-power-states = <&pstate_em1 &pstate_em2>; +}; + +&pstate_em3 { + status = "disabled"; }; &usart0 { diff --git a/boards/arm/efr32xg24_dk2601b/Kconfig.defconfig b/boards/arm/efr32xg24_dk2601b/Kconfig.defconfig index 14405984017a465..0f0cf9aa16334b9 100644 --- a/boards/arm/efr32xg24_dk2601b/Kconfig.defconfig +++ b/boards/arm/efr32xg24_dk2601b/Kconfig.defconfig @@ -18,6 +18,13 @@ config FLASH_BASE_ADDRESS hex default 0x08000000 +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + if BT config FPU diff --git a/boards/arm/mimxrt1170_evk/doc/index.rst b/boards/arm/mimxrt1170_evk/doc/index.rst index f62bd6c63dacd95..63b0e5ddbe662ff 100644 --- a/boards/arm/mimxrt1170_evk/doc/index.rst +++ b/boards/arm/mimxrt1170_evk/doc/index.rst @@ -131,8 +131,9 @@ RT1170 EVKB (`mimxrt1170_evkb_cm7/cm4`) | HWINFO | on-chip | Unique device serial number | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ | DISPLAY | on-chip | eLCDIF; MIPI-DSI. Tested with | Supported (M7) | Supported (M7) | -| | | :ref:`rk055hdmipi4m` and | | | -| | | :ref:`g1120b0mipi` shields | | | +| | | :ref:`rk055hdmipi4m`, | | | +| | | :ref:`rk055hdmipi4ma0`, | | | +| | | and :ref:`g1120b0mipi` shields | | | +-----------+------------+-------------------------------------+-----------------+-----------------+ | ACMP | on-chip | analog comparator | Supported | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ diff --git a/boards/arm/mimxrt595_evk/doc/index.rst b/boards/arm/mimxrt595_evk/doc/index.rst index a7b53ea763ce7d2..61ed427858a101a 100644 --- a/boards/arm/mimxrt595_evk/doc/index.rst +++ b/boards/arm/mimxrt595_evk/doc/index.rst @@ -109,7 +109,8 @@ already supported, which can also be re-used on this mimxrt595_evk board: | I2S | on-chip | i2s | +-----------+------------+-------------------------------------+ | DISPLAY | on-chip | LCDIF; MIPI-DSI. Tested with | -| | | :ref:`rk055hdmipi4m` and | +| | | :ref:`rk055hdmipi4m`, | +| | | :ref:`rk055hdmipi4ma0`, and | | | | :ref:`g1120b0mipi` display shields | +-----------+------------+-------------------------------------+ diff --git a/boards/arm/mr_canhubk3/Kconfig.defconfig b/boards/arm/mr_canhubk3/Kconfig.defconfig index 32f28454047259d..72675122196b18b 100644 --- a/boards/arm/mr_canhubk3/Kconfig.defconfig +++ b/boards/arm/mr_canhubk3/Kconfig.defconfig @@ -13,4 +13,11 @@ config UART_CONSOLE endif # SERIAL +if CAN + +config GPIO + default y + +endif # CAN + endif # BOARD_MR_CANHUBK3 diff --git a/boards/arm/mr_canhubk3/doc/index.rst b/boards/arm/mr_canhubk3/doc/index.rst index 5c8c5e2997c3339..0ae9bccccc1001d 100644 --- a/boards/arm/mr_canhubk3/doc/index.rst +++ b/boards/arm/mr_canhubk3/doc/index.rst @@ -50,6 +50,9 @@ SIUL2 on-chip | pinctrl | external interrupt controller LPUART on-chip serial QSPI on-chip flash +FLEXCAN on-chip can +LPI2C on-chip i2c +ADC SAR on-chip adc ============ ========== ================================ The default configuration can be found in the Kconfig file @@ -107,6 +110,97 @@ P6.2 PTA9 LPUART2_TX P6.3 PTA8 LPUART2_RX ========= ===== ============ +CAN +=== + +CAN is provided through FLEXCAN interface with 6 instances. + +=============== ======= =============== ============= +Devicetree node Pin Pin Function Bus Connector +=============== ======= =============== ============= +flexcan0 | PTA6 | PTA6_CAN0_RX P12/P13 + | PTA7 | PTA7_CAN0_TX +flexcan1 | PTC9 | PTC9_CAN0_RX P14/P15 + | PTC8 | PTC8_CAN0_TX +flexcan2 | PTE25 | PTE25_CAN0_RX P16/P17 + | PTE24 | PTE24_CAN0_TX +flexcan3 | PTC29 | PTC29_CAN0_RX P18/019 + | PTC28 | PTC28_CAN0_TX +flexcan4 | PTC31 | PTC31_CAN0_RX P20/P21 + | PTC30 | PTC30_CAN0_TX +flexcan5 | PTC11 | PTC11_CAN0_RX P22/P23 + | PTC10 | PTC10_CAN0_TX +=============== ======= =============== ============= + +.. note:: + There is limitation by HAL SDK, so CAN only has support maximum 64 message buffers (MBs) + and support maximum 32 message buffers for concurrent active instances with 8 bytes + payload. We need to pay attention to configuration options: + + 1. :kconfig:option:`CONFIG_CAN_MAX_MB` must be less or equal than the + maximum number of message buffers that is according to the table below. + + 2. :kconfig:option:`CONFIG_CAN_MAX_FILTER` must be less or equal than + :kconfig:option:`CONFIG_CAN_MAX_MB`. + +=============== ========== ================ ================ +Devicetree node Payload Hardware support Software support +=============== ========== ================ ================ +flexcan0 | 8 bytes | 96 MBs | 64 MBs + | 16 bytes | 63 MBs | 42 MBs + | 32 bytes | 36 MBs | 24 MBs + | 64 bytes | 21 MBs | 14 MBs +flexcan1 | 8 bytes | 64 MBs | 64 MBs + | 16 bytes | 42 MBs | 42 MBs + | 32 bytes | 24 MBs | 24 MBs + | 64 bytes | 14 MBs | 14 MBs +flexcan2 | 8 bytes | 64 MBs | 64 MBs + | 16 bytes | 42 MBs | 42 MBs + | 32 bytes | 24 MBs | 24 MBs + | 64 bytes | 14 MBs | 14 MBs +flexcan3 | 8 bytes | 32 MBs | 32 MBs + | 16 bytes | 21 MBs | 21 MBs + | 32 bytes | 12 MBs | 12 MBs + | 64 bytes | 7 MBs | 7 MBs +flexcan4 | 8 bytes | 32 MBs | 32 MBs + | 16 bytes | 21 MBs | 21 MBs + | 32 bytes | 12 MBs | 12 MBs + | 64 bytes | 7 MBs | 7 MBs +flexcan5 | 8 bytes | 32 MBs | 32 MBs + | 16 bytes | 21 MBs | 21 MBs + | 32 bytes | 12 MBs | 12 MBs + | 64 bytes | 7 MBs | 7 MBs +=============== ========== ================ ================ + +.. note:: + A CAN bus usually requires 60 Ohm termination at both ends of the bus. This may be + accomplished using one of the included CAN termination boards. For more details, refer + to the section ``6.3 CAN Connectors`` in the Hardware User Manual of `NXP MR-CANHUBK3`_. + +I2C +=== + +I2C is provided through LPI2C interface with 2 instances ``lpi2c0`` and ``lpi2c1`` +on corresponding connectors ``P4``, ``P3``. + +========= ===== ============ +Connector Pin Pin Function +========= ===== ============ +P3.2 PTD9 LPI2C1_SCL +P3.3 PTD8 LPI2C1_SDA +P4.3 PTD14 LPI2C0_SCL +P4.4 PTD13 LPI2C0_SDA +========= ===== ============ + +ADC +=== + +ADC is provided through ADC SAR controller with 3 instances. ADC channels are divided into +3 groups (precision, standard and external). + +.. note:: + All channels of an instance only run on 1 group channel at the same time. + FS26 SBC Watchdog ================= diff --git a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi index aedc0ebfb5f4c71..460a4e35b468a1c 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi +++ b/boards/arm/mr_canhubk3/mr_canhubk3-pinctrl.dtsi @@ -110,4 +110,88 @@ bias-pull-up; }; }; + + flexcan0_default: flexcan0_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + flexcan1_default: flexcan1_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + flexcan2_default: flexcan2_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + flexcan3_default: flexcan3_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + flexcan4_default: flexcan4_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + flexcan5_default: flexcan5_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; + + lpi2c0_default: lpi2c0_default { + group1 { + pinmux = <(PTD13_LPI2C0_SDA_I | PTD13_LPI2C0_SDA_O)>, + <(PTD14_LPI2C0_SCL_I | PTD14_LPI2C0_SCL_O)>; + input-enable; + output-enable; + }; + }; + + lpi2c1_default: lpi2c1_default { + group1 { + pinmux = <(PTD8_LPI2C1_SDA_I | PTD8_LPI2C1_SDA_O)>, + <(PTD9_LPI2C1_SCL_I | PTD9_LPI2C1_SCL_O)>; + input-enable; + output-enable; + }; + }; }; diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.dts b/boards/arm/mr_canhubk3/mr_canhubk3.dts index e068090ec8b9456..df1f85c84b8776a 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.dts +++ b/boards/arm/mr_canhubk3/mr_canhubk3.dts @@ -22,6 +22,7 @@ zephyr,console = &lpuart2; zephyr,shell-uart = &lpuart2; zephyr,flash-controller = &mx25l6433f; + zephyr,canbus = &flexcan0; }; aliases { @@ -59,6 +60,54 @@ gpios = <&gpioa_h 9 GPIO_ACTIVE_HIGH>; }; }; + + can_phy0: can-phy0 { + compatible = "nxp,tja1443", "can-transceiver-gpio"; + enable-gpios = <&gpioc_h 8 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpioc_h 5 GPIO_ACTIVE_LOW>; + max-bitrate = <5000000>; + #phy-cells = <0>; + }; + + can_phy1: can-phy1 { + compatible = "nxp,tja1443", "can-transceiver-gpio"; + enable-gpios = <&gpiod_l 2 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpiod_h 7 GPIO_ACTIVE_LOW>; + max-bitrate = <5000000>; + #phy-cells = <0>; + }; + + can_phy2: can-phy2 { + compatible = "nxp,tja1463", "can-transceiver-gpio"; + enable-gpios = <&gpiod_l 4 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpiod_h 6 GPIO_ACTIVE_LOW>; + max-bitrate = <8000000>; + #phy-cells = <0>; + }; + + can_phy3: can-phy3 { + compatible = "nxp,tja1463", "can-transceiver-gpio"; + enable-gpios = <&gpiob_l 0 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpiob_l 1 GPIO_ACTIVE_LOW>; + max-bitrate = <8000000>; + #phy-cells = <0>; + }; + + can_phy4: can-phy4 { + compatible = "nxp,tja1153", "can-transceiver-gpio"; + enable-gpios = <&gpioc_h 10 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpioc_h 9 GPIO_ACTIVE_LOW>; + max-bitrate = <2000000>; + #phy-cells = <0>; + }; + + can_phy5: can-phy5 { + compatible = "nxp,tja1153", "can-transceiver-gpio"; + enable-gpios = <&gpioe_h 1 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpiod_h 14 GPIO_ACTIVE_LOW>; + max-bitrate = <2000000>; + #phy-cells = <0>; + }; }; &flash0 { @@ -87,10 +136,28 @@ status = "okay"; }; +/* Enable gpio to control the CAN transceivers */ + +&gpioc_h { + status = "okay"; +}; + &gpiod_l { status = "okay"; }; +&gpiod_h { + status = "okay"; +}; + +&gpiob_l { + status = "okay"; +}; + +&gpioe_h { + status = "okay"; +}; + &eirq0 { pinctrl-0 = <&eirq0_default>; pinctrl-names = "default"; @@ -168,3 +235,88 @@ }; }; }; + +&flexcan0 { + pinctrl-0 = <&flexcan0_default>; + pinctrl-names = "default"; + phys = <&can_phy0>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; + status = "okay"; +}; + +&flexcan1 { + pinctrl-0 = <&flexcan1_default>; + pinctrl-names = "default"; + phys = <&can_phy1>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; +}; + +&flexcan2 { + pinctrl-0 = <&flexcan2_default>; + pinctrl-names = "default"; + phys = <&can_phy2>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; +}; + +&flexcan3 { + pinctrl-0 = <&flexcan3_default>; + pinctrl-names = "default"; + phys = <&can_phy3>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; +}; + +&flexcan4 { + pinctrl-0 = <&flexcan4_default>; + pinctrl-names = "default"; + phys = <&can_phy4>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; +}; + +&flexcan5 { + pinctrl-0 = <&flexcan5_default>; + pinctrl-names = "default"; + phys = <&can_phy5>; + bus-speed = <125000>; + sample-point = <875>; + sjw = <1>; + bus-speed-data = <1000000>; + sample-point-data = <875>; + sjw-data = <1>; +}; + +&lpi2c0 { + pinctrl-0 = <&lpi2c0_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&lpi2c1 { + pinctrl-0 = <&lpi2c1_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; diff --git a/boards/arm/mr_canhubk3/mr_canhubk3.yaml b/boards/arm/mr_canhubk3/mr_canhubk3.yaml index 97abfd20b502364..32648c36efac7ad 100644 --- a/boards/arm/mr_canhubk3/mr_canhubk3.yaml +++ b/boards/arm/mr_canhubk3/mr_canhubk3.yaml @@ -12,3 +12,6 @@ toolchain: supported: - gpio - uart + - can + - i2c + - adc diff --git a/boards/arm/nucleo_f030r8/st_morpho_connector.dtsi b/boards/arm/nucleo_f030r8/st_morpho_connector.dtsi index 6ab1c8ce24d6f2b..745c50a5ca93e49 100644 --- a/boards/arm/nucleo_f030r8/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f030r8/st_morpho_connector.dtsi @@ -12,60 +12,60 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f070rb/st_morpho_connector.dtsi b/boards/arm/nucleo_f070rb/st_morpho_connector.dtsi index 0727b65bc2524a8..5f05f019a2cf753 100644 --- a/boards/arm/nucleo_f070rb/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f070rb/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f091rc/st_morpho_connector.dtsi b/boards/arm/nucleo_f091rc/st_morpho_connector.dtsi index 354dab3052f232b..900d50219859335 100644 --- a/boards/arm/nucleo_f091rc/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f091rc/st_morpho_connector.dtsi @@ -12,57 +12,57 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f103rb/st_morpho_connector.dtsi b/boards/arm/nucleo_f103rb/st_morpho_connector.dtsi index 3bfb0315db3a51c..46f13702e072137 100644 --- a/boards/arm/nucleo_f103rb/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f103rb/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f302r8/st_morpho_connector.dtsi b/boards/arm/nucleo_f302r8/st_morpho_connector.dtsi index 61a86c06c429c6b..4b0b19bb22324db 100644 --- a/boards/arm/nucleo_f302r8/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f302r8/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f303re/st_morpho_connector.dtsi b/boards/arm/nucleo_f303re/st_morpho_connector.dtsi index 0727b65bc2524a8..5f05f019a2cf753 100644 --- a/boards/arm/nucleo_f303re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f303re/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f334r8/st_morpho_connector.dtsi b/boards/arm/nucleo_f334r8/st_morpho_connector.dtsi index 0727b65bc2524a8..5f05f019a2cf753 100644 --- a/boards/arm/nucleo_f334r8/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f334r8/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f401re/st_morpho_connector.dtsi b/boards/arm/nucleo_f401re/st_morpho_connector.dtsi index 2385545b7f285c9..eb4c8f0e4f75ce7 100644 --- a/boards/arm/nucleo_f401re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f401re/st_morpho_connector.dtsi @@ -12,55 +12,55 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f410rb/st_morpho_connector.dtsi b/boards/arm/nucleo_f410rb/st_morpho_connector.dtsi index b4d0911921a7094..d91c931f633b712 100644 --- a/boards/arm/nucleo_f410rb/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f410rb/st_morpho_connector.dtsi @@ -12,55 +12,55 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f411re/st_morpho_connector.dtsi b/boards/arm/nucleo_f411re/st_morpho_connector.dtsi index 2385545b7f285c9..eb4c8f0e4f75ce7 100644 --- a/boards/arm/nucleo_f411re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f411re/st_morpho_connector.dtsi @@ -12,55 +12,55 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_f446re/st_morpho_connector.dtsi b/boards/arm/nucleo_f446re/st_morpho_connector.dtsi index 2385545b7f285c9..eb4c8f0e4f75ce7 100644 --- a/boards/arm/nucleo_f446re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_f446re/st_morpho_connector.dtsi @@ -12,55 +12,55 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_g070rb/nucleo_g070rb.dts b/boards/arm/nucleo_g070rb/nucleo_g070rb.dts index 7795983eaad4f3c..94c577c09813c40 100644 --- a/boards/arm/nucleo_g070rb/nucleo_g070rb.dts +++ b/boards/arm/nucleo_g070rb/nucleo_g070rb.dts @@ -158,10 +158,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1>; -}; - &vref { status = "okay"; }; diff --git a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts index 4494cc20d703690..873c6fdd8a15a2d 100644 --- a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts @@ -166,10 +166,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1>; -}; - &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; diff --git a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts index ca6666bdcc16791..fdffaff74b4aaec 100644 --- a/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts +++ b/boards/arm/nucleo_g0b1re/nucleo_g0b1re.dts @@ -209,10 +209,6 @@ zephyr_udc0: &usb { }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1>; -}; - &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; diff --git a/boards/arm/nucleo_g431rb/st_morpho_connector.dtsi b/boards/arm/nucleo_g431rb/st_morpho_connector.dtsi index 61a86c06c429c6b..4b0b19bb22324db 100644 --- a/boards/arm/nucleo_g431rb/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_g431rb/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_g474re/nucleo_g474re.dts b/boards/arm/nucleo_g474re/nucleo_g474re.dts index 36761654136c5fb..41619d7ea27a6d1 100644 --- a/boards/arm/nucleo_g474re/nucleo_g474re.dts +++ b/boards/arm/nucleo_g474re/nucleo_g474re.dts @@ -45,12 +45,6 @@ }; }; - cpus { - cpu@0 { - cpu-power-states = <&stop0 &stop1>; - }; - }; - aliases { led0 = &green_led; pwm-led0 = &green_pwm_led; diff --git a/boards/arm/nucleo_h563zi/nucleo_h563zi-common.dtsi b/boards/arm/nucleo_h563zi/nucleo_h563zi-common.dtsi index 6b72080177d5ced..2c87df305e9fae9 100644 --- a/boards/arm/nucleo_h563zi/nucleo_h563zi-common.dtsi +++ b/boards/arm/nucleo_h563zi/nucleo_h563zi-common.dtsi @@ -8,6 +8,7 @@ #include #include #include "arduino_r3_connector.dtsi" +#include "st_morpho_connector.dtsi" / { leds { diff --git a/boards/arm/nucleo_h563zi/st_morpho_connector.dtsi b/boards/arm/nucleo_h563zi/st_morpho_connector.dtsi new file mode 100644 index 000000000000000..b348ad313a5b18c --- /dev/null +++ b/boards/arm/nucleo_h563zi/st_morpho_connector.dtsi @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023 Marcin Niestroj + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + st_morpho_header: st-morpho-header { + compatible = "st-morpho-header"; + #gpio-cells = <2>; + gpio-map-mask = ; + gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , /* SB45=ON, R34=OFF */ + , /* SB44=ON, R35=OFF */ + , + , + , /* SB58=OFF */ + , + , /* SB56=OFF */ + , /* LD1 green LED if SB43=ON */ + , + , /* SB62=OFF */ + , + , + , + , + , + , + , + , + , + , /* SB64=ON */ + , /* SB78=ON */ + , /* SB8=ON */ + , /* SB9=ON */ + , + , + , + , + , + , + , + , + , + , /* SB68=ON */ + , + , + , + , + , /* SB37=OFF */ + , /* SB75=ON, SB18=OFF, SB65=OFF */ + , /* SB34=OFF */ + + , + , + , + , + , + , /* SB36=OFF */ + , + , /* LD1 green LED if SB51=ON */ + , /* SB22=ON, SB28=OFF */ + , + , /* SB21=ON, SB27=OFF */ + , /* SB38=OFF */ + , + , + , + , /* SB31=OFF */ + , + , + , + , + , /* JP6=OFF */ + , + , /* SB30=OFF */ + , + , /* SB29=OFF */ + , /* SB39=OFF */ + , + , /* SB42=OFF */ + , /* SB69=OFF */ + , + , + , /* LD2 yellow LED */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB74=OFF */ + , + , /* LD3 red LED */ + ; + }; +}; diff --git a/boards/arm/nucleo_l053r8/st_morpho_connector.dtsi b/boards/arm/nucleo_l053r8/st_morpho_connector.dtsi index 30c9999389c249b..3c0d419f02f9064 100644 --- a/boards/arm/nucleo_l053r8/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_l053r8/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_l073rz/st_morpho_connector.dtsi b/boards/arm/nucleo_l073rz/st_morpho_connector.dtsi index 30c9999389c249b..3c0d419f02f9064 100644 --- a/boards/arm/nucleo_l073rz/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_l073rz/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_l152re/st_morpho_connector.dtsi b/boards/arm/nucleo_l152re/st_morpho_connector.dtsi index 30c9999389c249b..3c0d419f02f9064 100644 --- a/boards/arm/nucleo_l152re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_l152re/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_l452re/st_morpho_connector.dtsi b/boards/arm/nucleo_l452re/st_morpho_connector.dtsi index 30c9999389c249b..3c0d419f02f9064 100644 --- a/boards/arm/nucleo_l452re/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_l452re/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_l476rg/nucleo_l476rg.dts b/boards/arm/nucleo_l476rg/nucleo_l476rg.dts index 7d9ac593d77f1eb..20b0620e9a85ee9 100644 --- a/boards/arm/nucleo_l476rg/nucleo_l476rg.dts +++ b/boards/arm/nucleo_l476rg/nucleo_l476rg.dts @@ -73,10 +73,6 @@ apb2-prescaler = <1>; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; diff --git a/boards/arm/nucleo_l476rg/st_morpho_connector.dtsi b/boards/arm/nucleo_l476rg/st_morpho_connector.dtsi index 30c9999389c249b..3c0d419f02f9064 100644 --- a/boards/arm/nucleo_l476rg/st_morpho_connector.dtsi +++ b/boards/arm/nucleo_l476rg/st_morpho_connector.dtsi @@ -12,56 +12,56 @@ #gpio-cells = <2>; gpio-map-mask = ; gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; - gpio-map = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , /* SB56=ON, SB46=OFF */ - , - , /* SB51=ON, SB52=OFF */ - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; }; }; diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts index fa23301d389b523..f580993a8cd56b5 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts @@ -103,10 +103,6 @@ apb2-prescaler = <1>; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &usart1 { pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; pinctrl-names = "default"; diff --git a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts index fe439d6da870506..1959ad16127cf1c 100644 --- a/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts +++ b/boards/arm/nucleo_wl55jc/nucleo_wl55jc.dts @@ -66,10 +66,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &clk_lsi { status = "okay"; }; diff --git a/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.dts b/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.dts index 8655ee06add67f4..434fa8b5fb721bd 100644 --- a/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.dts +++ b/boards/arm/olimex_lora_stm32wl_devkit/olimex_lora_stm32wl_devkit.dts @@ -43,10 +43,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; diff --git a/boards/arm/qomu/CMakeLists.txt b/boards/arm/qomu/CMakeLists.txt deleted file mode 100644 index a17def9a23147a0..000000000000000 --- a/boards/arm/qomu/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2022 Antmicro -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources(board.c) diff --git a/boards/arm/qomu/board.c b/boards/arm/qomu/board.c deleted file mode 100644 index d6752dff91338cc..000000000000000 --- a/boards/arm/qomu/board.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2022 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "board.h" - -static int qomu_board_init(void) -{ - - /* IO MUX setup for UART */ - eos_s3_io_mux(UART_TX_PAD, UART_TX_PAD_CFG); - eos_s3_io_mux(UART_RX_PAD, UART_RX_PAD_CFG); - - IO_MUX->UART_rxd_SEL = UART_RX_SEL; - - /* IO MUX setup for USB */ - eos_s3_io_mux(USB_PU_CTRL_PAD, USB_PAD_CFG); - eos_s3_io_mux(USB_DN_PAD, USB_PAD_CFG); - eos_s3_io_mux(USB_DP_PAD, USB_PAD_CFG); - - return 0; -} - -SYS_INIT(qomu_board_init, PRE_KERNEL_1, CONFIG_BOARD_INIT_PRIORITY); diff --git a/boards/arm/qomu/board.h b/boards/arm/qomu/board.h deleted file mode 100644 index 9bcd5820b10f237..000000000000000 --- a/boards/arm/qomu/board.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2022 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __INC_BOARD_H -#define __INC_BOARD_H - -#include - -#define USB_PU_CTRL_PAD 23 -#define USB_DN_PAD 28 -#define USB_DP_PAD 31 -#define USB_PAD_CFG (PAD_E_4MA | PAD_P_Z | PAD_OEN_NORMAL | PAD_SMT_DISABLE \ - | PAD_REN_DISABLE | PAD_SR_SLOW | PAD_CTRL_SEL_FPGA) - -#define UART_TX_PAD 44 -#define UART_TX_PAD_CFG UART_TXD_PAD44 -#define UART_RX_PAD 45 -#define UART_RX_PAD_CFG UART_RXD_PAD45 - -#define UART_RX_SEL UART_RXD_SEL_PAD45 - -#endif /* __INC_BOARD_H */ diff --git a/boards/arm/qomu/qomu.dts b/boards/arm/qomu/qomu.dts index c58825a5f4f6608..dfdb9a14c18c6c6 100644 --- a/boards/arm/qomu/qomu.dts +++ b/boards/arm/qomu/qomu.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "QuickLogic Qomu board"; @@ -56,6 +57,35 @@ }; }; +&pinctrl { + uart1_rx_default: uart1_rx_default { + pinmux = ; + input-enable; + }; + uart1_tx_default: uart1_tx_default { + pinmux = ; + output-enable; + }; + usb_pu_default: usb_pu_default { + pinmux = ; + bias-high-impedance; + quicklogic,control-selection = "fabric"; + output-enable; + }; + usb_dn_default: usb_dn_default { + pinmux = ; + bias-high-impedance; + quicklogic,control-selection = "fabric"; + output-enable; + }; + usb_dp_default: usb_dp_default { + pinmux = ; + bias-high-impedance; + quicklogic,control-selection = "fabric"; + output-enable; + }; +}; + &cpu0 { clock-frequency = <61440000>; }; @@ -71,4 +101,7 @@ &uart1 { status = "okay"; current-speed = <115200>; + pinctrl-0 = <&uart1_rx_default &uart1_tx_default + &usb_pu_default &usb_dn_default &usb_dp_default>; + pinctrl-names = "default"; }; diff --git a/boards/arm/quick_feather/CMakeLists.txt b/boards/arm/quick_feather/CMakeLists.txt deleted file mode 100644 index 77aee051c0c72ca..000000000000000 --- a/boards/arm/quick_feather/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2020 Antmicro -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources(board.c) -zephyr_include_directories(.) diff --git a/boards/arm/quick_feather/board.c b/boards/arm/quick_feather/board.c deleted file mode 100644 index cf89c208ced0dd0..000000000000000 --- a/boards/arm/quick_feather/board.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2020 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -static int eos_s3_board_init(void) -{ - - /* IO MUX setup for UART */ - eos_s3_io_mux(UART_TX_PAD, UART_TX_PAD_CFG); - eos_s3_io_mux(UART_RX_PAD, UART_RX_PAD_CFG); - - IO_MUX->UART_rxd_SEL = UART_RX_SEL; - - return 0; -} - -SYS_INIT(eos_s3_board_init, PRE_KERNEL_1, CONFIG_BOARD_INIT_PRIORITY); diff --git a/boards/arm/quick_feather/board.h b/boards/arm/quick_feather/board.h deleted file mode 100644 index 857a6edd037270c..000000000000000 --- a/boards/arm/quick_feather/board.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2020 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __INC_BOARD_H -#define __INC_BOARD_H - -#include - -#define UART_TX_PAD 44 -#define UART_TX_PAD_CFG UART_TXD_PAD44 -#define UART_RX_PAD 45 -#define UART_RX_PAD_CFG UART_RXD_PAD45 - -#define UART_RX_SEL UART_RXD_SEL_PAD45 - -#endif /* __INC_BOARD_H */ diff --git a/boards/arm/quick_feather/quick_feather.dts b/boards/arm/quick_feather/quick_feather.dts index 9bde6c938c3490d..2dc8053255a04ac 100644 --- a/boards/arm/quick_feather/quick_feather.dts +++ b/boards/arm/quick_feather/quick_feather.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "QuickLogic Quick Feather board"; @@ -56,6 +57,17 @@ }; }; +&pinctrl { + uart_rx_default: uart_rx_default { + pinmux = ; + input-enable; + }; + uart_tx_default: uart_tx_default { + pinmux = ; + output-enable; + }; +}; + &cpu0 { clock-frequency = <61440000>; }; @@ -67,4 +79,6 @@ &uart0 { status = "okay"; current-speed = <115200>; + pinctrl-0 = <&uart_rx_default &uart_tx_default>; + pinctrl-names = "default"; }; diff --git a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi index 1471d56a3382e78..d6d58aa9a858739 100644 --- a/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi +++ b/boards/arm/s32z270dc2_r52/s32z270dc2_r52.dtsi @@ -109,7 +109,7 @@ pinctrl-0 = <ð0_default>; pinctrl-names = "default"; clock-frequency = <300000000>; - phy-dev = <&phy0>; + phy-handle = <&phy0>; status = "okay"; }; diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_black.dts b/boards/arm/stm32_min_dev/stm32_min_dev_black.dts index 8df88f45052fe70..80c283d24d93f87 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_black.dts +++ b/boards/arm/stm32_min_dev/stm32_min_dev_black.dts @@ -9,7 +9,7 @@ / { model = "STM32 Minimum Development Board (Black)"; - compatible = "st,stm32_min_dev_black", "st,stm32f103c8"; + compatible = "stm32_min_dev_black", "st,stm32f103c8"; leds { led: led { diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts b/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts index fe3c23e34810f0f..8d0f3419b86694a 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts +++ b/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts @@ -9,7 +9,7 @@ / { model = "STM32 Minimum Development Board (Blue)"; - compatible = "st,stm32_min_dev_blue", "st,stm32f103c8"; + compatible = "stm32_min_dev_blue", "st,stm32f103c8"; leds { led: led { diff --git a/boards/arm/stm32f030_demo/stm32f030_demo.dts b/boards/arm/stm32f030_demo/stm32f030_demo.dts index 794cc7dce8e6fd8..5bb5b80da34c639 100644 --- a/boards/arm/stm32f030_demo/stm32f030_demo.dts +++ b/boards/arm/stm32f030_demo/stm32f030_demo.dts @@ -10,7 +10,7 @@ / { model = "STM32F030 DEMO board"; - compatible = "st,stm32f030-demo"; + compatible = "stm32f030-demo"; chosen { zephyr,console = &usart1; diff --git a/boards/arm/stm32f103_mini/stm32f103_mini.dts b/boards/arm/stm32f103_mini/stm32f103_mini.dts index 95a6cc5233aa854..1a158b9be7e73d9 100644 --- a/boards/arm/stm32f103_mini/stm32f103_mini.dts +++ b/boards/arm/stm32f103_mini/stm32f103_mini.dts @@ -10,7 +10,7 @@ / { model = "stm32f103_mini board"; - compatible = "st,stm32f103"; + compatible = "stm32f103"; chosen { zephyr,console = &usart1; diff --git a/boards/arm/stm32f412g_disco/stm32f412g_disco.dts b/boards/arm/stm32f412g_disco/stm32f412g_disco.dts index 56704e923d4801a..959a3706f5333c9 100644 --- a/boards/arm/stm32f412g_disco/stm32f412g_disco.dts +++ b/boards/arm/stm32f412g_disco/stm32f412g_disco.dts @@ -35,7 +35,7 @@ label = "User LD3"; }; blue_led_4: led_4 { - gpios = <&gpioe 4 GPIO_ACTIVE_HIGH>; + gpios = <&gpioe 3 GPIO_ACTIVE_HIGH>; label = "User LD4"; }; }; diff --git a/boards/arm/stm32f746g_disco/support/openocd.cfg b/boards/arm/stm32f746g_disco/support/openocd.cfg index ad005693e338ff2..2dd9cf42c1c0ccf 100644 --- a/boards/arm/stm32f746g_disco/support/openocd.cfg +++ b/boards/arm/stm32f746g_disco/support/openocd.cfg @@ -11,9 +11,13 @@ $_TARGETNAME configure -event gdb-detach { resume } +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + adapter serial $_ZEPHYR_BOARD_SERIAL +} + # Event reset-init already uses the maximum speed however adapter speed # inherited from stm32f7x.cfg for reset-start defaults to 2000 kHz, so # override that speed setting it also to the maximum speed. $_TARGETNAME configure -event reset-start { - adapter speed 4000 + adapter speed 4000 } diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi index f9a13cceb34dd01..fff6676bdac4e09 100644 --- a/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -37,10 +37,6 @@ }; }; -&cpu0 { - cpu-power-states = <&stop0 &stop1 &stop2>; -}; - &clk_hsi48 { status = "okay"; }; diff --git a/boards/arm/twr_ke18f/twr_ke18f.dts b/boards/arm/twr_ke18f/twr_ke18f.dts index d58804dff507c01..465ef203fb44a92 100644 --- a/boards/arm/twr_ke18f/twr_ke18f.dts +++ b/boards/arm/twr_ke18f/twr_ke18f.dts @@ -140,7 +140,6 @@ &cpu0 { clock-frequency = <120000000>; - cpu-power-states = <&idle &stop>; }; &idle { diff --git a/boards/arm/xmc45_relax_kit/doc/index.rst b/boards/arm/xmc45_relax_kit/doc/index.rst index ee107a66fb9b26d..17669cedcbe1fc3 100644 --- a/boards/arm/xmc45_relax_kit/doc/index.rst +++ b/boards/arm/xmc45_relax_kit/doc/index.rst @@ -45,6 +45,16 @@ The Relax Kit development board configuration supports the following hardware fe +-----------+------------+-----------------------+ | SPI | on-chip | spi | +-----------+------------+-----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+-----------------------+ +| ADC | on-chip | adc | ++-----------+------------+-----------------------+ +| DMA | on-chip | dma | ++-----------+------------+-----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-----------------------+ More details about the supported peripherals are available in `XMC4500 TRM`_ Other hardware features are not currently supported by the Zephyr kernel. diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit-pinctrl.dtsi b/boards/arm/xmc45_relax_kit/xmc45_relax_kit-pinctrl.dtsi index 790bb49bbc05be0..04156e2890ceb6b 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit-pinctrl.dtsi +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit-pinctrl.dtsi @@ -15,3 +15,15 @@ drive-strength = "strong-soft-edge"; hwctrl = "disabled"; }; + +&pwm_out_p1_0_ccu40_ch3 { + drive-strength = "strong-medium-edge"; + drive-push-pull; + hwctrl = "disabled"; +}; + +&pwm_out_p1_1_ccu40_ch2 { + drive-strength = "strong-medium-edge"; + drive-push-pull; + hwctrl = "disabled"; +}; diff --git a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts index 4033b530ad57ede..a6fe5e5942ca301 100644 --- a/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts +++ b/boards/arm/xmc45_relax_kit/xmc45_relax_kit.dts @@ -10,6 +10,7 @@ #include #include +#include #include "xmc45_relax_kit-pinctrl.dtsi" / { @@ -20,6 +21,7 @@ aliases { led0 = &led1; die-temp0 = &die_temp; + pwm-led0 = &pwm_led1; }; leds { @@ -33,6 +35,18 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + pwm_led1: pwm_led1 { + pwms = <&pwm_ccu40 2 PWM_SEC(1) PWM_POLARITY_NORMAL>; + label = "PWM LED1"; + }; + pwm_led2: pwm_led2 { + pwms = <&pwm_ccu40 3 PWM_SEC(1) PWM_POLARITY_NORMAL>; + label = "PWM LED2"; + }; + }; + chosen { zephyr,sram = &dsram1; zephyr,flash = &flash0; @@ -102,3 +116,9 @@ &gpio1 { status = "okay"; }; + +&pwm_ccu40 { + slice-prescaler = <15 15 15 15>; + pinctrl-0 = <&pwm_out_p1_0_ccu40_ch3 &pwm_out_p1_1_ccu40_ch2>; + pinctrl-names = "default"; +}; diff --git a/boards/arm/xmc47_relax_kit/doc/index.rst b/boards/arm/xmc47_relax_kit/doc/index.rst index 891f7c0952fbb9c..fea191f4c30b73f 100644 --- a/boards/arm/xmc47_relax_kit/doc/index.rst +++ b/boards/arm/xmc47_relax_kit/doc/index.rst @@ -56,6 +56,8 @@ The Relax Kit development board configuration supports the following hardware fe +-----------+------------+-----------------------+ | DMA | on-chip | dma | +-----------+------------+-----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-----------------------+ More details about the supported peripherals are available in `XMC4700 TRM`_ Other hardware features are not currently supported by the Zephyr kernel. diff --git a/boards/arm/xmc47_relax_kit/xmc47_relax_kit-pinctrl.dtsi b/boards/arm/xmc47_relax_kit/xmc47_relax_kit-pinctrl.dtsi index 9a4b8fde34d86fa..c8dbbd27a5eddb5 100644 --- a/boards/arm/xmc47_relax_kit/xmc47_relax_kit-pinctrl.dtsi +++ b/boards/arm/xmc47_relax_kit/xmc47_relax_kit-pinctrl.dtsi @@ -43,3 +43,15 @@ drive-push-pull; hwctrl = "disabled"; }; + +&pwm_out_p5_9_ccu80_ch4_high { + drive-strength = "strong-medium-edge"; + drive-push-pull; + hwctrl = "disabled"; +}; + +&pwm_out_p5_8_ccu80_ch0_low { + drive-strength = "strong-medium-edge"; + drive-push-pull; + hwctrl = "disabled"; +}; diff --git a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts index c02b4215d91efc7..3f0a6e8b0c91b70 100644 --- a/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts +++ b/boards/arm/xmc47_relax_kit/xmc47_relax_kit.dts @@ -9,6 +9,7 @@ #include #include +#include #include "xmc47_relax_kit-pinctrl.dtsi" #include "arduino_r3_connector.dtsi" @@ -19,6 +20,7 @@ aliases { led0 = &led1; die-temp0 = &die_temp; + pwm-led0 = &pwm_led1; }; leds { @@ -32,6 +34,18 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + pwm_led1: pwm_led1 { + pwms = <&pwm_ccu80 4 PWM_SEC(1) PWM_POLARITY_NORMAL>; + label = "PWM LED1"; + }; + pwm_led2: pwm_led2 { + pwms = <&pwm_ccu80 0 PWM_SEC(1) PWM_POLARITY_NORMAL>; + label = "PWM LED2"; + }; + }; + chosen { zephyr,sram = &psram1; zephyr,flash = &flash0; @@ -135,3 +149,14 @@ &gpio5 { status = "okay"; }; + +/* this example is not using the high-side/low-side signals of the same channel */ +/* the PWM signals are only used for the blink led example */ +&pwm_ccu80 { + slice-prescaler = <15 15 15 15>; + slice-deadtime-prescaler = <3 3 3 3>; + channel-deadtime-high = <0 0 0 0 0 0 0 0>; + channel-deadtime-low = <0 0 0 0 0 0 0 0>; + pinctrl-0 = <&pwm_out_p5_9_ccu80_ch4_high &pwm_out_p5_8_ccu80_ch0_low>; + pinctrl-names = "default"; +}; diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml index 37e25bc5d8eb723..0d6ed9a59fd25d8 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350.yaml @@ -13,6 +13,7 @@ supported: - spi - eeprom - watchdog + - mbox testing: ignore_tags: - bluetooth diff --git a/boards/shields/rk055hdmipi4ma0/Kconfig.defconfig b/boards/shields/rk055hdmipi4ma0/Kconfig.defconfig new file mode 100644 index 000000000000000..6b7c77037b4d256 --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/Kconfig.defconfig @@ -0,0 +1,56 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_RK055HDMIPI4MA0 + +if DISPLAY + +# Enable MIPI DSI, as this display controller requires it. + +config MIPI_DSI + default y + +endif # DISPLAY + +if LVGL + +# Configure LVGL to use touchscreen with KSCAN API + +config KSCAN + default y + +config INPUT + default y if KSCAN + +config INPUT_GT911_INTERRUPT + default y + +config LV_Z_POINTER_KSCAN + default y + +# LVGL should allocate buffers equal to size of display +config LV_Z_VDB_SIZE + default 100 + +# Enable double buffering +config LV_Z_DOUBLE_VDB + default y + +# Force full refresh. This prevents memory copy associated with partial +# display refreshes, which is not necessary for the eLCDIF driver +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 16 + +config LV_DPI_DEF + default 128 + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_16 +endchoice + +endif # LVGL + +endif # SHIELD_RK055HDMIPI4MA0 diff --git a/boards/shields/rk055hdmipi4ma0/Kconfig.shield b/boards/shields/rk055hdmipi4ma0/Kconfig.shield new file mode 100644 index 000000000000000..96702b2dce692e8 --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RK055HDMIPI4MA0 + def_bool $(shields_list_contains,rk055hdmipi4ma0) diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.conf b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.conf new file mode 100644 index 000000000000000..bf60c87c6934c0c --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.conf @@ -0,0 +1,14 @@ +# +# Copyright 2023, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Use external framebuffer memory +CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y +CONFIG_LV_Z_VBD_CUSTOM_SECTION=y +# Use FlexSPI2 for framebuffer (pSRAM is present on this bus) +CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x38400000 +# M33 core and LCDIF both access FlexSPI2 through the same cache, +# so coherency does not need to be managed. +CONFIG_MCUX_DCNANO_LCDIF_MAINTAIN_CACHE=n diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.overlay b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.overlay new file mode 100644 index 000000000000000..38bc21b8de71447 --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_cm33.overlay @@ -0,0 +1,18 @@ +/* + * Copyright 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Configure FlexSPI2 to use 1KB of AHB RX buffer for GPU/Display master. + * This will improve performance when using external pSRAM. + */ +&flexspi2 { + rx-buffer-config = <1 7 11 1024>; +}; + +/* GT911 IRQ GPIO is active low on this board */ +&touch_controller_rk055hdmipi4ma0 { + irq-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_LOW>; +}; diff --git a/boards/shields/rk055hdmipi4ma0/doc/index.rst b/boards/shields/rk055hdmipi4ma0/doc/index.rst new file mode 100644 index 000000000000000..887a70fb24679f0 --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/doc/index.rst @@ -0,0 +1,68 @@ +.. _rk055hdmipi4ma0: + +RK055HDMIPI4MA0 MIPI Display +############################ + +Overview +******** + +The Rocktech RK055HDMIPI4MA0 MIPI Display is a 5.5 inch TFT 720x1280 pixels +panel with LED backlighting, full viewing angle, MIPI interface and +capacitive touch panel from Rocktech. + +More information about the shield can be found +at the `RK055HDMIPI4MA0 product page`_. + +This display uses a 40 pin FPC interface, which is available on many +NXP EVKs. + +Pins Assignment of the Rocktech RK055HDMIPI4MA0 MIPI Display +============================================================ + ++-----------------------+------------------------+ +| FPC Connector Pin | Function | ++=======================+========================+ +| 1 | LED backlight cathode | ++-----------------------+------------------------+ +| 21 | Controller reset | ++-----------------------+------------------------+ +| 22 | Controller LPTE | ++-----------------------+------------------------+ +| 26 | Touch ctrl I2C SDA | ++-----------------------+------------------------+ +| 27 | Touch ctrl I2C SCL | ++-----------------------+------------------------+ +| 28 | Touch ctrl reset | ++-----------------------+------------------------+ +| 29 | Touch ctrl interrupt | ++-----------------------+------------------------+ +| 32 | LCD power enable | ++-----------------------+------------------------+ +| 34 | Backlight power enable | ++-----------------------+------------------------+ + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for the 40 pin FPC interface + +Programming +*********** + +Set ``-DSHIELD=rk055hdmipi4ma0`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/display + :board: mixmrt1170_evk_cm7 + :shield: rk055hdmipi4ma0 + :goals: build + +References +********** + +.. target-notes:: + +.. _RK055HDMIPI4MA0 product page: + https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/5-5-lcd-panel:RK055HDMIPI4MA0 diff --git a/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay new file mode 100644 index 000000000000000..c7e5e3966a97ee1 --- /dev/null +++ b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay @@ -0,0 +1,91 @@ +/* + * Copyright 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/{ + aliases { + kscan0 = &kscan_input_gt911; + }; + + chosen { + zephyr,display = &lcdif; + zephyr,keyboard-scan = &kscan_input_gt911; + }; + + en_mipi_display_rk055hdmipi4ma0: enable-mipi-display-rk055hdmipi4ma0 { + compatible = "regulator-fixed"; + regulator-name = "en_mipi_display"; + enable-gpios = <&nxp_mipi_connector 32 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; +}; + +&nxp_mipi_i2c { + status = "okay"; + touch_controller_rk055hdmipi4ma0: gt911-rk055hdmipi4ma0@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + irq-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_HIGH>; + reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_HIGH>; + kscan_input_gt911: kscan-input { + compatible = "zephyr,kscan-input"; + }; + }; +}; + +&zephyr_lcdif { + status = "okay"; + width = <720>; + height = <1280>; + display-timings { + compatible = "zephyr,panel-timing"; + hsync-len = <6>; + hfront-porch = <12>; + hback-porch = <24>; + vsync-len = <2>; + vfront-porch = <16>; + vback-porch = <14>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + /* + * Pixel clock is given by the following formula: + * (height + vsync-len + vfront-porch + vback-porch) * + * (width + hsync-len + hfront-porch + hback-porch) * frame rate + */ + clock-frequency = <62346240>; + }; + pixel-format = ; + data-bus-width = "24-bit"; + backlight-gpios = <&nxp_mipi_connector 0 GPIO_ACTIVE_HIGH>; +}; + +&zephyr_mipi_dsi { + status = "okay"; + nxp,lcdif = <&lcdif>; + dpi-color-coding = "24-bit"; + dpi-pixel-packet = "24-bit"; + dpi-video-mode = "burst"; + dpi-bllp-mode = "low-power"; + autoinsert-eotp; + /* + * PHY clock is given by the following formula: + * (pixel clock * bits per pixel) / MIPI data lanes + */ + phy-clock = <748154880>; + hx8394-rk055hdmipi4ma0@0 { + status = "okay"; + compatible = "himax,hx8394"; + reg = <0x0>; + reset-gpios = <&nxp_mipi_connector 21 GPIO_ACTIVE_HIGH>; + data-lanes = <2>; + width = <720>; + height = <1280>; + pixel-format = ; + }; +}; diff --git a/boards/x86/intel_ish/Kconfig.board b/boards/x86/intel_ish/Kconfig.board new file mode 100644 index 000000000000000..77962495a12e7e2 --- /dev/null +++ b/boards/x86/intel_ish/Kconfig.board @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config BOARD_INTEL_ISH_5_4_1 + bool "Intel ISH 5.4.1 board" + depends on SOC_INTEL_ISH_5_4_1 + +config BOARD_INTEL_ISH_5_6_0 + bool "Intel ISH 5.6.0 board" + depends on SOC_INTEL_ISH_5_6_0 + +config BOARD_INTEL_ISH_5_8_0 + bool "Intel ISH 5.8.0 board" + depends on SOC_INTEL_ISH_5_8_0 diff --git a/boards/x86/intel_ish/Kconfig.defconfig b/boards/x86/intel_ish/Kconfig.defconfig new file mode 100644 index 000000000000000..f989dfcd6ed365a --- /dev/null +++ b/boards/x86/intel_ish/Kconfig.defconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +if BOARD_INTEL_ISH_5_4_1 || BOARD_INTEL_ISH_5_6_0 || BOARD_INTEL_ISH_5_8_0 + +config BOARD + default "intel_ish_5_4_1" if BOARD_INTEL_ISH_5_4_1 + default "intel_ish_5_6_0" if BOARD_INTEL_ISH_5_6_0 + default "intel_ish_5_8_0" if BOARD_INTEL_ISH_5_8_0 + +if TEST +config TEST_EXTRA_STACK_SIZE + int + default 1024 +endif # TEST + +config HPET_TIMER + default y + +config SYS_CLOCK_TICKS_PER_SEC + default 2048 if HPET_TIMER # HPET is 32768 HZ + +endif # BOARD_INTEL_ISH_5_4_1 || BOARD_INTEL_ISH_5_6_0 || BOARD_INTEL_ISH_5_8_0 diff --git a/boards/x86/intel_ish/doc/index.rst b/boards/x86/intel_ish/doc/index.rst new file mode 100644 index 000000000000000..2f621483f1c9cd0 --- /dev/null +++ b/boards/x86/intel_ish/doc/index.rst @@ -0,0 +1,78 @@ +.. _intel_ish: + +Intel Integrated Sensor Hub (ISH) +################################# + +Overview +******** +Intel Integrated Sensor Hub (ISH) is a lower-power/always-on co-processor +inside many Intel Processors. It helps offload sensor processing tasks from +the core processor for better power saving. + +Hardware +******** + +- LMT MinuteIA Core, with + . 16KB instruction cache and 16KB data cache. + . 640KB SRAM space for code and data - implemented as L2 SRAM. + . 8KB AON RF space for code resident during deep D0i2/3 PG states. +- Interface-to-Sensor peripherals (I2C, SPI, UART, I3C, GPIO, DMA). +- Inter Process Communications (IPC) to core processor and other IP processors. + +.. include:: ../../../../soc/x86/intel_ish/doc/supported_features.txt + +Programming and Debugging +************************* +Use the following procedures for booting an ISH image on a ADL RVP board +for Chrome. + +.. contents:: + :depth: 1 + :local: + :backlinks: top + +Build Zephyr application +======================== + +#. Build a Zephyr application; for instance, to build the ``hello_world`` + application for ISH 5.4.1 on Intel ADL Processor: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: intel_ish_5_4_1 + :goals: build + + .. note:: + + A Zephyr image file named :file:`ish_fw.bin` is automatically + created in the build directory after the application is built. + +Run ish_fw.bin on ADL RVP board for Chrome +========================================== + +# Power on the ADL RVP board. + +# Log in Chrome OS. (Note: the user must have root access right.) + +# Re-mount the root filesystem as read-write: + + .. code-block:: console + + $ mount -o remount,rw / + + If re-mount fails, execute below commands to Remove rootfs verification: + + .. code-block:: console + + $ /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification --partitions + $ reboot + +# Go to the ISH firmware direcoty: + + .. code-block:: console + + $ cd /lib/firmware/intel + + Relace the file adlrvp_ish.bin with zephyr image built out, ish_fw.bin. + +# Reboot, then observe zephyr log output via ISH UART0. diff --git a/boards/x86/intel_ish/intel_ish_5_4_1.dts b/boards/x86/intel_ish/intel_ish_5_4_1.dts new file mode 100644 index 000000000000000..04479034cf41fe9 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_4_1.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "intel/intel_ish5.dtsi" + +/ { + model = "intel_ish_5_4_1"; + compatible = "intel,ish_5_4_1"; + + chosen { + zephyr,sram = &sram; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; diff --git a/boards/x86/intel_ish/intel_ish_5_4_1.yaml b/boards/x86/intel_ish/intel_ish_5_4_1.yaml new file mode 100644 index 000000000000000..a04b3c0e5d0b4e1 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_4_1.yaml @@ -0,0 +1,13 @@ +identifier: intel_ish_5_4_1 +name: Intel ISH 5.4.1 SoC +type: mcu +arch: x86 +toolchain: + - zephyr +ram: 640 +supported: + - serial +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/x86/intel_ish/intel_ish_5_4_1_defconfig b/boards/x86/intel_ish/intel_ish_5_4_1_defconfig new file mode 100644 index 000000000000000..527466ad337b6b5 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_4_1_defconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_FAMILY_INTEL_ISH=y +CONFIG_SOC_SERIES_INTEL_ISH5=y +CONFIG_SOC_INTEL_ISH_5_4_1=y +CONFIG_BOARD_INTEL_ISH_5_4_1=y + +# uart & console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/x86/intel_ish/intel_ish_5_6_0.dts b/boards/x86/intel_ish/intel_ish_5_6_0.dts new file mode 100644 index 000000000000000..431180843de6646 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_6_0.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "intel/intel_ish5.dtsi" + +/ { + model = "intel_ish_5_6_0"; + compatible = "intel,ish_5_6_0"; + + chosen { + zephyr,sram = &sram; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; diff --git a/boards/x86/intel_ish/intel_ish_5_6_0.yaml b/boards/x86/intel_ish/intel_ish_5_6_0.yaml new file mode 100644 index 000000000000000..42044c0d14cd394 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_6_0.yaml @@ -0,0 +1,13 @@ +identifier: intel_ish_5_6_0 +name: Intel ISH 5.6.0 SoC +type: mcu +arch: x86 +toolchain: + - zephyr +ram: 640 +supported: + - serial +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/x86/intel_ish/intel_ish_5_6_0_defconfig b/boards/x86/intel_ish/intel_ish_5_6_0_defconfig new file mode 100644 index 000000000000000..74b00676d399779 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_6_0_defconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_FAMILY_INTEL_ISH=y +CONFIG_SOC_SERIES_INTEL_ISH5=y +CONFIG_SOC_INTEL_ISH_5_6_0=y +CONFIG_BOARD_INTEL_ISH_5_6_0=y + +# uart & console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/x86/intel_ish/intel_ish_5_8_0.dts b/boards/x86/intel_ish/intel_ish_5_8_0.dts new file mode 100644 index 000000000000000..34c5ef2f7336450 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_8_0.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "intel/intel_ish5_8.dtsi" + +/ { + model = "intel_ish_5_8_0"; + compatible = "intel,ish_5_8_0"; + + chosen { + zephyr,sram = &sram; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; diff --git a/boards/x86/intel_ish/intel_ish_5_8_0.yaml b/boards/x86/intel_ish/intel_ish_5_8_0.yaml new file mode 100644 index 000000000000000..e750d236d064e9d --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_8_0.yaml @@ -0,0 +1,13 @@ +identifier: intel_ish_5_8_0 +name: Intel ISH 5.8.0 SoC +type: mcu +arch: x86 +toolchain: + - zephyr +ram: 640 +supported: + - serial +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/x86/intel_ish/intel_ish_5_8_0_defconfig b/boards/x86/intel_ish/intel_ish_5_8_0_defconfig new file mode 100644 index 000000000000000..ee319557f761b47 --- /dev/null +++ b/boards/x86/intel_ish/intel_ish_5_8_0_defconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_FAMILY_INTEL_ISH=y +CONFIG_SOC_SERIES_INTEL_ISH5=y +CONFIG_SOC_INTEL_ISH_5_8_0=y +CONFIG_BOARD_INTEL_ISH_5_8_0=y + +# uart & console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/x86/up_squared/up_squared.dts b/boards/x86/up_squared/up_squared.dts index 9d3ff269ba1cae1..987125da950d5d9 100644 --- a/boards/x86/up_squared/up_squared.dts +++ b/boards/x86/up_squared/up_squared.dts @@ -29,6 +29,25 @@ zephyr,uart-pipe = &uart1; zephyr,bt-mon-uart = &uart1; }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "intel,apollo_lake"; + d-cache-line-size = <64>; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "intel,apollo_lake"; + d-cache-line-size = <64>; + reg = <1>; + }; + }; }; &hpet { diff --git a/doc/connectivity/usb/device/api/index.rst b/doc/connectivity/usb/device/api/index.rst index ddc06aa4768613a..02bf793805e342f 100644 --- a/doc/connectivity/usb/device/api/index.rst +++ b/doc/connectivity/usb/device/api/index.rst @@ -9,3 +9,4 @@ USB device support APIs usb_dc.rst usb_device.rst usb_device_hid.rst + usb_device_bos.rst diff --git a/doc/connectivity/usb/device/api/usb_device_bos.rst b/doc/connectivity/usb/device/api/usb_device_bos.rst new file mode 100644 index 000000000000000..a40318796467286 --- /dev/null +++ b/doc/connectivity/usb/device/api/usb_device_bos.rst @@ -0,0 +1,9 @@ +.. _usb_bos_api: + +Binary Device Object Store (BOS) support API +############################################ + +API reference +************* + +.. doxygengroup:: usb_bos diff --git a/doc/contribute/bin_blobs.rst b/doc/contribute/bin_blobs.rst index f821cac1d254802..661007927a0d069 100644 --- a/doc/contribute/bin_blobs.rst +++ b/doc/contribute/bin_blobs.rst @@ -217,6 +217,12 @@ over bit-rot, security issues, etc. The submitter of the proposal to integrate a binary blob must commit to maintain the integration of such blob for the foreseeable future. +Regarding Continuous Integration, binary blobs will **not** be fetched in the +project's CI infrastructure that builds and optionally executes tests and samples +to prevent regressions and issues from entering the codebase. This includes +both CI ran when a new GitHub Pull Request is opened as well as any other +regularly scheduled execution of the CI infrastructure. + .. _blobs-process: Submission and review process diff --git a/doc/hardware/peripherals/sensor.rst b/doc/hardware/peripherals/sensor.rst index d0dcf8f20d3a9dd..5c7817b627bbb12 100644 --- a/doc/hardware/peripherals/sensor.rst +++ b/doc/hardware/peripherals/sensor.rst @@ -228,3 +228,4 @@ API Reference ************** .. doxygengroup:: sensor_interface +.. doxygengroup:: sensor_emulator_backend diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index a6bb1beaec3d60a..ac174f415e21fb0 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -24,6 +24,14 @@ Changes in this release ``16``). Bootloaders that use a part of the SRAM should set this value to an appropriate size. :github:`60371` +* Time and timestamps in the network subsystem, PTP and IEEE 802.15.4 + were more precisely specified and all in-tree call sites updated accordingly. + Fields for timed TX and TX/RX timestamps have been consolidated. See + :c:type:`net_time_t`, :c:struct:`net_ptp_time`, :c:struct:`ieee802154_config`, + :c:struct:`ieee802154_radio_api` and :c:struct:`net_pkt` for extensive + documentation. As this is largely an internal API, existing applications will + most probably continue to work unchanged. + Removed APIs in this release ============================ diff --git a/doc/services/device_mgmt/smp_groups/smp_group_1.rst b/doc/services/device_mgmt/smp_groups/smp_group_1.rst index 61622ee71b2eb83..2389d9758ad4c66 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_1.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_1.rst @@ -269,7 +269,7 @@ CBOR data of request: (str,opt)"len" : (uint) (str)"off" : (uint) (str,opt)"sha" : (byte str) - (str,opt)"data" : (byte str) + (str)"data" : (byte str) (str,opt)"upgrade" : (bool) } @@ -278,41 +278,45 @@ where: .. table:: :align: center - +-----------------------+---------------------------------------------------+ - | "image" | optional image number, it does not have to appear | - | | in request at all, in which case it is assumed to | - | | be 0; only request with "off" 0 can contain | - | | image number | - +-----------------------+---------------------------------------------------+ - | "len" | optional length of an image, it only appears in | - | | the first packet of request, where "off" is 0 | - +-----------------------+---------------------------------------------------+ - | "off" | offset of image chunk the request carries | - +-----------------------+---------------------------------------------------+ - | "sha" | SHA256 hash of an upload; this is used to | - | | identify an upload session (e.g. to allow MCUmgr | - | | to continue a broken session), and for image | - | | verification purposes. This must be a full SHA256 | - | | hash of the whole image being uploaded, or not | - | | included if the hash is not available (in which | - | | case, upload session continuation and image | - | | verification functionality will be unavailable). | - | | Should only be present if "off" is zero. | - +-----------------------+---------------------------------------------------+ - | "data" | optional image data | - +-----------------------+---------------------------------------------------+ - | "upgrade" | optional flag that states that only upgrade | - | | should be allowed, so if the version of uploaded | - | | software is not higher then already on a device, | - | | the image upload will be rejected. | - | | Zephyr only compares major, minor and revision | - | | (x.y.z). | - +-----------------------+---------------------------------------------------+ + +-----------+--------------------------------------------------------------------------------+ + | "image" | optional image number, it does not have to appear in request at all, in which | + | | case it is assumed to be 0. Should only be present when "off" is 0. | + +-----------+--------------------------------------------------------------------------------+ + | "len" | optional length of an image. Must appear when "off" is 0. | + +-----------+--------------------------------------------------------------------------------+ + | "off" | offset of image chunk the request carries. | + +-----------+--------------------------------------------------------------------------------+ + | "sha" | SHA256 hash of an upload; this is used to identify an upload session (e.g. to | + | | allow MCUmgr to continue a broken session), and for image verification | + | | purposes. This must be a full SHA256 hash of the whole image being uploaded, | + | | or not included if the hash is not available (in which case, upload session | + | | continuation and image verification functionality will be unavailable). Should | + | | only be present when "off" is 0. | + +-----------+--------------------------------------------------------------------------------+ + | "data" | image data to write at provided offset. | + +-----------+--------------------------------------------------------------------------------+ + | "upgrade" | optional flag that states that only upgrade should be allowed, so if the | + | | version of uploaded software is not higher then already on a device, the image | + | | upload will be rejected. Zephyr compares major, minor and revision (x.y.z) by | + | | default unless | + | | :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER` is set, | + | | whereby it will compare build numbers too. Should only be present when "off" | + | | is 0. | + +-----------+--------------------------------------------------------------------------------+ .. note:: There is no field representing size of chunk that is carried as "data" because that information is embedded within "data" field itself. +.. note:: + It is possible that a server will respond to an upload with "off" of 0, this + may happen if an upload on another transport (or outside of MCUmgr entirely) + is started, if the device has rebooted or if a packet has been lost. If this + happens, a client must re-send all the required and optional fields that it + sent in the original first packet so that the upload state can be re-created + by the server. If the original fields are not included, the upload will be + unable to continue. + The MCUmgr library uses "sha" field to tag ongoing update session, to be able to continue it in case when it gets broken, and for upload verification purposes. diff --git a/doc/services/rtio/index.rst b/doc/services/rtio/index.rst index 11f5602b1157ce9..63761ce5f642546 100644 --- a/doc/services/rtio/index.rst +++ b/doc/services/rtio/index.rst @@ -122,6 +122,14 @@ does this work is up to the author of the iodev, perhaps the entire queue of operations can be converted to a set of DMA transfer descriptors, meaning the hardware does almost all of the real work. +Cancellation +************ + +Canceling an already queued operation is possible but not guaranteed. If the +SQE has not yet started, it's likely that a call to :c:func:`rtio_sqe_cancel` +will remove the SQE and never run it. If, however, the SQE already started +running, the cancel request will be ignored. + Memory pools ************ diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index daf2dff347e6029..f10326d4d1957cd 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -43,3 +43,4 @@ zephyr_library_sources_ifdef(CONFIG_ADC_INFINEON_CAT1 adc_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_GPADC adc_smartbond_gpadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_SDADC adc_smartbond_sdadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_TLA2021 adc_tla2021.c) +zephyr_library_sources_ifdef(CONFIG_ADC_NXP_S32_ADC_SAR adc_nxp_s32_adc_sar.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 48c57c71a359463..a915fa18fc0536c 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -110,4 +110,6 @@ source "drivers/adc/Kconfig.smartbond" source "drivers/adc/Kconfig.tla2021" +source "drivers/adc/Kconfig.nxp_s32" + endif # ADC diff --git a/drivers/adc/Kconfig.nxp_s32 b/drivers/adc/Kconfig.nxp_s32 new file mode 100644 index 000000000000000..e57d21a9a0fe802 --- /dev/null +++ b/drivers/adc/Kconfig.nxp_s32 @@ -0,0 +1,9 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config ADC_NXP_S32_ADC_SAR + bool "NXP S32 ADC SAR driver" + default y + depends on DT_HAS_NXP_S32_ADC_SAR_ENABLED + help + This option enables the NXP S32 ADC SAR driver. diff --git a/drivers/adc/adc_nxp_s32_adc_sar.c b/drivers/adc/adc_nxp_s32_adc_sar.c new file mode 100644 index 000000000000000..7cb5baf5b5cf7af --- /dev/null +++ b/drivers/adc/adc_nxp_s32_adc_sar.c @@ -0,0 +1,446 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +#define DT_DRV_COMPAT nxp_s32_adc_sar +LOG_MODULE_REGISTER(adc_nxp_s32_adc_sar, CONFIG_ADC_LOG_LEVEL); + +/* Convert channel of group ADC to channel of physical ADC instance */ +#define ADC_NXP_S32_GROUPCHAN_2_PHYCHAN(group, channel) \ + (ADC_SAR_IP_HW_REG_SIZE * group + channel) + +struct adc_nxp_s32_config { + ADC_Type *base; + uint8_t instance; + uint8_t group_channel; + uint8_t callback_select; + Adc_Sar_Ip_ConfigType *adc_cfg; + void (*irq_config_func)(const struct device *dev); + const struct pinctrl_dev_config *pin_cfg; +}; + +struct adc_nxp_s32_data { + const struct device *dev; + struct adc_context ctx; + uint16_t *buffer; + uint16_t *buf_end; + uint16_t *repeat_buffer; + uint32_t mask_channels; + uint8_t num_channels; +}; + +static int adc_nxp_s32_init(const struct device *dev) +{ + const struct adc_nxp_s32_config *config = dev->config; + struct adc_nxp_s32_data *data = dev->data; + Adc_Sar_Ip_StatusType status; + /* This array shows max number of channels of each group */ + uint8_t map_chan_group[ADC_SAR_IP_INSTANCE_COUNT][ADC_SAR_IP_NUM_GROUP_CHAN] + = FEATURE_ADC_MAX_CHN_COUNT; + + data->num_channels = map_chan_group[config->instance][config->group_channel]; + + if (config->pin_cfg) { + if (pinctrl_apply_state(config->pin_cfg, PINCTRL_STATE_DEFAULT)) { + return -EIO; + } + } + + status = Adc_Sar_Ip_Init(config->instance, config->adc_cfg); + if (status) { + return -EIO; + } + +#if FEATURE_ADC_HAS_CALIBRATION + status = Adc_Sar_Ip_DoCalibration(config->instance); + if (status) { + return -EIO; + } +#endif + + Adc_Sar_Ip_EnableNotifications(config->instance, + config->callback_select ? + ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN + : ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC); + + data->dev = dev; + config->irq_config_func(dev); + + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int adc_nxp_s32_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + struct adc_nxp_s32_data *data = dev->data; + + if (channel_cfg->channel_id >= data->num_channels) { + LOG_ERR("Channel %d is not valid", channel_cfg->channel_id); + return -EINVAL; + } + + if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { + LOG_ERR("Unsupported channel acquisition time"); + return -ENOTSUP; + } + + if (channel_cfg->differential) { + LOG_ERR("Differential channels are not supported"); + return -ENOTSUP; + } + + if (channel_cfg->gain != ADC_GAIN_1) { + LOG_ERR("Unsupported channel gain %d", channel_cfg->gain); + return -ENOTSUP; + } + + if (channel_cfg->reference != ADC_REF_INTERNAL) { + LOG_ERR("Unsupported channel reference"); + return -ENOTSUP; + } + + return 0; +} + +static int adc_nxp_s32_validate_buffer_size(const struct device *dev, + const struct adc_sequence *sequence) +{ + uint8_t active_channels = 0; + size_t needed_size; + + active_channels = POPCOUNT(sequence->channels); + + needed_size = active_channels * sizeof(uint16_t); + if (sequence->options) { + needed_size *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < needed_size) { + return -ENOSPC; + } + + return 0; +} + +#if FEATURE_ADC_HAS_AVERAGING +static int adc_nxp_s32_set_averaging(const struct device *dev, uint8_t oversampling) +{ + const struct adc_nxp_s32_config *config = dev->config; + Adc_Sar_Ip_AvgSelectType avg_sel = ADC_SAR_IP_AVG_4_CONV; + bool avg_en = true; + + switch (oversampling) { + case 0: + avg_en = false; + break; + case 2: + avg_sel = ADC_SAR_IP_AVG_4_CONV; + break; + case 3: + avg_sel = ADC_SAR_IP_AVG_8_CONV; + break; + case 4: + avg_sel = ADC_SAR_IP_AVG_16_CONV; + break; + case 5: + avg_sel = ADC_SAR_IP_AVG_32_CONV; + break; + default: + LOG_ERR("Unsupported oversampling value"); + return -ENOTSUP; + } + Adc_Sar_Ip_SetAveraging(config->instance, avg_en, avg_sel); + + return 0; +} +#endif + +#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON) +static int adc_nxp_s32_set_resolution(const struct device *dev, uint8_t adc_resol) +{ + const struct adc_nxp_s32_config *config = dev->config; + Adc_Sar_Ip_Resolution resolution; + + switch (adc_resol) { + case 8: + resolution = ADC_SAR_IP_RESOLUTION_8; + break; + case 10: + resolution = ADC_SAR_IP_RESOLUTION_10; + break; + case 12: + resolution = ADC_SAR_IP_RESOLUTION_12; + break; + case 14: + resolution = ADC_SAR_IP_RESOLUTION_14; + break; + default: + LOG_ERR("Unsupported resolution"); + return -ENOTSUP; + } + Adc_Sar_Ip_SetResolution(config->instance, resolution); + + return 0; +} +#endif + +static int adc_nxp_s32_start_read_async(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct adc_nxp_s32_config *config = dev->config; + struct adc_nxp_s32_data *data = dev->data; + int error; + uint32_t mask; + uint8_t channel; + + if (find_msb_set(sequence->channels) > data->num_channels) { + LOG_ERR("Channels out of bit map"); + return -EINVAL; + } + + error = adc_nxp_s32_validate_buffer_size(dev, sequence); + if (error) { + LOG_ERR("Buffer size isn't enough"); + return -EINVAL; + } + +#if FEATURE_ADC_HAS_AVERAGING + error = adc_nxp_s32_set_averaging(dev, sequence->oversampling); + if (error) { + return -ENOTSUP; + } +#else + if (sequence->oversampling) { + LOG_ERR("Oversampling can't be changed"); + return -ENOTSUP; + } +#endif + +#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON) + error = adc_nxp_s32_set_resolution(dev, sequence->resolution); + if (error) { + return -ENOTSUP; + } +#else + if (sequence->resolution != ADC_SAR_IP_MAX_RESOLUTION) { + LOG_ERR("Resolution can't be changed"); + return -ENOTSUP; + } +#endif + + if (sequence->calibrate) { +#if FEATURE_ADC_HAS_CALIBRATION + error = Adc_Sar_Ip_DoCalibration(config->instance); + if (error) { + LOG_ERR("Error during calibration"); + return -EIO; + } +#else + LOG_ERR("Unsupported calibration"); + return -ENOTSUP; +#endif + } + + for (int i = 0; i < data->num_channels; i++) { + mask = (sequence->channels >> i) & 0x1; + channel = ADC_NXP_S32_GROUPCHAN_2_PHYCHAN(config->group_channel, i); + if (mask) { + Adc_Sar_Ip_EnableChannelNotifications(config->instance, + channel, ADC_SAR_IP_CHAN_NOTIF_EOC); + Adc_Sar_Ip_EnableChannel(config->instance, + ADC_SAR_IP_CONV_CHAIN_NORMAL, channel); + } else { + Adc_Sar_Ip_DisableChannelNotifications(config->instance, + channel, ADC_SAR_IP_CHAN_NOTIF_EOC); + Adc_Sar_Ip_DisableChannel(config->instance, + ADC_SAR_IP_CONV_CHAIN_NORMAL, channel); + } + } + + /* Save ADC sequence sampling buffer and its end pointer address */ + data->buffer = sequence->buffer; + if (config->callback_select) { + data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t); + } + + adc_context_start_read(&data->ctx, sequence); + error = adc_context_wait_for_completion(&data->ctx); + + return error; +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct adc_nxp_s32_data *data = CONTAINER_OF(ctx, struct adc_nxp_s32_data, ctx); + const struct adc_nxp_s32_config *config = data->dev->config; + + data->mask_channels = ctx->sequence.channels; + data->repeat_buffer = data->buffer; + + Adc_Sar_Ip_StartConversion(config->instance, ADC_SAR_IP_CONV_CHAIN_NORMAL); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, + bool repeat_sampling) +{ + struct adc_nxp_s32_data *const data = + CONTAINER_OF(ctx, struct adc_nxp_s32_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +static int adc_nxp_s32_read_async(const struct device *dev, + const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_nxp_s32_data *data = dev->data; + int error = 0; + + adc_context_lock(&data->ctx, async ? true : false, async); + error = adc_nxp_s32_start_read_async(dev, sequence); + adc_context_release(&data->ctx, error); + + return error; +} + +static int adc_nxp_s32_read(const struct device *dev, + const struct adc_sequence *sequence) +{ + return adc_nxp_s32_read_async(dev, sequence, NULL); +} + +static void adc_nxp_s32_isr(const struct device *dev) +{ + const struct adc_nxp_s32_config *config = dev->config; + + Adc_Sar_Ip_IRQHandler(config->instance); +} + +#define ADC_NXP_S32_DRIVER_API(n) \ + static const struct adc_driver_api adc_nxp_s32_driver_api_##n = { \ + .channel_setup = adc_nxp_s32_channel_setup, \ + .read = adc_nxp_s32_read, \ + IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_nxp_s32_read_async,))\ + .ref_internal = DT_INST_PROP(n, vref_mv), \ + }; + +#define ADC_NXP_S32_IRQ_CONFIG(n) \ + static void adc_nxp_s32_adc_sar_config_func_##n(const struct device *dev)\ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + adc_nxp_s32_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + }; + +#define ADC_NXP_S32_CALLBACK_DEFINE(n) \ + void adc_nxp_s32_normal_end_conversion_callback##n(const uint16 PhysicalChanId)\ + { \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ + const struct adc_nxp_s32_config *config = dev->config; \ + struct adc_nxp_s32_data *data = dev->data; \ + uint16_t result = 0; \ + \ + result = Adc_Sar_Ip_GetConvData(n, PhysicalChanId); \ + LOG_DBG("End conversion, channel %d, group %d, result = %d", \ + ADC_SAR_IP_CHAN_2_BIT(PhysicalChanId), \ + config->group_channel, result); \ + \ + *data->buffer++ = result; \ + data->mask_channels &= \ + ~BIT(ADC_SAR_IP_CHAN_2_BIT(PhysicalChanId)); \ + \ + if (!data->mask_channels) { \ + adc_context_on_sampling_done(&data->ctx, \ + (struct device *)dev); \ + } \ + }; \ + void adc_nxp_s32_normal_endchain_callback##n(void) \ + { \ + const struct device *dev = DEVICE_DT_INST_GET(n); \ + const struct adc_nxp_s32_config *config = dev->config; \ + struct adc_nxp_s32_data *data = dev->data; \ + uint16_t result = 0; \ + uint8_t channel; \ + \ + while (data->mask_channels) { \ + channel = ADC_NXP_S32_GROUPCHAN_2_PHYCHAN( \ + config->group_channel, \ + (find_lsb_set(data->mask_channels)-1)); \ + result = Adc_Sar_Ip_GetConvData(n, channel); \ + LOG_DBG("End chain, channel %d, group %d, result = %d", \ + ADC_SAR_IP_CHAN_2_BIT(channel), \ + config->group_channel, result); \ + if (data->buffer < data->buf_end) { \ + *data->buffer++ = result; \ + } \ + data->mask_channels &= \ + ~BIT(ADC_SAR_IP_CHAN_2_BIT(channel)); \ + } \ + \ + adc_context_on_sampling_done(&data->ctx, (struct device *)dev); \ + }; + +#define ADC_NXP_S32_INSTANCE_CHECK(indx, n) \ + ((DT_INST_REG_ADDR(n) == IP_ADC_##indx##_BASE) ? indx : 0) +#define ADC_NXP_S32_GET_INSTANCE(n) \ + LISTIFY(__DEBRACKET ADC_INSTANCE_COUNT, ADC_NXP_S32_INSTANCE_CHECK, (|), n) + +#define ADC_NXP_S32_INIT_DEVICE(n) \ + ADC_NXP_S32_DRIVER_API(n) \ + ADC_NXP_S32_CALLBACK_DEFINE(n) \ + ADC_NXP_S32_IRQ_CONFIG(n) \ + COND_CODE_1(DT_INST_NUM_PINCTRL_STATES(n), \ + (PINCTRL_DT_INST_DEFINE(n);), (EMPTY)) \ + static const Adc_Sar_Ip_ConfigType adc_nxp_s32_default_config##n = \ + { \ + .ConvMode = ADC_SAR_IP_CONV_MODE_ONESHOT, \ + .AdcResolution = ADC_SAR_IP_RESOLUTION_14, \ + .HighSpeedConvEn = DT_INST_PROP(n, high_speed), \ + .EndOfNormalChainNotification = \ + adc_nxp_s32_normal_endchain_callback##n, \ + .EndOfConvNotification = \ + adc_nxp_s32_normal_end_conversion_callback##n, \ + }; \ + static struct adc_nxp_s32_data adc_nxp_s32_data_##n = { \ + ADC_CONTEXT_INIT_TIMER(adc_nxp_s32_data_##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(adc_nxp_s32_data_##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_nxp_s32_data_##n, ctx), \ + }; \ + static const struct adc_nxp_s32_config adc_nxp_s32_config_##n = { \ + .base = (ADC_Type *)DT_INST_REG_ADDR(n), \ + .instance = ADC_NXP_S32_GET_INSTANCE(n), \ + .group_channel = DT_INST_ENUM_IDX(n, group_channel), \ + .callback_select = DT_INST_ENUM_IDX(n, callback_select), \ + .adc_cfg = (Adc_Sar_Ip_ConfigType *)&adc_nxp_s32_default_config##n,\ + .irq_config_func = adc_nxp_s32_adc_sar_config_func_##n, \ + .pin_cfg = COND_CODE_1(DT_INST_NUM_PINCTRL_STATES(n), \ + (PINCTRL_DT_INST_DEV_CONFIG_GET(n)), (NULL)), \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + &adc_nxp_s32_init, \ + NULL, \ + &adc_nxp_s32_data_##n, \ + &adc_nxp_s32_config_##n, \ + POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, \ + &adc_nxp_s32_driver_api_##n); + +DT_INST_FOREACH_STATUS_OKAY(ADC_NXP_S32_INIT_DEVICE) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index d7ac4f59115c790..8a50caa92f05f36 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -60,6 +60,7 @@ config BT_SILABS_HCI bool "Silicon Labs Bluetooth interface" depends on SOC_SERIES_EFR32BG22 || SOC_SERIES_EFR32MG24 || SOC_SERIES_EFR32BG27 depends on !PM || SOC_GECKO_PM_BACKEND_PMGR + select SOC_GECKO_USE_RAIL select ENTROPY_GENERATOR select MBEDTLS select MBEDTLS_PSA_CRYPTO_C diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index f97671bf613d508..6ccaad15e4535f0 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -21,12 +21,21 @@ config CAN_MCUX_FLEXCAN_FD help Enable support for CAN-FD capable NXP FlexCAN devices. +config CAN_MAX_MB + int "Maximum number of message buffers for concurrent active instances" + default 16 + depends on SOC_SERIES_S32K3_M7 + range 1 96 + help + Defines maximum number of message buffers for concurrent active instances. + config CAN_MAX_FILTER int "Maximum number of concurrent active RX filters" default 5 range 1 15 if SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_KINETIS_K6X range 1 13 if SOC_SERIES_IMX_RT && CAN_MCUX_FLEXCAN_FD range 1 63 if SOC_SERIES_IMX_RT + range 1 96 if SOC_SERIES_S32K3_M7 help Defines maximum number of concurrent active RX filters diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 974fda4ca09fe87..fd754a184a59c04 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -49,14 +49,19 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL); #define RX_START_IDX 0 #endif +/* The maximum number of message buffers for concurrent active instances */ +#ifdef CONFIG_CAN_MAX_MB +#define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MAX_MB +#else +#define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0) +#endif + /* * RX message buffers (filters) will take up the first N message * buffers. The rest are available for TX use. */ #define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX) -#define MCUX_FLEXCAN_MAX_TX \ - (FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0) \ - - MCUX_FLEXCAN_MAX_RX) +#define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX) /* * Convert from RX message buffer index to allocated filter ID and @@ -1246,7 +1251,7 @@ static int mcux_flexcan_init(const struct device *dev) data->dev = dev; FLEXCAN_GetDefaultConfig(&flexcan_config); - flexcan_config.maxMbNum = FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0); + flexcan_config.maxMbNum = MCUX_FLEXCAN_MAX_MB; flexcan_config.clkSrc = config->clk_source; flexcan_config.baudRate = clock_freq / (1U + data->timing.prop_seg + data->timing.phase_seg1 + diff --git a/drivers/can/can_stm32h7.c b/drivers/can/can_stm32h7.c index 7ff6fcd1eb9c746..ecffd4ce1cba8c2 100644 --- a/drivers/can/can_stm32h7.c +++ b/drivers/can/can_stm32h7.c @@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(can_stm32h7, CONFIG_CAN_LOG_LEVEL); struct can_stm32h7_config { mm_reg_t base; + mem_addr_t mrba; mem_addr_t mram; void (*config_irq)(void); const struct pinctrl_dev_config *pcfg; @@ -132,7 +133,7 @@ static int can_stm32h7_init(const struct device *dev) return ret; } - ret = can_mcan_configure_mram(dev, stm32h7_cfg->mram, stm32h7_cfg->mram); + ret = can_mcan_configure_mram(dev, stm32h7_cfg->mrba, stm32h7_cfg->mram); if (ret != 0) { return ret; } @@ -205,6 +206,7 @@ static const struct can_mcan_ops can_stm32h7_ops = { \ static const struct can_stm32h7_config can_stm32h7_cfg_##n = { \ .base = CAN_MCAN_DT_INST_MCAN_ADDR(n), \ + .mrba = CAN_MCAN_DT_INST_MRBA(n), \ .mram = CAN_MCAN_DT_INST_MRAM_ADDR(n), \ .config_irq = stm32h7_mcan_irq_config_##n, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 30e31ed2b116dc8..20bd8659afffb56 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_library_sources_ifdef(CONFIG_ST7735R display_st7735r.c) zephyr_library_sources_ifdef(CONFIG_STM32_LTDC display_stm32_ltdc.c) zephyr_library_sources_ifdef(CONFIG_RM68200 display_rm68200.c) zephyr_library_sources_ifdef(CONFIG_RM67162 display_rm67162.c) +zephyr_library_sources_ifdef(CONFIG_HX8394 display_hx8394.c) zephyr_library_sources_ifdef(CONFIG_MICROBIT_DISPLAY mb_display.c diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index 6654f14d87e750e..f6a39f0f98473ca 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -39,5 +39,6 @@ source "drivers/display/Kconfig.max7219" source "drivers/display/Kconfig.intel_multibootfb" source "drivers/display/Kconfig.mcux_dcnano_lcdif" source "drivers/display/Kconfig.otm8009a" +source "drivers/display/Kconfig.hx8394" endif # DISPLAY diff --git a/drivers/display/Kconfig.hx8394 b/drivers/display/Kconfig.hx8394 new file mode 100644 index 000000000000000..0c36e125e1c62b7 --- /dev/null +++ b/drivers/display/Kconfig.hx8394 @@ -0,0 +1,10 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +config HX8394 + bool "HX8394 display driver" + default y + depends on MIPI_DSI + depends on DT_HAS_HIMAX_HX8394_ENABLED + help + Enable driver for HX8394 display driver. diff --git a/drivers/display/display_hx8394.c b/drivers/display/display_hx8394.c new file mode 100644 index 000000000000000..9a71197b481c70e --- /dev/null +++ b/drivers/display/display_hx8394.c @@ -0,0 +1,801 @@ +/* + * Copyright 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT himax_hx8394 + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(hx8394, CONFIG_DISPLAY_LOG_LEVEL); + +struct hx8394_config { + const struct device *mipi_dsi; + const struct gpio_dt_spec reset_gpio; + const struct gpio_dt_spec bl_gpio; + uint8_t num_of_lanes; + uint8_t pixel_format; + uint16_t panel_width; + uint16_t panel_height; + uint8_t channel; +}; + +/* MIPI DCS commands specific to this display driver */ +#define HX8394_SETMIPI 0xBA +#define HX8394_MIPI_LPTX_BTA_READ BIT(6) +#define HX8394_MIPI_LP_CD_DIS BIT(5) +#define HX8394_MIPI_TA_6TL 0x3 +#define HX8394_MIPI_DPHYCMD_LPRX_8NS 0x40 +#define HX8394_MIPI_DPHYCMD_LPRX_66mV 0x10 +#define HX8394_MIPI_DPHYCMD_LPTX_SRLIM 0x8 +#define HX8394_MIPI_DPHYCMD_LDO_1_55V 0x60 +#define HX8394_MIPI_DPHYCMD_HSRX_7X 0x8 +#define HX8394_MIPI_DPHYCMD_HSRX_100OHM 0x2 +#define HX8394_MIPI_DPHYCMD_LPCD_1X 0x1 + +#define HX8394_SET_ADDRESS 0x36 +#define HX8394_FLIP_HORIZONTAL BIT(1) +#define HX8394_FLIP_VERTICAL BIT(0) + +#define HX8394_SETPOWER 0xB1 +#define HX8394_POWER_AP_1_0UA 0x8 +#define HX8394_POWER_HX5186 0x40 +#define HX8394_POWER_VRHP_4_8V 0x12 +#define HX8394_POWER_VRHN_4_8V 0x12 +#define HX8394_POWER_VPPS_8_25V 0x60 +#define HX8394_POWER_XDK_X2 0x1 +#define HX8394_POWER_VSP_FBOFF 0x8 +#define HX8394_POWER_FS0_DIV_8 0x2 +#define HX8394_POWER_CLK_OPT_VGH_HSYNC_RST 0x10 +#define HX8394_POWER_CLK_OPT_VGL_HSYNC_RST 0x20 +#define HX8394_POWER_FS2_DIV_192 0x4 +#define HX8394_POWER_FS1_DIV_224 0x50 +#define HX8394_POWER_BTP_5_55V 0x11 +#define HX8394_POWER_VGH_RATIO_2VSPVSN 0x60 +#define HX8394_POWER_BTN_5_55V 0x11 +#define HX8394_POWER_VGL_RATIO_2VSPVSN 0x60 +#define HX8394_POWER_VGHS_16V 0x57 +#define HX8394_POWER_VGLS_12_4V 0x47 + +#define HX8394_SETDISP 0xB2 +#define HX8394_DISP_COL_INV 0x0 +#define HX8394_DISP_MESSI_ENB 0x80 +#define HX8394_DISP_NL_1280 0x64 +#define HX8394_DISP_BP_14 0xC +#define HX8394_DISP_FP_15 0xD +#define HX8394_DISP_RTN_144 0x2F + +#define HX8394_SETCYC 0xB4 + +#define HX8394_SETGIP0 0xD3 +#define HX8394_GIP0_EQ_OPT_BOTH 0x0 +#define HX8394_GIP0_EQ_HSYNC_NORMAL 0x0 +#define HX8394_GIP0_EQ_VSEL_VSSA 0x0 +#define HX8394_SHP_START_4 0x40 +#define HX8394_SCP_WIDTH_7X_HSYNC 0x7 +#define HX8394_CHR0_12X_HSYNC 0xA +#define HX8394_CHR1_18X_HSYNC 0x10 + +#define HX8394_SETGIP1 0xD5 + +#define HX8394_SETGIP2 0xD6 + +#define HX8394_SETVCOM 0xB6 +#define HX8394_VCMC_F_1_76V 0x92 +#define HX8394_VCMC_B_1_76V 0x92 + +#define HX8394_SETGAMMA 0xE0 + +#define HX8394_SETPANEL 0xCC +#define HX8394_COLOR_BGR BIT(0) +#define HX8394_REV_PANEL BIT(1) + +#define HX8394_SETBANK 0xBD + +#define HX8394_SET_TEAR 0x35 +#define HX8394_TEAR_VBLANK 0x0 + +#define HX8394_SETEXTC 0xB9 +#define HX8394_EXTC1_MAGIC 0xFF +#define HX8394_EXTC2_MAGIC 0x83 +#define HX8394_EXTC3_MAGIC 0x94 + + +const uint8_t enable_extension[] = { + HX8394_SETEXTC, + HX8394_EXTC1_MAGIC, + HX8394_EXTC2_MAGIC, + HX8394_EXTC3_MAGIC, +}; + +const uint8_t address_config[] = { + HX8394_SET_ADDRESS, + HX8394_FLIP_HORIZONTAL +}; + +const uint8_t power_config[] = { + HX8394_SETPOWER, + (HX8394_POWER_HX5186 | HX8394_POWER_AP_1_0UA), + HX8394_POWER_VRHP_4_8V, + (HX8394_POWER_VPPS_8_25V | HX8394_POWER_VRHN_4_8V), + (HX8394_POWER_VSP_FBOFF | HX8394_POWER_XDK_X2), + (HX8394_POWER_CLK_OPT_VGL_HSYNC_RST | + HX8394_POWER_CLK_OPT_VGH_HSYNC_RST | + HX8394_POWER_FS0_DIV_8), + (HX8394_POWER_FS1_DIV_224 | HX8394_POWER_FS2_DIV_192), + (HX8394_POWER_VGH_RATIO_2VSPVSN | HX8394_POWER_BTP_5_55V), + (HX8394_POWER_VGL_RATIO_2VSPVSN | HX8394_POWER_BTN_5_55V), + HX8394_POWER_VGHS_16V, + HX8394_POWER_VGLS_12_4V +}; + +const uint8_t line_config[] = { + HX8394_SETDISP, + HX8394_DISP_COL_INV, + HX8394_DISP_MESSI_ENB, + HX8394_DISP_NL_1280, + HX8394_DISP_BP_14, + HX8394_DISP_FP_15, + HX8394_DISP_RTN_144 +}; + +const uint8_t cycle_config[] = { + HX8394_SETCYC, + 0x73, /* SPON delay */ + 0x74, /* SPOFF delay */ + 0x73, /* CON delay */ + 0x74, /* COFF delay */ + 0x73, /* CON1 delay */ + 0x74, /* COFF1 delay */ + 0x1, /* EQON time */ + 0xC, /* SON time */ + 0x86, /* SOFF time */ + 0x75, /* SAP1_P, SAP2 (1st and second stage op amp bias) */ + 0x00, /* DX2 off, EQ off, EQ_MI off */ + 0x3F, /* DX2 off period setting */ + 0x73, /* SPON_MPU delay */ + 0x74, /* SPOFF_MPU delay */ + 0x73, /* CON_MPU delay */ + 0x74, /* COFF_MPU delay */ + 0x73, /* CON1_MPU delay */ + 0x74, /* COFF1_MPU delay */ + 0x1, /* EQON_MPU time */ + 0xC, /* SON_MPU time */ + 0x86 /* SOFF_MPU time */ +}; + +const uint8_t gip0_config[] = { + HX8394_SETGIP0, + (HX8394_GIP0_EQ_OPT_BOTH | HX8394_GIP0_EQ_HSYNC_NORMAL), + HX8394_GIP0_EQ_VSEL_VSSA, + 0x7, /* EQ_DELAY_ON1 (in cycles of TCON CLK */ + 0x7, /* EQ_DELAY_OFF1 (in cycles of TCON CLK */ + 0x40, /* GPWR signal frequency (64x per frame) */ + 0x7, /* GPWR signal non overlap timing (in cycles of TCON */ + 0xC, /* GIP dummy clock for first CKV */ + 0x00, /* GIP dummy clock for second CKV */ + /* Group delays. Sets start/end signal delay from VYSNC + * falling edge in multiples of HSYNC + */ + 0x8, /* SHR0_2 = 8, SHR0_3 = 0 */ + 0x10, /* SHR0_1 = 1, SHR0[11:8] = 0x0 */ + 0x8, /* SHR0 = 0x8 */ + 0x0, /* SHR0_GS[11:8]. Unset. */ + 0x8, /* SHR0_GS = 0x8 */ + 0x54, /* SHR1_3 = 0x5, SHR1_2 = 0x4 */ + 0x15, /* SHR1_1 = 0x1, SHR1[11:8] = 0x5 */ + 0xA, /* SHR1[7:0] = 0xA (SHR1 = 0x50A) */ + 0x5, /* SHR1_GS[11:8] = 0x5 */ + 0xA, /* SHR1_GS[7:0] = 0xA (SHR1_GS = 0x50A) */ + 0x2, /* SHR2_3 = 0x0, SHR2_2 = 0x2 */ + 0x15, /* SHR2_1 = 0x1, SHR2[11:8] = 0x5 */ + 0x6, /* SHR2[7:0] = 0x6 (SHR2 = 0x506) */ + 0x5, /* SHR2_GS[11:8] = 0x5 */ + 0x6, /* SHR2_GS[7:0 = 0x6 (SHR2_GS = 0x506) */ + (HX8394_SHP_START_4 | HX8394_SCP_WIDTH_7X_HSYNC), + 0x44, /* SHP2 = 0x4, SHP1 = 0x4 */ + HX8394_CHR0_12X_HSYNC, + HX8394_CHR0_12X_HSYNC, + 0x4B, /* CHP0 = 4x hsync, CCP0 = 0xB */ + HX8394_CHR1_18X_HSYNC, + 0x7, /* CHR1_GS = 9x hsync */ + 0x7, /* CHP1 = 1x hsync, CCP1 = 0x7 */ + /* These parameters are not documented in datasheet */ + 0xC, + 0x40 +}; + +const uint8_t gip1_config[] = { + HX8394_SETGIP1, + /* Select output clock sources + * See COSn_L/COSn_R values in datasheet + */ + 0x1C, /* COS1_L */ + 0x1C, /* COS1_R */ + 0x1D, /* COS2_L */ + 0x1D, /* COS2_R */ + 0x00, /* COS3_L */ + 0x01, /* COS3_R */ + 0x02, /* COS4_L */ + 0x03, /* COS4_R */ + 0x04, /* COS5_L */ + 0x05, /* COS5_R */ + 0x06, /* COS6_L */ + 0x07, /* COS6_R */ + 0x08, /* COS7_L */ + 0x09, /* COS7_R */ + 0x0A, /* COS8_L */ + 0x0B, /* COS8_R */ + 0x24, /* COS9_L */ + 0x25, /* COS9_R */ + 0x18, /* COS10_L */ + 0x18, /* COS10_R */ + 0x26, /* COS11_L */ + 0x27, /* COS11_R */ + 0x18, /* COS12_L */ + 0x18, /* COS12_R */ + 0x18, /* COS13_L */ + 0x18, /* COS13_R */ + 0x18, /* COS14_L */ + 0x18, /* COS14_R */ + 0x18, /* COS15_L */ + 0x18, /* COS15_R */ + 0x18, /* COS16_L */ + 0x18, /* COS16_R */ + 0x18, /* COS17_L */ + 0x18, /* COS17_R */ + 0x18, /* COS18_L */ + 0x18, /* COS18_R */ + 0x18, /* COS19_L */ + 0x18, /* COS19_R */ + 0x20, /* COS20_L */ + 0x21, /* COS20_R */ + 0x18, /* COS21_L */ + 0x18, /* COS21_R */ + 0x18, /* COS22_L */ + 0x18 /* COS22_R */ +}; + +const uint8_t gip2_config[] = { + HX8394_SETGIP2, + /* Select output clock sources for GS mode. + * See COSn_L_GS/COSn_R_GS values in datasheet + */ + 0x1C, /* COS1_L_GS */ + 0x1C, /* COS1_R_GS */ + 0x1D, /* COS2_L_GS */ + 0x1D, /* COS2_R_GS */ + 0x07, /* COS3_L_GS */ + 0x06, /* COS3_R_GS */ + 0x05, /* COS4_L_GS */ + 0x04, /* COS4_R_GS */ + 0x03, /* COS5_L_GS */ + 0x02, /* COS5_R_GS */ + 0x01, /* COS6_L_GS */ + 0x00, /* COS6_R_GS */ + 0x0B, /* COS7_L_GS */ + 0x0A, /* COS7_R_GS */ + 0x09, /* COS8_L_GS */ + 0x08, /* COS8_R_GS */ + 0x21, /* COS9_L_GS */ + 0x20, /* COS9_R_GS */ + 0x18, /* COS10_L_GS */ + 0x18, /* COS10_R_GS */ + 0x27, /* COS11_L_GS */ + 0x26, /* COS11_R_GS */ + 0x18, /* COS12_L_GS */ + 0x18, /* COS12_R_GS */ + 0x18, /* COS13_L_GS */ + 0x18, /* COS13_R_GS */ + 0x18, /* COS14_L_GS */ + 0x18, /* COS14_R_GS */ + 0x18, /* COS15_L_GS */ + 0x18, /* COS15_R_GS */ + 0x18, /* COS16_L_GS */ + 0x18, /* COS16_R_GS */ + 0x18, /* COS17_L_GS */ + 0x18, /* COS17_R_GS */ + 0x18, /* COS18_L_GS */ + 0x18, /* COS18_R_GS */ + 0x18, /* COS19_L_GS */ + 0x18, /* COS19_R_GS */ + 0x25, /* COS20_L_GS */ + 0x24, /* COS20_R_GS */ + 0x18, /* COS21_L_GS */ + 0x18, /* COS21_R_GS */ + 0x18, /* COS22_L_GS */ + 0x18 /* COS22_R_GS */ +}; + +const uint8_t vcom_config[] = { + HX8394_SETVCOM, + HX8394_VCMC_F_1_76V, + HX8394_VCMC_B_1_76V +}; + +const uint8_t gamma_config[] = { + HX8394_SETGAMMA, + 0x00, /* VHP0 */ + 0x0A, /* VHP1 */ + 0x15, /* VHP2 */ + 0x1B, /* VHP3 */ + 0x1E, /* VHP4 */ + 0x21, /* VHP5 */ + 0x24, /* VHP6 */ + 0x22, /* VHP7 */ + 0x47, /* VMP0 */ + 0x56, /* VMP1 */ + 0x65, /* VMP2 */ + 0x66, /* VMP3 */ + 0x6E, /* VMP4 */ + 0x82, /* VMP5 */ + 0x88, /* VMP6 */ + 0x8B, /* VMP7 */ + 0x9A, /* VMP8 */ + 0x9D, /* VMP9 */ + 0x98, /* VMP10 */ + 0xA8, /* VMP11 */ + 0xB9, /* VMP12 */ + 0x5D, /* VLP0 */ + 0x5C, /* VLP1 */ + 0x61, /* VLP2 */ + 0x66, /* VLP3 */ + 0x6A, /* VLP4 */ + 0x6F, /* VLP5 */ + 0x7F, /* VLP6 */ + 0x7F, /* VLP7 */ + 0x00, /* VHN0 */ + 0x0A, /* VHN1 */ + 0x15, /* VHN2 */ + 0x1B, /* VHN3 */ + 0x1E, /* VHN4 */ + 0x21, /* VHN5 */ + 0x24, /* VHN6 */ + 0x22, /* VHN7 */ + 0x47, /* VMN0 */ + 0x56, /* VMN1 */ + 0x65, /* VMN2 */ + 0x65, /* VMN3 */ + 0x6E, /* VMN4 */ + 0x81, /* VMN5 */ + 0x87, /* VMN6 */ + 0x8B, /* VMN7 */ + 0x98, /* VMN8 */ + 0x9D, /* VMN9 */ + 0x99, /* VMN10 */ + 0xA8, /* VMN11 */ + 0xBA, /* VMN12 */ + 0x5D, /* VLN0 */ + 0x5D, /* VLN1 */ + 0x62, /* VLN2 */ + 0x67, /* VLN3 */ + 0x6B, /* VLN4 */ + 0x72, /* VLN5 */ + 0x7F, /* VLN6 */ + 0x7F /* VLN7 */ +}; + +const uint8_t hx8394_cmd1[] = {0xC0U, 0x1FU, 0x31U}; + +const uint8_t panel_config[] = { + HX8394_SETPANEL, + (HX8394_COLOR_BGR | HX8394_REV_PANEL) +}; + +const uint8_t hx8394_cmd2[] = {0xD4, 0x2}; + +const uint8_t hx8394_bank2[] = { + 0xD8U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, + 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, + 0xFFU +}; + +const uint8_t hx8394_bank1[] = {0xB1U, 0x00U}; + +const uint8_t hx8394_bank0[] = { + 0xBFU, 0x40U, 0x81U, 0x50U, + 0x00U, 0x1AU, 0xFCU, 0x01 +}; + +const uint8_t hx8394_cmd3[] = {0xC6U, 0xEDU}; + +const uint8_t tear_config[] = {HX8394_SET_TEAR, HX8394_TEAR_VBLANK | 0x3}; + +static int hx8394_write(const struct device *dev, const uint16_t x, + const uint16_t y, + const struct display_buffer_descriptor *desc, + const void *buf) +{ + LOG_WRN("Write not supported, use LCD controller display driver"); + return 0; +} + +static int hx8394_read(const struct device *dev, const uint16_t x, + const uint16_t y, + const struct display_buffer_descriptor *desc, + void *buf) +{ + LOG_WRN("Read not implemented"); + return -ENOTSUP; +} + +static void *hx8394_get_framebuffer(const struct device *dev) +{ + LOG_WRN("Direct framebuffer access not implemented"); + return NULL; +} + +static int hx8394_blanking_off(const struct device *dev) +{ + const struct hx8394_config *config = dev->config; + + if (config->bl_gpio.port != NULL) { + return gpio_pin_set_dt(&config->bl_gpio, 1); + } else { + return -ENOTSUP; + } +} + +static int hx8394_blanking_on(const struct device *dev) +{ + const struct hx8394_config *config = dev->config; + + if (config->bl_gpio.port != NULL) { + return gpio_pin_set_dt(&config->bl_gpio, 0); + } else { + return -ENOTSUP; + } +} + +static int hx8394_set_brightness(const struct device *dev, + const uint8_t brightness) +{ + LOG_WRN("Set brightness not implemented"); + return -ENOTSUP; +} + +static int hx8394_set_contrast(const struct device *dev, + const uint8_t contrast) +{ + LOG_WRN("Set contrast not implemented"); + return -ENOTSUP; +} + +static int hx8394_set_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + const struct hx8394_config *config = dev->config; + + if (pixel_format == config->pixel_format) { + return 0; + } + LOG_WRN("Pixel format change not implemented"); + return -ENOTSUP; +} + +static int hx8394_set_orientation(const struct device *dev, + const enum display_orientation orientation) +{ + const struct hx8394_config *config = dev->config; + uint8_t param[2] = {0}; + + /* Note- this simply flips the scan direction of the display + * driver. Can be useful if your application needs the display + * flipped on the X or Y axis + */ + param[0] = HX8394_SET_ADDRESS; + switch (orientation) { + case DISPLAY_ORIENTATION_NORMAL: + /* Default orientation for this display flips image on x axis */ + param[1] = HX8394_FLIP_HORIZONTAL; + break; + case DISPLAY_ORIENTATION_ROTATED_90: + param[1] = HX8394_FLIP_VERTICAL; + break; + case DISPLAY_ORIENTATION_ROTATED_180: + param[1] = 0; + break; + case DISPLAY_ORIENTATION_ROTATED_270: + param[1] = HX8394_FLIP_HORIZONTAL | HX8394_FLIP_VERTICAL; + break; + default: + return -ENOTSUP; + } + return mipi_dsi_generic_write(config->mipi_dsi, config->channel, param, 2); +} + +static void hx8394_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct hx8394_config *config = dev->config; + + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = config->panel_width; + capabilities->y_resolution = config->panel_height; + capabilities->supported_pixel_formats = config->pixel_format; + capabilities->current_pixel_format = config->pixel_format; + capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL; +} + +static const struct display_driver_api hx8394_api = { + .blanking_on = hx8394_blanking_on, + .blanking_off = hx8394_blanking_off, + .write = hx8394_write, + .read = hx8394_read, + .get_framebuffer = hx8394_get_framebuffer, + .set_brightness = hx8394_set_brightness, + .set_contrast = hx8394_set_contrast, + .get_capabilities = hx8394_get_capabilities, + .set_pixel_format = hx8394_set_pixel_format, + .set_orientation = hx8394_set_orientation, +}; + +static int hx8394_init(const struct device *dev) +{ + const struct hx8394_config *config = dev->config; + int ret; + struct mipi_dsi_device mdev; + uint8_t param[2]; + uint8_t setmipi[7] = { + HX8394_SETMIPI, + (HX8394_MIPI_LPTX_BTA_READ | HX8394_MIPI_LP_CD_DIS), + HX8394_MIPI_TA_6TL, + (HX8394_MIPI_DPHYCMD_LPRX_8NS | + HX8394_MIPI_DPHYCMD_LPRX_66mV | + HX8394_MIPI_DPHYCMD_LPTX_SRLIM), + (HX8394_MIPI_DPHYCMD_LDO_1_55V | + HX8394_MIPI_DPHYCMD_HSRX_7X | + HX8394_MIPI_DPHYCMD_HSRX_100OHM | + HX8394_MIPI_DPHYCMD_LPCD_1X), + /* The remaining parameters here are not documented */ + 0xB2U, 0xC0U}; + + mdev.data_lanes = config->num_of_lanes; + mdev.pixfmt = config->pixel_format; + /* HX8394 runs in video mode */ + mdev.mode_flags = MIPI_DSI_MODE_VIDEO; + + ret = mipi_dsi_attach(config->mipi_dsi, config->channel, &mdev); + if (ret < 0) { + LOG_ERR("Could not attach to MIPI-DSI host"); + return ret; + } + + if (gpio_is_ready_dt(&config->reset_gpio)) { + /* Regulator API will have supplied power to the display + * driver. Per datasheet, we must wait 1ms for the RESX + * pin to be valid. + */ + k_sleep(K_MSEC(1)); + /* Initialize reset GPIO */ + ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + /* Pull reset GPIO low */ + gpio_pin_set_dt(&config->reset_gpio, 0); + /* Datasheet says we must keep reset pin low at least 10us. + * hold it low for 1ms to be safe. + */ + k_sleep(K_MSEC(1)); + gpio_pin_set_dt(&config->reset_gpio, 1); + /* Per datasheet, we must delay at least 50ms before first + * host command + */ + k_sleep(K_MSEC(50)); + } + /* Enable extended commands */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + enable_extension, sizeof(enable_extension)); + if (ret < 0) { + return ret; + } + + /* Set the number of lanes to DSISETUP0 parameter */ + setmipi[1] |= (config->num_of_lanes - 1); + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + setmipi, sizeof(setmipi)); + if (ret < 0) { + return ret; + } + + /* Set scan direction */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + address_config, sizeof(address_config)); + if (ret < 0) { + return ret; + } + + /* Set voltage and current targets */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + power_config, sizeof(power_config)); + if (ret < 0) { + return ret; + } + + /* Setup display line count and front/back porch size */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + line_config, sizeof(line_config)); + if (ret < 0) { + return ret; + } + + /* Setup display cycle counts (in counts of TCON CLK) */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + cycle_config, sizeof(cycle_config)); + if (ret < 0) { + return ret; + } + + /* Set group delay values */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + gip0_config, sizeof(gip0_config)); + if (ret < 0) { + return ret; + } + + + /* Set group clock selections */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + gip1_config, sizeof(gip1_config)); + if (ret < 0) { + return ret; + } + + /* Set group clock selections for GS mode */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + gip2_config, sizeof(gip2_config)); + if (ret < 0) { + return ret; + } + + /* Delay for a moment before setting VCOM. It is not clear + * from the datasheet why this is required, but without this + * delay the panel stops responding to additional commands + */ + k_msleep(1); + /* Set VCOM voltage config */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + vcom_config, sizeof(vcom_config)); + if (ret < 0) { + return ret; + } + + /* Set manufacturer supplied gamma values */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + gamma_config, sizeof(gamma_config)); + if (ret < 0) { + return ret; + } + + /* This command is not documented in datasheet, but is included + * in the display initialization done by MCUXpresso SDK + */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_cmd1, sizeof(hx8394_cmd1)); + if (ret < 0) { + return ret; + } + + /* Set panel to BGR mode, and reverse colors */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + panel_config, sizeof(panel_config)); + if (ret < 0) { + return ret; + } + + /* This command is not documented in datasheet, but is included + * in the display initialization done by MCUXpresso SDK + */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_cmd2, sizeof(hx8394_cmd2)); + if (ret < 0) { + return ret; + } + + /* Write values to manufacturer register banks */ + param[0] = HX8394_SETBANK; + param[1] = 0x2; + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + param, 2); + if (ret < 0) { + return ret; + } + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_bank2, sizeof(hx8394_bank2)); + if (ret < 0) { + return ret; + } + param[1] = 0x0; + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + param, 2); + if (ret < 0) { + return ret; + } + /* Select bank 1 */ + param[1] = 0x1; + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + param, 2); + if (ret < 0) { + return ret; + } + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_bank1, sizeof(hx8394_bank1)); + if (ret < 0) { + return ret; + } + /* Select bank 0 */ + param[1] = 0x0; + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + param, 2); + if (ret < 0) { + return ret; + } + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_bank0, sizeof(hx8394_bank0)); + if (ret < 0) { + return ret; + } + + /* This command is not documented in datasheet, but is included + * in the display initialization done by MCUXpresso SDK + */ + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + hx8394_cmd3, sizeof(hx8394_cmd3)); + if (ret < 0) { + return ret; + } + + ret = mipi_dsi_generic_write(config->mipi_dsi, config->channel, + tear_config, sizeof(tear_config)); + if (ret < 0) { + return ret; + } + + ret = mipi_dsi_dcs_write(config->mipi_dsi, config->channel, + MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (ret < 0) { + return ret; + } + /* We must delay 120ms after exiting sleep mode per datasheet */ + k_sleep(K_MSEC(120)); + ret = mipi_dsi_dcs_write(config->mipi_dsi, config->channel, + MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + + if (config->bl_gpio.port != NULL) { + ret = gpio_pin_configure_dt(&config->bl_gpio, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure bl GPIO (%d)", ret); + return ret; + } + } + + return ret; +} + +#define HX8394_PANEL(id) \ + static const struct hx8394_config hx8394_config_##id = { \ + .mipi_dsi = DEVICE_DT_GET(DT_INST_BUS(id)), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(id, reset_gpios, {0}), \ + .bl_gpio = GPIO_DT_SPEC_INST_GET_OR(id, bl_gpios, {0}), \ + .num_of_lanes = DT_INST_PROP_BY_IDX(id, data_lanes, 0), \ + .pixel_format = DT_INST_PROP(id, pixel_format), \ + .panel_width = DT_INST_PROP(id, width), \ + .panel_height = DT_INST_PROP(id, height), \ + .channel = DT_INST_REG_ADDR(id), \ + }; \ + DEVICE_DT_INST_DEFINE(id, \ + &hx8394_init, \ + NULL, \ + NULL, \ + &hx8394_config_##id, \ + POST_KERNEL, \ + CONFIG_APPLICATION_INIT_PRIORITY, \ + &hx8394_api); + +DT_INST_FOREACH_STATUS_OKAY(HX8394_PANEL) diff --git a/drivers/ethernet/eth_nxp_s32_netc_psi.c b/drivers/ethernet/eth_nxp_s32_netc_psi.c index bd00d13fdcf9d53..375767de97df1de 100644 --- a/drivers/ethernet/eth_nxp_s32_netc_psi.c +++ b/drivers/ethernet/eth_nxp_s32_netc_psi.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(nxp_s32_eth_psi); #include "eth_nxp_s32_netc_priv.h" #define PSI_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_s32_netc_psi) -#define PHY_NODE DT_PHANDLE(PSI_NODE, phy_dev) +#define PHY_NODE DT_PHANDLE(PSI_NODE, phy_handle) #define INIT_VSIS DT_NODE_HAS_PROP(PSI_NODE, vsis) #define TX_RING_IDX 1 #define RX_RING_IDX 0 diff --git a/drivers/ethernet/eth_smsc91x.c b/drivers/ethernet/eth_smsc91x.c index b36cd5fe969c647..013a36f2f4238c6 100644 --- a/drivers/ethernet/eth_smsc91x.c +++ b/drivers/ethernet/eth_smsc91x.c @@ -252,6 +252,8 @@ static void smsc_miibus_writereg(struct smsc_data *sc, int phy, int reg, uint16_ irq_disable(sc->irq); SMSC_LOCK(sc); + smsc_select_bank(sc, 3); + smsc_miibus_sync(sc); smsc_miibus_sendbits(sc, MII_COMMAND_START, 2); diff --git a/drivers/ethernet/eth_stm32_hal.c b/drivers/ethernet/eth_stm32_hal.c index 4d8ea3479f2f0e5..bdb4771d01f3773 100644 --- a/drivers/ethernet/eth_stm32_hal.c +++ b/drivers/ethernet/eth_stm32_hal.c @@ -1098,9 +1098,6 @@ void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth_handle) static void generate_mac(uint8_t *mac_addr) { - uint8_t unique_device_ID_12_bytes[12]; - uint32_t result_mac_32_bits; - #if defined(ETH_STM32_RANDOM_MAC) /* Either CONFIG_ETH_STM32_HAL_RANDOM_MAC or device tree property */ /* "zephyr,random-mac-address" is set, generate a random mac address */ @@ -1118,6 +1115,9 @@ static void generate_mac(uint8_t *mac_addr) mac_addr[4] = CONFIG_ETH_STM32_HAL_MAC4; mac_addr[5] = CONFIG_ETH_STM32_HAL_MAC5; #else + uint8_t unique_device_ID_12_bytes[12]; + uint32_t result_mac_32_bits; + /* Nothing defined by the user, use device id */ hwinfo_get_device_id(unique_device_ID_12_bytes, 12); result_mac_32_bits = crc32_ieee((uint8_t *)unique_device_ID_12_bytes, 12); diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index f6daea97fe302cb..cba4a76a9690562 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -45,6 +45,15 @@ static const struct flash_parameters flash_stm32_parameters = { static int flash_stm32_write_protection(const struct device *dev, bool enable); +bool __weak flash_stm32_valid_range(const struct device *dev, off_t offset, + uint32_t len, bool write) +{ + if (write && !flash_stm32_valid_write(offset, len)) { + return false; + } + return flash_stm32_range_exists(dev, offset, len); +} + int __weak flash_stm32_check_configuration(void) { return 0; diff --git a/drivers/flash/flash_stm32.h b/drivers/flash/flash_stm32.h index dd8628f81d77734..e0fba89a55039fa 100644 --- a/drivers/flash/flash_stm32.h +++ b/drivers/flash/flash_stm32.h @@ -257,6 +257,12 @@ static inline bool flash_stm32_range_exists(const struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static inline bool flash_stm32_valid_write(off_t offset, uint32_t len) +{ + return ((offset % FLASH_STM32_WRITE_BLOCK_SIZE == 0) && + (len % FLASH_STM32_WRITE_BLOCK_SIZE == 0U)); +} + bool flash_stm32_valid_range(const struct device *dev, off_t offset, uint32_t len, bool write); diff --git a/drivers/flash/flash_stm32f1x.c b/drivers/flash/flash_stm32f1x.c index 71d5ffbeece0137..0c54d3f69fef2e3 100644 --- a/drivers/flash/flash_stm32f1x.c +++ b/drivers/flash/flash_stm32f1x.c @@ -163,17 +163,6 @@ static int write_value(const struct device *dev, off_t offset, return rc; } -/* offset and len must be aligned on 2 for write - * positive and not beyond end of flash - */ -bool flash_stm32_valid_range(const struct device *dev, off_t offset, - uint32_t len, - bool write) -{ - return (!write || (offset % 2 == 0 && len % 2 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - int flash_stm32_block_erase_loop(const struct device *dev, unsigned int offset, unsigned int len) diff --git a/drivers/flash/flash_stm32g0x.c b/drivers/flash/flash_stm32g0x.c index a3be761f391c700..07eea9ce32b49be 100644 --- a/drivers/flash/flash_stm32g0x.c +++ b/drivers/flash/flash_stm32g0x.c @@ -40,20 +40,6 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #define STM32G0_PAGES_PER_BANK \ ((STM32G0_FLASH_SIZE / STM32G0_FLASH_PAGE_SIZE) / STM32G0_BANK_COUNT) -/* - * offset and len must be aligned on 8 for write, - * positive and not beyond end of flash - * On dual-bank SoCs memory accesses starting on the first bank and continuing - * beyond the first bank into the second bank are allowed. - */ -bool flash_stm32_valid_range(const struct device *dev, off_t offset, - uint32_t len, - bool write) -{ - return (!write || (offset % 8 == 0 && len % 8 == 0)) && - flash_stm32_range_exists(dev, offset, len); -} - static inline void flush_cache(FLASH_TypeDef *regs) { if (regs->ACR & FLASH_ACR_ICEN) { diff --git a/drivers/flash/flash_stm32g4x.c b/drivers/flash/flash_stm32g4x.c index af2535840641ee4..e1f012c254b5e4d 100644 --- a/drivers/flash/flash_stm32g4x.c +++ b/drivers/flash/flash_stm32g4x.c @@ -42,8 +42,10 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset, } #endif - return (!write || (offset % 8 == 0 && len % 8 == 0U)) && - flash_stm32_range_exists(dev, offset, len); + if (write && !flash_stm32_valid_write(offset, len)) { + return false; + } + return flash_stm32_range_exists(dev, offset, len); } static inline void flush_cache(FLASH_TypeDef *regs) diff --git a/drivers/flash/flash_stm32l4x.c b/drivers/flash/flash_stm32l4x.c index 56fe85e1fad62f1..24644aba95e498b 100644 --- a/drivers/flash/flash_stm32l4x.c +++ b/drivers/flash/flash_stm32l4x.c @@ -32,16 +32,6 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #define CONTROL_DCACHE #endif -/* offset and len must be aligned on 8 for write - * , positive and not beyond end of flash */ -bool flash_stm32_valid_range(const struct device *dev, off_t offset, - uint32_t len, - bool write) -{ - return (!write || (offset % 8 == 0 && len % 8 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - static inline void flush_cache(FLASH_TypeDef *regs) { if (regs->ACR & FLASH_ACR_DCEN) { diff --git a/drivers/flash/flash_stm32l5x.c b/drivers/flash/flash_stm32l5x.c index a0b692b45c80a2e..8ece9b22492d2e5 100644 --- a/drivers/flash/flash_stm32l5x.c +++ b/drivers/flash/flash_stm32l5x.c @@ -128,7 +128,7 @@ static int icache_wait_for_invalidate_complete(void) #endif /* CONFIG_SOC_SERIES_STM32H5X */ /* - * offset and len must be aligned on 8 for write, + * offset and len must be aligned on write-block-size for write, * positive and not beyond end of flash */ bool flash_stm32_valid_range(const struct device *dev, off_t offset, @@ -149,17 +149,21 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset, } } - return (!write || (offset % 8 == 0 && len % 8 == 0U)) && - flash_stm32_range_exists(dev, offset, len); + if (write && !flash_stm32_valid_write(offset, len)) { + return false; + } + return flash_stm32_range_exists(dev, offset, len); } -static int write_dword(const struct device *dev, off_t offset, uint64_t val) +static int write_nwords(const struct device *dev, off_t offset, const uint32_t *buff, size_t n) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); + bool full_zero = true; uint32_t tmp; int rc; + int i; /* if the non-secure control register is locked,do not fail silently */ if (regs->NSCR & FLASH_STM32_NSLOCK) { @@ -173,16 +177,26 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val) return rc; } - /* Check if this double word is erased and value isn't 0. + /* Check if this double/quad word is erased and value isn't 0. * - * It is allowed to write only zeros over an already written dword + * It is allowed to write only zeros over an already written dword / qword * See 6.3.7 in STM32L5 reference manual. * See 7.3.7 in STM32U5 reference manual. + * See 7.3.5 in STM32H5 reference manual. */ - if ((flash[0] != 0xFFFFFFFFUL || - flash[1] != 0xFFFFFFFFUL) && val != 0UL) { - LOG_ERR("Word at offs %ld not erased", (long)offset); - return -EIO; + for (i = 0; i < n; i++) { + if (buff[i] != 0) { + full_zero = false; + break; + } + } + if (!full_zero) { + for (i = 0; i < n; i++) { + if (flash[i] != 0xFFFFFFFFUL) { + LOG_ERR("Word at offs %ld not erased", (long)(offset + i)); + return -EIO; + } + } } /* Set the NSPG bit */ @@ -192,8 +206,9 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val) tmp = regs->NSCR; /* Perform the data write operation at the desired memory address */ - flash[0] = (uint32_t)val; - flash[1] = (uint32_t)(val >> 32); + for (i = 0; i < n; i++) { + flash[i] = buff[i]; + } /* Wait until the NSBSY bit is cleared */ rc = flash_stm32_wait_flash_idle(dev); @@ -341,8 +356,9 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, } } - for (i = 0; i < len; i += 8, offset += 8) { - rc = write_dword(dev, offset, ((const uint64_t *) data)[i>>3]); + for (i = 0; i < len; i += FLASH_STM32_WRITE_BLOCK_SIZE) { + rc = write_nwords(dev, offset + i, ((const uint32_t *) data + (i>>2)), + FLASH_STM32_WRITE_BLOCK_SIZE / 4); if (rc < 0) { break; } diff --git a/drivers/flash/flash_stm32wbax.c b/drivers/flash/flash_stm32wbax.c index 605b727ddfbcd9f..0796b9a5be40196 100644 --- a/drivers/flash/flash_stm32wbax.c +++ b/drivers/flash/flash_stm32wbax.c @@ -105,18 +105,6 @@ static int icache_wait_for_invalidate_complete(void) return status; } -/* - * offset and len must be aligned on 16 for write, - * positive and not beyond end of flash - */ -bool flash_stm32_valid_range(const struct device *dev, off_t offset, - uint32_t len, - bool write) -{ - return (!write || (offset % 16 == 0 && len % 16 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - static int write_qword(const struct device *dev, off_t offset, const uint32_t *buff) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); diff --git a/drivers/flash/flash_stm32wbx.c b/drivers/flash/flash_stm32wbx.c index 90746d10b170c19..e72fddf756f7599 100644 --- a/drivers/flash/flash_stm32wbx.c +++ b/drivers/flash/flash_stm32wbx.c @@ -26,17 +26,6 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #define STM32WBX_PAGE_SHIFT 12 -/* offset and len must be aligned on 8 for write, - * positive and not beyond end of flash - */ -bool flash_stm32_valid_range(const struct device *dev, off_t offset, - uint32_t len, - bool write) -{ - return (!write || (offset % 8 == 0 && len % 8 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - /* * Up to 255 4K pages */ diff --git a/drivers/gpio/gpio_stellaris.c b/drivers/gpio/gpio_stellaris.c index 433962e105856e3..e7114fa0e7f1dce 100644 --- a/drivers/gpio/gpio_stellaris.c +++ b/drivers/gpio/gpio_stellaris.c @@ -107,6 +107,34 @@ static int gpio_stellaris_configure(const struct device *dev, return 0; } +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_stellaris_get_config(const struct device *dev, + gpio_pin_t pin, + gpio_flags_t *out_flags) +{ + const struct gpio_stellaris_config *cfg = dev->config; + uint32_t base = cfg->base; + gpio_flags_t flags = 0; + mm_reg_t mask_addr; + + if (sys_test_bit(GPIO_REG_ADDR(base, GPIO_DEN_OFFSET), pin) == 0) { + flags = GPIO_DISCONNECTED; + } else if (sys_test_bit(GPIO_REG_ADDR(base, GPIO_DIR_OFFSET), pin)) { + mask_addr = GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, BIT(pin)); + + if (sys_test_bit(mask_addr, pin)) { + flags |= GPIO_OUTPUT_HIGH; + } else { + flags |= GPIO_OUTPUT_LOW; + } + } else { + flags = GPIO_INPUT; + } + *out_flags = flags; + return 0; +} +#endif + static int gpio_stellaris_port_get_raw(const struct device *dev, uint32_t *value) { @@ -221,6 +249,9 @@ static int gpio_stellaris_manage_callback(const struct device *dev, static const struct gpio_driver_api gpio_stellaris_driver_api = { .pin_configure = gpio_stellaris_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_stellaris_get_config, +#endif .port_get_raw = gpio_stellaris_port_get_raw, .port_set_masked_raw = gpio_stellaris_port_set_masked_raw, .port_set_bits_raw = gpio_stellaris_port_set_bits_raw, diff --git a/drivers/i2c/i2c_mcux_lpi2c.c b/drivers/i2c/i2c_mcux_lpi2c.c index 605ac838ef59abe..dea6d110eb07e31 100644 --- a/drivers/i2c/i2c_mcux_lpi2c.c +++ b/drivers/i2c/i2c_mcux_lpi2c.c @@ -494,6 +494,11 @@ static int mcux_lpi2c_init(const struct device *dev) return -ENODEV; } + error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (error) { + return error; + } + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq)) { return -EINVAL; @@ -513,11 +518,6 @@ static int mcux_lpi2c_init(const struct device *dev) return error; } - error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (error) { - return error; - } - config->irq_config_func(dev); return 0; diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index d85ae2e71a88977..7403583026abaf1 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -291,7 +291,7 @@ static int nrf5_energy_scan_start(const struct device *dev, if (nrf_802154_energy_detection(duration * 1000) == false) { nrf5_data.energy_scan_done = NULL; - err = -EPERM; + err = -EBUSY; } } else { err = -EALREADY; @@ -486,8 +486,11 @@ static bool nrf5_tx_csma_ca(struct net_pkt *pkt, uint8_t *payload) #if defined(CONFIG_NET_PKT_TXTIME) /** * @brief Convert 32-bit target time to absolute 64-bit target time. + * + * @param target_time_ns_wrapped time in nanoseconds referred to the radio clock + * modulo (UINT32_MAX * NSEC_PER_USEC). */ -static uint64_t target_time_convert_to_64_bits(uint32_t target_time) +static uint64_t target_time_convert_to_64_bits(uint64_t target_time_ns_wrapped) { /** * Target time is provided as two 32-bit integers defining a moment in time @@ -501,9 +504,10 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) * time. Let's assume that half of the 32-bit range can be used for specifying * target times in the future, and the other half - in the past. */ + uint32_t target_time_us_wrapped = target_time_ns_wrapped / NSEC_PER_USEC; uint64_t now_us = nrf_802154_time_get(); uint32_t now_us_wrapped = (uint32_t)now_us; - uint32_t time_diff = target_time - now_us_wrapped; + uint32_t time_diff = target_time_us_wrapped - now_us_wrapped; uint64_t result = UINT64_C(0); if (time_diff < 0x80000000) { @@ -511,32 +515,32 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) * Target time is assumed to be in the future. Check if a 32-bit overflow * occurs between the current time and the target time. */ - if (now_us_wrapped > target_time) { + if (now_us_wrapped > target_time_us_wrapped) { /** * Add a 32-bit overflow and replace the least significant 32 bits * with the provided target time. */ result = now_us + UINT32_MAX + 1; result &= ~(uint64_t)UINT32_MAX; - result |= target_time; + result |= target_time_us_wrapped; } else { /** * Leave the most significant 32 bits and replace the least significant * 32 bits with the provided target time. */ - result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time; + result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time_us_wrapped; } } else { /** * Target time is assumed to be in the past. Check if a 32-bit overflow * occurs between the target time and the current time. */ - if (now_us_wrapped > target_time) { + if (now_us_wrapped > target_time_us_wrapped) { /** * Leave the most significant 32 bits and replace the least significant * 32 bits with the provided target time. */ - result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time; + result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time_us_wrapped; } else { /** * Subtract a 32-bit overflow and replace the least significant @@ -544,7 +548,7 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) */ result = now_us - UINT32_MAX - 1; result &= ~(uint64_t)UINT32_MAX; - result |= target_time; + result |= target_time_us_wrapped; } } @@ -594,7 +598,7 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, .extra_cca_attempts = max_extra_cca_attempts, #endif }; - uint64_t tx_at = target_time_convert_to_64_bits(net_pkt_txtime(pkt) / NSEC_PER_USEC); + uint64_t tx_at = target_time_convert_to_64_bits(net_ptp_time_to_ns(net_pkt_timestamp(pkt))); return nrf_802154_transmit_raw_at(payload, tx_at, &metadata); } @@ -703,11 +707,11 @@ static int nrf5_tx(const struct device *dev, } } -static uint64_t nrf5_get_time(const struct device *dev) +static net_time_t nrf5_get_time(const struct device *dev) { ARG_UNUSED(dev); - return nrf_802154_time_get(); + return (net_time_t)nrf_802154_time_get() * NSEC_PER_USEC; } static uint8_t nrf5_get_acc(const struct device *dev) @@ -998,13 +1002,12 @@ static int nrf5_configure(const struct device *dev, * anchor_time will be used for calculations. * * `target_time_convert_to_64_bits()` is a workaround until OpenThread - * (the only CSL user in Zephyr so far) is able to schedule RX windows - * using 64-bit time. + * is able to schedule RX windows using 64-bit time. */ uint64_t start = target_time_convert_to_64_bits(config->rx_slot.start); - nrf_802154_receive_at(start, config->rx_slot.duration, config->rx_slot.channel, - DRX_SLOT_RX); + nrf_802154_receive_at(start, config->rx_slot.duration / NSEC_PER_USEC, + config->rx_slot.channel, DRX_SLOT_RX); } break; case IEEE802154_CONFIG_CSL_PERIOD: diff --git a/drivers/interrupt_controller/Kconfig.plic b/drivers/interrupt_controller/Kconfig.plic index c1e16c7c1c554d6..fd5f3b95de4b0f2 100644 --- a/drivers/interrupt_controller/Kconfig.plic +++ b/drivers/interrupt_controller/Kconfig.plic @@ -10,3 +10,9 @@ config PLIC help Platform Level Interrupt Controller provides support for external interrupt lines defined by the RISC-V SoC. + +config PLIC_SUPPORTS_EDGE_IRQ + bool "The given interrupt controller supports edge interrupts" + help + The given interrupt controller supports edge triggered + interrupts. diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 11d41e2f191a1a7..67a5313287c200c 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -29,6 +29,9 @@ #define PLIC_IRQS (CONFIG_NUM_IRQS - CONFIG_2ND_LVL_ISR_TBL_OFFSET) #define PLIC_EN_SIZE ((PLIC_IRQS >> 5) + 1) +#define PLIC_EDGE_TRIG_TYPE (PLIC_MAX_PRIO + DT_INST_PROP(0, riscv_trigger_reg_offset)) +#define PLIC_EDGE_TRIG_SHIFT 5 + struct plic_regs_t { uint32_t threshold_prio; uint32_t claim_complete; @@ -36,6 +39,28 @@ struct plic_regs_t { static int save_irq; +/** + * @brief return edge irq value or zero + * + * In the event edge irq is enable this will return the trigger + * value of the irq. In the event edge irq is not supported this + * routine will return 0 + * + * @param irq IRQ number to add to the trigger + * + * @return irq value when enabled 0 otherwise + */ +static int riscv_plic_is_edge_irq(uint32_t irq) +{ + if (IS_ENABLED(CONFIG_PLIC_SUPPORTS_EDGE_IRQ)) { + volatile uint32_t *trig = (volatile uint32_t *)PLIC_EDGE_TRIG_TYPE; + + trig += (irq >> PLIC_EDGE_TRIG_SHIFT); + return *trig & BIT(irq); + } + return 0; +} + /** * @brief Enable a riscv PLIC-specific interrupt line * @@ -135,6 +160,7 @@ static void plic_irq_handler(const void *arg) uint32_t irq; struct _isr_table_entry *ite; + int edge_irq; /* Get the IRQ number generating the interrupt */ irq = regs->claim_complete; @@ -154,6 +180,16 @@ static void plic_irq_handler(const void *arg) if (irq == 0U || irq >= PLIC_IRQS) z_irq_spurious(NULL); + edge_irq = riscv_plic_is_edge_irq(irq); + + /* + * For edge triggered interrupts, write to the claim_complete register + * to indicate to the PLIC controller that the IRQ has been handled + * for edge triggered interrupts. + */ + if (edge_irq) + regs->claim_complete = save_irq; + irq += CONFIG_2ND_LVL_ISR_TBL_OFFSET; /* Call the corresponding IRQ handler in _sw_isr_table */ @@ -162,9 +198,11 @@ static void plic_irq_handler(const void *arg) /* * Write to claim_complete register to indicate to - * PLIC controller that the IRQ has been handled. + * PLIC controller that the IRQ has been handled + * for level triggered interrupts. */ - regs->claim_complete = save_irq; + if (!edge_irq) + regs->claim_complete = save_irq; } /** diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index be9d00e36e67f62..aa39b235522b49f 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE mbox_handlers.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NRFX_IPC mbox_nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_S32_MRU mbox_nxp_s32_mru.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_ANDES_PLIC_SW mbox_andes_plic_sw.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index 79f220794917e37..a88a84472b48cfb 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -13,6 +13,7 @@ if MBOX # overridden (by defining symbols in multiple locations) source "drivers/mbox/Kconfig.nrfx" source "drivers/mbox/Kconfig.nxp_s32" +source "drivers/mbox/Kconfig.andes" config MBOX_INIT_PRIORITY int "MBOX init priority" diff --git a/drivers/mbox/Kconfig.andes b/drivers/mbox/Kconfig.andes new file mode 100644 index 000000000000000..6412e9fb6928ebf --- /dev/null +++ b/drivers/mbox/Kconfig.andes @@ -0,0 +1,14 @@ +# Kconfig Andes mbox configuration options +# +# Copyright (c) 2022 Andes Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +config MBOX_ANDES_PLIC_SW + bool "MBOX Andes PLIC-SW driver" + default y + depends on DT_HAS_ANDESTECH_PLIC_SW_ENABLED + help + Enable driver for the Andes IPM mailbox controller. + Says n if not sure. diff --git a/drivers/mbox/mbox_andes_plic_sw.c b/drivers/mbox/mbox_andes_plic_sw.c new file mode 100644 index 000000000000000..13254c464afef83 --- /dev/null +++ b/drivers/mbox/mbox_andes_plic_sw.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022 Andes Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define LOG_LEVEL CONFIG_MBOX_LOG_LEVEL +#include +#include +LOG_MODULE_REGISTER(mbox_andes_plic_sw); + +#define DT_DRV_COMPAT andestech_plic_sw + +#define IRQ_REG(n) (n >> 5) +#define PLIC_BASE(dev) \ + ((const struct mbox_andes_conf * const)(dev)->config)->base + +#define REG_PRIORITY(dev, irq) \ + (PLIC_BASE(dev) + 0x0 + (irq << 2)) +#define REG_PENDING(dev, irq) \ + (PLIC_BASE(dev) + 0x1000 + (IRQ_REG(irq) << 2)) +#define REG_ENABLE(dev, hart, irq) \ + (PLIC_BASE(dev) + 0x2000 + (hart << 7) + IRQ_REG(irq)) +#define REG_CLAIM(dev, hart) \ + (PLIC_BASE(dev) + 0x200004 + (hart << 12)) + +#define IPI_NUM DT_INST_PROP(0, channel_max) + +static struct mbox_andes_data { + mbox_callback_t cb[IPI_NUM]; + void *user_data[IPI_NUM]; + uint32_t enabled_channel[CONFIG_MP_NUM_CPUS]; +#ifdef CONFIG_SCHED_IPI_SUPPORTED + uint32_t reg_cb_channel; + uint32_t ipi_channel; +#endif +} andes_mbox_data; + +static struct mbox_andes_conf { + uint32_t base; + uint32_t channel_max; +} andes_mbox_conf = { + .base = DT_INST_REG_ADDR(0), + .channel_max = IPI_NUM, +}; + +static struct k_spinlock mbox_syn; + +static void plic_sw_irq_set_pending(const struct device *dev, uint32_t irq) +{ + uint32_t pend; + k_spinlock_key_t key = k_spin_lock(&mbox_syn); + + pend = sys_read32(REG_PENDING(dev, irq)); + pend |= BIT(irq); + sys_write32(pend, REG_PENDING(dev, irq)); + + k_spin_unlock(&mbox_syn, key); +} + +static inline bool is_channel_valid(const struct device *dev, uint32_t ch) +{ + const struct mbox_andes_conf *conf = dev->config; + + return (ch <= conf->channel_max); +} + +static int mbox_andes_send(const struct device *dev, uint32_t ch, + const struct mbox_msg *msg) +{ + if (msg) { + LOG_WRN("Sending data not supported"); + } + + if (!is_channel_valid(dev, ch)) { + return -EINVAL; + } + + /* Send IPI by triggering the pending register of PLIC SW. */ + plic_sw_irq_set_pending(dev, ch + 1); + + return 0; +} + +static int mbox_andes_register_callback(const struct device *dev, uint32_t ch, + mbox_callback_t cb, void *user_data) +{ + struct mbox_andes_data *data = dev->data; + const struct mbox_andes_conf *conf = dev->config; + int ret = 0; + + k_spinlock_key_t key = k_spin_lock(&mbox_syn); + + if (ch > conf->channel_max) { + ret = -EINVAL; + goto out; + } + +#ifdef CONFIG_SCHED_IPI_SUPPORTED + if (ch & data->ipi_channel & data->reg_cb_channel) { + ret = -EALREADY; + goto out; + } + + data->reg_cb_channel |= BIT(ch); +#endif + data->cb[ch] = cb; + data->user_data[ch] = user_data; + +out: + k_spin_unlock(&mbox_syn, key); + + return 0; +} + +static int mbox_andes_mtu_get(const struct device *dev) +{ + /* We only support signalling */ + return 0; +} + +static uint32_t mbox_andes_max_channels_get(const struct device *dev) +{ + const struct mbox_andes_conf *conf = dev->config; + + return conf->channel_max; +} + +static int mbox_andes_set_enabled(const struct device *dev, uint32_t ch, + bool enable) +{ + uint32_t en, is_enabled_ch, hartid, cpu_id, irq; + struct mbox_andes_data *data = dev->data; + int ret = 0; + + k_spinlock_key_t key = k_spin_lock(&mbox_syn); + + if (!is_channel_valid(dev, ch)) { + ret = -EINVAL; + goto out; + } + + irq = ch + 1; + hartid = arch_proc_id(); + cpu_id = _current_cpu->id; + + is_enabled_ch = data->enabled_channel[cpu_id] & BIT(ch); + + if ((!enable && !is_enabled_ch) || (enable && is_enabled_ch)) { + ret = -EALREADY; + goto out; + } + + if (enable && !(data->cb[ch])) { + LOG_WRN("Enabling channel without a registered callback\n"); + } + + en = sys_read32(REG_ENABLE(dev, hartid, irq)); + + if (enable) { + data->enabled_channel[cpu_id] |= BIT(ch); + sys_write32(1, REG_PRIORITY(dev, irq)); + en |= BIT(irq); + } else { + data->enabled_channel[cpu_id] &= ~BIT(ch); + en &= ~BIT(irq); + } + + sys_write32(en, REG_ENABLE(dev, hartid, irq)); +out: + k_spin_unlock(&mbox_syn, key); + + return ret; +} + +static void andes_plic_sw_irq_handler(const struct device *dev) +{ + struct mbox_andes_data *data = dev->data; + uint32_t irq, ch, hartid; + + hartid = arch_proc_id(); + + /* PLIC claim: Get the SW IRQ number generating the interrupt. */ + irq = sys_read32(REG_CLAIM(dev, hartid)); + ch = irq - 1; + + if (irq) { + sys_write32(irq, REG_CLAIM(dev, hartid)); + + if (data->cb[ch]) { + /* Only one MAILBOX, id is unused and set to 0 */ + data->cb[ch](dev, ch, data->user_data[ch], NULL); + } + } +} + +static int mbox_andes_init(const struct device *dev) +{ + /* Setup IRQ handler for PLIC SW driver */ + IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 1, + andes_plic_sw_irq_handler, DEVICE_DT_INST_GET(0), 0); + +#ifndef CONFIG_SMP + irq_enable(RISCV_MACHINE_SOFT_IRQ); +#endif + return 0; +} + +static const struct mbox_driver_api mbox_andes_driver_api = { + .send = mbox_andes_send, + .register_callback = mbox_andes_register_callback, + .mtu_get = mbox_andes_mtu_get, + .max_channels_get = mbox_andes_max_channels_get, + .set_enabled = mbox_andes_set_enabled, +}; + +DEVICE_DT_INST_DEFINE(0, mbox_andes_init, NULL, &andes_mbox_data, + &andes_mbox_conf, PRE_KERNEL_1, CONFIG_MBOX_INIT_PRIORITY, + &mbox_andes_driver_api); diff --git a/drivers/mipi_dsi/dsi_mcux.c b/drivers/mipi_dsi/dsi_mcux.c index 6326ace79121d34..f0eceb4697ef1ea 100644 --- a/drivers/mipi_dsi/dsi_mcux.c +++ b/drivers/mipi_dsi/dsi_mcux.c @@ -261,6 +261,9 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: dsi_xfer.txDataType = kDSI_TxDataGenShortWrTwoParam; break; + case MIPI_DSI_GENERIC_LONG_WRITE: + dsi_xfer.txDataType = kDSI_TxDataGenLongWr; + break; case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: __fallthrough; case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 044b27bef78f468..9f4dcdf095725fd 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -191,6 +191,9 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: dsi_xfer.txDataType = kDSI_TxDataGenShortWrTwoParam; break; + case MIPI_DSI_GENERIC_LONG_WRITE: + dsi_xfer.txDataType = kDSI_TxDataGenLongWr; + break; case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: __fallthrough; case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 521f1e61c19988a..a14ee14286eac16 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -33,3 +33,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 80551869d59503e..cdecc3ae554b3fb 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -62,5 +62,6 @@ source "drivers/pinctrl/Kconfig.ti_k3" source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" +source "drivers/pinctrl/Kconfig.eos_s3" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.eos_s3 b/drivers/pinctrl/Kconfig.eos_s3 new file mode 100644 index 000000000000000..04d8cd1cbe172e9 --- /dev/null +++ b/drivers/pinctrl/Kconfig.eos_s3 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_QUICKLOGIC_EOS_S3 + bool "QuickLogic EOS S3 SoC pinctrl driver" + default y + depends on DT_HAS_QUICKLOGIC_EOS_S3_PINCTRL_ENABLED + help + Enable driver for the QuickLogic EOS S3 SoC pinctrl driver diff --git a/drivers/pinctrl/pinctrl_cc13xx_cc26xx.c b/drivers/pinctrl/pinctrl_cc13xx_cc26xx.c index e8aeb660059d230..f3e853d0047a818 100644 --- a/drivers/pinctrl/pinctrl_cc13xx_cc26xx.c +++ b/drivers/pinctrl/pinctrl_cc13xx_cc26xx.c @@ -8,8 +8,6 @@ #include -#include - static int pinctrl_c13xx_cc26xx_set(uint32_t pin, uint32_t func, uint32_t mode) { if (pin >= NUM_IO_MAX || func >= NUM_IO_PORTS) { diff --git a/drivers/pinctrl/pinctrl_eos_s3.c b/drivers/pinctrl/pinctrl_eos_s3.c new file mode 100644 index 000000000000000..5fcd62711da8dd1 --- /dev/null +++ b/drivers/pinctrl/pinctrl_eos_s3.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT quicklogic_eos_s3_pinctrl + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(pinctrl_eos_s3, CONFIG_PINCTRL_LOG_LEVEL); + +#define FUNCTION_REGISTER(func) (func >> 13) +#define PAD_FUNC_SEL_MASK GENMASK(2, 0) +#define PAD_CTRL_SEL_BIT0 3 +#define PAD_CTRL_SEL_BIT1 4 +#define PAD_OUTPUT_EN_BIT 5 +#define PAD_PULL_UP_BIT 6 +#define PAD_PULL_DOWN_BIT 7 +#define PAD_DRIVE_STRENGTH_BIT0 8 +#define PAD_DRIVE_STRENGTH_BIT1 9 +#define PAD_SLEW_RATE_BIT 10 +#define PAD_INPUT_EN_BIT 11 +#define PAD_SCHMITT_EN_BIT 12 + +/* + * Program IOMUX_func_SEL register. + */ +static int pinctrl_eos_s3_input_selection(uint32_t pin, uint32_t sel_reg) +{ + volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE; + + if (sel_reg <= IO_MUX_MAX_PAD_NR || sel_reg > IO_MUX_REG_MAX_OFFSET) { + return -EINVAL; + } + reg += sel_reg; + *reg = pin; + + return 0; +} + +/* + * Program IOMUX_PAD_x_CTRL register. + */ +static int pinctrl_eos_s3_set(uint32_t pin, uint32_t func) +{ + volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE; + + if (pin > IO_MUX_REG_MAX_OFFSET) { + return -EINVAL; + } + reg += pin; + *reg = func; + + return 0; +} + +static int pinctrl_eos_s3_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t reg_value = 0; + + /* Set function. */ + reg_value |= (pin->iof & PAD_FUNC_SEL_MASK); + + /* Output enable is active low. */ + WRITE_BIT(reg_value, PAD_OUTPUT_EN_BIT, pin->output_enable ? 0 : 1); + + /* These are active high. */ + WRITE_BIT(reg_value, PAD_INPUT_EN_BIT, pin->input_enable); + WRITE_BIT(reg_value, PAD_SLEW_RATE_BIT, pin->slew_rate); + WRITE_BIT(reg_value, PAD_SCHMITT_EN_BIT, pin->schmitt_enable); + WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT0, pin->control_selection & BIT(0)); + WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT1, pin->control_selection & BIT(1)); + + switch (pin->drive_strength) { + case 2: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0); + break; + case 4: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0); + break; + case 8: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1); + break; + case 12: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1); + break; + default: + LOG_ERR("Selected drive-strength is not supported: %d\n", pin->drive_strength); + } + + /* Enable pull-up by default; overwrite if any setting was chosen. */ + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 1); + WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, 0); + if (pin->high_impedance) { + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 0); + } else if (pin->pull_up | pin->pull_down) { + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, pin->pull_up); + WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, pin->pull_down); + } + + /* Program registers. */ + pinctrl_eos_s3_set(pin->pin, reg_value); + if (pin->input_enable && FUNCTION_REGISTER(pin->iof)) { + pinctrl_eos_s3_input_selection(pin->pin, FUNCTION_REGISTER(pin->iof)); + } + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (int i = 0; i < pin_cnt; i++) { + pinctrl_eos_s3_configure_pin(&pins[i]); + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_gecko.c b/drivers/pinctrl/pinctrl_gecko.c index d801ced94bb1588..2aede54a32558cb 100644 --- a/drivers/pinctrl/pinctrl_gecko.c +++ b/drivers/pinctrl/pinctrl_gecko.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Silicon Labs + * Copyright (c) 2023 Silicon Labs * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,19 +11,25 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { USART_TypeDef *base = (USART_TypeDef *)reg; - int usart_num = USART_NUM(base); uint8_t loc; - -#ifdef CONFIG_SPI_GECKO - struct soc_gpio_pin spi_pin_cfg = {0, 0, 0, 0}; -#endif /* CONFIG_SPI_GECKO */ +#ifdef CONFIG_SOC_GECKO_SERIES1 + LEUART_TypeDef *lebase = (LEUART_TypeDef *)reg; +#else + int usart_num = USART_NUM(base); +#endif #ifdef CONFIG_UART_GECKO struct soc_gpio_pin rxpin = {0, 0, 0, 0}; struct soc_gpio_pin txpin = {0, 0, 0, 0}; #endif /* CONFIG_UART_GECKO */ + struct soc_gpio_pin pin_config = {0, 0, 0, 0}; + for (uint8_t i = 0U; i < pin_cnt; i++) { + pin_config.port = GECKO_GET_PORT(pins[i]); + pin_config.pin = GECKO_GET_PIN(pins[i]); + loc = GECKO_GET_LOC(pins[i]); + switch (GECKO_GET_FUN(pins[i])) { #ifdef CONFIG_UART_GECKO case GECKO_FUN_UART_RX: @@ -32,18 +38,70 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp rxpin.mode = gpioModeInput; rxpin.out = 1; GPIO_PinModeSet(rxpin.port, rxpin.pin, rxpin.mode, - rxpin.out); + rxpin.out); break; + case GECKO_FUN_UART_TX: txpin.port = GECKO_GET_PORT(pins[i]); txpin.pin = GECKO_GET_PIN(pins[i]); txpin.mode = gpioModePushPull; txpin.out = 1; GPIO_PinModeSet(txpin.port, txpin.pin, txpin.mode, - txpin.out); + txpin.out); + break; + +#ifdef CONFIG_SOC_GECKO_SERIES1 + case GECKO_FUN_UART_RTS: + pin_config.mode = gpioModePushPull; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_UART_CTS: + pin_config.mode = gpioModeInput; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_UART_RX_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_RXPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_RXLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_RXLOC_SHIFT); break; + + case GECKO_FUN_UART_TX_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_TXPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_TXLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_TXLOC_SHIFT); + break; + + case GECKO_FUN_UART_RTS_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_RTSPEN; + base->ROUTELOC1 &= ~_USART_ROUTELOC1_RTSLOC_MASK; + base->ROUTELOC1 |= (loc << _USART_ROUTELOC1_RTSLOC_SHIFT); + break; + + case GECKO_FUN_UART_CTS_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_CTSPEN; + base->ROUTELOC1 &= ~_USART_ROUTELOC1_CTSLOC_MASK; + base->ROUTELOC1 |= (loc << _USART_ROUTELOC1_CTSLOC_SHIFT); + break; + + case GECKO_FUN_LEUART_RX_LOC: + lebase->ROUTEPEN |= LEUART_ROUTEPEN_RXPEN; + lebase->ROUTELOC0 &= ~_LEUART_ROUTELOC0_RXLOC_MASK; + lebase->ROUTELOC0 |= (loc << _LEUART_ROUTELOC0_RXLOC_SHIFT); + break; + + case GECKO_FUN_LEUART_TX_LOC: + lebase->ROUTEPEN |= LEUART_ROUTEPEN_TXPEN; + lebase->ROUTELOC0 &= ~_LEUART_ROUTELOC0_TXLOC_MASK; + lebase->ROUTELOC0 |= (loc << _LEUART_ROUTELOC0_TXLOC_SHIFT); + break; +#else /* CONFIG_SOC_GECKO_SERIES1 */ case GECKO_FUN_UART_LOC: - loc = GECKO_GET_LOC(pins[i]); #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION /* For SOCs with configurable pin_cfg locations (set in SOC Kconfig) */ base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; @@ -98,47 +156,128 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp } #endif /* UART_GECKO_HW_FLOW_CONTROL */ break; +#endif /* CONFIG_SOC_GECKO_SERIES1 */ #endif /* CONFIG_UART_GECKO */ + #ifdef CONFIG_SPI_GECKO +#ifdef CONFIG_SOC_GECKO_SERIES1 + case GECKO_FUN_SPIM_SCK: + pin_config.mode = gpioModePushPull; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIM_MOSI: + pin_config.mode = gpioModePushPull; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIM_MISO: + pin_config.mode = gpioModeInput; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIM_CS: + pin_config.mode = gpioModePushPull; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIS_SCK: + pin_config.mode = gpioModeInput; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIS_MOSI: + pin_config.mode = gpioModeInput; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIS_MISO: + pin_config.mode = gpioModePushPull; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPIS_CS: + pin_config.mode = gpioModeInput; + pin_config.out = 1; + GPIO_PinModeSet(pin_config.port, pin_config.pin, pin_config.mode, + pin_config.out); + break; + + case GECKO_FUN_SPI_SCK_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_CLKPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_CLKLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_CLKLOC_SHIFT); + break; + + case GECKO_FUN_SPI_MOSI_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_TXPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_TXLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_TXLOC_SHIFT); + break; + + case GECKO_FUN_SPI_MISO_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_RXPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_RXLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_RXLOC_SHIFT); + break; + + case GECKO_FUN_SPI_CS_LOC: + base->ROUTEPEN |= USART_ROUTEPEN_CSPEN; + base->ROUTELOC0 &= ~_USART_ROUTELOC0_CSLOC_MASK; + base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_CSLOC_SHIFT); + break; + +#else /* CONFIG_SOC_GECKO_SERIES1 */ case GECKO_FUN_SPI_SCK: - spi_pin_cfg.port = GECKO_GET_PORT(pins[i]); - spi_pin_cfg.pin = GECKO_GET_PIN(pins[i]); - spi_pin_cfg.mode = gpioModePushPull; - spi_pin_cfg.out = 1; + pin_config.mode = gpioModePushPull; + pin_config.out = 1; GPIO->USARTROUTE[usart_num].ROUTEEN |= GPIO_USART_ROUTEEN_CLKPEN; GPIO->USARTROUTE[usart_num].CLKROUTE = - (spi_pin_cfg.pin << _GPIO_USART_CLKROUTE_PIN_SHIFT) | - (spi_pin_cfg.port << _GPIO_USART_CLKROUTE_PORT_SHIFT); + (pin_config.pin << _GPIO_USART_CLKROUTE_PIN_SHIFT) | + (pin_config.port << _GPIO_USART_CLKROUTE_PORT_SHIFT); break; + case GECKO_FUN_SPI_MOSI: - spi_pin_cfg.port = GECKO_GET_PORT(pins[i]); - spi_pin_cfg.pin = GECKO_GET_PIN(pins[i]); - spi_pin_cfg.mode = gpioModePushPull; - spi_pin_cfg.out = 1; + pin_config.mode = gpioModePushPull; + pin_config.out = 1; GPIO->USARTROUTE[usart_num].ROUTEEN |= GPIO_USART_ROUTEEN_TXPEN; GPIO->USARTROUTE[usart_num].TXROUTE = - (spi_pin_cfg.pin << _GPIO_USART_TXROUTE_PIN_SHIFT) | - (spi_pin_cfg.port << _GPIO_USART_TXROUTE_PORT_SHIFT); + (pin_config.pin << _GPIO_USART_TXROUTE_PIN_SHIFT) | + (pin_config.port << _GPIO_USART_TXROUTE_PORT_SHIFT); break; + case GECKO_FUN_SPI_MISO: - spi_pin_cfg.port = GECKO_GET_PORT(pins[i]); - spi_pin_cfg.pin = GECKO_GET_PIN(pins[i]); - spi_pin_cfg.mode = gpioModeInput; - spi_pin_cfg.out = 1; + pin_config.mode = gpioModeInput; + pin_config.out = 1; GPIO->USARTROUTE[usart_num].ROUTEEN |= GPIO_USART_ROUTEEN_RXPEN; GPIO->USARTROUTE[usart_num].RXROUTE = - (spi_pin_cfg.pin << _GPIO_USART_RXROUTE_PIN_SHIFT) | - (spi_pin_cfg.port << _GPIO_USART_RXROUTE_PORT_SHIFT); + (pin_config.pin << _GPIO_USART_RXROUTE_PIN_SHIFT) | + (pin_config.port << _GPIO_USART_RXROUTE_PORT_SHIFT); break; +#endif /* CONFIG_SOC_GECKO_SERIES1 */ #endif /* CONFIG_SPI_GECKO */ default: return -ENOTSUP; } -#ifdef CONFIG_SPI_GECKO - GPIO_PinModeSet(spi_pin_cfg.port, spi_pin_cfg.pin, - spi_pin_cfg.mode, spi_pin_cfg.out); -#endif /* CONFIG_SPI_GECKO */ +#if defined(CONFIG_SPI_GECKO) && !defined(CONFIG_SOC_GECKO_SERIES1) + GPIO_PinModeSet(pin_config.port, pin_config.pin, + pin_config.mode, pin_config.out); +#endif /* defined(CONFIG_SPI_GECKO) && !defined(CONFIG_SOC_GECKO_SERIES1) */ } return 0; diff --git a/drivers/power_domain/power_domain_gpio.c b/drivers/power_domain/power_domain_gpio.c index 511564dbc3350ff..c0fb25b3d457f59 100644 --- a/drivers/power_domain/power_domain_gpio.c +++ b/drivers/power_domain/power_domain_gpio.c @@ -30,6 +30,8 @@ struct pd_visitor_context { enum pm_device_action action; }; +#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN + static int pd_on_domain_visitor(const struct device *dev, void *context) { struct pd_visitor_context *visitor_context = context; @@ -43,12 +45,16 @@ static int pd_on_domain_visitor(const struct device *dev, void *context) return 0; } +#endif + static int pd_gpio_pm_action(const struct device *dev, enum pm_device_action action) { +#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN + struct pd_visitor_context context = {.domain = dev}; +#endif const struct pd_gpio_config *cfg = dev->config; struct pd_gpio_data *data = dev->data; - struct pd_visitor_context context = {.domain = dev}; int64_t next_boot_ticks; int rc = 0; @@ -67,14 +73,18 @@ static int pd_gpio_pm_action(const struct device *dev, LOG_INF("%s is now ON", dev->name); /* Wait for domain to come up */ k_sleep(K_USEC(cfg->startup_delay_us)); +#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN /* Notify devices on the domain they are now powered */ context.action = PM_DEVICE_ACTION_TURN_ON; (void)device_supported_foreach(dev, pd_on_domain_visitor, &context); +#endif break; case PM_DEVICE_ACTION_SUSPEND: +#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN /* Notify devices on the domain that power is going down */ context.action = PM_DEVICE_ACTION_TURN_OFF; (void)device_supported_foreach(dev, pd_on_domain_visitor, &context); +#endif /* Switch power off */ gpio_pin_set_dt(&cfg->enable, 0); LOG_INF("%s is now OFF", dev->name); @@ -103,7 +113,6 @@ static int pd_gpio_init(const struct device *dev) { const struct pd_gpio_config *cfg = dev->config; struct pd_gpio_data *data = dev->data; - int rc; if (!device_is_ready(cfg->enable.port)) { LOG_ERR("GPIO port %s is not ready", cfg->enable.port->name); @@ -112,16 +121,8 @@ static int pd_gpio_init(const struct device *dev) /* We can't know how long the domain has been off for before boot */ data->next_boot = K_TIMEOUT_ABS_US(cfg->off_on_delay_us); - if (pm_device_on_power_domain(dev)) { - /* Device is unpowered */ - pm_device_init_off(dev); - rc = gpio_pin_configure_dt(&cfg->enable, GPIO_DISCONNECTED); - } else { - pm_device_init_suspended(dev); - rc = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT_INACTIVE); - } - - return rc; + /* Boot according to state */ + return pm_device_driver_init(dev, pd_gpio_pm_action); } #define POWER_DOMAIN_DEVICE(id) \ diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 4f2fde5fd4fe81d..4619914abcb51bd 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -34,6 +34,8 @@ zephyr_library_sources_ifdef(CONFIG_PWM_TEST pwm_test.c) zephyr_library_sources_ifdef(CONFIG_PWM_RPI_PICO pwm_rpi_pico.c) 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_USERSPACE pwm_handlers.c) zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 796989048f0b162..0c467faf5621356 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -89,4 +89,8 @@ source "drivers/pwm/Kconfig.rpi_pico" source "drivers/pwm/Kconfig.intel_blinky" +source "drivers/pwm/Kconfig.xmc4xxx_ccu4" + +source "drivers/pwm/Kconfig.xmc4xxx_ccu8" + endif # PWM diff --git a/drivers/pwm/Kconfig.xmc4xxx_ccu4 b/drivers/pwm/Kconfig.xmc4xxx_ccu4 new file mode 100644 index 000000000000000..9301182ef233e6c --- /dev/null +++ b/drivers/pwm/Kconfig.xmc4xxx_ccu4 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 SLB +# SPDX-License-Identifier: Apache-2.0 + +config PWM_XMC4XXX_CCU4 + bool "Infineon XMC4XXX CCU4 driver" + default y + depends on DT_HAS_INFINEON_XMC4XXX_CCU4_PWM_ENABLED + help + Enables Infineon XMC4XXX CCU4 PWM driver. diff --git a/drivers/pwm/Kconfig.xmc4xxx_ccu8 b/drivers/pwm/Kconfig.xmc4xxx_ccu8 new file mode 100644 index 000000000000000..299bf86aab8055b --- /dev/null +++ b/drivers/pwm/Kconfig.xmc4xxx_ccu8 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 SLB +# SPDX-License-Identifier: Apache-2.0 + +config PWM_XMC4XXX_CCU8 + bool "Infineon XMC4XXX CCU4 driver" + default y + depends on DT_HAS_INFINEON_XMC4XXX_CCU8_PWM_ENABLED + help + Enables Infineon XMC4XXX CCU8 PWM driver. diff --git a/drivers/pwm/pwm_xmc4xxx_ccu4.c b/drivers/pwm/pwm_xmc4xxx_ccu4.c new file mode 100644 index 000000000000000..9800003df39623c --- /dev/null +++ b/drivers/pwm/pwm_xmc4xxx_ccu4.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_xmc4xxx_ccu4_pwm + +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(pwm_xmc4xxx_ccu4, CONFIG_PWM_LOG_LEVEL); + +#define NUM_SLICES 4 +#define NUM_CHANNELS NUM_SLICES +#define SLICE_ADDR_FROM_MODULE(module_ptr, idx) ((uint32_t)(module_ptr) + ((idx) + 1) * 0x100) + +struct pwm_xmc4xxx_ccu4_config { + XMC_CCU4_MODULE_t *ccu4; + const struct pinctrl_dev_config *pcfg; + const uint8_t slice_prescaler[NUM_SLICES]; +}; + +static int pwm_xmc4xxx_ccu4_init(const struct device *dev) +{ + const struct pwm_xmc4xxx_ccu4_config *config = dev->config; + + /* enables the CCU4 clock and ungates clock to CCU4x */ + XMC_CCU4_EnableModule(config->ccu4); + XMC_CCU4_StartPrescaler(config->ccu4); + + for (int i = 0; i < NUM_SLICES; i++) { + XMC_CCU4_SLICE_t *slice; + XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_conf = { + .prescaler_initval = config->slice_prescaler[i] + }; + + slice = (XMC_CCU4_SLICE_t *)SLICE_ADDR_FROM_MODULE(config->ccu4, i); + XMC_CCU4_SLICE_CompareInit(slice, &slice_conf); + } + + return pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); +} + +static int pwm_xmc4xxx_ccu4_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_xmc4xxx_ccu4_config *config = dev->config; + XMC_CCU4_SLICE_t *slice; + int slice_idx = channel; + + if (channel >= NUM_CHANNELS) { + return -EINVAL; + } + + if (period_cycles == 0 || period_cycles > UINT16_MAX + 1 || pulse_cycles > UINT16_MAX) { + return -EINVAL; + } + + slice = (XMC_CCU4_SLICE_t *)SLICE_ADDR_FROM_MODULE(config->ccu4, slice_idx); + slice->PRS = period_cycles - 1; + slice->CRS = period_cycles - pulse_cycles; + slice->PSL = flags & PWM_POLARITY_INVERTED; + + XMC_CCU4_EnableShadowTransfer(config->ccu4, BIT(slice_idx * 4)); + + /* start if not already running */ + XMC_CCU4_EnableClock(config->ccu4, slice_idx); + XMC_CCU4_SLICE_StartTimer(slice); + + return 0; +} + +static int pwm_xmc4xxx_ccu4_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_xmc4xxx_ccu4_config *config = dev->config; + int slice_idx = channel; + + if (channel >= NUM_SLICES) { + return -EINVAL; + } + + *cycles = XMC_SCU_CLOCK_GetCcuClockFrequency() >> config->slice_prescaler[slice_idx]; + + return 0; +} + +static const struct pwm_driver_api pwm_xmc4xxx_ccu4_driver_api = { + .set_cycles = pwm_xmc4xxx_ccu4_set_cycles, + .get_cycles_per_sec = pwm_xmc4xxx_ccu4_get_cycles_per_sec, +}; + +#define PWM_XMC4XXX_CCU4_INIT(n) \ +PINCTRL_DT_INST_DEFINE(n); \ + \ +static const struct pwm_xmc4xxx_ccu4_config config##n = { \ + .ccu4 = (CCU4_GLOBAL_TypeDef *)DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .slice_prescaler = DT_INST_PROP(n, slice_prescaler)}; \ + \ +DEVICE_DT_INST_DEFINE(n, pwm_xmc4xxx_ccu4_init, NULL, NULL, &config##n, POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, &pwm_xmc4xxx_ccu4_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_XMC4XXX_CCU4_INIT) diff --git a/drivers/pwm/pwm_xmc4xxx_ccu8.c b/drivers/pwm/pwm_xmc4xxx_ccu8.c new file mode 100644 index 000000000000000..e6d68cb115b43de --- /dev/null +++ b/drivers/pwm/pwm_xmc4xxx_ccu8.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_xmc4xxx_ccu8_pwm + +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(pwm_xmc4xxx_ccu8, CONFIG_PWM_LOG_LEVEL); + +#define NUM_SLICES 4 +#define NUM_CHANNELS (NUM_SLICES * 2) +#define MAX_DEAD_TIME_VALUE 255 +#define MAX_SLICE_PRESCALER 15 +#define MAX_DEADTIME_PRESCALER 3 +#define SLICE_ADDR_FROM_MODULE(module_ptr, idx) ((uint32_t)(module_ptr) + ((idx) + 1) * 0x100) + +struct pwm_xmc4xxx_ccu8_config { + XMC_CCU8_MODULE_t *ccu8; + const struct pinctrl_dev_config *pcfg; + const uint8_t slice_prescaler[NUM_SLICES]; + const uint8_t slice_deadtime_prescaler[NUM_SLICES]; + const uint32_t deadtime_high_ns[NUM_CHANNELS]; + const uint32_t deadtime_low_ns[NUM_CHANNELS]; +}; + +static int pwm_xmc4xxx_ccu8_init(const struct device *dev) +{ + const struct pwm_xmc4xxx_ccu8_config *config = dev->config; + + /* enables the CCU8 clock and ungates clock to CCU8x */ + XMC_CCU8_EnableModule(config->ccu8); + XMC_CCU8_StartPrescaler(config->ccu8); + + for (int i = 0; i < NUM_SLICES; i++) { + XMC_CCU8_SLICE_t *slice; + XMC_CCU8_SLICE_DEAD_TIME_CONFIG_t deadtime_conf = {0}; + XMC_CCU8_SLICE_COMPARE_CONFIG_t slice_conf = { + .prescaler_initval = config->slice_prescaler[i], + .invert_out1 = 1, + .invert_out3 = 1, + }; + + if (config->slice_prescaler[i] > MAX_SLICE_PRESCALER) { + LOG_ERR("Invalid slice_prescaler value %d. Range [0, 15]", + config->slice_prescaler[i]); + return -EINVAL; + } + + if (config->slice_deadtime_prescaler[i] > MAX_DEADTIME_PRESCALER) { + LOG_ERR("Invalid dead time prescaler value %d. Range [0, 3]", + config->slice_deadtime_prescaler[i]); + return -EINVAL; + } + + slice = (XMC_CCU8_SLICE_t *)SLICE_ADDR_FROM_MODULE(config->ccu8, i); + XMC_CCU8_SLICE_CompareInit(slice, &slice_conf); + + deadtime_conf.div = config->slice_deadtime_prescaler[i]; + if (config->deadtime_high_ns[2*i] > 0 || config->deadtime_low_ns[2*i] > 0) { + deadtime_conf.enable_dead_time_channel1 = 1; + } + deadtime_conf.channel1_st_path = config->deadtime_high_ns[2*i] > 0; + deadtime_conf.channel1_inv_st_path = config->deadtime_low_ns[2*i] > 0; + + if (config->deadtime_high_ns[2*i + 1] > 0 || config->deadtime_low_ns[2*i + 1] > 0) { + deadtime_conf.enable_dead_time_channel2 = 1; + } + deadtime_conf.channel2_st_path = config->deadtime_high_ns[2*i + 1] > 0; + deadtime_conf.channel2_inv_st_path = config->deadtime_low_ns[2*i + 1] > 0; + + XMC_CCU8_SLICE_DeadTimeInit(slice, &deadtime_conf); + } + + return pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); +} + +static int pwm_xmc4xxx_ccu8_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_xmc4xxx_ccu8_config *config = dev->config; + XMC_CCU8_SLICE_t *slice; + uint32_t high_deadtime_value = 0, low_deadtime_value = 0; + uint64_t cycles; + int slice_idx = channel / 2; + + if (channel >= NUM_CHANNELS) { + return -EINVAL; + } + + if (period_cycles == 0 || period_cycles > UINT16_MAX + 1 || pulse_cycles > UINT16_MAX) { + return -EINVAL; + } + + slice = (XMC_CCU8_SLICE_t *)SLICE_ADDR_FROM_MODULE(config->ccu8, slice_idx); + slice->PRS = period_cycles - 1; + + if (channel & 0x1) { + slice->CR2S = period_cycles - pulse_cycles; + } else { + slice->CR1S = period_cycles - pulse_cycles; + } + slice->PSL = flags & PWM_POLARITY_INVERTED; + + /* set channel dead time */ + cycles = XMC_SCU_CLOCK_GetCcuClockFrequency() >> config->slice_prescaler[slice_idx]; + cycles >>= config->slice_deadtime_prescaler[slice_idx]; + high_deadtime_value = config->deadtime_high_ns[channel] * cycles / NSEC_PER_SEC; + low_deadtime_value = config->deadtime_low_ns[channel] * cycles / NSEC_PER_SEC; + + if (high_deadtime_value > MAX_DEAD_TIME_VALUE || low_deadtime_value > MAX_DEAD_TIME_VALUE) { + return -EINVAL; + } + + XMC_CCU8_SLICE_SetDeadTimeValue(slice, channel & 0x1, high_deadtime_value, + low_deadtime_value); + + XMC_CCU8_EnableShadowTransfer(config->ccu8, BIT(slice_idx * 4)); + + /* start if not already running */ + XMC_CCU8_EnableClock(config->ccu8, slice_idx); + XMC_CCU8_SLICE_StartTimer(slice); + + return 0; +} + +static int pwm_xmc4xxx_ccu8_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_xmc4xxx_ccu8_config *config = dev->config; + + if (channel >= NUM_CHANNELS) { + return -EINVAL; + } + + *cycles = XMC_SCU_CLOCK_GetCcuClockFrequency() >> config->slice_prescaler[channel / 2]; + + return 0; +} + +static const struct pwm_driver_api pwm_xmc4xxx_ccu8_driver_api = { + .set_cycles = pwm_xmc4xxx_ccu8_set_cycles, + .get_cycles_per_sec = pwm_xmc4xxx_ccu8_get_cycles_per_sec, +}; + +#define PWM_XMC4XXX_CCU8_INIT(n) \ +PINCTRL_DT_INST_DEFINE(n); \ + \ +static const struct pwm_xmc4xxx_ccu8_config config##n = { \ + .ccu8 = (CCU8_GLOBAL_TypeDef *)DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .slice_prescaler = DT_INST_PROP(n, slice_prescaler), \ + .slice_deadtime_prescaler = DT_INST_PROP(n, slice_deadtime_prescaler), \ + .deadtime_high_ns = DT_INST_PROP(n, channel_deadtime_high), \ + .deadtime_low_ns = DT_INST_PROP(n, channel_deadtime_low), \ +}; \ + \ +DEVICE_DT_INST_DEFINE(n, pwm_xmc4xxx_ccu8_init, NULL, NULL, &config##n, POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, &pwm_xmc4xxx_ccu8_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_XMC4XXX_CCU8_INIT) diff --git a/drivers/sdhc/sdhc_spi.c b/drivers/sdhc/sdhc_spi.c index 8c656175d6b5a9f..4224704414307c1 100644 --- a/drivers/sdhc/sdhc_spi.c +++ b/drivers/sdhc/sdhc_spi.c @@ -738,14 +738,25 @@ static int sdhc_spi_init(const struct device *dev) { const struct sdhc_spi_config *cfg = dev->config; struct sdhc_spi_data *data = dev->data; + int ret = 0; if (!device_is_ready(cfg->spi_dev)) { return -ENODEV; } + if (cfg->pwr_gpio.port) { + if (!gpio_is_ready_dt(&cfg->pwr_gpio)) { + return -ENODEV; + } + ret = gpio_pin_configure_dt(&cfg->pwr_gpio, GPIO_OUTPUT_INACTIVE); + if (ret != 0) { + LOG_ERR("Could not configure power gpio (%d)", ret); + return ret; + } + } data->power_mode = SDHC_POWER_OFF; data->spi_cfg = &data->cfg_a; data->spi_cfg->frequency = 0; - return 0; + return ret; } static struct sdhc_driver_api sdhc_spi_api = { diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 0dcca296d34b6c5..2dbc6e7b471bb96 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 +add_subdirectory_ifdef(CONFIG_A01NYUB a01nyub) add_subdirectory_ifdef(CONFIG_ADC_CMP_NPCX nuvoton_adc_cmp_npcx) add_subdirectory_ifdef(CONFIG_ADT7310 adt7310) add_subdirectory_ifdef(CONFIG_ADT7420 adt7420) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index eb88b079a2fdcda..56e43d61fc9013f 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -57,6 +57,7 @@ config SENSOR_INFO comment "Device Drivers" +source "drivers/sensor/a01nyub/Kconfig" source "drivers/sensor/adt7310/Kconfig" source "drivers/sensor/adt7420/Kconfig" source "drivers/sensor/adxl345/Kconfig" diff --git a/drivers/sensor/a01nyub/CMakeLists.txt b/drivers/sensor/a01nyub/CMakeLists.txt new file mode 100644 index 000000000000000..a95e9b413fc07e1 --- /dev/null +++ b/drivers/sensor/a01nyub/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2023 SteadConnect +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(a01nyub.c) diff --git a/drivers/sensor/a01nyub/Kconfig b/drivers/sensor/a01nyub/Kconfig new file mode 100644 index 000000000000000..ff40a6f0682e715 --- /dev/null +++ b/drivers/sensor/a01nyub/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2023 SteadConnect +# SPDX-License-Identifier: Apache-2.0 + +config A01NYUB + bool "DFRobot A01NYUB distance sensor" + default y + depends on DT_HAS_DFROBOT_A01NYUB_ENABLED + depends on UART_INTERRUPT_DRIVEN + help + Enable driver for the DFRobot A01NYUB distance sensor. diff --git a/drivers/sensor/a01nyub/a01nyub.c b/drivers/sensor/a01nyub/a01nyub.c new file mode 100644 index 000000000000000..f1d57becd04d057 --- /dev/null +++ b/drivers/sensor/a01nyub/a01nyub.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2023 SteadConnect + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://wiki.dfrobot.com/A01NYUB%20Waterproof%20Ultrasonic%20Sensor%20SKU:%20SEN0313 + * + */ + +#define DT_DRV_COMPAT dfrobot_a01nyub + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(a01nyub_sensor, CONFIG_SENSOR_LOG_LEVEL); + +#define A01NYUB_BUF_LEN 4 +#define A01NYUB_CHECKSUM_IDX 3 +#define A01NYUB_HEADER 0xff + +const struct uart_config uart_cfg_a01nyub = { + .baudrate = 9600, + .parity = UART_CFG_PARITY_NONE, + .stop_bits = UART_CFG_STOP_BITS_1, + .data_bits = UART_CFG_DATA_BITS_8, + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE +}; + +struct a01nyub_data { + /* Max data length is 16 bits */ + uint16_t data; + uint8_t xfer_bytes; + uint8_t rd_data[A01NYUB_BUF_LEN]; +}; + +struct a01nyub_cfg { + const struct device *uart_dev; + uart_irq_callback_user_data_t cb; +}; + +static void a01nyub_uart_flush(const struct device *uart_dev) +{ + uint8_t c; + + while (uart_fifo_read(uart_dev, &c, 1) > 0) { + continue; + } +} + +static uint8_t a01nyub_checksum(const uint8_t *data) +{ + uint16_t cs = 0; + + for (uint8_t i = 0; i < A01NYUB_BUF_LEN - 1; i++) { + cs += data[i]; + } + + return (uint8_t) (cs & 0x00FF); +} + +static inline int a01nyub_poll_data(const struct device *dev) +{ + struct a01nyub_data *data = dev->data; + uint8_t checksum; + + checksum = a01nyub_checksum(data->rd_data); + if (checksum != data->rd_data[A01NYUB_CHECKSUM_IDX]) { + LOG_DBG("Checksum mismatch: calculated 0x%x != data checksum 0x%x", + checksum, + data->rd_data[A01NYUB_CHECKSUM_IDX]); + LOG_DBG("Data bytes: (%x,%x,%x,%x)", + data->rd_data[0], + data->rd_data[1], + data->rd_data[2], + data->rd_data[3]); + + return -EBADMSG; + } + + data->data = (data->rd_data[1]<<8) + data->rd_data[2]; + + return 0; +} + +static int a01nyub_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct a01nyub_data *data = dev->data; + + if (chan != SENSOR_CHAN_DISTANCE) { + return -ENOTSUP; + } + /* val1 is meters, val2 is microns. Both are int32_t + * data->data is in mm and units of uint16_t + */ + val->val1 = (uint32_t) (data->data / (uint16_t) 1000); + val->val2 = (uint32_t) ((data->data % 1000) * 1000); + return 0; +} + +static int a01nyub_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + + if (chan == SENSOR_CHAN_DISTANCE || chan == SENSOR_CHAN_ALL) { + return a01nyub_poll_data(dev); + } + + return -ENOTSUP; +} + +static const struct sensor_driver_api a01nyub_api_funcs = { + .sample_fetch = a01nyub_sample_fetch, + .channel_get = a01nyub_channel_get, +}; + +static void a01nyub_uart_isr(const struct device *uart_dev, void *user_data) +{ + const struct device *dev = user_data; + struct a01nyub_data *data = dev->data; + + if (uart_dev == NULL) { + LOG_DBG("UART device is NULL"); + return; + } + + if (!uart_irq_update(uart_dev)) { + LOG_DBG("Unable to start processing interrupts"); + return; + } + + if (uart_irq_rx_ready(uart_dev)) { + data->xfer_bytes += uart_fifo_read(uart_dev, &data->rd_data[data->xfer_bytes], + A01NYUB_BUF_LEN - data->xfer_bytes); + + /* The first byte should be A01NYUB_HEADER for a valid read. + * If we do not read A01NYUB_HEADER on what we think is the + * first byte, then reset the number of bytes read until we do + */ + if ((data->rd_data[0] != A01NYUB_HEADER) & (data->xfer_bytes == 1)) { + LOG_DBG("First byte not header! Resetting # of bytes read."); + data->xfer_bytes = 0; + } + + if (data->xfer_bytes == A01NYUB_BUF_LEN) { + LOG_DBG("Read (0x%x,0x%x,0x%x,0x%x)", + data->rd_data[0], + data->rd_data[1], + data->rd_data[2], + data->rd_data[3]); + a01nyub_uart_flush(uart_dev); + data->xfer_bytes = 0; + } + } +} + +static int a01nyub_init(const struct device *dev) +{ + const struct a01nyub_cfg *cfg = dev->config; + int ret = 0; + + uart_irq_rx_disable(cfg->uart_dev); + uart_irq_tx_disable(cfg->uart_dev); + + a01nyub_uart_flush(cfg->uart_dev); + + LOG_DBG("Initializing A01NYUB driver"); + + ret = uart_configure(cfg->uart_dev, &uart_cfg_a01nyub); + if (ret == -ENOSYS) { + LOG_ERR("Unable to configure UART port"); + return -ENOSYS; + } + + ret = uart_irq_callback_user_data_set(cfg->uart_dev, cfg->cb, (void *)dev); + + if (ret < 0) { + if (ret == -ENOTSUP) { + LOG_ERR("Interrupt-driven UART API support not enabled"); + } else if (ret == -ENOSYS) { + LOG_ERR("UART device does not support interrupt-driven API"); + } else { + LOG_ERR("Error setting UART callback: %d", ret); + } + return ret; + } + + uart_irq_rx_enable(cfg->uart_dev); + + return ret; +} + +#define A01NYUB_INIT(inst) \ + \ + static struct a01nyub_data a01nyub_data_##inst; \ + \ + static const struct a01nyub_cfg a01nyub_cfg_##inst = { \ + .uart_dev = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .cb = a01nyub_uart_isr, \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, a01nyub_init, NULL, \ + &a01nyub_data_##inst, &a01nyub_cfg_##inst, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &a01nyub_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(A01NYUB_INIT) diff --git a/drivers/sensor/akm09918c/akm09918c.h b/drivers/sensor/akm09918c/akm09918c.h index 9bb1b6db40621cf..1745715287e852d 100644 --- a/drivers/sensor/akm09918c/akm09918c.h +++ b/drivers/sensor/akm09918c/akm09918c.h @@ -7,6 +7,7 @@ #define ZEPHYR_DRIVERS_SENSOR_AKM09918C_AKM09918C_H_ #include +#include #include #include "akm09918c_reg.h" @@ -15,7 +16,17 @@ #define AKM09918C_MEASURE_TIME_US 9000 /* Conversion values */ -#define AKM09918C_MICRO_GAUSS_PER_BIT INT64_C(500) +#define AKM09918C_MICRO_GAUSS_PER_BIT INT64_C(1500) + +/* Maximum and minimum raw register values for magnetometer data per datasheet */ +#define AKM09918C_MAGN_MAX_DATA_REG (32752) +#define AKM09918C_MAGN_MIN_DATA_REG (-32752) + +/* Maximum and minimum magnetometer values in microgauss. +/-32752 is the maximum range of the + * data registers (slightly less than the range of int16). This works out to +/- 49,128,000 uGs + */ +#define AKM09918C_MAGN_MAX_MICRO_GAUSS (AKM09918C_MAGN_MAX_DATA_REG * AKM09918C_MICRO_GAUSS_PER_BIT) +#define AKM09918C_MAGN_MIN_MICRO_GAUSS (AKM09918C_MAGN_MIN_DATA_REG * AKM09918C_MICRO_GAUSS_PER_BIT) struct akm09918c_data { int16_t x_sample; diff --git a/drivers/sensor/akm09918c/akm09918c_emul.c b/drivers/sensor/akm09918c/akm09918c_emul.c index 3f16a2fe67cfc97..2112acc8c001df3 100644 --- a/drivers/sensor/akm09918c/akm09918c_emul.c +++ b/drivers/sensor/akm09918c/akm09918c_emul.c @@ -7,10 +7,13 @@ #include #include +#include #include #include #include +#include +#include "akm09918c.h" #include "akm09918c_emul.h" #include "akm09918c_reg.h" @@ -130,14 +133,90 @@ static int akm09918c_emul_init(const struct emul *target, const struct device *p return 0; } +static int akm09918c_emul_backend_set_channel(const struct emul *target, enum sensor_channel ch, + q31_t value, int8_t shift) +{ + if (!target || !target->data) { + return -EINVAL; + } + + struct akm09918c_emul_data *data = target->data; + uint8_t reg; + + switch (ch) { + case SENSOR_CHAN_MAGN_X: + reg = AKM09918C_REG_HXL; + break; + case SENSOR_CHAN_MAGN_Y: + reg = AKM09918C_REG_HYL; + break; + case SENSOR_CHAN_MAGN_Z: + reg = AKM09918C_REG_HZL; + break; + /* This function only supports setting single channels, so skip MAGN_XYZ */ + default: + return -ENOTSUP; + } + + /* Set the ST1 register to show we have data */ + data->reg[AKM09918C_REG_ST1] |= AKM09918C_ST1_DRDY; + + /* Convert fixed-point Gauss values into microgauss and then into its bit representation */ + int32_t microgauss = (shift < 0 ? ((int64_t)value >> -shift) : ((int64_t)value << shift)) * + 1000000 / ((int64_t)INT32_MAX + 1); + + int16_t reg_val = + CLAMP(microgauss, AKM09918C_MAGN_MIN_MICRO_GAUSS, AKM09918C_MAGN_MAX_MICRO_GAUSS) / + AKM09918C_MICRO_GAUSS_PER_BIT; + + /* Insert reading into registers */ + data->reg[reg] = reg_val & 0xFF; + data->reg[reg + 1] = (reg_val >> 8) & 0xFF; + + return 0; +} + +static int akm09918c_emul_backend_get_sample_range(const struct emul *target, + enum sensor_channel ch, q31_t *lower, + q31_t *upper, q31_t *epsilon, int8_t *shift) +{ + ARG_UNUSED(target); + + if (!lower || !upper || !epsilon || !shift) { + return -EINVAL; + } + + switch (ch) { + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + /* +/- 49.12 Gs is the measurement range. 0.0015 Gs is the granularity */ + *shift = 6; + *upper = (int64_t)(49.12 * ((int64_t)INT32_MAX + 1)) >> *shift; + *lower = -*upper; + *epsilon = (int64_t)(0.0015 * ((int64_t)INT32_MAX + 1)) >> *shift; + break; + default: + return -ENOTSUP; + } + + return 0; +} + static const struct i2c_emul_api akm09918c_emul_api_i2c = { .transfer = akm09918c_emul_transfer_i2c, }; +static const struct emul_sensor_backend_api akm09918c_emul_sensor_backend_api = { + .set_channel = akm09918c_emul_backend_set_channel, + .get_sample_range = akm09918c_emul_backend_get_sample_range, +}; + #define AKM09918C_EMUL(n) \ const struct akm09918c_emul_cfg akm09918c_emul_cfg_##n; \ struct akm09918c_emul_data akm09918c_emul_data_##n; \ EMUL_DT_INST_DEFINE(n, akm09918c_emul_init, &akm09918c_emul_data_##n, \ - &akm09918c_emul_cfg_##n, &akm09918c_emul_api_i2c, NULL) + &akm09918c_emul_cfg_##n, &akm09918c_emul_api_i2c, \ + &akm09918c_emul_sensor_backend_api) DT_INST_FOREACH_STATUS_OKAY(AKM09918C_EMUL) diff --git a/drivers/sensor/bme280/bme280.c b/drivers/sensor/bme280/bme280.c index 082bacf1b1b80ec..f2bd7514c019069 100644 --- a/drivers/sensor/bme280/bme280.c +++ b/drivers/sensor/bme280/bme280.c @@ -245,6 +245,10 @@ static int bme280_channel_get(const struct device *dev, (((data->comp_press & 0xff) * 1000U) >> 8); break; case SENSOR_CHAN_HUMIDITY: + /* The BMP280 doesn't have a humidity sensor */ + if (data->chip_id != BME280_CHIP_ID) { + return -ENOTSUP; + } /* * data->comp_humidity has 22 integer bits and 10 * fractional. Output value of 47445 represents @@ -254,7 +258,7 @@ static int bme280_channel_get(const struct device *dev, val->val2 = (((data->comp_humidity & 0x3ff) * 1000U * 1000U) >> 10); break; default: - return -EINVAL; + return -ENOTSUP; } return 0; diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index b8c828297318fd5..bdd5e64b2ad5529 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -154,6 +155,9 @@ enum dynamic_command_context { static enum dynamic_command_context current_cmd_ctx = NONE; +/* Mutex for accessing shared RTIO/IODEV data structures */ +K_MUTEX_DEFINE(cmd_get_mutex); + /* Crate a single common config for one-shot reading */ static enum sensor_channel iodev_sensor_shell_channels[SENSOR_CHAN_ALL]; static struct sensor_read_config iodev_sensor_shell_read_config = { @@ -299,28 +303,32 @@ static void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; + int count = 0; int err; + err = k_mutex_lock(&cmd_get_mutex, K_NO_WAIT); + if (err < 0) { + shell_error(sh, "Another sensor reading in progress"); + return err; + } + dev = device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Device unknown (%s)", argv[1]); + k_mutex_unlock(&cmd_get_mutex); return -ENODEV; } if (argc == 2) { /* read all channels */ - int count = 0; - for (int i = 0; i < ARRAY_SIZE(iodev_sensor_shell_channels); ++i) { if (SENSOR_CHANNEL_3_AXIS(i)) { continue; } iodev_sensor_shell_channels[count++] = i; } - iodev_sensor_shell_read_config.count = count; } else { /* read specific channels */ - iodev_sensor_shell_read_config.count = 0; for (int i = 2; i < argc; ++i) { int chan = parse_named_int(argv[i], sensor_channel_name, ARRAY_SIZE(sensor_channel_name)); @@ -329,16 +337,17 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) shell_error(sh, "Failed to read channel (%s)", argv[i]); continue; } - iodev_sensor_shell_channels[iodev_sensor_shell_read_config.count++] = - chan; + iodev_sensor_shell_channels[count++] = chan; } } - if (iodev_sensor_shell_read_config.count == 0) { + if (count == 0) { shell_error(sh, "No channels to read, bailing"); + k_mutex_unlock(&cmd_get_mutex); return -EINVAL; } iodev_sensor_shell_read_config.sensor = dev; + iodev_sensor_shell_read_config.count = count; struct sensor_shell_processing_context ctx = { .dev = dev, @@ -350,6 +359,8 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) } sensor_processing_with_callback(&sensor_read_rtio, sensor_shell_processing_callback); + k_mutex_unlock(&cmd_get_mutex); + return 0; } diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 342fb1fd09cb209..de3ec08af8ba63a 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -63,6 +63,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_HOSTLINK uart_hostlink.c) zephyr_library_sources_ifdef(CONFIG_UART_EMUL uart_emul.c) zephyr_library_sources_ifdef(CONFIG_UART_NUMAKER uart_numaker.c) zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c) +zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index a803c152919ce98..39156777336c4c5 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -239,4 +239,6 @@ source "drivers/serial/Kconfig.numaker" source "drivers/serial/Kconfig.efinix_sapphire" +source "drivers/serial/Kconfig.sedi" + endif # SERIAL diff --git a/drivers/serial/Kconfig.gecko b/drivers/serial/Kconfig.gecko index 53f3ebca2ed3f21..2330fd401c74e6a 100644 --- a/drivers/serial/Kconfig.gecko +++ b/drivers/serial/Kconfig.gecko @@ -10,5 +10,6 @@ config UART_GECKO select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select SOC_GECKO_USART + select PINCTRL if SOC_GECKO_SERIES1 help Enable the Gecko uart driver. diff --git a/drivers/serial/Kconfig.pl011 b/drivers/serial/Kconfig.pl011 index 9c48001835a2846..95dd947b9dccdc9 100644 --- a/drivers/serial/Kconfig.pl011 +++ b/drivers/serial/Kconfig.pl011 @@ -7,6 +7,7 @@ menuconfig UART_PL011 depends on DT_HAS_ARM_PL011_ENABLED || DT_HAS_ARM_SBSA_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL if SOC_EOS_S3 help This option enables the UART driver for the PL011 diff --git a/drivers/serial/Kconfig.ql_usbserialport_s3b b/drivers/serial/Kconfig.ql_usbserialport_s3b index 197d26f5faf496e..b989c91516e5212 100644 --- a/drivers/serial/Kconfig.ql_usbserialport_s3b +++ b/drivers/serial/Kconfig.ql_usbserialport_s3b @@ -8,5 +8,6 @@ config UART_QUICKLOGIC_USBSERIALPORT_S3B default y depends on DT_HAS_QUICKLOGIC_USBSERIALPORT_S3B_ENABLED select SERIAL_HAS_DRIVER + select PINCTRL help This option enables the QuickLogic USBserialport_S3B serial driver. diff --git a/drivers/serial/Kconfig.sedi b/drivers/serial/Kconfig.sedi new file mode 100644 index 000000000000000..4710dfa15c4a8f3 --- /dev/null +++ b/drivers/serial/Kconfig.sedi @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config UART_SEDI + bool "Intel SEDI UART driver" + default y + depends on DT_HAS_INTEL_SEDI_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + This option enables the Intel SEDI UART driver. + This driver is simply a shim driver built upon the SEDI + bare metal UART driver in the hal-intel module diff --git a/drivers/serial/uart_sedi.c b/drivers/serial/uart_sedi.c new file mode 100644 index 000000000000000..e082f97ce57b77f --- /dev/null +++ b/drivers/serial/uart_sedi.c @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include "sedi_driver_uart.h" + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void uart_sedi_isr(void *arg); +static void uart_sedi_cb(struct device *port); +#endif + +#define DT_DRV_COMPAT intel_sedi_uart + +/* Helper macro to set flow control. */ +#define UART_CONFIG_FLOW_CTRL_SET(n) \ + .hw_fc = DT_INST_PROP(n, hw_flow_control) + +/* Helper macro to set line control. */ +#define UART_CONFIG_LINE_CTRL_SET \ + .line_ctrl = SEDI_UART_LC_8N1 + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +/* UART IRQ handler declaration. */ +#define UART_IRQ_HANDLER_DECL(n) \ + static void irq_config_uart_##n(const struct device *dev) + +/* Setting configuration function. */ +#define UART_CONFIG_IRQ_HANDLER_SET(n) \ + .uart_irq_config_func = irq_config_uart_##n +#define UART_IRQ_HANDLER_DEFINE(n) \ + static void irq_config_uart_##n(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), uart_sedi_isr, \ + DEVICE_DT_GET(DT_NODELABEL(uart##n)), \ + DT_INST_IRQ(n, sense)); \ + irq_enable(DT_INST_IRQN(n)); \ + } +#else /*CONFIG_UART_INTERRUPT_DRIVEN */ +#define UART_IRQ_HANDLER_DECL(n) +#define UART_CONFIG_IRQ_HANDLER_SET(n) (0) + +#define UART_IRQ_HANDLER_DEFINE(n) +#endif /* !CONFIG_UART_INTERRUPT_DRIVEN */ + +/* Device init macro for UART instance. As multiple uart instances follow a + * similar definition of data structures differing only in the instance + * number.This macro makes adding instances simpler. + */ +#define UART_SEDI_DEVICE_INIT(n) \ + UART_IRQ_HANDLER_DECL(n); \ + static K_MUTEX_DEFINE(uart_##n##_mutex); \ + static K_SEM_DEFINE(uart_##n##_tx_sem, 1, 1); \ + static K_SEM_DEFINE(uart_##n##_rx_sem, 1, 1); \ + static K_SEM_DEFINE(uart_##n##_sync_read_sem, 0, 1); \ + static const struct uart_sedi_config_info config_info_##n = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + .instance = SEDI_UART_##n, \ + .baud_rate = DT_INST_PROP(n, current_speed), \ + UART_CONFIG_FLOW_CTRL_SET(n), \ + UART_CONFIG_LINE_CTRL_SET, \ + .mutex = &uart_##n##_mutex, \ + .tx_sem = &uart_##n##_tx_sem, \ + .rx_sem = &uart_##n##_rx_sem, \ + .sync_read_sem = &uart_##n##_sync_read_sem, \ + UART_CONFIG_IRQ_HANDLER_SET(n) \ + }; \ + \ + static struct uart_sedi_drv_data drv_data_##n; \ + PM_DEVICE_DT_DEFINE(DT_NODELABEL(uart##n), \ + uart_sedi_pm_action); \ + DEVICE_DT_DEFINE(DT_NODELABEL(uart##n), \ + &uart_sedi_init, \ + PM_DEVICE_DT_GET(DT_NODELABEL(uart##n)), \ + &drv_data_##n, &config_info_##n, \ + PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, &api); \ + UART_IRQ_HANDLER_DEFINE(n) + + + +/* Convenient macro to get the controller instance. */ +#define GET_CONTROLLER_INSTANCE(dev) \ + (((const struct uart_sedi_config_info *) \ + dev->config)->instance) + +/* Convenient macro to get tx semamphore */ +#define GET_TX_SEM(dev) \ + (((const struct uart_sedi_config_info *) \ + dev->config)->tx_sem) + + +/* Convenient macro to get rx sempahore */ +#define GET_RX_SEM(dev) \ + (((const struct uart_sedi_config_info *) \ + dev->config)->rx_sem) + +/* Convenient macro to get sync_read sempahore */ +#define GET_SYNC_READ_SEM(dev) \ + (((const struct uart_sedi_config_info *) \ + dev->config)->sync_read_sem) + +#define GET_MUTEX(dev) \ + (((const struct uart_sedi_config_info *) \ + dev->config)->mutex) + +struct uart_sedi_config_info { + DEVICE_MMIO_ROM; + /* Specifies the uart instance for configuration. */ + sedi_uart_t instance; + + /* Specifies the baudrate for the uart instance. */ + uint32_t baud_rate; + + /* Specifies the port line contorl settings */ + sedi_uart_lc_t line_ctrl; + + struct k_mutex *mutex; + struct k_sem *tx_sem; + struct k_sem *rx_sem; + struct k_sem *sync_read_sem; + /* Enable / disable hardware flow control for UART. */ + + bool hw_fc; + + /* UART irq configuration function when supporting interrupt + * mode. + */ + uart_irq_config_func_t uart_irq_config_func; +}; + + +static int uart_sedi_init(const struct device *dev); + +struct uart_sedi_drv_data { + DEVICE_MMIO_RAM; + uart_irq_callback_user_data_t user_cb; + void *unsol_rx_usr_cb_param; + uint32_t sync_rx_len; + uint32_t sync_rx_status; + void *user_data; + void *usr_rx_buff; + uint32_t usr_rx_size; + uint8_t iir_cache; + uint8_t busy_count; +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void uart_busy_set(const struct device *dev) +{ + + struct uart_sedi_drv_data *context = dev->data; + + context->busy_count++; + + if (context->busy_count == 1) { + pm_device_busy_set(dev); + } +} + +static void uart_busy_clear(const struct device *dev) +{ + + struct uart_sedi_drv_data *context = dev->data; + + context->busy_count--; + + if (context->busy_count == 0) { + pm_device_busy_clear(dev); + } +} +#endif + +#ifdef CONFIG_PM_DEVICE + +#ifndef CONFIG_UART_CONSOLE + +static int uart_suspend_device(const struct device *dev) +{ + const struct uart_sedi_config_info *config = dev->config; + + if (pm_device_is_busy(dev)) { + return -EBUSY; + } + + int ret = sedi_uart_set_power(config->instance, SEDI_POWER_SUSPEND); + + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + return 0; +} + +static int uart_resume_device_from_suspend(const struct device *dev) +{ + const struct uart_sedi_config_info *config = dev->config; + int ret; + + ret = sedi_uart_set_power(config->instance, SEDI_POWER_FULL); + if (ret != SEDI_DRIVER_OK) { + return -EIO; + } + + return 0; +} + +static int uart_sedi_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = uart_suspend_device(dev); + break; + case PM_DEVICE_ACTION_RESUME: + ret = uart_resume_device_from_suspend(dev); + break; + + default: + ret = -ENOTSUP; + } + return ret; +} + +#else + +static int uart_sedi_pm_action(const struct device *dev, + enum pm_device_action action) +{ + /* do nothing if using UART print log to avoid clock gating + * pm driver already handled power management for uart. + */ + return 0; +} + +#endif /* CONFIG_UART_CONSOLE */ + +#endif /* CONFIG_PM_DEVICE */ + +static int uart_sedi_poll_in(const struct device *dev, unsigned char *data) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + uint32_t status; + int ret = 0; + + sedi_uart_get_status(instance, (uint32_t *) &status); + + /* In order to check if there is any data to read from UART + * controller we should check if the SEDI_UART_RX_BUSY bit from + * 'status' is not set. This bit is set only if there is any + * pending character to read. + */ + if (!(status & SEDI_UART_RX_BUSY)) { + ret = -1; + } else { + if (sedi_uart_read(instance, data, (uint32_t *)&status)) { + ret = -1; + } + } + return ret; +} + +static void uart_sedi_poll_out(const struct device *dev, + unsigned char data) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_write(instance, data); +} + +#ifdef CONFIG_UART_LINE_CTRL +static int get_xfer_error(int bsp_err) +{ + int err; + + switch (bsp_err) { + case SEDI_DRIVER_OK: + err = 0; + break; + case SEDI_USART_ERROR_CANCELED: + err = -ECANCELED; + break; + case SEDI_DRIVER_ERROR: + err = -EIO; + break; + case SEDI_DRIVER_ERROR_PARAMETER: + err = -EINVAL; + break; + case SEDI_DRIVER_ERROR_UNSUPPORTED: + err = -ENOTSUP; + break; + default: + err = -EFAULT; + } + return err; +} +#endif /* CONFIG_UART_LINE_CTRL */ + +static int uart_sedi_err_check(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + uint32_t status; + int ret_status = 0; + + sedi_uart_get_status(instance, (uint32_t *const)&status); + if (status & SEDI_UART_RX_OE) { + ret_status = UART_ERROR_OVERRUN; + } + + if (status & SEDI_UART_RX_PE) { + ret_status = UART_ERROR_PARITY; + } + + if (status & SEDI_UART_RX_FE) { + ret_status = UART_ERROR_FRAMING; + } + + if (status & SEDI_UART_RX_BI) { + ret_status = UART_BREAK; + } + + return ret_status; +} + + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_sedi_fifo_fill(const struct device *dev, const uint8_t *tx_data, + int size) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_fifo_fill(instance, tx_data, size); +} + +static int uart_sedi_fifo_read(const struct device *dev, uint8_t *rx_data, + const int size) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_fifo_read(instance, rx_data, size); +} + +static void uart_sedi_irq_tx_enable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_irq_tx_enable(instance); +} + +static void uart_sedi_irq_tx_disable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_irq_tx_disable(instance); +} + +static int uart_sedi_irq_tx_ready(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_irq_tx_ready(instance); +} + +static int uart_sedi_irq_tx_complete(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_is_tx_complete(instance); +} + +static void uart_sedi_irq_rx_enable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + uart_busy_set(dev); + sedi_uart_irq_rx_enable(instance); +} + +static void uart_sedi_irq_rx_disable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_irq_rx_disable(instance); + uart_busy_clear(dev); +} + +static int uart_sedi_irq_rx_ready(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_is_irq_rx_ready(instance); +} + +static void uart_sedi_irq_err_enable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_irq_err_enable(instance); +} + +static void uart_sedi_irq_err_disable(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_irq_err_disable(instance); +} + +static int uart_sedi_irq_is_pending(const struct device *dev) +{ + + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + return sedi_uart_is_irq_pending(instance); +} + +static int uart_sedi_irq_update(const struct device *dev) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + + sedi_uart_update_irq_cache(instance); + return 1; +} + +static void uart_sedi_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_sedi_drv_data *drv_data = dev->data; + + drv_data->user_cb = cb; + drv_data->user_data = user_data; + +} + +static void uart_sedi_isr(void *arg) +{ + struct device *dev = arg; + struct uart_sedi_drv_data *drv_data = dev->data; + + if (drv_data->user_cb) { + drv_data->user_cb(dev, drv_data->user_data); + } else { + uart_sedi_cb(dev); + } +} + +/* Called from generic callback of zephyr , set by set_cb. */ +static void uart_sedi_cb(struct device *port) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(port); + + sedi_uart_isr_handler(instance); +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#ifdef CONFIG_UART_LINE_CTRL +static int uart_sedi_line_ctrl_set(struct device *dev, + uint32_t ctrl, uint32_t val) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + sedi_uart_config_t cfg; + uint32_t mask; + int ret; + + k_mutex_lock(GET_MUTEX(dev), K_FOREVER); + switch (ctrl) { + case UART_LINE_CTRL_BAUD_RATE: + sedi_uart_get_config(instance, &cfg); + cfg.baud_rate = val; + ret = sedi_uart_set_config(instance, &cfg); + break; + + default: + ret = -ENODEV; + } + k_mutex_unlock(GET_MUTEX(dev)); + ret = get_xfer_error(ret); + return ret; +} + +static int uart_sedi_line_ctrl_get(struct device *dev, + uint32_t ctrl, uint32_t *val) +{ + sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + sedi_uart_config_t cfg; + uint32_t mask; + int ret; + + k_mutex_lock(GET_MUTEX(dev), K_FOREVER); + switch (ctrl) { + case UART_LINE_CTRL_BAUD_RATE: + ret = sedi_uart_get_config(instance, &cfg); + *val = cfg.baud_rate; + break; + + case UART_LINE_CTRL_LOOPBACK: + ret = sedi_uart_get_loopback_mode(instance, (uint32_t *)val); + break; + + case UART_LINE_CTRL_AFCE: + ret = sedi_uart_get_config(instance, &cfg); + *val = cfg.hw_fc; + break; + + case UART_LINE_CTRL_LINE_STATUS_REPORT_MASK: + mask = 0; + *val = 0; + ret = sedi_get_ln_status_report_mask(instance, + (uint32_t *)&mask); + *val |= ((mask & SEDI_UART_RX_OE) ? UART_ERROR_OVERRUN : 0); + *val |= ((mask & SEDI_UART_RX_PE) ? UART_ERROR_PARITY : 0); + *val |= ((mask & SEDI_UART_RX_FE) ? UART_ERROR_FRAMING : 0); + *val |= ((mask & SEDI_UART_RX_BI) ? UART_BREAK : 0); + break; + + case UART_LINE_CTRL_RTS: + ret = sedi_uart_read_rts(instance, (uint32_t *)val); + break; + + case UART_LINE_CTRL_CTS: + ret = sedi_uart_read_cts(instance, (uint32_t *)val); + break; + + + default: + ret = -ENODEV; + } + k_mutex_unlock(GET_MUTEX(dev)); + ret = get_xfer_error(ret); + return ret; +} + +#endif /* CONFIG_UART_LINE_CTRL */ + +static const struct uart_driver_api api = { + .poll_in = uart_sedi_poll_in, + .poll_out = uart_sedi_poll_out, + .err_check = uart_sedi_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_sedi_fifo_fill, + .fifo_read = uart_sedi_fifo_read, + .irq_tx_enable = uart_sedi_irq_tx_enable, + .irq_tx_disable = uart_sedi_irq_tx_disable, + .irq_tx_ready = uart_sedi_irq_tx_ready, + .irq_tx_complete = uart_sedi_irq_tx_complete, + .irq_rx_enable = uart_sedi_irq_rx_enable, + .irq_rx_disable = uart_sedi_irq_rx_disable, + .irq_rx_ready = uart_sedi_irq_rx_ready, + .irq_err_enable = uart_sedi_irq_err_enable, + .irq_err_disable = uart_sedi_irq_err_disable, + .irq_is_pending = uart_sedi_irq_is_pending, + .irq_update = uart_sedi_irq_update, + .irq_callback_set = uart_sedi_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_LINE_CTRL + .line_ctrl_set = uart_sedi_line_ctrl_set, + .line_ctrl_get = uart_sedi_line_ctrl_get, +#endif /* CONFIG_UART_LINE_CTRL */ + +}; + +static int uart_sedi_init(const struct device *dev) +{ + + const struct uart_sedi_config_info *config = dev->config; + sedi_uart_config_t cfg; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + sedi_uart_init(config->instance, (void *)DEVICE_MMIO_GET(dev)); + + cfg.line_control = config->line_ctrl; + cfg.baud_rate = config->baud_rate; + cfg.hw_fc = config->hw_fc; + + /* Setting to full power and enabling clk. */ + sedi_uart_set_power(config->instance, SEDI_POWER_FULL); + + sedi_uart_set_config(config->instance, &cfg); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + config->uart_irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + return 0; +} + +DT_INST_FOREACH_STATUS_OKAY(UART_SEDI_DEVICE_INIT) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 8590cc6fd580568..65dadb8d4a7bdd7 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -51,6 +51,36 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #endif /* CONFIG_SOC_SERIES_STM32MP1X */ #ifdef CONFIG_SPI_STM32_DMA + +#ifdef CONFIG_SOC_SERIES_STM32H7X + +#define IS_NOCACHE_MEM_REGION(node_id) \ + COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, zephyr_memory_attr, RAM_NOCACHE), \ + (1), \ + (0)) + +#define GET_MEM_REGION(node_id) \ + { \ + .start = DT_REG_ADDR(node_id), \ + .end = (DT_REG_ADDR(node_id) + DT_REG_SIZE(node_id)) - 1, \ + }, + +#define GET_MEM_REGION_IF_NOCACHE(node_id) \ + COND_CODE_1(IS_NOCACHE_MEM_REGION(node_id), \ + ( \ + GET_MEM_REGION(node_id) \ + ), ()) + +struct mem_region { + uintptr_t start; + uintptr_t end; +}; + +static const struct mem_region nocache_mem_regions[] = { + DT_MEMORY_ATTR_FOREACH_NODE(GET_MEM_REGION_IF_NOCACHE) +}; +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + /* dummy value used for transferring NOP when tx buf is null * and use as dummy sink for when rx buf is null */ @@ -723,6 +753,34 @@ static int wait_dma_rx_tx_done(const struct device *dev) return res; } +#ifdef CONFIG_SOC_SERIES_STM32H7X +static bool buf_in_nocache(uintptr_t buf, size_t len_bytes) +{ + for (size_t i = 0; i < ARRAY_SIZE(nocache_mem_regions); i++) { + const struct mem_region *mem_reg = &nocache_mem_regions[i]; + + const bool buf_within_bounds = + (buf >= mem_reg->start) && ((buf + len_bytes - 1) <= mem_reg->end); + if (buf_within_bounds) { + return true; + } + } + return false; +} + +static bool spi_buf_set_in_nocache(const struct spi_buf_set *bufs) +{ + for (size_t i = 0; i < bufs->count; i++) { + const struct spi_buf *buf = &bufs->buffers[i]; + + if (!buf_in_nocache((uintptr_t)buf->buf, buf->len)) { + return false; + } + } + return true; +} +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + static int transceive_dma(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, @@ -744,6 +802,13 @@ static int transceive_dma(const struct device *dev, return -ENOTSUP; } +#ifdef CONFIG_SOC_SERIES_STM32H7X + if ((tx_bufs != NULL && !spi_buf_set_in_nocache(tx_bufs)) || + (rx_bufs != NULL && !spi_buf_set_in_nocache(rx_bufs))) { + return -EFAULT; + } +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); k_sem_reset(&data->status_sem); diff --git a/drivers/usb/device/usb_dc_it82xx2.c b/drivers/usb/device/usb_dc_it82xx2.c index d90c351841b37e0..a18244aa1be4ee3 100644 --- a/drivers/usb/device/usb_dc_it82xx2.c +++ b/drivers/usb/device/usb_dc_it82xx2.c @@ -301,7 +301,7 @@ static void it8xxx2_usb_dc_wuc_init(const struct device *dev) /* Enabling the WUI */ it8xxx2_wuc_enable(cfg->wuc_list[0].wucs, cfg->wuc_list[0].mask); - /* Connect WU90 (USB D+) interrupt but make it disabled initally */ + /* Connect WU90 (USB D+) interrupt but make it disabled initially */ IRQ_CONNECT(IT8XXX2_WU90_IRQ, 0, it82xx2_wu90_isr, 0, 0); } @@ -1157,7 +1157,7 @@ int usb_dc_ep_enable(const uint8_t ep) if (ep_idx < EP4) { LOG_DBG("ep_idx < 4"); ep_regs[ep_idx].ep_ctrl |= ENDPOINT_EN; - LOG_DBG("EP%d Enbabled %02x", ep_idx, ep_regs[ep_idx].ep_ctrl); + LOG_DBG("EP%d Enabled %02x", ep_idx, ep_regs[ep_idx].ep_ctrl); } else { LOG_DBG("ep_idx >= 4"); it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ENABLE); diff --git a/drivers/usb/device/usb_dc_kinetis.c b/drivers/usb/device/usb_dc_kinetis.c index 9cb78c0230cee4d..5f45a59f1944c4f 100644 --- a/drivers/usb/device/usb_dc_kinetis.c +++ b/drivers/usb/device/usb_dc_kinetis.c @@ -878,7 +878,7 @@ static void usb_kinetis_isr_handler(void) /* * Device reset is not possible because the stack does not * configure the endpoints after the USB_DC_RESET event, - * therefore, we must reenable the default control 0 endpoint + * therefore, we must re-enable the default control 0 endpoint * after a reset event */ USB0->CTL |= USB_CTL_ODDRST_MASK; diff --git a/drivers/usb/device/usb_dc_sam_usbc.c b/drivers/usb/device/usb_dc_sam_usbc.c index eff44ee8ac31683..20162593400caa9 100644 --- a/drivers/usb/device/usb_dc_sam_usbc.c +++ b/drivers/usb/device/usb_dc_sam_usbc.c @@ -1109,7 +1109,7 @@ int usb_dc_ep_flush(uint8_t ep) dev_data.ep_data[ep_idx].out_at = 0U; - /* Reenable interrupts */ + /* Re-enable interrupts */ usb_dc_ep_enable_interrupts(ep_idx); irq_unlock(key); diff --git a/drivers/usb/device/usb_dc_sam_usbhs.c b/drivers/usb/device/usb_dc_sam_usbhs.c index 5f8288655d522ad..6415b4abfcf678f 100644 --- a/drivers/usb/device/usb_dc_sam_usbhs.c +++ b/drivers/usb/device/usb_dc_sam_usbhs.c @@ -710,7 +710,7 @@ int usb_dc_ep_flush(uint8_t ep) /* Reset the endpoint */ usb_dc_ep_reset(ep_idx); - /* Reenable interrupts */ + /* Re-enable interrupts */ usb_dc_ep_enable_interrupts(ep_idx); LOG_DBG("ep 0x%x", ep); diff --git a/drivers/usb/device/usb_dw_registers.h b/drivers/usb/device/usb_dw_registers.h index 44676232f371e65..83e67c157ced992 100644 --- a/drivers/usb/device/usb_dw_registers.h +++ b/drivers/usb/device/usb_dw_registers.h @@ -198,7 +198,7 @@ BUILD_ASSERT(sizeof(struct usb_dw_reg) <= 0x0D00); * IN endpoint offsets 0x0900 + (0x20 * n), n = 0 .. x, * offset 0x0900 and 0x0B00 are hardcoded to control type. * - * REVISE: Better own defenitions for DIEPTCTL0, DOEPTCTL0... + * REVISE: Better own definitions for DIEPTCTL0, DOEPTCTL0... */ #define USB_DW_DEPCTL_EP_ENA BIT(31) #define USB_DW_DEPCTL_EP_DIS BIT(30) @@ -242,7 +242,7 @@ BUILD_ASSERT(sizeof(struct usb_dw_reg) <= 0x0D00); * IN at offsets 0x0910 + (0x20 * n), n = 0 .. x, * OUT at offsets 0x0B10 + (0x20 * n), n = 0 .. x * - * REVISE: Better own defenitions for DIEPTSIZ0, DOEPTSIZ0... + * REVISE: Better own definitions for DIEPTSIZ0, DOEPTSIZ0... */ #define USB_DW_DEPTSIZ_PKT_CNT_OFFSET 19 #define USB_DW_DIEPTSIZ0_PKT_CNT_MASK (0x3 << 19) diff --git a/drivers/usb/udc/udc_kinetis.c b/drivers/usb/udc/udc_kinetis.c index 188fca5f1e82803..961e8b3ba082296 100644 --- a/drivers/usb/udc/udc_kinetis.c +++ b/drivers/usb/udc/udc_kinetis.c @@ -40,7 +40,7 @@ LOG_MODULE_REGISTER(usbfsotg, CONFIG_UDC_DRIVER_LOG_LEVEL); #define USBFSOTG_REV 0x33 /* - * There is no real advantage to change control enpoint size + * There is no real advantage to change control endpoint size * but we can use it for testing UDC driver API and higher layers. */ #define USBFSOTG_MPS0 UDC_MPS0_64 @@ -498,7 +498,7 @@ static void xfer_work_handler(struct k_work *item) udc_submit_event(ev->dev, UDC_EVT_ERROR, err); } - /* Peek next transer */ + /* Peek next transfer */ if (ev->ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ev->dev, ev->ep)) { if (usbfsotg_xfer_next(ev->dev, ep_cfg) == 0) { udc_ep_set_busy(ev->dev, ev->ep, true); diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index ccae117c6f86752..4610aff19f874bd 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(udc_nrf, CONFIG_UDC_DRIVER_LOG_LEVEL); /* - * There is no real advantage to change control enpoint size + * There is no real advantage to change control endpoint size * but we can use it for testing UDC driver API and higher layers. */ #define UDC_NRF_MPS0 UDC_MPS0_64 diff --git a/drivers/wifi/esp32/Kconfig.esp32 b/drivers/wifi/esp32/Kconfig.esp32 index d746d113153ae8f..4d92bc8f37b647b 100644 --- a/drivers/wifi/esp32/Kconfig.esp32 +++ b/drivers/wifi/esp32/Kconfig.esp32 @@ -22,6 +22,15 @@ menuconfig WIFI_ESP32 if WIFI_ESP32 +config NET_TCP_WORKQ_STACK_SIZE + default 2048 + +config NET_RX_STACK_SIZE + default 2048 + +config NET_MGMT_EVENT_STACK_SIZE + default 2048 + config ESP32_WIFI_STA_AUTO_DHCPV4 bool "Automatically starts DHCP4 negotiation" depends on NET_DHCPV4 diff --git a/dts/arm/infineon/psoc6/mpns/CY8C6244LQI_S4D92.dtsi b/dts/arm/infineon/psoc6/mpns/CY8C6244LQI_S4D92.dtsi index 48795999d1bdfd1..c5561e9f074f93a 100644 --- a/dts/arm/infineon/psoc6/mpns/CY8C6244LQI_S4D92.dtsi +++ b/dts/arm/infineon/psoc6/mpns/CY8C6244LQI_S4D92.dtsi @@ -8,7 +8,7 @@ #include #include "../psoc6_04/psoc6_04.68-qfn.dtsi" -/delete-node/ &scb3; +/delete-node/ &flash1; &nvic { arm,num-irq-priority-bits = <3>; diff --git a/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi b/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi index 9b9e0a96542ec1c..251d4291a6f6d76 100644 --- a/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi +++ b/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi @@ -199,4 +199,147 @@ /omit-if-no-ref/ spi_sclk_p5_2_u2c0: spi_sclk_p5_2_u2c0 { pinmux = ; }; + + /omit-if-no-ref/ pwm_out_p0_12_ccu40_ch3: pwm_out_p0_12_ccu40_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_0_ccu40_ch3: pwm_out_p1_0_ccu40_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_1_ccu40_ch2: pwm_out_p1_1_ccu40_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_2_ccu40_ch1: pwm_out_p1_2_ccu40_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_3_ccu40_ch0: pwm_out_p1_3_ccu40_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_2_ccu41_ch3: pwm_out_p2_2_ccu41_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_3_ccu41_ch2: pwm_out_p2_3_ccu41_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_4_ccu41_ch1: pwm_out_p2_4_ccu41_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_5_ccu41_ch0: pwm_out_p2_5_ccu41_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_0_ccu42_ch0: pwm_out_p3_0_ccu42_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_3_ccu42_ch3: pwm_out_p3_3_ccu42_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_4_ccu42_ch2: pwm_out_p3_4_ccu42_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_5_ccu42_ch1: pwm_out_p3_5_ccu42_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_6_ccu42_ch0: pwm_out_p3_6_ccu42_ch0 { + pinmux = ; + }; + + /omit-if-no-ref/ pwm_out_p0_0_ccu80_ch2_low: pwm_out_p0_0_ccu80_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_1_ccu80_ch1_low: pwm_out_p0_1_ccu80_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_2_ccu80_ch0_low: pwm_out_p0_2_ccu80_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_3_ccu80_ch2_high: pwm_out_p0_3_ccu80_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_4_ccu80_ch1_high: pwm_out_p0_4_ccu80_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_5_ccu80_ch0_high: pwm_out_p0_5_ccu80_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_6_ccu80_ch3_high: pwm_out_p0_6_ccu80_ch3_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_9_ccu80_ch1_high: pwm_out_p0_9_ccu80_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_10_ccu80_ch0_high: pwm_out_p0_10_ccu80_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_11_ccu80_ch3_low: pwm_out_p0_11_ccu80_ch3_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_4_ccu80_ch3_low: pwm_out_p1_4_ccu80_ch3_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_4_ccu81_ch2_high: pwm_out_p1_4_ccu81_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_5_ccu80_ch2_low: pwm_out_p1_5_ccu80_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_5_ccu81_ch1_high: pwm_out_p1_5_ccu81_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_10_ccu81_ch2_low: pwm_out_p1_10_ccu81_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_11_ccu81_ch1_low: pwm_out_p1_11_ccu81_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_12_ccu81_ch0_low: pwm_out_p1_12_ccu81_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_13_ccu81_ch2_high: pwm_out_p1_13_ccu81_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_14_ccu81_ch1_high: pwm_out_p1_14_ccu81_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_15_ccu81_ch0_high: pwm_out_p1_15_ccu81_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_0_ccu81_ch2_low: pwm_out_p2_0_ccu81_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_1_ccu81_ch1_low: pwm_out_p2_1_ccu81_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_2_ccu81_ch0_low: pwm_out_p2_2_ccu81_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_6_ccu80_ch1_low: pwm_out_p2_6_ccu80_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_7_ccu80_ch0_low: pwm_out_p2_7_ccu80_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_8_ccu80_ch3_high: pwm_out_p2_8_ccu80_ch3_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_9_ccu80_ch2_high: pwm_out_p2_9_ccu80_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_14_ccu80_ch2_low: pwm_out_p2_14_ccu80_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_15_ccu80_ch1_low: pwm_out_p2_15_ccu80_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_0_ccu81_ch3_low: pwm_out_p5_0_ccu81_ch3_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_1_ccu81_ch3_high: pwm_out_p5_1_ccu81_ch3_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_2_ccu81_ch2_low: pwm_out_p5_2_ccu81_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_7_ccu81_ch0_high: pwm_out_p5_7_ccu81_ch0_high { + pinmux = ; + }; }; diff --git a/dts/arm/infineon/xmc4700_F144x2048-pinctrl.dtsi b/dts/arm/infineon/xmc4700_F144x2048-pinctrl.dtsi index dd03fad36174c30..1ef8961968dcda3 100644 --- a/dts/arm/infineon/xmc4700_F144x2048-pinctrl.dtsi +++ b/dts/arm/infineon/xmc4700_F144x2048-pinctrl.dtsi @@ -714,4 +714,237 @@ /omit-if-no-ref/ i2c_target_sda_p3_5_u2c1: i2c_target_sda_p3_5_u2c1 { pinmux = ; }; + + /omit-if-no-ref/ pwm_out_p0_12_ccu40_ch3: pwm_out_p0_12_ccu40_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_13_ccu40_ch2: pwm_out_p0_13_ccu40_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_14_ccu40_ch1: pwm_out_p0_14_ccu40_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_15_ccu40_ch0: pwm_out_p0_15_ccu40_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_0_ccu40_ch3: pwm_out_p1_0_ccu40_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_1_ccu40_ch2: pwm_out_p1_1_ccu40_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_2_ccu40_ch1: pwm_out_p1_2_ccu40_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_3_ccu40_ch0: pwm_out_p1_3_ccu40_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_2_ccu41_ch3: pwm_out_p2_2_ccu41_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_3_ccu41_ch2: pwm_out_p2_3_ccu41_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_4_ccu41_ch1: pwm_out_p2_4_ccu41_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_5_ccu41_ch0: pwm_out_p2_5_ccu41_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_0_ccu42_ch0: pwm_out_p3_0_ccu42_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_3_ccu42_ch3: pwm_out_p3_3_ccu42_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_4_ccu42_ch2: pwm_out_p3_4_ccu42_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_5_ccu42_ch1: pwm_out_p3_5_ccu42_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_6_ccu42_ch0: pwm_out_p3_6_ccu42_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_7_ccu41_ch3: pwm_out_p3_7_ccu41_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_8_ccu41_ch2: pwm_out_p3_8_ccu41_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_9_ccu41_ch1: pwm_out_p3_9_ccu41_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_10_ccu41_ch0: pwm_out_p3_10_ccu41_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_11_ccu42_ch3: pwm_out_p3_11_ccu42_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_12_ccu42_ch2: pwm_out_p3_12_ccu42_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p3_13_ccu42_ch1: pwm_out_p3_13_ccu42_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p4_3_ccu43_ch3: pwm_out_p4_3_ccu43_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p4_4_ccu43_ch2: pwm_out_p4_4_ccu43_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p4_5_ccu43_ch1: pwm_out_p4_5_ccu43_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p4_6_ccu43_ch0: pwm_out_p4_6_ccu43_ch0 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_2_ccu43_ch3: pwm_out_p6_2_ccu43_ch3 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_3_ccu43_ch2: pwm_out_p6_3_ccu43_ch2 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_4_ccu43_ch1: pwm_out_p6_4_ccu43_ch1 { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_5_ccu43_ch0: pwm_out_p6_5_ccu43_ch0 { + pinmux = ; + }; + + /omit-if-no-ref/ pwm_out_p0_0_ccu80_ch4_low: pwm_out_p0_0_ccu80_ch4_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_1_ccu80_ch2_low: pwm_out_p0_1_ccu80_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_2_ccu80_ch0_low: pwm_out_p0_2_ccu80_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_3_ccu80_ch4_high: pwm_out_p0_3_ccu80_ch4_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_4_ccu80_ch2_high: pwm_out_p0_4_ccu80_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_5_ccu80_ch0_high: pwm_out_p0_5_ccu80_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_6_ccu80_ch6_high: pwm_out_p0_6_ccu80_ch6_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_9_ccu80_ch3_high: pwm_out_p0_9_ccu80_ch3_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_10_ccu80_ch1_high: pwm_out_p0_10_ccu80_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p0_11_ccu80_ch6_low: pwm_out_p0_11_ccu80_ch6_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_4_ccu80_ch7_low: pwm_out_p1_4_ccu80_ch7_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_4_ccu81_ch4_high: pwm_out_p1_4_ccu81_ch4_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_5_ccu80_ch5_low: pwm_out_p1_5_ccu80_ch5_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_5_ccu81_ch2_high: pwm_out_p1_5_ccu81_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_10_ccu81_ch4_low: pwm_out_p1_10_ccu81_ch4_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_11_ccu81_ch2_low: pwm_out_p1_11_ccu81_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_12_ccu81_ch0_low: pwm_out_p1_12_ccu81_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_13_ccu81_ch4_high: pwm_out_p1_13_ccu81_ch4_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_14_ccu81_ch2_high: pwm_out_p1_14_ccu81_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p1_15_ccu81_ch0_high: pwm_out_p1_15_ccu81_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_0_ccu81_ch4_low: pwm_out_p2_0_ccu81_ch4_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_1_ccu81_ch2_low: pwm_out_p2_1_ccu81_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_2_ccu81_ch0_low: pwm_out_p2_2_ccu81_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_6_ccu80_ch3_low: pwm_out_p2_6_ccu80_ch3_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_7_ccu80_ch1_low: pwm_out_p2_7_ccu80_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_8_ccu80_ch7_high: pwm_out_p2_8_ccu80_ch7_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_9_ccu80_ch5_high: pwm_out_p2_9_ccu80_ch5_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_11_ccu80_ch5_high: pwm_out_p2_11_ccu80_ch5_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_12_ccu81_ch7_low: pwm_out_p2_12_ccu81_ch7_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_14_ccu80_ch4_low: pwm_out_p2_14_ccu80_ch4_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p2_15_ccu80_ch2_low: pwm_out_p2_15_ccu80_ch2_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_0_ccu81_ch7_low: pwm_out_p5_0_ccu81_ch7_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_1_ccu81_ch7_high: pwm_out_p5_1_ccu81_ch7_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_2_ccu81_ch5_low: pwm_out_p5_2_ccu81_ch5_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_3_ccu81_ch5_high: pwm_out_p5_3_ccu81_ch5_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_4_ccu81_ch3_low: pwm_out_p5_4_ccu81_ch3_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_5_ccu81_ch3_high: pwm_out_p5_5_ccu81_ch3_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_6_ccu81_ch1_low: pwm_out_p5_6_ccu81_ch1_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_7_ccu81_ch1_high: pwm_out_p5_7_ccu81_ch1_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_8_ccu80_ch0_low: pwm_out_p5_8_ccu80_ch0_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_9_ccu80_ch4_high: pwm_out_p5_9_ccu80_ch4_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_10_ccu80_ch2_high: pwm_out_p5_10_ccu80_ch2_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p5_11_ccu80_ch0_high: pwm_out_p5_11_ccu80_ch0_high { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_0_ccu81_ch6_low: pwm_out_p6_0_ccu81_ch6_low { + pinmux = ; + }; + /omit-if-no-ref/ pwm_out_p6_1_ccu81_ch6_high: pwm_out_p6_1_ccu81_ch6_high { + pinmux = ; + }; }; diff --git a/dts/arm/infineon/xmc4xxx.dtsi b/dts/arm/infineon/xmc4xxx.dtsi index 250876eb969d548..54a5744be152ae3 100644 --- a/dts/arm/infineon/xmc4xxx.dtsi +++ b/dts/arm/infineon/xmc4xxx.dtsi @@ -187,6 +187,48 @@ compatible = "infineon,xmc4xxx-temp"; status = "disabled"; }; + + pwm_ccu40: ccu40@4000c000 { + compatible = "infineon,xmc4xxx-ccu4-pwm"; + reg = <0x4000c000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ccu41: ccu41@40010000 { + compatible = "infineon,xmc4xxx-ccu4-pwm"; + reg = <0x40010000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ccu42: ccu42@40014000 { + compatible = "infineon,xmc4xxx-ccu4-pwm"; + reg = <0x40014000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ccu43: ccu43@48004000 { + compatible = "infineon,xmc4xxx-ccu4-pwm"; + reg = <0x48004000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ccu80: ccu80@40020000 { + compatible = "infineon,xmc4xxx-ccu8-pwm"; + reg = <0x40020000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ccu81: ccu81@40024000 { + compatible = "infineon,xmc4xxx-ccu8-pwm"; + reg = <0x40024000 0x4000>; + #pwm-cells = <3>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/nordic/nrf51822_qfaa.dtsi b/dts/arm/nordic/nrf51822_qfaa.dtsi index 3543b23c3388ef7..07fc5dd1cce9e32 100644 --- a/dts/arm/nordic/nrf51822_qfaa.dtsi +++ b/dts/arm/nordic/nrf51822_qfaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF51822-QFAA", "nordic,nRF51822", "nordic,nRF51", "simple-bus"; + compatible = "nordic,nrf51822-qfaa", "nordic,nrf51822", + "nordic,nrf51", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf51822_qfab.dtsi b/dts/arm/nordic/nrf51822_qfab.dtsi index cccfb48e5a26e0c..7fb4364d03791a7 100644 --- a/dts/arm/nordic/nrf51822_qfab.dtsi +++ b/dts/arm/nordic/nrf51822_qfab.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF51822-QFAB", "nordic,nRF51822", "nordic,nRF51", "simple-bus"; + compatible = "nordic,nrf51822-qfab", "nordic,nrf51822", + "nordic,nrf51", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf51822_qfac.dtsi b/dts/arm/nordic/nrf51822_qfac.dtsi index d348645ccc10547..59a2ed265e673d3 100644 --- a/dts/arm/nordic/nrf51822_qfac.dtsi +++ b/dts/arm/nordic/nrf51822_qfac.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF51822-QFAC", "nordic,nRF51822", "nordic,nRF51", "simple-bus"; + compatible = "nordic,nrf51822-qfac", "nordic,nrf51822", + "nordic,nrf51", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52805_caaa.dtsi b/dts/arm/nordic/nrf52805_caaa.dtsi index 5463725fbeaa00d..b7d24861893a92c 100644 --- a/dts/arm/nordic/nrf52805_caaa.dtsi +++ b/dts/arm/nordic/nrf52805_caaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52805-CAAA", "nordic,nRF52805", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52805-caaa", "nordic,nrf52805", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52810_qfaa.dtsi b/dts/arm/nordic/nrf52810_qfaa.dtsi index a505cfed2fce785..98fbd9a09369a47 100644 --- a/dts/arm/nordic/nrf52810_qfaa.dtsi +++ b/dts/arm/nordic/nrf52810_qfaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52810-QFAA", "nordic,nRF52810", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52810-qfaa", "nordic,nrf52810", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52811_qfaa.dtsi b/dts/arm/nordic/nrf52811_qfaa.dtsi index 1941dc41b82c86b..3bb1556eadb7946 100644 --- a/dts/arm/nordic/nrf52811_qfaa.dtsi +++ b/dts/arm/nordic/nrf52811_qfaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52811-QFAA", "nordic,nRF52811", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52811-qfaa", "nordic,nrf52811", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52820_qdaa.dtsi b/dts/arm/nordic/nrf52820_qdaa.dtsi index d2008dcbe7c20fc..c1d4a5a95f5aead 100644 --- a/dts/arm/nordic/nrf52820_qdaa.dtsi +++ b/dts/arm/nordic/nrf52820_qdaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52820-QDAA", "nordic,nRF52820", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52820-qdaa", "nordic,nrf52820", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52832_ciaa.dtsi b/dts/arm/nordic/nrf52832_ciaa.dtsi index f46f2274690de27..88f16574bbb920e 100644 --- a/dts/arm/nordic/nrf52832_ciaa.dtsi +++ b/dts/arm/nordic/nrf52832_ciaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52832-CIAA", "nordic,nRF52832", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52832-ciaa", "nordic,nrf52832", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52832_qfaa.dtsi b/dts/arm/nordic/nrf52832_qfaa.dtsi index 42b139691dfd8b1..2943de6d1155bda 100644 --- a/dts/arm/nordic/nrf52832_qfaa.dtsi +++ b/dts/arm/nordic/nrf52832_qfaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52832-QFAA", "nordic,nRF52832", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52832-qfaa", "nordic,nrf52832", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52832_qfab.dtsi b/dts/arm/nordic/nrf52832_qfab.dtsi index 1e00142ff27898d..fe1605394e7208c 100644 --- a/dts/arm/nordic/nrf52832_qfab.dtsi +++ b/dts/arm/nordic/nrf52832_qfab.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52832-QFAB", "nordic,nRF52832", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52832-qfab", "nordic,nrf52832", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52833_qdaa.dtsi b/dts/arm/nordic/nrf52833_qdaa.dtsi new file mode 100644 index 000000000000000..7f9be6f22550990 --- /dev/null +++ b/dts/arm/nordic/nrf52833_qdaa.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(512)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(128)>; +}; + +/ { + soc { + compatible = "nordic,nrf52833-qdaa", "nordic,nrf52833", + "nordic,nrf52", "simple-bus"; + }; +}; diff --git a/dts/arm/nordic/nrf52833_qiaa.dtsi b/dts/arm/nordic/nrf52833_qiaa.dtsi index 71efb1cad5e0269..68eabb08bcf7aa0 100644 --- a/dts/arm/nordic/nrf52833_qiaa.dtsi +++ b/dts/arm/nordic/nrf52833_qiaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52833-QIAA", "nordic,nRF52833", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52833-qiaa", "nordic,nrf52833", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf52840_qfaa.dtsi b/dts/arm/nordic/nrf52840_qfaa.dtsi new file mode 100644 index 000000000000000..4483bbd6a434338 --- /dev/null +++ b/dts/arm/nordic/nrf52840_qfaa.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +/ { + soc { + compatible = "nordic,nrf52840-qfaa", "nordic,nrf52840", + "nordic,nrf52", "simple-bus"; + }; + + /delete-node/ &usbd; +}; diff --git a/dts/arm/nordic/nrf52840_qiaa.dtsi b/dts/arm/nordic/nrf52840_qiaa.dtsi index d460f0582ccaca0..7007fa4dbf487ec 100644 --- a/dts/arm/nordic/nrf52840_qiaa.dtsi +++ b/dts/arm/nordic/nrf52840_qiaa.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF52840-QIAA", "nordic,nRF52840", "nordic,nRF52", "simple-bus"; + compatible = "nordic,nrf52840-qiaa", "nordic,nrf52840", + "nordic,nrf52", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi b/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi index 3e8b110e583772b..9a730a3940688b9 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi @@ -21,6 +21,7 @@ / { soc { - compatible = "nordic,nRF5340-CPUAPP-QKAA", "nordic,nRF5340-CPUAPP", "nordic,nRF53", "simple-bus"; + compatible = "nordic,nrf5340-cpuapp-qkaa", "nordic,nrf5340-cpuapp", + "nordic,nrf53", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi b/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi index 63e239b00183e6b..e4f38769d8fac36 100644 --- a/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi +++ b/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi @@ -21,6 +21,7 @@ / { soc { - compatible = "nordic,nRF5340-CPUAPP-QKAA", "nordic,nRF5340-CPUAPP", "nordic,nRF53", "simple-bus"; + compatible = "nordic,nrf5340-cpuapp-qkaa", "nordic,nrf5340-cpuapp", + "nordic,nrf53", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf5340_cpunet_qkaa.dtsi b/dts/arm/nordic/nrf5340_cpunet_qkaa.dtsi index 3f30d43a8c91958..c8047ebf9051fe1 100644 --- a/dts/arm/nordic/nrf5340_cpunet_qkaa.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet_qkaa.dtsi @@ -25,6 +25,7 @@ / { soc { - compatible = "nordic,nRF5340-CPUNET-QKAA", "nordic,nRF5340-CPUNET", "nordic,nRF53", "simple-bus"; + compatible = "nordic,nrf5340-cpunet-qkaa", "nordic,nrf5340-cpunet", + "nordic,nrf53", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf9160_sica.dtsi b/dts/arm/nordic/nrf9160_sica.dtsi index e04347fc026186f..15096534016d082 100644 --- a/dts/arm/nordic/nrf9160_sica.dtsi +++ b/dts/arm/nordic/nrf9160_sica.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF9160-SICA", "nordic,nRF9160", "nordic,nRF91", "simple-bus"; + compatible = "nordic,nrf9160-sica", "nordic,nrf9160", + "nordic,nrf91", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf9160ns_sica.dtsi b/dts/arm/nordic/nrf9160ns_sica.dtsi index 7e35dd76b62f682..c6adbaa7ca2ff1d 100644 --- a/dts/arm/nordic/nrf9160ns_sica.dtsi +++ b/dts/arm/nordic/nrf9160ns_sica.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF9160-SICA", "nordic,nRF9160", "nordic,nRF91", "simple-bus"; + compatible = "nordic,nrf9160-sica", "nordic,nrf9160", + "nordic,nrf91", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf9161_sica.dtsi b/dts/arm/nordic/nrf9161_sica.dtsi index d6ae975ceaad07a..113ee14617c2c31 100644 --- a/dts/arm/nordic/nrf9161_sica.dtsi +++ b/dts/arm/nordic/nrf9161_sica.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF9161-SICA", "nordic,nRF9120", "nordic,nRF91", "simple-bus"; + compatible = "nordic,nrf9161-sica", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; }; }; diff --git a/dts/arm/nordic/nrf9161ns_sica.dtsi b/dts/arm/nordic/nrf9161ns_sica.dtsi index 1ff4f1d9ee9aca3..479021d11070836 100644 --- a/dts/arm/nordic/nrf9161ns_sica.dtsi +++ b/dts/arm/nordic/nrf9161ns_sica.dtsi @@ -17,6 +17,7 @@ / { soc { - compatible = "nordic,nRF9161-SICA", "nordic,nRF9120", "nordic,nRF91", "simple-bus"; + compatible = "nordic,nrf9161-sica", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; }; }; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index 9326b20c9cf79ac..e0ad94d0894e548 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -28,6 +28,7 @@ device_type = "cpu"; compatible = "arm,cortex-m4f"; reg = <0>; + cpu-power-states = <&idle &stop &pstop1 &pstop2>; }; power-states { diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 5f2f373e618ab64..798f0d123e58714 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { @@ -423,6 +424,111 @@ #size-cells = <0>; status = "disabled"; }; + + flexcan0: can@40304000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40304000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANA_CLK>; + clk-source = <0>; + interrupts = <109 0>, <110 0>, <111 0>, <112 0>; + interrupt-names = "ored", "ored_0_31_mb", + "ored_32_63_mb", "ored_64_95_mb"; + status = "disabled"; + }; + + flexcan1: can@40308000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40308000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANA_CLK>; + clk-source = <0>; + interrupts = <113 0>, <114 0>, <115 0>; + interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; + status = "disabled"; + }; + + flexcan2: can@4030c000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x4030c000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANA_CLK>; + clk-source = <0>; + interrupts = <116 0>, <117 0>, <118 0>; + interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; + status = "disabled"; + }; + + flexcan3: can@40310000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40310000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANB_CLK>; + clk-source = <0>; + interrupts = <119 0>, <120 0>; + interrupt-names = "ored", "ored_0_31_mb"; + status = "disabled"; + }; + + flexcan4: can@40314000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40314000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANB_CLK>; + clk-source = <0>; + interrupts = <121 0>, <122 0>; + interrupt-names = "ored", "ored_0_31_mb"; + status = "disabled"; + }; + + flexcan5: can@40318000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x40318000 0x4000>; + clocks = <&clock NXP_S32_FLEXCANB_CLK>; + clk-source = <0>; + interrupts = <123 0>, <124 0>; + interrupt-names = "ored", "ored_0_31_mb"; + status = "disabled"; + }; + + lpi2c0: i2c@40350000 { + compatible = "nxp,imx-lpi2c"; + reg = <0x40350000 0x10000>; + clocks = <&clock NXP_S32_LPI2C0_CLK>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <161 0>; + status = "disabled"; + }; + + lpi2c1: i2c@40354000 { + compatible = "nxp,imx-lpi2c"; + reg = <0x40354000 0x10000>; + clocks = <&clock NXP_S32_LPI2C1_CLK>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <162 0>; + status = "disabled"; + }; + + adc0: adc@400a0000 { + compatible = "nxp,s32-adc-sar"; + reg = <0x400a0000 0x1000>; + interrupts = <180 0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc1: adc@400a4000 { + compatible = "nxp,s32-adc-sar"; + reg = <0x400a4000 0x1000>; + interrupts = <181 0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc2: adc@400a8000 { + compatible = "nxp,s32-adc-sar"; + reg = <0x400a8000 0x1000>; + interrupts = <182 0>; + #io-channel-cells = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/quicklogic/quicklogic_eos_s3.dtsi b/dts/arm/quicklogic/quicklogic_eos_s3.dtsi index 8d3f3998e3091ae..f29b1c482ffdc3c 100644 --- a/dts/arm/quicklogic/quicklogic_eos_s3.dtsi +++ b/dts/arm/quicklogic/quicklogic_eos_s3.dtsi @@ -64,6 +64,11 @@ pin-secondary-config = <0x00>; gpio-controller; }; + + pinctrl: pinctrl@40004c00 { + compatible = "quicklogic,eos-s3-pinctrl"; + reg = <0x40004c00 0x1b0>; + }; }; }; diff --git a/dts/arm/silabs/efm32_jg_pg_12b.dtsi b/dts/arm/silabs/efm32_jg_pg_12b.dtsi index 59680df2c55916b..ccf8b8acf4d5b8c 100644 --- a/dts/arm/silabs/efm32_jg_pg_12b.dtsi +++ b/dts/arm/silabs/efm32_jg_pg_12b.dtsi @@ -253,6 +253,14 @@ status = "disabled"; #io-channel-cells = <1>; }; + + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; }; }; diff --git a/dts/arm/silabs/efr32bg2x.dtsi b/dts/arm/silabs/efr32bg2x.dtsi index deee10ccdde8012..e1f3726e4297670 100644 --- a/dts/arm/silabs/efr32bg2x.dtsi +++ b/dts/arm/silabs/efr32bg2x.dtsi @@ -36,7 +36,7 @@ * has implications on system performance. Read * KConfig documentation entry before enabling it. */ - cpu-power-states = <&pstate_em1>; + cpu-power-states = <&pstate_em1 &pstate_em2 &pstate_em3>; }; power-states { @@ -75,19 +75,6 @@ min-residency-us = <20000>; exit-latency-us = <2000>; }; - - /* - * EM4 does not preserve CPU or RAM state, so system runs - * through a cold boot upon wake up. BURTC can wake up the - * system from EM4 but that has to be manually configured - * by the application in BURTC registers. - */ - pstate_em4: em4 { - compatible = "zephyr,power-state"; - power-state-name = "soft-off"; - min-residency-us = <100000>; - exit-latency-us = <80000>; - }; }; }; diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index bfc61d8cfea622d..8c9120472ff612b 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -33,6 +33,7 @@ device_type = "cpu"; compatible = "arm,cortex-m0+"; reg = <0>; + cpu-power-states = <&stop0 &stop1>; }; power-states { diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 32d6c4d5f87a65a..33d46e66af8e1e5 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -32,6 +32,7 @@ device_type = "cpu"; compatible = "arm,cortex-m4f"; reg = <0>; + cpu-power-states = <&stop0 &stop1>; }; power-states { diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index 1b6452119fe41cb..b37f95def3ed716 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -32,6 +32,7 @@ device_type = "cpu"; compatible = "arm,cortex-m4f"; reg = <0>; + cpu-power-states = <&stop0 &stop1 &stop2>; }; power-states { diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 28c7d87491bed9e..e5b9f1b7a622d90 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -35,6 +35,7 @@ reg = <0>; #address-cells = <1>; #size-cells = <1>; + cpu-power-states = <&stop0 &stop1 &stop2>; mpu: mpu@e000ed90 { compatible = "arm,armv8m-mpu"; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 91f5822673b992f..28b5f38d9acb942 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -36,6 +36,7 @@ reg = <0>; #address-cells = <1>; #size-cells = <1>; + cpu-power-states = <&stop0 &stop1 &stop2>; mpu: mpu@e000ed90 { compatible = "arm,armv8m-mpu"; diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index 84f459dcf6f1364..6f9f0ba48581271 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -31,6 +31,7 @@ device_type = "cpu"; compatible = "arm,cortex-m4f"; reg = <0>; + cpu-power-states = <&stop0 &stop1 &stop2>; }; power-states { diff --git a/dts/bindings/adc/nxp,s32-adc-sar.yaml b/dts/bindings/adc/nxp,s32-adc-sar.yaml new file mode 100644 index 000000000000000..f7201698f7932c3 --- /dev/null +++ b/dts/bindings/adc/nxp,s32-adc-sar.yaml @@ -0,0 +1,49 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP S32 ADC SAR controller + +compatible: "nxp,s32-adc-sar" + +include: [adc-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + vref-mv: + type: int + default: 3300 + description: Indicates the reference voltage of the ADC in mV. + + group-channel: + type: string + required: true + enum: + - "precision" + - "standard" + - "external" + description: The ADC group channel. + + high-speed: + type: boolean + description: Use high speed during conversion, calibration. + + callback-select: + type: string + default: "normal-end-conversion" + enum: + - "normal-end-conversion" + - "normal-end-chain" + description: | + Select normal end conversion callback to reduce interrupt handling time. + Select normal end chain callback to reduce the number of interrupt occurrences. + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/bindings/cpu/intel,ish.yaml b/dts/bindings/cpu/intel,ish.yaml new file mode 100644 index 000000000000000..10ac4b2eeb9d1b2 --- /dev/null +++ b/dts/bindings/cpu/intel,ish.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: INTEL ISH CPU + +compatible: "intel,ish" + +include: cpu.yaml diff --git a/dts/bindings/display/himax,hx8394.yaml b/dts/bindings/display/himax,hx8394.yaml new file mode 100644 index 000000000000000..c137ad60fb2d582 --- /dev/null +++ b/dts/bindings/display/himax,hx8394.yaml @@ -0,0 +1,24 @@ +# +# Copyright 2023 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Himax HX8394 Panel + +compatible: "himax,hx8394" + +include: [mipi-dsi-device.yaml, display-controller.yaml] + +properties: + reset-gpios: + type: phandle-array + description: | + The RESX pin is asserted to disable the sensor causing a hard + reset. The sensor receives this as an active-low signal. + + bl-gpios: + type: phandle-array + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. diff --git a/dts/bindings/ethernet/atmel,gmac-common.yaml b/dts/bindings/ethernet/atmel,gmac-common.yaml index 95e063323178660..93cbb4edc4476a9 100644 --- a/dts/bindings/ethernet/atmel,gmac-common.yaml +++ b/dts/bindings/ethernet/atmel,gmac-common.yaml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 include: - - name: ethernet.yaml + - name: ethernet-controller.yaml - name: pinctrl-device.yaml properties: diff --git a/dts/bindings/ethernet/espressif,esp32-eth.yaml b/dts/bindings/ethernet/espressif,esp32-eth.yaml index 35aa4a6f7a6e911..b3021da7ca3366d 100644 --- a/dts/bindings/ethernet/espressif,esp32-eth.yaml +++ b/dts/bindings/ethernet/espressif,esp32-eth.yaml @@ -6,7 +6,7 @@ description: ESP32 Ethernet compatible: "espressif,esp32-eth" include: - - name: ethernet.yaml + - name: ethernet-controller.yaml properties: phy-connection-type: diff --git a/dts/bindings/ethernet/ethernet.yaml b/dts/bindings/ethernet/ethernet-controller.yaml similarity index 86% rename from dts/bindings/ethernet/ethernet.yaml rename to dts/bindings/ethernet/ethernet-controller.yaml index cd30125ea15daa4..a5a9cec2700c6d9 100644 --- a/dts/bindings/ethernet/ethernet.yaml +++ b/dts/bindings/ethernet/ethernet-controller.yaml @@ -9,6 +9,7 @@ properties: local-mac-address: type: uint8-array description: Specifies the MAC address that was assigned to the network device + zephyr,random-mac-address: type: boolean description: | @@ -21,3 +22,8 @@ properties: It is driver specific how the OUI octets are handled. If set we ignore any setting of the local-mac-address property. + + phy-handle: + type: phandle + description: | + Specifies a reference to a node representing a PHY device. diff --git a/dts/bindings/ethernet/litex,eth0.yaml b/dts/bindings/ethernet/litex,eth0.yaml index 50885777b197173..decdc96a48edfb9 100644 --- a/dts/bindings/ethernet/litex,eth0.yaml +++ b/dts/bindings/ethernet/litex,eth0.yaml @@ -5,7 +5,7 @@ description: LiteX Ethernet compatible: "litex,eth0" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/microchip,enc28j60.yaml b/dts/bindings/ethernet/microchip,enc28j60.yaml index 7fd0c46bc4c1977..f456b3c14faa137 100644 --- a/dts/bindings/ethernet/microchip,enc28j60.yaml +++ b/dts/bindings/ethernet/microchip,enc28j60.yaml @@ -5,7 +5,7 @@ description: ENC28J60 standalone 10BASE-T Ethernet controller with SPI interface compatible: "microchip,enc28j60" -include: [spi-device.yaml, ethernet.yaml] +include: [spi-device.yaml, ethernet-controller.yaml] properties: int-gpios: diff --git a/dts/bindings/ethernet/microchip,enc424j600.yaml b/dts/bindings/ethernet/microchip,enc424j600.yaml index 767684f3a720127..799917fc4da5874 100644 --- a/dts/bindings/ethernet/microchip,enc424j600.yaml +++ b/dts/bindings/ethernet/microchip,enc424j600.yaml @@ -6,7 +6,7 @@ description: | compatible: "microchip,enc424j600" -include: [spi-device.yaml, ethernet.yaml] +include: [spi-device.yaml, ethernet-controller.yaml] properties: int-gpios: diff --git a/dts/bindings/ethernet/nxp,kinetis-ethernet.yaml b/dts/bindings/ethernet/nxp,kinetis-ethernet.yaml index df95dabf8fa2b04..84e0e009f7a0c12 100644 --- a/dts/bindings/ethernet/nxp,kinetis-ethernet.yaml +++ b/dts/bindings/ethernet/nxp,kinetis-ethernet.yaml @@ -5,7 +5,7 @@ description: NXP Kinetis Ethernet compatible: "nxp,kinetis-ethernet" -include: ["ethernet.yaml", "ethernet,fixed-link.yaml", "pinctrl-device.yaml"] +include: ["ethernet-controller.yaml", "ethernet,fixed-link.yaml", "pinctrl-device.yaml"] properties: reg: diff --git a/dts/bindings/ethernet/nxp,s32-netc-psi.yaml b/dts/bindings/ethernet/nxp,s32-netc-psi.yaml index f9296a2d52bfb30..4ab34c506138f64 100644 --- a/dts/bindings/ethernet/nxp,s32-netc-psi.yaml +++ b/dts/bindings/ethernet/nxp,s32-netc-psi.yaml @@ -5,7 +5,7 @@ description: NXP S32 NETC Physical Station Interface (PSI) compatible: "nxp,s32-netc-psi" -include: [ethernet.yaml, pinctrl-device.yaml] +include: [ethernet-controller.yaml, pinctrl-device.yaml] properties: reg: @@ -22,11 +22,8 @@ properties: mbox-names: required: true - phy-dev: + phy-handle: required: true - type: phandle - description: | - Ethernet PHY device managed by this network interface. vsis: type: array diff --git a/dts/bindings/ethernet/nxp,s32-netc-vsi.yaml b/dts/bindings/ethernet/nxp,s32-netc-vsi.yaml index 2201232589c6125..c2174b21f9a2c70 100644 --- a/dts/bindings/ethernet/nxp,s32-netc-vsi.yaml +++ b/dts/bindings/ethernet/nxp,s32-netc-vsi.yaml @@ -5,7 +5,7 @@ description: NXP S32 NETC Virtual Station Interface (VSI) compatible: "nxp,s32-netc-vsi" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/siemens,ivshmem-eth.yaml b/dts/bindings/ethernet/siemens,ivshmem-eth.yaml index 2c16b40c403bfe7..6bd4de0a13f0ba0 100644 --- a/dts/bindings/ethernet/siemens,ivshmem-eth.yaml +++ b/dts/bindings/ethernet/siemens,ivshmem-eth.yaml @@ -5,7 +5,7 @@ description: IVSHMEM Ethernet compatible: "siemens,ivshmem-eth" -include: ethernet.yaml +include: ethernet-controller.yaml properties: diff --git a/dts/bindings/ethernet/silabs,gecko-ethernet.yaml b/dts/bindings/ethernet/silabs,gecko-ethernet.yaml index 1445669f41f5364..136e4cc6280f444 100644 --- a/dts/bindings/ethernet/silabs,gecko-ethernet.yaml +++ b/dts/bindings/ethernet/silabs,gecko-ethernet.yaml @@ -6,7 +6,7 @@ description: SiLabs Gecko Ethernet compatible: "silabs,gecko-ethernet" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/snps,designware-ethernet.yaml b/dts/bindings/ethernet/snps,designware-ethernet.yaml index b610a7c8a02b0fb..734eb1cced7c8b5 100644 --- a/dts/bindings/ethernet/snps,designware-ethernet.yaml +++ b/dts/bindings/ethernet/snps,designware-ethernet.yaml @@ -5,7 +5,7 @@ description: Synopsys DesignWare Ethernet compatible: "snps,designware-ethernet" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/snps,ethernet-cyclonev.yaml b/dts/bindings/ethernet/snps,ethernet-cyclonev.yaml index e0497c08c7edbc7..9aa0c94039fb2dc 100644 --- a/dts/bindings/ethernet/snps,ethernet-cyclonev.yaml +++ b/dts/bindings/ethernet/snps,ethernet-cyclonev.yaml @@ -5,7 +5,7 @@ description: Ethernet driver for Cyclone V SoC compatible: "snps,ethernet-cyclonev" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/st,stm32-ethernet.yaml b/dts/bindings/ethernet/st,stm32-ethernet.yaml index 4420006b9000cda..b0e5665f3374f7b 100644 --- a/dts/bindings/ethernet/st,stm32-ethernet.yaml +++ b/dts/bindings/ethernet/st,stm32-ethernet.yaml @@ -5,7 +5,7 @@ description: ST STM32 Ethernet compatible: "st,stm32-ethernet" -include: [ethernet.yaml, pinctrl-device.yaml] +include: [ethernet-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/ethernet/ti,stellaris-ethernet.yaml b/dts/bindings/ethernet/ti,stellaris-ethernet.yaml index f9310d773c64abf..8a60fba0ce2cdcf 100644 --- a/dts/bindings/ethernet/ti,stellaris-ethernet.yaml +++ b/dts/bindings/ethernet/ti,stellaris-ethernet.yaml @@ -5,7 +5,7 @@ description: TI Stellaris Ethernet compatible: "ti,stellaris-ethernet" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/wiznet,w5500.yaml b/dts/bindings/ethernet/wiznet,w5500.yaml index b37db750d1c443d..1490f0763b94d3b 100644 --- a/dts/bindings/ethernet/wiznet,w5500.yaml +++ b/dts/bindings/ethernet/wiznet,w5500.yaml @@ -5,7 +5,7 @@ description: W5500 standalone 10/100BASE-T Ethernet controller with SPI interfac compatible: "wiznet,w5500" -include: [spi-device.yaml, ethernet.yaml] +include: [spi-device.yaml, ethernet-controller.yaml] properties: int-gpios: diff --git a/dts/bindings/ethernet/xlnx,gem.yaml b/dts/bindings/ethernet/xlnx,gem.yaml index 0b1727f64de8faa..a4c16094b08d0d3 100644 --- a/dts/bindings/ethernet/xlnx,gem.yaml +++ b/dts/bindings/ethernet/xlnx,gem.yaml @@ -7,7 +7,7 @@ description: Xilinx GEM Ethernet controller compatible: "xlnx,gem" -include: ethernet.yaml +include: ethernet-controller.yaml properties: reg: diff --git a/dts/bindings/ethernet/zephyr,cdc-ecm-ethernet.yaml b/dts/bindings/ethernet/zephyr,cdc-ecm-ethernet.yaml index 6a19507a21f6e5e..24f670f9afb8a90 100644 --- a/dts/bindings/ethernet/zephyr,cdc-ecm-ethernet.yaml +++ b/dts/bindings/ethernet/zephyr,cdc-ecm-ethernet.yaml @@ -5,7 +5,7 @@ description: USB CDC ECM virtual Ethernet controller compatible: "zephyr,cdc-ecm-ethernet" -include: ethernet.yaml +include: ethernet-controller.yaml properties: remote-mac-address: diff --git a/dts/bindings/gpio/st-morpho-header.yaml b/dts/bindings/gpio/st-morpho-header.yaml index fb6568d2f11f9e4..c1726b7a2d66dd6 100644 --- a/dts/bindings/gpio/st-morpho-header.yaml +++ b/dts/bindings/gpio/st-morpho-header.yaml @@ -4,9 +4,10 @@ description: | GPIO pins exposed on ST Morpho connector. - The ST morpho connector consists in male pin headers (CN7 and CN10) accessible - on both sides of any Nucleo board. They can be used to connect shields. All - signals and power pins of the STM32 are available on the ST morpho connector. + The ST morpho connector consists in male pin headers (CN7 and CN10 in case of + Nucleo-64, CN11 and CN12 in case of Nucleo-144) accessible on both sides of + any Nucleo board. They can be used to connect shields. All signals and power + pins of the STM32 are available on the ST morpho connector. compatible: "st-morpho-header" diff --git a/dts/bindings/interrupt-controller/nxp,irqsteer-intc.yaml b/dts/bindings/interrupt-controller/nxp,irqsteer-intc.yaml new file mode 100644 index 000000000000000..03b5d3b39e036ea --- /dev/null +++ b/dts/bindings/interrupt-controller/nxp,irqsteer-intc.yaml @@ -0,0 +1,13 @@ +description: i.MX DSP interrupt controller + +compatible: "nxp,irqsteer-intc" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml index 4698d7f85150f58..839506f33ea0375 100644 --- a/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml +++ b/dts/bindings/interrupt-controller/sifive,plic-1.0.0.yaml @@ -12,3 +12,7 @@ properties: type: int description: Number of external interrupts supported required: true + riscv,trigger-reg-offset: + type: int + default: 4224 + description: Offset of the trigger type register if supported diff --git a/dts/bindings/mbox/andestech,plic-sw.yaml b/dts/bindings/mbox/andestech,plic-sw.yaml new file mode 100644 index 000000000000000..f054d8c206b6833 --- /dev/null +++ b/dts/bindings/mbox/andestech,plic-sw.yaml @@ -0,0 +1,24 @@ +# +# Copyright (c) 2022, Andes Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: | + This is a representation of AndesTech PLIC-SW node + +compatible: "andestech,plic-sw" + +include: [base.yaml, mailbox-controller.yaml] + +properties: + reg: + required: true + + channel-max: + type: int + required: true + description: Supported channels max + +mbox-cells: + - channel diff --git a/dts/bindings/pinctrl/pincfg-node.yaml b/dts/bindings/pinctrl/pincfg-node.yaml index 1f66639dc8d5dbf..9c3e126698c267b 100644 --- a/dts/bindings/pinctrl/pincfg-node.yaml +++ b/dts/bindings/pinctrl/pincfg-node.yaml @@ -63,14 +63,12 @@ properties: input-enable: type: boolean description: | - enable input on pin (no effect on output, such as enabling an input - buffer) + enable input on pin (e.g. enable an input buffer, no effect on output) input-disable: type: boolean description: | - disable input on pin (no effect on output, such as disabling an input - buffer) + disable input on pin (e.g. disable an input buffer, no effect on output) input-schmitt-enable: type: boolean @@ -99,13 +97,13 @@ properties: output-disable: type: boolean - description: disable output on a pin (such as disable an output buffer) + description: disable output on a pin (e.g. disable an output buffer) output-enable: type: boolean description: | - enable output on a pin without actively driving it (such as enabling - an output buffer) + enable output on a pin without actively driving it (e.g. enable an output + buffer) output-low: type: boolean diff --git a/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml b/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml new file mode 100644 index 000000000000000..cd9cd5ac532403e --- /dev/null +++ b/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml @@ -0,0 +1,75 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: | + Quicklogic EOS S3 IO MUX binding covers the 46 IOMUX_PAD_x_CTRL registers + that can be used to set the direction and the function of a pad. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with IO function and pin number. + + For example, setting pins 44 and 45 for use as UART would look like this: + + #include + + &pinctrl { + uart0_rx_default: uart0_rx_default { + pinmux = ; + input-enable; + }; + uart0_tx_default: uart0_tx_default { + pinmux = ; + output-enable; + }; + }; + +compatible: "quicklogic,eos-s3-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the SiFive FE310 pins + configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - input-enable + - output-enable + - bias-pull-up + - bias-pull-down + - bias-high-impedance + - input-schmitt-enable + - drive-strength + properties: + pinmux: + required: true + type: array + description: | + Quicklogic EOS S3 pin's configuration (pin, IO function). + slew-rate: + description: | + The default value "slow" matches the power-on reset value. + default: "slow" + type: string + enum: + - "slow" + - "fast" + quicklogic,control-selection: + description: | + Control selection for IO output. + It's either controlled from registers of the A0 always-on domain, + fabric-controlled for signaling with FPGA, + or other-controller for bidirectional signals. + The default value "a0registers" matches the power-on reset value. + default: "a0registers" + type: string + enum: + - "a0registers" + - "others" + - "fabric" diff --git a/dts/bindings/pinctrl/ti,cc13xx-cc26xx-pinctrl.yaml b/dts/bindings/pinctrl/ti,cc13xx-cc26xx-pinctrl.yaml index 5c78d9c561eeb23..fcc24e8928be04a 100644 --- a/dts/bindings/pinctrl/ti,cc13xx-cc26xx-pinctrl.yaml +++ b/dts/bindings/pinctrl/ti,cc13xx-cc26xx-pinctrl.yaml @@ -26,8 +26,10 @@ description: | - bias-pull-up: Enable pull-up resistor. - drive-open-drain: Output driver is open-drain. - drive-open-drain: Output driver is open-source. + - drive-strength: Minimum current that can be sourced from the pin. - input-enable: enable input. - input-schmitt-enable: enable input schmitt circuit. + - ti,input-edge-detect: enable and configure edge detection interrupts An example for CC13XX family, include the chip level pinctrl DTSI file in the board level DTS: @@ -57,6 +59,27 @@ description: | }; }; + To configure an input pin with edge detection (e.g. to count pulses): + + &pinctrl { + gpt0_edge_counter: gpt0_edge_counter { + pinmux = <15 IOC_PORT_MCU_PORT_EVENT0>; + input-enable; + bias-pull-up; + ti,input-edge-detect = ; + }; + }; + + To configure an output pin (e.g. for PWM output): + + &pinctrl { + gpt0_pwm: gpt0_pwm { + pinmux = <16 IOC_PORT_MCU_PORT_EVENT1>; + bias-disable; + drive-strength = <8>; /* in mA */ + }; + }; + compatible: "ti,cc13xx-cc26xx-pinctrl" include: base.yaml @@ -78,6 +101,7 @@ child-binding: - bias-pull-up - drive-open-drain - drive-open-source + - drive-strength - input-enable - input-schmitt-enable @@ -87,3 +111,26 @@ child-binding: type: array description: | CC13XX/CC26XX pin's configuration (IO pin, IO function). + + drive-strength: + enum: + - 2 + - 4 + - 8 + default: 2 + description: | + The drive strength controls the minimum output driver strength of an I/O pin + configured as an output. + 2: min 2 mA (SoC default) + 4: min 4 mA + 8: min 8 mA for for double drive strength IOs, min 4 mA for normal IOs + + ti,input-edge-detect: + type: int + default: 0 # no edge detection + description: | + Enables or disables the edge detection interrupt and configures it: + IOC_NO_EDGE: No edge detection (SoC default) + IOC_FALLING_EDGE: Edge detection on falling edge + IOC_RISING_EDGE: Edge detection on rising edge + IOC_BOTH_EDGES: Edge detection on both edges diff --git a/dts/bindings/pwm/infineon,xmc4xxx-ccu4-pwm.yaml b/dts/bindings/pwm/infineon,xmc4xxx-ccu4-pwm.yaml new file mode 100644 index 000000000000000..408f9b348d0a66f --- /dev/null +++ b/dts/bindings/pwm/infineon,xmc4xxx-ccu4-pwm.yaml @@ -0,0 +1,84 @@ +# Copyright (c) 2023 SLB +# SPDX-License-Identifier: Apache-2.0 + +description: | + Infineon XMC4XXX PWM Capture Compare Unit 4 (CCU4) module + + The are four CCU4 modules with dts node labels: + pwm_ccu40, pwm_ccu41, pwm_ccu42, pwm_ccu43. + Each module has four slices and each slice has one channel. + A channel is connected to a particular gpio pin, which are defined + using pinctrl in: + dts/arm/infineon/xmc4xxx_xxx-pinctrl.dtsi + + The CCU4 modules uses the CCU clock source. Each slice applies a separate + prescalar which divides the clock. + + Device tree example: + A node can define a 'pwm' field, usually referenced in a 'pwms' + property, where the entries include the PWM module phandle, + channel number, pulse period (in nanoseconds or set using + PWM_XX() macros), and a channela + flag (PWM_POLARITY_NORMAL/PWM_POLARITY_INVERTED). + + The pwm ccu4 node must define the slice-prescaler values and the pinctrl nodes: + &pwm_ccu40 { + slice-prescaler = <15 15 15 15>; + pinctrl-0 = <&pwm_out_p1_1_ccu40_ch2>; + pinctrl-names = "default"; + }; + + Another node can reference the PWM as follows: + &test_node { + ... + pwms = <&pwm_ccu40 0 PWM_SEC(1) PWM_POLARITY_NORMAL>; + ... + }; + + The user must also explicitly set pinctrl properties. + The pin should be configured with drive-push-pull bool option and hwctrl should be set + to disabled. The drive-strength field can be set to any of the supported values: + &pwm_out_p1_1_ccu40_ch2 { + drive-strength = "strong-medium-edge"; + drive-push-pull; + hwctrl = "disabled"; + }; + + The CCU4 pinctrl nodes have a node labels in the format + pwm_out_p{PORT}_{PIN}_ccu4{MODULE_IDX}_ch{CHANNEL_IDX}, where MODULE_IDX and + CHANNEL_IDX refers to specific pwm_ccu4x module and channel, respectively. + PORT/PIN pair defines what gpio the channel connects to. + +compatible: "infineon,xmc4xxx-ccu4-pwm" + +include: + - name: base.yaml + - name: pwm-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + slice-prescaler: + type: array + required: true + description: | + Defines the clock divider for each channel. + The entry in the array will divide CCU clock by (2 << value). + The range for the prescaler values is [0, 15]. + Reducing prescaler value will improve resolution but decrease the maximum period. + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/infineon,xmc4xxx-ccu8-pwm.yaml b/dts/bindings/pwm/infineon,xmc4xxx-ccu8-pwm.yaml new file mode 100644 index 000000000000000..9f2a2c256b80af7 --- /dev/null +++ b/dts/bindings/pwm/infineon,xmc4xxx-ccu8-pwm.yaml @@ -0,0 +1,126 @@ +# Copyright (c) 2023 SLB +# SPDX-License-Identifier: Apache-2.0 + +description: | + Infineon XMC4XXX PWM Capture Compare Unit 8 (CCU8) module + + The PWM CCU8 module can automatically generate a high-side + and a low-side PWM signal, where the two signals are complementary + to each other. + + The module supports adding a dead time between the high-side and + low-side PWM signals. + + The dead time ensures that there is a delay before the PWM state + transitions from 0 to 1, preventing the high-side and low-side + switches from being on simultaneously. + + There are two CCU8 modules with DTS node labels: pwm_ccu80 and + pwm_ccu81. Each module has four slices, and each slice has + two channels. A channel consists of a corresponding high-side + and low-side PWM signal. + + The CCU8 modules use the CCU clock source. Each slice applies + a separate prescaler to divide the clock. The clock divider is + defined by the 'slice-prescaler' property. Additionally, each + slice has a dead time prescaler, which divides the slice clock + for the dead time counter. + + Device tree example: + A node can define a 'pwm' field, usually referenced in a 'pwms' + property, where the entries include the PWM module phandle, + channel number, pulse period (in nanoseconds or set using + PWM_XX() macros), and a channel + flag (PWM_POLARITY_NORMAL/PWM_POLARITY_INVERTED). + + The 'pwm_ccu8' node must define the following fields: + &pwm_ccu80 { + slice-prescaler = <15 15 15 15>; + slice-deadtime-prescaler = <3 3 3 3>; + channel-deadtime-high = <0 0 0 0 PWM_MSEC(100) 0 0 0>; + channel-deadtime-low = <0 0 0 0 PWM_MSEC(100) 0 0 0>; + pinctrl-0 = <&pwm_out_p5_9_ccu80_ch4_high &pwm_out_p0_0_ccu80_ch4_low>; + pinctrl-names = "default"; + }; + + This will configure channel 4 with a 100msec deadtime on the high + and low side PWM signals. + + Another node can reference the PWM as follows: + &test_node { + ... + pwms = <&pwm_ccu80 0 PWM_SEC(1) PWM_POLARITY_NORMAL>; + ... + }; + + The 'pwm_out_p{PORT}_{PIN}_ccu8{MODULE_IDX}_ch{CHANNEL_IDX}_{HIGH_LOW}' + format is used for CCU8 pinctrl nodes. 'MODULE_IDX' and 'CHANNEL_IDX' + refer to a specific 'pwm_ccu8x' module and channel, respectively. + 'PORT/PIN' defines the GPIO that the channel connects to. + 'HIGH_LOW' indicates whether the pin is for the high or low-side signal. + + It's not necessary to specify both the high and low pinctrls. Only the low-side + signal can, for example, be used as PWM, but note that the duty cycle of the + low signal will be (1 - duty) as set via the API. + + Note that a slice has two channels. Channels 0/1 are in slice 0, + channels 2/3 are in slice 1, and so on. Each channel can have its own + duty cycle and high/low dead times. But the pulse duration applies to + both channels. Thus, when using the PWM control api to modify the pulse width + on a channel 0, it will also be updated for channel 1 since they are + in the same slice. + +compatible: "infineon,xmc4xxx-ccu8-pwm" + +include: + - name: base.yaml + - name: pwm-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + slice-prescaler: + type: array + required: true + description: | + Defines the clock divider for each slice. + The entry in the array will divide CCU clock by (2 << value). + The range for the prescaler values is [0, 15]. + Reducing prescaler value will improve resolution but decrease the maximum period. + + slice-deadtime-prescaler: + type: array + required: true + description: | + Defines the clock divider for dead time counter for each slice. + The range for the values is [0, 3]. + Reducing prescaler value will improve dead time resolution but decrease the + maximum dead time. + + channel-deadtime-high: + type: array + required: true + description: | + Defines the dead time in nanoseconds for the high-side PWM signal for each channel. + + channel-deadtime-low: + type: array + required: true + description: | + Defines the dead time in nanoseconds for the low-side PWM signal for each channel. + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/sdhc/zephyr,sdhc-spi-slot.yaml b/dts/bindings/sdhc/zephyr,sdhc-spi-slot.yaml index 500eb0d90352843..fe1d118f31d3678 100644 --- a/dts/bindings/sdhc/zephyr,sdhc-spi-slot.yaml +++ b/dts/bindings/sdhc/zephyr,sdhc-spi-slot.yaml @@ -27,4 +27,11 @@ properties: capture will occur on low to high transition and high to low if this option is not set (default). + pwr-gpios: + type: phandle-array + description: | + Power pin + This pin defaults to active high when consumed by the SPI SDHC driver. + It can be used to toggle card power via an external control circuit + bus: sd diff --git a/dts/bindings/sensor/dfrobot,a01nyub.yaml b/dts/bindings/sensor/dfrobot,a01nyub.yaml new file mode 100644 index 000000000000000..b40b28602b21428 --- /dev/null +++ b/dts/bindings/sensor/dfrobot,a01nyub.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Steadconnect +# SPDX-License-Identifier: Apache-2.0 + +description: DFRobot A01NYUB Distance Sensor + +compatible: "dfrobot,a01nyub" + +include: [sensor-device.yaml, uart-device.yaml] diff --git a/dts/bindings/serial/intel,sedi-uart.yaml b/dts/bindings/serial/intel,sedi-uart.yaml new file mode 100644 index 000000000000000..36eb79cfcf830dd --- /dev/null +++ b/dts/bindings/serial/intel,sedi-uart.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: INTEL SEDI UART + +compatible: "intel,sedi-uart" + +include: uart-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 68d457fc90bc904..255ceb37d171a11 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -150,6 +150,7 @@ delta Delta Electronics, Inc. denx Denx Software Engineering devantech Devantech, Ltd. dfi DFI Inc. +dfrobot DFRobot dh DH electronics GmbH difrnce Shenzhen Yagu Electronic Technology Co., Ltd. digi Digi International Inc. diff --git a/dts/riscv/andes/andes_v5_ae350.dtsi b/dts/riscv/andes/andes_v5_ae350.dtsi index 9c5ad76422da5a0..4a9456520a18968 100644 --- a/dts/riscv/andes/andes_v5_ae350.dtsi +++ b/dts/riscv/andes/andes_v5_ae350.dtsi @@ -183,18 +183,12 @@ &CPU6_intc 11 &CPU7_intc 11>; }; - plic_sw0: interrupt-controller@e6400000 { - compatible = "andestech,plic_sw"; - #address-cells = <1>; - #interrupt-cells = <2>; - interrupt-controller; + mbox: mbox-controller@e6400000 { + compatible = "andestech,plic-sw"; reg = <0xe6400000 0x00400000>; - riscv,max-priority = <255>; - riscv,ndev = <1023>; - interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3 - &CPU2_intc 3 &CPU3_intc 3 - &CPU4_intc 3 &CPU5_intc 3 - &CPU6_intc 3 &CPU7_intc 3>; + #mbox-cells = <1>; + channel-max = <30>; + status = "okay"; }; mtimer: timer@e6000000 { diff --git a/dts/x86/intel/intel_ish5.dtsi b/dts/x86/intel/intel_ish5.dtsi new file mode 100644 index 000000000000000..0a4720a5f346fd3 --- /dev/null +++ b/dts/x86/intel/intel_ish5.dtsi @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "skeleton.dtsi" +#include +#include + +/ { + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu0@0 { + device_type = "cpu"; + compatible = "intel,ish"; + reg = <0>; + }; + }; + + intc: ioapic@fec00000 { + compatible = "intel,ioapic"; + reg = <0xfec00000 0x100000>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + sram: memory@ff200000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xff200000 DT_SIZE_K(640)>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + hpet: hpet@4700000{ + compatible = "intel,hpet"; + reg = <0x04700000 0x400>; + interrupt-parent = <&intc>; + interrupts = <14 IRQ_TYPE_FIXED_LEVEL_HIGH 2>; + status = "okay"; + }; + + uart0: uart@8100000 { + compatible = "intel,sedi-uart"; + reg = <0x08100000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <23 IRQ_TYPE_LOWEST_EDGE_RISING 6>; + current-speed = <115200>; + status = "okay"; + }; + }; +}; diff --git a/dts/x86/intel/intel_ish5_8.dtsi b/dts/x86/intel/intel_ish5_8.dtsi new file mode 100644 index 000000000000000..fb22f65d175472a --- /dev/null +++ b/dts/x86/intel/intel_ish5_8.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&hpet { + interrupts = <17 IRQ_TYPE_FIXED_LEVEL_HIGH 2>; + + status = "okay"; +}; + +&uart0 { + interrupts = <28 IRQ_TYPE_LOWEST_EDGE_RISING 6>; + + status = "okay"; +}; diff --git a/dts/xtensa/nxp/nxp_imx8m.dtsi b/dts/xtensa/nxp/nxp_imx8m.dtsi index badbd5ac858fa61..9e72a3d59ed7bb3 100644 --- a/dts/xtensa/nxp/nxp_imx8m.dtsi +++ b/dts/xtensa/nxp/nxp_imx8m.dtsi @@ -33,6 +33,14 @@ }; soc { + interrupt-parent = <&irqsteer>; + + irqsteer: interrupt-controller { + compatible = "nxp,irqsteer-intc"; + interrupt-controller; + #interrupt-cells = <2>; + }; + ccm: ccm@30380000 { compatible = "nxp,imx-ccm"; reg = <0x30380000 DT_SIZE_K(64)>; @@ -59,5 +67,13 @@ clocks = <&ccm IMX_CCM_UART4_CLK 0x6c 24>; status = "disabled"; }; + + mailbox0: mailbox@30e70000 { + compatible = "nxp,imx-mu-rev2"; + reg = <0x30e70000 0x10000>; + interrupts = <7 0>; + rdc = <0>; + status = "disabled"; + }; }; }; diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index c5ebd5d7176ce00..6d8ed75dfc721a3 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -49,6 +49,10 @@ extern "C" { #define BT_ISO_SDU_INTERVAL_MIN 0x0000FFU /** Maximum interval value in microseconds */ #define BT_ISO_SDU_INTERVAL_MAX 0x0FFFFFU +/** Minimum ISO interval (N * 1.25 ms) */ +#define BT_ISO_ISO_INTERVAL_MIN 0x0004U +/** Maximum ISO interval (N * 1.25 ms) */ +#define BT_ISO_ISO_INTERVAL_MAX 0x0C80U /** Minimum latency value in milliseconds */ #define BT_ISO_LATENCY_MIN 0x0005 /** Maximum latency value in milliseconds */ @@ -63,8 +67,28 @@ extern "C" { #define BT_ISO_FRAMING_FRAMED 0x01 /** Maximum number of isochronous channels in a single group */ #define BT_ISO_MAX_GROUP_ISO_COUNT 0x1F +/** Minimum SDU size */ +#define BT_ISO_MIN_SDU 0x0001 /** Maximum SDU size */ #define BT_ISO_MAX_SDU 0x0FFF +/** Minimum PDU size */ +#define BT_ISO_CONNECTED_PDU_MIN 0x0000U +/** Minimum PDU size */ +#define BT_ISO_BROADCAST_PDU_MIN 0x0001U +/** Maximum PDU size */ +#define BT_ISO_PDU_MAX 0x00FBU +/** Minimum burst number */ +#define BT_ISO_BN_MIN 0x01U +/** Maximum burst number */ +#define BT_ISO_BN_MAX 0x0FU +/** Minimum flush timeout */ +#define BT_ISO_FT_MIN 0x01U +/** Maximum flush timeout */ +#define BT_ISO_FT_MAX 0xFFU +/** Minimum number of subevents */ +#define BT_ISO_NSE_MIN 0x01U +/** Maximum number of subevents */ +#define BT_ISO_NSE_MAX 0x1FU /** Minimum BIG sync timeout value (N * 10 ms) */ #define BT_ISO_SYNC_TIMEOUT_MIN 0x000A /** Maximum BIG sync timeout value (N * 10 ms) */ @@ -85,6 +109,16 @@ extern "C" { #define BT_ISO_BIS_INDEX_MIN 0x01 /** Highest BIS index */ #define BT_ISO_BIS_INDEX_MAX 0x1F +/** Minimum Immediate Repetition Count */ +#define BT_ISO_IRC_MIN 0x01U +/** Maximum Immediate Repetition Count */ +#define BT_ISO_IRC_MAX 0x0FU +/** Minimum pre-transmission offset */ +#define BT_ISO_PTO_MIN 0x00U +/** Maximum pre-transmission offset */ +#define BT_ISO_PTO_MAX 0x0FU + + /** Omit time stamp when sending to controller * * Using this value will enqueue the ISO SDU in a FIFO manner, instead of @@ -154,7 +188,10 @@ struct bt_iso_chan_io_qos { * Setting BT_GAP_LE_PHY_NONE is invalid. */ uint8_t phy; - /** Channel Retransmission Number. */ + /** @brief Channel Retransmission Number. + * + * This value is ignored if any advanced ISO parameters are set. + */ uint8_t rtn; /** @brief Channel data path reference * @@ -162,6 +199,27 @@ struct bt_iso_chan_io_qos { * to BT_ISO_DATA_PATH_HCI). */ struct bt_iso_chan_path *path; + +#if defined(CONFIG_BT_ISO_ADVANCED) + /** @brief Maximum PDU size + * + * Maximum size, in octets, of the payload from link layer to link + * layer. + * + * Value range @ref BT_ISO_CONNECTED_PDU_MIN to @ref BT_ISO_PDU_MAX for + * connected ISO. + * + * Value range @ref BT_ISO_BROADCAST_PDU_MIN to @ref BT_ISO_PDU_MAX for + * broadcast ISO. + */ + uint16_t max_pdu; + + /** @brief Burst number + * + * Value range @ref BT_ISO_BN_MIN to @ref BT_ISO_BN_MAX. + */ + uint8_t burst_number; +#endif /* CONFIG_BT_ISO_ADVANCED */ }; /** @brief ISO Channel QoS structure. */ @@ -182,6 +240,16 @@ struct bt_iso_chan_qos { * isochronous transmitter. */ struct bt_iso_chan_io_qos *tx; + +#if defined(CONFIG_BT_ISO_ADVANCED) + /** @brief Number of subevents + * + * Maximum number of subevents in each CIS or BIS event. + * + * Value range @ref BT_ISO_NSE_MIN to @ref BT_ISO_NSE_MAX. + */ + uint8_t num_subevents; +#endif /* CONFIG_BT_ISO_ADVANCED */ }; /** @brief ISO Channel Data Path structure. */ @@ -276,6 +344,8 @@ struct bt_iso_cig_param { /** @brief Channel Latency in ms. * * Value range BT_ISO_LATENCY_MIN - BT_ISO_LATENCY_MAX. + * + * This value is ignored if any advanced ISO parameters are set. */ uint16_t latency; @@ -300,6 +370,36 @@ struct bt_iso_cig_param { * BT_ISO_FRAMING_FRAMED for framed. */ uint8_t framing; + +#if defined(CONFIG_BT_ISO_ADVANCED) + /** @brief Central to Peripheral flush timeout + * + * The flush timeout in multiples of ISO_Interval for each payload sent + * from the Central to Peripheral. + * + * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX + */ + uint8_t c_to_p_ft; + + /** @brief Peripheral to Central flush timeout + * + * The flush timeout in multiples of ISO_Interval for each payload sent + * from the Peripheral to Central. + * + * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX. + */ + uint8_t p_to_c_ft; + + /** @brief ISO interval + * + * Time between consecutive CIS anchor points. + * + * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to + * @ref BT_ISO_ISO_INTERVAL_MAX. + */ + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_ADVANCED */ + }; /** ISO connection parameters structure */ @@ -335,6 +435,8 @@ struct bt_iso_big_create_param { /** @brief Channel Latency in ms. * * Value range BT_ISO_LATENCY_MIN - BT_ISO_LATENCY_MAX. + * + * This value is ignored if any advanced ISO parameters are set. */ uint16_t latency; @@ -367,6 +469,34 @@ struct bt_iso_big_create_param { * [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00] */ uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE]; + +#if defined(CONFIG_BT_ISO_ADVANCED) + /** @brief Immediate Repetition Count + * + * The number of times the scheduled payloads are transmitted in a + * given event. + * + * Value range from @ref BT_ISO_MIN_IRC to @ref BT_ISO_MAX_IRC. + */ + uint8_t irc; + + /** @brief Pre-transmission offset + * + * Offset used for pre-transmissions. + * + * Value range from @ref BT_ISO_MIN_PTO to @ref BT_ISO_MAX_PTO. + */ + uint8_t pto; + + /** @brief ISO interval + * + * Time between consecutive BIS anchor points. + * + * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to + * @ref BT_ISO_ISO_INTERVAL_MAX. + */ + uint16_t iso_interval; +#endif /* CONFIG_BT_ISO_ADVANCED */ }; /** @brief Broadcast Isochronous Group (BIG) Sync Parameters */ diff --git a/include/zephyr/drivers/can/can_mcan.h b/include/zephyr/drivers/can/can_mcan.h index e2162894eeaf539..c1a1fb9f85d2f1f 100644 --- a/include/zephyr/drivers/can/can_mcan.h +++ b/include/zephyr/drivers/can/can_mcan.h @@ -573,13 +573,25 @@ * @brief Get the Bosch M_CAN Message RAM base address * * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns - * the base address of the Message RAM, taking in the Message RAM offset into account. + * the base address of the Message RAM. * * @param node_id node identifier - * @return the Bosch M_CAN Message RAM base address + * @return the Bosch M_CAN Message RAM base address (MRBA) + */ +#define CAN_MCAN_DT_MRBA(node_id) \ + (mem_addr_t)DT_REG_ADDR_BY_NAME(node_id, message_ram) + +/** + * @brief Get the Bosch M_CAN Message RAM address + * + * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns + * the address of the Message RAM, taking in the Message RAM offset into account. + * + * @param node_id node identifier + * @return the Bosch M_CAN Message RAM address */ #define CAN_MCAN_DT_MRAM_ADDR(node_id) \ - (mem_addr_t)(DT_REG_ADDR_BY_NAME(node_id, message_ram) + CAN_MCAN_DT_MRAM_OFFSET(node_id)) + (mem_addr_t)(CAN_MCAN_DT_MRBA(node_id) + CAN_MCAN_DT_MRAM_OFFSET(node_id)) /** * @brief Get the Bosch M_CAN Message RAM size @@ -782,10 +794,18 @@ */ #define CAN_MCAN_DT_INST_MCAN_ADDR(inst) CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst)) +/** + * @brief Equivalent to CAN_MCAN_DT_MRBA(DT_DRV_INST(inst)) + * @param inst DT_DRV_COMPAT instance number + * @return the Bosch M_CAN Message RAM Base Address (MRBA) + * @see CAN_MCAN_DT_MRBA() + */ +#define CAN_MCAN_DT_INST_MRBA(inst) CAN_MCAN_DT_MRBA(DT_DRV_INST(inst)) + /** * @brief Equivalent to CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst)) * @param inst DT_DRV_COMPAT instance number - * @return the Bosch M_CAN Message RAM base address + * @return the Bosch M_CAN Message RAM address * @see CAN_MCAN_DT_MRAM_ADDR() */ #define CAN_MCAN_DT_INST_MRAM_ADDR(inst) CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst)) diff --git a/include/zephyr/drivers/emul_fuel_gauge.h b/include/zephyr/drivers/emul_fuel_gauge.h index 47044d09318ebc4..c8af1c91a561a1e 100644 --- a/include/zephyr/drivers/emul_fuel_gauge.h +++ b/include/zephyr/drivers/emul_fuel_gauge.h @@ -59,6 +59,10 @@ static inline int emul_fuel_gauge_set_battery_charging(const struct emul *target const struct fuel_gauge_emul_driver_api *backend_api = (const struct fuel_gauge_emul_driver_api *)target->backend_api; + if (backend_api->set_battery_charging == 0) { + return -ENOTSUP; + } + return backend_api->set_battery_charging(target, uV, uA); } diff --git a/include/zephyr/drivers/emul_sensor.h b/include/zephyr/drivers/emul_sensor.h new file mode 100644 index 000000000000000..44a497ee4019b57 --- /dev/null +++ b/include/zephyr/drivers/emul_sensor.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +/** + * @brief Sensor emulator backend API + * @defgroup sensor_emulator_backend Sensor emulator backend API + * @ingroup io_interfaces + * @{ + */ + +/** + * @cond INTERNAL_HIDDEN + * + * These are for internal use only, so skip these in public documentation. + */ + +/** + * @brief Collection of function pointers implementing a common backend API for sensor emulators + */ +__subsystem struct emul_sensor_backend_api { + /** Sets a given fractional value for a given sensor channel. */ + int (*set_channel)(const struct emul *target, enum sensor_channel ch, q31_t value, + int8_t shift); + /** Retrieve a range of sensor values to use with test. */ + int (*get_sample_range)(const struct emul *target, enum sensor_channel ch, q31_t *lower, + q31_t *upper, q31_t *epsilon, int8_t *shift); +}; +/** + * @endcond + */ + +/** + * @brief Check if a given sensor emulator supports the backend API + * + * @param target Pointer to emulator instance to query + * + * @return True if supported, false if unsupported or if \p target is NULL. + */ +static inline bool emul_sensor_backend_is_supported(const struct emul *target) +{ + return target && target->backend_api; +} + +/** + * @brief Set an expected value for a given channel on a given sensor emulator + * + * @param target Pointer to emulator instance to operate on + * @param ch Sensor channel to set expected value for + * @param value Expected value in fixed-point format using standard SI unit for sensor type + * @param shift Shift value (scaling factor) applied to \p value + * + * @return 0 if successful + * @return -ENOTSUP if no backend API or if channel not supported by emul + * @return -ERANGE if provided value is not in the sensor's supported range + */ +static inline int emul_sensor_backend_set_channel(const struct emul *target, enum sensor_channel ch, + q31_t value, int8_t shift) +{ + if (!target || !target->backend_api) { + return -ENOTSUP; + } + + struct emul_sensor_backend_api *api = (struct emul_sensor_backend_api *)target->backend_api; + + if (api->set_channel) { + return api->set_channel(target, ch, value, shift); + } + return -ENOTSUP; +} + +/** + * @brief Query an emulator for a channel's supported sample value range and tolerance + * + * @param target Pointer to emulator instance to operate on + * @param ch The channel to request info for. If \p ch is unsupported, return `-ENOTSUP` + * @param[out] lower Minimum supported sample value in SI units, fixed-point format + * @param[out] upper Maximum supported sample value in SI units, fixed-point format + * @param[out] epsilon Tolerance to use comparing expected and actual values to account for rounding + * and sensor precision issues. This can usually be set to the minimum sample value step + * size. Uses SI units and fixed-point format. + * @param[out] shift The shift value (scaling factor) associated with \p lower, \p upper, and + * \p epsilon. + * + * @return 0 if successful + * @return -ENOTSUP if no backend API or if channel not supported by emul + * + */ +static inline int emul_sensor_backend_get_sample_range(const struct emul *target, + enum sensor_channel ch, q31_t *lower, + q31_t *upper, q31_t *epsilon, int8_t *shift) +{ + if (!target || !target->backend_api) { + return -ENOTSUP; + } + + struct emul_sensor_backend_api *api = (struct emul_sensor_backend_api *)target->backend_api; + + if (api->get_sample_range) { + return api->get_sample_range(target, ch, lower, upper, epsilon, shift); + } + return -ENOTSUP; +} + +/** + * @} + */ diff --git a/include/zephyr/drivers/usb/udc.h b/include/zephyr/drivers/usb/udc.h index f5f74ec12782c27..0f01d877e541ca7 100644 --- a/include/zephyr/drivers/usb/udc.h +++ b/include/zephyr/drivers/usb/udc.h @@ -478,7 +478,7 @@ static inline int udc_host_wakeup(const struct device *dev) * of the endpoint. All properties of the descriptor, * such as direction, and transfer type, should be set correctly. * If wMaxPacketSize value is zero, it will be - * updated to maximum buffer size of the enpoint. + * updated to maximum buffer size of the endpoint. * * @param[in] dev Pointer to device struct of the driver instance * @param[in] ep Endpoint address (same as bEndpointAddress) diff --git a/include/zephyr/drivers/w1.h b/include/zephyr/drivers/w1.h index 4c56d246510f9ae..a23f3577c5b975c 100644 --- a/include/zephyr/drivers/w1.h +++ b/include/zephyr/drivers/w1.h @@ -348,13 +348,55 @@ static inline int z_impl_w1_configure(const struct device *dev, * @name 1-Wire ROM Commands * @{ */ + +/** + * This command allows the bus master to read the slave devices without + * providing their ROM code. + */ #define W1_CMD_SKIP_ROM 0xCC + +/** + * This command allows the bus master to address a specific slave device by + * providing its ROM code. + */ #define W1_CMD_MATCH_ROM 0x55 + +/** + * This command allows the bus master to resume a previous read out from where + * it left off. + */ #define W1_CMD_RESUME 0xA5 + +/** + * This command allows the bus master to read the ROM code from a single slave + * device. + * This command should be used when there is only a single slave device on the + * bus. + */ #define W1_CMD_READ_ROM 0x33 + +/** + * This command allows the bus master to discover the addresses (i.e., ROM + * codes) of all slave devices on the bus. + */ #define W1_CMD_SEARCH_ROM 0xF0 + +/** + * This command allows the bus master to identify which devices have experienced + * an alarm condition. + */ #define W1_CMD_SEARCH_ALARM 0xEC + +/** + * This command allows the bus master to address all devices on the bus and then + * switch them to overdrive speed. + */ #define W1_CMD_OVERDRIVE_SKIP_ROM 0x3C + +/** + * This command allows the bus master to address a specific device and switch it + * to overdrive speed. + */ #define W1_CMD_OVERDRIVE_MATCH_ROM 0x69 /** @} */ diff --git a/include/zephyr/dt-bindings/gpio/st-morpho-header.h b/include/zephyr/dt-bindings/gpio/st-morpho-header.h index c2365fdc7ffec45..82047c391cb0b08 100644 --- a/include/zephyr/dt-bindings/gpio/st-morpho-header.h +++ b/include/zephyr/dt-bindings/gpio/st-morpho-header.h @@ -5,89 +5,158 @@ #ifndef INCLUDE_ZEPHYR_DT_BINDINGS_GPIO_ST_MORPHO_HEADER_H_ #define INCLUDE_ZEPHYR_DT_BINDINGS_GPIO_ST_MORPHO_HEADER_H_ -/** ST Morpho pin mask (0...75). */ -#define ST_MORPHO_PIN_MASK 0x7F +/** ST Morpho pin mask (0...143). */ +#define ST_MORPHO_PIN_MASK 0xFF /** * @name ST Morpho pin identifiers * @{ */ -#define ST_MORPHO_CN7_1 0 -#define ST_MORPHO_CN7_2 1 -#define ST_MORPHO_CN7_3 2 -#define ST_MORPHO_CN7_4 3 -#define ST_MORPHO_CN7_5 4 -#define ST_MORPHO_CN7_6 5 -#define ST_MORPHO_CN7_7 6 -#define ST_MORPHO_CN7_8 7 -#define ST_MORPHO_CN7_9 8 -#define ST_MORPHO_CN7_10 9 -#define ST_MORPHO_CN7_11 10 -#define ST_MORPHO_CN7_12 11 -#define ST_MORPHO_CN7_13 12 -#define ST_MORPHO_CN7_14 13 -#define ST_MORPHO_CN7_15 14 -#define ST_MORPHO_CN7_16 15 -#define ST_MORPHO_CN7_17 16 -#define ST_MORPHO_CN7_18 17 -#define ST_MORPHO_CN7_19 18 -#define ST_MORPHO_CN7_20 19 -#define ST_MORPHO_CN7_21 20 -#define ST_MORPHO_CN7_22 21 -#define ST_MORPHO_CN7_23 22 -#define ST_MORPHO_CN7_24 23 -#define ST_MORPHO_CN7_25 24 -#define ST_MORPHO_CN7_26 25 -#define ST_MORPHO_CN7_27 26 -#define ST_MORPHO_CN7_28 27 -#define ST_MORPHO_CN7_29 28 -#define ST_MORPHO_CN7_30 29 -#define ST_MORPHO_CN7_31 30 -#define ST_MORPHO_CN7_32 31 -#define ST_MORPHO_CN7_33 32 -#define ST_MORPHO_CN7_34 33 -#define ST_MORPHO_CN7_35 34 -#define ST_MORPHO_CN7_36 35 -#define ST_MORPHO_CN7_37 36 -#define ST_MORPHO_CN7_38 37 -#define ST_MORPHO_CN10_1 38 -#define ST_MORPHO_CN10_2 39 -#define ST_MORPHO_CN10_3 40 -#define ST_MORPHO_CN10_4 41 -#define ST_MORPHO_CN10_5 42 -#define ST_MORPHO_CN10_6 43 -#define ST_MORPHO_CN10_7 44 -#define ST_MORPHO_CN10_8 45 -#define ST_MORPHO_CN10_9 46 -#define ST_MORPHO_CN10_10 47 -#define ST_MORPHO_CN10_11 48 -#define ST_MORPHO_CN10_12 49 -#define ST_MORPHO_CN10_13 50 -#define ST_MORPHO_CN10_14 51 -#define ST_MORPHO_CN10_15 52 -#define ST_MORPHO_CN10_16 53 -#define ST_MORPHO_CN10_17 54 -#define ST_MORPHO_CN10_18 55 -#define ST_MORPHO_CN10_19 56 -#define ST_MORPHO_CN10_20 57 -#define ST_MORPHO_CN10_21 58 -#define ST_MORPHO_CN10_22 59 -#define ST_MORPHO_CN10_23 60 -#define ST_MORPHO_CN10_24 61 -#define ST_MORPHO_CN10_25 62 -#define ST_MORPHO_CN10_26 63 -#define ST_MORPHO_CN10_27 64 -#define ST_MORPHO_CN10_28 65 -#define ST_MORPHO_CN10_29 66 -#define ST_MORPHO_CN10_30 67 -#define ST_MORPHO_CN10_31 68 -#define ST_MORPHO_CN10_32 69 -#define ST_MORPHO_CN10_33 70 -#define ST_MORPHO_CN10_34 71 -#define ST_MORPHO_CN10_35 72 -#define ST_MORPHO_CN10_36 73 -#define ST_MORPHO_CN10_37 74 -#define ST_MORPHO_CN10_38 75 +#define ST_MORPHO_L_1 0 +#define ST_MORPHO_L_2 1 +#define ST_MORPHO_L_3 2 +#define ST_MORPHO_L_4 3 +#define ST_MORPHO_L_5 4 +#define ST_MORPHO_L_6 5 +#define ST_MORPHO_L_7 6 +#define ST_MORPHO_L_8 7 +#define ST_MORPHO_L_9 8 +#define ST_MORPHO_L_10 9 +#define ST_MORPHO_L_11 10 +#define ST_MORPHO_L_12 11 +#define ST_MORPHO_L_13 12 +#define ST_MORPHO_L_14 13 +#define ST_MORPHO_L_15 14 +#define ST_MORPHO_L_16 15 +#define ST_MORPHO_L_17 16 +#define ST_MORPHO_L_18 17 +#define ST_MORPHO_L_19 18 +#define ST_MORPHO_L_20 19 +#define ST_MORPHO_L_21 20 +#define ST_MORPHO_L_22 21 +#define ST_MORPHO_L_23 22 +#define ST_MORPHO_L_24 23 +#define ST_MORPHO_L_25 24 +#define ST_MORPHO_L_26 25 +#define ST_MORPHO_L_27 26 +#define ST_MORPHO_L_28 27 +#define ST_MORPHO_L_29 28 +#define ST_MORPHO_L_30 29 +#define ST_MORPHO_L_31 30 +#define ST_MORPHO_L_32 31 +#define ST_MORPHO_L_33 32 +#define ST_MORPHO_L_34 33 +#define ST_MORPHO_L_35 34 +#define ST_MORPHO_L_36 35 +#define ST_MORPHO_L_37 36 +#define ST_MORPHO_L_38 37 +#define ST_MORPHO_L_39 38 +#define ST_MORPHO_L_40 39 +#define ST_MORPHO_L_41 40 +#define ST_MORPHO_L_42 41 +#define ST_MORPHO_L_43 42 +#define ST_MORPHO_L_44 43 +#define ST_MORPHO_L_45 44 +#define ST_MORPHO_L_46 45 +#define ST_MORPHO_L_47 46 +#define ST_MORPHO_L_48 47 +#define ST_MORPHO_L_49 48 +#define ST_MORPHO_L_50 49 +#define ST_MORPHO_L_51 50 +#define ST_MORPHO_L_52 51 +#define ST_MORPHO_L_53 52 +#define ST_MORPHO_L_54 53 +#define ST_MORPHO_L_55 54 +#define ST_MORPHO_L_56 55 +#define ST_MORPHO_L_57 56 +#define ST_MORPHO_L_58 57 +#define ST_MORPHO_L_59 58 +#define ST_MORPHO_L_60 59 +#define ST_MORPHO_L_61 60 +#define ST_MORPHO_L_62 61 +#define ST_MORPHO_L_63 62 +#define ST_MORPHO_L_64 63 +#define ST_MORPHO_L_65 64 +#define ST_MORPHO_L_66 65 +#define ST_MORPHO_L_67 66 +#define ST_MORPHO_L_68 67 +#define ST_MORPHO_L_69 68 +#define ST_MORPHO_L_70 69 +#define ST_MORPHO_L_71 70 +#define ST_MORPHO_L_72 71 + +#define ST_MORPHO_R_1 72 +#define ST_MORPHO_R_2 73 +#define ST_MORPHO_R_3 74 +#define ST_MORPHO_R_4 75 +#define ST_MORPHO_R_5 76 +#define ST_MORPHO_R_6 77 +#define ST_MORPHO_R_7 78 +#define ST_MORPHO_R_8 79 +#define ST_MORPHO_R_9 80 +#define ST_MORPHO_R_10 81 +#define ST_MORPHO_R_11 82 +#define ST_MORPHO_R_12 83 +#define ST_MORPHO_R_13 84 +#define ST_MORPHO_R_14 85 +#define ST_MORPHO_R_15 86 +#define ST_MORPHO_R_16 87 +#define ST_MORPHO_R_17 88 +#define ST_MORPHO_R_18 89 +#define ST_MORPHO_R_19 90 +#define ST_MORPHO_R_20 91 +#define ST_MORPHO_R_21 92 +#define ST_MORPHO_R_22 93 +#define ST_MORPHO_R_23 94 +#define ST_MORPHO_R_24 95 +#define ST_MORPHO_R_25 96 +#define ST_MORPHO_R_26 97 +#define ST_MORPHO_R_27 98 +#define ST_MORPHO_R_28 99 +#define ST_MORPHO_R_29 100 +#define ST_MORPHO_R_30 101 +#define ST_MORPHO_R_31 102 +#define ST_MORPHO_R_32 103 +#define ST_MORPHO_R_33 104 +#define ST_MORPHO_R_34 105 +#define ST_MORPHO_R_35 106 +#define ST_MORPHO_R_36 107 +#define ST_MORPHO_R_37 108 +#define ST_MORPHO_R_38 109 +#define ST_MORPHO_R_39 110 +#define ST_MORPHO_R_40 111 +#define ST_MORPHO_R_41 112 +#define ST_MORPHO_R_42 113 +#define ST_MORPHO_R_43 114 +#define ST_MORPHO_R_44 115 +#define ST_MORPHO_R_45 116 +#define ST_MORPHO_R_46 117 +#define ST_MORPHO_R_47 118 +#define ST_MORPHO_R_48 119 +#define ST_MORPHO_R_49 120 +#define ST_MORPHO_R_50 121 +#define ST_MORPHO_R_51 122 +#define ST_MORPHO_R_52 123 +#define ST_MORPHO_R_53 124 +#define ST_MORPHO_R_54 125 +#define ST_MORPHO_R_55 126 +#define ST_MORPHO_R_56 127 +#define ST_MORPHO_R_57 128 +#define ST_MORPHO_R_58 129 +#define ST_MORPHO_R_59 130 +#define ST_MORPHO_R_60 131 +#define ST_MORPHO_R_61 132 +#define ST_MORPHO_R_62 133 +#define ST_MORPHO_R_63 134 +#define ST_MORPHO_R_64 135 +#define ST_MORPHO_R_65 136 +#define ST_MORPHO_R_66 137 +#define ST_MORPHO_R_67 138 +#define ST_MORPHO_R_68 139 +#define ST_MORPHO_R_69 140 +#define ST_MORPHO_R_70 141 +#define ST_MORPHO_R_71 142 +#define ST_MORPHO_R_72 143 /** @} */ diff --git a/include/zephyr/dt-bindings/pinctrl/cc13xx_cc26xx-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/cc13xx_cc26xx-pinctrl.h index 72586136fc6fd9a..042fb9df7a79a85 100644 --- a/include/zephyr/dt-bindings/pinctrl/cc13xx_cc26xx-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/cc13xx_cc26xx-pinctrl.h @@ -57,4 +57,10 @@ #define IOC_PORT_RFC_SMI_CL_OUT 0x00000037 /* RF Core SMI Command Link Out */ #define IOC_PORT_RFC_SMI_CL_IN 0x00000038 /* RF Core SMI Command Link In */ +/* Edge Detection */ +#define IOC_NO_EDGE 0x00000000 /* No edge detection */ +#define IOC_FALLING_EDGE 0x00010000 /* Edge detection on falling edge */ +#define IOC_RISING_EDGE 0x00020000 /* Edge detection on rising edge */ +#define IOC_BOTH_EDGES 0x00030000 /* Edge detection on both edges */ + #endif /* CC13XX_CC26XX_PINCTRL_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h new file mode 100644 index 000000000000000..425c767b2f3408e --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Silicon Labs + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ + +/* + * The whole GECKO_pin configuration information is encoded in a 32-bit bitfield + * organized as follows: + * + * - 31..24: Pin function. + * - 23..16: Reserved. + * - 15..8: Port for UART_RX/UART_TX functions. + * - 7..0: Pin number for UART_RX/UART_TX functions. + * - 15..8: Reserved for UART_LOC function. + * - 7..0: Loc for UART_LOC function. + */ + +/** + * @name GECKO_pin configuration bit field positions and masks. + * @{ + */ + +/** Position of the function field. */ +#define GECKO_FUN_POS 24U +/** Mask for the function field. */ +#define GECKO_FUN_MSK 0xFFFU + +/** Position of the pin field. */ +#define GECKO_PIN_POS 0U +/** Mask for the pin field. */ +#define GECKO_PIN_MSK 0xFFU + +/** Position of the port field. */ +#define GECKO_PORT_POS 8U +/** Mask for the port field. */ +#define GECKO_PORT_MSK 0xFFU + +/** Position of the loc field. */ +#define GECKO_LOC_POS 0U +/** Mask for the pin field. */ +#define GECKO_LOC_MSK 0xFFU + +/** @} */ + +/** + * @name GECKO_pinctrl pin functions. + * @{ + */ + +/** UART TX */ +#define GECKO_FUN_UART_TX 0U +/** UART RX */ +#define GECKO_FUN_UART_RX 1U +/** UART RTS */ +#define GECKO_FUN_UART_RTS 2U +/** UART CTS */ +#define GECKO_FUN_UART_CTS 3U +/** UART RX LOCATION */ +#define GECKO_FUN_UART_RX_LOC 4U +/** UART TX LOCATION */ +#define GECKO_FUN_UART_TX_LOC 5U +/** UART RTS LOCATION */ +#define GECKO_FUN_UART_RTS_LOC 6U +/** UART CTS LOCATION */ +#define GECKO_FUN_UART_CTS_LOC 7U + +#define GECKO_FUN_SPIM_MISO 8U +#define GECKO_FUN_SPIM_MOSI 9U +#define GECKO_FUN_SPIM_CS 10U +#define GECKO_FUN_SPIM_SCK 11U + +#define GECKO_FUN_LEUART_RX_LOC 12U +#define GECKO_FUN_LEUART_TX_LOC 13U + +#define GECKO_FUN_SPIS_MISO 14U +#define GECKO_FUN_SPIS_MOSI 15U +#define GECKO_FUN_SPIS_CS 16U +#define GECKO_FUN_SPIS_SCK 17U + +#define GECKO_FUN_SPI_MISO_LOC 18U +#define GECKO_FUN_SPI_MOSI_LOC 19U +#define GECKO_FUN_SPI_CS_LOC 20U +#define GECKO_FUN_SPI_SCK_LOC 21U + + +/** @} */ + +/** + * @brief Utility macro to build GECKO psels property entry. + * + * @param fun Pin function configuration (see GECKO_FUNC_{name} macros). + * @param port Port (0 or 1). + * @param pin Pin (0..31). + */ +#define GECKO_PSEL(fun, port, pin) \ + (((GECKO_PORT_##port & GECKO_PORT_MSK) << GECKO_PORT_POS) | \ + ((GECKO_PIN(##pin##) & GECKO_PIN_MSK) << GECKO_PIN_POS) | \ + ((GECKO_FUN_##fun & GECKO_FUN_MSK) << GECKO_FUN_POS)) + +/** + * @brief Utility macro to build GECKO_psels property entry. + * + * @param fun Pin function configuration (see GECKO_FUNC_{name} macros). + * @param loc Location. + */ +#define GECKO_LOC(fun, loc) \ + (((GECKO_LOCATION(##loc##) & GECKO_LOC_MSK) << GECKO_LOC_POS) | \ + ((GECKO_FUN_##fun##_LOC & GECKO_FUN_MSK) << GECKO_FUN_POS)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h new file mode 100644 index 000000000000000..b49e2141444ab20 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ + +#include + +#define IO_MUX_REG_MAX_OFFSET 107 +#define IO_MUX_MAX_PAD_NR 45 + +#define FUNC_SEL_UART_RX (77 << 13) + +#define QUICKLOGIC_EOS_S3_PINMUX(pin, fun) (pin) (fun) + +#define UART_TX_PAD44 QUICKLOGIC_EOS_S3_PINMUX(44, 0x3) +#define UART_RX_PAD45 QUICKLOGIC_EOS_S3_PINMUX(45, FUNC_SEL_UART_RX | BIT(2)) +#define USB_PU_CTRL_PAD23 QUICKLOGIC_EOS_S3_PINMUX(23, 0x0) +#define USB_DN_PAD28 QUICKLOGIC_EOS_S3_PINMUX(28, 0x0) +#define USB_DP_PAD31 QUICKLOGIC_EOS_S3_PINMUX(31, 0x0) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ */ diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/image.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/image.h deleted file mode 100644 index 761428446b36c19..000000000000000 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/image.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2018-2021 mcumgr authors - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef H_IMAGE_ -#define H_IMAGE_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define IMAGE_MAGIC 0x96f3b83d -#define IMAGE_TLV_INFO_MAGIC 0x6907 -#define IMAGE_TLV_PROT_INFO_MAGIC 0x6908 - -#define IMAGE_HEADER_SIZE 32 - -/** Image header flags. */ -#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */ -#define IMAGE_F_ROM_FIXED_ADDR 0x00000100 - -/** Image trailer TLV types. */ -#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */ - -/** Image TLV-specific definitions. */ -#define IMAGE_HASH_LEN 32 - -struct image_version { - uint8_t iv_major; - uint8_t iv_minor; - uint16_t iv_revision; - uint32_t iv_build_num; -} __packed; - -/** Image header. All fields are in little endian byte order. */ -struct image_header { - uint32_t ih_magic; - uint32_t ih_load_addr; - uint16_t ih_hdr_size; /* Size of image header (bytes). */ - uint16_t _pad2; - uint32_t ih_img_size; /* Does not include header. */ - uint32_t ih_flags; /* IMAGE_F_[...]. */ - struct image_version ih_ver; - uint32_t _pad3; -} __packed; - -/** Image TLV header. All fields in little endian. */ -struct image_tlv_info { - uint16_t it_magic; - uint16_t it_tlv_tot; /* size of TLV area (including tlv_info header) */ -} __packed; - -/** Image trailer TLV format. All fields in little endian. */ -struct image_tlv { - uint8_t it_type; /* IMAGE_TLV_[...]. */ - uint8_t _pad; - uint16_t it_len; /* Data length (not including TLV header). */ -} __packed; - -_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, - "struct image_header not required size"); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index ef5f840c261e551..3a86873e4088de0 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include /** @@ -25,8 +25,6 @@ extern "C" { #endif -#define IMG_MGMT_HASH_STR 48 -#define IMG_MGMT_HASH_LEN 32 #define IMG_MGMT_DATA_SHA_LEN 32 /* SHA256 */ /** @@ -152,6 +150,12 @@ enum img_mgmt_ret_code_t { /** The image vector table is invalid. */ IMG_MGMT_RET_RC_INVALID_IMAGE_VECTOR_TABLE, + + /** The image it too large to fit. */ + IMG_MGMT_RET_RC_INVALID_IMAGE_TOO_LARGE, + + /** The amount of data sent is larger than the provided image size. */ + IMG_MGMT_RET_RC_INVALID_IMAGE_DATA_OVERRUN, }; /** @@ -354,6 +358,8 @@ extern const char *img_mgmt_err_str_flash_erase_failed; extern const char *img_mgmt_err_str_flash_write_failed; extern const char *img_mgmt_err_str_downgrade; extern const char *img_mgmt_err_str_image_bad_flash_addr; +extern const char *img_mgmt_err_str_image_too_large; +extern const char *img_mgmt_err_str_data_overrun; #else #define IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, rsn) #define IMG_MGMT_UPLOAD_ACTION_RC_RSN(action) NULL diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h index 4b29f7b991421c0..a9e05b5d3d11796 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h @@ -8,12 +8,14 @@ #ifndef H_MCUMGR_IMG_MGMT_CALLBACKS_ #define H_MCUMGR_IMG_MGMT_CALLBACKS_ -#include - #ifdef __cplusplus extern "C" { #endif +/* Dummy definitions, include zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h for actual definitions */ +struct img_mgmt_upload_action; +struct img_mgmt_upload_req; + /** * @brief MCUmgr img_mgmt callback API * @defgroup mcumgr_callback_api_img_mgmt MCUmgr img_mgmt callback API diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h new file mode 100644 index 000000000000000..6ee12fb5a61246b --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_IMG_MGMT_CLIENT_ +#define H_IMG_MGMT_CLIENT_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Image list flags. + */ +struct mcumgr_image_list_flags { + /** Bootable image */ + bool bootable: 1; + /** Pending update state */ + bool pending: 1; + /** Confirmed image */ + bool confirmed: 1; + /** Active image */ + bool active: 1; + /** Permanent image state */ + bool permanent: 1; +}; + +/** + * @brief Image list data. + */ +struct mcumgr_image_data { + /** Image slot num */ + uint32_t slot_num; + /** Image number */ + uint32_t img_num; + /** Image SHA256 checksum */ + char hash[IMG_MGMT_HASH_LEN]; + /** Image Version */ + char version[IMG_MGMT_VER_MAX_STR_LEN + 1]; + /** Image Flags */ + struct mcumgr_image_list_flags flags; +}; + +/** + * @brief MCUmgr Image list response. + */ +struct mcumgr_image_state { + /** Status */ + enum mcumgr_err_t status; + /** Length of image_list */ + int image_list_length; + /** Image list pointer */ + struct mcumgr_image_data *image_list; +}; + +/** + * @brief MCUmgr Image upload response. + */ +struct mcumgr_image_upload { + /** Status */ + enum mcumgr_err_t status; + /** Reported image offset */ + size_t image_upload_offset; +}; + +/** + * @brief IMG mgmt client upload structure + * + * Structure is used internally by the client + */ +struct img_gr_upload { + /** Image 256-bit hash */ + char sha256[IMG_MGMT_HASH_LEN]; + /** True when Hash is configured, false when not */ + bool hash_initialized; + /** Image size */ + size_t image_size; + /** Image upload offset state */ + size_t offset; + /** Worst case init upload message size */ + size_t upload_header_size; + /** Image slot num */ + uint32_t image_num; +}; + +/** + * @brief IMG mgmt client object. + */ +struct img_mgmt_client { + /** SMP client object */ + struct smp_client_object *smp_client; + /** Image Upload state data for client internal use */ + struct img_gr_upload upload; + /** Client image list buffer size */ + int image_list_length; + /** Image list buffer */ + struct mcumgr_image_data *image_list; + /** Command status */ + int status; +}; + +/** + * @brief Inilialize image group client. + * + * Function initializes image group client for given SMP client using supplied image data. + * + * @param client IMG mgmt client object + * @param smp_client SMP client object + * @param image_list_size Length of image_list buffer. + * @param image_list Image list buffer pointer. + * + */ +void img_mgmt_client_init(struct img_mgmt_client *client, struct smp_client_object *smp_client, + int image_list_size, struct mcumgr_image_data *image_list); + +/** + * @brief Initialize image upload. + * + * @param client IMG mgmt client object + * @param image_size Size of image in bytes. + * @param image_num Image slot Num. + * @param image_hash Pointer to HASH for image must be SHA256 hash of entire upload + * if present (32 bytes). Use NULL when HASH from image is not available. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_size, + uint32_t image_num, const char *image_hash); + +/** + * @brief Upload part of image. + * + * @param client IMG mgmt client object + * @param data Pointer to data. + * @param length Length of data + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, size_t length, + struct mcumgr_image_upload *res_buf); + +/** + * @brief Write image state. + * + * @param client IMG mgmt client object + * @param hash Pointer to Hash (Needed for test). + * @param confirm Set false for test and true for confirmation. + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ + +int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool confirm, + struct mcumgr_image_state *res_buf); + +/** + * @brief Read image state. + * + * @param client IMG mgmt client object + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_image_state *res_buf); + +/** + * @brief Erase selected Image Slot + * + * @param client IMG mgmt client object + * @param slot Slot number + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ + +int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot); + +#ifdef __cplusplus +} +#endif + +#endif /* H_IMG_MGMT_CLIENT_ */ diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h new file mode 100644 index 000000000000000..12e8abde246c18c --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_OS_MGMT_CLIENT_ +#define H_OS_MGMT_CLIENT_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief OS mgmt client object + */ +struct os_mgmt_client { + /** SMP client object */ + struct smp_client_object *smp_client; + /** Command status */ + int status; +}; + +/** + * @brief Initialize OS management client. + * + * @param client OS mgmt client object + * @param smp_client SMP client object + * + */ +void os_mgmt_client_init(struct os_mgmt_client *client, struct smp_client_object *smp_client); + +/** + * @brief Send SMP message for Echo command. + * + * @param client OS mgmt client object + * @param echo_string Echo string + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string); + +/** + * @brief Send SMP Reset command. + * + * @param client OS mgmt client object + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int os_mgmt_client_reset(struct os_mgmt_client *client); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_MGMT_CLIENT_ */ diff --git a/include/zephyr/mgmt/mcumgr/smp/smp_client.h b/include/zephyr/mgmt/mcumgr/smp/smp_client.h new file mode 100644 index 000000000000000..88b2af701b09f4d --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/smp/smp_client.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_SMP_CLIENT_ +#define H_SMP_CLIENT_ + +#include +#include +#include +#include +#include + +/** + * @brief SMP client object + */ +struct smp_client_object { + /** Must be the first member. */ + struct k_work work; + /** FIFO for client TX queue */ + struct k_fifo tx_fifo; + /** SMP transport object */ + struct smp_transport *smpt; + /** SMP SEQ */ + uint8_t smp_seq; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize a SMP client object. + * + * @param smp_client The Client to construct. + * @param smp_type SMP transport type for discovering transport object + * + * @return 0 if successful + * @return mcumgr_err_t code on failure + */ +int smp_client_object_init(struct smp_client_object *smp_client, int smp_type); + +/** + * @brief Response callback for SMP send. + * + * @param nb net_buf for response + * @param user_data same user data that was provided as part of the request + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +typedef int (*smp_client_res_fn)(struct net_buf *nb, void *user_data); + +/** + * @brief SMP client response handler. + * + * @param nb response net_buf + * @param res_hdr Parsed SMP header + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int smp_client_single_response(struct net_buf *nb, const struct smp_hdr *res_hdr); + +/** + * @brief Allocate buffer and initialize with SMP header. + * + * @param smp_client SMP client object + * @param group SMP group id + * @param command_id SMP command id + * @param op SMP operation type + * @param version SMP MCUmgr version + * + * @return A newly-allocated buffer net_buf on success + * @return NULL on failure. + */ +struct net_buf *smp_client_buf_allocation(struct smp_client_object *smp_client, uint16_t group, + uint8_t command_id, uint8_t op, + enum smp_mcumgr_version_t version); +/** + * @brief Free a SMP client buffer. + * + * @param nb The net_buf to free. + */ +void smp_client_buf_free(struct net_buf *nb); + +/** + * @brief SMP client data send request. + * + * @param smp_client SMP client object + * @param nb net_buf packet for send + * @param cb Callback for response handler + * @param user_data user defined data pointer which will be returned back to response callback + * @param timeout_in_sec Timeout in seconds for send process. Client will retry transport + * based CONFIG_SMP_CMD_RETRY_TIME + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb, + smp_client_res_fn cb, void *user_data, int timeout_in_sec); + +#ifdef __cplusplus +} +#endif + +#endif /* H_SMP_CLIENT_ */ diff --git a/include/zephyr/mgmt/mcumgr/transport/smp.h b/include/zephyr/mgmt/mcumgr/transport/smp.h index 55c9c7b0826e00e..d8cec6878f7961c 100644 --- a/include/zephyr/mgmt/mcumgr/transport/smp.h +++ b/include/zephyr/mgmt/mcumgr/transport/smp.h @@ -134,6 +134,35 @@ struct smp_transport { #endif }; +/** + * @brief SMP transport type for client registration + */ +enum smp_transport_type { + /** SMP serial */ + SMP_SERIAL_TRANSPORT = 0, + /** SMP bluetooth */ + SMP_BLUETOOTH_TRANSPORT, + /** SMP shell*/ + SMP_SHELL_TRANSPORT, + /** SMP UDP IPv4 */ + SMP_UDP_IPV4_TRANSPORT, + /** SMP UDP IPv6 */ + SMP_UDP_IPV6_TRANSPORT, + /** SMP user defined type */ + SMP_USER_DEFINED_TRANSPORT +}; + +/** + * @brief SMP Client transport structure + */ +struct smp_client_transport_entry { + sys_snode_t node; + /** Transport structure pointer */ + struct smp_transport *smpt; + /** Transport type */ + int smpt_type; +}; + /** * @brief Initializes a Zephyr SMP transport object. * @@ -162,6 +191,22 @@ void smp_rx_remove_invalid(struct smp_transport *zst, void *arg); */ void smp_rx_clear(struct smp_transport *zst); +/** + * @brief Register a Zephyr SMP transport object for client. + * + * @param entry The transport to construct. + */ +void smp_client_transport_register(struct smp_client_transport_entry *entry); + +/** + * @brief Discover a registered SMP transport client object. + * + * @param smpt_type Type of transport + * + * @return Pointer to registered object. Unknown type return NULL. + */ +struct smp_transport *smp_client_transport_get(int smpt_type); + /** * @} */ diff --git a/include/zephyr/multi_heap/shared_multi_heap.h b/include/zephyr/multi_heap/shared_multi_heap.h index 1ab55fc0b658d1d..0d5e66bf293d6e3 100644 --- a/include/zephyr/multi_heap/shared_multi_heap.h +++ b/include/zephyr/multi_heap/shared_multi_heap.h @@ -66,7 +66,7 @@ extern "C" { * Enumeration type for some common memory region attributes. * */ -enum smh_reg_attr { +enum shared_multi_heap_attr { /** cacheable */ SMH_REG_ATTR_CACHEABLE, @@ -126,7 +126,7 @@ int shared_multi_heap_pool_init(void); * @retval ptr a valid pointer to heap memory. * @retval err NULL if no memory is available. */ -void *shared_multi_heap_alloc(unsigned int attr, size_t bytes); +void *shared_multi_heap_alloc(enum shared_multi_heap_attr attr, size_t bytes); /** * @brief Allocate aligned memory from the memory shared multi-heap pool @@ -142,7 +142,8 @@ void *shared_multi_heap_alloc(unsigned int attr, size_t bytes); * @retval ptr a valid pointer to heap memory. * @retval err NULL if no memory is available. */ -void *shared_multi_heap_aligned_alloc(unsigned int attr, size_t align, size_t bytes); +void *shared_multi_heap_aligned_alloc(enum shared_multi_heap_attr attr, + size_t align, size_t bytes); /** * @brief Free memory from the shared multi-heap pool diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 6006bd813ece9bb..cc8ac4d20bcac85 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -15,9 +15,9 @@ #define ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_H_ #include -#include #include #include +#include #include #include @@ -97,24 +97,83 @@ enum ieee802154_channel { }; enum ieee802154_hw_caps { - IEEE802154_HW_FCS = BIT(0), /* Frame Check-Sum supported */ - IEEE802154_HW_PROMISC = BIT(1), /* Promiscuous mode supported */ - IEEE802154_HW_FILTER = BIT(2), /* Filter PAN ID, long/short addr */ - IEEE802154_HW_CSMA = BIT(3), /* Executes CSMA-CA procedure on TX */ - IEEE802154_HW_RETRANSMISSION = BIT(4), /* Handles retransmission on TX ACK timeout */ - IEEE802154_HW_TX_RX_ACK = BIT(5), /* Waits for ACK on TX if AR bit is set in TX pkt */ - IEEE802154_HW_RX_TX_ACK = BIT(6), /* Sends ACK on RX if AR bit is set in RX pkt */ - IEEE802154_HW_ENERGY_SCAN = BIT(7), /* Energy scan supported */ - IEEE802154_HW_TXTIME = BIT(8), /* TX at specified time supported */ - IEEE802154_HW_SLEEP_TO_TX = BIT(9), /* TX directly from sleep supported */ - IEEE802154_HW_TX_SEC = BIT(10), /* TX security handling supported */ - IEEE802154_HW_RXTIME = BIT(11), /* RX at specified time supported */ - IEEE802154_HW_2_4_GHZ = BIT(12), /* 2.4Ghz radio supported - * TODO: Replace with channel page attribute. - */ - IEEE802154_HW_SUB_GHZ = BIT(13), /* Sub-GHz radio supported - * TODO: Replace with channel page attribute. - */ + + /* + * PHY capabilities + * + * The following capabilities describe features of the underlying radio + * hardware (PHY/L1). + * + * Note: A device driver must support the mandatory channel pages, + * frequency bands and channels of at least one IEEE 802.15.4 PHY. + */ + + /** + * 2.4Ghz radio supported + * + * TODO: Replace with channel page attribute. + */ + IEEE802154_HW_2_4_GHZ = BIT(0), + + /** + * Sub-GHz radio supported + * + * TODO: Replace with channel page attribute. + */ + IEEE802154_HW_SUB_GHZ = BIT(1), + + /** Energy detection (ED) supported (optional) */ + IEEE802154_HW_ENERGY_SCAN = BIT(2), + + + /* + * MAC offloading capabilities (optional) + * + * The following MAC/L2 features may optionally be offloaded to + * specialized hardware or proprietary driver firmware ("hard MAC"). + * + * L2 implementations will have to provide a "soft MAC" fallback for + * these features in case the driver does not support them natively. + * + * Note: Some of these offloading capabilities may be mandatory in + * practice to stay within timing requirements of certain IEEE 802.15.4 + * protocols, e.g. CPUs may not be fast enough to send ACKs within the + * required delays in the 2.4 GHz band without hard MAC support. + */ + + /** Frame checksum verification supported */ + IEEE802154_HW_FCS = BIT(3), + + /** Filtering of PAN ID, extended and short address supported */ + IEEE802154_HW_FILTER = BIT(4), + + /** Promiscuous mode supported */ + IEEE802154_HW_PROMISC = BIT(5), + + /** CSMA-CA procedure supported on TX */ + IEEE802154_HW_CSMA = BIT(6), + + /** Waits for ACK on TX if AR bit is set in TX pkt */ + IEEE802154_HW_TX_RX_ACK = BIT(7), + + /** Supports retransmission on TX ACK timeout */ + IEEE802154_HW_RETRANSMISSION = BIT(8), + + /** Sends ACK on RX if AR bit is set in RX pkt */ + IEEE802154_HW_RX_TX_ACK = BIT(9), + + /** TX at specified time supported */ + IEEE802154_HW_TXTIME = BIT(10), + + /** TX directly from sleep supported */ + IEEE802154_HW_SLEEP_TO_TX = BIT(11), + + /** Timed RX window scheduling supported */ + IEEE802154_HW_RXTIME = BIT(12), + + /** TX security supported (key management, encryption and authentication) */ + IEEE802154_HW_TX_SEC = BIT(13), + /* Note: Update also IEEE802154_HW_CAPS_BITS_COMMON_COUNT when changing * the ieee802154_hw_caps type. */ @@ -155,13 +214,13 @@ typedef void (*ieee802154_event_cb_t)(const struct device *dev, void *event_params); struct ieee802154_filter { -/** @cond ignore */ +/** @cond INTERNAL_HIDDEN */ union { uint8_t *ieee_addr; /* in little endian */ uint16_t short_addr; /* in CPU byte order */ uint16_t pan_id; /* in CPU byte order */ }; -/* @endcond */ +/** @endcond */ }; struct ieee802154_key { @@ -181,20 +240,23 @@ enum ieee802154_tx_mode { IEEE802154_TX_MODE_CCA, /** - * Perform full CSMA CA procedure before packet transmission. - * Requires IEEE802154_HW_CSMA capability. + * Perform full CSMA/CA procedure before packet transmission. + * + * @note requires IEEE802154_HW_CSMA capability. */ IEEE802154_TX_MODE_CSMA_CA, /** * Transmit packet in the future, at specified time, no CCA. - * Requires IEEE802154_HW_TXTIME capability. + * + * @note requires IEEE802154_HW_TXTIME capability. */ IEEE802154_TX_MODE_TXTIME, /** * Transmit packet in the future, perform CCA before transmission. - * Requires IEEE802154_HW_TXTIME capability. + * + * @note requires IEEE802154_HW_TXTIME capability. */ IEEE802154_TX_MODE_TXTIME_CCA, @@ -254,14 +316,14 @@ enum ieee802154_config_type { IEEE802154_CONFIG_FRAME_COUNTER, /** Sets the current MAC frame counter value if the provided value is greater than - * the current one. + * the current one. */ - IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER, - /** Configure a radio reception slot. This can be used for any scheduled reception, e.g.: - * Zigbee GP device, CSL, TSCH, etc. - * Requires IEEE802154_HW_RXTIME capability. + /** Configure a radio reception window. This can be used for any + * scheduled reception, e.g.: Zigbee GP device, CSL, TSCH, etc. + * + * @note requires IEEE802154_HW_RXTIME capability. */ IEEE802154_CONFIG_RX_SLOT, @@ -270,19 +332,19 @@ enum ieee802154_config_type { * In order to configure a CSL receiver the upper layer should combine several * configuration options in the following way: * 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the radio driver of the - * short and extended addresses of the peer to which it should inject CSL IEs. + * short and extended addresses of the peer to which it should inject CSL IEs. * 2. Use ``IEEE802154_CONFIG_CSL_RX_TIME`` periodically, before each use of - * ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, and - * before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not the - * nearest one) CSL RX window, to allow the radio driver to calculate the proper CSL Phase - * to the nearest CSL window to inject in the CSL IEs for both transmitted data and ack - * frames. + * ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, + * and before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not + * the nearest one) CSL RX window, to allow the radio driver to calculate the proper + * CSL Phase to the nearest CSL window to inject in the CSL IEs for both transmitted + * data and ACK frames. * 3. Use ``IEEE802154_CONFIG_CSL_PERIOD`` on each value change to update the current CSL - * period value which will be injected in the CSL IEs together with the CSL Phase based on - * ``IEEE802154_CONFIG_CSL_RX_TIME``. + * period value which will be injected in the CSL IEs together with the CSL Phase + * based on ``IEEE802154_CONFIG_CSL_RX_TIME``. * 4. Use ``IEEE802154_CONFIG_RX_SLOT`` periodically to schedule the immediate receive - * window earlier enough before the expected window start time, taking into account - * possible clock drifts and scheduling uncertainties. + * window earlier enough before the expected window start time, taking into account + * possible clock drifts and scheduling uncertainties. * * This diagram shows the usage of the four options over time: * Start CSL Schedule CSL window @@ -301,8 +363,8 @@ enum ieee802154_config_type { */ IEEE802154_CONFIG_CSL_PERIOD, - /** Configure the next CSL receive window center, in units of microseconds, - * based on the radio time. + /** Configure the next CSL receive window (i.e. "channel sample") center, + * in units of nanoseconds relative to the network subsystem's local clock. */ IEEE802154_CONFIG_CSL_RX_TIME, @@ -363,41 +425,69 @@ struct ieee802154_config { /** ``IEEE802154_CONFIG_RX_SLOT`` */ struct { + /** + * Nanosecond resolution timestamp relative to the + * network subsystem's local clock defining the start of + * the RX window during which the receiver is expected + * to be listening (i.e. not including any startup + * times). + */ + net_time_t start; + + /** + * Nanosecond resolution duration of the RX window + * relative to the above RX window start time during + * which the receiver is expected to be listening (i.e. + * not including any shutdown times). + */ + net_time_t duration; + uint8_t channel; - uint32_t start; - uint32_t duration; } rx_slot; - /** ``IEEE802154_CONFIG_CSL_PERIOD`` */ - uint32_t csl_period; /* in CPU byte order */ + /** + * ``IEEE802154_CONFIG_CSL_PERIOD`` + * + * The CSL period in units of 10 symbol periods, + * see section 7.4.2.3. + * + * in CPU byte order + */ + uint32_t csl_period; - /** ``IEEE802154_CONFIG_CSL_RX_TIME`` */ - uint32_t csl_rx_time; /* in microseconds, - * based on ieee802154_radio_api.get_time() - */ + /** + * ``IEEE802154_CONFIG_CSL_RX_TIME`` + * + * Nanosecond resolution timestamp relative to the network + * subsystem's local clock defining the center of the CSL RX window + * at which the receiver is expected to be fully started up + * (i.e. not including any startup times). + */ + net_time_t csl_rx_time; /** ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` */ struct { - const uint8_t *data; /* header IEs to be added to the Enh-Ack frame in - * little endian byte order - */ - uint16_t data_len; - uint16_t short_addr; /* in CPU byte order */ /** - * The extended address is expected to be passed starting - * with the most significant octet and ending with the - * least significant octet. - * A device with an extended address 01:23:45:67:89:ab:cd:ef - * as written in the usual big-endian hex notation should - * provide a pointer to an array containing values in the - * exact same order. + * header IEs to be added to the Enh-Ack frame + * + * in little endian */ - const uint8_t *ext_addr; /* in big endian */ + const uint8_t *data; + uint16_t data_len; + /** in CPU byte order */ + uint16_t short_addr; + /** in big endian */ + const uint8_t *ext_addr; } ack_ie; }; }; -/** IEEE 802.15.4 attributes. */ +/** + * @brief IEEE 802.15.4 driver attributes. + * + * See @ref ieee802154_attr_value and @ref ieee802154_radio_api for usage + * details. + */ enum ieee802154_attr { /** Number of attributes defined in ieee802154_attr. */ IEEE802154_ATTR_COMMON_COUNT, @@ -406,11 +496,28 @@ enum ieee802154_attr { IEEE802154_ATTR_PRIV_START = IEEE802154_ATTR_COMMON_COUNT, }; -/** IEEE 802.15.4 attribute value data. */ +/** + * @brief IEEE 802.15.4 driver attributes. + * + * @details This structure is reserved to scalar and structured attributes that + * originate in the driver implementation and can neither be implemented as + * boolean @ref ieee802154_hw_caps nor be derived directly or indirectly by the + * MAC (L2) layer. In particular this structure MUST NOT be used to return + * configuration data that originate from L2. + * + * @note To keep this union reasonably small, any attribute requiring a large + * memory area, SHALL be provided pointing to memory allocated from the driver's + * stack. Clients that need to persist the attribute value SHALL therefore copy + * such memory before returning control to the driver. + */ struct ieee802154_attr_value { union { /* TODO: Please remove when first attribute is added. */ uint8_t dummy; + + /* TODO: Add driver specific PHY attributes (symbol rate, + * aTurnaroundTime, aCcaTime, channels, channel pages, etc.) + */ }; }; @@ -420,84 +527,271 @@ struct ieee802154_attr_value { */ struct ieee802154_radio_api { /** - * Mandatory to get in first position. - * A network device should indeed provide a pointer on such - * net_if_api structure. So we make current structure pointer - * that can be casted to a net_if_api structure pointer. + * @brief network interface API + * + * @note Network devices must extend the network interface API. It is + * therefore mandatory to place it at the top of the radio API struct so + * that it can be cast to a network interface. */ struct net_if_api iface_api; - /** Get the device capabilities */ + /** + * @brief Get the device driver capabilities. + * + * @param dev pointer to radio device + * + * @return Bit field with all supported device driver capabilities. + */ enum ieee802154_hw_caps (*get_capabilities)(const struct device *dev); - /** Clear Channel Assessment - Check channel's activity */ + /** + * @brief Clear Channel Assessment - Check channel's activity + * + * @param dev pointer to radio device + * + * @retval 0 the channel is available + * @retval -EBUSY The channel is busy. + * @retval -EIO The CCA procedure could not be executed. + * @retval -ENOTSUP CCA is not supported by this driver. + */ int (*cca)(const struct device *dev); - /** Set current channel, channel is in CPU byte order. */ + /** + * @brief Set current channel + * + * @param dev pointer to radio device + * @param channel the number of the channel to be set in CPU byte order + * + * @retval 0 channel was successfully set + * @retval -EINVAL The given channel is not within the range of valid + * channels of the driver's current channel page. + * @retval -ENOTSUP The given channel is within the range of valid + * channels of the driver's current channel page but unsupported by the + * current driver. + * @retval -EIO The channel could not be set. + */ int (*set_channel)(const struct device *dev, uint16_t channel); - /** Set/Unset filters. Requires IEEE802154_HW_FILTER capability. */ + /** + * @brief Set/Unset PAN ID, extended or short address filters. + * + * @note requires IEEE802154_HW_FILTER capability. + * + * @param dev pointer to radio device + * @param set true to set the filter, false to remove it + * @param type the type of entity to be added/removed from the filter + * list (a PAN ID or a source/destination address) + * @param filter the entity to be added/removed from the filter list + * + * @retval 0 The filter was successfully added/removed. + * @retval -EINVAL The given filter entity or filter entity type + * was not valid. + * @retval -ENOTSUP Setting/removing this filter or filter type + * is not supported by this driver. + * @retval -EIO Error while setting/removing the filter. + */ int (*filter)(const struct device *dev, bool set, enum ieee802154_filter_type type, const struct ieee802154_filter *filter); - /** Set TX power level in dbm */ + /** + * @brief Set TX power level in dbm + * + * @param dev pointer to radio device + * @param dbm TX power in dbm + * + * @retval 0 The TX power was successfully set. + * @retval -EINVAL The given dbm value is invalid or not supported by + * the driver. + * @retval -EIO The TX power could not be set. + */ int (*set_txpower)(const struct device *dev, int16_t dbm); - /** Transmit a packet fragment */ + /** + * @brief Transmit a packet fragment as a single frame + * + * @warning The driver must not take ownership of the given network + * packet and frame (fragment) buffer. Any data required by the driver + * (including the actual frame content) must be read synchronously and + * copied internally if transmission is delayed or executed + * asynchronously. Both, the packet and the buffer may be re-used or + * released immediately after the function returns. + * + * @note Depending on the level of offloading features supported by the + * driver, the frame may not be fully encrypted/authenticated, may not + * contain an FCS or may contain incomplete information elements (IEs). + * It is the responsibility of L2 implementations to prepare the frame + * according to the offloading capabilities announced by the driver and + * to decide whether CCA, CSMA/CA or ACK procedures need to be executed + * in software ("soft MAC") or will be provided by the driver itself + * ("hard MAC"). + * + * @param dev pointer to radio device + * @param mode the transmission mode, some of which require specific + * offloading capabilities. + * @param pkt pointer to the network packet to be transmitted. + * @param frag pointer to a network buffer containing a single fragment + * with the frame data to be transmitted + * + * @retval 0 The frame was successfully sent or scheduled. If the driver + * supports ACK offloading and the frame requested acknowlegment (AR bit + * set), this means that the packet was successfully acknowledged by its + * peer. + * @retval -ENOTSUP The given TX mode is not supported. + * @retval -EIO The frame could not be sent due to some unspecified + * error. + * @retval -EBUSY The frame could not be sent because the medium was + * busy (CSMA/CA or CCA offloading feature only). + * @retval -ENOMSG The frame was not confirmed by an ACK packet (TX ACK + * offloading feature only). + * @retval -ENOBUFS The frame could not be scheduled due to missing + * internal buffer resources (timed TX offloading feature only). + */ int (*tx)(const struct device *dev, enum ieee802154_tx_mode mode, struct net_pkt *pkt, struct net_buf *frag); - /** Start the device */ + /** + * @brief Start the device and place it in receive mode. + * + * @param dev pointer to radio device + * + * @retval 0 The driver was successfully started. + * @retval -EIO The driver could not be started. + */ int (*start)(const struct device *dev); - /** Stop the device */ + /** + * @brief Stop the device and switch off the receiver (sleep mode). + * + * @param dev pointer to radio device + * + * @retval 0 The driver was successfully stopped. + * @retval -EIO The driver could not be stopped. + */ int (*stop)(const struct device *dev); - /** Start continuous carrier wave transmission. - * To leave this mode, `start()` or `stop()` API function should be called, - * resulting in changing radio's state to receive or sleep, respectively. + /** + * @brief Start continuous carrier wave transmission. + * + * @details To leave this mode, `start()` or `stop()` should be called, + * putting the radio driver in receive or sleep mode, respectively. + * + * @param dev pointer to radio device + * + * @retval 0 continuous carrier wave transmission started + * @retval -EIO not started */ int (*continuous_carrier)(const struct device *dev); - /** Set specific radio driver configuration. */ + /** + * @brief Set radio driver configuration. + * + * @param dev pointer to radio device + * @param type the configuration type to be set + * @param config the configuration parameters to be set for the given + * configuration type + * + * @retval 0 configuration successful + * @retval -ENOTSUP The given configuration type is not supported by + * this driver. + * @retval -EINVAL The configuration parameters are invalid for the + * given configuration type. + * @retval -ENOMEM The configuration cannot be saved due to missing + * memory resources. + * @retval -ENOENT The resource referenced in the configuration + * parameters cannot be found in the configuration. + */ int (*configure)(const struct device *dev, enum ieee802154_config_type type, const struct ieee802154_config *config); /** - * Get the available amount of Sub-GHz channels - * TODO: Replace with a combination of channel page and channel attributes. + * @brief Get the available amount of Sub-GHz channels. + * + * TODO: Replace with a combination of channel page and channel + * attributes. + * + * @param dev pointer to radio device + * + * @return number of available channels in the sub-gigahertz band */ uint16_t (*get_subg_channel_count)(const struct device *dev); - /** Run an energy detection scan. - * Note: channel must be set prior to request this function. - * duration parameter is in ms. - * Requires IEEE802154_HW_ENERGY_SCAN capability. + /** + * @brief Run an energy detection scan. + * + * @note requires IEEE802154_HW_ENERGY_SCAN capability + * + * @note The radio channel must be set prior to calling this function. + * + * @param dev pointer to radio device + * @param duration duration of energy scan in ms + * @param done_cb function called when the energy scan has finished + * + * @retval 0 the energy detection scan was successfully scheduled + * + * @retval -EBUSY the energy detection scan could not be scheduled at + * this time + * @retval -EALREADY a previous energy detection scan has not finished + * yet. + * @retval -ENOTSUP This driver does not support energy scans. */ int (*ed_scan)(const struct device *dev, uint16_t duration, energy_scan_done_cb_t done_cb); - /** Get the current radio time in microseconds - * Requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME capabilities. + /** + * @brief Get the current time in nanoseconds relative to the network + * subsystem's local uptime clock as represented by this network + * interface. + * + * See @ref net_time_t for semantic details. + * + * @note requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME + * capabilities. + * + * @param dev pointer to radio device + * + * @return nanoseconds relative to the network subsystem's local clock */ - uint64_t (*get_time)(const struct device *dev); + net_time_t (*get_time)(const struct device *dev); - /** Get the current accuracy, in units of ± ppm, of the clock used for - * scheduling delayed receive or transmit radio operations. - * Note: Implementations may optimize this value based on operational - * conditions (i.e.: temperature). - * Requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME capabilities. + /** + * @brief Get the current estimated worst case accuracy (maximum ± + * deviation from the nominal frequency) of the network subsystem's + * local clock used to calculate tolerances and guard times when + * scheduling delayed receive or transmit radio operations. + * + * The deviation is given in units of PPM (parts per million). + * + * @note requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME + * capabilities. + * + * @note Implementations may estimate this value based on current + * operating conditions (e.g. temperature). + * + * @param dev pointer to radio device + * + * @return current estimated clock accuracy in PPM */ uint8_t (*get_sch_acc)(const struct device *dev); - /** Get the value of an attribute. - * If the requested attribute is supported by implementation, this function returns 0 - * and fills appropriate version of union in `value`. - * If requested attribute is not supported, this function returns -ENOENT. + /** + * @brief Get the value of a driver specific attribute. + * + * @note This function SHALL NOT return any values configurable by the + * MAC (L2) layer. It is reserved to non-boolean (i.e. scalar or + * structured) attributes that originate from the driver implementation + * and cannot be directly or indirectly derived by L2. Boolean + * attributes SHALL be implemented as @ref ieee802154_hw_caps. + * + * @retval 0 The requested attribute is supported by the driver and the + * value can be retrieved from the corresponding @ref ieee802154_attr_value + * member. + * + * @retval -ENOENT The driver does not provide the requested attribute. + * The value structure has does not been updated with attribute data. */ int (*attr_get)(const struct device *dev, enum ieee802154_attr attr, @@ -515,11 +809,10 @@ BUILD_ASSERT(offsetof(struct ieee802154_radio_api, iface_api) == 0); * @brief Check if AR flag is set on the frame inside given net_pkt * * @param frag A valid pointer on a net_buf structure, must not be NULL, - * and its length should be at least made of 1 byte (ACK frames - * are the smallest frames on 15.4 and made of 3 bytes, not - * not counting the FCS part). + * and its length should be at least 1 byte (ImmAck frames are the + * shortest supported frames with 3 bytes excluding FCS). * - * @return True if AR flag is set, False otherwise + * @return true if AR flag is set, false otherwise */ static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag) { diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index d540a91d9ffa793..fbc2d2773d1d015 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -94,10 +95,24 @@ struct net_pkt { struct net_if *orig_iface; /* Original network interface */ #endif -#if defined(CONFIG_NET_PKT_TIMESTAMP) +#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME) /** - * Timestamp if available. - * For IEEE 802.15.4 packets this refers to the first symbol of the MAC Header. + * TX or RX timestamp if available + * + * For packets that have been sent over the medium, the timestamp refers + * to the time the message timestamp point was encountered at the + * reference plane. + * + * Unsent packages can be scheduled by setting the timestamp to a future + * point in time. + * + * All timestamps refer to the network subsystem's local clock. + * + * See @ref net_ptp_time for definitions of local clock, message + * timestamp point and reference plane. See @ref net_time_t for + * semantics of the network reference clock. + * + * TODO: Replace with net_time_t to decouple from PTP. */ struct net_ptp_time timestamp; #endif @@ -123,11 +138,6 @@ struct net_pkt { }; #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */ -#if defined(CONFIG_NET_PKT_TXTIME) - /** Network packet TX time in the future (in nanoseconds) */ - uint64_t txtime; -#endif /* CONFIG_NET_PKT_TXTIME */ - /** Reference counter */ atomic_t atomic_ref; @@ -943,7 +953,7 @@ static inline void net_pkt_set_vlan_tci(struct net_pkt *pkt, uint16_t tci) } #endif -#if defined(CONFIG_NET_PKT_TIMESTAMP) +#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME) static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt) { return &pkt->timestamp; @@ -969,7 +979,7 @@ static inline void net_pkt_set_timestamp(struct net_pkt *pkt, ARG_UNUSED(pkt); ARG_UNUSED(timestamp); } -#endif /* CONFIG_NET_PKT_TIMESTAMP */ +#endif /* CONFIG_NET_PKT_TIMESTAMP || CONFIG_NET_PKT_TXTIME */ #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS) static inline uint32_t net_pkt_create_time(struct net_pkt *pkt) @@ -998,30 +1008,33 @@ static inline void net_pkt_set_create_time(struct net_pkt *pkt, } #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */ -#if defined(CONFIG_NET_PKT_TXTIME) +/** + * @deprecated Use @ref net_pkt_timestamp instead. + */ static inline uint64_t net_pkt_txtime(struct net_pkt *pkt) { - return pkt->txtime; -} - -static inline void net_pkt_set_txtime(struct net_pkt *pkt, uint64_t txtime) -{ - pkt->txtime = txtime; -} +#if defined(CONFIG_NET_PKT_TXTIME) + return pkt->timestamp.second * NSEC_PER_SEC + pkt->timestamp.nanosecond; #else -static inline uint64_t net_pkt_txtime(struct net_pkt *pkt) -{ ARG_UNUSED(pkt); return 0; +#endif /* CONFIG_NET_PKT_TXTIME */ } +/** + * @deprecated Use @ref net_pkt_set_timestamp instead. + */ static inline void net_pkt_set_txtime(struct net_pkt *pkt, uint64_t txtime) { +#if defined(CONFIG_NET_PKT_TXTIME) + pkt->timestamp.second = txtime / NSEC_PER_SEC; + pkt->timestamp.nanosecond = txtime % NSEC_PER_SEC; +#else ARG_UNUSED(pkt); ARG_UNUSED(txtime); -} #endif /* CONFIG_NET_PKT_TXTIME */ +} #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \ defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL) diff --git a/include/zephyr/net/net_time.h b/include/zephyr/net/net_time.h new file mode 100644 index 000000000000000..6277ea994c8628c --- /dev/null +++ b/include/zephyr/net/net_time.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 Zephyr Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Representation of nanosecond resolution elapsed time and timestamps in + * the network stack. + * + * Inspired by + * https://github.com/torvalds/linux/blob/master/include/linux/ktime.h and + * https://github.com/torvalds/linux/blob/master/[tools/]include/linux/time64.h + */ + +#ifndef ZEPHYR_INCLUDE_NET_NET_TIME_H_ +#define ZEPHYR_INCLUDE_NET_NET_TIME_H_ + +/* Include required for NSEC_PER_* constants. */ +#include "zephyr/sys_clock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Any occurrence of net_time_t specifies a concept of nanosecond + * resolution scalar time span, future (positive) or past (negative) relative + * time or absolute timestamp referred to some local network uptime reference + * clock that does not wrap during uptime and is - in a certain, well-defined + * sense - common to all local network interfaces, sometimes even to remote + * interfaces on the same network. + * + * This type is EXPERIMENTAL. Usage is currently restricted to representation of + * time within the network subsystem. + * + * @details Timed network protocols (PTP, TDMA, ...) usually require several + * local or remote interfaces to share a common notion of elapsed time within + * well-defined tolerances. Network uptime therefore differs from time + * represented by a single hardware counter peripheral in that it will need to + * be represented in several distinct hardware peripherals with different + * frequencies, accuracy and precision. To co-operate, these hardware counters + * will have to be "syntonized" or "disciplined" (i.e. frequency and phase + * locked) with respect to a common local or remote network reference time + * signal. Be aware that while syntonized clocks share the same frequency and + * phase, they do not usually share the same epoch (zero-point). + * + * This also explains why network time, if represented as a cycle value of some + * specific hardware counter, will never be "precise" but only can be "good + * enough" with respect to the tolerances (resolution, drift, jitter) required + * by a given network protocol. All counter peripherals involved in a timed + * network protocol must comply with these tolerances. + * + * Please use specific cycle/tick counter values rather than net_time_t whenever + * possible especially when referring to the kernel system clock or values of + * any single counter peripheral. + * + * net_time_t cannot represent general clocks referred to an arbitrary epoch as + * it only covers roughly +/- ~290 years. It also cannot be used to represent + * time according to a more complex timescale (e.g. including leap seconds, time + * adjustments, complex calendars or time zones). In these cases you may use + * @ref timespec (C11, POSIX.1-2001), @ref timeval (POSIX.1-2001) or broken down + * time as in @ref tm (C90). The advantage of net_time_t over these structured + * time representations is lower memory footprint, faster and simpler scalar + * arithmetics and easier conversion from/to low-level hardware counter values. + * Also net_time_t can be used in the network stack as well as in applications + * while POSIX concepts cannot. Converting net_time_t from/to structured time + * representations is possible in a limited way but - except for @ref timespec - + * requires concepts that must be implemented by higher-level APIs. Utility + * functions converting from/to @ref timespec will be provided as part of the + * net_time_t API as and when needed. + * + * If you want to represent more coarse grained scalar time in network + * applications, use @ref time_t (C99, POSIX.1-2001) which is specified to + * represent seconds or @ref suseconds_t (POSIX.1-2001) for microsecond + * resolution. Kernel @ref k_ticks_t and cycles (both specific to Zephyr) have + * an unspecified resolution but are useful to represent kernel timer values and + * implement high resolution spinning. + * + * If you need even finer grained time resolution, you may want to look at + * (g)PTP concepts, see @ref net_ptp_extended_time. + * + * The reason why we don't use int64_t directly to represent scalar nanosecond + * resolution times in the network stack is that it has been shown in the past + * that fields using generic type will often not be used correctly (e.g. with + * the wrong resolution or to represent underspecified concepts of time with + * unclear syntonization semantics). + * + * Any API that exposes or consumes net_time_t values SHALL ensure that it + * maintains the specified contract including all protocol specific tolerances + * and therefore clients can rely on common semantics of this type. This makes + * times coming from different hardware peripherals and even from different + * network nodes comparable within well-defined limits and therefore net_time_t + * is the ideal intermediate building block for timed network protocols. + */ +typedef int64_t net_time_t; + +/** The largest positive time value that can be represented by net_time_t */ +#define NET_TIME_MAX INT64_MAX + +/** The smallest negative time value that can be represented by net_time_t */ +#define NET_TIME_MIN INT64_MIN + +/** The largest positive number of seconds that can be safely represented by net_time_t */ +#define NET_TIME_SEC_MAX (NET_TIME_MAX / NSEC_PER_SEC) + +/** The smallest negative number of seconds that can be safely represented by net_time_t */ +#define NET_TIME_SEC_MIN (NET_TIME_MIN / NSEC_PER_SEC) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_NET_TIME_H_ */ diff --git a/include/zephyr/net/ptp_time.h b/include/zephyr/net/ptp_time.h index 81c445511369ad1..99c5037e7ba0b21 100644 --- a/include/zephyr/net/ptp_time.h +++ b/include/zephyr/net/ptp_time.h @@ -8,6 +8,8 @@ * @file * @brief Public functions for the Precision Time Protocol time specification. * + * References are to version 2019 of IEEE 1588, ("PTP") + * and version 2020 of IEEE 802.1AS ("gPTP"). */ #ifndef ZEPHYR_INCLUDE_NET_PTP_TIME_H_ @@ -21,6 +23,7 @@ */ #include +#include #include #ifdef __cplusplus @@ -28,13 +31,80 @@ extern "C" { #endif /** - * @brief Precision Time Protocol Timestamp format. + * @brief (Generalized) Precision Time Protocol Timestamp format. * - * This structure represents a timestamp according - * to the Precision Time Protocol standard. + * @details This structure represents a timestamp according to the Precision + * Time Protocol standard ("PTP", IEEE 1588, section 5.3.3), the Generalized + * Precision Time Protocol standard ("gPTP", IEEE 802.1AS, section 6.4.3.4), or + * any other well-defined context in which precision structured timestamps are + * required on network messages in Zephyr. * - * Seconds are encoded as a 48 bits unsigned integer. - * Nanoseconds are encoded as a 32 bits unsigned integer. + * Seconds are encoded as a 48 bits unsigned integer. Nanoseconds are encoded + * as a 32 bits unsigned integer. + * + * In the context of (g)PTP, @em timestamps designate the time, relative to a + * local clock ("LocalClock") at which the message timestamp point passes a + * reference plane marking the boundary between the PTP Instance and the network + * medium (IEEE 1855, section 7.3.4.2; IEEE 802.1AS, section 8.4.3). + * + * The exact definitions of the message timestamp point and + * reference plane depends on the network medium and use case. + * + * For (g)PTP the media-specific message timestamp points and reference planes + * are defined in the standard. In non-PTP contexts specific to Zephyr, + * timestamps are measured relative to the same local clock but with a + * context-specific message timestamp point and reference plane, defined below + * per use case. + * + * A @em "LocalClock" is a freerunning clock, embedded into a well-defined + * entity (e.g. a PTP Instance) and provides a common time to that entity + * relative to an arbitrary epoch (IEEE 1855, section 3.1.26, IEEE 802.1AS, + * section 3.16). + * + * In Zephyr, the local clock is usually any instance of a kernel system clock + * driver, counter driver, RTC API driver or low-level counter/timer peripheral + * (e.g. an ethernet peripheral with hardware timestamp support or a radio + * timer) with sufficient precision for the context in which it is used. + * + * See IEEE 802.1AS, Annex B for specific performance requirements regarding + * conformance of local clocks in the gPTP context. See IEEE 1588, Annex A, + * section A5.4 for general performance requirements regarding PTP local clocks. + * See IEEE 802.15.4-2020, section 15.7 for requirements in the context of + * ranging applications and ibid., section 6.7.6 for the relation between guard + * times and clock accuracy which again influence the precision required for + * subprotocols like CSL, TSCH, RIT, etc. + * + * Applications that use timestamps across different subsystems or media must + * ensure that they understand the definition of the respective reference planes + * and interpret timestamps accordingly. Applications must further ensure that + * timestamps are either all referenced to the same local clock or convert + * between clocks based on sufficiently precise conversion algorithms. + * + * Timestamps may be measured on ingress (RX timestamps) or egress (TX + * timestamps) of network messages. Timestamps can also be used to schedule a + * network message to a well-defined point in time in the future at which it is + * to be sent over the medium (timed TX). A future timestamp and a duration, + * both referenced to the local clock, may be given to specify a time window at + * which a network device should expect incoming messages (RX window). + * + * In Zephyr this timestamp structure is currently used in the following + * contexts: + * * gPTP for Full Duplex Point-to-Point IEEE 802.3 links (IEEE 802.1AS, + * section 11): the reference plane and message timestamp points are as + * defined in the standard. + * * IEEE 802.15.4 timed TX and RX: Timestamps designate the point in time at + * which the end of the last symbol of the start-of-frame delimiter (SFD) (or + * equivalently, the start of the first symbol of the PHY header) is at the + * local antenna. The standard also refers to this as the "RMARKER" (IEEE + * 802.15.4-2020, section 6.9.1) or "symbol boundary" (ibid., section 6.5.2), + * depending on the context. In the context of beacon timestamps, the + * difference between the timestamp measurement plane and the reference plane + * is defined by the MAC PIB attribute "macSyncSymbolOffset", ibid., section + * 8.4.3.1, table 8-94. + * + * If further use cases are added to Zephyr using this timestamp structure, + * their clock performance requirements, message timestamp points and reference + * plane definition SHALL be added to the above list. */ struct net_ptp_time { /** Seconds encoded on 48 bits. */ @@ -62,14 +132,17 @@ struct net_ptp_time { #endif /** - * @brief Precision Time Protocol Extended Timestamp format. + * @brief Generalized Precision Time Protocol Extended Timestamp format. + * + * @details This structure represents an extended timestamp according to the + * Generalized Precision Time Protocol standard (IEEE 802.1AS), see section + * 6.4.3.5. * - * This structure represents an extended timestamp according - * to the Precision Time Protocol standard. + * Seconds are encoded as 48 bits unsigned integer. Fractional nanoseconds are + * encoded as 48 bits, their unit is 2*(-16) ns. * - * Seconds are encoded as 48 bits unsigned integer. - * Fractional nanoseconds are encoded as 48 bits, their unit - * is 2*(-16) ns. + * A precise definition of PTP timestamps and their uses in Zephyr is given in + * the description of @ref net_ptp_time. */ struct net_ptp_extended_time { /** Seconds encoded on 48 bits. */ @@ -105,6 +178,50 @@ struct net_ptp_extended_time { }; } __packed; +/** + * @brief Convert a PTP timestamp to a nanosecond precision timestamp, both + * related to the local network reference clock. + * + * @note Only timestamps representing up to ~290 years can be converted to + * nanosecond timestamps. Larger timestamps will return the maximum + * representable nanosecond precision timestamp. + * + * @param ts the PTP timestamp + * + * @return the corresponding nanosecond precision timestamp + */ +static inline net_time_t net_ptp_time_to_ns(struct net_ptp_time *ts) +{ + if (!ts) { + return 0; + } + + if (ts->second >= NET_TIME_SEC_MAX) { + return NET_TIME_MAX; + } + + return ((int64_t)ts->second * NSEC_PER_SEC) + ts->nanosecond; +} + +/** + * @brief Convert a nanosecond precision timestamp to a PTP timestamp, both + * related to the local network reference clock. + * + * @param nsec a nanosecond precision timestamp + * + * @return the corresponding PTP timestamp + */ +static inline struct net_ptp_time ns_to_net_ptp_time(net_time_t nsec) +{ + struct net_ptp_time ts; + + __ASSERT_NO_MSG(nsec >= 0); + + ts.second = nsec / NSEC_PER_SEC; + ts.nanosecond = nsec % NSEC_PER_SEC; + return ts; +} + /** * @} */ diff --git a/include/zephyr/pm/device.h b/include/zephyr/pm/device.h index 734f6c08a60f4cc..29cd4b26a1e8dc0 100644 --- a/include/zephyr/pm/device.h +++ b/include/zephyr/pm/device.h @@ -581,6 +581,22 @@ int pm_device_power_domain_remove(const struct device *dev, * @retval false If device is not currently powered */ bool pm_device_is_powered(const struct device *dev); + +/** + * @brief Setup a device driver into the lowest valid power mode + * + * This helper function is intended to be called at the end of a driver + * init function to automatically setup the device into the lowest power + * mode. It assumes that the device has been configured as if it is in + * @ref PM_DEVICE_STATE_OFF. + * + * @param dev Device instance. + * @param action_cb Device PM control callback function. + * @retval 0 On success. + * @retval -errno Error code from @a action_cb on failure. + */ +int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb); + #else static inline int pm_device_state_get(const struct device *dev, enum pm_device_state *state) @@ -667,6 +683,19 @@ static inline bool pm_device_is_powered(const struct device *dev) ARG_UNUSED(dev); return true; } + +static inline int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb) +{ + int rc; + + /* When power management is not enabled, all drivers should initialise to active state */ + rc = action_cb(dev, PM_DEVICE_ACTION_TURN_ON); + if (rc == 0) { + rc = action_cb(dev, PM_DEVICE_ACTION_RESUME); + } + return rc; +} + #endif /* CONFIG_PM_DEVICE */ /** @} */ diff --git a/include/zephyr/pm/device_runtime.h b/include/zephyr/pm/device_runtime.h index 42a833432f5065f..09bf0c04278e47c 100644 --- a/include/zephyr/pm/device_runtime.h +++ b/include/zephyr/pm/device_runtime.h @@ -81,12 +81,16 @@ int pm_device_runtime_disable(const struct device *dev); * pm_device_runtime_put_async(), this function will wait for the operation to * finish to then resume the device. * + * @note It is safe to use this function in contexts where blocking is not + * allowed, e.g. ISR, provided the device PM implementation does not block. + * * @funcprops \pre_kernel_ok * * @param dev Device instance. * * @retval 0 If it succeeds. In case device runtime PM is not enabled or not * available this function will be a no-op and will also return 0. + * @retval -EWOUDBLOCK If call would block but it is not allowed (e.g. in ISR). * @retval -errno Other negative errno, result of the PM action callback. */ int pm_device_runtime_get(const struct device *dev); diff --git a/include/zephyr/pm/state.h b/include/zephyr/pm/state.h index c7fe6f4b4acd62d..1d21ffd997a91aa 100644 --- a/include/zephyr/pm/state.h +++ b/include/zephyr/pm/state.h @@ -158,25 +158,42 @@ struct pm_state_info { /** @cond INTERNAL_HIDDEN */ +/** + * @brief Helper macro that expands to 1 if a phandle node is enabled, 0 otherwise. + * + * @param node_id Node identifier. + * @param prop Property holding phandle-array. + * @param idx Index within the array. + */ +#define Z_DT_PHANDLE_01(node_id, prop, idx) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, prop, idx), okay), \ + (1), (0)) + /** * @brief Helper macro to initialize an entry of a struct pm_state_info array * when using UTIL_LISTIFY in PM_STATE_INFO_LIST_FROM_DT_CPU. * + * @note Only enabled states are initialized. + * * @param i UTIL_LISTIFY entry index. * @param node_id A node identifier with compatible zephyr,power-state */ -#define Z_PM_STATE_INFO_FROM_DT_CPU(i, node_id) \ - PM_STATE_INFO_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)) +#define Z_PM_STATE_INFO_FROM_DT_CPU(i, node_id) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i), okay), \ + (PM_STATE_INFO_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ()) /** * @brief Helper macro to initialize an entry of a struct pm_state array when * using UTIL_LISTIFY in PM_STATE_LIST_FROM_DT_CPU. * + * @note Only enabled states are initialized. + * * @param i UTIL_LISTIFY entry index. * @param node_id A node identifier with compatible zephyr,power-state */ -#define Z_PM_STATE_FROM_DT_CPU(i, node_id) \ - PM_STATE_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)) +#define Z_PM_STATE_FROM_DT_CPU(i, node_id) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i), okay), \ + (PM_STATE_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ()) /** @endcond */ @@ -204,18 +221,20 @@ struct pm_state_info { DT_ENUM_IDX(node_id, power_state_name) /** - * @brief Obtain number of CPU power states supported by the given CPU node - * identifier. + * @brief Obtain number of CPU power states supported and enabled by the given + * CPU node identifier. * * @param node_id A CPU node identifier. - * @return Number of supported CPU power states. + * @return Number of supported and enabled CPU power states. */ -#define DT_NUM_CPU_POWER_STATES(node_id) \ - DT_PROP_LEN_OR(node_id, cpu_power_states, 0) +#define DT_NUM_CPU_POWER_STATES(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, cpu_power_states), \ + (DT_FOREACH_PROP_ELEM_SEP(node_id, cpu_power_states, Z_DT_PHANDLE_01, (+))), \ + (0)) /** * @brief Initialize an array of struct pm_state_info with information from all - * the states present in the given CPU node identifier. + * the states present and enabled in the given CPU node identifier. * * Example devicetree fragment: * @@ -258,13 +277,13 @@ struct pm_state_info { */ #define PM_STATE_INFO_LIST_FROM_DT_CPU(node_id) \ { \ - LISTIFY(DT_NUM_CPU_POWER_STATES(node_id), \ - Z_PM_STATE_INFO_FROM_DT_CPU, (,), node_id) \ + LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0), \ + Z_PM_STATE_INFO_FROM_DT_CPU, (), node_id) \ } /** * @brief Initialize an array of struct pm_state with information from all the - * states present in the given CPU node identifier. + * states present and enabled in the given CPU node identifier. * * Example devicetree fragment: * @@ -305,8 +324,8 @@ struct pm_state_info { */ #define PM_STATE_LIST_FROM_DT_CPU(node_id) \ { \ - LISTIFY(DT_NUM_CPU_POWER_STATES(node_id), \ - Z_PM_STATE_FROM_DT_CPU, (,), node_id) \ + LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0), \ + Z_PM_STATE_FROM_DT_CPU, (), node_id) \ } diff --git a/include/zephyr/toolchain/xcc.h b/include/zephyr/toolchain/xcc.h index c9344926c52afbf..65ddc7ea35edb4d 100644 --- a/include/zephyr/toolchain/xcc.h +++ b/include/zephyr/toolchain/xcc.h @@ -19,21 +19,10 @@ #endif #ifdef __clang__ -#if __clang_major__ >= 10 -#define __fallthrough __attribute__((fallthrough)) -#endif - -#define TOOLCHAIN_CLANG_VERSION \ - ((__clang_major__ * 10000) + (__clang_minor__ * 100) + \ - __clang_patchlevel__) - -#if TOOLCHAIN_CLANG_VERSION >= 30800 -#define TOOLCHAIN_HAS_C_GENERIC 1 -#define TOOLCHAIN_HAS_C_AUTO_TYPE 1 -#endif -#endif - +#include +#else #include +#endif #ifndef __clang__ #undef __BYTE_ORDER__ diff --git a/include/zephyr/usb/bos.h b/include/zephyr/usb/bos.h index f61b30a8cc96e25..b7a0ef08339fe37 100644 --- a/include/zephyr/usb/bos.h +++ b/include/zephyr/usb/bos.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,40 +8,53 @@ #ifndef ZEPHYR_INCLUDE_USB_BOS_H_ #define ZEPHYR_INCLUDE_USB_BOS_H_ -#if defined(CONFIG_USB_DEVICE_BOS) -#define USB_DEVICE_BOS_DESC_DEFINE_HDR \ - static __in_section(usb, bos_desc_area, 0) __aligned(1) __used +#include + +/** + * @brief USB Binary Device Object Store support + * @defgroup usb_bos USB BOS support + * @ingroup usb + * @{ + */ + +/** + * @brief Helper macro to place the BOS compatibility descriptor + * in the right memory section. + */ #define USB_DEVICE_BOS_DESC_DEFINE_CAP \ static __in_section(usb, bos_desc_area, 1) __aligned(1) __used -#define USB_BOS_CAPABILITY_EXTENSION 0x02 -#define USB_BOS_CAPABILITY_PLATFORM 0x05 +/** Device capability type codes */ +enum usb_bos_capability_types { + USB_BOS_CAPABILITY_EXTENSION = 0x02, + USB_BOS_CAPABILITY_PLATFORM = 0x05, +}; -/* BOS Capability Descriptor */ -struct usb_bos_platform_descriptor { +/** BOS USB 2.0 extension capability descriptor */ +struct usb_bos_capability_lpm { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDevCapabilityType; - uint8_t bReserved; - uint8_t PlatformCapabilityUUID[16]; + uint32_t bmAttributes; } __packed; -/* BOS Descriptor */ -struct usb_bos_descriptor { +/** BOS platform capability descriptor */ +struct usb_bos_platform_descriptor { uint8_t bLength; uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumDeviceCaps; + uint8_t bDevCapabilityType; + uint8_t bReserved; + uint8_t PlatformCapabilityUUID[16]; } __packed; -/* BOS Capability webusb */ +/** WebUSB specific part of platform capability descriptor */ struct usb_bos_capability_webusb { uint16_t bcdVersion; uint8_t bVendorCode; uint8_t iLandingPage; } __packed; -/* BOS Capability MS OS Descriptors version 2 */ +/** Microsoft OS 2.0 descriptor specific part of platform capability descriptor */ struct usb_bos_capability_msos { uint32_t dwWindowsVersion; uint16_t wMSOSDescriptorSetTotalLength; @@ -48,20 +62,47 @@ struct usb_bos_capability_msos { uint8_t bAltEnumCode; } __packed; -struct usb_bos_capability_lpm { +/** + * @brief Register BOS capability descriptor + * + * This function should be used by the application to register BOS capability + * descriptors before the USB device stack is enabled. + * + * @param[in] hdr Pointer to BOS capability descriptor + */ +void usb_bos_register_cap(struct usb_bos_platform_descriptor *hdr); + +/** + * @cond INTERNAL_HIDDEN + * Internally used functions + */ + +/* BOS Descriptor (root descriptor) */ +struct usb_bos_descriptor { uint8_t bLength; uint8_t bDescriptorType; - uint8_t bDevCapabilityType; - uint32_t bmAttributes; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; } __packed; +#define USB_DEVICE_BOS_DESC_DEFINE_HDR \ + static __in_section(usb, bos_desc_area, 0) __aligned(1) __used + size_t usb_bos_get_length(void); + void usb_bos_fix_total_length(void); -void usb_bos_register_cap(struct usb_bos_platform_descriptor *hdr); + const void *usb_bos_get_header(void); + +#if defined(CONFIG_USB_DEVICE_BOS) int usb_handle_bos(struct usb_setup_packet *setup, int32_t *len, uint8_t **data); #else #define usb_handle_bos(x, y, z) -ENOTSUP #endif +/** @endcond */ + +/** + * @} + */ #endif /* ZEPHYR_INCLUDE_USB_BOS_H_ */ diff --git a/include/zephyr/usb/class/usb_msc.h b/include/zephyr/usb/class/usb_msc.h deleted file mode 100644 index add76ac68bf5ec2..000000000000000 --- a/include/zephyr/usb/class/usb_msc.h +++ /dev/null @@ -1,109 +0,0 @@ -/* usb_msc.h - USB MSC public header */ - -/* - * Copyright (c) 2017 PHYTEC Messtechnik GmbH - * - * SPDX-License-Identifier: Apache-2.0 - * - * This file is based on mass_storage.h - * - * This file are derived from material that is - * Copyright (c) 2010-2011 mbed.org, MIT License - * Copyright (c) 2016 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - - -/** - * @file - * @brief USB Mass Storage Class public header - * - * Header follows the Mass Storage Class Specification - * (Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf) and - * Mass Storage Class Bulk-Only Transport Specification - * (usbmassbulk_10.pdf). - * Header is limited to Bulk-Only Transfer protocol. - */ - -#ifndef ZEPHYR_INCLUDE_USB_CLASS_USB_MSC_H_ -#define ZEPHYR_INCLUDE_USB_CLASS_USB_MSC_H_ - -/** MSC Subclass and Protocol Codes */ -#define SCSI_TRANSPARENT_SUBCLASS 0x06 -#define BULK_ONLY_TRANSPORT_PROTOCOL 0x50 - -/** MSC Request Codes for Bulk-Only Transport */ -#define MSC_REQUEST_GET_MAX_LUN 0xFE -#define MSC_REQUEST_RESET 0xFF - -/** MSC Command Block Wrapper (CBW) Signature */ -#define CBW_Signature 0x43425355 - -/** MSC Command Block Wrapper Flags */ -#define CBW_DIRECTION_DATA_IN 0x80 - -/** MSC Bulk-Only Command Block Wrapper (CBW) */ -struct CBW { - uint32_t Signature; - uint32_t Tag; - uint32_t DataLength; - uint8_t Flags; - uint8_t LUN; - uint8_t CBLength; - uint8_t CB[16]; -} __packed; - -/** MSC Command Status Wrapper (CBW) Signature */ -#define CSW_Signature 0x53425355 - -/** MSC Command Block Status Values */ -#define CSW_STATUS_CMD_PASSED 0x00 -#define CSW_STATUS_CMD_FAILED 0x01 -#define CSW_STATUS_PHASE_ERROR 0x02 - -/** MSC Bulk-Only Command Status Wrapper (CSW) */ -struct CSW { - uint32_t Signature; - uint32_t Tag; - uint32_t DataResidue; - uint8_t Status; -} __packed; - -/** SCSI transparent command set used by MSC */ -#define TEST_UNIT_READY 0x00 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define INQUIRY 0x12 -#define MODE_SELECT6 0x15 -#define MODE_SENSE6 0x1A -#define START_STOP_UNIT 0x1B -#define MEDIA_REMOVAL 0x1E -#define READ_FORMAT_CAPACITIES 0x23 -#define READ_CAPACITY 0x25 -#define READ10 0x28 -#define WRITE10 0x2A -#define VERIFY10 0x2F -#define READ12 0xA8 -#define WRITE12 0xAA -#define MODE_SELECT10 0x55 -#define MODE_SENSE10 0x5A - -#endif /* ZEPHYR_INCLUDE_USB_CLASS_USB_MSC_H_ */ diff --git a/include/zephyr/usb/usbd.h b/include/zephyr/usb/usbd.h index f55047a43a18849..aad53b47550339b 100644 --- a/include/zephyr/usb/usbd.h +++ b/include/zephyr/usb/usbd.h @@ -126,7 +126,7 @@ enum usbd_ch9_state { struct usbd_ch9_data { /** Setup packet, up-to-date for the respective control request */ struct usb_setup_packet setup; - /** Control type, internaly used for stage verification */ + /** Control type, internally used for stage verification */ int ctrl_type; /** Protocol state of the USB device stack */ enum usbd_ch9_state state; @@ -183,7 +183,7 @@ struct usbd_contex { * @brief Vendor Requests Table */ struct usbd_cctx_vendor_req { - /** Array of vendor requests supportd by the class */ + /** Array of vendor requests supported by the class */ const uint8_t *reqs; /** Length of the array */ uint8_t len; diff --git a/lib/cpp/Kconfig b/lib/cpp/Kconfig index 3cfb8ac57e9df44..52084fbe6906285 100644 --- a/lib/cpp/Kconfig +++ b/lib/cpp/Kconfig @@ -12,7 +12,7 @@ config CPP if CPP -choice +choice STD_CPP prompt "C++ Standard" default STD_CPP11 help diff --git a/lib/hash/Kconfig.hash_map b/lib/hash/Kconfig.hash_map index dfbe9e8a82eac1d..d36a4e124535525 100644 --- a/lib/hash/Kconfig.hash_map +++ b/lib/hash/Kconfig.hash_map @@ -39,9 +39,9 @@ config SYS_HASH_MAP_OA_LP config SYS_HASH_MAP_CXX bool "C++ Hashmap" - select CPLUSPLUS - select LIB_CPLUSPLUS - select EXCEPTIONS + select CPP + select REQUIRES_FULL_LIBCPP + select CPP_EXCEPTIONS help This enables a C wrapper around the C++ std::unordered_map. diff --git a/lib/os/dec.c b/lib/os/dec.c index d087fa1635b22f7..188235ff80d504a 100644 --- a/lib/os/dec.c +++ b/lib/os/dec.c @@ -12,10 +12,10 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value) uint8_t num_digits = 0; uint8_t digit; - while (buflen > 0 && divisor > 0) { + while ((buflen > 0) && (divisor > 0)) { digit = value / divisor; - if (digit != 0 || divisor == 1 || num_digits != 0) { - *buf = (char)digit + '0'; + if ((digit != 0) || (divisor == 1) || (num_digits != 0)) { + *buf = digit + (char)'0'; buf++; buflen--; num_digits++; @@ -25,7 +25,7 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value) divisor /= 10; } - if (buflen) { + if (buflen != 0) { *buf = '\0'; } diff --git a/lib/os/hex.c b/lib/os/hex.c index b26c470d1c36954..58383f9c977b834 100644 --- a/lib/os/hex.c +++ b/lib/os/hex.c @@ -27,9 +27,9 @@ int char2hex(char c, uint8_t *x) int hex2char(uint8_t x, char *c) { if (x <= 9) { - *c = x + '0'; + *c = x + (char)'0'; } else if (x <= 15) { - *c = x - 10 + 'a'; + *c = x - 10 + (char)'a'; } else { return -EINVAL; } @@ -39,33 +39,33 @@ int hex2char(uint8_t x, char *c) size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen) { - if (hexlen < (buflen * 2 + 1)) { + if (hexlen < (buflen * 2U + 1U)) { return 0; } for (size_t i = 0; i < buflen; i++) { - if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) { + if (hex2char(buf[i] >> 4, &hex[2U * i]) < 0) { return 0; } - if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) { + if (hex2char(buf[i] & 0xf, &hex[2U * i + 1U]) < 0) { return 0; } } - hex[2 * buflen] = '\0'; - return 2 * buflen; + hex[2U * buflen] = '\0'; + return 2U * buflen; } size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen) { uint8_t dec; - if (buflen < hexlen / 2 + hexlen % 2) { + if (buflen < hexlen / 2U + hexlen % 2U) { return 0; } /* if hexlen is uneven, insert leading zero nibble */ - if (hexlen % 2) { + if (hexlen % 2U) { if (char2hex(hex[0], &dec) < 0) { return 0; } @@ -75,17 +75,17 @@ size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen) } /* regular hex conversion */ - for (size_t i = 0; i < hexlen / 2; i++) { - if (char2hex(hex[2 * i], &dec) < 0) { + for (size_t i = 0; i < hexlen / 2U; i++) { + if (char2hex(hex[2U * i], &dec) < 0) { return 0; } buf[i] = dec << 4; - if (char2hex(hex[2 * i + 1], &dec) < 0) { + if (char2hex(hex[2U * i + 1U], &dec) < 0) { return 0; } buf[i] += dec; } - return hexlen / 2 + hexlen % 2; + return hexlen / 2U + hexlen % 2U; } diff --git a/lib/os/shared_multi_heap.c b/lib/os/shared_multi_heap.c index e2ae4bf7d78486f..57ff2970cdeff7f 100644 --- a/lib/os/shared_multi_heap.c +++ b/lib/os/shared_multi_heap.c @@ -12,17 +12,19 @@ #include static struct sys_multi_heap shared_multi_heap; -static struct sys_heap heap_pool[MAX_SHARED_MULTI_HEAP_ATTR][MAX_MULTI_HEAPS]; -static unsigned int attr_cnt[MAX_SHARED_MULTI_HEAP_ATTR]; +static struct { + struct sys_heap heap_pool[MAX_MULTI_HEAPS]; + unsigned int heap_cnt; +} smh_data[MAX_SHARED_MULTI_HEAP_ATTR]; static void *smh_choice(struct sys_multi_heap *mheap, void *cfg, size_t align, size_t size) { struct sys_heap *h; - unsigned int attr; + enum shared_multi_heap_attr attr; void *block; - attr = (unsigned int)(long) cfg; + attr = (enum shared_multi_heap_attr)(long) cfg; if (attr >= MAX_SHARED_MULTI_HEAP_ATTR || size == 0) { return NULL; @@ -31,8 +33,8 @@ static void *smh_choice(struct sys_multi_heap *mheap, void *cfg, size_t align, s /* Set in case the user requested a non-existing attr */ block = NULL; - for (size_t hdx = 0; hdx < attr_cnt[attr]; hdx++) { - h = &heap_pool[attr][hdx]; + for (size_t hdx = 0; hdx < smh_data[attr].heap_cnt; hdx++) { + h = &smh_data[attr].heap_pool[hdx]; if (h->heap == NULL) { return NULL; @@ -49,26 +51,28 @@ static void *smh_choice(struct sys_multi_heap *mheap, void *cfg, size_t align, s int shared_multi_heap_add(struct shared_multi_heap_region *region, void *user_data) { - static int n_heaps; + enum shared_multi_heap_attr attr; struct sys_heap *h; unsigned int slot; - if (region->attr >= MAX_SHARED_MULTI_HEAP_ATTR) { + attr = region->attr; + + if (attr >= MAX_SHARED_MULTI_HEAP_ATTR) { return -EINVAL; } /* No more heaps available */ - if (n_heaps++ >= MAX_MULTI_HEAPS) { + if (smh_data[attr].heap_cnt >= MAX_MULTI_HEAPS) { return -ENOMEM; } - slot = attr_cnt[region->attr]; - h = &heap_pool[region->attr][slot]; + slot = smh_data[attr].heap_cnt; + h = &smh_data[attr].heap_pool[slot]; sys_heap_init(h, (void *) region->addr, region->size); sys_multi_heap_add_heap(&shared_multi_heap, h, user_data); - attr_cnt[region->attr]++; + smh_data[attr].heap_cnt++; return 0; } @@ -78,7 +82,7 @@ void shared_multi_heap_free(void *block) sys_multi_heap_free(&shared_multi_heap, block); } -void *shared_multi_heap_alloc(unsigned int attr, size_t bytes) +void *shared_multi_heap_alloc(enum shared_multi_heap_attr attr, size_t bytes) { if (attr >= MAX_SHARED_MULTI_HEAP_ATTR) { return NULL; @@ -87,7 +91,8 @@ void *shared_multi_heap_alloc(unsigned int attr, size_t bytes) return sys_multi_heap_alloc(&shared_multi_heap, (void *)(long) attr, bytes); } -void *shared_multi_heap_aligned_alloc(unsigned int attr, size_t align, size_t bytes) +void *shared_multi_heap_aligned_alloc(enum shared_multi_heap_attr attr, + size_t align, size_t bytes) { if (attr >= MAX_SHARED_MULTI_HEAP_ATTR) { return NULL; diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index a6505d4f9d33be1..0b5ca1865301eb9 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -623,7 +623,6 @@ int pthread_join(pthread_t pthread, void **status) { int err; int ret; - k_spinlock_key_t key; struct posix_thread *t; if (pthread == pthread_self()) { @@ -636,28 +635,40 @@ int pthread_join(pthread_t pthread, void **status) } ret = 0; - key = k_spin_lock(&pthread_pool_lock); - if (t->detachstate != PTHREAD_CREATE_JOINABLE) { - ret = EINVAL; - } else if (t->qid == POSIX_THREAD_READY_Q) { - /* marginal chance thread has moved to ready_q between to_posix_thread() and here */ - ret = ESRCH; - } else { + K_SPINLOCK(&pthread_pool_lock) + { + if (t->detachstate != PTHREAD_CREATE_JOINABLE) { + ret = EINVAL; + K_SPINLOCK_BREAK; + } + + if (t->qid == POSIX_THREAD_READY_Q) { + /* in case thread has moved to ready_q between to_posix_thread() and here */ + ret = ESRCH; + K_SPINLOCK_BREAK; + } + /* * thread is joinable and is in run_q or done_q. * let's ensure that the thread cannot be joined again after this point. */ t->detachstate = PTHREAD_CREATE_DETACHED; - ret = 0; } - k_spin_unlock(&pthread_pool_lock, key); - if (ret == 0) { - err = k_thread_join(&t->thread, K_FOREVER); - /* other possibilities? */ - __ASSERT_NO_MSG(err == 0); + if (ret != 0) { + return ret; + } + + err = k_thread_join(&t->thread, K_FOREVER); + /* other possibilities? */ + __ASSERT_NO_MSG(err == 0); + + if (status != NULL) { + *status = t->retval; } + posix_thread_recycle(); + return 0; } diff --git a/modules/Kconfig b/modules/Kconfig index f35dfdcbd486ccb..8f5a9b55d781bff 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -45,6 +45,7 @@ source "modules/Kconfig.wurthelektronik" source "modules/Kconfig.xtensa" source "modules/zcbor/Kconfig" source "modules/Kconfig.mcuboot" +source "modules/Kconfig.intel" comment "Unavailable modules, please install those via the project manifest." diff --git a/modules/Kconfig.infineon b/modules/Kconfig.infineon index 87d140bc9af42e7..348305ccbf73351 100644 --- a/modules/Kconfig.infineon +++ b/modules/Kconfig.infineon @@ -45,4 +45,9 @@ config HAS_XMCLIB_I2C help Enable XMCLIB I2C +config HAS_XMCLIB_CCU + bool + help + Enable XMCLIB CCU4/CCU8 + endif # HAS_XMCLIB diff --git a/modules/Kconfig.intel b/modules/Kconfig.intel new file mode 100644 index 000000000000000..7ce9101497d9203 --- /dev/null +++ b/modules/Kconfig.intel @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config INTEL_HAL + bool + help + Build the Intel HAL module during build process. + This is selected by the ARCH kconfig automatically. diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 16a282ff93f669a..60bf5f503958ea2 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #include #include #include +#include #include #include @@ -316,7 +317,9 @@ void transmit_message(struct k_work *tx_job) (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) { uint64_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + sTransmitFrame.mInfo.mTxInfo.mTxDelay; - net_pkt_set_txtime(tx_pkt, NSEC_PER_USEC * tx_at); + struct net_ptp_time timestamp = ns_to_net_ptp_time(tx_at * NSEC_PER_USEC); + + net_pkt_set_timestamp(tx_pkt, ×tamp); tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_TXTIME_CCA, tx_pkt, tx_payload); } else if (sTransmitFrame.mInfo.mTxInfo.mCsmaCaEnabled) { @@ -663,8 +666,8 @@ otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, struct ieee802154_config config = { .rx_slot.channel = aChannel, - .rx_slot.start = aStart, - .rx_slot.duration = aDuration, + .rx_slot.start = (net_time_t)aStart * NSEC_PER_USEC, + .rx_slot.duration = (net_time_t)aDuration * NSEC_PER_USEC, }; result = radio_api->configure(radio_dev, IEEE802154_CONFIG_RX_SLOT, @@ -1051,7 +1054,7 @@ uint64_t otPlatTimeGet(void) if (radio_api == NULL || radio_api->get_time == NULL) { return k_ticks_to_us_floor64(k_uptime_ticks()); } else { - return radio_api->get_time(radio_dev); + return radio_api->get_time(radio_dev) / NSEC_PER_USEC; } } @@ -1192,7 +1195,7 @@ void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTi { ARG_UNUSED(aInstance); - struct ieee802154_config config = { .csl_rx_time = aCslSampleTime }; + struct ieee802154_config config = { .csl_rx_time = aCslSampleTime * NSEC_PER_USEC }; (void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, &config); } diff --git a/modules/thrift/src/thrift/concurrency/Mutex.cpp b/modules/thrift/src/thrift/concurrency/Mutex.cpp index 422914349136745..20848f6ed80a545 100644 --- a/modules/thrift/src/thrift/concurrency/Mutex.cpp +++ b/modules/thrift/src/thrift/concurrency/Mutex.cpp @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include namespace apache @@ -13,31 +15,52 @@ namespace thrift namespace concurrency { +class Mutex::impl +{ +public: + k_spinlock_key_t key; + struct k_spinlock lock; +}; + Mutex::Mutex() { + impl_ = std::make_shared(); } void Mutex::lock() const { + while (!trylock()) { + k_msleep(1); + } } bool Mutex::trylock() const { - return false; + return k_spin_trylock(&impl_->lock, &impl_->key) == 0; } bool Mutex::timedlock(int64_t milliseconds) const { + k_timepoint_t end = sys_timepoint_calc(K_MSEC(milliseconds)); + + do { + if (trylock()) { + return true; + } + k_msleep(5); + } while(!sys_timepoint_expired(end)); + return false; } void Mutex::unlock() const { + k_spin_unlock(&impl_->lock, impl_->key); } void *Mutex::getUnderlyingImpl() const { - return nullptr; + return &impl_->lock; } } // namespace concurrency } // namespace thrift diff --git a/modules/thrift/src/thrift/server/TFDServer.cpp b/modules/thrift/src/thrift/server/TFDServer.cpp index 30cb1e3ad8b19d7..f87bcb5684e06c0 100644 --- a/modules/thrift/src/thrift/server/TFDServer.cpp +++ b/modules/thrift/src/thrift/server/TFDServer.cpp @@ -71,6 +71,11 @@ class xport : public TVirtualTransport r = poll(&pollfds.front(), pollfds.size(), -1); if (r == -1) { + if (efd == -1 || fd == -1) { + /* channel has been closed */ + return 0; + } + LOG_ERR("failed to poll fds %d, %d: %d", fd, efd, errno); throw system_error(errno, system_category(), "poll"); } diff --git a/samples/basic/blinky_pwm/boards/xmc45_relax_kit.overlay b/samples/basic/blinky_pwm/boards/xmc45_relax_kit.overlay new file mode 100644 index 000000000000000..c480721420eded5 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/xmc45_relax_kit.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwm_led1 { + status = "okay"; +}; + +&pwm_ccu40 { + status = "okay"; +}; diff --git a/samples/basic/blinky_pwm/boards/xmc47_relax_kit.overlay b/samples/basic/blinky_pwm/boards/xmc47_relax_kit.overlay new file mode 100644 index 000000000000000..33db6bf0d1dffa1 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/xmc47_relax_kit.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023 SLB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwm_led1 { + status = "okay"; +}; + +&pwm_ccu80 { + status = "okay"; +}; diff --git a/samples/basic/hash_map/prj.conf b/samples/basic/hash_map/prj.conf index 3f1a62538eec57c..4eb90ce10ca2371 100644 --- a/samples/basic/hash_map/prj.conf +++ b/samples/basic/hash_map/prj.conf @@ -6,8 +6,6 @@ CONFIG_BOOT_BANNER=n CONFIG_LOG=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 -CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 CONFIG_SYS_HASH_FUNC32=y CONFIG_SYS_HASH_MAP=y diff --git a/samples/basic/hash_map/sample.yaml b/samples/basic/hash_map/sample.yaml index b73474975813cbf..40dec267473c0a3 100644 --- a/samples/basic/hash_map/sample.yaml +++ b/samples/basic/hash_map/sample.yaml @@ -25,11 +25,13 @@ tests: libraries.hash_map.minimal.separate_chaining.djb2: extra_configs: - CONFIG_MINIMAL_LIBC=y + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_SC=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.minimal.open_addressing.djb2: extra_configs: - CONFIG_MINIMAL_LIBC=y + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_OA_LP=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y # Newlib @@ -37,18 +39,21 @@ tests: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_SC=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.newlib.open_addressing.djb2: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_OA_LP=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.newlib.cxx_unordered_map.djb2: filter: TOOLCHAIN_HAS_NEWLIB == 1 extra_configs: - CONFIG_NEWLIB_LIBC=y + - CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_CXX=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y - CONFIG_MAIN_STACK_SIZE=2048 @@ -56,10 +61,12 @@ tests: libraries.hash_map.picolibc.separate_chaining.djb2: extra_configs: - CONFIG_PICOLIBC=y + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_SC=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y libraries.hash_map.picolibc.open_addressing.djb2: extra_configs: - CONFIG_PICOLIBC=y + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=8192 - CONFIG_SYS_HASH_MAP_CHOICE_OA_LP=y - CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2=y diff --git a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c index 620471805680a1e..735ac7a3318bc4f 100644 --- a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c +++ b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c @@ -14,14 +14,22 @@ #include LOG_MODULE_REGISTER(iso_broadcast_broadcaster, LOG_LEVEL_DBG); -#define DEFAULT_BIS_RTN 2 -#define DEFAULT_BIS_INTERVAL_US 7500 -#define DEFAULT_BIS_LATENCY_MS 10 -#define DEFAULT_BIS_PHY BT_GAP_LE_PHY_2M -#define DEFAULT_BIS_SDU CONFIG_BT_ISO_TX_MTU -#define DEFAULT_BIS_PACKING 0 -#define DEFAULT_BIS_FRAMING 0 -#define DEFAULT_BIS_COUNT CONFIG_BT_ISO_MAX_CHAN +#define DEFAULT_BIS_RTN 2 +#define DEFAULT_BIS_INTERVAL_US 7500 +#define DEFAULT_BIS_LATENCY_MS 10 +#define DEFAULT_BIS_PHY BT_GAP_LE_PHY_2M +#define DEFAULT_BIS_SDU CONFIG_BT_ISO_TX_MTU +#define DEFAULT_BIS_PACKING 0 +#define DEFAULT_BIS_FRAMING 0 +#define DEFAULT_BIS_COUNT CONFIG_BT_ISO_MAX_CHAN +#if defined(CONFIG_BT_ISO_ADVANCED) +#define DEFAULT_BIS_NSE BT_ISO_NSE_MIN +#define DEFAULT_BIS_BN BT_ISO_BN_MIN +#define DEFAULT_BIS_PDU_SIZE CONFIG_BT_ISO_TX_MTU +#define DEFAULT_BIS_IRC BT_ISO_IRC_MIN +#define DEFAULT_BIS_PTO BT_ISO_PTO_MIN +#define DEFAULT_BIS_ISO_INTERVAL DEFAULT_BIS_INTERVAL_US / 1250U /* N * 10 ms */ +#endif /* CONFIG_BT_ISO_ADVANCED */ NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), @@ -45,6 +53,11 @@ static struct bt_iso_big_create_param big_create_param = { .framing = DEFAULT_BIS_FRAMING, /* 0 - unframed, 1 - framed */ .interval = DEFAULT_BIS_INTERVAL_US, /* in microseconds */ .latency = DEFAULT_BIS_LATENCY_MS, /* milliseconds */ +#if defined(CONFIG_BT_ISO_ADVANCED) + .irc = DEFAULT_BIS_IRC, + .pto = DEFAULT_BIS_PTO, + .iso_interval = DEFAULT_BIS_ISO_INTERVAL, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static void iso_connected(struct bt_iso_chan *chan) @@ -78,10 +91,17 @@ static struct bt_iso_chan_io_qos iso_tx_qos = { .sdu = DEFAULT_BIS_SDU, /* bytes */ .rtn = DEFAULT_BIS_RTN, .phy = DEFAULT_BIS_PHY, +#if defined(CONFIG_BT_ISO_ADVANCED) + .max_pdu = DEFAULT_BIS_PDU_SIZE, + .burst_number = DEFAULT_BIS_BN, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static struct bt_iso_chan_qos bis_iso_qos = { .tx = &iso_tx_qos, +#if defined(CONFIG_BT_ISO_ADVANCED) + .num_subevents = DEFAULT_BIS_NSE, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static size_t get_chars(char *buffer, size_t max_size) @@ -221,6 +241,152 @@ static int parse_sdu_arg(void) return (int)sdu; } +#if defined(CONFIG_BT_ISO_ADVANCED) +static int parse_irc_arg(void) +{ + size_t char_count; + char buffer[4]; + uint64_t irc; + + printk("Set IRC (current %u, default %u)\n", + big_create_param.irc, DEFAULT_BIS_IRC); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_IRC; + } + + irc = strtoul(buffer, NULL, 0); + if (!IN_RANGE(irc, BT_ISO_IRC_MIN, BT_ISO_IRC_MAX)) { + printk("Invalid IRC %llu", irc); + + return -EINVAL; + } + + return (int)irc; +} + +static int parse_pto_arg(void) +{ + size_t char_count; + char buffer[4]; + uint64_t pto; + + printk("Set PTO (current %u, default %u)\n", + big_create_param.pto, DEFAULT_BIS_PTO); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_PTO; + } + + pto = strtoul(buffer, NULL, 0); + if (!IN_RANGE(pto, BT_ISO_PTO_MIN, BT_ISO_PTO_MAX)) { + printk("Invalid PTO %llu", pto); + + return -EINVAL; + } + + return (int)pto; +} + +static int parse_iso_interval_arg(void) +{ + uint64_t iso_interval; + size_t char_count; + char buffer[8]; + + printk("Set ISO interval (current %u, default %u)\n", + big_create_param.iso_interval, DEFAULT_BIS_ISO_INTERVAL); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_ISO_INTERVAL; + } + + iso_interval = strtoul(buffer, NULL, 0); + if (!IN_RANGE(iso_interval, BT_ISO_ISO_INTERVAL_MIN, BT_ISO_ISO_INTERVAL_MAX)) { + printk("Invalid ISO interval %llu", iso_interval); + + return -EINVAL; + } + + return (int)iso_interval; +} + +static int parse_nse_arg(void) +{ + uint64_t num_subevents; + size_t char_count; + char buffer[4]; + + printk("Set number of subevents (current %u, default %u)\n", + bis_iso_qos.num_subevents, DEFAULT_BIS_NSE); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_NSE; + } + + num_subevents = strtoul(buffer, NULL, 0); + if (!IN_RANGE(num_subevents, BT_ISO_NSE_MIN, BT_ISO_NSE_MAX)) { + printk("Invalid number of subevents %llu", num_subevents); + + return -EINVAL; + } + + return (int)num_subevents; +} + +static int parse_max_pdu_arg(void) +{ + size_t char_count; + uint64_t max_pdu; + char buffer[6]; + + printk("Set max PDU (current %u, default %u)\n", + iso_tx_qos.max_pdu, DEFAULT_BIS_PDU_SIZE); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_PDU_SIZE; + } + + max_pdu = strtoul(buffer, NULL, 0); + if (max_pdu > BT_ISO_PDU_MAX) { + printk("Invalid max PDU %llu", max_pdu); + + return -EINVAL; + } + + return (int)max_pdu; +} + +static int parse_bn_arg(void) +{ + uint64_t burst_number; + size_t char_count; + char buffer[4]; + + printk("Set burst number (current %u, default %u)\n", + iso_tx_qos.burst_number, DEFAULT_BIS_BN); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_BIS_PDU_SIZE; + } + + burst_number = strtoul(buffer, NULL, 0); + if (!IN_RANGE(burst_number, BT_ISO_BN_MIN, BT_ISO_BN_MAX)) { + printk("Invalid burst number %llu", burst_number); + + return -EINVAL; + } + + return (int)burst_number; +} +#endif /* CONFIG_BT_ISO_ADVANCED */ + static int parse_packing_arg(void) { char buffer[3]; @@ -302,6 +468,14 @@ static int parse_args(void) int packing; int framing; int bis_count; +#if defined(CONFIG_BT_ISO_ADVANCED) + int num_subevents; + int iso_interval; + int burst_number; + int max_pdu; + int irc; + int pto; +#endif /* CONFIG_BT_ISO_ADVANCED */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -345,6 +519,38 @@ static int parse_args(void) return -EINVAL; } +#if defined(CONFIG_BT_ISO_ADVANCED) + irc = parse_irc_arg(); + if (irc < 0) { + return -EINVAL; + } + + pto = parse_pto_arg(); + if (pto < 0) { + return -EINVAL; + } + + iso_interval = parse_iso_interval_arg(); + if (iso_interval < 0) { + return -EINVAL; + } + + num_subevents = parse_nse_arg(); + if (num_subevents < 0) { + return -EINVAL; + } + + max_pdu = parse_max_pdu_arg(); + if (max_pdu < 0) { + return -EINVAL; + } + + burst_number = parse_bn_arg(); + if (burst_number < 0) { + return -EINVAL; + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + iso_tx_qos.rtn = rtn; iso_tx_qos.phy = phy; iso_tx_qos.sdu = sdu; @@ -353,6 +559,14 @@ static int parse_args(void) big_create_param.packing = packing; big_create_param.framing = framing; big_create_param.num_bis = bis_count; +#if defined(CONFIG_BT_ISO_ADVANCED) + bis_iso_qos.num_subevents = num_subevents; + iso_tx_qos.max_pdu = max_pdu; + iso_tx_qos.burst_number = burst_number; + big_create_param.irc = irc; + big_create_param.pto = pto; + big_create_param.iso_interval = iso_interval; +#endif /* CONFIG_BT_ISO_ADVANCED */ return 0; } diff --git a/samples/bluetooth/iso_connected_benchmark/src/main.c b/samples/bluetooth/iso_connected_benchmark/src/main.c index ed2bd0f3b28b5d6..7eb5b05cbb9f672 100644 --- a/samples/bluetooth/iso_connected_benchmark/src/main.c +++ b/samples/bluetooth/iso_connected_benchmark/src/main.c @@ -35,9 +35,17 @@ enum benchmark_role { #define DEFAULT_CIS_SDU_SIZE CONFIG_BT_ISO_TX_MTU #define DEFAULT_CIS_PACKING 0 #define DEFAULT_CIS_FRAMING 0 -#define DEFAULT_CIS_COUNT CONFIG_BT_ISO_MAX_CHAN +#define DEFAULT_CIS_COUNT 1U #define DEFAULT_CIS_SEC_LEVEL BT_SECURITY_L1 +#if defined(CONFIG_BT_ISO_ADVANCED) +#define DEFAULT_CIS_NSE BT_ISO_NSE_MIN +#define DEFAULT_CIS_BN BT_ISO_BN_MIN +#define DEFAULT_CIS_PDU_SIZE CONFIG_BT_ISO_TX_MTU +#define DEFAULT_CIS_FT BT_ISO_FT_MIN +#define DEFAULT_CIS_ISO_INTERVAL DEFAULT_CIS_INTERVAL_US / 1250U /* N * 1.25 ms */ +#endif /* CONFIG_BT_ISO_ADVANCED */ + #define BUFFERS_ENQUEUED 2 /* Number of buffers enqueue for each channel */ BUILD_ASSERT(BUFFERS_ENQUEUED * CONFIG_BT_ISO_MAX_CHAN <= CONFIG_BT_ISO_TX_BUF_COUNT, @@ -83,17 +91,28 @@ static struct bt_iso_chan_io_qos iso_tx_qos = { .sdu = DEFAULT_CIS_SDU_SIZE, /* bytes */ .rtn = DEFAULT_CIS_RTN, .phy = DEFAULT_CIS_PHY, +#if defined(CONFIG_BT_ISO_ADVANCED) + .max_pdu = DEFAULT_CIS_PDU_SIZE, + .burst_number = DEFAULT_CIS_BN, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static struct bt_iso_chan_io_qos iso_rx_qos = { .sdu = DEFAULT_CIS_SDU_SIZE, /* bytes */ .rtn = DEFAULT_CIS_RTN, .phy = DEFAULT_CIS_PHY, +#if defined(CONFIG_BT_ISO_ADVANCED) + .max_pdu = DEFAULT_CIS_PDU_SIZE, + .burst_number = DEFAULT_CIS_BN, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static struct bt_iso_chan_qos iso_qos = { .tx = &iso_tx_qos, .rx = &iso_rx_qos, +#if defined(CONFIG_BT_ISO_ADVANCED) + .num_subevents = DEFAULT_CIS_NSE, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static struct bt_iso_cig_param cig_create_param = { @@ -103,7 +122,12 @@ static struct bt_iso_cig_param cig_create_param = { .packing = DEFAULT_CIS_PACKING, .framing = DEFAULT_CIS_FRAMING, .cis_channels = cis, - .num_cis = DEFAULT_CIS_COUNT + .num_cis = DEFAULT_CIS_COUNT, +#if defined(CONFIG_BT_ISO_ADVANCED) + .c_to_p_ft = DEFAULT_CIS_FT, + .p_to_c_ft = DEFAULT_CIS_FT, + .iso_interval = DEFAULT_CIS_ISO_INTERVAL, +#endif /* CONFIG_BT_ISO_ADVANCED */ }; static enum benchmark_role device_role_select(void) @@ -608,6 +632,154 @@ static int parse_sdu_arg(struct bt_iso_chan_io_qos *qos) return (int)sdu; } +#if defined(CONFIG_BT_ISO_ADVANCED) +static int parse_c_to_p_ft_arg(void) +{ + char buffer[4]; + size_t char_count; + uint64_t c_to_p_ft; + + printk("Set central to peripheral flush timeout (current %u, default %u)\n", + cig_create_param.c_to_p_ft, DEFAULT_CIS_FT); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_FT; + } + + c_to_p_ft = strtoul(buffer, NULL, 0); + if (!IN_RANGE(c_to_p_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) { + printk("Invalid central to peripheral flush timeout %llu", + c_to_p_ft); + + return -EINVAL; + } + + return (int)c_to_p_ft; +} + +static int parse_p_to_c_ft_arg(void) +{ + char buffer[4]; + size_t char_count; + uint64_t p_to_c_ft; + + printk("Set peripheral to central flush timeout (current %u, default %u)\n", + cig_create_param.p_to_c_ft, DEFAULT_CIS_FT); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_FT; + } + + p_to_c_ft = strtoul(buffer, NULL, 0); + if (!IN_RANGE(p_to_c_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) { + printk("Invalid peripheral to central flush timeout %llu", + p_to_c_ft); + + return -EINVAL; + } + + return (int)p_to_c_ft; +} + +static int parse_iso_interval_arg(void) +{ + char buffer[8]; + size_t char_count; + uint64_t iso_interval; + + printk("Set ISO interval (current %u, default %u)\n", + cig_create_param.iso_interval, DEFAULT_CIS_ISO_INTERVAL); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_ISO_INTERVAL; + } + + iso_interval = strtoul(buffer, NULL, 0); + if (IN_RANGE(iso_interval, BT_ISO_ISO_INTERVAL_MIN, BT_ISO_ISO_INTERVAL_MAX)) { + printk("Invalid ISO interval %llu", iso_interval); + + return -EINVAL; + } + + return (int)iso_interval; +} + +static int parse_nse_arg(struct bt_iso_chan_qos *qos) +{ + char buffer[4]; + size_t char_count; + uint64_t nse; + + printk("Set number of subevents (current %u, default %u)\n", + qos->num_subevents, DEFAULT_CIS_NSE); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_NSE; + } + + nse = strtoul(buffer, NULL, 0); + if (IN_RANGE(nse, BT_ISO_NSE_MIN, BT_ISO_NSE_MAX)) { + printk("Invalid number of subevents %llu", nse); + + return -EINVAL; + } + + return (int)nse; +} + +static int parse_pdu_arg(const struct bt_iso_chan_io_qos *qos) +{ + char buffer[6]; + size_t char_count; + uint64_t pdu; + + printk("Set PDU (current %u, default %u)\n", + qos->max_pdu, DEFAULT_CIS_PDU_SIZE); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_PDU_SIZE; + } + + pdu = strtoul(buffer, NULL, 0); + if (pdu > BT_ISO_PDU_MAX) { + printk("Invalid PDU %llu", pdu); + + return -EINVAL; + } + + return (int)pdu; +} + +static int parse_bn_arg(const struct bt_iso_chan_io_qos *qos) +{ + char buffer[4]; + size_t char_count; + uint64_t bn; + + printk("Set burst number (current %u, default %u)\n", + qos->burst_number, DEFAULT_CIS_BN); + + char_count = get_chars(buffer, sizeof(buffer) - 1); + if (char_count == 0) { + return DEFAULT_CIS_PDU_SIZE; + } + + bn = strtoul(buffer, NULL, 0); + if (!IN_RANGE(bn, BT_ISO_BN_MIN, BT_ISO_BN_MAX)) { + printk("Invalid burst number %llu", bn); + + return -EINVAL; + } + + return (int)bn; +} +#endif /* CONFIG_BT_ISO_ADVANCED */ + static int parse_cis_count_arg(void) { char buffer[4]; @@ -636,6 +808,12 @@ static int parse_cig_args(void) int interval; int latency; int cis_count; +#if defined(CONFIG_BT_ISO_ADVANCED) + int c_to_p_ft; + int p_to_c_ft; + int iso_interval; + int num_subevents; +#endif /* CONFIG_BT_ISO_ADVANCED */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -654,9 +832,37 @@ static int parse_cig_args(void) return -EINVAL; } +#if defined(CONFIG_BT_ISO_ADVANCED) + c_to_p_ft = parse_c_to_p_ft_arg(); + if (c_to_p_ft < 0) { + return -EINVAL; + } + + p_to_c_ft = parse_p_to_c_ft_arg(); + if (p_to_c_ft < 0) { + return -EINVAL; + } + + iso_interval = parse_iso_interval_arg(); + if (iso_interval < 0) { + return -EINVAL; + } + + num_subevents = parse_nse_arg(&iso_qos); + if (num_subevents < 0) { + return -EINVAL; + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + cig_create_param.interval = interval; cig_create_param.latency = latency; cig_create_param.num_cis = cis_count; +#if defined(CONFIG_BT_ISO_ADVANCED) + cig_create_param.c_to_p_ft = c_to_p_ft; + cig_create_param.p_to_c_ft = p_to_c_ft; + cig_create_param.iso_interval = iso_interval; + iso_qos.num_subevents = num_subevents; +#endif /* CONFIG_BT_ISO_ADVANCED */ return 0; } @@ -666,6 +872,10 @@ static int parse_cis_args(struct bt_iso_chan_io_qos *qos) int rtn; int phy; int sdu; +#if defined(CONFIG_BT_ISO_ADVANCED) + int max_pdu; + int burst_number; +#endif /* CONFIG_BT_ISO_ADVANCED */ printk("Follow the prompts. Press enter to use default values.\n"); @@ -684,9 +894,25 @@ static int parse_cis_args(struct bt_iso_chan_io_qos *qos) return -EINVAL; } +#if defined(CONFIG_BT_ISO_ADVANCED) + max_pdu = parse_pdu_arg(qos); + if (max_pdu < 0) { + return -EINVAL; + } + + burst_number = parse_bn_arg(qos); + if (burst_number < 0) { + return -EINVAL; + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + qos->rtn = rtn; qos->phy = phy; qos->sdu = sdu; +#if defined(CONFIG_BT_ISO_ADVANCED) + qos->max_pdu = max_pdu; + qos->burst_number = burst_number; +#endif /* CONFIG_BT_ISO_ADVANCED */ return 0; } diff --git a/samples/drivers/adc/boards/mr_canhubk3.overlay b/samples/drivers/adc/boards/mr_canhubk3.overlay new file mode 100644 index 000000000000000..3f60c3c465c0778 --- /dev/null +++ b/samples/drivers/adc/boards/mr_canhubk3.overlay @@ -0,0 +1,77 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 6>, <&adc1 2>, <&adc2 3>, <&adc2 4>, <&adc2 5>; + }; +}; + +&adc0 { + group-channel = "precision"; + callback-select = "normal-end-chain"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; +}; + +&adc1 { + group-channel = "precision"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + +}; + + +&adc2 { + group-channel = "precision"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@5 { + reg = <5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; +}; diff --git a/samples/drivers/adc/sample.yaml b/samples/drivers/adc/sample.yaml index 678e0afd8802df9..0187d38ac54a6db 100644 --- a/samples/drivers/adc/sample.yaml +++ b/samples/drivers/adc/sample.yaml @@ -23,6 +23,7 @@ tests: - esp32c3_devkitm - gd32l233r_eval - lpcxpresso55s36 + - mr_canhubk3 integration_platforms: - nucleo_l073rz - nrf52840dk_nrf52840 diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index 5fe78156f383d84..dd7ab1155704d28 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -10,6 +10,8 @@ set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/mbox_ipc_remote-prefix/src/mbo if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") set(BOARD_REMOTE "nrf5340dk_nrf5340_cpunet") +elseif("${BOARD}" STREQUAL "adp_xc7k_ae350") + set(BOARD_REMOTE "adp_xc7k_ae350") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() diff --git a/samples/drivers/mbox/boards/adp_xc7k_ae350.conf b/samples/drivers/mbox/boards/adp_xc7k_ae350.conf new file mode 100644 index 000000000000000..bdeaed5e8853720 --- /dev/null +++ b/samples/drivers/mbox/boards/adp_xc7k_ae350.conf @@ -0,0 +1 @@ +CONFIG_RV_BOOT_HART=0 diff --git a/samples/drivers/mbox/boards/adp_xc7k_ae350.overlay b/samples/drivers/mbox/boards/adp_xc7k_ae350.overlay new file mode 100644 index 000000000000000..e97501416707535 --- /dev/null +++ b/samples/drivers/mbox/boards/adp_xc7k_ae350.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + zephyr,sram = &sram; + }; + + sram: memory@0 { + compatible = "mmio-sram"; + reg = <0x00000000 0x10000000 >; + }; +}; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 94e87d6fcdc1f53..a2efccf2227f8fd 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -8,6 +8,8 @@ cmake_minimum_required(VERSION 3.20.0) if("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpunet") message(STATUS "${BOARD} compile as remote in this sample") +elseif("${BOARD}" STREQUAL "adp_xc7k_ae350") + message(STATUS "${BOARD} compile as remote in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") endif() diff --git a/samples/drivers/mbox/remote/sample.yaml b/samples/drivers/mbox/remote/sample.yaml index df30347e98ecca1..014ad53a126792c 100644 --- a/samples/drivers/mbox/remote/sample.yaml +++ b/samples/drivers/mbox/remote/sample.yaml @@ -2,7 +2,7 @@ sample: name: MBOX IPC sample (remote) tests: sample.drivers.mbox_remote: - platform_allow: nrf5340dk_nrf5340_cpunet + platform_allow: nrf5340dk_nrf5340_cpunet adp_xc7k_ae350 integration_platforms: - nrf5340dk_nrf5340_cpunet tags: mbox diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 8080026435b167b..6d1ee5fd23551f0 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -2,7 +2,7 @@ sample: name: MBOX IPC sample tests: sample.drivers.mbox: - platform_allow: nrf5340dk_nrf5340_cpuapp + platform_allow: nrf5340dk_nrf5340_cpuapp adp_xc7k_ae350 integration_platforms: - nrf5340dk_nrf5340_cpuapp tags: mbox diff --git a/samples/net/sockets/echo_server/sample.yaml b/samples/net/sockets/echo_server/sample.yaml index 6c90fa6eee0cd5f..6b4a8d44487e39f 100644 --- a/samples/net/sockets/echo_server/sample.yaml +++ b/samples/net/sockets/echo_server/sample.yaml @@ -84,15 +84,6 @@ tests: tags: - net - usb - sample.net.sockets.echo_server.usbnet_composite: - depends_on: usb_device - harness: net - extra_args: OVERLAY_CONFIG="overlay-netusb.conf" - extra_configs: - - CONFIG_USB_COMPOSITE_DEVICE=y - tags: - - net - - usb sample.net.sockets.echo_server.nrf_openthread: extra_args: OVERLAY_CONFIG="overlay-ot.conf" slow: true diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index 38ed702797b31d9..bec25977680a652 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -153,15 +153,14 @@ static void tx(struct app_data *data) struct cmsghdr hdr; unsigned char buf[CMSG_SPACE(sizeof(uint64_t))]; } cmsgbuf; - uint64_t txtime, delay, interval; + net_time_t txtime, delay, interval; int ret; int print_offset; print_offset = IS_ENABLED(CONFIG_NET_SAMPLE_PACKET_SOCKET) ? sizeof(struct net_eth_hdr) : 0; - interval = CONFIG_NET_SAMPLE_PACKET_INTERVAL * NSEC_PER_USEC * - USEC_PER_MSEC; + interval = CONFIG_NET_SAMPLE_PACKET_INTERVAL * NSEC_PER_MSEC; delay = CONFIG_NET_SAMPLE_PACKET_TXTIME * NSEC_PER_USEC; io_vector[0].iov_base = (void *)txtime_str; @@ -182,14 +181,14 @@ static void tx(struct app_data *data) LOG_DBG("Sending network packets with SO_TXTIME"); ptp_clock_get(data->clk, &time); - txtime = (time.second * NSEC_PER_SEC) + time.nanosecond; + txtime = net_ptp_time_to_ns(&time); snprintk(txtime_str + print_offset, - sizeof(txtime_str) - print_offset, "%"PRIx64, txtime); + sizeof(txtime_str) - print_offset, "%"PRIx64, (uint64_t)txtime); io_vector[0].iov_len = sizeof(txtime_str); while (1) { - *(uint64_t *)CMSG_DATA(cmsg) = txtime + delay; + *(net_time_t *)CMSG_DATA(cmsg) = txtime + delay; ret = sendmsg(data->sock, &msg, 0); if (ret < 0) { @@ -202,7 +201,7 @@ static void tx(struct app_data *data) txtime += interval; snprintk(txtime_str + print_offset, - sizeof(txtime_str) - print_offset, "%"PRIx64, txtime); + sizeof(txtime_str) - print_offset, "%"PRIx64, (uint64_t)txtime); k_sleep(K_NSEC(interval)); } diff --git a/samples/net/zperf/sample.yaml b/samples/net/zperf/sample.yaml index 558b4f7d69de740..82b8b519e79af1f 100644 --- a/samples/net/zperf/sample.yaml +++ b/samples/net/zperf/sample.yaml @@ -1,5 +1,4 @@ common: - harness: net tags: - net - zperf @@ -14,12 +13,26 @@ sample: name: zperf tests: sample.net.zperf: + harness: net platform_allow: qemu_x86 + sample.net.zperf_st: + harness: console + harness_config: + type: multi_line + regex: + - "coming up" + platform_allow: + - nucleo_h563zi + - nucleo_h743zi + - nucleo_f429zi + - nucleo_f746zg sample.net.zperf_no_shell: + harness: net extra_configs: - CONFIG_NET_SHELL=n platform_allow: qemu_x86 sample.net.zperf.netusb_ecm: + harness: net extra_args: OVERLAY_CONFIG="overlay-netusb.conf" tags: - usb @@ -27,12 +40,14 @@ tests: - zperf depends_on: usb_device sample.net.zperf.device_next_ecm: + harness: net extra_args: OVERLAY_CONFIG="overlay-usbd_next_ecm.conf" DTC_OVERLAY_FILE="usbd_next_ecm.overlay" platform_allow: nrf52840dk_nrf52840 frdm_k64f tags: usb net zperf depends_on: usb_device sample.net.zperf.netusb_eem: + harness: net extra_args: OVERLAY_CONFIG="overlay-netusb.conf" extra_configs: - CONFIG_USB_DEVICE_NETWORK_ECM=n @@ -43,6 +58,7 @@ tests: - zperf depends_on: usb_device sample.net.zperf.netusb_rndis: + harness: net extra_args: OVERLAY_CONFIG="overlay-netusb.conf" extra_configs: - CONFIG_USB_DEVICE_NETWORK_ECM=n @@ -53,6 +69,7 @@ tests: - zperf depends_on: usb_device sample.net.zperf.shield: + harness: net platform_allow: reel_board extra_args: SHIELD=link_board_eth tags: diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf new file mode 100644 index 000000000000000..0f7274227ce41a8 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.conf @@ -0,0 +1,4 @@ +CONFIG_LOG_PRINTK=n +CONFIG_IPM_IMX_MAX_DATA_SIZE_16=n +CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y +CONFIG_OPENAMP_WITH_DCACHE=y diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.overlay b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.overlay new file mode 100644 index 000000000000000..8fefebe548500b9 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/boards/nxp_adsp_imx8m.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + zephyr,ipc_shm = &dspsram3; + zephyr,ipc = &mailbox0; + }; + + dspsram3: memory@942f0000 { + compatible = "mmio-sram"; + reg = <0x942f0000 0x110000>; + }; +}; + +&mailbox0 { + status = "okay"; +}; diff --git a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c index bea90ddf3ffab5a..9b6b634952c6f1c 100644 --- a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c +++ b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c @@ -31,10 +31,10 @@ LOG_MODULE_REGISTER(openamp_rsc_table, LOG_LEVEL_DBG); #define SHM_START_ADDR DT_REG_ADDR(SHM_NODE) #define SHM_SIZE DT_REG_SIZE(SHM_NODE) -#define APP_TASK_STACK_SIZE (512) +#define APP_TASK_STACK_SIZE (1024) -/* Add 512 extra bytes for the TTY task stack for the "tx_buff" buffer. */ -#define APP_TTY_TASK_STACK_SIZE (1024) +/* Add 1024 extra bytes for the TTY task stack for the "tx_buff" buffer. */ +#define APP_TTY_TASK_STACK_SIZE (1536) K_THREAD_STACK_DEFINE(thread_mng_stack, APP_TASK_STACK_SIZE); K_THREAD_STACK_DEFINE(thread_rp__client_stack, APP_TASK_STACK_SIZE); diff --git a/samples/subsys/nvs/boards/nucleo_g474re.overlay b/samples/subsys/nvs/boards/nucleo_g474re.overlay new file mode 100644 index 000000000000000..c6f256628b4b4ad --- /dev/null +++ b/samples/subsys/nvs/boards/nucleo_g474re.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &storage_partition; + +&flash0 { + partitions { + /* Set 6KB of storage at the end of 512KB flash */ + storage_partition: partition@7e800 { + label = "storage"; + reg = <0x0007e800 DT_SIZE_K(6)>; + }; + }; +}; diff --git a/samples/subsys/pm/latency/src/pm.c b/samples/subsys/pm/latency/src/pm.c index d1e7beeba4d9d04..c7dee14900e0535 100644 --- a/samples/subsys/pm/latency/src/pm.c +++ b/samples/subsys/pm/latency/src/pm.c @@ -13,8 +13,6 @@ LOG_MODULE_REGISTER(soc_pm, CONFIG_APP_LOG_LEVEL); static const char *state2str(enum pm_state state) { switch (state) { - case PM_STATE_ACTIVE: - return "ACTIVE"; case PM_STATE_RUNTIME_IDLE: return "RUNTIME_IDLE"; case PM_STATE_SUSPEND_TO_IDLE: diff --git a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-dfu.conf b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-dfu.conf index 0f84f23b0608848..e1fc3c9a994fe65 100644 --- a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-dfu.conf +++ b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-dfu.conf @@ -6,8 +6,6 @@ # (does not re-enumerates) and thus make it unable for the device # to restart in DFU mode. -CONFIG_USB_COMPOSITE_DEVICE=y - CONFIG_USB_DFU_CLASS=y CONFIG_FLASH=y CONFIG_IMG_MANAGER=y diff --git a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf index ff01af597910e9c..a272869511ea76f 100644 --- a/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf +++ b/samples/subsys/usb/cdc_acm/overlay-composite-cdc-msc.conf @@ -1,8 +1,6 @@ # Overlay file for composite configuration # CDC ACM + Mass Storage (RAM) -CONFIG_USB_COMPOSITE_DEVICE=y - CONFIG_USB_MASS_STORAGE=y CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y diff --git a/samples/subsys/usb/cdc_acm_composite/prj.conf b/samples/subsys/usb/cdc_acm_composite/prj.conf index 6b029f43a5e826c..db41a5ba64dcb4c 100644 --- a/samples/subsys/usb/cdc_acm_composite/prj.conf +++ b/samples/subsys/usb/cdc_acm_composite/prj.conf @@ -7,7 +7,6 @@ CONFIG_UART_LINE_CTRL=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC ACM Composite sample" CONFIG_USB_DEVICE_PID=0x0002 -CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_CDC_ACM_RINGBUF_SIZE=512 CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n diff --git a/samples/subsys/usb/hid-cdc/prj.conf b/samples/subsys/usb/hid-cdc/prj.conf index cf274459fb5a5b6..695f97698a3bd55 100644 --- a/samples/subsys/usb/hid-cdc/prj.conf +++ b/samples/subsys/usb/hid-cdc/prj.conf @@ -1,4 +1,3 @@ -CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_PRODUCT="Zephyr HID and CDC ACM sample" CONFIG_USB_DEVICE_PID=0x0003 diff --git a/samples/subsys/usb/hid/sample.yaml b/samples/subsys/usb/hid/sample.yaml index 7cec4d2ec815de3..7f63562bbf73eb9 100644 --- a/samples/subsys/usb/hid/sample.yaml +++ b/samples/subsys/usb/hid/sample.yaml @@ -11,18 +11,6 @@ tests: regex: - "main: HID Device: dev" - "main: Starting application" - sample.usb.hid_composite: - depends_on: usb_device - extra_configs: - - CONFIG_USB_COMPOSITE_DEVICE=y - tags: usb - arch_exclude: posix - harness: console - harness_config: - type: multi_line - regex: - - "main: HID Device: dev" - - "main: Starting application" sample.usb.hid.buildonly: depends_on: usb_device tags: usb diff --git a/scripts/native_simulator/common/src/nct.c b/scripts/native_simulator/common/src/nct.c index d048f52954f67a8..c56ee2034d4c0c7 100644 --- a/scripts/native_simulator/common/src/nct.c +++ b/scripts/native_simulator/common/src/nct.c @@ -79,6 +79,7 @@ #define ERPREFIX PREFIX"error on " #define NO_MEM_ERR PREFIX"Can't allocate memory\n" +#define NCT_ENABLE_CANCEL 0 /* See Note.c1 */ #define NCT_ALLOC_CHUNK_SIZE 64 /* In how big chunks we grow the thread table */ #define NCT_REUSE_ABORTED_ENTRIES 0 /* For the Zephyr OS, tests/kernel/threads/scheduling/schedule_api fails when setting @@ -552,7 +553,6 @@ void *nct_init(void (*fptr)(void *)) void nct_clean_up(void *this_arg) { struct te_status_t *this = (struct te_status_t *)this_arg; - struct threads_table_el *tt_el; if (!this || !this->threads_table) { /* LCOV_EXCL_BR_LINE */ return; /* LCOV_EXCL_LINE */ @@ -560,7 +560,8 @@ void nct_clean_up(void *this_arg) this->terminate = true; - tt_el = this->threads_table; +#if (NCT_ENABLE_CANCEL) + struct threads_table_el *tt_el = this->threads_table; for (int i = 0; i < this->threads_table_size; i++, tt_el = tt_el->next) { if (tt_el->state != USED) { @@ -575,7 +576,7 @@ void nct_clean_up(void *this_arg) } /* LCOV_EXCL_STOP */ } - +#endif /* * This is the cleanup we do not do: * @@ -687,4 +688,17 @@ int nct_get_unique_thread_id(void *this_arg, int thread_idx) * Some other code will never or only very rarely trigger and is therefore * excluded with LCOV_EXCL_LINE * + * + * Notes about (memory) cleanup: + * + * Note.c1: + * + * In some very rare cases in very loaded machines, a race in the glibc pthread_cancel() + * seems to be triggered. + * In this, the cancelled thread cleanup overtakes the pthread_cancel() code, and frees the + * pthread structure before pthread_cancel() has finished, resulting in a dereference into already + * free'd memory, and therefore a segfault. + * Calling pthread_cancel() during cleanup is not required beyond preventing a valgrind + * memory leak report (all threads will be canceled immediately on exit). + * Therefore we do not do this, to avoid this very rare crashes. */ diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 3509c9c6fdc4890..2d8805903343c50 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -25,6 +25,7 @@ from domains import Domains from twisterlib.cmakecache import CMakeCache from twisterlib.environment import canonical_zephyr_base +from twisterlib.error import BuildError import elftools from elftools.elf.elffile import ELFFile @@ -618,8 +619,14 @@ def process(self, pipeline, done, message, lock, results): pipeline.put({"op": "report", "test": self.instance}) else: logger.debug(f"Determine test cases for test instance: {self.instance.name}") - self.determine_testcases(results) - pipeline.put({"op": "gather_metrics", "test": self.instance}) + try: + self.determine_testcases(results) + pipeline.put({"op": "gather_metrics", "test": self.instance}) + except BuildError as e: + logger.error(str(e)) + self.instance.status = "error" + self.instance.reason = str(e) + pipeline.put({"op": "report", "test": self.instance}) elif op == "gather_metrics": self.gather_metrics(self.instance) @@ -673,7 +680,8 @@ def determine_testcases(self, results): yaml_testsuite_name = self.instance.testsuite.id logger.debug(f"Determine test cases for test suite: {yaml_testsuite_name}") - elf = ELFFile(open(self.instance.get_elf_file(), "rb")) + elf_file = self.instance.get_elf_file() + elf = ELFFile(open(elf_file, "rb")) logger.debug(f"Test instance {self.instance.name} already has {len(self.instance.testcases)} cases.") new_ztest_unit_test_regex = re.compile(r"z_ztest_unit_test__([^\s]*)__([^\s]*)") @@ -695,6 +703,7 @@ def determine_testcases(self, results): detected_cases.append(testcase_id) if detected_cases: + logger.debug(f"{', '.join(detected_cases)} in {elf_file}") self.instance.testcases.clear() self.instance.testsuite.testcases.clear() diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index 62b0dd8cd335cd5..4632de8c2b61be9 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -290,15 +290,17 @@ def get_elf_file(self) -> str: build_dir = self.build_dir fns = glob.glob(os.path.join(build_dir, "zephyr", "*.elf")) - fns.extend(glob.glob(os.path.join(build_dir, "zephyr", "*.exe"))) fns.extend(glob.glob(os.path.join(build_dir, "testbinary"))) blocklist = [ 'remapped', # used for xtensa plaforms 'zefi', # EFI for Zephyr - '_pre' ] + 'qemu', # elf files generated after running in qemu + '_pre'] fns = [x for x in fns if not any(bad in os.path.basename(x) for bad in blocklist)] - if len(fns) != 1 and self.platform.type != 'native': - raise BuildError("Missing/multiple output ELF binary") + if not fns: + raise BuildError("Missing output binary") + elif len(fns) > 1: + logger.warning(f"multiple ELF files detected: {', '.join(fns)}") return fns[0] def get_buildlog_file(self) -> str: diff --git a/scripts/west_commands/runners/openocd.py b/scripts/west_commands/runners/openocd.py index 0346935a22e57f2..ff92d4f58f452bd 100644 --- a/scripts/west_commands/runners/openocd.py +++ b/scripts/west_commands/runners/openocd.py @@ -356,6 +356,11 @@ def do_debugserver(self, **kwargs): pre_init_cmd.append("-c") pre_init_cmd.append(i) + if self.thread_info_enabled and self.supports_thread_info(): + pre_init_cmd.append("-c") + rtos_command = '${} configure -rtos Zephyr'.format(self.target_handle) + pre_init_cmd.append(rtos_command) + cmd = (self.openocd_cmd + self.cfg_cmd + ['-c', 'tcl_port {}'.format(self.tcl_port), '-c', 'telnet_port {}'.format(self.telnet_port), diff --git a/soc/arm/infineon_cat1/psoc6/Kconfig.defconfig.soc.psoc6_04 b/soc/arm/infineon_cat1/psoc6/Kconfig.defconfig.soc.psoc6_04 new file mode 100644 index 000000000000000..622a0af848f39e7 --- /dev/null +++ b/soc/arm/infineon_cat1/psoc6/Kconfig.defconfig.soc.psoc6_04 @@ -0,0 +1,37 @@ +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) David Ullmann +# SPDX-License-Identifier: Apache-2.0 + +# Infineon PSoC6_04 based MCU default configuration + +if SOC_DIE_PSOC6_04 + +config NUM_IRQS + default 16 if CPU_CORTEX_M0PLUS + default 175 if CPU_CORTEX_M4 + +config SOC + default "CY8C6244AZI_S4D92" if SOC_CY8C6244AZI_S4D92 + default "CY8C6244LQI_S4D92" if SOC_CY8C6244LQI_S4D92 + default "CY8C6244AZI_S4D93" if SOC_CY8C6244AZI_S4D93 + default "CY8C6244AZI_S4D82" if SOC_CY8C6244AZI_S4D82 + default "CY8C6244LQI_S4D82" if SOC_CY8C6244LQI_S4D82 + default "CY8C6244AZI_S4D83" if SOC_CY8C6244AZI_S4D83 + default "CY8C6244AZI_S4D62" if SOC_CY8C6244AZI_S4D62 + default "CY8C6244LQI_S4D62" if SOC_CY8C6244LQI_S4D62 + default "CY8C6244AZI_S4D12" if SOC_CY8C6244AZI_S4D12 + default "CY8C6244LQI_S4D12" if SOC_CY8C6244LQI_S4D12 + default "CY8C6144AZI_S4F92" if SOC_CY8C6144AZI_S4F92 + default "CY8C6144LQI_S4F92" if SOC_CY8C6144LQI_S4F92 + default "CY8C6144AZI_S4F93" if SOC_CY8C6144AZI_S4F93 + default "CY8C6144AZI_S4F82" if SOC_CY8C6144AZI_S4F82 + default "CY8C6144LQI_S4F82" if SOC_CY8C6144LQI_S4F82 + default "CY8C6144AZI_S4F83" if SOC_CY8C6144AZI_S4F83 + default "CY8C6144AZI_S4F62" if SOC_CY8C6144AZI_S4F62 + default "CY8C6144LQI_S4F62" if SOC_CY8C6144LQI_S4F62 + default "CY8C6144AZI_S4F12" if SOC_CY8C6144AZI_S4F12 + default "CY8C6144LQI_S4F12" if SOC_CY8C6144LQI_S4F12 + + +endif # SOC_DIE_PSOC6_04 diff --git a/soc/arm/infineon_cat1/psoc6/Kconfig.soc.psoc6_04 b/soc/arm/infineon_cat1/psoc6/Kconfig.soc.psoc6_04 new file mode 100644 index 000000000000000..b18e8ecaa825e32 --- /dev/null +++ b/soc/arm/infineon_cat1/psoc6/Kconfig.soc.psoc6_04 @@ -0,0 +1,125 @@ +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Infineon PSoC6_04 series MCUs + +config SOC_CY8C6244AZI_S4D92 + bool "CY8C6244AZI_S4D92" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244LQI_S4D92 + bool "CY8C6244LQI_S4D92" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244AZI_S4D93 + bool "CY8C6244AZI_S4D93" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_80_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244AZI_S4D82 + bool "CY8C6244AZI_S4D82" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244LQI_S4D82 + bool "CY8C6244LQI_S4D82" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244AZI_S4D83 + bool "CY8C6244AZI_S4D83" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_80_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244AZI_S4D62 + bool "CY8C6244AZI_S4D62" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244LQI_S4D62 + bool "CY8C6244LQI_S4D62" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244AZI_S4D12 + bool "CY8C6244AZI_S4D12" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6244LQI_S4D12 + bool "CY8C6244LQI_S4D12" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_62 + +config SOC_CY8C6144AZI_S4F92 + bool "CY8C6144AZI_S4F92" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144LQI_S4F92 + bool "CY8C6144LQI_S4F92" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144AZI_S4F93 + bool "CY8C6144AZI_S4F93" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_80_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144AZI_S4F82 + bool "CY8C6144AZI_S4F82" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144LQI_S4F82 + bool "CY8C6144LQI_S4F82" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144AZI_S4F83 + bool "CY8C6144AZI_S4F83" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_80_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144AZI_S4F62 + bool "CY8C6144AZI_S4F62" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144LQI_S4F62 + bool "CY8C6144LQI_S4F62" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144AZI_S4F12 + bool "CY8C6144AZI_S4F12" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_64_TQFP + depends on SOC_SERIES_PSOC_61 + +config SOC_CY8C6144LQI_S4F12 + bool "CY8C6144LQI_S4F12" + select SOC_DIE_PSOC6_04 + select SOC_PACKAGE_PSOC6_04_68_QFN + depends on SOC_SERIES_PSOC_61 diff --git a/soc/arm/infineon_xmc/4xxx/Kconfig.series b/soc/arm/infineon_xmc/4xxx/Kconfig.series index 66a93102352c4ec..5bfdb994fe43bc5 100644 --- a/soc/arm/infineon_xmc/4xxx/Kconfig.series +++ b/soc/arm/infineon_xmc/4xxx/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_XMC_4XXX select HAS_XMCLIB_DMA select HAS_XMCLIB_SPI select HAS_XMCLIB_I2C + select HAS_XMCLIB_CCU help Enable support for XMC 4xxx MCU series diff --git a/soc/arm/infineon_xmc/4xxx/soc.c b/soc/arm/infineon_xmc/4xxx/soc.c index 9f1b2162333f398..0d4060568a33b9a 100644 --- a/soc/arm/infineon_xmc/4xxx/soc.c +++ b/soc/arm/infineon_xmc/4xxx/soc.c @@ -31,7 +31,14 @@ void z_arm_platform_init(void) temp |= PMU_FLASH_WS; FLASH0->FCON = temp; - XMC_SCU_CLOCK_SetSleepConfig(XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_SYSCLK_FPLL); + XMC_SCU_CLOCK_SetSleepConfig(XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_SYSCLK_FPLL +#ifdef CONFIG_PWM_XMC4XXX_CCU4 + | XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_ENABLE_CCU +#endif +#ifdef CONFIG_PWM_XMC4XXX_CCU8 + | XMC_SCU_CLOCK_SLEEP_MODE_CONFIG_ENABLE_CCU +#endif + ); /* configure PLL & system clock */ SystemCoreClockSetup(); diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52833_QDAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52833_QDAA new file mode 100644 index 000000000000000..237bee5813a2912 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52833_QDAA @@ -0,0 +1,16 @@ +# Nordic Semiconductor nRF52833 MCU + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF52833_QDAA + +config SOC + string + default "nRF52833_QDAA" + +config NUM_IRQS + int + default 48 + +endif # SOC_NRF52833_QDAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52840_QFAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52840_QFAA new file mode 100644 index 000000000000000..451fea911b45a62 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52840_QFAA @@ -0,0 +1,14 @@ +# Nordic Semiconductor nRF52840 MCU + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF52840_QFAA + +config SOC + default "nRF52840_QFAA" + +config NUM_IRQS + default 48 + +endif # SOC_NRF52840_QFAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index d423779a63ffa67..13a2fef932b0b79 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -64,10 +64,18 @@ config SOC_NRF52832_QFAB bool "NRF52832_QFAB" select SOC_NRF52832 +config SOC_NRF52833_QDAA + bool "NRF52833_QDAA" + select SOC_NRF52833 + config SOC_NRF52833_QIAA bool "NRF52833_QIAA" select SOC_NRF52833 +config SOC_NRF52840_QFAA + bool "NRF52840_QFAA" + select SOC_NRF52840 + config SOC_NRF52840_QIAA bool "NRF52840_QIAA" select SOC_NRF52840 @@ -81,7 +89,7 @@ config SOC_DCDC_NRF52X config SOC_DCDC_NRF52X_HV bool - depends on SOC_NRF52840 + depends on SOC_NRF52840_QIAA help Enable nRF52 series System on Chip High Voltage DC/DC converter. diff --git a/soc/arm/nxp_s32/s32k/Kconfig.series b/soc/arm/nxp_s32/s32k/Kconfig.series index 3bee28013eafd7b..5d41e1bc1dc9ffd 100644 --- a/soc/arm/nxp_s32/s32k/Kconfig.series +++ b/soc/arm/nxp_s32/s32k/Kconfig.series @@ -16,5 +16,7 @@ config SOC_SERIES_S32K3_M7 select CLOCK_CONTROL select HAS_MCUX select HAS_MCUX_LPUART + select HAS_MCUX_FLEXCAN + select HAS_MCUX_LPI2C help Enable support for NXP S32K3 MCUs family on Cortex-M7 cores diff --git a/soc/arm/quicklogic_eos_s3/pinctrl_soc.h b/soc/arm/quicklogic_eos_s3/pinctrl_soc.h new file mode 100644 index 000000000000000..957129a3d0e3a87 --- /dev/null +++ b/soc/arm/quicklogic_eos_s3/pinctrl_soc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ +#define ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pinctrl_soc_pin_t { + uint32_t pin; + uint32_t iof; + uint32_t input_enable: 1; + uint32_t output_enable: 1; + uint32_t pull_up: 1; + uint32_t pull_down: 1; + uint32_t high_impedance: 1; + uint32_t slew_rate: 2; + uint8_t drive_strength; + uint32_t schmitt_enable: 1; + uint32_t control_selection: 2; +} pinctrl_soc_pin_t; + +#define QUICKLOGIC_EOS_S3_DT_PIN(node_id) \ + { \ + .pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .iof = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .input_enable = DT_PROP(node_id, input_enable), \ + .output_enable = DT_PROP(node_id, output_enable), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .high_impedance = DT_PROP(node_id, bias_high_impedance), \ + .slew_rate = DT_ENUM_IDX(node_id, slew_rate), \ + .drive_strength = DT_PROP_OR(node_id, drive_strength, 4), \ + .schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \ + .control_selection = DT_ENUM_IDX(node_id, quicklogic_control_selection), \ + }, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + QUICKLOGIC_EOS_S3_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ */ diff --git a/soc/arm/quicklogic_eos_s3/soc.c b/soc/arm/quicklogic_eos_s3/soc.c index 81d070df427cb53..ed2cdb70ef96430 100644 --- a/soc/arm/quicklogic_eos_s3/soc.c +++ b/soc/arm/quicklogic_eos_s3/soc.c @@ -20,20 +20,6 @@ void eos_s3_lock_disable(void) MISC_CTRL->LOCK_KEY_CTRL = 1; } -int eos_s3_io_mux(uint32_t pad_nr, uint32_t pad_cfg) -{ - volatile uint32_t *p = (uint32_t *)IO_MUX_BASE; - - if (pad_nr > EOS_S3_MAX_PAD_NR) { - return -EINVAL; - } - - p += pad_nr; - *p = pad_cfg; - - return 0; -} - static void eos_s3_cru_init(void) { /* Set desired frequency */ diff --git a/soc/arm/quicklogic_eos_s3/soc.h b/soc/arm/quicklogic_eos_s3/soc.h index b294be96e9bbabf..a82e5399248c882 100644 --- a/soc/arm/quicklogic_eos_s3/soc.h +++ b/soc/arm/quicklogic_eos_s3/soc.h @@ -46,11 +46,7 @@ #define OSC_SET_FREQ_INC(FREQ) (AIP->OSC_CTRL_1 = ((FREQ / 32768) - 3) & 0xFFF) #define OSC_GET_FREQ_INC() (((AIP->OSC_CTRL_1 & 0xFFF) + 3) * 32768) -#define EOS_S3_MAX_PAD_NR 45 - void eos_s3_lock_enable(void); void eos_s3_lock_disable(void); -int eos_s3_io_mux(uint32_t pad_nr, uint32_t pad_cfg); - #endif /* _SOC__H_ */ diff --git a/soc/arm/quicklogic_eos_s3/soc_pinmap.h b/soc/arm/quicklogic_eos_s3/soc_pinmap.h index 65715300c61177d..1acee4443649770 100644 --- a/soc/arm/quicklogic_eos_s3/soc_pinmap.h +++ b/soc/arm/quicklogic_eos_s3/soc_pinmap.h @@ -9,14 +9,4 @@ #include -/* Set UART TX to PAD44 */ -#define UART_TXD_PAD44 (UART_TXD_SEL_PAD44 | PAD_CTRL_SEL_AO_REG \ - | PAD_OEN_NORMAL | PAD_P_Z | PAD_SR_SLOW \ - | PAD_E_4MA | PAD_REN_DISABLE | PAD_SMT_DISABLE) - -/* Set UART RX to PAD45 */ -#define UART_RXD_PAD45 (UART_RXD_SEL_PAD45 | PAD_CTRL_SEL_AO_REG \ - | PAD_OEN_DISABLE | PAD_P_Z | PAD_SR_SLOW \ - | PAD_E_4MA | PAD_REN_ENABLE | PAD_SMT_DISABLE) - #endif /* _QUICKLOGIC_EOS_S3_SOC_PINMAP_H_ */ diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index af050de810903bd..d2faeca4bf6436e 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -28,6 +28,13 @@ config SOC_GECKO_SERIES2 This is equivalent of _SILICON_LABS_32B_SERIES_2 definition in HAL code. +config SOC_GECKO_SERIES1 + bool + help + Set if we're building for Gecko Series 1 SoC. + This is equivalent of _SILICON_LABS_32B_SERIES_1 definition in HAL + code. + config SOC_GECKO_BURTC bool help @@ -312,4 +319,11 @@ 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_USE_RAIL + bool "Use RAIL (Radio Abstraction Interface Layer)" + 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. + endif # SOC_FAMILY_EXX32 diff --git a/soc/arm/silabs_exx32/common/pinctrl_soc.h b/soc/arm/silabs_exx32/common/pinctrl_soc.h index 7bbcdeab81ba473..8cfad9d46883919 100644 --- a/soc/arm/silabs_exx32/common/pinctrl_soc.h +++ b/soc/arm/silabs_exx32/common/pinctrl_soc.h @@ -15,7 +15,11 @@ #include #include +#if CONFIG_SOC_GECKO_SERIES1 +#include +#else #include +#endif #ifdef __cplusplus extern "C" { diff --git a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series index 2d9675430bef699..c82872f4eec06b6 100644 --- a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_EFM32JG12B select SOC_FAMILY_EXX32 select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE + select SOC_GECKO_SERIES1 select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO diff --git a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series index 6df3aa9b6997ce1..0ab448b6fb72878 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_EFM32PG12B select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_EXX32 + select SOC_GECKO_SERIES1 select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE select SOC_GECKO_CMU diff --git a/soc/arm/st_stm32/stm32l4/power.c b/soc/arm/st_stm32/stm32l4/power.c index 8b1a68fc767e875..44fe58e8f49d1d8 100644 --- a/soc/arm/st_stm32/stm32l4/power.c +++ b/soc/arm/st_stm32/stm32l4/power.c @@ -132,8 +132,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) case PM_STATE_SOFT_OFF: /* We should not get there */ __fallthrough; - case PM_STATE_ACTIVE: - __fallthrough; case PM_STATE_SUSPEND_TO_RAM: __fallthrough; case PM_STATE_SUSPEND_TO_DISK: diff --git a/soc/arm/st_stm32/stm32u5/power.c b/soc/arm/st_stm32/stm32u5/power.c index 4cd5834cf8be8e8..4d6034a8c47f0e8 100644 --- a/soc/arm/st_stm32/stm32u5/power.c +++ b/soc/arm/st_stm32/stm32u5/power.c @@ -105,8 +105,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) case PM_STATE_SOFT_OFF: /* We should not get there */ __fallthrough; - case PM_STATE_ACTIVE: - __fallthrough; case PM_STATE_SUSPEND_TO_RAM: __fallthrough; case PM_STATE_SUSPEND_TO_DISK: diff --git a/soc/arm/st_stm32/stm32wba/power.c b/soc/arm/st_stm32/stm32wba/power.c index 83073b7b293cb40..4d7fd0d049103c0 100644 --- a/soc/arm/st_stm32/stm32wba/power.c +++ b/soc/arm/st_stm32/stm32wba/power.c @@ -82,8 +82,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) case PM_STATE_SOFT_OFF: /* We should not get there */ __fallthrough; - case PM_STATE_ACTIVE: - __fallthrough; case PM_STATE_SUSPEND_TO_RAM: __fallthrough; case PM_STATE_SUSPEND_TO_DISK: diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/pinctrl_soc.h b/soc/arm/ti_simplelink/cc13x2_cc26x2/pinctrl_soc.h index df1ec138fb23353..94d71f51f63984d 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/pinctrl_soc.h +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/pinctrl_soc.h @@ -9,26 +9,7 @@ #include -/* Defines for enabling/disabling an IO */ -#define IOC_SLEW_ENABLE 0x00001000 -#define IOC_SLEW_DISABLE 0x00000000 -#define IOC_INPUT_ENABLE 0x20000000 -#define IOC_INPUT_DISABLE 0x00000000 -#define IOC_HYST_ENABLE 0x40000000 -#define IOC_HYST_DISABLE 0x00000000 - -/* Defines that can be used to set the IO Mode of an IO */ -#define IOC_IOMODE_NORMAL 0x00000000 -#define IOC_IOMODE_INV 0x01000000 -#define IOC_IOMODE_OPEN_DRAIN_NORMAL 0x04000000 -#define IOC_IOMODE_OPEN_DRAIN_INV 0x05000000 -#define IOC_IOMODE_OPEN_SRC_NORMAL 0x06000000 -#define IOC_IOMODE_OPEN_SRC_INV 0x07000000 - -/* Defines that can be used to set pull on an IO */ -#define IOC_NO_IOPULL 0x00006000 -#define IOC_IOPULL_UP 0x00004000 -#define IOC_IOPULL_DOWN 0x00002000 +#include typedef struct pinctrl_soc_pin { uint32_t pin; @@ -43,8 +24,10 @@ typedef struct pinctrl_soc_pin { DT_PROP(node_id, bias_disable) * IOC_NO_IOPULL | \ DT_PROP(node_id, drive_open_drain) * IOC_IOMODE_OPEN_DRAIN_NORMAL | \ DT_PROP(node_id, drive_open_source) * IOC_IOMODE_OPEN_SRC_NORMAL | \ + (DT_PROP(node_id, drive_strength) >> 2) << IOC_IOCFG0_IOCURR_S | \ DT_PROP(node_id, input_enable) * IOC_INPUT_ENABLE | \ - DT_PROP(node_id, input_schmitt_enable) * IOC_HYST_ENABLE) + DT_PROP(node_id, input_schmitt_enable) * IOC_HYST_ENABLE | \ + DT_PROP(node_id, ti_input_edge_detect)) #define CC13XX_CC26XX_DT_PIN(node_id) \ { \ diff --git a/soc/x86/intel_ish/CMakeLists.txt b/soc/x86/intel_ish/CMakeLists.txt new file mode 100644 index 000000000000000..667c8ac97e4cd16 --- /dev/null +++ b/soc/x86/intel_ish/CMakeLists.txt @@ -0,0 +1,7 @@ +# Intel ISH SoC family +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/x86/intel_ish/Kconfig b/soc/x86/intel_ish/Kconfig new file mode 100644 index 000000000000000..9c13acba9d55df0 --- /dev/null +++ b/soc/x86/intel_ish/Kconfig @@ -0,0 +1,14 @@ +# Intel ISH family configuration options +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_INTEL_ISH + bool "Intel ISH SoC family" + select X86 + select X86_NO_SPECULATIVE_VULNERABILITIES + select IOAPIC + select LOAPIC + select CPU_HAS_FPU + select INTEL_HAL diff --git a/soc/x86/intel_ish/Kconfig.defconfig b/soc/x86/intel_ish/Kconfig.defconfig new file mode 100644 index 000000000000000..adcca64b9a80694 --- /dev/null +++ b/soc/x86/intel_ish/Kconfig.defconfig @@ -0,0 +1,30 @@ +# Intel ISH family default configuration options +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_INTEL_ISH + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 if HPET_TIMER + +config SOC_FAMILY + string + default "intel_ish" + +config X86_VERY_EARLY_CONSOLE + default n + +config SRAM_OFFSET + hex + default 0x0 + +# Target platforms are not PC-compatible +# (e.g. without BIOS, ACPI, CMOS, etc.). +config X86_PC_COMPATIBLE + default n + +endif # SOC_FAMILY_INTEL_ISH + +rsource "*/Kconfig.defconfig.series" diff --git a/soc/x86/intel_ish/Kconfig.soc b/soc/x86/intel_ish/Kconfig.soc new file mode 100644 index 000000000000000..b4b1e1456b93f38 --- /dev/null +++ b/soc/x86/intel_ish/Kconfig.soc @@ -0,0 +1,8 @@ +# Intel ISH family selection +# +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +rsource "*/Kconfig.series" +rsource "*/Kconfig.soc" diff --git a/soc/x86/intel_ish/doc/supported_features.txt b/soc/x86/intel_ish/doc/supported_features.txt new file mode 100644 index 000000000000000..41d34a732b8c4d2 --- /dev/null +++ b/soc/x86/intel_ish/doc/supported_features.txt @@ -0,0 +1,7 @@ +Supported Features +================== + +In addition to the standard architecture devices (HPET, local and I/O APICs, +etc.), Zephyr supports the following ISH-specific SoC devices: + +* HSUART diff --git a/soc/x86/intel_ish/intel_ish5/CMakeLists.txt b/soc/x86/intel_ish/intel_ish5/CMakeLists.txt new file mode 100644 index 000000000000000..ee4d915f9b19fe0 --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_cc_option(-march=pentium -mtune=i486) + +zephyr_sources(soc.c) + +include(../utils/build_ish_firmware.cmake) diff --git a/soc/x86/intel_ish/intel_ish5/Kconfig.defconfig.series b/soc/x86/intel_ish/intel_ish5/Kconfig.defconfig.series new file mode 100644 index 000000000000000..a7865f8fd939fbf --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/Kconfig.defconfig.series @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_SERIES_INTEL_ISH5 + +config SOC_SERIES + string + default "intel_ish5" + +config SOC + string + default "intel_ish_5_4_1" if SOC_INTEL_ISH_5_4_1 + default "intel_ish_5_6_0" if SOC_INTEL_ISH_5_6_0 + default "intel_ish_5_8_0" if SOC_INTEL_ISH_5_8_0 + +endif # SOC_SERIES_INTEL_ISH5 diff --git a/soc/x86/intel_ish/intel_ish5/Kconfig.series b/soc/x86/intel_ish/intel_ish5/Kconfig.series new file mode 100644 index 000000000000000..ef39ee29c20aeec --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/Kconfig.series @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_SERIES_INTEL_ISH5 + bool "Intel ISH5 SoC" + select SOC_FAMILY_INTEL_ISH diff --git a/soc/x86/intel_ish/intel_ish5/Kconfig.soc b/soc/x86/intel_ish/intel_ish5/Kconfig.soc new file mode 100644 index 000000000000000..bbc4a76fdae429f --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/Kconfig.soc @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +choice + prompt "Intel ISH5 SoCs" + depends on SOC_SERIES_INTEL_ISH5 + +config SOC_INTEL_ISH_5_4_1 + bool "Intel ISH 5.4.1 SoC" + +config SOC_INTEL_ISH_5_6_0 + bool "Intel ISH 5.6.0 SoC" + +config SOC_INTEL_ISH_5_8_0 + bool "Intel ISH 5.8.0 SoC" + +endchoice diff --git a/soc/x86/intel_ish/intel_ish5/linker.ld b/soc/x86/intel_ish/intel_ish5/linker.ld new file mode 100644 index 000000000000000..0795cf8a6f5063b --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/linker.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/soc/x86/intel_ish/intel_ish5/soc.c b/soc/x86/intel_ish/intel_ish5/soc.c new file mode 100644 index 000000000000000..ccf044824a7fb2e --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/soc.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc.h" + +#if defined(CONFIG_HPET_TIMER) +#include "sedi_driver_hpet.h" +#endif + +static int intel_ish_init(void) +{ +#if defined(CONFIG_HPET_TIMER) + sedi_hpet_set_min_delay(HPET_CMP_MIN_DELAY); +#endif + + return 0; +} + +SYS_INIT(intel_ish_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/x86/intel_ish/intel_ish5/soc.h b/soc/x86/intel_ish/intel_ish5/soc.h new file mode 100644 index 000000000000000..69528a74b688522 --- /dev/null +++ b/soc/x86/intel_ish/intel_ish5/soc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023, Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_H_ +#define __SOC_H_ + +#include + +#ifndef _ASMLANGUAGE +#include +#include + +#ifdef CONFIG_HPET_TIMER +#include "sedi_driver_hpet.h" + +#define HPET_USE_CUSTOM_REG_ACCESS_FUNCS + +/* COUNTER_CLK_PERIOD (CLK_PERIOD_REG) is in picoseconds (1e-12 sec) */ +#define HPET_COUNTER_CLK_PERIOD (1000000000000ULL) + +#define HPET_CMP_MIN_DELAY (5) + +__pinned_func +static inline void hpet_timer_comparator_set(uint64_t next) +{ + sedi_hpet_set_comparator(HPET_0, next); +} + +#endif /*CONFIG_HPET_TIMER */ + +#endif /* !_ASMLANGUAGE */ + +/* ISH specific DMA channel direction */ +#define IMR_TO_MEMORY (DMA_CHANNEL_DIRECTION_PRIV_START) +#define MEMORY_TO_IMR (DMA_CHANNEL_DIRECTION_PRIV_START + 1) + +#endif /* __SOC_H_ */ diff --git a/soc/x86/intel_ish/utils/build_ish_firmware.cmake b/soc/x86/intel_ish/utils/build_ish_firmware.cmake new file mode 100644 index 000000000000000..faaab0c5f5ebb15 --- /dev/null +++ b/soc/x86/intel_ish/utils/build_ish_firmware.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/build_ish_firmware.py + ARGS -k ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin + -o ${PROJECT_BINARY_DIR}/ish_fw.bin +) diff --git a/soc/x86/intel_ish/utils/build_ish_firmware.py b/soc/x86/intel_ish/utils/build_ish_firmware.py new file mode 100644 index 000000000000000..3db3909e66f1846 --- /dev/null +++ b/soc/x86/intel_ish/utils/build_ish_firmware.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*-" + +# Copyright 2019 The Chromium OS Authors. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Script to pack EC binary with manifest header. + +Package ecos main FW binary (kernel) and AON task binary into final EC binary +image with a manifest header, ISH shim loader will parse this header and load +each binaries into right memory location. +""" + +import argparse +import struct +import os + +MANIFEST_ENTRY_SIZE = 0x80 +HEADER_SIZE = 0x1000 +PAGE_SIZE = 0x1000 + +def parseargs(): + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("-k", "--kernel", + help="EC kernel binary to pack, \ + usually ec.RW.bin or ec.RW.flat.", + required=True) + parser.add_argument("-a", "--aon", + help="EC aontask binary to pack, \ + usually ish_aontask.bin.", + required=False) + parser.add_argument("-o", "--output", + help="Output flash binary file") + + return parser.parse_args() + +def gen_manifest(ext_id, comp_app_name, code_offset, module_size): + """Returns a binary blob that represents a manifest entry""" + m = bytearray(MANIFEST_ENTRY_SIZE) + + # 4 bytes of ASCII encode ID (little endian) + struct.pack_into('<4s', m, 0, ext_id) + # 8 bytes of ASCII encode ID (little endian) + struct.pack_into('<8s', m, 32, comp_app_name) + # 4 bytes of code offset (little endian) + struct.pack_into(' 0) + +def main(): + args = parseargs() + print(" Packing EC image file for ISH") + + with open(args.output, 'wb') as f: + kernel_size = os.path.getsize(args.kernel) + + if args.aon is not None: + aon_size = os.path.getsize(args.aon) + + print(" kernel binary size:", kernel_size) + kern_rdup_pg_size = roundup_page(kernel_size) + # Add manifest for main ISH binary + f.write(gen_manifest(b'ISHM', b'ISH_KERN', HEADER_SIZE, kern_rdup_pg_size)) + + if args.aon is not None: + print(" AON binary size: ", aon_size) + aon_rdup_pg_size = roundup_page(aon_size) + # Add manifest for aontask binary + f.write(gen_manifest(b'ISHM', b'AON_TASK', + (HEADER_SIZE + kern_rdup_pg_size * PAGE_SIZE - + MANIFEST_ENTRY_SIZE), aon_rdup_pg_size)) + + # Add manifest that signals end of manifests + f.write(gen_manifest(b'ISHE', b'', 0, 0)) + + # Pad the remaining HEADER with 0s + if args.aon is not None: + f.write(b'\x00' * (HEADER_SIZE - (MANIFEST_ENTRY_SIZE * 3))) + else: + f.write(b'\x00' * (HEADER_SIZE - (MANIFEST_ENTRY_SIZE * 2))) + + # Append original kernel image + with open(args.kernel, 'rb') as in_file: + f.write(in_file.read()) + # Filling padings due to size round up as pages + f.write(b'\x00' * (kern_rdup_pg_size * PAGE_SIZE - kernel_size)) + + if args.aon is not None: + # Append original aon image + with open(args.aon, 'rb') as in_file: + f.write(in_file.read()) + # Filling padings due to size round up as pages + f.write(b'\x00' * (aon_rdup_pg_size * PAGE_SIZE - aon_size)) + +if __name__ == '__main__': + main() diff --git a/soc/xtensa/espressif_esp32/common/Kconfig.soc b/soc/xtensa/espressif_esp32/common/Kconfig.soc index 4cf8bf9095f824d..3446e6882434cfc 100644 --- a/soc/xtensa/espressif_esp32/common/Kconfig.soc +++ b/soc/xtensa/espressif_esp32/common/Kconfig.soc @@ -40,6 +40,15 @@ config ESP_HEAP_SEARCH_ALL_REGIONS menu "SPI RAM config" depends on ESP_SPIRAM +choice SPIRAM_MODE + prompt "Mode (QUAD/OCT) of SPI RAM chip in use" + default SPIRAM_MODE_QUAD + +config SPIRAM_MODE_QUAD + bool "Quad Mode PSRAM" + +endchoice # SPIRAM_MODE + choice SPIRAM_TYPE prompt "Type of SPI RAM chip in use" depends on ESP_SPIRAM @@ -98,6 +107,10 @@ config SPIRAM_SPEED_80M depends on ESPTOOLPY_FLASHFREQ_80M bool "80MHz clock speed" +config SPIRAM_SPEED_120M + depends on SPIRAM_MODE_QUAD && SOC_SERIES_ESP32S3 + bool "120MHz clock speed" + endchoice # SPIRAM_SPEED menu "PSRAM clock and cs IO for ESP32-DOWD" diff --git a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc index 7dd8fc4dddb83a6..ac265e5edb011fb 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc +++ b/soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc @@ -293,4 +293,23 @@ config MAC_BB_PD endmenu # Cache config +menu "PSRAM Clock and CS IO for ESP32S3" + depends on ESP_SPIRAM + +config DEFAULT_PSRAM_CLK_IO + int "PSRAM CLK IO number" + range 0 33 + default 30 + help + The PSRAM Clock IO can be any unused GPIO, please refer to your hardware design. + +config DEFAULT_PSRAM_CS_IO + int "PSRAM CS IO number" + range 0 33 + default 26 + help + The PSRAM CS IO can be any unused GPIO, please refer to your hardware design. + +endmenu # PSRAM clock and cs IO for ESP32S3 + endif # SOC_SERIES_ESP32S3 diff --git a/soc/xtensa/espressif_esp32/esp32s3/default.ld b/soc/xtensa/espressif_esp32/esp32s3/default.ld index 4361e7b38e3abf3..27e27a0a8cba41f 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/default.ld +++ b/soc/xtensa/espressif_esp32/esp32s3/default.ld @@ -39,6 +39,8 @@ #define RAMABLE_REGION dram0_0_seg #define ROMABLE_REGION ROM +#define EXT_RAM_ORG (0x3E000000 - CONFIG_ESP_SPIRAM_SIZE) + #ifdef CONFIG_FLASH_SIZE #define FLASH_SIZE CONFIG_FLASH_SIZE #else @@ -70,7 +72,13 @@ MEMORY * Hence, an offset of 0x40 is added to DROM segment origin. */ drom0_0_seg(R): org = 0x3C000040, len = FLASH_SIZE - 0x40 - + /** + * `extern_ram_seg` and `drom0_0_seg` share the same bus and the address region. + * so we allocate `extern_ram_seg` at the end of the address region. + */ +#if defined(CONFIG_ESP_SPIRAM) + ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE +#endif /* RTC fast memory (executable). Persists over deep sleep. */ rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000 @@ -219,6 +227,28 @@ SECTIONS _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) +#if defined(CONFIG_ESP_SPIRAM) + /* This section holds .ext_ram.bss data, and will be put in PSRAM */ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + . = ALIGN(4); + _ext_ram_bss_end = ABSOLUTE(.); + } > ext_ram_seg + + .ext_ram_noinit (NOLOAD) : + { +#if defined(CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM) + *libdrivers__wifi.a:(.noinit .noinit.*) + *libsubsys__net__l2__ethernet.a:(.noinit .noinit.*) + *libsubsys__net__lib__config.a:(.noinit .noinit.*) + *libsubsys__net__ip.a:(.noinit .noinit.*) + *libsubsys__net.a:(.noinit .noinit.*) +#endif + } > ext_ram_seg +#endif + /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) { @@ -272,6 +302,9 @@ SECTIONS *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libzephyr.a:spiram*.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_timing*.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash*.*(.literal .text .literal.* .text.*) *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) *libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*) *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) @@ -642,3 +675,8 @@ SECTIONS ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), "IRAM0 segment data does not fit.") + +#if defined(CONFIG_ESP_SPIRAM) +ASSERT(((ORIGIN(ext_ram_seg)) > _image_rodata_end), + "External RAM segment does not fit.") +#endif diff --git a/soc/xtensa/espressif_esp32/esp32s3/soc.c b/soc/xtensa/espressif_esp32/esp32s3/soc.c index 3e8bb7373202e71..4d44fe2f004aeb7 100644 --- a/soc/xtensa/espressif_esp32/esp32s3/soc.c +++ b/soc/xtensa/espressif_esp32/esp32s3/soc.c @@ -34,11 +34,18 @@ #include "esp_app_format.h" #include "esp_clk_internal.h" +#include "esp32s3/spiram.h" + #ifdef CONFIG_MCUBOOT #include "bootloader_init.h" #endif /* CONFIG_MCUBOOT */ #include +#if CONFIG_ESP_SPIRAM +extern int _ext_ram_bss_start; +extern int _ext_ram_bss_end; +#endif + extern void z_cstart(void); #ifndef CONFIG_MCUBOOT @@ -104,6 +111,30 @@ void IRAM_ATTR __esp_platform_start(void) /* Apply SoC patches */ esp_errata(); +#if CONFIG_ESP_SPIRAM + esp_err_t err = esp_spiram_init(); + + if (err != ESP_OK) { + printk("Failed to Initialize external RAM, aborting.\n"); + abort(); + } + + esp_spiram_init_cache(); + if (esp_spiram_get_size() < CONFIG_ESP_SPIRAM_SIZE) { + printk("External RAM size is less than configured, aborting.\n"); + abort(); + } + + if (!esp_spiram_test()) { + printk("External RAM failed memory test!\n"); + abort(); + } + + memset(&_ext_ram_bss_start, 0, + (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); + +#endif /* CONFIG_ESP_SPIRAM */ + /* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence * related issues in application. Hence disable that as we are about to start * Zephyr environment. diff --git a/soc/xtensa/intel_adsp/Kconfig b/soc/xtensa/intel_adsp/Kconfig index a2b9c1011d2ecbb..f04286ccae12b4d 100644 --- a/soc/xtensa/intel_adsp/Kconfig +++ b/soc/xtensa/intel_adsp/Kconfig @@ -95,6 +95,13 @@ config ADSP_INIT_HPSRAM help Need to init HP SRAM. +config ADSP_POWER_DOWN_HPSRAM + bool + default n if ZTEST + default y + help + Switch off HP SRAM during power down. + config ADSP_DISABLE_L2CACHE_AT_BOOT bool diff --git a/soc/xtensa/intel_adsp/ace/power.c b/soc/xtensa/intel_adsp/ace/power.c index cb915988298182c..620a6852bd63ceb 100644 --- a/soc/xtensa/intel_adsp/ace/power.c +++ b/soc/xtensa/intel_adsp/ace/power.c @@ -282,9 +282,12 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) (void *)rom_entry; sys_cache_data_flush_range(imr_layout, sizeof(*imr_layout)); #endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */ + uint32_t hpsram_mask = 0; +#ifdef CONFIG_ADSP_POWER_DOWN_HPSRAM /* turn off all HPSRAM banks - get a full bitmap */ uint32_t ebb_banks = ace_hpsram_get_bank_count(); - uint32_t hpsram_mask = (1 << ebb_banks) - 1; + hpsram_mask = (1 << ebb_banks) - 1; +#endif /* CONFIG_ADSP_POWER_DOWN_HPSRAM */ /* do power down - this function won't return */ power_down(true, uncache_to_cache(&hpsram_mask), true); diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index 42598e9b56fd28a..8bb18f316f34392 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -87,7 +87,7 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) soc_cpus_active[cpu] = false; sys_cache_data_flush_and_invd_all(); if (cpu == 0) { - uint32_t hpsram_mask[HPSRAM_SEGMENTS]; + uint32_t hpsram_mask[HPSRAM_SEGMENTS] = {0}; struct imr_header hdr = { .adsp_imr_magic = ADSP_IMR_MAGIC_VALUE, @@ -97,9 +97,11 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) arch_xtensa_uncached_ptr((struct imr_layout *)L3_MEM_BASE_ADDR); imr_layout->imr_state.header = hdr; +#ifdef CONFIG_ADSP_POWER_DOWN_HPSRAM /* turn off all HPSRAM banks - get a full bitmap */ for (int i = 0; i < HPSRAM_SEGMENTS; i++) hpsram_mask[i] = HPSRAM_MEMMASK(i); +#endif /* CONFIG_ADSP_POWER_DOWN_HPSRAM */ /* do power down - this function won't return */ power_down_cavs(true, uncache_to_cache(&hpsram_mask[0])); } else { diff --git a/soc/xtensa/nxp_adsp/imx8m/linker.ld b/soc/xtensa/nxp_adsp/imx8m/linker.ld index 2f23680d55524ee..aab0a0b6548fc1e 100644 --- a/soc/xtensa/nxp_adsp/imx8m/linker.ld +++ b/soc/xtensa/nxp_adsp/imx8m/linker.ld @@ -171,6 +171,12 @@ EXTERN(ext_man_fw_ver) SECTIONS { +#ifdef CONFIG_OPENAMP_RSC_TABLE + SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) + { + KEEP(*(.resource_table*)) + } GROUP_LINK_IN(ROMABLE_REGION) +#endif #include .ResetVector.text : ALIGN(4) diff --git a/subsys/bluetooth/Kconfig.iso b/subsys/bluetooth/Kconfig.iso index f77fe75c2ea28cc..553ff3a7fb429d5 100644 --- a/subsys/bluetooth/Kconfig.iso +++ b/subsys/bluetooth/Kconfig.iso @@ -114,6 +114,14 @@ config BT_ISO_RX_MTU help Maximum MTU for Isochronous channels RX buffers. +config BT_ISO_ADVANCED + bool "Advanced ISO parameters" + help + Enabling advanced ISO parameters will allow the use of the ISO test + parameters for creating a CIG or a BIG. These test parameters were + intended for testing, but can be used to allow the host to set more + settings that are otherwise usually controlled by the controller. + if BT_ISO_UNICAST config BT_ISO_MAX_CIG diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 56314ed47326b38..4a32448ef2f741d 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -142,31 +142,10 @@ config BT_CTLR_HCI_VS_BUILD_INFO character is required at the beginning to separate it from the already included information. -config BT_CTLR_AD_DATA_BACKUP - bool "Legacy AD Data backup" - depends on BT_PERIPHERAL || BT_CTLR_ADV_EXT - default y - help - Backup Legacy Advertising Data when switching to Legacy Directed or - to Extended Advertising mode, and restore it when switching back to - Legacy Non-Directed Advertising mode. - Application can disable this feature if not using Directed - Advertising or switch between Legacy and Extended Advertising. - -config BT_CTLR_HCI_ADV_HANDLE_MAPPING - bool "Advertising set handle mapping between HCI and LL" - depends on BT_CTLR_ADV_EXT - default y if BT_HCI_RAW - help - Enable mapping of advertising set handles between HCI and LL when - using external host since it can use arbitrary numbers as set handles - (as defined by Core specification) as opposed to LL which always uses - zero-based numbering. When using with Zephyr host this option can be - disabled to remove extra mapping logic. - config BT_CTLR_DUP_FILTER_LEN int "Number of addresses in the scan duplicate filter" depends on BT_OBSERVER + depends on BT_LL_SW_SPLIT default 16 help Set the number of unique BLE addresses that can be filtered as @@ -175,32 +154,16 @@ config BT_CTLR_DUP_FILTER_LEN config BT_CTLR_DUP_FILTER_ADV_SET_MAX int "Number of Extended Advertising Sets in the scan duplicate filter" depends on BT_OBSERVER && BT_CTLR_ADV_EXT && (BT_CTLR_DUP_FILTER_LEN > 0) + depends on BT_LL_SW_SPLIT range 1 16 default 1 help Set the number of unique Advertising Set ID per Bluetooth Low Energy addresses that can be filtered as duplicates while Extended Scanning. -config BT_CTLR_MESH_SCAN_FILTERS - int "Number of Mesh scan filters" - depends on BT_HCI_MESH_EXT - default 1 - range 1 15 - help - Set the number of unique Mesh Scan Filters available as part of - the Intel Mesh Vendor Specific Extensions. - -config BT_CTLR_MESH_SF_PATTERNS - int "Number of Mesh scan filter patterns" - depends on BT_HCI_MESH_EXT - default 15 - range 1 15 - help - Set the number of unique Mesh Scan Filter patterns available per - Scan Filter as part of the Intel Mesh Vendor Specific Extensions. - config BT_CTLR_RX_BUFFERS int "Number of Rx buffers" + depends on BT_LL_SW_SPLIT default 6 if BT_HCI_RAW default 1 range 1 18 @@ -530,10 +493,6 @@ config BT_CTLR_CONN_RSSI help Enable connection RSSI measurement. -config BT_CTLR_CHECK_SAME_PEER_CONN - bool - default BT_MAX_CONN > 1 && !BT_CTLR_ALLOW_SAME_PEER_CONN - endif # BT_CONN config BT_CTLR_FILTER_ACCEPT_LIST @@ -644,22 +603,6 @@ config BT_CTLR_ADV_DATA_LEN_MAX help Maximum Extended Advertising Data Length. -config BT_CTLR_ADV_EXT_RX_PDU_LEN_MAX - int "Maximum Advertising Extensions Receive PDU Length" - depends on BT_OBSERVER - range 255 255 if BT_HCI_RAW - range 31 255 - default 255 - help - Maximum Advertising Extensions Receive PDU Length. - -config BT_CTLR_SCAN_DATA_LEN_MAX - int "Maximum Extended Scanning Data Length" - depends on BT_OBSERVER - range 31 1650 - help - Maximum Extended Scanning Data Length. - config BT_CTLR_ADV_PERIODIC bool "LE Periodic Advertising in Advertising State" depends on BT_BROADCASTER && BT_CTLR_ADV_PERIODIC_SUPPORT @@ -748,11 +691,6 @@ config BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING Enable filtering of periodic advertisements depending on type of Constant Tone Extension. -config BT_CTLR_CHECK_SAME_PEER_SYNC - # Hidden Kconfig to add same peer synchronization check - bool - default BT_PER_ADV_SYNC_MAX > 1 - config BT_CTLR_SYNC_TRANSFER_RECEIVER bool "Periodic Advertising Sync Transfer receiver" depends on BT_CTLR_SYNC_TRANSFER_RECEIVER_SUPPORT @@ -931,13 +869,6 @@ config BT_CTLR_CONN_ISO_STREAMS_PER_GROUP help Maximum supported CISes per CIG. -config BT_CTLR_CONN_ISO_HCI_DATAPATH_SKIP_INVALID_DATA - bool "Do not pass invalid SDUs on HCI datapath" - depends on BT_CTLR_CONN_ISO - help - This allows for applications to decide whether to - forward invalid SDUs through HCI upwards. - config BT_CTLR_CONN_ISO_PDU_LEN_MAX int "Maximum Connected Isochronous Channel PDU Length" depends on BT_CTLR_CONN_ISO @@ -963,28 +894,6 @@ config BT_CTLR_CONN_ISO_STREAMS_MAX_NSE help Maximum number of CIS subevents. -choice - prompt "CIS Creation Policy Selection" - default BT_CTLR_CONN_ISO_RELIABILITY_POLICY - -config BT_CTLR_CONN_ISO_RELIABILITY_POLICY - bool "CIS creation policy for reliability" - depends on BT_CTLR_CENTRAL_ISO - help - Select this option to use reliability policy for CIS creation. This - favors a CIS layout/configuration which utilizes the full range of the - Max_Transmission_Latency for maximum retransmission and payload - recovery. - -config BT_CTLR_CONN_ISO_LOW_LATENCY_POLICY - bool "CIS creation policy for low latency" - depends on BT_CTLR_CENTRAL_ISO - help - Select this option to use low latency policy for CIS creation. This - favors a CIS layout/configuration which compacts payload transmission - for lowest possible latency. -endchoice - config BT_CTLR_ISO bool default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO @@ -1033,11 +942,6 @@ config BT_CTLR_ASSERT_HANDLER and will be invoked whenever the controller code encounters an unrecoverable error. -config BT_CTLR_TEST - bool "Run in-system unit tests" - help - Run in-system unit tests - endif # BT_CTLR config BT_CTLR_DEBUG_PINS_CPUAPP diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 9dd013c47868e76..b1affdd55884212 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -133,11 +133,116 @@ config BT_CTLR_SUBVERSION_NUMBER help Set the Subversion Number that will be used in VERSION_IND PDU. +config BT_CTLR_AD_DATA_BACKUP + bool "Legacy AD Data backup" + depends on BT_PERIPHERAL || BT_CTLR_ADV_EXT + default y + help + Backup Legacy Advertising Data when switching to Legacy Directed or + to Extended Advertising mode, and restore it when switching back to + Legacy Non-Directed Advertising mode. + Application can disable this feature if not using Directed + Advertising or switch between Legacy and Extended Advertising. + +config BT_CTLR_HCI_ADV_HANDLE_MAPPING + bool "Advertising set handle mapping between HCI and LL" + depends on BT_CTLR_ADV_EXT + default y if BT_HCI_RAW + help + Enable mapping of advertising set handles between HCI and LL when + using external host since it can use arbitrary numbers as set handles + (as defined by Core specification) as opposed to LL which always uses + zero-based numbering. When using with Zephyr host this option can be + disabled to remove extra mapping logic. + +config BT_CTLR_MESH_SCAN_FILTERS + int "Number of Mesh scan filters" + depends on BT_HCI_MESH_EXT + default 1 + range 1 15 + help + Set the number of unique Mesh Scan Filters available as part of + the Intel Mesh Vendor Specific Extensions. + +config BT_CTLR_MESH_SF_PATTERNS + int "Number of Mesh scan filter patterns" + depends on BT_HCI_MESH_EXT + default 15 + range 1 15 + help + Set the number of unique Mesh Scan Filter patterns available per + Scan Filter as part of the Intel Mesh Vendor Specific Extensions. + +config BT_CTLR_CHECK_SAME_PEER_CONN + bool + depends on BT_CONN + default BT_MAX_CONN > 1 && !BT_CTLR_ALLOW_SAME_PEER_CONN + +if BT_CTLR_ADV_EXT + +config BT_CTLR_ADV_EXT_RX_PDU_LEN_MAX + int "Maximum Advertising Extensions Receive PDU Length" + depends on BT_OBSERVER + range 255 255 if BT_HCI_RAW + range 31 255 + default 255 + help + Maximum Advertising Extensions Receive PDU Length. + +config BT_CTLR_SCAN_DATA_LEN_MAX + int "Maximum Extended Scanning Data Length" + depends on BT_OBSERVER + range 31 1650 + help + Maximum Extended Scanning Data Length. + +config BT_CTLR_CHECK_SAME_PEER_SYNC + # Hidden Kconfig to add same peer synchronization check + bool + depends on BT_CTLR_SYNC_PERIODIC + default BT_PER_ADV_SYNC_MAX > 1 + +endif # BT_CTLR_ADV_EXT + +config BT_CTLR_CONN_ISO_HCI_DATAPATH_SKIP_INVALID_DATA + bool "Do not pass invalid SDUs on HCI datapath" + depends on BT_CTLR_CONN_ISO + help + This allows for applications to decide whether to + forward invalid SDUs through HCI upwards. + config BT_CTLR_ADVANCED_FEATURES bool "Show advanced features" help Makes advanced features visible to controller developers. +choice + prompt "CIS Creation Policy Selection" + default BT_CTLR_CONN_ISO_RELIABILITY_POLICY + +config BT_CTLR_CONN_ISO_RELIABILITY_POLICY + bool "CIS creation policy for reliability" + depends on BT_CTLR_CENTRAL_ISO + help + Select this option to use reliability policy for CIS creation. This + favors a CIS layout/configuration which utilizes the full range of the + Max_Transmission_Latency for maximum retransmission and payload + recovery. + +config BT_CTLR_CONN_ISO_LOW_LATENCY_POLICY + bool "CIS creation policy for low latency" + depends on BT_CTLR_CENTRAL_ISO + help + Select this option to use low latency policy for CIS creation. This + favors a CIS layout/configuration which compacts payload transmission + for lowest possible latency. +endchoice + +config BT_CTLR_TEST + bool "Run in-system unit tests" + help + Run in-system unit tests + menu "Advanced features" visible if BT_CTLR_ADVANCED_FEATURES diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index c4db3b1cca5f407..4e63d45678d989e 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -6969,6 +6969,19 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, LOG_DBG(" AD Data (%u): ", data_len); } + if (data_len_total + data_len_curr > CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX) { + /* Truncating advertising data + * Note that this has to be done at a PDU boundary, so stop + * processing nodes from this one forward + */ + if (scan_data) { + scan_data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE; + } else { + data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE; + } + break; + } + if (node_rx_curr == node_rx) { evt_type = evt_type_curr; adv_addr_type = adv_addr_type_curr; @@ -7102,16 +7115,6 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, } } - /* Restrict data length to maximum scan data length */ - if (data_len_total > CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX) { - data_len_total = CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX; - if (data_len > data_len_total) { - data_len = data_len_total; - } - - data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE; - } - /* Set directed advertising bit */ if (direct_addr) { evt_type |= BT_HCI_LE_ADV_EVT_TYPE_DIRECT; @@ -7151,16 +7154,6 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, return; } - /* Restrict scan response data length to maximum scan data length */ - if (scan_data_len_total > CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX) { - scan_data_len_total = CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX; - if (scan_data_len > scan_data_len_total) { - scan_data_len = scan_data_len_total; - } - - scan_data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE; - } - /* Set scan response bit */ evt_type |= BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP; diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 8758a677c8af93c..194252da87fa6e3 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -537,6 +537,10 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx) } else { aux->data_len += data_len; + + if (aux->data_len >= CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX) { + goto ull_scan_aux_rx_flush; + } } /* In sync context we can dispatch rx immediately, in scan context we diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 0dd182fd2bd521d..daae434ac1bb73b 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -815,21 +815,63 @@ int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, #if defined(CONFIG_BT_ISO_CENTRAL) || defined(CONFIG_BT_ISO_BROADCASTER) static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos, - bool is_tx) + bool is_tx, bool is_broadcast, bool advanced) { const size_t max_mtu = (is_tx ? CONFIG_BT_ISO_TX_MTU : CONFIG_BT_ISO_RX_MTU); const size_t max_sdu = MIN(max_mtu, BT_ISO_MAX_SDU); if (io_qos->sdu > max_sdu) { - LOG_DBG("sdu (%u) shall be smaller than %zu", io_qos->sdu, max_sdu); + LOG_DBG("sdu (%u) shall be smaller or equal to %zu", io_qos->sdu, max_sdu); + return false; } - if (io_qos->phy > BT_GAP_LE_PHY_CODED) { - LOG_DBG("Invalid phy %u", io_qos->phy); + if (!IN_RANGE(io_qos->phy, BT_GAP_LE_PHY_1M, BT_GAP_LE_PHY_CODED)) { + LOG_DBG("Invalid PHY %u", io_qos->phy); + return false; } + if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && + is_broadcast && + io_qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { + LOG_DBG("Invalid RTN %u", io_qos->phy); + + return false; + } + +#if defined(CONFIG_BT_ISO_ADVANCED) + if (advanced) { + if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && is_broadcast) { + if (!IN_RANGE(io_qos->max_pdu, + BT_ISO_BROADCAST_PDU_MIN, + BT_ISO_PDU_MAX)) { + LOG_DBG("Invalid PDU %u", io_qos->max_pdu); + + return false; + } + } else if (IS_ENABLED(CONFIG_BT_ISO_CENTRAL)) { + if (!IN_RANGE(io_qos->max_pdu, + BT_ISO_CONNECTED_PDU_MIN, + BT_ISO_PDU_MAX)) { + LOG_DBG("Invalid PDU %u", io_qos->max_pdu); + + return false; + } + } + + if (!IN_RANGE(io_qos->burst_number, + BT_ISO_BN_MIN, + BT_ISO_BN_MAX)) { + LOG_DBG("Invalid BN %u", io_qos->burst_number); + + return false; + } + } +#else + ARG_UNUSED(advanced); +#endif /* CONFIG_BT_ISO_ADVANCED */ + return true; } #endif /* CONFIG_BT_ISO_CENTRAL || CONFIG_BT_ISO_BROADCASTER */ @@ -1399,10 +1441,19 @@ static void bt_iso_remove_data_path(struct bt_conn *iso) } } -static bool valid_chan_qos(const struct bt_iso_chan_qos *qos) +static bool valid_chan_qos(const struct bt_iso_chan_qos *qos, bool advanced) { +#if defined(CONFIG_BT_ISO_ADVANCED) + if (advanced && + !IN_RANGE(qos->num_subevents, BT_ISO_NSE_MIN, BT_ISO_NSE_MAX)) { + LOG_DBG("Invalid NSE: %u", qos->num_subevents); + + return false; + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + if (qos->rx != NULL) { - if (!valid_chan_io_qos(qos->rx, false)) { + if (!valid_chan_io_qos(qos->rx, false, false, advanced)) { LOG_DBG("Invalid rx qos"); return false; } @@ -1412,7 +1463,7 @@ static bool valid_chan_qos(const struct bt_iso_chan_qos *qos) } if (qos->tx != NULL) { - if (!valid_chan_io_qos(qos->tx, true)) { + if (!valid_chan_io_qos(qos->tx, true, false, advanced)) { LOG_DBG("Invalid tx qos"); return false; } @@ -1526,6 +1577,138 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, return rsp; } +#if defined(CONFIG_BT_ISO_ADVANCED) +static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, + const struct bt_iso_cig_param *param) +{ + struct bt_hci_cp_le_set_cig_params_test *req; + struct bt_hci_cis_params_test *cis_param; + struct net_buf *buf; + struct net_buf *rsp; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CIG_PARAMS_TEST, + sizeof(*req) + sizeof(*cis_param) * param->num_cis); + if (!buf) { + return NULL; + } + + req = net_buf_add(buf, sizeof(*req)); + + memset(req, 0, sizeof(*req)); + + req->cig_id = cig->id; + sys_put_le24(param->interval, req->c_interval); + sys_put_le24(param->interval, req->p_interval); + + req->c_ft = param->c_to_p_ft; + req->p_ft = param->p_to_c_ft; + req->iso_interval = sys_cpu_to_le16(param->iso_interval); + req->sca = param->sca; + req->packing = param->packing; + req->framing = param->framing; + req->num_cis = param->num_cis; + + LOG_DBG("id %u, SDU interval %u, c_ft %u, p_ft %u, iso_interval %u, " + "sca %u, packing %u, framing %u, num_cis %u", + cig->id, param->interval, param->c_to_p_ft, param->p_to_c_ft, + param->iso_interval, param->sca, param->packing, + param->framing, param->num_cis); + + /* Program the cis parameters */ + for (uint8_t i = 0U; i < param->num_cis; i++) { + const struct bt_iso_chan *cis = param->cis_channels[i]; + const struct bt_iso_chan_qos *qos = cis->qos; + + cis_param = net_buf_add(buf, sizeof(*cis_param)); + + memset(cis_param, 0, sizeof(*cis_param)); + + cis_param->cis_id = cis->iso->iso.cis_id; + cis_param->nse = qos->num_subevents; + + if (!qos->tx && !qos->rx) { + LOG_ERR("Both TX and RX QoS are disabled"); + net_buf_unref(buf); + return NULL; + } + + if (!qos->tx) { + /* Use RX PHY if TX is not set (disabled) + * to avoid setting invalid values + */ + cis_param->c_phy = qos->rx->phy; + } else { + cis_param->c_sdu = sys_cpu_to_le16(qos->tx->sdu); + cis_param->c_pdu = sys_cpu_to_le16(qos->tx->max_pdu); + cis_param->c_phy = qos->tx->phy; + cis_param->c_bn = qos->tx->burst_number; + } + + if (!qos->rx) { + /* Use TX PHY if RX is not set (disabled) + * to avoid setting invalid values + */ + cis_param->p_phy = qos->tx->phy; + } else { + cis_param->p_sdu = sys_cpu_to_le16(qos->rx->sdu); + cis_param->p_pdu = sys_cpu_to_le16(qos->rx->max_pdu); + cis_param->p_phy = qos->rx->phy; + cis_param->p_bn = qos->rx->burst_number; + } + + LOG_DBG("[%d]: id %u, nse %u c_sdu %u, p_sdu %u, c_pdu %u, " + "p_pdu %u, c_phy %u, p_phy %u, c_bn %u, p_bn %u", + i, cis_param->cis_id, cis_param->nse, cis_param->c_sdu, + cis_param->p_sdu, cis_param->c_pdu, cis_param->p_pdu, + cis_param->c_phy, cis_param->p_phy, cis_param->c_bn, + cis_param->p_bn); + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CIG_PARAMS_TEST, buf, &rsp); + if (err) { + return NULL; + } + + return rsp; +} + +static bool is_advanced_cig_param(const struct bt_iso_cig_param *param) +{ + if (param->c_to_p_ft != 0U || + param->p_to_c_ft != 0U || + param->iso_interval != 0U) { + return true; + } + + /* Check if any of the CIS contain any test-param-only values */ + for (uint8_t i = 0U; i < param->num_cis; i++) { + const struct bt_iso_chan *cis = param->cis_channels[i]; + const struct bt_iso_chan_qos *qos = cis->qos; + + if (qos->num_subevents > 0U) { + return true; + } + + if (qos->tx != NULL) { + if (qos->tx->max_pdu > 0U || + qos->tx->burst_number > 0U) { + return true; + } + } + + if (qos->rx != NULL) { + if (qos->rx->max_pdu > 0U || + qos->rx->burst_number > 0U) { + return true; + } + } + } + + return false; +} +#endif /* CONFIG_BT_ISO_ADVANCED */ + static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan) { if (iso_chan->iso == NULL) { @@ -1607,7 +1790,7 @@ static void cleanup_cig(struct bt_iso_cig *cig) memset(cig, 0, sizeof(*cig)); } -static bool valid_cig_param(const struct bt_iso_cig_param *param) +static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced) { if (param == NULL) { return false; @@ -1626,7 +1809,7 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param) return false; } - if (!valid_chan_qos(cis->qos)) { + if (!valid_chan_qos(cis->qos, advanced)) { LOG_DBG("cis_channels[%d]: Invalid QOS", i); return false; } @@ -1664,12 +1847,39 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param) return false; } - if (param->latency < BT_ISO_LATENCY_MIN || - param->latency > BT_ISO_LATENCY_MAX) { + if (!advanced && + (param->latency < BT_ISO_LATENCY_MIN || + param->latency > BT_ISO_LATENCY_MAX)) { LOG_DBG("Invalid latency: %u", param->latency); return false; } +#if defined(CONFIG_BT_ISO_ADVANCED) + if (advanced) { + if (!IN_RANGE(param->c_to_p_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) { + LOG_DBG("Invalid Central to Peripheral FT %u", + param->c_to_p_ft); + + return false; + } + + if (!IN_RANGE(param->p_to_c_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) { + LOG_DBG("Invalid Peripheral to Central FT %u", + param->p_to_c_ft); + + return false; + } + + if (!IN_RANGE(param->iso_interval, + BT_ISO_ISO_INTERVAL_MIN, + BT_ISO_ISO_INTERVAL_MAX)) { + LOG_DBG("Invalid ISO interval %u", param->iso_interval); + + return false; + } + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + return true; } @@ -1681,6 +1891,7 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, struct bt_iso_cig *cig; struct bt_hci_rp_le_set_cig_params *cig_rsp; struct bt_iso_chan *cis; + bool advanced = false; int i; CHECKIF(out_cig == NULL) { @@ -1706,7 +1917,11 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, return -EINVAL; } - CHECKIF(!valid_cig_param(param)) { +#if defined(CONFIG_BT_ISO_ADVANCED) + advanced = is_advanced_cig_param(param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + + CHECKIF(!valid_cig_param(param, advanced)) { LOG_DBG("Invalid CIG params"); return -EINVAL; } @@ -1724,7 +1939,14 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, return err; } - rsp = hci_le_set_cig_params(cig, param); + if (!advanced) { + rsp = hci_le_set_cig_params(cig, param); +#if defined(CONFIG_BT_ISO_ADVANCED) + } else { + rsp = hci_le_set_cig_test_params(cig, param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + } + if (rsp == NULL) { LOG_WRN("Unexpected response to hci_le_set_cig_params"); err = -EIO; @@ -1785,6 +2007,7 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, struct bt_hci_rp_le_set_cig_params *cig_rsp; uint8_t existing_num_cis; struct bt_iso_chan *cis; + bool advanced = false; struct net_buf *rsp; int err; int i; @@ -1799,7 +2022,11 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, return -EINVAL; } - CHECKIF(!valid_cig_param(param)) { +#if defined(CONFIG_BT_ISO_ADVANCED) + advanced = is_advanced_cig_param(param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + + CHECKIF(!valid_cig_param(param, advanced)) { LOG_DBG("Invalid CIG params"); return -EINVAL; } @@ -1825,7 +2052,14 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, return err; } - rsp = hci_le_set_cig_params(cig, param); + if (!advanced) { + rsp = hci_le_set_cig_params(cig, param); +#if defined(CONFIG_BT_ISO_ADVANCED) + } else { + rsp = hci_le_set_cig_test_params(cig, param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + } + if (rsp == NULL) { LOG_WRN("Unexpected response to hci_le_set_cig_params"); err = -EIO; @@ -2335,25 +2569,113 @@ static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big, return err; } -int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param, - struct bt_iso_big **out_big) +#if defined(CONFIG_BT_ISO_ADVANCED) +static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, + struct bt_iso_big *big, + const struct bt_iso_big_create_param *param) { + struct bt_hci_cp_le_create_big_test *req; + struct bt_hci_cmd_state_set state; + const struct bt_iso_chan_qos *qos; + struct bt_iso_chan *bis; + struct net_buf *buf; int err; - struct bt_iso_big *big; - if (!atomic_test_bit(padv->flags, BT_PER_ADV_PARAMS_SET)) { - LOG_DBG("PA params not set; invalid adv object"); - return -EINVAL; + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_BIG_TEST, sizeof(*req)); + + if (!buf) { + return -ENOBUFS; } + bis = SYS_SLIST_PEEK_HEAD_CONTAINER(&big->bis_channels, bis, node); + __ASSERT(bis != NULL, "bis was NULL"); + + /* All BIS will share the same QOS */ + qos = bis->qos; + + req = net_buf_add(buf, sizeof(*req)); + req->big_handle = big->handle; + req->adv_handle = padv->handle; + req->num_bis = big->num_bis; + sys_put_le24(param->interval, req->sdu_interval); + req->iso_interval = sys_cpu_to_le16(param->iso_interval); + req->nse = qos->num_subevents; + req->max_sdu = sys_cpu_to_le16(qos->tx->sdu); + req->max_pdu = sys_cpu_to_le16(qos->tx->max_pdu); + req->phy = qos->tx->phy; + req->packing = param->packing; + req->framing = param->framing; + req->bn = qos->tx->burst_number; + req->irc = param->irc; + req->pto = param->pto; + req->encryption = param->encryption; + if (req->encryption) { + memcpy(req->bcode, param->bcode, sizeof(req->bcode)); + } else { + memset(req->bcode, 0, sizeof(req->bcode)); + } + + LOG_DBG("BIG handle %u, adv handle %u, num_bis %u, SDU interval %u, " + "ISO interval %u, NSE %u, SDU %u, PDU %u, PHY %u, packing %u, " + "framing %u, BN %u, IRC %u, PTO %u, encryption %u", + req->big_handle, req->adv_handle, req->num_bis, param->interval, + param->iso_interval, req->nse, req->max_sdu, req->max_pdu, + req->phy, req->packing, req->framing, req->bn, req->irc, + req->pto, req->encryption); + + bt_hci_cmd_state_set_init(buf, &state, big->flags, BT_BIG_PENDING, true); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_BIG_TEST, buf, NULL); + if (err) { + return err; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) { + bt_iso_chan_set_state(bis, BT_ISO_STATE_CONNECTING); + } + + return err; +} + +static bool is_advanced_big_param(const struct bt_iso_big_create_param *param) +{ + if (param->irc != 0U || + param->iso_interval != 0U) { + return true; + } + + /* Check if any of the CIS contain any test-param-only values */ + for (uint8_t i = 0U; i < param->num_bis; i++) { + const struct bt_iso_chan *bis = param->bis_channels[i]; + const struct bt_iso_chan_qos *qos = bis->qos; + + if (qos->num_subevents > 0U) { + return true; + } + + __ASSERT(qos->tx != NULL, "TX cannot be NULL for broadcaster"); + + if (qos->tx->max_pdu > 0U || qos->tx->burst_number > 0U) { + return true; + } + } + + return false; +} +#endif /* CONFIG_BT_ISO_ADVANCED */ + +static bool valid_big_param(const struct bt_iso_big_create_param *param, + bool advanced) +{ CHECKIF(!param->bis_channels) { LOG_DBG("NULL BIS channels"); - return -EINVAL; + + return false; } CHECKIF(!param->num_bis) { LOG_DBG("Invalid number of BIS %u", param->num_bis); - return -EINVAL; + + return false; } for (uint8_t i = 0; i < param->num_bis; i++) { @@ -2361,54 +2683,116 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param CHECKIF(bis == NULL) { LOG_DBG("bis_channels[%u]: NULL channel", i); - return -EINVAL; + + return false; } if (bis->iso) { LOG_DBG("bis_channels[%u]: already allocated", i); - return -EALREADY; + + return false; } CHECKIF(bis->qos == NULL) { LOG_DBG("bis_channels[%u]: qos is NULL", i); - return -EINVAL; + + return false; } CHECKIF(bis->qos->tx == NULL || - !valid_chan_io_qos(bis->qos->tx, true)) { + !valid_chan_io_qos(bis->qos->tx, true, true, + advanced)) { LOG_DBG("bis_channels[%u]: Invalid QOS", i); - return -EINVAL; + + return false; } } CHECKIF(param->framing != BT_ISO_FRAMING_UNFRAMED && param->framing != BT_ISO_FRAMING_FRAMED) { LOG_DBG("Invalid framing parameter: %u", param->framing); - return -EINVAL; + + return false; } CHECKIF(param->packing != BT_ISO_PACKING_SEQUENTIAL && param->packing != BT_ISO_PACKING_INTERLEAVED) { LOG_DBG("Invalid packing parameter: %u", param->packing); - return -EINVAL; + + return false; } CHECKIF(param->num_bis > BT_ISO_MAX_GROUP_ISO_COUNT || param->num_bis > CONFIG_BT_ISO_MAX_CHAN) { LOG_DBG("num_bis (%u) shall be lower than: %u", param->num_bis, MAX(CONFIG_BT_ISO_MAX_CHAN, BT_ISO_MAX_GROUP_ISO_COUNT)); - return -EINVAL; + + return false; } - CHECKIF(param->interval < BT_ISO_SDU_INTERVAL_MIN || - param->interval > BT_ISO_SDU_INTERVAL_MAX) { + CHECKIF(!IN_RANGE(param->interval, + BT_ISO_SDU_INTERVAL_MIN, + BT_ISO_SDU_INTERVAL_MAX)) { LOG_DBG("Invalid interval: %u", param->interval); - return -EINVAL; + + return false; } - CHECKIF(param->latency < BT_ISO_LATENCY_MIN || - param->latency > BT_ISO_LATENCY_MAX) { + CHECKIF(!advanced && + !IN_RANGE(param->latency, + BT_ISO_LATENCY_MIN, + BT_ISO_LATENCY_MAX)) { LOG_DBG("Invalid latency: %u", param->latency); + + return false; + } + +#if defined(CONFIG_BT_ISO_ADVANCED) + if (advanced) { + CHECKIF(!IN_RANGE(param->irc, BT_ISO_IRC_MIN, BT_ISO_IRC_MAX)) { + LOG_DBG("Invalid IRC %u", param->irc); + + return false; + } + + CHECKIF(!IN_RANGE(param->pto, BT_ISO_PTO_MIN, BT_ISO_PTO_MAX)) { + LOG_DBG("Invalid PTO %u", param->pto); + + return false; + } + + CHECKIF(!IN_RANGE(param->iso_interval, + BT_ISO_ISO_INTERVAL_MIN, + BT_ISO_ISO_INTERVAL_MAX)) { + LOG_DBG("Invalid ISO interval %u", param->iso_interval); + + return false; + } + } +#endif /* CONFIG_BT_ISO_ADVANCED */ + + return true; +} + +int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param, + struct bt_iso_big **out_big) +{ + int err; + struct bt_iso_big *big; + bool advanced = false; + + if (!atomic_test_bit(padv->flags, BT_PER_ADV_PARAMS_SET)) { + LOG_DBG("PA params not set; invalid adv object"); + return -EINVAL; + } + +#if defined(CONFIG_BT_ISO_ADVANCED) + advanced = is_advanced_big_param(param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + + if (!valid_big_param(param, advanced)) { + LOG_DBG("Invalid BIG parameters"); + return -EINVAL; } @@ -2426,7 +2810,14 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param } big->num_bis = param->num_bis; - err = hci_le_create_big(padv, big, param); + if (!advanced) { + err = hci_le_create_big(padv, big, param); +#if defined(CONFIG_BT_ISO_ADVANCED) + } else { + err = hci_le_create_big_test(padv, big, param); +#endif /* CONFIG_BT_ISO_ADVANCED */ + } + if (err) { LOG_DBG("Could not create BIG %d", err); cleanup_big(big); diff --git a/subsys/bluetooth/lib/Kconfig b/subsys/bluetooth/lib/Kconfig index 15cfa142b131443..4e72027b5ee9f60 100644 --- a/subsys/bluetooth/lib/Kconfig +++ b/subsys/bluetooth/lib/Kconfig @@ -2,8 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 config BT_EAD - bool "Encrypted Advertising Data [EXPERIMENTAL]" - select EXPERIMENTAL + bool "Encrypted Advertising Data" select BT_HOST_CCM help Enable the Encrypted Advertising Data library diff --git a/subsys/canbus/isotp/Kconfig b/subsys/canbus/isotp/Kconfig index f0aaf8eb69f9f27..b533bf6d1e8f533 100644 --- a/subsys/canbus/isotp/Kconfig +++ b/subsys/canbus/isotp/Kconfig @@ -51,7 +51,7 @@ config ISOTP_CR_TIMEOUT config ISOTP_REQUIRE_RX_PADDING bool "Require padding for received messages" help - If enabled, SFs and the last CF must always have a DLC of 8 bytes + If enabled, SFs, FCs and the last CF must always have a DLC of 8 bytes (for classic CAN) and unused bytes must be padded by the sending device. This setting allows to be compliant to AUTOSAR Specification of CAN Transport Layer. @@ -60,6 +60,7 @@ config ISOTP_REQUIRE_RX_PADDING config ISOTP_ENABLE_TX_PADDING bool "Padding for transmitted messages" + default y if ISOTP_REQUIRE_RX_PADDING help Add padding bytes 0xCC (as recommended by Bosch) if the PDU payload does not fit exactly into the CAN frame. diff --git a/subsys/canbus/isotp/isotp.c b/subsys/canbus/isotp/isotp.c index 3a6e8c22e43d075..dfe43bb9e2459c8 100644 --- a/subsys/canbus/isotp/isotp.c +++ b/subsys/canbus/isotp/isotp.c @@ -137,8 +137,7 @@ static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) *data++ = ctx->opts.stmin; payload_len = data - frame.data; -#if defined(CONFIG_ISOTP_REQUIRE_RX_PADDING) || \ - defined(CONFIG_ISOTP_ENABLE_TX_PADDING) +#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING /* AUTOSAR requirement SWS_CanTp_00347 */ memset(&frame.data[payload_len], 0xCC, ISOTP_CAN_DL - payload_len); frame.dlc = ISOTP_CAN_DL; @@ -776,7 +775,7 @@ static void send_process_fc(struct isotp_send_ctx *ctx, return; } -#ifdef CONFIG_ISOTP_ENABLE_TX_PADDING +#ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING /* AUTOSAR requirement SWS_CanTp_00349 */ if (frame->dlc != ISOTP_CAN_DL) { LOG_ERR("FC DL invalid. Ignore"); diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index c977160f05b0b0d..39d4a4ca8ce0ae6 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -13,5 +13,6 @@ add_subdirectory(smp) add_subdirectory(util) add_subdirectory(grp) add_subdirectory(transport) +add_subdirectory_ifdef(CONFIG_SMP_CLIENT smp_client) zephyr_library_link_libraries(mgmt_mcumgr) diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index 0aa02b04437dcf1..107ee3263e946aa 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -33,6 +33,12 @@ config MCUMGR_SMP_LEGACY_RC_BEHAVIOUR response will be empty with the new behaviour enabled, as opposed to the old behaviour where the rc field will be present in the response. +menu "SMP Client" + +rsource "smp_client/Kconfig" + +endmenu + menu "Command Handlers" rsource "grp/Kconfig" diff --git a/subsys/mgmt/mcumgr/grp/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/CMakeLists.txt index 56df0fb517664aa..b77fcddf25e02a3 100644 --- a/subsys/mgmt/mcumgr/grp/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/CMakeLists.txt @@ -5,9 +5,11 @@ # SPDX-License-Identifier: Apache-2.0 # -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_FS fs_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG img_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_STAT stat_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_SHELL shell_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_ZBASIC zephyr_basic) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_FS fs_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG img_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG_CLIENT img_mgmt_client) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS_CLIENT os_mgmt_client) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_STAT stat_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_SHELL shell_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_ZBASIC zephyr_basic) diff --git a/subsys/mgmt/mcumgr/grp/Kconfig b/subsys/mgmt/mcumgr/grp/Kconfig index b0a018ca4d3e011..6005d57a850445f 100644 --- a/subsys/mgmt/mcumgr/grp/Kconfig +++ b/subsys/mgmt/mcumgr/grp/Kconfig @@ -6,8 +6,12 @@ rsource "fs_mgmt/Kconfig" rsource "img_mgmt/Kconfig" +rsource "img_mgmt_client/Kconfig" + rsource "os_mgmt/Kconfig" +rsource "os_mgmt_client/Kconfig" + rsource "shell_mgmt/Kconfig" rsource "stat_mgmt/Kconfig" diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c index 4cbd6b893b3f141..23978686170ecb0 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c @@ -280,9 +280,9 @@ static int fs_mgmt_file_download(struct smp_streamer *ctxt) rc = fs_open(&fs_mgmt_ctxt.file, path, FS_O_READ); if (rc != 0) { - if (rc == EINVAL) { + if (rc == -EINVAL) { rc = FS_MGMT_RET_RC_FILE_INVALID_NAME; - } else if (ENOENT) { + } else if (rc == -ENOENT) { rc = FS_MGMT_RET_RC_FILE_NOT_FOUND; } else { rc = FS_MGMT_RET_RC_UNKNOWN; @@ -422,9 +422,9 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) rc = fs_open(&fs_mgmt_ctxt.file, file_name, FS_O_CREATE | FS_O_WRITE); if (rc != 0) { - if (rc == EINVAL) { + if (rc == -EINVAL) { rc = FS_MGMT_RET_RC_FILE_INVALID_NAME; - } else if (ENOENT) { + } else if (rc == -ENOENT) { rc = FS_MGMT_RET_RC_FILE_NOT_FOUND; } else { rc = FS_MGMT_RET_RC_UNKNOWN; @@ -741,9 +741,9 @@ static int fs_mgmt_file_hash_checksum(struct smp_streamer *ctxt) rc = fs_open(&file, path, FS_O_READ); if (rc != 0) { - if (rc == EINVAL) { + if (rc == -EINVAL) { rc = FS_MGMT_RET_RC_FILE_INVALID_NAME; - } else if (ENOENT) { + } else if (rc == -ENOENT) { rc = FS_MGMT_RET_RC_FILE_NOT_FOUND; } else { rc = FS_MGMT_RET_RC_UNKNOWN; @@ -911,13 +911,13 @@ static int fs_mgmt_translate_error_code(uint16_t ret) switch (ret) { case FS_MGMT_RET_RC_FILE_INVALID_NAME: case FS_MGMT_RET_RC_CHECKSUM_HASH_NOT_FOUND: - rc = MGMT_ERR_EINVAL; - break; + rc = MGMT_ERR_EINVAL; + break; case FS_MGMT_RET_RC_FILE_NOT_FOUND: case FS_MGMT_RET_RC_FILE_IS_DIRECTORY: - rc = MGMT_ERR_ENOENT; - break; + rc = MGMT_ERR_ENOENT; + break; case FS_MGMT_RET_RC_UNKNOWN: case FS_MGMT_RET_RC_FILE_OPEN_FAILED: @@ -928,8 +928,8 @@ static int fs_mgmt_translate_error_code(uint16_t ret) case FS_MGMT_RET_RC_FILE_WRITE_FAILED: case FS_MGMT_RET_RC_FILE_OFFSET_NOT_VALID: case FS_MGMT_RET_RC_FILE_OFFSET_LARGER_THAN_FILE: - default: - rc = MGMT_ERR_EUNKNOWN; + default: + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 42f3bf76c8e2711..06c04e0b17a9a0f 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -76,6 +75,9 @@ #error "Unsupported code parition is set as active application partition" #endif +_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, + "struct image_header not required size"); + LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; @@ -94,6 +96,8 @@ const char *img_mgmt_err_str_flash_erase_failed = "fa erase fail"; const char *img_mgmt_err_str_flash_write_failed = "fa write fail"; const char *img_mgmt_err_str_downgrade = "downgrade"; const char *img_mgmt_err_str_image_bad_flash_addr = "img addr mismatch"; +const char *img_mgmt_err_str_image_too_large = "img too large"; +const char *img_mgmt_err_str_data_overrun = "data overrun"; #endif void img_mgmt_take_lock(void) @@ -771,18 +775,18 @@ static int img_mgmt_translate_error_code(uint16_t ret) switch (ret) { case IMG_MGMT_RET_RC_NO_IMAGE: case IMG_MGMT_RET_RC_NO_TLVS: - rc = MGMT_ERR_ENOENT; - break; + rc = MGMT_ERR_ENOENT; + break; case IMG_MGMT_RET_RC_NO_FREE_SLOT: case IMG_MGMT_RET_RC_CURRENT_VERSION_IS_NEWER: case IMG_MGMT_RET_RC_IMAGE_ALREADY_PENDING: - rc = MGMT_ERR_EBADSTATE; - break; + rc = MGMT_ERR_EBADSTATE; + break; case IMG_MGMT_RET_RC_NO_FREE_MEMORY: - rc = MGMT_ERR_ENOMEM; - break; + rc = MGMT_ERR_ENOMEM; + break; case IMG_MGMT_RET_RC_INVALID_SLOT: case IMG_MGMT_RET_RC_INVALID_PAGE_OFFSET: @@ -791,8 +795,8 @@ static int img_mgmt_translate_error_code(uint16_t ret) case IMG_MGMT_RET_RC_INVALID_IMAGE_HEADER: case IMG_MGMT_RET_RC_INVALID_HASH: case IMG_MGMT_RET_RC_INVALID_FLASH_ADDRESS: - rc = MGMT_ERR_EINVAL; - break; + rc = MGMT_ERR_EINVAL; + break; case IMG_MGMT_RET_RC_FLASH_CONFIG_QUERY_FAIL: case IMG_MGMT_RET_RC_VERSION_GET_FAILED: @@ -809,9 +813,11 @@ static int img_mgmt_translate_error_code(uint16_t ret) case IMG_MGMT_RET_RC_FLASH_AREA_DEVICE_NULL: case IMG_MGMT_RET_RC_INVALID_IMAGE_HEADER_MAGIC: case IMG_MGMT_RET_RC_INVALID_IMAGE_VECTOR_TABLE: + case IMG_MGMT_RET_RC_INVALID_IMAGE_TOO_LARGE: + case IMG_MGMT_RET_RC_INVALID_IMAGE_DATA_OVERRUN: case IMG_MGMT_RET_RC_UNKNOWN: - default: - rc = MGMT_ERR_EUNKNOWN; + default: + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 2e673fff9780824..9e55a511063ea53 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_util.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_util.c index 4125889e33afdfd..e52f958541748f9 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_util.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_util.c @@ -8,7 +8,6 @@ #include #include -#include int img_mgmt_ver_str(const struct image_version *ver, char *dst) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index a809e2980c4bfef..4a995989bbad4ac 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -16,7 +16,6 @@ #include #include -#include #include @@ -571,6 +570,8 @@ int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, if (req->off == 0) { /* First upload chunk. */ + const struct flash_area *fa; + if (req->img_data.len < sizeof(struct image_header)) { /* Image header is the first thing in the image */ IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_hdr_malformed); @@ -615,30 +616,35 @@ int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, return IMG_MGMT_RET_RC_NO_FREE_SLOT; } -#if defined(CONFIG_MCUMGR_GRP_IMG_REJECT_DIRECT_XIP_MISMATCHED_SLOT) - if (hdr->ih_flags & IMAGE_F_ROM_FIXED_ADDR) { - const struct flash_area *fa; + rc = flash_area_open(action->area_id, &fa); + if (rc) { + IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, + img_mgmt_err_str_flash_open_failed); + LOG_ERR("Failed to open flash area ID %u: %d", action->area_id, rc); + return IMG_MGMT_RET_RC_FLASH_OPEN_FAILED; + } - rc = flash_area_open(action->area_id, &fa); - if (rc) { - IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, - img_mgmt_err_str_flash_open_failed); - LOG_ERR("Failed to open flash area ID %u: %d", action->area_id, - rc); - return IMG_MGMT_RET_RC_FLASH_OPEN_FAILED; - } + /* Check that the area is of sufficient size to store the new image */ + if (req->size > fa->fa_size) { + IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, + img_mgmt_err_str_image_too_large); + flash_area_close(fa); + LOG_ERR("Upload too large for slot: %u > %u", req->size, fa->fa_size); + return IMG_MGMT_RET_RC_INVALID_IMAGE_TOO_LARGE; + } +#if defined(CONFIG_MCUMGR_GRP_IMG_REJECT_DIRECT_XIP_MISMATCHED_SLOT) + if (hdr->ih_flags & IMAGE_F_ROM_FIXED) { if (fa->fa_off != hdr->ih_load_addr) { IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_image_bad_flash_addr); flash_area_close(fa); return IMG_MGMT_RET_RC_INVALID_FLASH_ADDRESS; } - - flash_area_close(fa); } #endif + flash_area_close(fa); if (req->upgrade) { /* User specified upgrade-only. Make sure new image version is @@ -676,6 +682,14 @@ int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, */ return IMG_MGMT_RET_RC_OK; } + + if ((req->off + req->img_data.len) > action->size) { + /* Data overrun, the amount of data written would be more than the size + * of the image that the client originally sent + */ + IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_data_overrun); + return IMG_MGMT_RET_RC_INVALID_IMAGE_DATA_OVERRUN; + } } action->write_bytes = req->img_data.len; diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt new file mode 100644 index 000000000000000..693891896d8e267 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Image management client group public API is exported by MCUmgr interface API, +# when Image Management client is enabled. + +zephyr_library(mcumgr_grp_img_client) +zephyr_library_sources( + src/img_mgmt_client.c +) + +zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig new file mode 100644 index 000000000000000..dbdb4c4eb603d5c --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig @@ -0,0 +1,39 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to Application Image management group of +# of MCUmgr client subsystem and provides Kconfig options to configure +# group commands behaviour and other aspects. +# +# Options defined in this file should be prefixed: +# MCUMGR_GRP_IMG_CLIENT_ -- general group options; +# +# When adding Kconfig options, that control the same feature, +# try to group them together by the same stem after prefix. + +menuconfig MCUMGR_GRP_IMG_CLIENT + bool "MCUmgr client handlers for image management" + depends on SMP_CLIENT + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_3 + help + Enables MCUmgr client handlers for image management. + +if MCUMGR_GRP_IMG_CLIENT + +config MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE + int "MCUmgr upload data alignment size" + default 4 + help + Change default value when platform needs different data alignment. + +config MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT + int "MCUmgr reset or upload command timeout" + default 15 + help + Change default value when platform needs a different time. + +module = MCUMGR_GRP_IMG_CLIENT +module-str = mcumgr_grp_img_client +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c new file mode 100644 index 000000000000000..2bb9743160db468 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_grp_img_client, CONFIG_MCUMGR_GRP_IMG_CLIENT_LOG_LEVEL); + +#define MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE 128 + +/* Pointer for active Client */ +static struct img_mgmt_client *active_client; +/* Image State read or set response pointer */ +static struct mcumgr_image_state *image_info; +/* Image upload response pointer */ +static struct mcumgr_image_upload *image_upload_buf; + +static K_SEM_DEFINE(mcumgr_img_client_grp_sem, 0, 1); +static K_MUTEX_DEFINE(mcumgr_img_client_grp_mutex); + +static const char smp_images_str[] = "images"; +#define IMAGES_STR_LEN (sizeof(smp_images_str) - 1) + +static int image_state_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + struct zcbor_string value = {0}; + int buf_len, rc; + uint32_t img_num, slot_num; + struct zcbor_string hash, version; + bool bootable, pending, confirmed, active, permanent, ok; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + /* Mandatory */ + ZCBOR_MAP_DECODE_KEY_DECODER("version", zcbor_tstr_decode, &version), + ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash), + ZCBOR_MAP_DECODE_KEY_DECODER("slot", zcbor_uint32_decode, &slot_num), + /* Optional */ + ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &img_num), + ZCBOR_MAP_DECODE_KEY_DECODER("bootable", zcbor_bool_decode, &bootable), + ZCBOR_MAP_DECODE_KEY_DECODER("pending", zcbor_bool_decode, &pending), + ZCBOR_MAP_DECODE_KEY_DECODER("confirmed", zcbor_bool_decode, &confirmed), + ZCBOR_MAP_DECODE_KEY_DECODER("active", zcbor_bool_decode, &active), + ZCBOR_MAP_DECODE_KEY_DECODER("permanent", zcbor_bool_decode, &permanent) + }; + + buf_len = active_client->image_list_length; + + if (!nb) { + image_info->status = MGMT_ERR_ETIMEOUT; + goto out; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + ok = zcbor_map_start_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + + ok = zcbor_tstr_decode(zsd, &value); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + if (value.len != IMAGES_STR_LEN || memcmp(value.value, smp_images_str, IMAGES_STR_LEN)) { + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + + ok = zcbor_list_start_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + + rc = 0; + /* Parse Image map info to configured buffer */ + while (rc == 0) { + decoded = 0; + zcbor_map_decode_bulk_reset(list_res_decode, ARRAY_SIZE(list_res_decode)); + /* Init buffer values */ + active = false; + bootable = false; + confirmed = false; + pending = false; + permanent = false; + img_num = 0; + slot_num = UINT32_MAX; + hash.len = 0; + version.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), + &decoded); + if (rc) { + if (image_info->image_list_length) { + /* No more map */ + break; + } + LOG_ERR("Corrupted Image data %d", rc); + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + /* Check that mandatory parameters have decoded */ + if (hash.len != IMG_MGMT_HASH_LEN || !version.len || + !zcbor_map_decode_bulk_key_found(list_res_decode, ARRAY_SIZE(list_res_decode), + "slot")) { + LOG_ERR("Missing mandatory parametrs"); + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + /* Store parsed values */ + if (buf_len) { + image_info->image_list[image_info->image_list_length].img_num = img_num; + image_info->image_list[image_info->image_list_length].slot_num = slot_num; + memcpy(image_info->image_list[image_info->image_list_length].hash, + hash.value, IMG_MGMT_HASH_LEN); + if (version.len > IMG_MGMT_VER_MAX_STR_LEN) { + LOG_WRN("Version truncated len %d -> %d", version.len, + IMG_MGMT_VER_MAX_STR_LEN); + version.len = IMG_MGMT_VER_MAX_STR_LEN; + } + memcpy(image_info->image_list[image_info->image_list_length].version, + version.value, version.len); + image_info->image_list[image_info->image_list_length].version[version.len] = + '\0'; + /* Set Image flags */ + image_info->image_list[image_info->image_list_length].flags.bootable = + bootable; + image_info->image_list[image_info->image_list_length].flags.pending = + pending; + image_info->image_list[image_info->image_list_length].flags.confirmed = + confirmed; + image_info->image_list[image_info->image_list_length].flags.active = active; + image_info->image_list[image_info->image_list_length].flags.permanent = + permanent; + /* Update valid image count */ + image_info->image_list_length++; + buf_len--; + } else { + LOG_INF("User configured image list buffer size %d can't store all info", + active_client->image_list_length); + } + } + + ok = zcbor_list_end_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + } else { + + image_info->status = MGMT_ERR_EOK; + } + +out: + if (image_info->status != MGMT_ERR_EOK) { + image_info->image_list_length = 0; + } + rc = image_info->status; + k_sem_give(user_data); + return rc; +} + +static int image_upload_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + int rc; + int32_t res_rc = MGMT_ERR_EOK; + + struct zcbor_map_decode_key_val upload_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_size_decode, + &image_upload_buf->image_upload_offset), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &res_rc)}; + + if (!nb) { + image_upload_buf->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); + if (rc || image_upload_buf->image_upload_offset == SIZE_MAX) { + image_upload_buf->status = MGMT_ERR_EINVAL; + goto end; + } + image_upload_buf->status = res_rc; + + active_client->upload.offset = image_upload_buf->image_upload_offset; +end: + /* Set status for Upload request handler */ + rc = image_upload_buf->status; + k_sem_give(user_data); + return rc; +} + +static int erase_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + int rc, status = MGMT_ERR_EOK; + + struct zcbor_map_decode_key_val upload_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &status) + }; + + if (!nb) { + active_client->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); + if (rc) { + LOG_ERR("Erase fail %d", rc); + active_client->status = MGMT_ERR_EINVAL; + goto end; + } + active_client->status = status; +end: + rc = active_client->status; + k_sem_give(user_data); + return rc; +} + +static size_t upload_message_header_size(struct img_gr_upload *upload_state) +{ + bool ok; + size_t cbor_length; + int map_count; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + uint8_t temp_buf[MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE]; + uint8_t temp_data; + + /* Calculation of message header with data length of 1 */ + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), temp_buf, MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE, + 0); + if (upload_state->hash_initialized) { + map_count = 12; + } else { + map_count = 10; + } + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, upload_state->image_num) && zcbor_tstr_put_lit(zse, "data") && + zcbor_bstr_encode_ptr(zse, &temp_data, 1) && zcbor_tstr_put_lit(zse, "len") && + zcbor_size_put(zse, upload_state->image_size) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, upload_state->offset); + + /* Write hash when it defined and offset is 0 */ + if (ok && upload_state->hash_initialized) { + ok = zcbor_tstr_put_lit(zse, "sha") && + zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_HASH_LEN); + } + + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + LOG_ERR("Failed to encode Image Upload packet"); + return 0; + } + cbor_length = zse->payload - temp_buf; + /* Return Message header length */ + return cbor_length + (CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE - 1); +} + +void img_mgmt_client_init(struct img_mgmt_client *client, struct smp_client_object *smp_client, + int image_list_size, struct mcumgr_image_data *image_list) +{ + client->smp_client = smp_client; + client->image_list_length = image_list_size; + client->image_list = image_list; +} + +int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_size, + uint32_t image_num, const char *image_hash) +{ + int rc; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + client->upload.image_size = image_size; + client->upload.offset = 0; + client->upload.image_num = image_num; + if (image_hash) { + memcpy(client->upload.sha256, image_hash, IMG_MGMT_HASH_LEN); + client->upload.hash_initialized = true; + } else { + client->upload.hash_initialized = false; + } + + /* Calculate worst case header size for adapt payload length */ + client->upload.upload_header_size = upload_message_header_size(&client->upload); + if (client->upload.upload_header_size) { + rc = MGMT_ERR_EOK; + } else { + rc = MGMT_ERR_ENOMEM; + } + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, size_t length, + struct mcumgr_image_upload *res_buf) +{ + struct net_buf *nb; + const uint8_t *write_ptr; + int rc; + uint32_t map_count; + bool ok; + size_t write_length, max_data_length, offset_before_send, request_length, wrote_length; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + image_upload_buf = res_buf; + + request_length = length; + wrote_length = 0; + /* Calculate max data length based on net_buf size - (SMP header + CBOR message_len) */ + max_data_length = CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE - + (active_client->upload.upload_header_size + MGMT_HDR_SIZE); + /* Trim length based on CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE */ + if (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE) { + max_data_length -= + (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE); + } + + while (request_length != wrote_length) { + write_ptr = data + wrote_length; + write_length = request_length - wrote_length; + if (write_length > max_data_length) { + write_length = max_data_length; + } + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_UPLOAD, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + if (!nb) { + image_upload_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, + net_buf_tailroom(nb), 0); + if (active_client->upload.offset) { + map_count = 6; + } else if (active_client->upload.hash_initialized) { + map_count = 12; + } else { + map_count = 10; + } + + /* Init map start and write image info, data and offset */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, active_client->upload.image_num) && + zcbor_tstr_put_lit(zse, "data") && + zcbor_bstr_encode_ptr(zse, write_ptr, write_length) && + zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, active_client->upload.offset); + /* Write Len and configured hash when offset is zero */ + if (ok && !active_client->upload.offset) { + ok = zcbor_tstr_put_lit(zse, "len") && + zcbor_size_put(zse, active_client->upload.image_size); + if (ok && active_client->upload.hash_initialized) { + ok = zcbor_tstr_put_lit(zse, "sha") && + zcbor_bstr_encode_ptr(zse, active_client->upload.sha256, + IMG_MGMT_HASH_LEN); + } + } + + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + LOG_ERR("Failed to encode Image Upload packet"); + smp_packet_free(nb); + image_upload_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + offset_before_send = active_client->upload.offset; + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + + image_upload_buf->status = MGMT_ERR_EINVAL; + image_upload_buf->image_upload_offset = SIZE_MAX; + + rc = smp_client_send_cmd(active_client->smp_client, nb, image_upload_res_fn, + &mcumgr_img_client_grp_sem, + CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT); + if (rc) { + LOG_ERR("Failed to send SMP Upload init packet, err: %d", rc); + smp_packet_free(nb); + image_upload_buf->status = rc; + goto end; + + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); + if (image_upload_buf->status) { + LOG_ERR("Upload Fail: %d", image_upload_buf->status); + goto end; + } + + if (offset_before_send + write_length < active_client->upload.offset) { + /* Offset further than expected which indicate upload session resume */ + goto end; + } + + wrote_length += write_length; + } +end: + rc = image_upload_buf->status; + active_client = NULL; + image_upload_buf = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + + return rc; +} + +int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool confirm, + struct mcumgr_image_state *res_buf) +{ + struct net_buf *nb; + int rc; + uint32_t map_count; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + image_info = res_buf; + /* Init Response */ + res_buf->image_list_length = 0; + res_buf->image_list = active_client->image_list; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_STATE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + if (hash) { + map_count = 4; + } else { + map_count = 2; + } + + /* Write map start init and confirm params */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "confirm") && + zcbor_bool_put(zse, confirm); + /* Write hash data */ + if (ok && hash) { + ok = zcbor_tstr_put_lit(zse, "hash") && + zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_HASH_LEN); + } + /* Close map */ + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + smp_packet_free(nb); + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn, + &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + res_buf->status = rc; + smp_packet_free(nb); + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = res_buf->status; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_image_state *res_buf) +{ + struct net_buf *nb; + int rc; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + /* Init Response */ + res_buf->image_list_length = 0; + res_buf->image_list = active_client->image_list; + + image_info = res_buf; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_STATE, MGMT_OP_READ, SMP_MCUMGR_VERSION_1); + if (!nb) { + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + ok = zcbor_map_start_encode(zse, 1) && zcbor_map_end_encode(zse, 1); + if (!ok) { + smp_packet_free(nb); + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn, + &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + smp_packet_free(nb); + res_buf->status = rc; + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = res_buf->status; + image_info = NULL; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot) +{ + struct net_buf *nb; + int rc; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_ERASE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "slot") && + zcbor_uint32_put(zse, slot) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_packet_free(nb); + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(client->smp_client, nb, erase_res_fn, &mcumgr_img_client_grp_sem, + CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT); + if (rc) { + smp_packet_free(nb); + active_client->status = rc; + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = active_client->status; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index 8b0c3dd024689c3..761d77d9e6323d6 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -688,12 +688,12 @@ static int os_mgmt_translate_error_code(uint16_t ret) switch (ret) { case OS_MGMT_RET_RC_INVALID_FORMAT: - rc = MGMT_ERR_EINVAL; - break; + rc = MGMT_ERR_EINVAL; + break; case OS_MGMT_RET_RC_UNKNOWN: default: - rc = MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt new file mode 100644 index 000000000000000..b033b363fa67ab5 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# OS Management client group public API is exposed through zephyr_interface, +# when OS Management is enabled. +zephyr_library(mgmt_mcumgr_grp_os_client) +zephyr_library_sources(src/os_mgmt_client.c) +zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig new file mode 100644 index 000000000000000..46c95a3cf871be4 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig @@ -0,0 +1,35 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to OS management group of +# of MCUmgr client subsystem and provides Kconfig options to configure +# group commands behaviour and other aspects. +# +# Options defined in this file should be prefixed: +# MCUMGR_GRP_OS_CLIENT_ -- general group options; +# +# When adding Kconfig options, that control the same feature, +# try to group them together by the same stem after prefix. + +menuconfig MCUMGR_GRP_OS_CLIENT + bool "MCUmgr client request and response handlers for OS management" + depends on SMP_CLIENT + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_3 + help + Enables MCUmgr client request and response handlers for OS management. + +if MCUMGR_GRP_OS_CLIENT + +config MCUMGR_GRP_OS_CLIENT_ECHO + default y + bool "Support for echo command request" + +config MCUMGR_GRP_OS_CLIENT_RESET + default y + bool "support for reset command request" + +module = MCUMGR_GRP_OS_CLIENT +module-str = mcumgr_grp_os_client +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c new file mode 100644 index 000000000000000..2bd804494c41d6c --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_grp_os_client, CONFIG_MCUMGR_GRP_OS_CLIENT_LOG_LEVEL); + +static struct os_mgmt_client *active_client; +static K_SEM_DEFINE(mcummgr_os_client_grp_sem, 0, 1); +static K_MUTEX_DEFINE(mcummgr_os_client_grp_mutex); + +void os_mgmt_client_init(struct os_mgmt_client *client, struct smp_client_object *smp_client) +{ + client->smp_client = smp_client; +} + +#ifdef CONFIG_MCUMGR_GRP_OS_CLIENT_RESET + +static int reset_res_fn(struct net_buf *nb, void *user_data) +{ + if (!nb) { + active_client->status = MGMT_ERR_ETIMEOUT; + } else { + active_client->status = MGMT_ERR_EOK; + } + k_sem_give(user_data); + return 0; +} + +int os_mgmt_client_reset(struct os_mgmt_client *client) +{ + struct net_buf *nb; + int rc; + + k_mutex_lock(&mcummgr_os_client_grp_mutex, K_FOREVER); + active_client = client; + /* allocate buffer */ + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_OS, + OS_MGMT_ID_RESET, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + k_sem_reset(&mcummgr_os_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, reset_res_fn, + &mcummgr_os_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + active_client->status = rc; + smp_packet_free(nb); + goto end; + } + /* Wait for process end update event */ + k_sem_take(&mcummgr_os_client_grp_sem, K_FOREVER); +end: + rc = active_client->status; + active_client = NULL; + k_mutex_unlock(&mcummgr_os_client_grp_mutex); + return rc; +} + +#endif /* CONFIG_MCUMGR_GRP_OS_CLIENT_RESET */ + +#ifdef CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO + +static int echo_res_fn(struct net_buf *nb, void *user_data) +{ + struct zcbor_string val = {0}; + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + bool ok; + int rc; + struct zcbor_map_decode_key_val echo_response[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("r", zcbor_tstr_decode, &val) + }; + + if (!nb) { + LOG_ERR("Echo command timeout"); + active_client->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + /* Init ZCOR decoder state */ + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, echo_response, ARRAY_SIZE(echo_response), &decoded) == 0; + + if (!ok) { + active_client->status = MGMT_ERR_ECORRUPT; + goto end; + } + active_client->status = MGMT_ERR_EOK; +end: + rc = active_client->status; + k_sem_give(user_data); + return rc; +} + +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string) +{ + struct net_buf *nb; + int rc; + bool ok; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + + k_mutex_lock(&mcummgr_os_client_grp_mutex, K_FOREVER); + active_client = client; + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_OS, OS_MGMT_ID_ECHO, + MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + rc = active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "d") && zcbor_tstr_put_term(zse, echo_string) && + zcbor_map_end_encode(zse, 2); + + if (!ok) { + smp_packet_free(nb); + rc = active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + + LOG_DBG("Echo Command packet len %d", nb->len); + k_sem_reset(&mcummgr_os_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, echo_res_fn, + &mcummgr_os_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + smp_packet_free(nb); + } else { + k_sem_take(&mcummgr_os_client_grp_sem, K_FOREVER); + /* Take response status */ + rc = active_client->status; + } +end: + active_client = NULL; + k_mutex_unlock(&mcummgr_os_client_grp_mutex); + return rc; +} +#endif diff --git a/subsys/mgmt/mcumgr/grp/shell_mgmt/src/shell_mgmt.c b/subsys/mgmt/mcumgr/grp/shell_mgmt/src/shell_mgmt.c index d0f2a39497310de..2aa141671a3667c 100644 --- a/subsys/mgmt/mcumgr/grp/shell_mgmt/src/shell_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/shell_mgmt/src/shell_mgmt.c @@ -143,11 +143,11 @@ static int shell_mgmt_translate_error_code(uint16_t ret) switch (ret) { case SHELL_MGMT_RET_RC_COMMAND_TOO_LONG: case SHELL_MGMT_RET_RC_EMPTY_COMMAND: - rc = MGMT_ERR_EINVAL; - break; + rc = MGMT_ERR_EINVAL; + break; default: - rc = MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c b/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c index 9f9b9301168026f..1e4a3332e8e1ea4 100644 --- a/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c @@ -254,16 +254,16 @@ static int stat_mgmt_translate_error_code(uint16_t ret) switch (ret) { case STAT_MGMT_RET_RC_INVALID_GROUP: case STAT_MGMT_RET_RC_INVALID_STAT_NAME: - rc = MGMT_ERR_ENOENT; - break; + rc = MGMT_ERR_ENOENT; + break; case STAT_MGMT_RET_RC_INVALID_STAT_SIZE: - rc = MGMT_ERR_EINVAL; - break; + rc = MGMT_ERR_EINVAL; + break; case STAT_MGMT_RET_RC_WALK_ABORTED: default: - rc = MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/grp/zephyr_basic/src/basic_mgmt.c b/subsys/mgmt/mcumgr/grp/zephyr_basic/src/basic_mgmt.c index 4ccf95b2e71fb97..ba1cc4caf4052bc 100644 --- a/subsys/mgmt/mcumgr/grp/zephyr_basic/src/basic_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/zephyr_basic/src/basic_mgmt.c @@ -78,16 +78,16 @@ static int zephyr_basic_group_translate_error_code(uint16_t ret) switch (ret) { case ZEPHYR_MGMT_GRP_CMD_RC_FLASH_OPEN_FAILED: - rc = MGMT_ERR_ENOENT; - break; + rc = MGMT_ERR_ENOENT; + break; case ZEPHYR_MGMT_GRP_CMD_RC_FLASH_CONFIG_QUERY_FAIL: case ZEPHYR_MGMT_GRP_CMD_RC_FLASH_ERASE_FAILED: - rc = MGMT_ERR_EOK; - break; + rc = MGMT_ERR_EOK; + break; default: - rc = MGMT_ERR_EUNKNOWN; + rc = MGMT_ERR_EUNKNOWN; } return rc; diff --git a/subsys/mgmt/mcumgr/smp/src/smp.c b/subsys/mgmt/mcumgr/smp/src/smp.c index 42bf633f09d5afb..6de806d7e6d774d 100644 --- a/subsys/mgmt/mcumgr/smp/src/smp.c +++ b/subsys/mgmt/mcumgr/smp/src/smp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -50,12 +51,9 @@ static int smp_translate_error_code(uint16_t group, uint16_t ret) static void cbor_nb_reader_init(struct cbor_nb_reader *cnr, struct net_buf *nb) { - /* Skip the smp_hdr */ - void *new_ptr = net_buf_pull(nb, sizeof(struct smp_hdr)); - cnr->nb = nb; - zcbor_new_decode_state(cnr->zs, ARRAY_SIZE(cnr->zs), new_ptr, - cnr->nb->len, 1); + zcbor_new_decode_state(cnr->zs, ARRAY_SIZE(cnr->zs), nb->data, + nb->len, 1); } static void cbor_nb_writer_init(struct cbor_nb_writer *cnw, struct net_buf *nb) @@ -391,37 +389,54 @@ int smp_process_request_packet(struct smp_streamer *streamer, void *vreq) if (rc != 0) { rc = MGMT_ERR_ECORRUPT; break; - } else { - valid_hdr = true; } + + valid_hdr = true; + /* Skip the smp_hdr */ + net_buf_pull(req, sizeof(struct smp_hdr)); /* Does buffer contain whole message? */ - if (req->len < (req_hdr.nh_len + MGMT_HDR_SIZE)) { + if (req->len < req_hdr.nh_len) { rc = MGMT_ERR_ECORRUPT; break; } - rsp = smp_alloc_rsp(req, streamer->smpt); - if (rsp == NULL) { - rc = MGMT_ERR_ENOMEM; - break; - } + if (req_hdr.nh_op == MGMT_OP_READ || req_hdr.nh_op == MGMT_OP_WRITE) { + rsp = smp_alloc_rsp(req, streamer->smpt); + if (rsp == NULL) { + rc = MGMT_ERR_ENOMEM; + break; + } - cbor_nb_reader_init(streamer->reader, req); - cbor_nb_writer_init(streamer->writer, rsp); + cbor_nb_reader_init(streamer->reader, req); + cbor_nb_writer_init(streamer->writer, rsp); - /* Process the request payload and build the response. */ - rc = smp_handle_single_req(streamer, &req_hdr, &handler_found, &rsn); - if (rc != 0) { - break; + /* Process the request payload and build the response. */ + rc = smp_handle_single_req(streamer, &req_hdr, &handler_found, &rsn); + if (rc != 0) { + break; + } + + /* Send the response. */ + rc = streamer->smpt->functions.output(rsp); + rsp = NULL; + } else if (IS_ENABLED(CONFIG_SMP_CLIENT) && (req_hdr.nh_op == MGMT_OP_READ_RSP || + req_hdr.nh_op == MGMT_OP_WRITE_RSP)) { + rc = smp_client_single_response(req, &req_hdr); + + if (rc == MGMT_ERR_EOK) { + handler_found = true; + } else { + /* Server shuold not send error response for response */ + valid_hdr = false; + } + + } else { + rc = MGMT_ERR_ENOTSUP; } - /* Send the response. */ - rc = streamer->smpt->functions.output(rsp); - rsp = NULL; if (rc != 0) { break; } - /* Trim processed request to free up space for subsequent responses. */ net_buf_pull(req, req_hdr.nh_len); diff --git a/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt new file mode 100644 index 000000000000000..061d28b30638bab --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# Protocol API is only exposed to MCUmgr internals. + +zephyr_library(mgmt_mcumgr_client_protocol) +zephyr_library_sources(src/client.c) diff --git a/subsys/mgmt/mcumgr/smp_client/Kconfig b/subsys/mgmt/mcumgr/smp_client/Kconfig new file mode 100644 index 000000000000000..b946efe1b324112 --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/Kconfig @@ -0,0 +1,42 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to smp_client subdirectory of MCUmgr +# subsystem and provides Kconfig options to control aspects of +# Simple Management Protocol Client (SMP) processing source code provided +# under the subdirectory. + +config SMP_CLIENT + bool "SMP Client support" + help + This will enable SMP Request generation and response handling. + +if SMP_CLIENT || ZTEST + +config SMP_CMD_DEFAULT_LIFE_TIME + int "SMP command lifetime in seconds" + range 2 30 + default 5 + help + This define lifetime for SMP client send request. This configure is used if a request + with a timeout of 0 is used. + +config SMP_CMD_RETRY_TIME + int "SMP command re-send period in ms" + range 100 1000 + default 500 + help + The time (in ms) which the SMP client will wait for a response before re-sending + a command. + +config SMP_CLIENT_CMD_MAX + int "SMP client max buffer count" + default 4 + help + Define how many active requests that the client can handle + +module = MCUMGR_SMP_CLIENT +module-str = mcumgr_smp_client +source "subsys/logging/Kconfig.template.log_config" + +endif # SMP_CLIENT diff --git a/subsys/mgmt/mcumgr/smp_client/src/client.c b/subsys/mgmt/mcumgr/smp_client/src/client.c new file mode 100644 index 000000000000000..cca1738f117e631 --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/src/client.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** SMP - Simple Management Client Protocol. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_smp_client, CONFIG_MCUMGR_SMP_CLIENT_LOG_LEVEL); + +struct smp_client_cmd_req { + sys_snode_t node; + struct net_buf *nb; + struct smp_client_object *smp_client; + void *user_data; + smp_client_res_fn cb; + int64_t timestamp; + int retry_cnt; +}; + +struct smp_client_data_base { + struct k_work_delayable work_delay; + sys_slist_t cmd_free_list; + sys_slist_t cmd_list; +}; + +static struct smp_client_cmd_req smp_cmd_req_bufs[CONFIG_SMP_CLIENT_CMD_MAX]; +static struct smp_client_data_base smp_client_data; + +static void smp_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr); +static void smp_client_cmd_req_free(struct smp_client_cmd_req *cmd_req); + +/** + * Send all SMP client request packets. + */ +static void smp_client_handle_reqs(struct k_work *work) +{ + struct smp_client_object *smp_client; + struct smp_transport *smpt; + struct net_buf *nb; + + smp_client = (void *)work; + smpt = smp_client->smpt; + + while ((nb = net_buf_get(&smp_client->tx_fifo, K_NO_WAIT)) != NULL) { + smpt->functions.output(nb); + } +} + +static void smp_header_init(struct smp_hdr *header, uint16_t group, uint8_t id, uint8_t op, + uint16_t payload_len, uint8_t seq, enum smp_mcumgr_version_t version) +{ + /* Pre config SMP header structure */ + memset(header, 0, sizeof(struct smp_hdr)); + header->nh_version = version; + header->nh_op = op; + header->nh_len = sys_cpu_to_be16(payload_len); + header->nh_group = sys_cpu_to_be16(group); + header->nh_id = id; + header->nh_seq = seq; +} + +static void smp_client_transport_work_fn(struct k_work *work) +{ + struct smp_client_cmd_req *entry, *tmp; + smp_client_res_fn cb; + void *user_data; + int backoff_ms = CONFIG_SMP_CMD_RETRY_TIME; + int64_t time_stamp_cmp; + int64_t time_stamp_ref; + int64_t time_stamp_delta; + + ARG_UNUSED(work); + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* No more packet for Transport */ + return; + } + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&smp_client_data.cmd_list, entry, tmp, node) { + time_stamp_ref = entry->timestamp; + /* Check Time delta and get current time to reference */ + time_stamp_delta = k_uptime_delta(&time_stamp_ref); + + if (time_stamp_delta < 0) { + time_stamp_cmp = entry->timestamp - time_stamp_ref; + if (time_stamp_cmp < CONFIG_SMP_CMD_RETRY_TIME && + time_stamp_cmp < backoff_ms) { + /* Update new shorter shedule */ + backoff_ms = time_stamp_cmp; + } + continue; + } else if (entry->retry_cnt) { + /* Increment reference for re-transmission */ + entry->nb = net_buf_ref(entry->nb); + entry->retry_cnt--; + entry->timestamp = time_stamp_ref + CONFIG_SMP_CMD_RETRY_TIME; + net_buf_put(&entry->smp_client->tx_fifo, entry->nb); + smp_tx_req(&entry->smp_client->work); + continue; + } + + cb = entry->cb; + user_data = entry->user_data; + smp_client_cmd_req_free(entry); + if (cb) { + cb(NULL, user_data); + } + } + + if (!sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* Re-schedule new timeout to next */ + k_work_reschedule(&smp_client_data.work_delay, K_MSEC(backoff_ms)); + } +} + +static int smp_client_init(void) +{ + k_work_init_delayable(&smp_client_data.work_delay, smp_client_transport_work_fn); + sys_slist_init(&smp_client_data.cmd_list); + sys_slist_init(&smp_client_data.cmd_free_list); + for (int i = 0; i < CONFIG_SMP_CLIENT_CMD_MAX; i++) { + sys_slist_append(&smp_client_data.cmd_free_list, &smp_cmd_req_bufs[i].node); + } + return 0; +} + +static struct smp_client_cmd_req *smp_client_cmd_req_allocate(void) +{ + sys_snode_t *cmd_node; + struct smp_client_cmd_req *req; + + cmd_node = sys_slist_get(&smp_client_data.cmd_free_list); + if (!cmd_node) { + return NULL; + } + + req = SYS_SLIST_CONTAINER(cmd_node, req, node); + + return req; +} + +static void smp_cmd_add_to_list(struct smp_client_cmd_req *cmd_req) +{ + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* Enable timer */ + k_work_reschedule(&smp_client_data.work_delay, K_MSEC(CONFIG_SMP_CMD_RETRY_TIME)); + } + sys_slist_append(&smp_client_data.cmd_list, &cmd_req->node); +} + +static void smp_client_cmd_req_free(struct smp_client_cmd_req *cmd_req) +{ + smp_client_buf_free(cmd_req->nb); + cmd_req->nb = NULL; + sys_slist_find_and_remove(&smp_client_data.cmd_list, &cmd_req->node); + /* Add to free list */ + sys_slist_append(&smp_client_data.cmd_free_list, &cmd_req->node); + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* cancel delay */ + k_work_cancel_delayable(&smp_client_data.work_delay); + } +} + +static struct smp_client_cmd_req *smp_client_response_discover(const struct smp_hdr *res_hdr) +{ + struct smp_hdr smp_header; + enum mcumgr_op_t response; + struct smp_client_cmd_req *cmd_req; + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + return NULL; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&smp_client_data.cmd_list, cmd_req, node) { + smp_read_hdr(cmd_req->nb, &smp_header); + if (smp_header.nh_op == MGMT_OP_READ) { + response = MGMT_OP_READ_RSP; + } else { + response = MGMT_OP_WRITE_RSP; + } + + if (smp_header.nh_seq != res_hdr->nh_seq) { + continue; + } else if (res_hdr->nh_op != response) { + continue; + } + + return cmd_req; + } + return NULL; +} + +int smp_client_object_init(struct smp_client_object *smp_client, int smp_type) +{ + smp_client->smpt = smp_client_transport_get(smp_type); + if (!smp_client->smpt) { + return MGMT_ERR_EINVAL; + } + + /* Init TX FIFO */ + k_work_init(&smp_client->work, smp_client_handle_reqs); + k_fifo_init(&smp_client->tx_fifo); + + return MGMT_ERR_EOK; +} + +int smp_client_single_response(struct net_buf *nb, const struct smp_hdr *res_hdr) +{ + struct smp_client_cmd_req *cmd_req; + smp_client_res_fn cb; + void *user_data; + + /* Discover request for incoming response */ + cmd_req = smp_client_response_discover(res_hdr); + LOG_DBG("Response Header len %d, flags %d OP: %d group %d id %d seq %d", res_hdr->nh_len, + res_hdr->nh_flags, res_hdr->nh_op, res_hdr->nh_group, res_hdr->nh_id, + res_hdr->nh_seq); + + if (cmd_req) { + cb = cmd_req->cb; + user_data = cmd_req->user_data; + smp_client_cmd_req_free(cmd_req); + if (cb) { + cb(nb, user_data); + return MGMT_ERR_EOK; + } + } + + return MGMT_ERR_ENOENT; +} + +struct net_buf *smp_client_buf_allocation(struct smp_client_object *smp_client, uint16_t group, + uint8_t command_id, uint8_t op, + enum smp_mcumgr_version_t version) +{ + struct net_buf *nb; + struct smp_hdr smp_header; + + nb = smp_packet_alloc(); + + if (nb) { + /* Write SMP header with payload length 0 */ + smp_header_init(&smp_header, group, command_id, op, 0, smp_client->smp_seq++, + version); + memcpy(nb->data, &smp_header, sizeof(smp_header)); + nb->len = sizeof(smp_header); + } + return nb; +} + +void smp_client_buf_free(struct net_buf *nb) +{ + smp_packet_free(nb); +} + +static void smp_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + +int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb, + smp_client_res_fn cb, void *user_data, int timeout_in_sec) +{ + struct smp_hdr smp_header; + struct smp_client_cmd_req *cmd_req; + + if (timeout_in_sec > 30) { + LOG_ERR("Command timeout can't be over 30 seconds"); + return MGMT_ERR_EINVAL; + } + + if (timeout_in_sec == 0) { + timeout_in_sec = CONFIG_SMP_CMD_DEFAULT_LIFE_TIME; + } + + smp_read_hdr(nb, &smp_header); + if (nb->len < sizeof(smp_header)) { + return MGMT_ERR_EINVAL; + } + /* Update Length */ + smp_header.nh_len = sys_cpu_to_be16(nb->len - sizeof(smp_header)); + smp_header.nh_group = sys_cpu_to_be16(smp_header.nh_group), + memcpy(nb->data, &smp_header, sizeof(smp_header)); + + cmd_req = smp_client_cmd_req_allocate(); + if (!cmd_req) { + return MGMT_ERR_ENOMEM; + } + + LOG_DBG("Command send Header flags %d OP: %d group %d id %d seq %d", smp_header.nh_flags, + smp_header.nh_op, sys_be16_to_cpu(smp_header.nh_group), smp_header.nh_id, + smp_header.nh_seq); + cmd_req->nb = nb; + cmd_req->cb = cb; + cmd_req->smp_client = smp_client; + cmd_req->user_data = user_data; + cmd_req->retry_cnt = timeout_in_sec * (1000 / CONFIG_SMP_CMD_RETRY_TIME); + cmd_req->timestamp = k_uptime_get() + CONFIG_SMP_CMD_RETRY_TIME; + /* Increment reference for re-transmission and read smp header */ + nb = net_buf_ref(nb); + smp_cmd_add_to_list(cmd_req); + net_buf_put(&smp_client->tx_fifo, nb); + smp_tx_req(&smp_client->work); + return MGMT_ERR_EOK; +} + +SYS_INIT(smp_client_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h b/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h index 828a15ffb1623f4..898f2134c26cfff 100644 --- a/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h +++ b/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h @@ -9,6 +9,7 @@ #define MGMT_MCUMGR_SMP_INTERNAL_H_ #include +#include #include #include @@ -47,6 +48,15 @@ struct zephyr_smp_transport; */ void smp_rx_req(struct smp_transport *smtp, struct net_buf *nb); +#ifdef CONFIG_SMP_CLIENT +/** + * @brief Trig SMP client request packet for transmission. + * + * @param work The transport to use to send the corresponding response(s). + */ +void smp_tx_req(struct k_work *work); +#endif + __deprecated static inline void zephyr_smp_rx_req(struct zephyr_smp_transport *smpt, struct net_buf *nb) { diff --git a/subsys/mgmt/mcumgr/transport/src/smp.c b/subsys/mgmt/mcumgr/transport/src/smp.c index 1052b82cd04f3c0..0f23bd4c44db9d8 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp.c @@ -31,6 +31,10 @@ K_THREAD_STACK_DEFINE(smp_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_ST static struct k_work_q smp_work_queue; +#ifdef CONFIG_SMP_CLIENT +static sys_slist_t smp_transport_clients; +#endif + static const struct k_work_queue_config smp_work_queue_config = { .name = "mcumgr smp" }; @@ -131,6 +135,7 @@ smp_handle_reqs(struct k_work *work) smpt = (void *)work; + /* Read and handle received messages */ while ((nb = net_buf_get(&smpt->fifo, K_NO_WAIT)) != NULL) { smp_process_packet(smpt, nb); } @@ -155,6 +160,33 @@ int smp_transport_init(struct smp_transport *smpt) return 0; } +#ifdef CONFIG_SMP_CLIENT +struct smp_transport *smp_client_transport_get(int smpt_type) +{ + struct smp_client_transport_entry *entry; + + SYS_SLIST_FOR_EACH_CONTAINER(&smp_transport_clients, entry, node) { + if (entry->smpt_type == smpt_type) { + return entry->smpt; + } + } + + return NULL; +} + +void smp_client_transport_register(struct smp_client_transport_entry *entry) +{ + if (smp_client_transport_get(entry->smpt_type)) { + /* Already in list */ + return; + } + + sys_slist_append(&smp_transport_clients, &entry->node); + +} + +#endif /* CONFIG_SMP_CLIENT */ + /** * @brief Enqueues an incoming SMP request packet for processing. * @@ -171,6 +203,13 @@ smp_rx_req(struct smp_transport *smpt, struct net_buf *nb) k_work_submit_to_queue(&smp_work_queue, &smpt->work); } +#ifdef CONFIG_SMP_CLIENT +void smp_tx_req(struct k_work *work) +{ + k_work_submit_to_queue(&smp_work_queue, work); +} +#endif + void smp_rx_remove_invalid(struct smp_transport *zst, void *arg) { struct net_buf *nb; @@ -227,6 +266,10 @@ void smp_rx_clear(struct smp_transport *zst) static int smp_init(void) { +#ifdef CONFIG_SMP_CLIENT + sys_slist_init(&smp_transport_clients); +#endif + k_work_queue_init(&smp_work_queue); k_work_queue_start(&smp_work_queue, smp_work_queue_stack, diff --git a/subsys/mgmt/mcumgr/transport/src/smp_bt.c b/subsys/mgmt/mcumgr/transport/src/smp_bt.c index 6cd2d53d9ffdfcd..87706fd8f47fa14 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_bt.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_bt.c @@ -109,6 +109,10 @@ BT_CONN_CB_DEFINE(mcumgr_bt_callbacks) = { .disconnected = disconnected, }; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif + /* Helper function that allocates conn_param_data for a conn. */ static struct conn_param_data *conn_param_data_alloc(struct bt_conn *conn) { @@ -665,6 +669,14 @@ static void smp_bt_setup(void) rc = smp_bt_register(); } +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + smp_client_transport.smpt = &smp_bt_transport; + smp_client_transport.smpt_type = SMP_BLUETOOTH_TRANSPORT; + rc = smp_client_transport_register(&smp_client_transport); + } +#endif + if (rc != 0) { LOG_ERR("Bluetooth SMP transport register failed (err %d)", rc); } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_shell.c b/subsys/mgmt/mcumgr/transport/src/smp_shell.c index ac196c100854d9e..c30874070bac02b 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_shell.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_shell.c @@ -39,6 +39,10 @@ static struct smp_transport smp_shell_transport; static struct mcumgr_serial_rx_ctxt smp_shell_rx_ctxt; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif + /** SMP mcumgr frame fragments. */ enum smp_shell_esc_mcumgr { ESC_MCUMGR_PKT_1, @@ -241,6 +245,13 @@ int smp_shell_init(void) smp_shell_transport.functions.get_mtu = smp_shell_get_mtu; rc = smp_transport_init(&smp_shell_transport); +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + smp_client_transport.smpt = &CONFIG_SMP_CLIENT; + smp_client_transport.smpt_type = SMP_SHELL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); + } +#endif return rc; } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_uart.c b/subsys/mgmt/mcumgr/transport/src/smp_uart.c index 9c3dade2f8e30f1..643caf6eb48a0c1 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_uart.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_uart.c @@ -31,6 +31,9 @@ K_WORK_DEFINE(smp_uart_work, smp_uart_process_rx_queue); static struct mcumgr_serial_rx_ctxt smp_uart_rx_ctxt; static struct smp_transport smp_uart_transport; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif /** * Processes a single line (fragment) coming from the mcumgr UART driver. @@ -101,6 +104,11 @@ static int smp_uart_init(void) if (rc == 0) { uart_mcumgr_register(smp_uart_rx_frag); +#ifdef CONFIG_SMP_CLIENT + smp_client_transport.smpt = &smp_uart_transport; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); +#endif } return rc; diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index e772cf499de79cd..6f8f9a137353d60 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -66,9 +66,15 @@ struct config { struct configs { #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 struct config ipv4; +#ifdef CONFIG_SMP_CLIENT + struct smp_client_transport_entry ipv4_transport; +#endif #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 struct config ipv6; +#ifdef CONFIG_SMP_CLIENT + struct smp_client_transport_entry ipv6_transport; +#endif #endif }; @@ -381,7 +387,13 @@ static void smp_udp_start(void) configs.ipv4.smp_transport.functions.ud_copy = smp_udp_ud_copy; rc = smp_transport_init(&configs.ipv4.smp_transport); - +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + configs.ipv4_transport.smpt = &configs.ipv4.smp_transport; + configs.ipv4_transport.smpt_type = SMP_UDP_IPV4_TRANSPORT; + smp_client_transport_register(&configs.ipv4_transport); + } +#endif if (rc) { LOG_ERR("Failed to register IPv4 UDP MCUmgr SMP transport: %d", rc); } @@ -394,6 +406,13 @@ static void smp_udp_start(void) configs.ipv6.smp_transport.functions.ud_copy = smp_udp_ud_copy; rc = smp_transport_init(&configs.ipv6.smp_transport); +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + configs.ipv6_transport.smpt = &configs.ipv6.smp_transport; + configs.ipv6_transport.smpt_type = SMP_UDP_IPV6_TRANSPORT; + smp_client_transport_register(&configs.ipv6_transport); + } +#endif if (rc) { LOG_ERR("Failed to register IPv6 UDP MCUmgr SMP transport: %d", rc); diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 3b9947eb50b01c9..ea592a9a26ef60e 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -840,7 +840,8 @@ config NET_PKT_TIMESTAMP help Enable network packet timestamp support. This is needed for example in gPTP which needs to know how long it takes to send - a network packet. + a network packet or for timed radio protocols like IEEE 802.15.4 + CSL and TSCH. config NET_PKT_TIMESTAMP_THREAD bool "Create TX timestamp thread" diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index a32a673de4acc7f..c7755c52ddd12be 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1459,9 +1459,10 @@ static void set_pkt_txtime(struct net_pkt *pkt, const struct msghdr *msghdr) if (cmsg->cmsg_len == CMSG_LEN(sizeof(uint64_t)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TXTIME) { - uint64_t txtime = *(uint64_t *)CMSG_DATA(cmsg); + struct net_ptp_time txtime = + ns_to_net_ptp_time(*(net_time_t *)CMSG_DATA(cmsg)); - net_pkt_set_txtime(pkt, txtime); + net_pkt_set_timestamp(pkt, &txtime); break; } } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index ae9d59e7e16d5d2..4cc6fa32bde3850 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2343,6 +2343,10 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) } } #endif + NET_ASSERT((conn->send_data_total == 0) || + k_work_delayable_is_pending(&conn->send_data_timer), + "conn: %p, Missing a subscription " + "of the send_data queue timer", conn); if (th && (net_tcp_seq_cmp(th_ack(th), conn->seq) > 0)) { uint32_t len_acked = th_ack(th) - conn->seq; @@ -2383,19 +2387,16 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) conn_send_data_dump(conn); - if (!k_work_delayable_remaining_get( - &conn->send_data_timer)) { - NET_DBG("conn: %p, Missing a subscription " - "of the send_data queue timer", conn); - break; - } conn->send_data_retries = 0; - k_work_cancel_delayable(&conn->send_data_timer); if (conn->data_mode == TCP_DATA_MODE_RESEND) { conn->unacked_len = 0; tcp_derive_rto(conn); } conn->data_mode = TCP_DATA_MODE_SEND; + if (conn->send_data_total > 0) { + k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer, + K_MSEC(TCP_RTO_MS)); + } /* We are closing the connection, send a FIN to peer */ if (conn->in_close && conn->send_data_total == 0) { @@ -2457,6 +2458,20 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) verdict = NET_OK; } } + + /* Check if there is any data left to retransmit possibly*/ + if (conn->send_data_total == 0) { + conn->send_data_retries = 0; + k_work_cancel_delayable(&conn->send_data_timer); + } + + /* A lot could have happened to the transmission window check the situation here */ + if (tcp_window_full(conn)) { + (void)k_sem_take(&conn->tx_sem, K_NO_WAIT); + } else { + k_sem_give(&conn->tx_sem); + } + break; case TCP_CLOSE_WAIT: tcp_out(conn, FIN); diff --git a/subsys/pm/device.c b/subsys/pm/device.c index baf37983d692f17..bba0c316257ab45 100644 --- a/subsys/pm/device.c +++ b/subsys/pm/device.c @@ -385,3 +385,41 @@ bool pm_device_is_powered(const struct device *dev) return true; #endif } + +int pm_device_driver_init(const struct device *dev, + pm_device_action_cb_t action_cb) +{ + struct pm_device *pm = dev->pm; + int rc = 0; + + /* Work only needs to be performed if the device is powered */ + if (pm_device_is_powered(dev)) { + /* Run power-up logic */ + rc = action_cb(dev, PM_DEVICE_ACTION_TURN_ON); + if (rc != 0) { + return rc; + } + /* If device has no PM structure */ + if (pm == NULL) { + /* Device should always be active */ + return action_cb(dev, PM_DEVICE_ACTION_RESUME); + } + /* If device will have PM device runtime enabled */ + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) && + atomic_test_bit(&pm->flags, PM_DEVICE_FLAG_RUNTIME_AUTO)) { + /* Init into suspend mode. + * This saves a SUSPENDED->ACTIVE->SUSPENDED cycle. + */ + pm_device_init_suspended(dev); + } + /* No PM enabled on the device by default */ + else { + /* Startup into active mode */ + return action_cb(dev, PM_DEVICE_ACTION_RESUME); + } + } else { + /* Start in off mode */ + pm_device_init_off(dev); + } + return rc; +} diff --git a/subsys/pm/device_runtime.c b/subsys/pm/device_runtime.c index 393c0e734783f14..804cd5d2f5765f6 100644 --- a/subsys/pm/device_runtime.c +++ b/subsys/pm/device_runtime.c @@ -145,7 +145,15 @@ int pm_device_runtime_get(const struct device *dev) } if (!k_is_pre_kernel()) { - (void)k_sem_take(&pm->lock, K_FOREVER); + ret = k_sem_take(&pm->lock, k_is_in_isr() ? K_NO_WAIT : K_FOREVER); + if (ret < 0) { + return -EWOULDBLOCK; + } + } + + if (k_is_in_isr() && (pm->state == PM_DEVICE_STATE_SUSPENDING)) { + ret = -EWOULDBLOCK; + goto unlock; } /* diff --git a/subsys/pm/state.c b/subsys/pm/state.c index 14352dfe2df5719..297d28a37680b75 100644 --- a/subsys/pm/state.c +++ b/subsys/pm/state.c @@ -33,7 +33,7 @@ BUILD_ASSERT(DT_NODE_EXISTS(DT_PATH(cpus)), * @param node_id A CPU node identifier. */ #define CHECK_POWER_STATES_CONSISTENCY(node_id) \ - LISTIFY(DT_NUM_CPU_POWER_STATES(node_id), \ + LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0), \ CHECK_POWER_STATE_CONSISTENCY, (;), node_id); \ /* Check that all power states are consistent */ @@ -48,12 +48,12 @@ DT_FOREACH_CHILD(DT_PATH(cpus), DEFINE_CPU_STATES); /** CPU power states information for each CPU */ static const struct pm_state_info *cpus_states[] = { - DT_FOREACH_CHILD_SEP(DT_PATH(cpus), CPU_STATE_REF, (,)) + DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), CPU_STATE_REF, (,)) }; /** Number of states for each CPU */ static const uint8_t states_per_cpu[] = { - DT_FOREACH_CHILD_SEP(DT_PATH(cpus), DT_NUM_CPU_POWER_STATES, (,)) + DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_NUM_CPU_POWER_STATES, (,)) }; uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states) diff --git a/subsys/shell/shell_ops.c b/subsys/shell/shell_ops.c index b8ff0f0e56c6951..db68c62155ba16e 100644 --- a/subsys/shell/shell_ops.c +++ b/subsys/shell/shell_ops.c @@ -161,16 +161,16 @@ void z_shell_op_cursor_word_move(const struct shell *sh, int16_t val) void z_shell_op_word_remove(const struct shell *sh) { - char *str = &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos - 1]; - char *str_start = &sh->ctx->cmd_buff[0]; - uint16_t chars_to_delete; - /* Line must not be empty and cursor must not be at 0 to continue. */ if ((sh->ctx->cmd_buff_len == 0) || (sh->ctx->cmd_buff_pos == 0)) { return; } + char *str = &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos - 1]; + char *str_start = &sh->ctx->cmd_buff[0]; + uint16_t chars_to_delete; + /* Start at the current position. */ chars_to_delete = 0U; diff --git a/subsys/usb/device/Kconfig b/subsys/usb/device/Kconfig index 20addc2f1c1dddc..476f7400270c20a 100644 --- a/subsys/usb/device/Kconfig +++ b/subsys/usb/device/Kconfig @@ -49,9 +49,11 @@ config USB_DEVICE_SN Hardware Information Driver (HWINFO). config USB_COMPOSITE_DEVICE - bool "Composite device driver" + bool "Use Interface Association Descriptor code triple" help - Enable composite USB device driver. + This option modifies the code triple in the device descriptor + to signal that one of the functions has two or more interfaces and + uses the Interface Association Descriptor. config USB_MAX_NUM_TRANSFERS int "Set number of USB transfer data buffers" diff --git a/subsys/usb/device/class/Kconfig.cdc b/subsys/usb/device/class/Kconfig.cdc index af1d8aba3982f75..7c74802802387ed 100644 --- a/subsys/usb/device/class/Kconfig.cdc +++ b/subsys/usb/device/class/Kconfig.cdc @@ -6,6 +6,7 @@ menu "USB CDC ACM Class support" config USB_CDC_ACM bool "USB CDC ACM Class support" default y + select USB_COMPOSITE_DEVICE depends on SERIAL depends on DT_HAS_ZEPHYR_CDC_ACM_UART_ENABLED select SERIAL_HAS_DRIVER diff --git a/subsys/usb/device/class/audio/Kconfig b/subsys/usb/device/class/audio/Kconfig index e38bf11f0d57ebc..825f2580a509749 100644 --- a/subsys/usb/device/class/audio/Kconfig +++ b/subsys/usb/device/class/audio/Kconfig @@ -6,6 +6,7 @@ config USB_DEVICE_AUDIO bool "USB Audio Device Class Driver" select EXPERIMENTAL + select USB_COMPOSITE_DEVICE help USB Audio Device Class driver. Zephyr USB Audio Class is considered experimental diff --git a/subsys/usb/device/class/audio/audio.c b/subsys/usb/device/class/audio/audio.c index 637096052f771c3..dc7e15f08d8232a 100644 --- a/subsys/usb/device/class/audio/audio.c +++ b/subsys/usb/device/class/audio/audio.c @@ -292,12 +292,10 @@ static void audio_interface_config(struct usb_desc_header *head, struct usb_if_descriptor *iface = (struct usb_if_descriptor *)head; struct cs_ac_if_descriptor *header; -#ifdef CONFIG_USB_COMPOSITE_DEVICE struct usb_association_descriptor *iad = (struct usb_association_descriptor *) ((char *)iface - sizeof(struct usb_association_descriptor)); iad->bFirstInterface = bInterfaceNumber; -#endif fix_fu_descriptors(iface); /* Audio Control Interface */ diff --git a/subsys/usb/device/class/audio/usb_audio_internal.h b/subsys/usb/device/class/audio/usb_audio_internal.h index 1cf8a10702d88c9..c0d5383577d9063 100644 --- a/subsys/usb/device/class/audio/usb_audio_internal.h +++ b/subsys/usb/device/class/audio/usb_audio_internal.h @@ -328,13 +328,8 @@ struct dev##_feature_unit_descriptor_##i { \ .iFunction = 0, \ } -#ifdef CONFIG_USB_COMPOSITE_DEVICE #define USB_AUDIO_IAD_DECLARE struct usb_association_descriptor iad; #define USB_AUDIO_IAD(if_cnt) .iad = INIT_IAD(USB_AUDIO_AUDIOCONTROL, if_cnt), -#else -#define USB_AUDIO_IAD_DECLARE -#define USB_AUDIO_IAD(if_cnt) -#endif #define DECLARE_DESCRIPTOR(dev, i, ifaces) \ DECLARE_HEADER(dev, i, ifaces); \ diff --git a/subsys/usb/device/class/cdc_acm.c b/subsys/usb/device/class/cdc_acm.c index ab14732440e1346..9262cd5cf78ffd1 100644 --- a/subsys/usb/device/class/cdc_acm.c +++ b/subsys/usb/device/class/cdc_acm.c @@ -80,9 +80,7 @@ LOG_MODULE_REGISTER(usb_cdc_acm, CONFIG_USB_CDC_ACM_LOG_LEVEL); #define ACM_IN_EP_IDX 2 struct usb_cdc_acm_config { -#if (CONFIG_USB_COMPOSITE_DEVICE || CONFIG_CDC_ACM_IAD) struct usb_association_descriptor iad_cdc; -#endif struct usb_if_descriptor if0; struct cdc_header_descriptor if0_header; struct cdc_cm_descriptor if0_cm; @@ -437,9 +435,7 @@ static void cdc_interface_config(struct usb_desc_header *head, desc->if0_union.bControlInterface = bInterfaceNumber; desc->if1.bInterfaceNumber = bInterfaceNumber + 1; desc->if0_union.bSubordinateInterface0 = bInterfaceNumber + 1; -#if (CONFIG_USB_COMPOSITE_DEVICE || CONFIG_CDC_ACM_IAD) desc->iad_cdc.bFirstInterface = bInterfaceNumber; -#endif } /** @@ -1051,7 +1047,6 @@ static const struct uart_driver_api cdc_acm_driver_api = { #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ }; -#if (CONFIG_USB_COMPOSITE_DEVICE || CONFIG_CDC_ACM_IAD) #define INITIALIZER_IAD \ .iad_cdc = { \ .bLength = sizeof(struct usb_association_descriptor), \ @@ -1063,9 +1058,6 @@ static const struct uart_driver_api cdc_acm_driver_api = { .bFunctionProtocol = 0, \ .iFunction = 0, \ }, -#else -#define INITIALIZER_IAD -#endif #define INITIALIZER_IF(iface_num, num_ep, class, subclass) \ { \ diff --git a/subsys/usb/device/class/msc.c b/subsys/usb/device/class/msc.c index 037381cbafc088b..6eae1f6a3aba8bd 100644 --- a/subsys/usb/device/class/msc.c +++ b/subsys/usb/device/class/msc.c @@ -39,13 +39,72 @@ #include #include #include -#include #include #include #include LOG_MODULE_REGISTER(usb_msc, CONFIG_USB_MASS_STORAGE_LOG_LEVEL); +/* MSC Subclass and Protocol Codes */ +#define SCSI_TRANSPARENT_SUBCLASS 0x06 +#define BULK_ONLY_TRANSPORT_PROTOCOL 0x50 + +/* MSC Request Codes for Bulk-Only Transport */ +#define MSC_REQUEST_GET_MAX_LUN 0xFE +#define MSC_REQUEST_RESET 0xFF + +/* MSC Command Block Wrapper (CBW) Signature */ +#define CBW_Signature 0x43425355 + +/* MSC Command Block Wrapper Flags */ +#define CBW_DIRECTION_DATA_IN 0x80 + +/* MSC Bulk-Only Command Block Wrapper (CBW) */ +struct CBW { + uint32_t Signature; + uint32_t Tag; + uint32_t DataLength; + uint8_t Flags; + uint8_t LUN; + uint8_t CBLength; + uint8_t CB[16]; +} __packed; + +/* MSC Command Status Wrapper (CBW) Signature */ +#define CSW_Signature 0x53425355 + +/* MSC Command Block Status Values */ +#define CSW_STATUS_CMD_PASSED 0x00 +#define CSW_STATUS_CMD_FAILED 0x01 +#define CSW_STATUS_PHASE_ERROR 0x02 + +/* MSC Bulk-Only Command Status Wrapper (CSW) */ +struct CSW { + uint32_t Signature; + uint32_t Tag; + uint32_t DataResidue; + uint8_t Status; +} __packed; + +/* SCSI transparent command set used by MSC */ +#define TEST_UNIT_READY 0x00 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define INQUIRY 0x12 +#define MODE_SELECT6 0x15 +#define MODE_SENSE6 0x1A +#define START_STOP_UNIT 0x1B +#define MEDIA_REMOVAL 0x1E +#define READ_FORMAT_CAPACITIES 0x23 +#define READ_CAPACITY 0x25 +#define READ10 0x28 +#define WRITE10 0x2A +#define VERIFY10 0x2F +#define READ12 0xA8 +#define WRITE12 0xAA +#define MODE_SELECT10 0x55 +#define MODE_SENSE10 0x5A + /* max USB packet size */ #define MAX_PACKET CONFIG_MASS_STORAGE_BULK_EP_MPS diff --git a/subsys/usb/device/class/netusb/Kconfig b/subsys/usb/device/class/netusb/Kconfig index 803322536e89b37..e358c9b9ac79be0 100644 --- a/subsys/usb/device/class/netusb/Kconfig +++ b/subsys/usb/device/class/netusb/Kconfig @@ -12,6 +12,7 @@ config USB_DEVICE_NETWORK config USB_DEVICE_NETWORK_ECM bool "USB Ethernet Control Model (ECM) Networking device" select USB_DEVICE_NETWORK + select USB_COMPOSITE_DEVICE help Ethernet Control Model (ECM) is a part of Communications Device Class (CDC) USB protocol specified by USB-IF. @@ -27,6 +28,7 @@ config USB_DEVICE_NETWORK_EEM config USB_DEVICE_NETWORK_RNDIS bool "USB Remote NDIS (RNDIS) Networking device" select USB_DEVICE_NETWORK + select USB_COMPOSITE_DEVICE help Remote NDIS (RNDIS) is commonly used Microsoft vendor protocol with Specification available from Microsoft web site. diff --git a/subsys/usb/device/class/netusb/function_ecm.c b/subsys/usb/device/class/netusb/function_ecm.c index b5eaa0dfd8d2137..256cf9b9d1ed84e 100644 --- a/subsys/usb/device/class/netusb/function_ecm.c +++ b/subsys/usb/device/class/netusb/function_ecm.c @@ -31,9 +31,7 @@ LOG_MODULE_REGISTER(usb_ecm, CONFIG_USB_DEVICE_NETWORK_LOG_LEVEL); static uint8_t tx_buf[NET_ETH_MAX_FRAME_SIZE], rx_buf[NET_ETH_MAX_FRAME_SIZE]; struct usb_cdc_ecm_config { -#ifdef CONFIG_USB_COMPOSITE_DEVICE struct usb_association_descriptor iad; -#endif struct usb_if_descriptor if0; struct cdc_header_descriptor if0_header; struct cdc_union_descriptor if0_union; @@ -48,7 +46,6 @@ struct usb_cdc_ecm_config { } __packed; USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_cdc_ecm_config cdc_ecm_cfg = { -#ifdef CONFIG_USB_COMPOSITE_DEVICE .iad = { .bLength = sizeof(struct usb_association_descriptor), .bDescriptorType = USB_DESC_INTERFACE_ASSOC, @@ -59,7 +56,6 @@ USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_cdc_ecm_config cdc_ecm_cfg = { .bFunctionProtocol = 0, .iFunction = 0, }, -#endif /* Interface descriptor 0 */ /* CDC Communication interface */ .if0 = { @@ -422,9 +418,7 @@ static void ecm_interface_config(struct usb_desc_header *head, cdc_ecm_cfg.if0_union.bSubordinateInterface0 = bInterfaceNumber + 1; cdc_ecm_cfg.if1_0.bInterfaceNumber = bInterfaceNumber + 1; cdc_ecm_cfg.if1_1.bInterfaceNumber = bInterfaceNumber + 1; -#ifdef CONFIG_USB_COMPOSITE_DEVICE cdc_ecm_cfg.iad.bFirstInterface = bInterfaceNumber; -#endif } USBD_DEFINE_CFG_DATA(cdc_ecm_config) = { diff --git a/subsys/usb/device_next/class/loopback.c b/subsys/usb/device_next/class/loopback.c index 5400d7c21b96dca..bdd20717e7483b1 100644 --- a/subsys/usb/device_next/class/loopback.c +++ b/subsys/usb/device_next/class/loopback.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(usb_loopback, CONFIG_USBD_LOOPBACK_LOG_LEVEL); * interface and endpoint configuration. */ -/* Internal buffer for intermidiate test data */ +/* Internal buffer for intermediate test data */ static uint8_t lb_buf[1024]; #define LB_VENDOR_REQ_OUT 0x5b diff --git a/subsys/usb/device_next/class/usbd_msc_scsi.c b/subsys/usb/device_next/class/usbd_msc_scsi.c index 81172670b17112a..82aa0f50e624f33 100644 --- a/subsys/usb/device_next/class/usbd_msc_scsi.c +++ b/subsys/usb/device_next/class/usbd_msc_scsi.c @@ -459,7 +459,7 @@ static int fill_inquiry(struct scsi_ctx *ctx, memset(&r, 0, sizeof(struct scsi_inquiry_response)); - /* Accesible; Direct access block device (SBC) */ + /* Accessible; Direct access block device (SBC) */ r.peripheral = 0x00; /* Removable; not a part of conglomerate. Note that when device is * accessible via USB Mass Storage, it should always be marked as @@ -526,7 +526,7 @@ static int fill_vpd_page(struct scsi_ctx *ctx, enum vpd_page_code page, return -ENOTSUP; } - /* Accesible; Direct access block device (SBC) */ + /* Accessible; Direct access block device (SBC) */ buf[0] = 0x00; buf[1] = page; sys_put_be16(offset, &buf[2]); diff --git a/subsys/usb/device_next/usbd_ch9.h b/subsys/usb/device_next/usbd_ch9.h index 3531a97ab91af27..657e492f33adfc2 100644 --- a/subsys/usb/device_next/usbd_ch9.h +++ b/subsys/usb/device_next/usbd_ch9.h @@ -131,7 +131,7 @@ usbd_get_setup_pkt(struct usbd_contex *const uds_ctx) * * @param[in] uds_ctx Pointer to a device context * @param[in] buf Pointer to UDC request buffer - * @param[in] err Trasnfer status + * @param[in] err Transfer status * * @return 0 on success, other values on fail. */ diff --git a/subsys/usb/device_next/usbd_class.c b/subsys/usb/device_next/usbd_class.c index 41d6d7e6ae8eb25..407e9145258ed54 100644 --- a/subsys/usb/device_next/usbd_class.c +++ b/subsys/usb/device_next/usbd_class.c @@ -313,7 +313,7 @@ int usbd_register_class(struct usbd_contex *const uds_ctx, /* TODO: does it still need to be atomic ? */ if (atomic_test_bit(&data->state, USBD_CCTX_REGISTERED)) { - LOG_WRN("Class instance allready registered"); + LOG_WRN("Class instance already registered"); ret = -EBUSY; goto register_class_error; } diff --git a/subsys/usb/device_next/usbd_class.h b/subsys/usb/device_next/usbd_class.h index a4d67939c97d98f..63a32ed57278008 100644 --- a/subsys/usb/device_next/usbd_class.h +++ b/subsys/usb/device_next/usbd_class.h @@ -14,7 +14,7 @@ * * @param[in] uds_ctx Pointer to device context * @param[in] buf Pointer to UDC request buffer - * @param[in] err Trasnfer status + * @param[in] err Transfer status * * @return usbd_class_request() return value */ diff --git a/subsys/usb/device_next/usbd_class_api.h b/subsys/usb/device_next/usbd_class_api.h index 244ff873a3c6920..ccff5243cac3a66 100644 --- a/subsys/usb/device_next/usbd_class_api.h +++ b/subsys/usb/device_next/usbd_class_api.h @@ -190,7 +190,7 @@ static inline void usbd_class_resumed(struct usbd_class_node *const node) } /** - * @brief Class associated configuration activ handler + * @brief Class associated configuration active handler * * @note The execution of the handler must not block. * diff --git a/subsys/usb/device_next/usbd_desc.c b/subsys/usb/device_next/usbd_desc.c index 2e8cb1c99aa7a82..825d1b910a0a6d7 100644 --- a/subsys/usb/device_next/usbd_desc.c +++ b/subsys/usb/device_next/usbd_desc.c @@ -68,7 +68,7 @@ static void usbd_ascii7_to_utf16le(struct usbd_desc_node *const dn) /** * @brief Get common USB descriptor * - * Get descriptor from internal descrptor list. + * Get descriptor from internal descriptor list. * * @param[in] dn Pointer to descriptor node * diff --git a/subsys/usb/device_next/usbd_desc.h b/subsys/usb/device_next/usbd_desc.h index ab796ef3f90febc..0b3702206d24422 100644 --- a/subsys/usb/device_next/usbd_desc.h +++ b/subsys/usb/device_next/usbd_desc.h @@ -12,7 +12,7 @@ /** * @brief Get common USB descriptor * - * Get descriptor from internal descrptor list. + * Get descriptor from internal descriptor list. * * @param[in] ctx Pointer to USB device support context * @param[in] type Descriptor type (bDescriptorType) diff --git a/subsys/usb/host/usbh_core.c b/subsys/usb/host/usbh_core.c index efbf3a84985d11c..a6aa968bb622420 100644 --- a/subsys/usb/host/usbh_core.c +++ b/subsys/usb/host/usbh_core.c @@ -72,7 +72,7 @@ static int ALWAYS_INLINE usbh_event_handler(struct usbh_contex *const ctx, } break; case UHC_EVT_RESETED: - LOG_DBG("Bus reseted"); + LOG_DBG("Bus reset"); /* TODO */ if (class_data && class_data->removed) { ret = class_data->removed(ctx); diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index 48262c94331486b..3f331ab543cbb72 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -510,7 +510,7 @@ static int cmd_bus_reset(const struct shell *sh, if (err) { shell_error(sh, "host: Failed to perform bus reset %d", err); } else { - shell_print(sh, "host: USB bus reseted"); + shell_print(sh, "host: USB bus reset"); } err = uhc_sof_enable(uhs_ctx.dev); diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index 986e82e90d341bb..dee7d5be5178562 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -39,6 +39,8 @@ struct btp_gap_read_controller_index_list_rp { #define BTP_GAP_SETTINGS_PRIVACY 13 #define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 #define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 +#define BTP_GAP_SETTINGS_SC_ONLY 16 +#define BTP_GAP_SETTINGS_EXTENDED_ADVERTISING 17 #define BTP_GAP_READ_CONTROLLER_INFO 0x03 struct btp_gap_read_controller_info_rp { @@ -234,6 +236,19 @@ struct btp_gap_set_filter_list { bt_addr_le_t addr[0]; } __packed; +#define BTP_GAP_SET_PRIVACY 0x1d +#define BTP_GAP_SET_SC_ONLY 0x1e +#define BTP_GAP_SET_SC 0x1f +#define BTP_GAP_SET_MIN_ENC_KEY_SIZE 0x20 + +#define BTP_GAP_SET_EXTENDED_ADVERTISING 0x21 +struct btp_gap_set_extended_advertising_cmd { + uint8_t settings; +} __packed; +struct btp_gap_set_extended_advertising_rp { + uint32_t current_settings; +} __packed; + /* events */ #define BTP_GAP_EV_NEW_SETTINGS 0x80 struct btp_gap_new_settings_ev { diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 3fc01e371f65c40..48b961e6375cf64 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -32,6 +32,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #define BT_LE_AD_DISCOV_MASK (BT_LE_AD_LIMITED | BT_LE_AD_GENERAL) #define ADV_BUF_LEN (sizeof(struct btp_gap_device_found_ev) + 2 * 31) +#if defined(CONFIG_BT_EXT_ADV) +static struct bt_le_ext_adv *ext_adv; +#endif + static atomic_t current_settings; struct bt_conn_auth_cb cb; static uint8_t oob_legacy_tk[16] = { 0 }; @@ -254,6 +258,9 @@ static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */ tester_set_bit(rp->data, BTP_GAP_SET_MITM); tester_set_bit(rp->data, BTP_GAP_SET_FILTER_LIST); +#if defined(CONFIG_BT_EXT_ADV) + tester_set_bit(rp->data, BTP_GAP_SET_EXTENDED_ADVERTISING); +#endif *rsp_len = sizeof(*rp) + 4; @@ -306,6 +313,7 @@ static uint8_t controller_info(const void *cmd, uint16_t cmd_len, supported_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE); supported_settings |= BIT(BTP_GAP_SETTINGS_LE); supported_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); + supported_settings |= BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); rp->supported_settings = sys_cpu_to_le32(supported_settings); rp->current_settings = sys_cpu_to_le32(current_settings); @@ -533,6 +541,7 @@ static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, uint32_t duration; uint8_t adv_len; uint8_t sd_len; + int err; int i; /* This command is very unfortunate since after variable data there is @@ -600,8 +609,38 @@ static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } + if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) { +#if defined(CONFIG_BT_EXT_ADV) + param.options |= BT_LE_ADV_OPT_EXT_ADV; + if (ext_adv != NULL) { + err = bt_le_ext_adv_delete(ext_adv); + if (err) { + return BTP_STATUS_FAILED; + } + + ext_adv = NULL; + } + + err = bt_le_ext_adv_create(¶m, NULL, &ext_adv); + if (err) { + return BTP_STATUS_FAILED; + } + + err = bt_le_ext_adv_set_data(ext_adv, ad, adv_len, sd_len ? sd : NULL, sd_len); + if (err) { + return BTP_STATUS_FAILED; + } + + err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT); +#else + return BTP_STATUS_FAILED; +#endif + } else { + err = bt_le_adv_start(¶m, ad, adv_len, sd_len ? sd : NULL, sd_len); + } + /* BTP API don't allow to set empty scan response data. */ - if (bt_le_adv_start(¶m, ad, adv_len, sd_len ? sd : NULL, sd_len) < 0) { + if (err < 0) { LOG_ERR("Failed to start advertising"); return BTP_STATUS_FAILED; } @@ -1212,6 +1251,28 @@ static uint8_t set_filter_list(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t set_extended_advertising(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gap_set_extended_advertising_cmd *cp = cmd; + struct btp_gap_set_extended_advertising_rp *rp = rsp; + + LOG_DBG("ext adv settings: %u", cp->settings); + + if (cp->settings != 0) { + atomic_set_bit(¤t_settings, + BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + } else { + atomic_clear_bit(¤t_settings, + BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + } + + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); + return BTP_STATUS_SUCCESS; +} + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -1337,6 +1398,13 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_list, }, +#if defined(CONFIG_BT_EXT_ADV) + { + .opcode = BTP_GAP_SET_EXTENDED_ADVERTISING, + .expect_len = sizeof(struct btp_gap_set_extended_advertising_cmd), + .func = set_extended_advertising, + }, +#endif }; uint8_t tester_init_gap(void) diff --git a/tests/boards/espressif_esp32/cache_coex/README.rst b/tests/boards/espressif_esp32/cache_coex/README.rst index 00a6877841d8171..12bd79143ffc3c8 100644 --- a/tests/boards/espressif_esp32/cache_coex/README.rst +++ b/tests/boards/espressif_esp32/cache_coex/README.rst @@ -12,32 +12,44 @@ with a random generated pattern. At the same time, a whole SPI Flash page is upd value. By the end of the thread iterations, both PSRAM and SPI Flash have its contents compared against expected values to check for integrity. +Supported Boards +**************** +- esp32_devkitc_wrover +- esp32s2_saola +- esp32s3_devkitm + Building and Running ******************** -Make sure you have the ESP32 DevKitC connected over USB port. +Make sure you have the target connected over USB port. .. code-block:: console - west build -b esp32_devkitc_wrover tests/boards/espressif_esp32/cache_coex - west flash --esp-device /dev/ttyUSB0 + west build -b tests/boards/espressif_esp32/cache_coex + west flash && west espressif monitor Sample Output ============= -To check output of this test, any serial console program can be used (i.e. on Linux picocom, putty, screen, etc). -This test uses ``minicom`` on the serial port ``/dev/ttyUS0``. The following lines indicate a successful test: - .. code-block:: console - Running test suite cache_coex_test - =================================================================== - START - flash_integrity_test - PASS - flash_integrity_test in 0.1 seconds - =================================================================== - START - ram_integrity_test - PASS - ram_integrity_test in 0.1 seconds - =================================================================== - Test suite cache_coex_test succeeded - =================================================================== - PROJECT EXECUTION SUCCESSFUL + Running TESTSUITE cache_coex + =================================================================== + START - test_flash_integrity + PASS - test_flash_integrity in 0.001 seconds + =================================================================== + START - test_ram_integrity + PASS - test_ram_integrity in 0.001 seconds + =================================================================== + START - test_using_spiram + PASS - test_using_spiram in 0.001 seconds + =================================================================== + TESTSUITE cache_coex succeeded + ------ TESTSUITE SUMMARY START ------ + SUITE PASS - 100.00% [cache_coex]: pass = 3, fail = 0, skip = 0, total = 3 duration = 0.003 seconds + - PASS - [cache_coex.test_flash_integrity] duration = 0.001 seconds + - PASS - [cache_coex.test_ram_integrity] duration = 0.001 seconds + - PASS - [cache_coex.test_using_spiram] duration = 0.001 seconds + ------ TESTSUITE SUMMARY END ------ + =================================================================== + PROJECT EXECUTION SUCCESSFUL diff --git a/tests/boards/espressif_esp32/cache_coex/testcase.yaml b/tests/boards/espressif_esp32/cache_coex/testcase.yaml index 9de6d546a4b3976..063d4e9fb3b0e42 100644 --- a/tests/boards/espressif_esp32/cache_coex/testcase.yaml +++ b/tests/boards/espressif_esp32/cache_coex/testcase.yaml @@ -1,6 +1,9 @@ tests: boards.esp32.cache_coex: - platform_allow: esp32_devkitc_wrover esp32s2_saola + platform_allow: + - esp32_devkitc_wrover + - esp32s2_saola + - esp32s3_devkitm tags: - spiram - spiflash diff --git a/tests/bsim/bluetooth/ll/bis/src/main.c b/tests/bsim/bluetooth/ll/bis/src/main.c index 7b8a0b4338f946d..23d9db61c2e51e5 100644 --- a/tests/bsim/bluetooth/ll/bis/src/main.c +++ b/tests/bsim/bluetooth/ll/bis/src/main.c @@ -58,6 +58,7 @@ static const struct bt_data per_ad_data2[] = { static uint8_t chan_map[] = { 0x1F, 0XF1, 0x1F, 0xF1, 0x1F }; static bool volatile is_iso_connected; +static uint8_t volatile is_iso_disconnected; static bool volatile deleting_pa_sync; static void iso_connected(struct bt_iso_chan *chan); static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason); @@ -147,23 +148,12 @@ bool ll_data_path_sink_create(uint16_t handle, struct ll_iso_datapath *datapath, } #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */ -static void test_iso_main(void) +static void setup_ext_adv(struct bt_le_ext_adv **adv) { - struct bt_le_ext_adv *adv; int err; - printk("\n*ISO broadcast test*\n"); - - printk("Bluetooth initializing..."); - err = bt_enable(NULL); - if (err) { - FAIL("Could not init BT: %d\n", err); - return; - } - printk("success.\n"); - printk("Create advertising set..."); - err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, &adv); + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, adv); if (err) { FAIL("Failed to create advertising set (err %d)\n", err); return; @@ -171,7 +161,7 @@ static void test_iso_main(void) printk("success.\n"); printk("Setting Periodic Advertising parameters..."); - err = bt_le_per_adv_set_param(adv, BT_LE_PER_ADV_DEFAULT); + err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_DEFAULT); if (err) { FAIL("Failed to set periodic advertising parameters (err %d)\n", err); @@ -180,7 +170,7 @@ static void test_iso_main(void) printk("success.\n"); printk("Enable Periodic Advertising..."); - err = bt_le_per_adv_start(adv); + err = bt_le_per_adv_start(*adv); if (err) { FAIL("Failed to enable periodic advertising (err %d)\n", err); return; @@ -188,29 +178,60 @@ static void test_iso_main(void) printk("success.\n"); printk("Start extended advertising..."); - err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + err = bt_le_ext_adv_start(*adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); return; } printk("success.\n"); +} +static void teardown_ext_adv(struct bt_le_ext_adv *adv) +{ + int err; + + printk("Stop Periodic Advertising..."); + err = bt_le_per_adv_stop(adv); + if (err) { + FAIL("Failed to stop periodic advertising (err %d)\n", err); + return; + } + printk("success.\n"); + + printk("Stop Extended Advertising..."); + err = bt_le_ext_adv_stop(adv); + if (err) { + FAIL("Failed to stop extended advertising (err %d)\n", err); + return; + } + printk("success.\n"); + + printk("Deleting Extended Advertising..."); + err = bt_le_ext_adv_delete(adv); + if (err) { + FAIL("Failed to delete extended advertising (err %d)\n", err); + return; + } + printk("success.\n"); +} #if TEST_LL_INTERFACE - printk("Creating BIG..."); +static void create_ll_big(uint8_t big_handle, struct bt_le_ext_adv *adv) +{ uint16_t max_sdu = CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX; uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE] = { 0 }; uint32_t sdu_interval = 10000; /* us */ uint16_t max_latency = 10; /* ms */ uint8_t encryption = 0; - uint8_t big_handle = 0; uint8_t bis_count = 1; /* TODO: Add support for multiple BIS per BIG */ uint8_t phy = BIT(1); uint8_t packing = 0; uint8_t framing = 0; uint8_t adv_handle; uint8_t rtn = 0; + int err; + printk("Creating LL BIG..."); /* Assume that index == handle */ adv_handle = bt_le_ext_adv_get_index(adv); @@ -222,12 +243,28 @@ static void test_iso_main(void) return; } printk("success.\n"); -#endif +} - printk("Creating BIG...\n"); - struct bt_iso_big_create_param big_create_param; - struct bt_iso_big *big; +static void terminate_ll_big(uint8_t big_handle) +{ + int err; + + printk("Terminating LL BIG..."); + err = ll_big_terminate(big_handle, BT_HCI_ERR_LOCALHOST_TERM_CONN); + if (err) { + FAIL("Could not terminate BIG: %d\n", err); + return; + } + printk("success.\n"); +} +#endif /* TEST_LL_INTERFACE */ + +static void create_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big) +{ + struct bt_iso_big_create_param big_create_param = { 0 }; + int err; + printk("Creating BIG...\n"); big_create_param.bis_channels = bis_channels; big_create_param.num_bis = BIS_ISO_CHAN_COUNT; big_create_param.encryption = false; @@ -240,7 +277,47 @@ static void test_iso_main(void) iso_tx_qos.phy = BT_GAP_LE_PHY_2M; bis_iso_qos.tx = &iso_tx_qos; bis_iso_qos.rx = NULL; - err = bt_iso_big_create(adv, &big_create_param, &big); + err = bt_iso_big_create(adv, &big_create_param, big); + if (err) { + FAIL("Could not create BIG: %d\n", err); + return; + } + printk("success.\n"); + + printk("Wait for ISO connected callback..."); + while (!is_iso_connected) { + k_sleep(K_MSEC(100)); + } + printk("ISO connected\n"); +} + +#if defined(CONFIG_BT_ISO_ADVANCED) +static void create_advanced_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big) +{ + struct bt_iso_big_create_param big_create_param; + int err; + + printk("Creating BIG...\n"); + big_create_param.bis_channels = bis_channels; + big_create_param.num_bis = BIS_ISO_CHAN_COUNT; + big_create_param.encryption = false; + big_create_param.interval = 10000; /* us */ + big_create_param.packing = 0; /* 0 - sequential; 1 - interleaved */ + big_create_param.framing = 0; /* 0 - unframed; 1 - framed */ + big_create_param.irc = BT_ISO_IRC_MIN; + big_create_param.pto = BT_ISO_PTO_MIN; + big_create_param.iso_interval = big_create_param.interval / 1250U; /* N * 10 ms */ + + iso_tx_qos.sdu = 502; /* bytes */ + iso_tx_qos.phy = BT_GAP_LE_PHY_2M; + iso_tx_qos.max_pdu = BT_ISO_PDU_MAX; + iso_tx_qos.burst_number = BT_ISO_BN_MIN; + + bis_iso_qos.tx = &iso_tx_qos; + bis_iso_qos.rx = NULL; + bis_iso_qos.num_subevents = BT_ISO_NSE_MIN; + + err = bt_iso_big_create(adv, &big_create_param, big); if (err) { FAIL("Could not create BIG: %d\n", err); return; @@ -252,10 +329,34 @@ static void test_iso_main(void) k_sleep(K_MSEC(100)); } printk("ISO connected\n"); +} +#endif /* CONFIG_BT_ISO_ADVANCED */ +static void terminate_big(struct bt_iso_big *big) +{ + int err; + + printk("Terminating BIG...\n"); + err = bt_iso_big_terminate(big); + if (err) { + FAIL("Could not terminate BIG: %d\n", err); + return; + } + printk("success.\n"); + + printk("Wait for ISO disconnected callback..."); + while (is_iso_disconnected == 0U) { + k_sleep(K_MSEC(100)); + } + printk("ISO disconnected\n"); +} + +static void send_iso_data(void) +{ uint32_t iso_send_count = 0; uint8_t iso_data[sizeof(iso_send_count)] = { 0 }; struct net_buf *buf; + int err; buf = net_buf_alloc(&bis_tx_pool, K_FOREVER); net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); @@ -268,6 +369,35 @@ static void test_iso_main(void) return; } printk("Sending value %u\n", iso_send_count); +} + +static void test_iso_main(void) +{ + struct bt_le_ext_adv *adv; + struct bt_iso_big *big; + int err; + + printk("\n*ISO broadcast test*\n"); + + printk("Bluetooth initializing..."); + err = bt_enable(NULL); + if (err) { + FAIL("Could not init BT: %d\n", err); + return; + } + printk("success.\n"); + + setup_ext_adv(&adv); + +#if TEST_LL_INTERFACE + uint8_t big_handle = 0; + + create_ll_big(big_handle, adv); +#endif + + create_big(adv, &big); + + send_iso_data(); k_sleep(K_MSEC(5000)); @@ -303,33 +433,26 @@ static void test_iso_main(void) k_sleep(K_MSEC(5000)); #if TEST_LL_INTERFACE - printk("Terminating BIG..."); - err = ll_big_terminate(big_handle, BT_HCI_ERR_LOCALHOST_TERM_CONN); - if (err) { - FAIL("Could not terminate BIG: %d\n", err); - return; - } - printk("success.\n"); + terminate_ll_big(big_handle); #endif - printk("Terminating BIG...\n"); - err = bt_iso_big_terminate(big); - if (err) { - FAIL("Could not terminate BIG: %d\n", err); - return; - } - printk("success.\n"); + terminate_big(big); + big = NULL; - k_sleep(K_MSEC(10000)); +#if defined(CONFIG_BT_ISO_ADVANCED) + /* Quick check to just verify that creating a BIG using advanced/test + * parameters work + */ + create_advanced_big(adv, &big); - printk("Stop Periodic Advertising..."); - err = bt_le_per_adv_stop(adv); - if (err) { - FAIL("Failed to stop periodic advertising (err %d)\n", err); - return; - } - printk("success.\n"); + terminate_big(big); + big = NULL; +#endif /* CONFIG_BT_ISO_ADVANCED */ + k_sleep(K_MSEC(10000)); + + teardown_ext_adv(adv); + adv = NULL; PASS("ISO tests Passed\n"); @@ -362,8 +485,6 @@ static void iso_connected(struct bt_iso_chan *chan) is_iso_connected = true; } -static uint8_t volatile is_iso_disconnected; - static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) { printk("ISO Channel %p disconnected with reason 0x%02x\n", chan, reason); diff --git a/tests/drivers/adc/adc_api/boards/mr_canhubk3.overlay b/tests/drivers/adc/adc_api/boards/mr_canhubk3.overlay new file mode 100644 index 000000000000000..0e1443dec89c9cc --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/mr_canhubk3.overlay @@ -0,0 +1,36 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 22>, <&adc0 23>; + }; +}; + +&adc0 { + group-channel = "standard"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@16 { + reg = <22>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; + + channel@17 { + reg = <23>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <14>; + }; +}; diff --git a/tests/drivers/build_all/sensor/CMakeLists.txt b/tests/drivers/build_all/sensor/CMakeLists.txt index 518596a02f7800b..459749709aef629 100644 --- a/tests/drivers/build_all/sensor/CMakeLists.txt +++ b/tests/drivers/build_all/sensor/CMakeLists.txt @@ -4,5 +4,6 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(build_all) -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) +# Exclude main when running the generic test because ztest supplies its own +target_sources_ifndef(CONFIG_GENERIC_SENSOR_TEST app PRIVATE src/main.c) +target_sources_ifdef(CONFIG_GENERIC_SENSOR_TEST app PRIVATE src/generic_test.c) diff --git a/tests/drivers/build_all/sensor/Kconfig b/tests/drivers/build_all/sensor/Kconfig new file mode 100644 index 000000000000000..10730a1f50b897b --- /dev/null +++ b/tests/drivers/build_all/sensor/Kconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config GENERIC_SENSOR_TEST + bool "Compile and run the generic sensor tests" + depends on ZTEST && ZTEST_NEW_API + help + Enables building and running the generic sensor test suite that will + iterate through the device tree and run sample path tests on any + sensor that supports the backend sensor emulator API. + +config GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS + int "Number of expected values to use in test" + default 5 + depends on GENERIC_SENSOR_TEST + help + Controls the number of expected values to use in the generic sensor + test, interpolated from the sensor's reported lower and upper sample + range boundaries. The test will run one iteration for each expected + value. For example, if GENERIC_TEST_NUM_EXPECTED_VALS == 5, and the + sensor range is 0..100, the test will run 5 times with expected values + 0, 25, 50, 75, and 100. These iterations are run in parallel. + +source "Kconfig.zephyr" diff --git a/tests/drivers/build_all/sensor/src/generic_test.c b/tests/drivers/build_all/sensor/src/generic_test.c new file mode 100644 index 000000000000000..0df8b953da997db --- /dev/null +++ b/tests/drivers/build_all/sensor/src/generic_test.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(generic_test); + +/* + * Set up an RTIO context that can be shared for all sensors + */ + +static enum sensor_channel iodev_all_channels[SENSOR_CHAN_ALL]; +static struct sensor_read_config iodev_read_config = { + .channels = iodev_all_channels, + .max = SENSOR_CHAN_ALL, +}; +RTIO_IODEV_DEFINE(iodev_read, &__sensor_iodev_api, &iodev_read_config); + +/* Create the RTIO context to service the reading */ +RTIO_DEFINE_WITH_MEMPOOL(sensor_read_rtio_ctx, 1, 1, 1, 64, 4); + +/** + * @brief Prepare the RTIO context for next test + */ +static void before(void *args) +{ + ARG_UNUSED(args); + + /* Clear the array of requested channels */ + memset(iodev_all_channels, 0, sizeof(iodev_all_channels)); + + /* Reset the channel count */ + iodev_read_config.count = 0; + + /* Remove previous sensor pointer */ + iodev_read_config.sensor = NULL; + + /* Wipe the mempool by marking every block free */ + zassert_ok(sys_bitarray_clear_region(sensor_read_rtio_ctx_block_pool.mempool->bitmap, + sensor_read_rtio_ctx_block_pool.mempool->num_blocks, + 0)); + + /* Flush the SQ and CQ */ + rtio_sqe_drop_all(&sensor_read_rtio_ctx); + while (rtio_cqe_consume(&sensor_read_rtio_ctx)) + ; +} + +/** + * @brief Helper function the carries out the generic sensor test for a given sensor device. + * Verifies that the device has a suitable emulator that implements the backend API and + * skips the test gracefully if not. + */ +static void run_generic_test(const struct device *dev) +{ + zassert_not_null(dev, "Cannot get device pointer. Is this driver properly instantiated?"); + + const struct emul *emul = emul_get_binding(dev->name); + + /* Skip this sensor if there is no emulator loaded. */ + if (!emul) { + ztest_test_skip(); + } + + /* Also skip if this emulator does not implement the backend API. */ + if (!emul_sensor_backend_is_supported(emul)) { + ztest_test_skip(); + } + + /* + * Begin the actual test sequence + */ + + static struct { + bool supported; + bool received; + q31_t expected_values[CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS]; + q31_t epsilon; + int8_t expected_value_shift; + } channel_table[SENSOR_CHAN_ALL]; + + memset(channel_table, 0, sizeof(channel_table)); + + /* Discover supported channels on this device and fill out our sensor read request */ + for (enum sensor_channel ch = 0; ch < ARRAY_SIZE(channel_table); ch++) { + if (SENSOR_CHANNEL_3_AXIS(ch)) { + continue; + } + + q31_t lower, upper; + int8_t shift; + + if (emul_sensor_backend_get_sample_range(emul, ch, &lower, &upper, + &channel_table[ch].epsilon, &shift) == 0) { + /* This channel is supported */ + channel_table[ch].supported = true; + + LOG_INF("CH %d: lower=%d, upper=%d, eps=%d, shift=%d", ch, lower, upper, + channel_table[ch].epsilon, shift); + + /* Add to the list of channels to read */ + iodev_all_channels[iodev_read_config.count++] = ch; + + /* Generate a set of CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS test + * values. + */ + + channel_table[ch].expected_value_shift = shift; + for (size_t i = 0; i < CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS; i++) { + channel_table[ch].expected_values[i] = + lower + + (i * ((int64_t)upper - lower) / + (CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS - 1)); + LOG_INF("CH %d: Expected value %d/%d: %d", ch, i + 1, + CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS, + channel_table[ch].expected_values[i]); + } + } + } + iodev_read_config.sensor = dev; + + /* Do a read of all channels for quantity CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS + * iterations. + */ + + for (size_t iteration = 0; iteration < CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS; + iteration++) { + int rv; + + /* Reset received flag */ + for (size_t i = 0; i < ARRAY_SIZE(channel_table); i++) { + channel_table[i].received = false; + } + + /* Set this iteration's expected values in emul for every supported channel */ + for (size_t i = 0; i < iodev_read_config.count; i++) { + enum sensor_channel ch = iodev_all_channels[i]; + + rv = emul_sensor_backend_set_channel( + emul, ch, channel_table[ch].expected_values[iteration], + channel_table[ch].expected_value_shift); + zassert_ok( + rv, + "Cannot set value 0x%08x on channel %d (error %d, iteration %d/%d)", + channel_table[i].expected_values[iteration], ch, rv, iteration + 1, + CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS); + } + + /* Perform the actual sensor read */ + rv = sensor_read(&iodev_read, &sensor_read_rtio_ctx, NULL); + zassert_ok(rv, "Could not read sensor (error %d, iteration %d/%d)", rv, + iteration + 1, CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS); + + /* Wait for a CQE */ + struct rtio_cqe *cqe = rtio_cqe_consume_block(&sensor_read_rtio_ctx); + + zassert_ok(cqe->result, "CQE has failed status (error %d, iteration %d/%d)", + cqe->result, iteration + 1, + CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS); + + uint8_t *buf = NULL; + uint32_t buf_len = 0; + + /* Cache the data from the CQE */ + rtio_cqe_get_mempool_buffer(&sensor_read_rtio_ctx, cqe, &buf, &buf_len); + + /* Release the CQE */ + rtio_cqe_release(&sensor_read_rtio_ctx, cqe); + + enum sensor_channel channel; + sensor_frame_iterator_t fit = {0}; + sensor_channel_iterator_t cit = {0}; + const struct sensor_decoder_api *decoder; + int8_t shift; + q31_t q; + + zassert_ok(sensor_get_decoder(dev, &decoder)); + + /* Decode the buffer and verify all channels */ + while (decoder->decode(buf, &fit, &cit, &channel, &q, 1) > 0) { + zassert_true(channel_table[channel].supported); + zassert_false(channel_table[channel].received); + channel_table[channel].received = true; + + zassert_ok(decoder->get_shift(buf, channel, &shift)); + + /* Align everything to be a 64-bit Q32.32 number for comparison */ + int64_t expected_shifted = + (int64_t)channel_table[channel].expected_values[iteration] + << channel_table[channel].expected_value_shift; + int64_t actual_shifted = (int64_t)q << shift; + int64_t epsilon_shifted = (int64_t)channel_table[channel].epsilon + << channel_table[channel].expected_value_shift; + + zassert_within(expected_shifted, actual_shifted, epsilon_shifted, + "Expected %lld, got %lld (shift %d, ch %d, iteration %d/%d, " + "Error %lld, Epsilon %lld)", + expected_shifted, actual_shifted, shift, channel, + iteration + 1, CONFIG_GENERIC_SENSOR_TEST_NUM_EXPECTED_VALS, + expected_shifted - actual_shifted, epsilon_shifted); + } + + /* Release the memory */ + rtio_release_buffer(&sensor_read_rtio_ctx, buf, buf_len); + + /* Ensure all supported channels were received */ + int missing_channel_count = 0; + + for (size_t i = 0; i < ARRAY_SIZE(channel_table); i++) { + if (channel_table[i].supported && !channel_table[i].received) { + missing_channel_count++; + } + } + + zassert_equal(0, missing_channel_count); + } +} + +#define DECLARE_ZTEST_PER_DEVICE(n) \ + ZTEST(generic, test_##n) \ + { \ + run_generic_test(DEVICE_DT_GET(n)); \ + } + +/* Iterate through each of the emulated buses and create a test for each device. */ +DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(test_i2c), DECLARE_ZTEST_PER_DEVICE) +DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(test_spi), DECLARE_ZTEST_PER_DEVICE) + +ZTEST_SUITE(generic, NULL, NULL, before, NULL, NULL); diff --git a/tests/drivers/build_all/sensor/testcase.yaml b/tests/drivers/build_all/sensor/testcase.yaml index e94945e3cebdb9c..ef07b4a5886a1eb 100644 --- a/tests/drivers/build_all/sensor/testcase.yaml +++ b/tests/drivers/build_all/sensor/testcase.yaml @@ -19,3 +19,11 @@ tests: extra_configs: - CONFIG_PM=y - CONFIG_PM_DEVICE=y + sensors.generic_test: + extra_configs: + - CONFIG_GENERIC_SENSOR_TEST=y + - CONFIG_ZTEST=y + - CONFIG_ZTEST_NEW_API=y + - CONFIG_EMUL=y + - CONFIG_NATIVE_UART_0_ON_STDINOUT=y + - CONFIG_SENSOR_ASYNC_API=y diff --git a/tests/drivers/build_all/sensor/uart.dtsi b/tests/drivers/build_all/sensor/uart.dtsi index 2982e6ea116a16a..9d63ee3555fe0f5 100644 --- a/tests/drivers/build_all/sensor/uart.dtsi +++ b/tests/drivers/build_all/sensor/uart.dtsi @@ -26,3 +26,7 @@ test_uart_grow_r502a { int-gpios = <&test_gpio 0 0>; }; }; + +test_uart_a01nyub { + compatible = "dfrobot,a01nyub"; +}; diff --git a/tests/drivers/eeprom/api/boards/mr_canhubk3.overlay b/tests/drivers/eeprom/api/boards/mr_canhubk3.overlay new file mode 100644 index 000000000000000..f63d3498b12d41d --- /dev/null +++ b/tests/drivers/eeprom/api/boards/mr_canhubk3.overlay @@ -0,0 +1,25 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Connect I2C0 (connector P4) to the external eeprom Microchip AT24C01C-XHM */ + +/ { + aliases { + eeprom-0 = &eeprom0; + }; +}; + +&lpi2c0 { + status = "okay"; + eeprom0: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <128>; + pagesize = <8>; + address-width = <8>; + timeout = <5>; + }; +}; diff --git a/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt b/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt index 9aaf0d0cd938e65..151d3bf8ce9db61 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt +++ b/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt @@ -5,4 +5,6 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(device) FILE(GLOB app_sources src/test_sbs_gauge.c) + +target_include_directories(app PRIVATE include) target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/fuel_gauge/sbs_gauge/include/test_sbs_gauge.h b/tests/drivers/fuel_gauge/sbs_gauge/include/test_sbs_gauge.h new file mode 100644 index 000000000000000..e7c3adab57acca2 --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/include/test_sbs_gauge.h @@ -0,0 +1,14 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +struct sbs_gauge_new_api_fixture { + const struct device *dev; + const struct emul *sbs_fuel_gauge; + const struct fuel_gauge_driver_api *api; +}; diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c index 5a67149181d3e12..2e5cea196095a2c 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_sbs_gauge.c @@ -16,11 +16,7 @@ #include #include -struct sbs_gauge_new_api_fixture { - const struct device *dev; - const struct emul *sbs_fuel_gauge; - const struct fuel_gauge_driver_api *api; -}; +#include "test_sbs_gauge.h" static void *sbs_gauge_new_api_setup(void) { diff --git a/tests/drivers/i2c/i2c_target_api/boards/mr_canhubk3.overlay b/tests/drivers/i2c/i2c_target_api/boards/mr_canhubk3.overlay new file mode 100644 index 000000000000000..9bf7ca16907da91 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/mr_canhubk3.overlay @@ -0,0 +1,25 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Connect P3.2 <-> P4.3 and P3.3 <-> P4.4 */ + +&lpi2c0 { + status = "okay"; + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <1024>; + }; +}; + +&lpi2c1 { + status = "okay"; + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <1024>; + }; +}; diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index 0ffc34a780733cf..bd7b34e0319528a 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -20,6 +20,7 @@ tests: - nucleo_l073rz - rpi_pico - efr32bg22_brd4184a + - mr_canhubk3 integration_platforms: - nucleo_f091rc extra_configs: diff --git a/tests/drivers/sensor/akm09918c/src/main.c b/tests/drivers/sensor/akm09918c/src/main.c index 132e450f13601b4..580bf64b761f126 100644 --- a/tests/drivers/sensor/akm09918c/src/main.c +++ b/tests/drivers/sensor/akm09918c/src/main.c @@ -10,6 +10,7 @@ #include #include +#include "akm09918c.h" #include "akm09918c_emul.h" #include "akm09918c_reg.h" @@ -72,19 +73,19 @@ static void test_fetch_magnetic_field(const struct akm09918c_fixture *fixture, /* Assert the data is within 0.000005 Gauss */ actual_ugauss = values[0].val1 * INT64_C(1000000) + values[0].val2; - expect_ugauss = magn_percent[0] * INT64_C(500); + expect_ugauss = magn_percent[0] * AKM09918C_MICRO_GAUSS_PER_BIT; zassert_within(expect_ugauss, actual_ugauss, INT64_C(5), "(X) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss", expect_ugauss, actual_ugauss); actual_ugauss = values[1].val1 * INT64_C(1000000) + values[1].val2; - expect_ugauss = magn_percent[1] * INT64_C(500); + expect_ugauss = magn_percent[1] * AKM09918C_MICRO_GAUSS_PER_BIT; zassert_within(expect_ugauss, actual_ugauss, INT64_C(5), "(Y) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss", expect_ugauss, actual_ugauss); actual_ugauss = values[2].val1 * INT64_C(1000000) + values[2].val2; - expect_ugauss = magn_percent[2] * INT64_C(500); + expect_ugauss = magn_percent[2] * AKM09918C_MICRO_GAUSS_PER_BIT; zassert_within(expect_ugauss, actual_ugauss, INT64_C(5), "(Z) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss", expect_ugauss, actual_ugauss); @@ -94,9 +95,9 @@ ZTEST_F(akm09918c, test_fetch_magn) { /* Use (0.25, -0.33..., 0.91) as the factors */ const int16_t magn_percent[3] = { - INT16_C(32752) / INT16_C(4), - INT16_C(-32751) / INT16_C(3), - (int16_t)(INT16_C(32752) * INT32_C(91) / INT32_C(100)), + INT16_C(AKM09918C_MAGN_MAX_DATA_REG) / INT16_C(4), + INT16_C(AKM09918C_MAGN_MIN_DATA_REG) / INT16_C(3), + (int16_t)(INT16_C(AKM09918C_MAGN_MAX_DATA_REG) * INT32_C(91) / INT32_C(100)), }; test_fetch_magnetic_field(fixture, magn_percent); diff --git a/tests/kernel/mem_heap/shared_multi_heap/src/main.c b/tests/kernel/mem_heap/shared_multi_heap/src/main.c index c99264430bc3f38..d2169f9164a2c56 100644 --- a/tests/kernel/mem_heap/shared_multi_heap/src/main.c +++ b/tests/kernel/mem_heap/shared_multi_heap/src/main.c @@ -66,7 +66,7 @@ static struct region_map *get_region_map(void *v_addr) return NULL; } -static inline enum smh_reg_attr mpu_to_reg_attr(int mpu_attr) +static inline enum shared_multi_heap_attr mpu_to_reg_attr(int mpu_attr) { /* * All the memory regions defined in the DT with the MPU property `RAM` diff --git a/tests/lib/thrift/ThriftTest/overlay-tls.conf b/tests/lib/thrift/ThriftTest/overlay-tls.conf index 2930b1fdc45c8ec..b98beb610c33922 100644 --- a/tests/lib/thrift/ThriftTest/overlay-tls.conf +++ b/tests/lib/thrift/ThriftTest/overlay-tls.conf @@ -1,5 +1,21 @@ CONFIG_THRIFT_SSL_SOCKET=y +# Currenty, in Zephyr's MBedTLS IPPROTO_TLS_1_0 implementation, 2 sockets are +# needed for every connection. +# +# Additionally, upstream Apache Thrift uses socketpair for cancellation rather +# than eventfd, since the latter is not portable to some operating systems. +# +# 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_POSIX_MAX_FDS=15 + # TLS configuration CONFIG_MBEDTLS=y CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y diff --git a/tests/lib/thrift/ThriftTest/prj.conf b/tests/lib/thrift/ThriftTest/prj.conf index 35361bf9b72fe06..4d2b145b13c4c59 100755 --- a/tests/lib/thrift/ThriftTest/prj.conf +++ b/tests/lib/thrift/ThriftTest/prj.conf @@ -39,7 +39,19 @@ CONFIG_NET_BUF_TX_COUNT=20 CONFIG_NET_PKT_TX_COUNT=20 CONFIG_NET_BUF_RX_COUNT=20 CONFIG_NET_PKT_RX_COUNT=20 -CONFIG_POSIX_MAX_FDS=16 + +# 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_POSIX_MAX_FDS=6 # Network address config CONFIG_NET_IPV4=y diff --git a/tests/lib/thrift/ThriftTest/src/main.cpp b/tests/lib/thrift/ThriftTest/src/main.cpp index b8ac60480084ac8..b903f3c8a9b38b6 100644 --- a/tests/lib/thrift/ThriftTest/src/main.cpp +++ b/tests/lib/thrift/ThriftTest/src/main.cpp @@ -148,19 +148,18 @@ static void thrift_test_before(void *data) static void thrift_test_after(void *data) { ARG_UNUSED(data); - void *unused; context.server->stop(); - pthread_join(context.server_thread, &unused); - - context.server.reset(); - context.client.reset(); + pthread_join(context.server_thread, NULL); for (auto &fd : context.fds) { close(fd); fd = -1; } + + context.client.reset(); + context.server.reset(); } ZTEST_SUITE(thrift, NULL, thrift_test_setup, thrift_test_before, thrift_test_after, NULL); diff --git a/tests/net/socket/udp/src/main.c b/tests/net/socket/udp/src/main.c index da13de8ee099453..f1affe585274610 100644 --- a/tests/net/socket/udp/src/main.c +++ b/tests/net/socket/udp/src/main.c @@ -939,7 +939,7 @@ static struct net_linkaddr server_link_addr = { }; #define MY_IPV6_ADDR_ETH "2001:db8:100::1" #define PEER_IPV6_ADDR_ETH "2001:db8:100::2" -#define TEST_TXTIME 0xff112233445566ff +#define TEST_TXTIME INT64_MAX #define WAIT_TIME K_MSEC(250) static void eth_fake_iface_init(struct net_if *iface) @@ -958,7 +958,7 @@ static void eth_fake_iface_init(struct net_if *iface) static int eth_fake_send(const struct device *dev, struct net_pkt *pkt) { - uint64_t txtime; + net_time_t txtime; ARG_UNUSED(dev); ARG_UNUSED(pkt); @@ -967,7 +967,7 @@ static int eth_fake_send(const struct device *dev, struct net_pkt *pkt) return 0; } - txtime = net_pkt_txtime(pkt); + txtime = net_ptp_time_to_ns(net_pkt_timestamp(pkt)); if (txtime != TEST_TXTIME) { test_failed = true; } else { @@ -1032,7 +1032,7 @@ ZTEST_USER(net_socket_udp, test_18_v6_sendmsg_with_txtime) int rv; int client_sock; bool optval; - uint64_t txtime; + net_time_t txtime; struct sockaddr_in6 client_addr; struct msghdr msg; struct cmsghdr *cmsg; @@ -1066,7 +1066,7 @@ ZTEST_USER(net_socket_udp, test_18_v6_sendmsg_with_txtime) cmsg->cmsg_len = CMSG_LEN(sizeof(txtime)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_TXTIME; - *(uint64_t *)CMSG_DATA(cmsg) = txtime; + *(net_time_t *)CMSG_DATA(cmsg) = txtime; optval = true; rv = setsockopt(client_sock, SOL_SOCKET, SO_TXTIME, &optval, diff --git a/tests/posix/common/src/mqueue.c b/tests/posix/common/src/mqueue.c index 74c16da6bfd54ab..7d1ec257323d942 100644 --- a/tests/posix/common/src/mqueue.c +++ b/tests/posix/common/src/mqueue.c @@ -21,8 +21,18 @@ K_THREAD_STACK_ARRAY_DEFINE(stacks, N_THR, STACKSZ); char queue[16] = "server"; + char send_data[MESSAGE_SIZE] = "timed data send"; +/* + * For platforms that select CONFIG_KERNEL_COHERENCE, the receive buffer can + * not be on the stack as the k_msgq that underlies the mq_timedsend() will + * copy directly to the receiver's buffer when there is already a waiting + * receiver. + */ + +char rec_data[MESSAGE_SIZE]; + void *sender_thread(void *p1) { mqd_t mqd; @@ -44,7 +54,6 @@ void *sender_thread(void *p1) void *receiver_thread(void *p1) { mqd_t mqd; - char rec_data[MESSAGE_SIZE]; struct timespec curtime; mqd = mq_open(queue, O_RDONLY); diff --git a/tests/posix/common/src/pthread.c b/tests/posix/common/src/pthread.c index e88703bae40445f..f02570d70ef0efa 100644 --- a/tests/posix/common/src/pthread.c +++ b/tests/posix/common/src/pthread.c @@ -793,9 +793,12 @@ ZTEST(posix_apis, test_pthread_equal) zassert_false(pthread_equal(pthread_self(), (pthread_t)4242)); } +/* A 32-bit value to use between threads for validation */ +#define BIOS_FOOD 0xB105F00D + static void *fun(void *arg) { - *((uint32_t *)arg) = 0xB105F00D; + *((uint32_t *)arg) = BIOS_FOOD; return NULL; } @@ -810,5 +813,50 @@ ZTEST(posix_apis, test_pthread_dynamic_stacks) zassert_ok(pthread_create(&th, NULL, fun, &x)); zassert_ok(pthread_join(th, NULL)); - zassert_equal(0xB105F00D, x); + zassert_equal(BIOS_FOOD, x); +} + +static void *non_null_retval(void *arg) +{ + ARG_UNUSED(arg); + + return (void *)BIOS_FOOD; +} + +ZTEST(posix_apis, test_pthread_return_val) +{ + pthread_t pth; + void *ret = NULL; + pthread_attr_t attr; + + zassert_ok(pthread_attr_init(&attr)); + zassert_ok(pthread_attr_setstack(&attr, &stack_e[0][0], STACKS)); + + zassert_ok(pthread_create(&pth, &attr, non_null_retval, NULL)); + zassert_ok(pthread_join(pth, &ret)); + zassert_equal(ret, (void *)BIOS_FOOD); +} + +static void *detached(void *arg) +{ + ARG_UNUSED(arg); + + return NULL; +} + +ZTEST(posix_apis, test_pthread_join_detached) +{ + pthread_t pth; + pthread_attr_t attr; + + zassert_ok(pthread_attr_init(&attr)); + zassert_ok(pthread_attr_setstack(&attr, &stack_e[0][0], STACKS)); + + zassert_ok(pthread_create(&pth, &attr, detached, NULL)); + zassert_ok(pthread_detach(pth)); + /* note, this was required to be EINVAL previously but is now undefined behaviour */ + zassert_not_equal(0, pthread_join(pth, NULL)); + + /* need to allow this thread to be clean-up by the recycler */ + k_msleep(500); } diff --git a/tests/subsys/canbus/isotp/conformance/src/main.c b/tests/subsys/canbus/isotp/conformance/src/main.c index b72b2a6d8272c7b..1e4a0bca6a92871 100644 --- a/tests/subsys/canbus/isotp/conformance/src/main.c +++ b/tests/subsys/canbus/isotp/conformance/src/main.c @@ -15,6 +15,7 @@ #define DATA_SIZE_CF 7 #define DATA_SIZE_SF_EXT 6 #define DATA_SIZE_FF 6 +#define DATA_SIZE_FC 3 #define CAN_DL 8 #define DATA_SEND_LENGTH 272 #define SF_PCI_TYPE 0 @@ -38,13 +39,6 @@ #define STMIN_VAL_2 50 #define STMIN_UPPER_TOLERANCE 5 -#if defined(CONFIG_ISOTP_ENABLE_TX_PADDING) || \ - defined(CONFIG_ISOTP_ENABLE_TX_PADDING) -#define DATA_SIZE_FC CAN_DL -#else -#define DATA_SIZE_FC 3 -#endif - #define BS_TIMEOUT_UPPER_MS 1100 #define BS_TIMEOUT_LOWER_MS 1000 @@ -258,17 +252,12 @@ static void check_frame_series(struct frame_desired *frames, size_t length, zassert_equal(ret, 0, "Timeout waiting for msg nr %d. ret: %d", i, ret); -#if !defined(CONFIG_ISOTP_REQUIRE_RX_PADDING) && \ - !defined(CONFIG_ISOTP_ENABLE_TX_PADDING) zassert_equal(frame.dlc, desired->length, "DLC of frame nr %d differ. Desired: %d, Got: %d", i, desired->length, frame.dlc); -#endif -#if !defined(CONFIG_ISOTP_ENABLE_TX_PADDING) ret = check_data(frame.data, desired->data, desired->length); zassert_equal(ret, 0, "Data differ"); -#endif desired++; } @@ -293,8 +282,23 @@ static int add_rx_msgq(uint32_t id, uint32_t mask) return filter_id; } +static void prepare_fc_frame(struct frame_desired *frame, uint8_t st, + const struct isotp_fc_opts *opts, bool tx) +{ + frame->data[0] = FC_PCI_BYTE_1(st); + frame->data[1] = FC_PCI_BYTE_2(opts->bs); + frame->data[2] = FC_PCI_BYTE_3(opts->stmin); + if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) || + (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) { + memset(&frame->data[DATA_SIZE_FC], 0xCC, CAN_DL - DATA_SIZE_FC); + frame->length = CAN_DL; + } else { + frame->length = DATA_SIZE_FC; + } +} + static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, - const uint8_t *data, size_t data_len) + const uint8_t *data, size_t data_len, bool tx) { int i; const uint8_t *data_ptr = data; @@ -306,9 +310,13 @@ static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt, memcpy(&des_frames[i].data[1], data_ptr, DATA_SIZE_CF); if (remaining_length < DATA_SIZE_CF) { -#ifndef CONFIG_ISOTP_ENABLE_TX_PADDING - frames[i].length = remaining_length + 1; -#endif + if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) || + (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) { + memset(&des_frames[i].data[remaining_length + 1], 0xCC, + CAN_DL - remaining_length - 1); + } else { + frames[i].length = remaining_length + 1; + } remaining_length = 0; } @@ -494,13 +502,10 @@ ZTEST(isotp_conformance, test_send_data) data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(0); - fc_frame.data[2] = FC_PCI_BYTE_3(0); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, false); prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr, - remaining_length); + remaining_length, true); filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", @@ -533,13 +538,10 @@ ZTEST(isotp_conformance, test_send_data_blocks) data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs); - fc_frame.data[2] = FC_PCI_BYTE_3(0); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, false); prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr, - remaining_length); + remaining_length, true); remaining_length = DATA_SEND_LENGTH; @@ -597,13 +599,10 @@ ZTEST(isotp_conformance, test_receive_data) data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts_single.bs); - fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts_single.stmin); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, true); prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr, - remaining_length); + remaining_length, false); filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK); @@ -641,13 +640,10 @@ ZTEST(isotp_conformance, test_receive_data_blocks) data_ptr += DATA_SIZE_FF; remaining_length -= DATA_SIZE_FF; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs); - fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, true); prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr, - remaining_length); + remaining_length, false); remaining_frames = DIV_ROUND_UP(remaining_length, DATA_SIZE_CF); @@ -692,10 +688,7 @@ ZTEST(isotp_conformance, test_send_timeouts) uint32_t start_time, time_diff; struct frame_desired fc_cts_frame; - fc_cts_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_cts_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs); - fc_cts_frame.data[2] = FC_PCI_BYTE_3(0); - fc_cts_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_cts_frame, FC_PCI_CTS, &fc_opts, false); /* Test timeout for first FC*/ start_time = k_uptime_get_32(); @@ -787,6 +780,9 @@ ZTEST(isotp_conformance, test_stmin) struct frame_desired fc_frame, ff_frame; struct can_frame raw_frame; uint32_t start_time, time_diff; + struct isotp_fc_opts fc_opts_stmin = { + .bs = 2, .stmin = STMIN_VAL_1 + }; if (CONFIG_SYS_CLOCK_TICKS_PER_SEC < 1000) { /* This test requires millisecond tick resolution */ @@ -798,10 +794,7 @@ ZTEST(isotp_conformance, test_stmin) memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF); ff_frame.length = DATA_SIZE_FF + 2; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(2); - fc_frame.data[2] = FC_PCI_BYTE_3(STMIN_VAL_1); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_stmin, false); filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", @@ -853,10 +846,7 @@ ZTEST(isotp_conformance, test_receiver_fc_errors) memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF); ff_frame.length = DATA_SIZE_FF + 2; - fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS); - fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs); - fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, true); filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK); zassert_true((filter_id >= 0), "Negative filter number [%d]", @@ -871,7 +861,7 @@ ZTEST(isotp_conformance, test_receiver_fc_errors) check_frame_series(&fc_frame, 1, &frame_msgq); prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), random_data + DATA_SIZE_FF, - sizeof(random_data) - DATA_SIZE_FF); + sizeof(random_data) - DATA_SIZE_FF, false); /* SN should be 2 but is set to 3 for this test */ des_frames[1].data[0] = CF_PCI_BYTE_1 | (3 & 0x0F); send_frame_series(des_frames, fc_opts.bs, rx_addr.std_id); @@ -883,6 +873,22 @@ ZTEST(isotp_conformance, test_receiver_fc_errors) zassert_equal(ret, ISOTP_N_WRONG_SN, "Expected wrong SN but got %d", ret); + /* buffer overflow */ + ff_frame.data[0] = FF_PCI_BYTE_1(0xFFF); + ff_frame.data[1] = FF_PCI_BYTE_2(0xFFF); + + fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_OVFLW); + fc_frame.data[1] = FC_PCI_BYTE_2(0); + fc_frame.data[2] = FC_PCI_BYTE_3(0); + + isotp_unbind(&recv_ctx); + ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, + &fc_opts_single, K_NO_WAIT); + zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret); + + send_frame_series(&ff_frame, 1, rx_addr.std_id); + check_frame_series(&fc_frame, 1, &frame_msgq); + can_remove_rx_filter(can_dev, filter_id); k_msgq_cleanup(&frame_msgq); isotp_unbind(&recv_ctx); @@ -901,10 +907,7 @@ ZTEST(isotp_conformance, test_sender_fc_errors) filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK); /* invalid flow status */ - fc_frame.data[0] = FC_PCI_BYTE_1(3); - fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs); - fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin); - fc_frame.length = DATA_SIZE_FC; + prepare_fc_frame(&fc_frame, 3, &fc_opts, false); k_sem_reset(&send_compl_sem); ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH, @@ -918,18 +921,6 @@ ZTEST(isotp_conformance, test_sender_fc_errors) zassert_equal(ret, 0, "Send complete callback not called"); /* buffer overflow */ - can_remove_rx_filter(can_dev, filter_id); - ret = isotp_bind(&recv_ctx, can_dev, &tx_addr, &rx_addr, - &fc_opts_single, K_NO_WAIT); - zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret); - - ret = isotp_send(&send_ctx, can_dev, random_data, 5*1024, - &tx_addr, &rx_addr, NULL, NULL); - zassert_equal(ret, ISOTP_N_BUFFER_OVERFLW, - "Expected overflow but got %d", ret); - isotp_unbind(&recv_ctx); - filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK); - k_sem_reset(&send_compl_sem); ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH, &tx_addr, &rx_addr, send_complete_cb, diff --git a/tests/subsys/canbus/isotp/implementation/prj.conf b/tests/subsys/canbus/isotp/implementation/prj.conf index af7b76b9fc381d9..4ab0fe51d3816b7 100644 --- a/tests/subsys/canbus/isotp/implementation/prj.conf +++ b/tests/subsys/canbus/isotp/implementation/prj.conf @@ -7,3 +7,4 @@ CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y CONFIG_ISOTP_RX_BUF_COUNT=2 CONFIG_ISOTP_RX_BUF_SIZE=56 CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2 +CONFIG_ZTEST_THREAD_PRIORITY=0 diff --git a/tests/subsys/logging/log_api/src/main.c b/tests/subsys/logging/log_api/src/main.c index ddc8ccc2543856c..7c790531a60b66f 100644 --- a/tests/subsys/logging/log_api/src/main.c +++ b/tests/subsys/logging/log_api/src/main.c @@ -184,16 +184,16 @@ ZTEST(test_log_api, test_log_various_messages) LOG_DBG(TEST_MSG_0, ll, ull, i); #ifdef CONFIG_FPU - float f = -1.2356; + float f = -1.2356f; double d = -1.2356; - snprintk(str, sizeof(str), TEST_MSG_1, f, 100, d); + snprintk(str, sizeof(str), TEST_MSG_1, (double)f, 100, d); mock_log_frontend_record(LOG_CURRENT_MODULE_ID(), LOG_LEVEL_INF, str); mock_log_backend_record(&backend1, LOG_CURRENT_MODULE_ID(), Z_LOG_LOCAL_DOMAIN_ID, LOG_LEVEL_INF, exp_timestamp++, str); - LOG_INF(TEST_MSG_1, f, 100, d); + LOG_INF(TEST_MSG_1, (double)f, 100, d); #endif /* CONFIG_FPU */ snprintk(str, sizeof(str), "wrn %s", dstr); diff --git a/tests/subsys/mgmt/mcumgr/all_options/other-options.conf b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf new file mode 100644 index 000000000000000..36ade8751a3d78e --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR=y +CONFIG_MCUMGR_GRP_IMG_MUTEX=y +CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER=y +CONFIG_MCUMGR_GRP_IMG_DIRECT_UPLOAD=y +CONFIG_MCUMGR_GRP_IMG_REJECT_DIRECT_XIP_MISMATCHED_SLOT=y +CONFIG_MCUMGR_GRP_OS_TASKSTAT_STACK_INFO=y +CONFIG_MCUMGR_GRP_OS_INFO=y +CONFIG_MCUMGR_GRP_OS_INFO_CUSTOM_HOOKS=y +CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME=y +CONFIG_MCUMGR_GRP_SHELL_LEGACY_RC_RETURN_CODE=y +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2048 +CONFIG_MCUMGR_TRANSPORT_SHELL=n +CONFIG_MCUMGR_TRANSPORT_UART=y +CONFIG_MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT=n +CONFIG_MCUMGR_TRANSPORT_DUMMY=n diff --git a/tests/subsys/mgmt/mcumgr/all_options/prj.conf b/tests/subsys/mgmt/mcumgr/all_options/prj.conf index e44d2420909f1c8..613ba6d8eea2234 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/prj.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/prj.conf @@ -17,18 +17,29 @@ CONFIG_FLASH_MAP=y CONFIG_STREAM_FLASH=y CONFIG_IMG_MANAGER=y CONFIG_MCUMGR=y +CONFIG_MCUMGR_TRANSPORT_BT=y +CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=n +CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y +CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y +CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=y CONFIG_MCUMGR_TRANSPORT_DUMMY=y CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=512 +CONFIG_MCUMGR_TRANSPORT_SHELL=y +CONFIG_MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT=y +CONFIG_MCUMGR_TRANSPORT_UDP=y +CONFIG_MCUMGR_TRANSPORT_UDP_IPV4=y +CONFIG_MCUMGR_TRANSPORT_UDP_IPV6=y CONFIG_MCUMGR_GRP_FS=y -CONFIG_MCUMGR_GRP_FS_FILE_STATUS=n +CONFIG_MCUMGR_GRP_FS_FILE_STATUS=y CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH=y CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_CMD=y CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS=y -CONFIG_MCUMGR_GRP_FS=y CONFIG_MCUMGR_GRP_FS_DL_CHUNK_SIZE_LIMIT=y CONFIG_MCUMGR_GRP_FS_DL_CHUNK_SIZE=128 CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK=y +CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y +CONFIG_MCUMGR_GRP_OS_TASKSTAT=y CONFIG_MCUMGR_GRP_IMG=y CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR=y CONFIG_MCUMGR_GRP_IMG_FRUGAL_LIST=y @@ -41,8 +52,6 @@ CONFIG_MCUMGR_GRP_SHELL=y CONFIG_MCUMGR_GRP_STAT=y CONFIG_MCUMGR_GRP_ZBASIC=y CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y -CONFIG_MCUMGR_TRANSPORT_DUMMY=y -CONFIG_MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE=512 CONFIG_SHELL=y CONFIG_SHELL_BACKEND_DUMMY=y CONFIG_STATS=y @@ -50,13 +59,9 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=y CONFIG_BT_SMP=y -CONFIG_MCUMGR_TRANSPORT_BT=y -CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=n -CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y -CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y -CONFIG_MCUMGR_TRANSPORT_SHELL=y -CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=y -CONFIG_MCUMGR_GRP_FS_FILE_STATUS=y -CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y -CONFIG_MCUMGR_GRP_OS_TASKSTAT=y CONFIG_BOOTLOADER_MCUBOOT=y +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=y +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_SOCKETS=y diff --git a/tests/subsys/mgmt/mcumgr/all_options/testcase.yaml b/tests/subsys/mgmt/mcumgr/all_options/testcase.yaml index f0c46171de85a57..471a96a935f6728 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/testcase.yaml +++ b/tests/subsys/mgmt/mcumgr/all_options/testcase.yaml @@ -1,12 +1,17 @@ # -# Copyright (c) 2022 Nordic Semiconductor ASA +# Copyright (c) 2022-2023 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # +common: + platform_allow: nrf52840dk_nrf52840 + tags: + - mgmt + - mcumgr + - all_options + build_only: true tests: - mgmt.mcumgr.all.options: - platform_allow: nrf52840dk_nrf52840 - tags: - - mgmt - - mcumgr - - all_options + mgmt.mcumgr.all.options: {} + mgmt.mcumgr.all.options.other: + extra_args: + - OVERLAY_CONFIG="other-options.conf" diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt new file mode 100644 index 000000000000000..a0f765546295bfb --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mcumgr_client) + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) + +add_compile_definitions(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1) diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf new file mode 100644 index 000000000000000..46835a49dc78007 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# ZTEST config +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=2048 + +CONFIG_NET_BUF=y +CONFIG_BASE64=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +# Enable mcumgr +CONFIG_MCUMGR=y +CONFIG_SMP_CLIENT=y +CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1 +CONFIG_MCUMGR_GRP_OS_CLIENT=y +CONFIG_MCUMGR_GRP_IMG_CLIENT=y +CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO=y +CONFIG_MCUMGR_GRP_OS_CLIENT_RESET=y + +# Extend System Workqueue stack size +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c new file mode 100644 index 000000000000000..5bd784a3954bc7e --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "smp_stub.h" +#include "img_gr_stub.h" + +static struct mcumgr_image_data image_dummy_info[2]; +static size_t test_offset; +static uint8_t *image_hash_ptr; + +#define ZCBOR_ENCODE_FLAG(zse, label, value) \ + (zcbor_tstr_put_lit(zse, label) && zcbor_bool_put(zse, value)) + +void img_upload_stub_init(void) +{ + test_offset = 0; +} + +void img_upload_response(size_t offset, int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + if (status) { + ok = zcbor_map_start_encode(zse, 4) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, offset) && zcbor_map_end_encode(zse, 4); + } else { + /* Drop Status away from response */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, offset) && zcbor_map_end_encode(zse, 4); + } + + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_fail_response(int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_read_response(int count) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 15) && zcbor_tstr_put_lit(zse, "images") && + zcbor_list_start_encode(zse, 2); + + for (int i = 0; ok && i < count; i++) { + + ok = zcbor_map_start_encode(zse, 15) && + ((zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, image_dummy_info[i].img_num))) && + zcbor_tstr_put_lit(zse, "slot") && + zcbor_uint32_put(zse, image_dummy_info[i].slot_num) && + zcbor_tstr_put_lit(zse, "version") && + zcbor_tstr_put_term(zse, image_dummy_info[i].version) && + + zcbor_tstr_put_term(zse, "hash") && + zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_HASH_LEN) && + ZCBOR_ENCODE_FLAG(zse, "bootable", image_dummy_info[i].flags.bootable) && + ZCBOR_ENCODE_FLAG(zse, "pending", image_dummy_info[i].flags.pending) && + ZCBOR_ENCODE_FLAG(zse, "confirmed", image_dummy_info[i].flags.confirmed) && + ZCBOR_ENCODE_FLAG(zse, "active", image_dummy_info[i].flags.active) && + ZCBOR_ENCODE_FLAG(zse, "permanent", image_dummy_info[i].flags.permanent) && + zcbor_map_end_encode(zse, 15); + } + + ok = ok && zcbor_list_end_encode(zse, 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER); + + ok = ok && zcbor_map_end_encode(zse, 15); + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_erase_response(int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_state_write_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + int rc; + struct zcbor_string hash; + bool confirm; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("confirm", zcbor_bool_decode, &confirm), + ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + + decoded = 0; + /* Init buffer values */ + confirm = false; + hash.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc) { + printf("Corrupted data %d\r\n", rc); + img_fail_response(MGMT_ERR_EINVAL); + return; + } + if (hash.len) { + printf("HASH %d", hash.len); + if (memcmp(hash.value, image_dummy_info[1].hash, 32) == 0) { + if (confirm) { + /* Set Permanent bit */ + image_dummy_info[1].flags.permanent = true; + } else { + /* Set pending */ + image_dummy_info[1].flags.pending = true; + } + img_read_response(2); + } else { + img_fail_response(MGMT_ERR_EINVAL); + } + } else { + if (confirm) { + image_dummy_info[0].flags.confirmed = true; + } + img_read_response(2); + } +} + +void img_upload_init_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + int rc; + uint32_t image; + struct zcbor_string sha, data; + size_t decoded, length, offset; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &image), + ZCBOR_MAP_DECODE_KEY_DECODER("data", zcbor_bstr_decode, &data), + ZCBOR_MAP_DECODE_KEY_DECODER("len", zcbor_size_decode, &length), + ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_size_decode, &offset), + ZCBOR_MAP_DECODE_KEY_DECODER("sha", zcbor_bstr_decode, &sha) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + + decoded = 0; + /* Init buffer values */ + sha.len = 0; + data.len = 0; + length = SIZE_MAX; + offset = SIZE_MAX; + image = UINT32_MAX; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc || data.len == 0 || offset == SIZE_MAX || image != TEST_IMAGE_NUM) { + printf("Corrupted data %d or %d data len\r\n", rc, data.len); + img_upload_response(0, MGMT_ERR_EINVAL); + return; + } + + if (sha.len) { + if (memcmp(sha.value, image_hash_ptr, 32)) { + printf("Hash not same\r\n"); + img_upload_response(0, MGMT_ERR_EINVAL); + return; + } + } + + if (offset != test_offset) { + printf("Offset not exepected %d vs received %d\r\n", test_offset, offset); + } + + if (offset == 0) { + if (length != TEST_IMAGE_SIZE) { + img_upload_response(0, MGMT_ERR_EINVAL); + } + } + + test_offset += data.len; + printf("Upload offset %d\r\n", test_offset); + if (test_offset <= TEST_IMAGE_SIZE) { + img_upload_response(test_offset, MGMT_ERR_EOK); + } else { + img_upload_response(0, MGMT_ERR_EINVAL); + } +} + +void img_gr_stub_data_init(uint8_t *hash_ptr) +{ + image_hash_ptr = hash_ptr; + for (int i = 0; i < 32; i++) { + image_hash_ptr[i] = i; + image_dummy_info[0].hash[i] = i + 32; + image_dummy_info[1].hash[i] = i + 64; + } + /* Set dummy image list data */ + for (int i = 0; i < 2; i++) { + image_dummy_info[i].img_num = i; + image_dummy_info[i].slot_num = i; + /* Write version */ + snprintf(image_dummy_info[i].version, IMG_MGMT_VER_MAX_STR_LEN, "1.1.%u", i); + image_dummy_info[i].version[sizeof(image_dummy_info[i].version) - 1] = '\0'; + image_dummy_info[i].flags.bootable = true; + image_dummy_info[i].flags.pending = false; + if (i) { + image_dummy_info[i].flags.confirmed = false; + image_dummy_info[i].flags.active = false; + } else { + image_dummy_info[i].flags.confirmed = true; + image_dummy_info[i].flags.active = true; + } + image_dummy_info[i].flags.permanent = false; + } +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h new file mode 100644 index 000000000000000..95fdbc8203b2723 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_IMG_GR_STUB_ +#define H_IMG_GR_STUB_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_IMAGE_NUM 1 +#define TEST_IMAGE_SIZE 2048 +#define TEST_SLOT_NUMBER 2 + +void img_upload_stub_init(void); +void img_upload_response(size_t offset, int status); +void img_fail_response(int status); +void img_read_response(int count); +void img_erase_response(int status); +void img_upload_init_verify(struct net_buf *nb); +void img_state_write_verify(struct net_buf *nb); +void img_gr_stub_data_init(uint8_t *hash_ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* H_IMG_GR_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c new file mode 100644 index 000000000000000..a15e82f17a645e6 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +/* Include stubbed test helpers */ +#include "smp_stub.h" +#include "img_gr_stub.h" +#include "os_gr_stub.h" + +/* IMG group data */ +static uint8_t image_hash[32]; +static struct mcumgr_image_data image_info[2]; +static uint8_t image_dummy[1024]; + +static const char os_echo_test[] = "TestString"; +static struct smp_client_object smp_client; +static struct img_mgmt_client img_client; +static struct os_mgmt_client os_client; + +ZTEST(mcumgr_client, img_upload) +{ + int rc; + struct mcumgr_image_upload response; + + smp_stub_set_rx_data_verify(NULL); + img_upload_stub_init(); + + img_mgmt_client_init(&img_client, &smp_client, 2, image_info); + + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + /* Start upload and test Timeout */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d\n", + MGMT_ERR_ETIMEOUT, response.status); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + /* Start upload and test Timeout */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, response.status); + + smp_client_send_status_stub(MGMT_ERR_EOK); + + /* Allocate response buf */ + img_upload_response(0, MGMT_ERR_EINVAL); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL, + rc); + zassert_equal(MGMT_ERR_EINVAL, response.status, "Expected to receive %d response %d", + MGMT_ERR_EINVAL, response.status); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d\n", MGMT_ERR_EOK, rc); + img_upload_response(1024, MGMT_ERR_EOK); + + smp_stub_set_rx_data_verify(img_upload_init_verify); + img_upload_stub_init(); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(1024, response.image_upload_offset, + "Expected to receive offset %d response %d", 1024, + response.image_upload_offset); + /* Send last frame from image */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset, + "Expected to receive offset %d response %d", TEST_IMAGE_SIZE, + response.image_upload_offset); + + /* Test without hash */ + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, NULL); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + img_upload_stub_init(); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(1024, response.image_upload_offset, + "Expected to receive offset %d response %d", 1024, + response.image_upload_offset); + /* Send last frame from image */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset, + "Expected to receive offset %d response %d", TEST_IMAGE_SIZE, + response.image_upload_offset); +} + +ZTEST(mcumgr_client, img_erase) +{ + int rc; + + smp_client_send_status_stub(MGMT_ERR_EOK); + + /* Test timeout */ + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + + /* Test erase fail */ + img_erase_response(MGMT_ERR_EINVAL); + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL, + rc); + /* Tesk ok */ + img_erase_response(MGMT_ERR_EOK); + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +ZTEST(mcumgr_client, image_state_read) +{ + int rc; + struct mcumgr_image_state res_buf; + + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Testing read successfully 1 image info and print that */ + img_read_response(1); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(1, res_buf.image_list_length, "Expected to receive %d response %d", 1, + res_buf.image_list_length); + img_read_response(2); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); +} + +ZTEST(mcumgr_client, image_state_set) +{ + int rc; + char hash[32]; + struct mcumgr_image_state res_buf; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = img_mgmt_client_state_write(&img_client, NULL, false, &res_buf); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + + printf("Timeout OK\r\n"); + /* Read secondary image hash for testing */ + img_read_response(2); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(false, image_info[1].flags.pending, "Expected to receive %d response %d", + false, image_info[1].flags.pending); + /* Copy hash for set pending flag */ + memcpy(hash, image_info[1].hash, 32); + printf("Read OK\r\n"); + + /* Read secondary image hash for testing */ + smp_stub_set_rx_data_verify(img_state_write_verify); + rc = img_mgmt_client_state_write(&img_client, hash, false, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(true, image_info[1].flags.pending, "Expected to receive %d response %d", + true, image_info[1].flags.pending); + /* Test to set confirmed bit */ + image_info[0].flags.confirmed = false; + smp_stub_set_rx_data_verify(img_state_write_verify); + rc = img_mgmt_client_state_write(&img_client, NULL, true, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(true, image_info[0].flags.confirmed, "Expected to receive %d response %d", + true, image_info[0].flags.confirmed); +} + +ZTEST(mcumgr_client, os_reset) +{ + int rc; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = os_mgmt_client_reset(&os_client); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Testing reset successfully handling */ + os_reset_response(); + rc = os_mgmt_client_reset(&os_client); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +ZTEST(mcumgr_client, os_echo) +{ + int rc; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = os_mgmt_client_echo(&os_client, os_echo_test); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Test successfully operation */ + smp_stub_set_rx_data_verify(os_echo_verify); + rc = os_mgmt_client_echo(&os_client, os_echo_test); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +static void *setup_custom_os(void) +{ + stub_smp_client_transport_register(); + smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT); + os_mgmt_client_init(&os_client, &smp_client); + img_mgmt_client_init(&img_client, &smp_client, 2, image_info); + + img_gr_stub_data_init(image_hash); + os_stub_init(os_echo_test); + return NULL; +} + +static void cleanup_test(void *p) +{ + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); +} + +/* Main test set */ +ZTEST_SUITE(mcumgr_client, NULL, setup_custom_os, NULL, cleanup_test, NULL); diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c new file mode 100644 index 000000000000000..888f00dba38d254 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "smp_stub.h" + +static const char *echo_ptr; + +void os_stub_init(const char *echo_str) +{ + echo_ptr = echo_str; +} + +void os_reset_response(void) +{ + struct net_buf *nb; + + nb = smp_response_buf_allocation(); + if (nb) { + nb->len = 0; + } +} + +static void os_echo_response(int status, struct zcbor_string *echo_data) +{ + struct net_buf *nb; + zcbor_state_t zse[3 + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + if (status) { + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + } else { + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "r") && + zcbor_tstr_encode_ptr(zse, echo_data->value, echo_data->len) && + zcbor_map_end_encode(zse, 2); + } + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void os_echo_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[3 + 2]; + int rc; + int response_status; + struct zcbor_string echo_data; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("d", zcbor_tstr_decode, &echo_data) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + echo_data.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc || !echo_data.len) { + printf("Corrupted data %d or no echo data %d\r\n", rc, echo_data.len); + response_status = MGMT_ERR_EINVAL; + } else if (memcmp(echo_data.value, echo_ptr, echo_data.len)) { + response_status = MGMT_ERR_EINVAL; + } else { + response_status = MGMT_ERR_EOK; + } + + os_echo_response(response_status, &echo_data); +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h new file mode 100644 index 000000000000000..ec6f3408979f278 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_OS_GR_STUB_ +#define H_OS_GR_STUB_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void os_stub_init(const char *echo_str); +void os_reset_response(void); +void os_echo_verify(struct net_buf *nb); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_GR_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c new file mode 100644 index 000000000000000..9b476082dd8e45b --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "smp_stub.h" + +K_THREAD_STACK_DEFINE(smp_stub_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE); + +static mcmgr_client_data_check_fn rx_verify_cb; +static int send_client_failure; +static struct net_buf *response_buf; +static struct smp_hdr res_hdr; +static struct smp_transport smpt_test; +static struct smp_client_transport_entry smp_client_transport; +static struct k_work_q smp_work_queue; +static struct k_work stub_work; + +static const struct k_work_queue_config smp_work_queue_config = { + .name = "mcumgr smp" +}; + +void smp_stub_set_rx_data_verify(mcmgr_client_data_check_fn cb) +{ + rx_verify_cb = cb; +} + +void smp_client_send_status_stub(int status) +{ + send_client_failure = status; +} + +struct net_buf *smp_response_buf_allocation(void) +{ + smp_client_response_buf_clean(); + + response_buf = smp_packet_alloc(); + + return response_buf; +} + +void smp_client_response_buf_clean(void) +{ + if (response_buf) { + smp_client_buf_free(response_buf); + response_buf = NULL; + } +} + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + + +static uint16_t smp_uart_get_mtu(const struct net_buf *nb) +{ + return 256; +} + +static int smp_uart_tx_pkt(struct net_buf *nb) +{ + if (send_client_failure) { + /* Test Send cmd fail */ + return send_client_failure; + } + + memcpy(&res_hdr, nb->data, sizeof(res_hdr)); + res_hdr.nh_len = sys_be16_to_cpu(res_hdr.nh_len); + res_hdr.nh_group = sys_be16_to_cpu(res_hdr.nh_group); + res_hdr.nh_op += 1; /* Request to response */ + + /* Validate Input data if callback is configured */ + if (rx_verify_cb) { + rx_verify_cb(nb); + } + + /* Free tx buf */ + net_buf_unref(nb); + + if (response_buf) { + k_work_submit_to_queue(&smp_work_queue, &stub_work); + } + + return 0; +} + +static void smp_client_handle_reqs(struct k_work *work) +{ + if (response_buf) { + smp_client_single_response(response_buf, &res_hdr); + } +} + +void stub_smp_client_transport_register(void) +{ + + smpt_test.functions.output = smp_uart_tx_pkt; + smpt_test.functions.get_mtu = smp_uart_get_mtu; + + smp_transport_init(&smpt_test); + smp_client_transport.smpt = &smpt_test; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); + + + k_work_queue_init(&smp_work_queue); + + k_work_queue_start(&smp_work_queue, smp_stub_work_queue_stack, + K_THREAD_STACK_SIZEOF(smp_stub_work_queue_stack), + CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_THREAD_PRIO, &smp_work_queue_config); + + k_work_init(&stub_work, smp_client_handle_reqs); +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h new file mode 100644 index 000000000000000..c8668a033d2e19d --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_SMP_STUB_ +#define H_SMP_STUB_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*mcmgr_client_data_check_fn)(struct net_buf *nb); + +void smp_stub_set_rx_data_verify(mcmgr_client_data_check_fn cb); +void smp_client_send_status_stub(int status); +void smp_client_response_buf_clean(void); +struct net_buf *smp_response_buf_allocation(void); +void stub_smp_client_transport_register(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_SMP_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt new file mode 100644 index 000000000000000..2d5fea068dbccc9 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(smp_client) + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/mgmt/mcumgr/smp_client/prj.conf b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf new file mode 100644 index 000000000000000..22740657b784718 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# ZTEST config +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=2048 + +CONFIG_NET_BUF=y +CONFIG_BASE64=y +CONFIG_CRC=y +CONFIG_ZCBOR=y +CONFIG_MCUMGR=y +CONFIG_SMP_CLIENT=y + +# Extend System Workqueue stack size +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c new file mode 100644 index 000000000000000..be1a3968274ab8d --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smp_transport_stub.h" + +static struct net_buf *buf[5]; + +static uint32_t testing_user_data; +static void *response_ptr; +static struct net_buf *res_buf; +static struct smp_client_object smp_client; + +int smp_client_res_cb(struct net_buf *nb, void *user_data) +{ + res_buf = nb; + response_ptr = user_data; + return 0; +} + +ZTEST(smp_client, buf_alloc) +{ + struct smp_client_object smp_client; + + /* Allocate all 4 buffer's and verify that 5th fail */ + for (int i = 0; i < 5; i++) { + buf[i] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, + MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (i == 4) { + zassert_is_null(buf[i], "Buffer was not Null"); + } else { + zassert_not_null(buf[i], "Buffer was Null"); + zassert_equal(sizeof(struct smp_hdr), buf[i]->len, + "Expected to receive %d response %d", + sizeof(struct smp_hdr), buf[i]->len); + } + } + + for (int i = 0; i < 4; i++) { + smp_client_buf_free(buf[i]); + buf[i] = NULL; + } +} + +ZTEST(smp_client, msg_send_timeout) +{ + struct net_buf *nb; + + int rc; + + nb = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(nb, "Buffer was Null"); + rc = smp_client_send_cmd(&smp_client, nb, smp_client_res_cb, &testing_user_data, 2); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + k_sleep(K_SECONDS(3)); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); +} + +ZTEST(smp_client, msg_response_handler) +{ + struct smp_hdr dst_hdr; + int rc; + + + response_ptr = NULL; + res_buf = NULL; + + buf[0] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(buf[0], "Buffer was Null"); + rc = smp_client_send_cmd(&smp_client, buf[0], smp_client_res_cb, &testing_user_data, 8); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + buf[1] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(buf[0], "Buffer was Null"); + /* Read Pushed packet Header */ + smp_transport_read_hdr(buf[0], &dst_hdr); + smp_client_single_response(buf[1], &dst_hdr); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_is_null(response_ptr, "NULL pointer was not returned"); + /* Set Correct OP */ + dst_hdr.nh_op = MGMT_OP_WRITE_RSP; + smp_client_single_response(buf[1], &dst_hdr); + zassert_equal_ptr(res_buf, buf[1], "Response Buf not correct"); + zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); + response_ptr = NULL; + res_buf = NULL; + smp_client_single_response(buf[1], &dst_hdr); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_is_null(response_ptr, "NULL pointer was not returned"); +} + +static void *setup_custom_os(void) +{ + /* Registre tarnsport and init client */ + stub_smp_client_transport_register(); + smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT); + return NULL; +} + +static void cleanup_test(void *p) +{ + for (int i = 0; i < 5; i++) { + if (buf[i]) { + smp_client_buf_free(buf[i]); + buf[i] = NULL; + } + } +} + +/* Main test set */ +ZTEST_SUITE(smp_client, NULL, setup_custom_os, NULL, cleanup_test, NULL); diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c new file mode 100644 index 000000000000000..d3248755e5ab089 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct smp_transport smpt_test; +static struct smp_client_transport_entry smp_client_transport; + +/* Stubbed functions */ + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + + + + +static uint16_t smp_uart_get_mtu(const struct net_buf *nb) +{ + return 256; +} + +static int smp_uart_tx_pkt(struct net_buf *nb) +{ + smp_packet_free(nb); + return 0; +} + +void stub_smp_client_transport_register(void) +{ + + smpt_test.functions.output = smp_uart_tx_pkt; + smpt_test.functions.get_mtu = smp_uart_get_mtu; + + smp_transport_init(&smpt_test); + smp_client_transport.smpt = &smpt_test; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); +} diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h new file mode 100644 index 000000000000000..9046aff622c00b4 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_OS_GR_STUB_ +#define H_OS_GR_STUB_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr); +void stub_smp_client_transport_register(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_GR_STUB_ */ diff --git a/tests/subsys/openthread/radio_test.c b/tests/subsys/openthread/radio_test.c index c7837016927db78..d9aec84732741c1 100644 --- a/tests/subsys/openthread/radio_test.c +++ b/tests/subsys/openthread/radio_test.c @@ -52,8 +52,6 @@ FAKE_VALUE_FUNC(int, start_mock, const struct device *); FAKE_VALUE_FUNC(int, stop_mock, const struct device *); FAKE_VALUE_FUNC(int, configure_mock, const struct device *, enum ieee802154_config_type, const struct ieee802154_config *); -FAKE_VALUE_FUNC(int, configure_promiscuous_mock, const struct device *, enum ieee802154_config_type, - const struct ieee802154_config *); FAKE_VALUE_FUNC(enum ieee802154_hw_caps, get_capabilities_caps_mock, const struct device *); static enum ieee802154_hw_caps get_capabilities(const struct device *dev); @@ -122,15 +120,18 @@ FAKE_VOID_FUNC(otPlatRadioTxDone, otInstance *, otRadioFrame *, otRadioFrame *, static enum ieee802154_hw_caps get_capabilities(const struct device *dev) { + enum ieee802154_hw_caps caps; + zassert_equal(dev, radio, "Device handle incorrect."); - return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | + caps = IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_FILTER | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_SLEEP_TO_TX; + if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) { + caps |= IEEE802154_HW_TXTIME; + } + return caps; } -FAKE_VALUE_FUNC(int, configure_match_mock, const struct device *, enum ieee802154_config_type, - const struct ieee802154_config *); - FAKE_VALUE_FUNC(otError, otIp6Send, otInstance *, otMessage *); otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings) @@ -260,6 +261,7 @@ ZTEST(openthread_radio, test_tx_test) const uint8_t chan = 20; uint8_t chan2 = chan - 1; const int8_t power = -3; + net_time_t expected_target_time = 0; otRadioFrame *frm = otPlatRadioGetTransmitBuffer(ot); @@ -281,12 +283,21 @@ ZTEST(openthread_radio, test_tx_test) RESET_FAKE(start_mock); FFF_RESET_HISTORY(); + if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) { + frm->mInfo.mTxInfo.mTxDelayBaseTime = 3U; + frm->mInfo.mTxInfo.mTxDelay = 5U; + expected_target_time = + (frm->mInfo.mTxInfo.mTxDelayBaseTime + frm->mInfo.mTxInfo.mTxDelay) * + NSEC_PER_USEC; + } + /* ACKed frame */ frm->mChannel = chan2; frm->mInfo.mTxInfo.mCsmaCaEnabled = true; frm->mPsdu[0] = IEEE802154_AR_FLAG_SET; set_channel_mock_fake.return_val = 0; zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE, "Transmit failed."); + k_yield(); create_ack_frame(); make_sure_sem_set(Z_TIMEOUT_MS(100)); @@ -294,12 +305,21 @@ ZTEST(openthread_radio, test_tx_test) platformRadioProcess(ot); zassert_equal(1, set_channel_mock_fake.call_count); zassert_equal(chan2, set_channel_mock_fake.arg1_val); - zassert_equal(1, cca_mock_fake.call_count); - zassert_equal_ptr(radio, cca_mock_fake.arg0_val, NULL); + if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) { + zassert_equal(0, cca_mock_fake.call_count); + } else { + zassert_equal(1, cca_mock_fake.call_count); + zassert_equal_ptr(radio, cca_mock_fake.arg0_val, NULL); + } zassert_equal(1, set_txpower_mock_fake.call_count); zassert_equal(power, set_txpower_mock_fake.arg1_val); zassert_equal(1, tx_mock_fake.call_count); zassert_equal_ptr(frm->mPsdu, tx_mock_fake.arg3_val->data, NULL); + zassert_equal(expected_target_time, + net_ptp_time_to_ns(net_pkt_timestamp(tx_mock_fake.arg2_val))); + zassert_equal(IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? IEEE802154_TX_MODE_TXTIME_CCA + : IEEE802154_TX_MODE_DIRECT, + tx_mock_fake.arg1_val); zassert_equal(1, otPlatRadioTxDone_fake.call_count); zassert_equal_ptr(ot, otPlatRadioTxDone_fake.arg0_val, NULL); zassert_equal(OT_ERROR_NONE, otPlatRadioTxDone_fake.arg3_val); @@ -432,9 +452,8 @@ static void set_expected_match_values(enum ieee802154_config_type type, uint8_t ZTEST(openthread_radio, test_source_match_test) { otExtAddress ext_addr; - configure_match_mock_fake.custom_fake = custom_configure_match_mock; + configure_mock_fake.custom_fake = custom_configure_match_mock; - rapi.configure = configure_match_mock; /* Enable/Disable */ set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false, true); otPlatRadioEnableSrcMatch(ot, true); @@ -473,8 +492,6 @@ ZTEST(openthread_radio, test_source_match_test) set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, NULL, true, false); otPlatRadioClearSrcMatchExtEntries(ot); - - rapi.configure = configure_mock; } static bool custom_configure_promiscuous_mock_promiscuous; @@ -495,27 +512,22 @@ static int custom_configure_promiscuous_mock(const struct device *dev, */ ZTEST(openthread_radio, test_promiscuous_mode_set_test) { - rapi.configure = configure_promiscuous_mock; - zassert_false(otPlatRadioGetPromiscuous(ot), "By default promiscuous mode shall be disabled."); - configure_promiscuous_mock_fake.custom_fake = custom_configure_promiscuous_mock; + configure_mock_fake.custom_fake = custom_configure_promiscuous_mock; otPlatRadioSetPromiscuous(ot, true); zassert_true(otPlatRadioGetPromiscuous(ot), "Mode not enabled."); - zassert_equal(1, configure_promiscuous_mock_fake.call_count); + zassert_equal(1, configure_mock_fake.call_count); zassert_true(custom_configure_promiscuous_mock_promiscuous); - RESET_FAKE(configure_promiscuous_mock); - FFF_RESET_HISTORY(); + RESET_FAKE(configure_mock); - configure_promiscuous_mock_fake.custom_fake = custom_configure_promiscuous_mock; + configure_mock_fake.custom_fake = custom_configure_promiscuous_mock; otPlatRadioSetPromiscuous(ot, false); zassert_false(otPlatRadioGetPromiscuous(ot), "Mode still enabled."); - zassert_equal(1, configure_promiscuous_mock_fake.call_count); + zassert_equal(1, configure_mock_fake.call_count); zassert_false(custom_configure_promiscuous_mock_promiscuous); - - rapi.configure = configure_mock; } /** @@ -545,10 +557,6 @@ ZTEST(openthread_radio, test_get_caps_test) "Incorrect capabilities returned."); /* not implemented or not fully supported */ - get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_TXTIME; - zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE, - "Incorrect capabilities returned."); - get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_PROMISC; zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE, "Incorrect capabilities returned."); @@ -566,6 +574,12 @@ ZTEST(openthread_radio, test_get_caps_test) zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_ACK_TIMEOUT, "Incorrect capabilities returned."); + get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_TXTIME; + zassert_equal(otPlatRadioGetCaps(ot), + IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? OT_RADIO_CAPS_TRANSMIT_TIMING + : OT_RADIO_CAPS_NONE, + "Incorrect capabilities returned."); + get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_SLEEP_TO_TX; zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_SLEEP_TO_TX, "Incorrect capabilities returned."); @@ -576,10 +590,12 @@ ZTEST(openthread_radio, test_get_caps_test) IEEE802154_HW_CSMA | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_SUB_GHZ | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_TXTIME | IEEE802154_HW_SLEEP_TO_TX; - zassert_equal(otPlatRadioGetCaps(ot), - OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN | - OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX, - "Incorrect capabilities returned."); + zassert_equal( + otPlatRadioGetCaps(ot), + OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | + OT_RADIO_CAPS_SLEEP_TO_TX | + (IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? OT_RADIO_CAPS_TRANSMIT_TIMING : 0), + "Incorrect capabilities returned."); rapi.get_capabilities = get_capabilities; } @@ -882,6 +898,62 @@ ZTEST(openthread_radio, test_net_pkt_transmit) zassert_equal_ptr(ip_msg, otIp6Send_fake.arg1_val, NULL); } +#ifdef CONFIG_OPENTHREAD_CSL_RECEIVER +static int64_t custom_configure_csl_rx_time_mock_csl_rx_time; +static int custom_configure_csl_rx_time(const struct device *dev, + enum ieee802154_config_type type, + const struct ieee802154_config *config) +{ + zassert_equal(dev, radio, "Device handle incorrect."); + zassert_equal(type, IEEE802154_CONFIG_CSL_RX_TIME, "Config type incorrect."); + custom_configure_csl_rx_time_mock_csl_rx_time = config->csl_rx_time; + + return 0; +} + +ZTEST(openthread_radio, test_csl_receiver_sample_time) +{ + uint32_t sample_time = 50U; + + configure_mock_fake.custom_fake = custom_configure_csl_rx_time; + otPlatRadioUpdateCslSampleTime(NULL, sample_time); + zassert_equal(1, configure_mock_fake.call_count); + zassert_equal(sample_time * NSEC_PER_USEC, custom_configure_csl_rx_time_mock_csl_rx_time); +} + + +static struct ieee802154_config custom_configure_rx_slot_mock_config; +static int custom_configure_csl_rx_slot(const struct device *dev, + enum ieee802154_config_type type, + const struct ieee802154_config *config) +{ + zassert_equal(dev, radio, "Device handle incorrect."); + zassert_equal(type, IEEE802154_CONFIG_RX_SLOT, "Config type incorrect."); + custom_configure_rx_slot_mock_config.rx_slot.channel = config->rx_slot.channel; + custom_configure_rx_slot_mock_config.rx_slot.start = config->rx_slot.start; + custom_configure_rx_slot_mock_config.rx_slot.duration = config->rx_slot.duration; + + return 0; +} + +ZTEST(openthread_radio, test_csl_receiver_receive_at) +{ + uint8_t channel = 11U; + uint32_t start = 1000U; + uint32_t duration = 100U; + int res; + + configure_mock_fake.custom_fake = custom_configure_csl_rx_slot; + res = otPlatRadioReceiveAt(NULL, channel, start, duration); + zassert_ok(res); + zassert_equal(1, configure_mock_fake.call_count); + zassert_equal(channel, custom_configure_rx_slot_mock_config.rx_slot.channel); + zassert_equal(start * NSEC_PER_USEC, custom_configure_rx_slot_mock_config.rx_slot.start); + zassert_equal(duration * NSEC_PER_USEC, + custom_configure_rx_slot_mock_config.rx_slot.duration); +} +#endif + static void *openthread_radio_setup(void) { platformRadioInit(); @@ -900,7 +972,6 @@ static void openthread_radio_before(void *f) RESET_FAKE(start_mock); RESET_FAKE(stop_mock); RESET_FAKE(configure_mock); - RESET_FAKE(configure_promiscuous_mock); RESET_FAKE(get_capabilities_caps_mock); RESET_FAKE(otPlatRadioEnergyScanDone); RESET_FAKE(otPlatRadioTxDone); diff --git a/tests/subsys/openthread/testcase.yaml b/tests/subsys/openthread/testcase.yaml index fb860a4798f072f..a442535a2783c85 100644 --- a/tests/subsys/openthread/testcase.yaml +++ b/tests/subsys/openthread/testcase.yaml @@ -1,8 +1,16 @@ +common: + platform_allow: + - native_posix + - native_posix_64 + integration_platforms: + - native_posix + tags: ot_radio tests: - openthread.radio: - platform_allow: - - native_posix - - native_posix_64 - integration_platforms: - - native_posix - tags: ot_radio + tests.subsys.openthread.radio_test.min: {} + tests.subsys.openthread.radio_test.timed_tx: + extra_configs: + - CONFIG_NET_PKT_TXTIME=y + tests.subsys.openthread.radio_test.csl: + # Hack to enable CSL w/o having to enable CONFIG_OPENTHREAD + extra_args: + - EXTRA_CPPFLAGS=-DCONFIG_OPENTHREAD_CSL_RECEIVER diff --git a/tests/subsys/pm/device_driver_init/CMakeLists.txt b/tests/subsys/pm/device_driver_init/CMakeLists.txt new file mode 100644 index 000000000000000..ddb4b524925a830 --- /dev/null +++ b/tests/subsys/pm/device_driver_init/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023, CSIRO. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device_driver_init) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/pm/device_driver_init/app.overlay b/tests/subsys/pm/device_driver_init/app.overlay new file mode 100644 index 000000000000000..a5518b74be2ce0b --- /dev/null +++ b/tests/subsys/pm/device_driver_init/app.overlay @@ -0,0 +1,44 @@ +/ { + test_reg: test_reg { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 0 0>; + }; + + test_reg_chained: test_reg_chained { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 1 0>; + power-domain = <&test_reg>; + }; + + test_reg_chained_auto: test_reg_chained_auto { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 2 0>; + power-domain = <&test_reg>; + zephyr,pm-device-runtime-auto; + }; + + test_reg_auto: test_reg_auto { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 3 0>; + zephyr,pm-device-runtime-auto; + }; + + test_reg_auto_chained: test_reg_auto_chained { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 4 0>; + power-domain = <&test_reg_auto>; + }; + + test_reg_auto_chained_auto: test_reg_auto_chained_auto { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 5 0>; + power-domain = <&test_reg_auto>; + zephyr,pm-device-runtime-auto; + }; + + test_reg_disabled: test_reg_disabled { + compatible = "power-domain-gpio"; + enable-gpios = <&gpio0 6 0>; + status = "disabled"; + }; +}; diff --git a/tests/subsys/pm/device_driver_init/prj.conf b/tests/subsys/pm/device_driver_init/prj.conf new file mode 100644 index 000000000000000..e6d05f591acfe5b --- /dev/null +++ b/tests/subsys/pm/device_driver_init/prj.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Commonwealth Scientific and Industrial Research +# Organisation (CSIRO) ABN 41 687 119 230. +CONFIG_ZTEST=y +CONFIG_MP_MAX_NUM_CPUS=1 + +CONFIG_GPIO=y +CONFIG_GPIO_GET_CONFIG=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZTEST_NEW_API=y diff --git a/tests/subsys/pm/device_driver_init/src/main.c b/tests/subsys/pm/device_driver_init/src/main.c new file mode 100644 index 000000000000000..55621b95faaaf51 --- /dev/null +++ b/tests/subsys/pm/device_driver_init/src/main.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * SPDX-License-Identifier: Apache-2.0 + * + * State checking in this test is done via the GPIO state instead of + * the PM API as this test runs without the PM api enabled. + */ + +#include +#include +#include +#include + +#define POWER_GPIO_CONFIG_IS(node_id, config)\ + {\ + const struct gpio_dt_spec gpio = GPIO_DT_SPEC_GET(node_id, enable_gpios);\ + gpio_flags_t gpio_config; \ + int rc = gpio_pin_get_config_dt(&gpio, &gpio_config); \ + zassert_equal(rc, 0, "GPIO config retrieval failed"); \ + zassert_equal(gpio_config, config, "Unexpected config");\ + } + +#define DEVICE_STATE_IS(node_id, value) \ + rc = pm_device_state_get(DEVICE_DT_GET(node_id), &state); \ + zassert_equal(rc, 0, "Device state retrieval failed"); \ + zassert_equal(state, value, "Unexpected device state"); + +ZTEST(device_driver_init, test_demo) +{ +#if IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) + enum pm_device_state state; + int rc; + + /* No device runtime PM, starts on */ + DEVICE_STATE_IS(DT_NODELABEL(test_reg), PM_DEVICE_STATE_ACTIVE); + DEVICE_STATE_IS(DT_NODELABEL(test_reg_chained), PM_DEVICE_STATE_ACTIVE); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_chained), GPIO_OUTPUT_HIGH); + + /* Device powered, zephyr,pm-device-runtime-auto, starts suspended */ + DEVICE_STATE_IS(DT_NODELABEL(test_reg_chained_auto), PM_DEVICE_STATE_SUSPENDED); + DEVICE_STATE_IS(DT_NODELABEL(test_reg_auto), PM_DEVICE_STATE_SUSPENDED); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_chained_auto), GPIO_OUTPUT_LOW); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto), GPIO_OUTPUT_LOW); + /* Device not powered, starts off */ + DEVICE_STATE_IS(DT_NODELABEL(test_reg_auto_chained), PM_DEVICE_STATE_OFF); + DEVICE_STATE_IS(DT_NODELABEL(test_reg_auto_chained_auto), PM_DEVICE_STATE_OFF); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto_chained), GPIO_DISCONNECTED); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto_chained_auto), GPIO_DISCONNECTED); +#else + /* Every regulator should be in "active" mode automatically. + * State checking via GPIO as PM API is disabled. + */ + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_chained), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_chained_auto), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto_chained), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_auto_chained_auto), GPIO_OUTPUT_HIGH); + POWER_GPIO_CONFIG_IS(DT_NODELABEL(test_reg_disabled), GPIO_DISCONNECTED); +#endif +} + +ZTEST_SUITE(device_driver_init, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/subsys/pm/device_driver_init/testcase.yaml b/tests/subsys/pm/device_driver_init/testcase.yaml new file mode 100644 index 000000000000000..e3e35d97841b833 --- /dev/null +++ b/tests/subsys/pm/device_driver_init/testcase.yaml @@ -0,0 +1,17 @@ +tests: + pm.device_driver_init: + tags: pm + platform_allow: qemu_cortex_m3 + pm.device_driver_init.pm: + tags: pm + platform_allow: qemu_cortex_m3 + extra_configs: + - CONFIG_PM_DEVICE=y + - CONFIG_PM_DEVICE_POWER_DOMAIN=y + pm.device_driver_init.pm_device_runtime: + tags: pm + platform_allow: qemu_cortex_m3 + extra_configs: + - CONFIG_PM_DEVICE=y + - CONFIG_PM_DEVICE_POWER_DOMAIN=y + - CONFIG_PM_DEVICE_RUNTIME=y diff --git a/tests/subsys/pm/device_power_domains/src/main.c b/tests/subsys/pm/device_power_domains/src/main.c index 8bc7789fa4b0688..50726bcef199e1c 100644 --- a/tests/subsys/pm/device_power_domains/src/main.c +++ b/tests/subsys/pm/device_power_domains/src/main.c @@ -40,17 +40,17 @@ ZTEST(device_power_domain, test_demo) /* Initial power state */ zassert_true(pm_device_is_powered(reg_0), ""); zassert_true(pm_device_is_powered(reg_1), ""); - zassert_false(pm_device_is_powered(reg_chained), ""); - zassert_false(pm_device_is_powered(dev), ""); + zassert_true(pm_device_is_powered(reg_chained), ""); + zassert_true(pm_device_is_powered(dev), ""); TC_PRINT("Enabling runtime power management on regulators\n"); - pm_device_runtime_enable(reg_0); - pm_device_runtime_enable(reg_1); - pm_device_runtime_enable(reg_chained); pm_device_runtime_enable(dev); + pm_device_runtime_enable(reg_chained); + pm_device_runtime_enable(reg_1); + pm_device_runtime_enable(reg_0); - /* State shouldn't have changed */ + /* Power domains should now be suspended */ zassert_true(pm_device_is_powered(reg_0), ""); zassert_true(pm_device_is_powered(reg_1), ""); zassert_false(pm_device_is_powered(reg_chained), ""); diff --git a/tests/subsys/pm/power_mgmt_multicore/src/main.c b/tests/subsys/pm/power_mgmt_multicore/src/main.c index 60a35b269c00be8..6915694a6d82a38 100644 --- a/tests/subsys/pm/power_mgmt_multicore/src/main.c +++ b/tests/subsys/pm/power_mgmt_multicore/src/main.c @@ -34,9 +34,6 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) ARG_UNUSED(substate_id); switch (state_testing[_current_cpu->id]) { - case PM_STATE_ACTIVE: - zassert_equal(PM_STATE_ACTIVE, state); - break; case PM_STATE_RUNTIME_IDLE: zassert_equal(PM_STATE_RUNTIME_IDLE, state); break; diff --git a/tests/subsys/pm/power_states_api/boards/native_posix.overlay b/tests/subsys/pm/power_states_api/boards/native_posix.overlay index 79fafb582b0c172..e7222630000ba68 100644 --- a/tests/subsys/pm/power_states_api/boards/native_posix.overlay +++ b/tests/subsys/pm/power_states_api/boards/native_posix.overlay @@ -7,7 +7,7 @@ / { cpus { cpu@0 { - cpu-power-states = <&state0 &state1 &state2>; + cpu-power-states = <&state0 &state1 &state2 &state3>; }; power-states { @@ -29,6 +29,12 @@ compatible = "zephyr,power-state"; power-state-name = "standby"; }; + + state3: state3 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + status = "disabled"; + }; }; }; }; diff --git a/tests/subsys/usb/desc_sections/prj.conf b/tests/subsys/usb/desc_sections/prj.conf index 7358e60b1eb11c9..a7265e4f03c2972 100644 --- a/tests/subsys/usb/desc_sections/prj.conf +++ b/tests/subsys/usb/desc_sections/prj.conf @@ -1,6 +1,5 @@ CONFIG_ZTEST=y CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_COMPOSITE_DEVICE=n CONFIG_USB_DEVICE_LOG_LEVEL_DBG=y CONFIG_LOG=y diff --git a/tests/subsys/usb/desc_sections/src/desc_sections.c b/tests/subsys/usb/desc_sections/src/desc_sections.c index 6297d9fc8854438..5100f1b90aefbb3 100644 --- a/tests/subsys/usb/desc_sections/src/desc_sections.c +++ b/tests/subsys/usb/desc_sections/src/desc_sections.c @@ -14,10 +14,6 @@ #include LOG_MODULE_REGISTER(test_main, LOG_LEVEL_DBG); -#ifdef CONFIG_USB_COMPOSITE_DEVICE -#error Do not use composite configuration -#endif - /* Linker-defined symbols bound the USB descriptor structs */ extern struct usb_desc_header __usb_descriptor_start[]; extern struct usb_desc_header __usb_descriptor_end[]; diff --git a/west.yml b/west.yml index f3fa27117d4a1de..1485e3ade81855f 100644 --- a/west.yml +++ b/west.yml @@ -167,13 +167,18 @@ manifest: path: modules/hal/infineon groups: - hal + - name: hal_intel + revision: 89a0db5d9155484624447d62a5211bcf6f6f0387 + path: modules/hal/intel + groups: + - hal - name: hal_microchip revision: 5d079f1683a00b801373bbbbf5d181d4e33b30d5 path: modules/hal/microchip groups: - hal - name: hal_nordic - revision: 20ae0a7be9030dd58fb59db1c74315a60efb076f + revision: cf6e9fc5f7c2c98df26f2a4227a95df9a50823e7 path: modules/hal/nordic groups: - hal @@ -183,7 +188,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 35b0e5afc4f061cedc5a0411e024dad6d9e8101f + revision: 1a55ccfde649a97df74a8853cbd9787ddd34bfc4 path: modules/hal/nxp groups: - hal @@ -271,7 +276,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 6a8746d7acd75ff81fb6888d7776f412663f7897 + revision: 76d19b3b8885ea7ae25a6f4f5d8501f7ec646447 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t @@ -287,10 +292,10 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 7a5b67d9ee66d84e4ef5cb1f56c8f0f3252d5aa2 + revision: cee41373eb0bb720a370586de1ee5eb693e62c95 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp - revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad + revision: 42b7c577714b8f22ce82a901e19c1814af4609a8 path: modules/lib/open-amp - name: openthread revision: f7690fe7e9d638341921808cba6a3e695ec0131e