From 9c27d72922fb58882ebe653e0a4fcdb7be169138 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Tue, 8 Jul 2025 10:18:31 -0500 Subject: [PATCH 0001/1076] rtio: Add a context pool Adds a context pool that can be used when a number of threads may be dynamically created to use with RTIO. While the pool has a small cost to it, the cost of verifying a statically declared kobject likely makes it worth avoiding dynamically allocating these with the typical kobject_alloc method. Instead this arena style pool of objects can be used where the kobject validation uses the gperf hash created at build time. Signed-off-by: Tom Burdick --- include/zephyr/linker/common-ram.ld | 1 + include/zephyr/rtio/rtio.h | 125 ++++++++++++++++++ scripts/build/gen_kobject_list.py | 1 + subsys/rtio/CMakeLists.txt | 2 +- .../rtio/{rtio_handlers.c => rtio_syscalls.c} | 19 +++ tests/subsys/rtio/rtio_api/CMakeLists.txt | 2 +- .../subsys/rtio/rtio_api/src/test_rtio_pool.c | 65 +++++++++ 7 files changed, 213 insertions(+), 2 deletions(-) rename subsys/rtio/{rtio_handlers.c => rtio_syscalls.c} (88%) create mode 100644 tests/subsys/rtio/rtio_api/src/test_rtio_pool.c diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index 792574c9d37a2..c85bdce6c7093 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -126,6 +126,7 @@ ITERABLE_SECTION_RAM(scmi_protocol, Z_LINK_ITERABLE_SUBALIGN) #if defined(CONFIG_RTIO) ITERABLE_SECTION_RAM(rtio, Z_LINK_ITERABLE_SUBALIGN) + ITERABLE_SECTION_RAM(rtio_pool, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(rtio_iodev, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(rtio_sqe_pool, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(rtio_cqe_pool, Z_LINK_ITERABLE_SUBALIGN) diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 092f13f002d42..25b4beaa91242 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -1421,6 +1421,9 @@ static inline void z_impl_rtio_release_buffer(struct rtio *r, void *buff, uint32 /** * Grant access to an RTIO context to a user thread + * + * @param r RTIO context + * @param t Thread to grant permissions to */ static inline void rtio_access_grant(struct rtio *r, struct k_thread *t) { @@ -1435,6 +1438,26 @@ static inline void rtio_access_grant(struct rtio *r, struct k_thread *t) #endif } + +/** + * Revoke access to an RTIO context from a user thread + * + * @param r RTIO context + * @param t Thread to revoke permissions from + */ +static inline void rtio_access_revoke(struct rtio *r, struct k_thread *t) +{ + k_object_access_revoke(r, t); + +#ifdef CONFIG_RTIO_SUBMIT_SEM + k_object_access_revoke(r->submit_sem, t); +#endif + +#ifdef CONFIG_RTIO_CONSUME_SEM + k_object_access_revoke(r->consume_sem, t); +#endif +} + /** * @brief Attempt to cancel an SQE * @@ -1674,6 +1697,108 @@ static inline int z_impl_rtio_submit(struct rtio *r, uint32_t wait_count) } #endif /* CONFIG_RTIO_SUBMIT_SEM */ +/** + * @brief Pool of RTIO contexts to use with dynamically created threads + */ +struct rtio_pool { + /** Size of the pool */ + size_t pool_size; + + /** Array containing contexts of the pool */ + struct rtio **contexts; + + /** Atomic bitmap to signal a member is used/unused */ + atomic_t *used; +}; + +/** + * @brief Obtain an RTIO context from a pool + * + * @param pool RTIO pool to acquire a context from + * + * @retval NULL no available contexts + * @retval r Valid context with permissions granted to the calling thread + */ +__syscall struct rtio *rtio_pool_acquire(struct rtio_pool *pool); + +static inline struct rtio *z_impl_rtio_pool_acquire(struct rtio_pool *pool) +{ + struct rtio *r = NULL; + + for (size_t i = 0; i < pool->pool_size; i++) { + if (atomic_test_and_set_bit(pool->used, i) == 0) { + r = pool->contexts[i]; + break; + } + } + + if (r != NULL) { + rtio_access_grant(r, k_current_get()); + } + + return r; +} + +/** + * @brief Return an RTIO context to a pool + * + * @param pool RTIO pool to return a context to + * @param r RTIO context to return to the pool + */ +__syscall void rtio_pool_release(struct rtio_pool *pool, struct rtio *r); + +static inline void z_impl_rtio_pool_release(struct rtio_pool *pool, struct rtio *r) +{ + + if (k_is_user_context()) { + rtio_access_revoke(r, k_current_get()); + } + + for (size_t i = 0; i < pool->pool_size; i++) { + if (pool->contexts[i] == r) { + atomic_clear_bit(pool->used, i); + break; + } + } +} + +/* clang-format off */ + +/** @cond ignore */ + +#define Z_RTIO_POOL_NAME_N(n, name) \ + name##_##n + +#define Z_RTIO_POOL_DEFINE_N(n, name, sq_sz, cq_sz) \ + RTIO_DEFINE(Z_RTIO_POOL_NAME_N(n, name), sq_sz, cq_sz) + +#define Z_RTIO_POOL_REF_N(n, name) \ + &Z_RTIO_POOL_NAME_N(n, name) + +/** @endcond */ + +/** + * @brief Statically define and initialize a pool of RTIO contexts + * + * @param name Name of the RTIO pool + * @param pool_sz Number of RTIO contexts to allocate in the pool + * @param sq_sz Size of the submission queue entry pool per context + * @param cq_sz Size of the completion queue entry pool per context + */ +#define RTIO_POOL_DEFINE(name, pool_sz, sq_sz, cq_sz) \ + LISTIFY(pool_sz, Z_RTIO_POOL_DEFINE_N, (;), name, sq_sz, cq_sz); \ + static struct rtio *name##_contexts[] = { \ + LISTIFY(pool_sz, Z_RTIO_POOL_REF_N, (,), name) \ + }; \ + ATOMIC_DEFINE(name##_used, pool_sz); \ + STRUCT_SECTION_ITERABLE(rtio_pool, name) = { \ + .pool_size = pool_sz, \ + .contexts = name##_contexts, \ + .used = name##_used, \ + } + +/* clang-format on */ + /** * @} */ diff --git a/scripts/build/gen_kobject_list.py b/scripts/build/gen_kobject_list.py index 1d60c0df0fc9d..300c41319e668 100755 --- a/scripts/build/gen_kobject_list.py +++ b/scripts/build/gen_kobject_list.py @@ -114,6 +114,7 @@ ("ztest_test_rule", ("CONFIG_ZTEST", True, False)), ("rtio", ("CONFIG_RTIO", False, False)), ("rtio_iodev", ("CONFIG_RTIO", False, False)), + ("rtio_pool", ("CONFIG_RTIO", False, False)), ("sensor_decoder_api", ("CONFIG_SENSOR_ASYNC_API", True, False)) ]) diff --git a/subsys/rtio/CMakeLists.txt b/subsys/rtio/CMakeLists.txt index f75eaa7912af4..8fa968b771a65 100644 --- a/subsys/rtio/CMakeLists.txt +++ b/subsys/rtio/CMakeLists.txt @@ -11,7 +11,7 @@ if(CONFIG_RTIO) zephyr_library_sources(rtio_executor.c) zephyr_library_sources(rtio_init.c) zephyr_library_sources(rtio_sched.c) - zephyr_library_sources_ifdef(CONFIG_USERSPACE rtio_handlers.c) + zephyr_library_sources_ifdef(CONFIG_USERSPACE rtio_syscalls.c) endif() zephyr_library_sources_ifdef(CONFIG_RTIO_WORKQ rtio_workq.c) diff --git a/subsys/rtio/rtio_handlers.c b/subsys/rtio/rtio_syscalls.c similarity index 88% rename from subsys/rtio/rtio_handlers.c rename to subsys/rtio/rtio_syscalls.c index beb2a545c520b..08e91a508615f 100644 --- a/subsys/rtio/rtio_handlers.c +++ b/subsys/rtio/rtio_syscalls.c @@ -135,3 +135,22 @@ static inline int z_vrfy_rtio_submit(struct rtio *r, uint32_t wait_count) return z_impl_rtio_submit(r, wait_count); } #include + + +static inline struct rtio *z_vrfy_rtio_pool_acquire(struct rtio_pool *rpool) +{ + K_OOPS(K_SYSCALL_OBJ(rpool, K_OBJ_RTIO_POOL)); + + return z_impl_rtio_pool_acquire(rpool); +} +#include + + +static inline void z_vrfy_rtio_pool_release(struct rtio_pool *rpool, struct rtio *r) +{ + K_OOPS(K_SYSCALL_OBJ(rpool, K_OBJ_RTIO_POOL)); + K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO)); + + z_impl_rtio_pool_release(rpool, r); +} +#include diff --git a/tests/subsys/rtio/rtio_api/CMakeLists.txt b/tests/subsys/rtio/rtio_api/CMakeLists.txt index 88d15b5f0da54..c77376373284a 100644 --- a/tests/subsys/rtio/rtio_api/CMakeLists.txt +++ b/tests/subsys/rtio/rtio_api/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(rtio_api_test) -target_sources(app PRIVATE src/test_rtio_api.c) +target_sources(app PRIVATE src/test_rtio_api.c src/test_rtio_pool.c) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/include diff --git a/tests/subsys/rtio/rtio_api/src/test_rtio_pool.c b/tests/subsys/rtio/rtio_api/src/test_rtio_pool.c new file mode 100644 index 0000000000000..6904a18a4f51f --- /dev/null +++ b/tests/subsys/rtio/rtio_api/src/test_rtio_pool.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RTIO_POOL_DEFINE(rpool, 2, 8, 8); + +#ifdef CONFIG_USERSPACE +struct k_mem_domain pool_domain; +#endif + + +ZTEST_USER(rtio_pool, test_rtio_pool_acquire_release) +{ + struct rtio *r = rtio_pool_acquire(&rpool); + + zassert_not_null(r, "expected valid rtio context"); + + struct rtio_sqe nop_sqe; + struct rtio_cqe nop_cqe; + + rtio_sqe_prep_nop(&nop_sqe, NULL, NULL); + rtio_sqe_copy_in(r, &nop_sqe, 1); + rtio_submit(r, 1); + rtio_cqe_copy_out(r, &nop_cqe, 1, K_FOREVER); + + rtio_pool_release(&rpool, r); +} + +static void *rtio_pool_setup(void) +{ +#ifdef CONFIG_USERSPACE + k_mem_domain_init(&pool_domain, 0, NULL); + k_mem_domain_add_partition(&pool_domain, &rtio_partition); +#if Z_LIBC_PARTITION_EXISTS + k_mem_domain_add_partition(&pool_domain, &z_libc_partition); +#endif /* Z_LIBC_PARTITION_EXISTS */ +#endif /* CONFIG_USERSPACE */ + + return NULL; +} + +static void rtio_pool_before(void *a) +{ + ARG_UNUSED(a); + +#ifdef CONFIG_USERSPACE + k_object_access_grant(&rpool, k_current_get()); +#endif /* CONFIG_USERSPACE */ +} + +ZTEST_SUITE(rtio_pool, NULL, rtio_pool_setup, rtio_pool_before, NULL, NULL); From b69c9c1f10081a58766268ecc583414b81991cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 10:21:03 +0200 Subject: [PATCH 0002/1076] net: include: icmp: doxygen fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Group name was incorrectly used as a brief description ; used the opportunity to fully clean-up file and group definition Signed-off-by: Benjamin Cabé --- include/zephyr/net/icmp.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/icmp.h b/include/zephyr/net/icmp.h index 9cfcd38cc539a..b1fa9ddd7cdfe 100644 --- a/include/zephyr/net/icmp.h +++ b/include/zephyr/net/icmp.h @@ -4,11 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -/** @file icmp.h - * - * @brief ICMP sending and receiving. +/** + * @file icmp.h + * @brief Header file for ICMP protocol support. + * @ingroup icmp * - * @defgroup icmp Send and receive IPv4 or IPv6 ICMP Echo Request messages. + * @defgroup icmp ICMP + * @brief Send and receive IPv4 or IPv6 ICMP (Internet Control Message Protocol) + * Echo Request messages. * @since 3.5 * @version 0.8.0 * @ingroup networking From 2a17181576e4a5b62870c6f0bcf8a71f5deea10a Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Fri, 22 Aug 2025 11:21:21 +0200 Subject: [PATCH 0003/1076] tests: drivers: uart: uart_error: Add missing pull up for nrf53 Add missing pull up to the overlay file. Signed-off-by: Piotr Kosycarz --- .../uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay index 9be4328f7d19a..711d6d19cfc10 100644 --- a/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -3,8 +3,11 @@ &pinctrl { uart1_default_alt: uart1_default_alt { group1 { - psels = , - ; + psels = ; + bias-pull-up; + }; + group2 { + psels = ; }; }; From 6191f131d408f1e99025f6de867d07755264fed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 11:41:25 +0200 Subject: [PATCH 0004/1076] include: bindesc: doc: doxygen clean-ups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-organize groups, including addition of a top level "Binary Descriptors" group that becomes the main entry in OS Services Add missing documentation to some API (bindesc_entry, with public fields, and bindesc_handle, opaque) Signed-off-by: Benjamin Cabé --- include/zephyr/bindesc.h | 78 ++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/include/zephyr/bindesc.h b/include/zephyr/bindesc.h index 88e51dbf89b9f..39305334d6a61 100644 --- a/include/zephyr/bindesc.h +++ b/include/zephyr/bindesc.h @@ -4,9 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for binary descriptors + * @ingroup bindesc + */ + #ifndef ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ #define ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ +/** + * @defgroup bindesc Binary Descriptors + * @ingroup os_services + * @{ + */ + #include #ifdef __cplusplus @@ -17,19 +29,28 @@ extern "C" { * Corresponds to the definitions in scripts/west_commands/bindesc.py. * Do not change without syncing the definitions in both files! */ + +/** Magic number used to identify binary descriptor sections in firmware images */ #define BINDESC_MAGIC 0xb9863e5a7ea46046 +/** Required memory alignment for binary descriptor entries */ #define BINDESC_ALIGNMENT 4 -#define BINDESC_TYPE_UINT 0x0 -#define BINDESC_TYPE_STR 0x1 -#define BINDESC_TYPE_BYTES 0x2 -#define BINDESC_TYPE_DESCRIPTORS_END 0xf -/* sizeof ignores the data as it's a flexible array */ + +/** @name Binary Descriptor Types */ +/** @{ */ +#define BINDESC_TYPE_UINT 0x0 /**< Unsigned integer data */ +#define BINDESC_TYPE_STR 0x1 /**< String data */ +#define BINDESC_TYPE_BYTES 0x2 /**< Byte array data */ +#define BINDESC_TYPE_DESCRIPTORS_END 0xf /**< Marks the end of binary descriptor section */ +/** @} */ + +/** Size of the header of a binary descriptor entry */ +/* Needed as sizeof ignores the data as it's a flexible array */ #define BINDESC_ENTRY_HEADER_SIZE (sizeof(struct bindesc_entry)) /** - * @brief Binary Descriptor Definition - * @defgroup bindesc_define Bindesc Define - * @ingroup os_services + * @brief Macros for defining binary descriptors in firmware images + * @defgroup bindesc_define Binary Descriptor Definition + * @ingroup bindesc * @{ */ @@ -119,6 +140,7 @@ extern "C" { /** The C++ compiler version */ #define BINDESC_ID_CXX_COMPILER_VERSION 0xb04 +/** The end of binary descriptor section */ #define BINDESC_TAG_DESCRIPTORS_END BINDESC_TAG(DESCRIPTORS_END, 0x0fff) /** @@ -292,9 +314,15 @@ extern "C" { * @} */ -/* - * An entry of the binary descriptor header. Each descriptor is - * described by one of these entries. +/** + * @brief Functions for reading binary descriptors from firmware images + * @defgroup bindesc_read Binary Descriptor Reading + * @ingroup bindesc + * @{ + */ + +/** + * @brief Structure for a binary descriptor entry */ struct bindesc_entry { /** Tag of the entry */ @@ -305,6 +333,7 @@ struct bindesc_entry { uint8_t data[]; } __packed; +/** @cond INTERNAL_HIDDEN */ /* * We're assuming that `struct bindesc_entry` has a specific layout in * memory, so it's worth making sure that the layout is really what we @@ -314,8 +343,13 @@ struct bindesc_entry { BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout"); BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout"); BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout"); +/** @endcond */ +/** + * @brief Handle for reading binary descriptors from firmware images + */ struct bindesc_handle { + /** @cond INTERNAL_HIDDEN */ const uint8_t *address; enum { BINDESC_HANDLE_TYPE_RAM, @@ -328,15 +362,9 @@ struct bindesc_handle { uint8_t buffer[sizeof(struct bindesc_entry) + CONFIG_BINDESC_READ_FLASH_MAX_DATA_SIZE] __aligned(BINDESC_ALIGNMENT); #endif /* IS_ENABLED(CONFIG_BINDESC_READ_FLASH) */ + /** @endcond */ }; -/** - * @brief Reading Binary Descriptors of other images. - * @defgroup bindesc_read Bindesc Read - * @ingroup os_services - * @{ - */ - /** * @brief Callback type to be called on descriptors found during a walk * @@ -355,7 +383,7 @@ typedef int (*bindesc_callback_t)(const struct bindesc_entry *entry, void *user_ * Memory mapped flash is any flash that can be directly accessed by the CPU, * without needing to use the flash API for copying the data to RAM. * - * @param handle Bindesc handle to be given to subsequent calls + * @param[out] handle Bindesc handle to be given to subsequent calls * @param offset The offset from the beginning of the flash that the bindesc magic can be found at * * @retval 0 On success @@ -371,9 +399,9 @@ int bindesc_open_memory_mapped_flash(struct bindesc_handle *handle, size_t offse * It's assumed that the whole bindesc context was copied to RAM prior to calling * this function, either by the user or by a bootloader. * - * @note The given address must be aligned to BINDESC_ALIGNMENT + * @note The given address must be aligned to @ref BINDESC_ALIGNMENT * - * @param handle Bindesc handle to be given to subsequent calls + * @param[out] handle Bindesc handle to be given to subsequent calls * @param address The address that the bindesc magic can be found at * @param max_size Maximum size of the given buffer * @@ -392,10 +420,12 @@ int bindesc_open_ram(struct bindesc_handle *handle, const uint8_t *address, size * backend requires reading the data from flash to an internal buffer * using the flash API * - * @param handle Bindesc handle to be given to subsequent calls + * @param[out] handle Bindesc handle to be given to subsequent calls * @param offset The offset from the beginning of the flash that the bindesc magic can be found at * @param flash_device Flash device to read descriptors from * + * @kconfig_dep{CONFIG_BINDESC_READ_FLASH} + * * @retval 0 On success * @retval -ENOENT If no bindesc magic was found at the given offset */ @@ -599,4 +629,8 @@ extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version); } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ */ From db15de527442c4842c52e125e3d2e29b7b1f6e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=BCanowski?= Date: Wed, 20 Aug 2025 16:33:02 +0200 Subject: [PATCH 0005/1076] drivers: serial: stm32: fix race condition when both APIs enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a bug where if CONFIG_UART_ASYNC_API was enabled in the config, the interrupt flags would get cleared after the interrupt driven API callback finished executing, causing data loss if data happened to arrive after the callback but before the flags were cleared. Signed-off-by: Kamil Krzyżanowski --- drivers/serial/uart_stm32.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index f81a5f04df0e8..3d521fd593265 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -1359,6 +1359,16 @@ static void uart_stm32_isr(const struct device *dev) #endif #ifdef CONFIG_UART_ASYNC_API +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + /* If both ASYNC and INTERRUPT modes are supported in this build, + * check whether this instance is currently being used via the + * interrupt-driven API. If it is, do not process interrupt flags + * as the user callback invoked earlier is responsible for that. + */ + if (data->user_cb) { + return; + } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ if (LL_USART_IsEnabledIT_IDLE(usart) && LL_USART_IsActiveFlag_IDLE(usart)) { From 71be3c2823c70184f908cccaa87c64afee46bcee Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 20 Aug 2025 17:06:46 +0200 Subject: [PATCH 0006/1076] dts: bflb: fix bad uart device address 4 didnt become a 2 like it should have Signed-off-by: Camille BAUD --- dts/riscv/bflb/bl61x.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index 5e4de9d544e95..52125202774a7 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -156,9 +156,9 @@ status = "disabled"; }; - uart1: uart@4000a100 { + uart1: uart@2000a100 { compatible = "bflb,uart"; - reg = <0x4000a100 0x100>; + reg = <0x2000a100 0x100>; interrupts = <45 1>; interrupt-parent = <&clic>; status = "disabled"; From 089df60140962ff8e8ffe699ca6e9bf2cdd828ac Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 20 Aug 2025 13:57:51 -0300 Subject: [PATCH 0007/1076] bluetooth: esp32: fix VHCI semaphore misuse in HCI send path The TX flow control semaphore was initialized with a count of 1 and released again after every bt_esp32_send() call. This broke the VHCI flow control contract and could allow sending more packets than the controller advertised. This prevents host/controller overruns and ensures proper synchronization with the ESP32 VHCI interface. Signed-off-by: Sylvio Alves --- drivers/bluetooth/hci/hci_esp32.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/bluetooth/hci/hci_esp32.c b/drivers/bluetooth/hci/hci_esp32.c index c546e33fdb35d..6f58a84e9cc1f 100644 --- a/drivers/bluetooth/hci/hci_esp32.c +++ b/drivers/bluetooth/hci/hci_esp32.c @@ -25,7 +25,8 @@ struct bt_esp32_data { bt_hci_recv_t recv; }; -static K_SEM_DEFINE(hci_send_sem, 1, 1); +/* VHCI notifies when exactly one more HCI packet can be sent */ +static K_SEM_DEFINE(hci_send_sem, 0, 1); static bool is_hci_event_discardable(const uint8_t *evt_data) { @@ -64,7 +65,7 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining) return NULL; } - discardable = is_hci_event_discardable(data); + discardable = is_hci_event_discardable(data, remaining); memcpy((void *)&hdr, data, sizeof(hdr)); data += sizeof(hdr); @@ -242,22 +243,21 @@ static int bt_esp32_send(const struct device *dev, struct net_buf *buf) LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:"); - if (!esp_vhci_host_check_send_available()) { - LOG_WRN("Controller not ready to receive packets"); - } - - if (k_sem_take(&hci_send_sem, HCI_BT_ESP32_TIMEOUT) == 0) { - esp_vhci_host_send_packet(buf->data, buf->len); - } else { + /* Wait for controller credit (callback gives the semaphore) */ + if (k_sem_take(&hci_send_sem, HCI_BT_ESP32_TIMEOUT) != 0) { LOG_ERR("Send packet timeout error"); err = -ETIMEDOUT; + } else { + if (!esp_vhci_host_check_send_available()) { + LOG_WRN("VHCI not available, sending anyway"); + } + esp_vhci_host_send_packet(buf->data, buf->len); } if (!err) { net_buf_unref(buf); } - k_sem_give(&hci_send_sem); return err; } @@ -291,6 +291,10 @@ static int bt_esp32_ble_init(void) esp_vhci_host_register_callback(&vhci_host_cb); + if (esp_vhci_host_check_send_available()) { + k_sem_give(&hci_send_sem); + } + return 0; } @@ -318,6 +322,8 @@ static int bt_esp32_open(const struct device *dev, bt_hci_recv_t recv) struct bt_esp32_data *hci = dev->data; int err; + k_sem_reset(&hci_send_sem); + err = bt_esp32_ble_init(); if (err) { return err; From 7305e109fb0724684a258c7a8afb52bea7bc05d4 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 20 Aug 2025 14:25:18 -0300 Subject: [PATCH 0008/1076] bluetooth: esp32: make LE discardability length-safe Determine event discardability after parsing the HCI header and require at least one byte before reading the LE subevent. This removes a possible OOB read on malformed/short LE Meta events. Also mark LE Extended Advertising Report as discardable, matching legacy Advertising Report to reduce RX pool pressure during heavy scanning. Signed-off-by: Sylvio Alves --- drivers/bluetooth/hci/hci_esp32.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/hci_esp32.c b/drivers/bluetooth/hci/hci_esp32.c index 6f58a84e9cc1f..efb4ca0c9b66d 100644 --- a/drivers/bluetooth/hci/hci_esp32.c +++ b/drivers/bluetooth/hci/hci_esp32.c @@ -28,21 +28,24 @@ struct bt_esp32_data { /* VHCI notifies when exactly one more HCI packet can be sent */ static K_SEM_DEFINE(hci_send_sem, 0, 1); -static bool is_hci_event_discardable(const uint8_t *evt_data) +static bool is_hci_event_discardable(uint8_t evt_code, const uint8_t *payload, size_t plen) { - uint8_t evt_type = evt_data[0]; - - switch (evt_type) { + switch (evt_code) { #if defined(CONFIG_BT_CLASSIC) case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: return true; #endif case BT_HCI_EVT_LE_META_EVENT: { - uint8_t subevt_type = evt_data[sizeof(struct bt_hci_evt_hdr)]; + /* Need at least 1 byte to read LE subevent safely */ + if (plen < 1U) { + return false; + } + uint8_t subevt_type = payload[0]; switch (subevt_type) { case BT_HCI_EVT_LE_ADVERTISING_REPORT: + case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: return true; default: return false; @@ -65,8 +68,6 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining) return NULL; } - discardable = is_hci_event_discardable(data, remaining); - memcpy((void *)&hdr, data, sizeof(hdr)); data += sizeof(hdr); remaining -= sizeof(hdr); @@ -77,6 +78,8 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining) } LOG_DBG("len %u", hdr.len); + discardable = is_hci_event_discardable(hdr.evt, data, remaining); + buf = bt_buf_get_evt(hdr.evt, discardable, K_NO_WAIT); if (!buf) { if (discardable) { From 6ae130b4a5915c00277917bdd89425b94ddccb93 Mon Sep 17 00:00:00 2001 From: David Leach Date: Wed, 20 Aug 2025 14:26:02 -0500 Subject: [PATCH 0009/1076] manifest: hal_nxp: clean up unneeded files Last update included files not needed in the NXP HAL Signed-off-by: David Leach --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a564256794447..f0b929d621ae2 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 54ebe9bfd5ecc96ee68ad54f710d92732bcc401d + revision: fc66564174efb80056851598d611b3353de2e374 path: modules/hal/nxp groups: - hal From 9e7313d98214a11e59e5338748234f761497f71c Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Wed, 20 Aug 2025 16:18:16 -0600 Subject: [PATCH 0010/1076] drivers: memc: MAX32 memc linker support improvements In order to allow the linker to place certain objects into external RAM, e.g. heaps, adjust the memc initialization level to PRE_KERNEL_1, allowing clock control and memc to come up before priority objects like heaps are initialized. Signed-off-by: Pete Johanson --- drivers/memc/Kconfig.max32_hpb | 7 +++++++ drivers/memc/memc_max32_hpb.c | 2 +- tests/drivers/memc/ram/boards/apard32690_max32690_m4.conf | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/memc/ram/boards/apard32690_max32690_m4.conf diff --git a/drivers/memc/Kconfig.max32_hpb b/drivers/memc/Kconfig.max32_hpb index b1976eb2439be..78b7fbc206bd1 100644 --- a/drivers/memc/Kconfig.max32_hpb +++ b/drivers/memc/Kconfig.max32_hpb @@ -8,3 +8,10 @@ config MEMC_MAX32_HPB select PINCTRL help Enable ADI MAX32 HyperBus controller. + + If you want to rely on the linker to place symbols in this memory + (using`zephyr_code_relocate() or Z_GENERIC_SECTION()), you have to + ensure this driver in initialized before KERNEL_INIT_PRIORITY_OBJECTS + (=30). In addition, this driver depends on a clock, so you have to + ensure the clock will be started before this driver as well (see + CLOCK_CONTROL_INIT_PRIORITY) diff --git a/drivers/memc/memc_max32_hpb.c b/drivers/memc/memc_max32_hpb.c index 5afc9e35e9a03..eeb3f57c4feac 100644 --- a/drivers/memc/memc_max32_hpb.c +++ b/drivers/memc/memc_max32_hpb.c @@ -136,5 +136,5 @@ static const struct memc_max32_hpb_config config = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; -DEVICE_DT_INST_DEFINE(0, memc_max32_hpb_init, NULL, NULL, &config, POST_KERNEL, +DEVICE_DT_INST_DEFINE(0, memc_max32_hpb_init, NULL, NULL, &config, PRE_KERNEL_1, CONFIG_MEMC_INIT_PRIORITY, NULL); diff --git a/tests/drivers/memc/ram/boards/apard32690_max32690_m4.conf b/tests/drivers/memc/ram/boards/apard32690_max32690_m4.conf new file mode 100644 index 0000000000000..43398485d6218 --- /dev/null +++ b/tests/drivers/memc/ram/boards/apard32690_max32690_m4.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_MEMC=y +CONFIG_CLOCK_CONTROL_INIT_PRIORITY=15 +CONFIG_MEMC_INIT_PRIORITY=20 From 5945a3fcd1eb6fcc704c39fa138ccb724150e6e0 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Wed, 20 Aug 2025 21:49:52 -0400 Subject: [PATCH 0011/1076] ethernet: nxp: Scrub tx_header As it's not being used anywhere in the driver. Moreover, the extra unref would trigger a double-free assert (#94311); which is what motivated this cleanup. Signed-off-by: Luis Ubieda --- drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c | 7 ------- drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c index 93178fb91f293..f01288acd141f 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c +++ b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c @@ -131,12 +131,7 @@ static int eth_nxp_enet_qos_tx(const struct device *dev, struct net_pkt *pkt) k_thread_name_get(k_current_get())); net_pkt_ref(pkt); - data->tx.pkt = pkt; - /* Need to save the header because the ethernet stack - * otherwise discards it from the packet after this call - */ - data->tx.tx_header = pkt->frags; LOG_DBG("Setting up TX descriptors for packet %p", pkt); @@ -197,8 +192,6 @@ static void tx_dma_done(const struct device *dev) net_pkt_frag_unref(fragment); fragment = fragment->frags; } - - net_pkt_frag_unref(data->tx.tx_header); net_pkt_unref(pkt); eth_stats_update_pkts_tx(data->iface); diff --git a/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h b/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h index bdc70108e8d2d..0df3736ad5d72 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h +++ b/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h @@ -106,7 +106,6 @@ struct nxp_enet_qos_mac_config { struct nxp_enet_qos_tx_data { struct k_sem tx_sem; struct net_pkt *pkt; - struct net_buf *tx_header; volatile union nxp_enet_qos_tx_desc descriptors[NUM_TX_BUFDESC]; }; From 9cb38ecf582ed69378b631f4ebaf8805b6168153 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Fri, 22 Aug 2025 11:49:14 -0500 Subject: [PATCH 0012/1076] drivers: mcux_os_timer: Fix build failure z_nxp_os_timer_ignore_timer_wakeup() was only added when Standby mode was enabled. Move this function out of the conditional section. Signed-off-by: Mahesh Mahadevan --- drivers/timer/mcux_os_timer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/timer/mcux_os_timer.c b/drivers/timer/mcux_os_timer.c index 40719f9b907a0..0fb6128789ed1 100644 --- a/drivers/timer/mcux_os_timer.c +++ b/drivers/timer/mcux_os_timer.c @@ -43,12 +43,12 @@ static const struct device *counter_dev = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(0, deep_sleep_counter)); /* Indicates if the counter is running. */ static bool counter_running; +static uint32_t counter_max_val; +#endif /* Indicates we received a call with ticks set to wait forever */ static bool wait_forever; /* Incase of counter overflow, track the remaining ticks left */ static uint32_t counter_remaining_ticks; -static uint32_t counter_max_val; -#endif static uint64_t mcux_lpc_ostick_get_compensated_timer_value(void) { @@ -191,11 +191,6 @@ static uint32_t mcux_lpc_ostick_compensate_system_timer(void) return 0; } -bool z_nxp_os_timer_ignore_timer_wakeup(void) -{ - return (wait_forever || counter_remaining_ticks); -} - static uint32_t mcux_os_timer_set_lp_counter_timeout(void) { uint64_t timeout; @@ -233,6 +228,11 @@ static uint32_t mcux_os_timer_set_lp_counter_timeout(void) #define mcux_os_timer_set_lp_counter_timeout(...) do { } while (0) #endif +bool z_nxp_os_timer_ignore_timer_wakeup(void) +{ + return (wait_forever || counter_remaining_ticks); +} + void sys_clock_set_timeout(int32_t ticks, bool idle) { if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { From bd8a2d3db4ee39eaea5c8ae84295bcbeead5dfb9 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Fri, 22 Aug 2025 12:00:30 -0500 Subject: [PATCH 0013/1076] soc: rw: Fix build failures when include RTC header files Include the RTC header files only for when Standby power mode is enabled. Signed-off-by: Mahesh Mahadevan --- soc/nxp/rw/power.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/nxp/rw/power.c b/soc/nxp/rw/power.c index f7e9bfe869832..09000c3a8359d 100644 --- a/soc/nxp/rw/power.c +++ b/soc/nxp/rw/power.c @@ -6,7 +6,9 @@ #include #include #include +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(standby)) #include +#endif #include #include #if CONFIG_GPIO && (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pin0)) || \ @@ -220,7 +222,9 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) CLOCK_AttachClk(kLPOSC_to_OSTIMER_CLK); /* Clear the RTC wakeup bits */ POWER_ClearWakeupStatus(DT_IRQN(DT_NODELABEL(rtc))); +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(standby)) RTC_ClearStatusFlags(RTC, kRTC_WakeupFlag); +#endif NVIC_ClearPendingIRQ(DT_IRQN(DT_NODELABEL(rtc))); sys_clock_idle_exit(); sys_clock_set_timeout(0, true); From 617b71bc174be034b6b910792ea922c47b568068 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Sun, 24 Aug 2025 19:00:49 +0200 Subject: [PATCH 0014/1076] doc: update pyOCD repository links The repository has been moved to a new organization, see https://pyocd.io/. Update links to the pyOCD repository. Signed-off-by: Johann Fischer --- boards/96boards/nitrogen/doc/index.rst | 4 ++-- doc/develop/debug/index.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/96boards/nitrogen/doc/index.rst b/boards/96boards/nitrogen/doc/index.rst index df3d0236ca596..3984192308681 100644 --- a/boards/96boards/nitrogen/doc/index.rst +++ b/boards/96boards/nitrogen/doc/index.rst @@ -311,7 +311,7 @@ You can debug an application in the usual way. Here is an example for the :goals: debug .. _pyOCD: - https://github.com/mbedmicro/pyOCD + https://github.com/pyocd/pyOCD .. _CMSIS DAP: https://developer.mbed.org/handbook/CMSIS-DAP @@ -323,7 +323,7 @@ You can debug an application in the usual way. Here is an example for the http://wiki.seeed.cc/BLE_Nitrogen/ .. _pyOCD issue 259: - https://github.com/mbedmicro/pyOCD/issues/259 + https://github.com/pyocd/pyOCD/issues/259 .. _96Boards IE Specification: https://linaro.co/ie-specification diff --git a/doc/develop/debug/index.rst b/doc/develop/debug/index.rst index b96cf263e7271..10571d3151cde 100644 --- a/doc/develop/debug/index.rst +++ b/doc/develop/debug/index.rst @@ -363,4 +363,4 @@ in the log. .. _Eclipse IDE for C/C++ Developers: https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/oxygen2 .. _GNU MCU Eclipse plug-ins: https://gnu-mcu-eclipse.github.io/plugins/install/ -.. _pyOCD v0.11.0: https://github.com/mbedmicro/pyOCD/releases/tag/v0.11.0 +.. _pyOCD v0.11.0: https://github.com/pyocd/pyOCD/releases/tag/v0.11.0 From 5a1065c37f8864296923e590e557533a5b3aa241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 2 Jul 2025 18:05:20 +0200 Subject: [PATCH 0015/1076] scripts: ci: differentiate warnings from failures in compliance_check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have a few checks that report warnings, and for some of them it's actually the _only_ type of failure they report, so it can be confusing when the output of check_compliance.py says the "check failed" and lists all the things that are effectively warnings as "ERROR"s. This commit makes the output more clear by differentiating between warnings and actual errors, both when printing out individual failures, but also when printing the summary for each test case (ie. a test case is said to be "failing" only when it has at least one error, and is only showing up as having warnings if it only contains... warnings). Signed-off-by: Benjamin Cabé --- scripts/ci/check_compliance.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 4fcae2e6b1faf..138b484e9a566 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -2288,6 +2288,7 @@ def _main(args): xml.write(args.output, pretty=True) failed_cases = [] + warning_cases = [] name2doc = {testcase.name: testcase.doc for testcase in inheritors(ComplianceTest)} @@ -2296,19 +2297,31 @@ def _main(args): if case.is_skipped: logging.warning(f"Skipped {case.name}") else: - failed_cases.append(case) + if any(res.type in ('error', 'failure') for res in case.result): + failed_cases.append(case) + else: + warning_cases.append(case) else: # Some checks can produce no .result logging.info(f"No JUnit result for {case.name}") n_fails = len(failed_cases) + n_warnings = len(warning_cases) - if n_fails: - print(f"{n_fails} checks failed") - for case in failed_cases: + if n_fails or n_warnings: + if n_fails: + print(f"{n_fails} check(s) failed") + if n_warnings: + print(f"{n_warnings} check(s) with warnings only") + + for case in failed_cases + warning_cases: for res in case.result: errmsg = res.text.strip() - logging.error(f"Test {case.name} failed: \n{errmsg}") + if res.type in ('error', 'failure'): + logging.error(f"Test {case.name} failed: \n{errmsg}") + else: + logging.warning(f"Test {case.name} warning: \n{errmsg}") + if args.no_case_output: continue with open(f"{case.name}.txt", "w") as f: From 4363d14bef9e62d7e05f72769b46785f272b6b20 Mon Sep 17 00:00:00 2001 From: Alen Karnil Date: Tue, 29 Jul 2025 12:51:48 +0100 Subject: [PATCH 0016/1076] dts: arm: st: stm32f303: fix I2C3 address in nodename Correct stm32f303 I2C3 address in nodename. Signed-off-by: Alen Karnil --- dts/arm/st/f3/stm32f303Xe.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/st/f3/stm32f303Xe.dtsi b/dts/arm/st/f3/stm32f303Xe.dtsi index e3ec3d7388d34..7d4ba86e59cab 100644 --- a/dts/arm/st/f3/stm32f303Xe.dtsi +++ b/dts/arm/st/f3/stm32f303Xe.dtsi @@ -121,7 +121,7 @@ }; }; - i2c3: i2c@4007800 { + i2c3: i2c@40007800 { compatible = "st,stm32-i2c-v2"; clock-frequency = ; #address-cells = <1>; From 0111cc903031fd32bb8187c4ee44ddb125dcbb5b Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 24 Jul 2025 13:17:17 -0700 Subject: [PATCH 0017/1076] kernel: Execute function on another CPU Adds infrastructure to allow the execution of a function on a different CPU. The function to be executed on another CPU runs within the IPI handler at ISR level (and is thus subject to those constraints). Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 91 +++++++++++++++++++++++++++++++ include/zephyr/kernel_structs.h | 4 ++ kernel/Kconfig.smp | 1 + kernel/init.c | 5 ++ kernel/ipi.c | 94 ++++++++++++++++++++++++++++++++- 5 files changed, 194 insertions(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 7fe1920c14701..a6aa3dddf1182 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -3416,6 +3416,97 @@ static inline unsigned int z_impl_k_sem_count_get(struct k_sem *sem) /** @} */ +#if defined(CONFIG_SCHED_IPI_SUPPORTED) || defined(__DOXYGEN__) +struct k_ipi_work; + +/** + * @cond INTERNAL_HIDDEN + */ + +typedef void (*k_ipi_func_t)(struct k_ipi_work *work); + +struct k_ipi_work { + sys_dnode_t node[CONFIG_MP_MAX_NUM_CPUS]; /* Node in IPI work queue */ + k_ipi_func_t func; /* Function to execute on target CPU */ + struct k_event event; /* Event to signal when processed */ + uint32_t bitmask; /* Bitmask of targeted CPUs */ +}; + +/** @endcond */ + +/** + * @brief Initialize the specified IPI work item + * + * @kconfig_dep{CONFIG_SCHED_IPI_SUPPORTED} + * + * @param work Pointer to the IPI work item to be initialized + */ +static inline void k_ipi_work_init(struct k_ipi_work *work) +{ + k_event_init(&work->event); + for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + sys_dnode_init(&work->node[i]); + } + work->bitmask = 0; +} + +/** + * @brief Add an IPI work item to the IPI work queue + * + * Adds the specified IPI work item to the IPI work queues of each CPU + * identified by @a cpu_bitmask. The specified IPI work item will subsequently + * execute at ISR level as those CPUs process their received IPIs. Do not + * re-use the specified IPI work item until it has been processed by all of + * the identified CPUs. + * + * @kconfig_dep{CONFIG_SCHED_IPI_SUPPORTED} + * + * @param work Pointer to the IPI work item + * @param cpu_bitmask Set of CPUs to which the IPI work item will be sent + * @param func Function to execute on the targeted CPU(s) + * + * @retval 0 on success + * @retval -EBUSY if the specified IPI work item is still being processed + */ +int k_ipi_work_add(struct k_ipi_work *work, uint32_t cpu_bitmask, + k_ipi_func_t func); + +/** + * @brief Wait until the IPI work item has been processed by all targeted CPUs + * + * This routine waits until the IPI work item has been processed by all CPUs + * to which it was sent. If called from an ISR, then @a timeout must be set to + * K_NO_WAIT. To prevent deadlocks the caller must not have IRQs locked when + * calling this function. + * + * @note It is not in general possible to poll safely for completion of this + * function in ISR or locked contexts where the calling CPU cannot service IPIs + * (because the targeted CPUs may themselves be waiting on the calling CPU). + * Application code must be prepared for failure or to poll from a thread + * context. + * + * @kconfig_dep{CONFIG_SCHED_IPI_SUPPORTED} + * + * @param work Pointer to the IPI work item + * @param timeout Maximum time to wait for IPI work to be processed + * + * @retval -EAGAIN Waiting period timed out. + * @retval 0 if processed by all targeted CPUs + */ +int k_ipi_work_wait(struct k_ipi_work *work, k_timeout_t timeout); + +/** + * @brief Signal that there is one or more IPI work items to process + * + * This routine sends an IPI to the set of CPUs identified by calls to + * k_ipi_work_add() since this CPU sent its last set of IPIs. + * + * @kconfig_dep{CONFIG_SCHED_IPI_SUPPORTED} + */ +void k_ipi_work_signal(void); + +#endif /* CONFIG_SCHED_IPI_SUPPORTED */ + /** * @cond INTERNAL_HIDDEN */ diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 5bf9ae6df1c50..be883530b842a 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -196,6 +196,10 @@ struct _cpu { struct k_obj_core obj_core; #endif +#ifdef CONFIG_SCHED_IPI_SUPPORTED + sys_dlist_t ipi_workq; +#endif + /* Per CPU architecture specifics */ struct _cpu_arch arch; }; diff --git a/kernel/Kconfig.smp b/kernel/Kconfig.smp index 33bc58a311ac3..3aecfccb7658d 100644 --- a/kernel/Kconfig.smp +++ b/kernel/Kconfig.smp @@ -48,6 +48,7 @@ config MP_MAX_NUM_CPUS config SCHED_IPI_SUPPORTED bool + select EVENTS help True if the architecture supports a call to arch_sched_broadcast_ipi() to broadcast an interrupt that will call z_sched_ipi() on other CPUs diff --git a/kernel/init.c b/kernel/init.c index dd9f3d7258f58..3cdf1ef36a34b 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -657,6 +658,10 @@ void z_init_cpu(int id) sizeof(struct k_cycle_stats)); #endif #endif + +#ifdef CONFIG_SCHED_IPI_SUPPORTED + sys_dlist_init(&_kernel.cpus[id].ipi_workq); +#endif } /** diff --git a/kernel/ipi.c b/kernel/ipi.c index 3c16fa1369746..a6b6ad6db4291 100644 --- a/kernel/ipi.c +++ b/kernel/ipi.c @@ -8,11 +8,12 @@ #include #include +static struct k_spinlock ipi_lock; + #ifdef CONFIG_TRACE_SCHED_IPI extern void z_trace_sched_ipi(void); #endif - void flag_ipi(uint32_t ipi_mask) { #if defined(CONFIG_SCHED_IPI_SUPPORTED) @@ -75,6 +76,7 @@ void signal_pending_ipi(void) * pending_ipi, the IPI will be sent the next time through * this code. */ + #if defined(CONFIG_SCHED_IPI_SUPPORTED) if (arch_num_cpus() > 1) { uint32_t cpu_bitmap; @@ -91,6 +93,92 @@ void signal_pending_ipi(void) #endif /* CONFIG_SCHED_IPI_SUPPORTED */ } +#ifdef CONFIG_SCHED_IPI_SUPPORTED +static struct k_ipi_work *first_ipi_work(sys_dlist_t *list) +{ + sys_dnode_t *work = sys_dlist_peek_head(list); + unsigned int cpu_id = _current_cpu->id; + + return (work == NULL) ? NULL + : CONTAINER_OF(work, struct k_ipi_work, node[cpu_id]); +} + +int k_ipi_work_add(struct k_ipi_work *work, uint32_t cpu_bitmask, + k_ipi_func_t func) +{ + __ASSERT(work != NULL, ""); + __ASSERT(func != NULL, ""); + + k_spinlock_key_t key = k_spin_lock(&ipi_lock); + + /* Verify the IPI work item is not currently in use */ + + if (k_event_wait_all(&work->event, work->bitmask, + false, K_NO_WAIT) != work->bitmask) { + k_spin_unlock(&ipi_lock, key); + return -EBUSY; + } + + /* + * Add the IPI work item to the list(s)--but not for the current + * CPU as the architecture may not support sending an IPI to itself. + */ + + unsigned int cpu_id = _current_cpu->id; + + cpu_bitmask &= (IPI_ALL_CPUS_MASK & ~BIT(cpu_id)); + + k_event_clear(&work->event, IPI_ALL_CPUS_MASK); + work->func = func; + work->bitmask = cpu_bitmask; + + for (unsigned int id = 0; id < arch_num_cpus(); id++) { + if ((cpu_bitmask & BIT(id)) != 0) { + sys_dlist_append(&_kernel.cpus[id].ipi_workq, &work->node[id]); + } + } + + flag_ipi(cpu_bitmask); + + k_spin_unlock(&ipi_lock, key); + + return 0; +} + +int k_ipi_work_wait(struct k_ipi_work *work, k_timeout_t timeout) +{ + uint32_t rv = k_event_wait_all(&work->event, work->bitmask, + false, timeout); + + return (rv == 0) ? -EAGAIN : 0; +} + +void k_ipi_work_signal(void) +{ + signal_pending_ipi(); +} + +static void ipi_work_process(sys_dlist_t *list) +{ + unsigned int cpu_id = _current_cpu->id; + + k_spinlock_key_t key = k_spin_lock(&ipi_lock); + + for (struct k_ipi_work *work = first_ipi_work(list); + work != NULL; work = first_ipi_work(list)) { + sys_dlist_remove(&work->node[cpu_id]); + k_spin_unlock(&ipi_lock, key); + + work->func(work); + + key = k_spin_lock(&ipi_lock); + k_event_post(&work->event, BIT(cpu_id)); + } + + k_spin_unlock(&ipi_lock, key); +} +#endif /* CONFIG_SCHED_IPI_SUPPORTED */ + void z_sched_ipi(void) { /* NOTE: When adding code to this, make sure this is called @@ -109,4 +197,8 @@ void z_sched_ipi(void) #ifdef CONFIG_ARCH_IPI_LAZY_COPROCESSORS_SAVE arch_ipi_lazy_coprocessors_save(); #endif + +#ifdef CONFIG_SCHED_IPI_SUPPORTED + ipi_work_process(&_kernel.cpus[_current_cpu->id].ipi_workq); +#endif } From 17ba7e73838ec184f69f69b01b70dd1fe1af88f1 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 25 Jul 2025 12:06:18 -0700 Subject: [PATCH 0018/1076] doc: Add IPI work item Updates the SMP documentation to include notes on IPI work items. Signed-off-by: Peter Mitsis --- doc/kernel/services/smp/smp.rst | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/doc/kernel/services/smp/smp.rst b/doc/kernel/services/smp/smp.rst index 9a81609188cac..5cd448e38603c 100644 --- a/doc/kernel/services/smp/smp.rst +++ b/doc/kernel/services/smp/smp.rst @@ -264,6 +264,57 @@ they must be processed. The third is the apparent sputtering of a thread as it "winks in" and then "winks out" due to cascades stemming from the aforementioned first cost. +IPI Work Items +============== + +The kernel allows developers to execute functions on other CPUs at ISR level +using one or more IPI work items. After IPI work items have been added to the +specified CPUs' work queues using :c:func:`k_ipi_work_add`, the targeted CPUs +will process them after receiving an IPI. Signaling an IPI is done by calling +:c:func:`k_ipi_work_signal`. Waiting for an IPI work item to be completed by +the targeted CPUs is done by calling :c:func:`k_ipi_work_wait`. Only a single +waiter is permitted at a time. + +.. note:: + IPI work items will only be added to the IPI work queues of other CPUs. If + adding IPI work items at thread level, the developer must ensure that the + current thread does not change CPUs until after signaling the IPIs. + +Sample Use +---------- + +The following code outlines how to use IPI work items to update status +information across a set of CPUs as a result of one CPU handling an ISR. + +.. code-block:: c + + struct k_ipi_work my_work; + + void remote_cpu_action(struct k_ipi_work *arg) + { + ... + } + + void my_isr(void) + { + /* + * Wait for previous use of to complete. + * It assumes that was initialized elsewhere. + */ + + uint32_t cpu_mask = ; + + while (k_ipi_work_wait(&my_work, K_NO_WAIT) == -EAGAIN) { + } + + /* Add and signal the new work */ + + k_ipi_work_add(&my_work, cpu_mask, remote_cpu_action); + + k_ipi_signal(); + } + + SMP Kernel Internals ******************** From 9bdb17aa32d79ba1e4fd7fa7105a012f2a336f7c Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 25 Jul 2025 10:11:56 -0700 Subject: [PATCH 0019/1076] tests: Add test for IPI work items Adds a simple test case for IPI work items. Signed-off-by: Peter Mitsis --- tests/kernel/ipi_work/CMakeLists.txt | 7 ++ tests/kernel/ipi_work/prj.conf | 3 + tests/kernel/ipi_work/src/main.c | 133 +++++++++++++++++++++++++++ tests/kernel/ipi_work/testcase.yaml | 6 ++ 4 files changed, 149 insertions(+) create mode 100644 tests/kernel/ipi_work/CMakeLists.txt create mode 100644 tests/kernel/ipi_work/prj.conf create mode 100644 tests/kernel/ipi_work/src/main.c create mode 100644 tests/kernel/ipi_work/testcase.yaml diff --git a/tests/kernel/ipi_work/CMakeLists.txt b/tests/kernel/ipi_work/CMakeLists.txt new file mode 100644 index 0000000000000..f7e737818f4f5 --- /dev/null +++ b/tests/kernel/ipi_work/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(smp) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/kernel/ipi_work/prj.conf b/tests/kernel/ipi_work/prj.conf new file mode 100644 index 0000000000000..8d9afb748cb01 --- /dev/null +++ b/tests/kernel/ipi_work/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_SMP=y +CONFIG_IPI_OPTIMIZE=y diff --git a/tests/kernel/ipi_work/src/main.c b/tests/kernel/ipi_work/src/main.c new file mode 100644 index 0000000000000..9af35843bddc8 --- /dev/null +++ b/tests/kernel/ipi_work/src/main.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2025 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if (CONFIG_MP_MAX_NUM_CPUS == 1) +#error "This test must have at least CONFIG_MP_MAX_NUM_CPUS=2 CPUs" +#endif + +/* structs */ + +struct test_ipi_work { + struct k_ipi_work work; + + volatile unsigned int cpu_bit; +}; + +/* forward declarations */ + +static void timer_func(struct k_timer *tmr); + +/* locals */ + +static struct test_ipi_work test_item; +static K_SEM_DEFINE(timer_sem, 0, 1); +static K_TIMER_DEFINE(timer, timer_func, NULL); +static uint32_t timer_target_cpu; + +/** + * This function is called when the IPI work item is executed on a CPU. + * It sets the CPU ID in the test_item structure to indicate which CPU + * executed the work item. + * + * @param item Pointer to the IPI work item to be executed + */ +static void test_function(struct k_ipi_work *item) +{ + struct test_ipi_work *my_work; + unsigned int cpu; + + cpu = arch_curr_cpu()->id; + + my_work = CONTAINER_OF(item, struct test_ipi_work, work); + my_work->cpu_bit = BIT(cpu); +} + +/** + * Timer function that is called to initiate the IPI work from + * an ISR and to wait for the work item to complete. + */ +static void timer_func(struct k_timer *tmr) +{ + ARG_UNUSED(tmr); + + timer_target_cpu = _current_cpu->id == 0 ? BIT(1) : BIT(0); + + /* Add the work item to the IPI queue, signal and wait */ + + k_ipi_work_add(&test_item.work, timer_target_cpu, test_function); + k_ipi_work_signal(); + while (k_ipi_work_wait(&test_item.work, K_NO_WAIT) == -EAGAIN) { + } + + /* Wake the thread waiting for the work item to complete */ + k_sem_give(&timer_sem); + +} + +/** + * This test covers the simplest working cases of IPI work + * item execution and waiting. It adds a single IPI work item + * to another CPU's queue, signals it and waits for it to complete. + * Waiting covers two scenarios + * 1. From thread level + * 2. From a k_timer (ISR). + */ +ZTEST(ipi_work, test_ipi_work_simple) +{ + unsigned int key; + unsigned int cpu_id; + unsigned int target_cpu_mask; + int status; + + k_ipi_work_init(&test_item.work); + + /* + * Issue the IPI work item from thread level. The current thread will + * pend while waiting for work completion. Interrupts are locked to + * ensure that the current thread does not change CPUs while setting + * up the IPI work item. + */ + + TC_PRINT("Thread level IPI\n"); + + key = arch_irq_lock(); + cpu_id = arch_curr_cpu()->id; + target_cpu_mask = _current_cpu->id == 0 ? BIT(1) : BIT(0); + + test_item.cpu_bit = 0xFFFFFFFFU; + k_ipi_work_add(&test_item.work, target_cpu_mask, test_function); + k_ipi_work_signal(); + arch_irq_unlock(key); + + /* Wait for the work item to complete */ + + status = k_ipi_work_wait(&test_item.work, K_FOREVER); + zassert_equal(status, 0, "k_ipi_work_wait failed: %d", status); + + zassert_equal(test_item.cpu_bit, target_cpu_mask, + "Work item was not executed on the expected CPU"); + + /* + * Issue the IPI work item from a k_timer (ISR). The k_timer will spin + * while waiting for the IPI work item to complete. + */ + + TC_PRINT("ISR level IPI\n"); + + test_item.cpu_bit = 0xFFFFFFFFU; + k_timer_start(&timer, K_TICKS(2), K_NO_WAIT); + status = k_sem_take(&timer_sem, K_SECONDS(10)); + + zassert_equal(status, 0, "k_sem_take failed: %d", status); + zassert_equal(test_item.cpu_bit, timer_target_cpu, + "Work item was not executed on the expected CPU"); +} + +ZTEST_SUITE(ipi_work, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/kernel/ipi_work/testcase.yaml b/tests/kernel/ipi_work/testcase.yaml new file mode 100644 index 0000000000000..5fd378ff7444c --- /dev/null +++ b/tests/kernel/ipi_work/testcase.yaml @@ -0,0 +1,6 @@ +tests: + kernel.ipi_work: + tags: + - kernel + - smp + filter: (CONFIG_MP_MAX_NUM_CPUS > 1) and CONFIG_SCHED_IPI_SUPPORTED From 030b9f35975c8ec06f822d1e2783897de63fba5e Mon Sep 17 00:00:00 2001 From: Utsav Munendra Date: Wed, 20 Aug 2025 11:55:35 -0700 Subject: [PATCH 0020/1076] drivers: mspi: mspi_dw: Fix compilation with CONFIG_MSPI_XIP disabled Move `api_timing_config()` impl outside of the block gated behind CONFIG_MSPI_XIP. Signed-off-by: Utsav Munendra --- drivers/mspi/Kconfig.dw | 1 + drivers/mspi/mspi_dw.c | 32 ++++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/mspi/Kconfig.dw b/drivers/mspi/Kconfig.dw index d429cff044c01..06d2e09c8af19 100644 --- a/drivers/mspi/Kconfig.dw +++ b/drivers/mspi/Kconfig.dw @@ -8,6 +8,7 @@ config MSPI_DW depends on DT_HAS_SNPS_DESIGNWARE_SSI_ENABLED select PINCTRL if $(dt_compat_any_has_prop,$(DT_COMPAT_SNPS_DESIGNWARE_SSI),pinctrl-0) imply MSPI_XIP + imply MSPI_TIMING if MSPI_DW diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index 0c6d8d1516617..f4e775ead4376 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -1193,6 +1193,22 @@ static int api_transceive(const struct device *dev, return rc; } +#if defined(CONFIG_MSPI_TIMING) +static int api_timing_config(const struct device *dev, + const struct mspi_dev_id *dev_id, + const uint32_t param_mask, void *cfg) +{ + struct mspi_dw_data *dev_data = dev->data; + struct mspi_dw_timing_cfg *config = cfg; + + if (param_mask & MSPI_DW_RX_TIMING_CFG) { + dev_data->rx_sample_dly = config->rx_sample_dly; + return 0; + } + return -ENOTSUP; +} +#endif /* defined(CONFIG_MSPI_TIMING) */ + #if defined(CONFIG_MSPI_XIP) static int _api_xip_config(const struct device *dev, const struct mspi_dev_id *dev_id, @@ -1299,20 +1315,6 @@ static int _api_xip_config(const struct device *dev, return 0; } -static int api_timing_config(const struct device *dev, - const struct mspi_dev_id *dev_id, - const uint32_t param_mask, void *cfg) -{ - struct mspi_dw_data *dev_data = dev->data; - struct mspi_dw_timing_cfg *config = cfg; - - if (param_mask & MSPI_DW_RX_TIMING_CFG) { - dev_data->rx_sample_dly = config->rx_sample_dly; - return 0; - } - return -ENOTSUP; -} - static int api_xip_config(const struct device *dev, const struct mspi_dev_id *dev_id, const struct mspi_xip_cfg *cfg) @@ -1461,7 +1463,9 @@ static DEVICE_API(mspi, drv_api) = { .dev_config = api_dev_config, .get_channel_status = api_get_channel_status, .transceive = api_transceive, +#if defined(CONFIG_MSPI_TIMING) .timing_config = api_timing_config, +#endif #if defined(CONFIG_MSPI_XIP) .xip_config = api_xip_config, #endif From d59af08b1951c8e54bd678957da165d9e2c95160 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 20 Aug 2025 21:34:44 +0200 Subject: [PATCH 0021/1076] bluetooth: host: gatt: Compile out att cmds for long write proc `bt_att_recv`, which parses ATT PDUs, already contains code that responds with `BT_ATT_ERR_NOT_SUPPORTED` if a given handler is not implemented. Therefore, `att_prepare_write_req` and `att_exec_write_req` handlers do not need to explicitly return `BT_ATT_ERR_NOT_SUPPORTED` when `CONFIG_BT_ATT_PREPARE_COUNT` is set to 0 and can be completely removed. Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/host/att.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 04bf353fd5eab..3c707b4fdb276 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -2291,13 +2291,9 @@ static uint8_t att_prep_write_rsp(struct bt_att_chan *chan, uint16_t handle, return 0; } -#endif /* CONFIG_BT_ATT_PREPARE_COUNT */ static uint8_t att_prepare_write_req(struct bt_att_chan *chan, struct net_buf *buf) { -#if CONFIG_BT_ATT_PREPARE_COUNT == 0 - return BT_ATT_ERR_NOT_SUPPORTED; -#else struct bt_att_prepare_write_req *req; uint16_t handle, offset; @@ -2309,10 +2305,8 @@ static uint8_t att_prepare_write_req(struct bt_att_chan *chan, struct net_buf *b LOG_DBG("handle 0x%04x offset %u", handle, offset); return att_prep_write_rsp(chan, handle, offset, buf->data, buf->len); -#endif /* CONFIG_BT_ATT_PREPARE_COUNT */ } -#if CONFIG_BT_ATT_PREPARE_COUNT > 0 static uint8_t exec_write_reassemble(uint16_t handle, uint16_t offset, sys_slist_t *list, struct net_buf_simple *buf) @@ -2432,14 +2426,9 @@ static uint8_t att_exec_write_rsp(struct bt_att_chan *chan, uint8_t flags) return 0; } -#endif /* CONFIG_BT_ATT_PREPARE_COUNT */ - static uint8_t att_exec_write_req(struct bt_att_chan *chan, struct net_buf *buf) { -#if CONFIG_BT_ATT_PREPARE_COUNT == 0 - return BT_ATT_ERR_NOT_SUPPORTED; -#else struct bt_att_exec_write_req *req; req = (void *)buf->data; @@ -2447,8 +2436,8 @@ static uint8_t att_exec_write_req(struct bt_att_chan *chan, struct net_buf *buf) LOG_DBG("flags 0x%02x", req->flags); return att_exec_write_rsp(chan, req->flags); -#endif /* CONFIG_BT_ATT_PREPARE_COUNT */ } +#endif /* CONFIG_BT_ATT_PREPARE_COUNT > 0 */ static uint8_t att_write_cmd(struct bt_att_chan *chan, struct net_buf *buf) { @@ -2806,6 +2795,7 @@ static const struct att_handler { sizeof(struct bt_att_write_req), ATT_REQUEST, att_write_req }, +#if CONFIG_BT_ATT_PREPARE_COUNT > 0 { BT_ATT_OP_PREPARE_WRITE_REQ, sizeof(struct bt_att_prepare_write_req), ATT_REQUEST, @@ -2814,6 +2804,7 @@ static const struct att_handler { sizeof(struct bt_att_exec_write_req), ATT_REQUEST, att_exec_write_req }, +#endif /* CONFIG_BT_ATT_PREPARE_COUNT > 0 */ { BT_ATT_OP_CONFIRM, 0, ATT_CONFIRMATION, From 9135918249b36dbbd675db8c4f94173c147438f3 Mon Sep 17 00:00:00 2001 From: Mikhail Siomin Date: Sat, 26 Jul 2025 21:22:29 +0300 Subject: [PATCH 0022/1076] soc: st: stm32: fix ccm region name in linker Use the region name token to describe the location of sections. Because for some linkers (e.g. llvm lld) region_name and "region_name" are not the same. Signed-off-by: Mikhail Siomin --- soc/st/stm32/common/ccm.ld | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/st/stm32/common/ccm.ld b/soc/st/stm32/common/ccm.ld index 656b4567b6f37..bf9cf65d0306c 100644 --- a/soc/st/stm32/common/ccm.ld +++ b/soc/st/stm32/common/ccm.ld @@ -9,7 +9,7 @@ GROUP_START(CCM) *(.ccm_bss) *(".ccm_bss.*") __ccm_bss_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ccm))) + } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm))) SECTION_PROLOGUE(_CCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4)) { @@ -17,7 +17,7 @@ GROUP_START(CCM) *(.ccm_noinit) *(".ccm_noinit.*") __ccm_noinit_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ccm))) + } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm))) SECTION_PROLOGUE(_CCM_DATA_SECTION_NAME,,SUBALIGN(4)) { @@ -25,7 +25,7 @@ GROUP_START(CCM) *(.ccm_data) *(".ccm_data.*") __ccm_data_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ccm)) AT> ROMABLE_REGION) + } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm)) AT> ROMABLE_REGION) __ccm_end = .; From 034673bc89ba504f406cf56e6b4cf015566506aa Mon Sep 17 00:00:00 2001 From: Filip Stojanovic Date: Mon, 21 Jul 2025 21:47:58 +0200 Subject: [PATCH 0023/1076] dts: arm: st: add stm32h523Xe support Provide support for STM32H523XE. Signed-off-by: Filip Stojanovic --- dts/arm/st/h5/stm32h523.dtsi | 28 +++++++++++++++ dts/arm/st/h5/stm32h523Xe.dtsi | 36 +++++++++++++++++++ dts/arm/st/h5/stm32h533.dtsi | 18 ++-------- soc/st/stm32/soc.yml | 1 + .../stm32h5x/Kconfig.defconfig.stm32h523xx | 11 ++++++ soc/st/stm32/stm32h5x/Kconfig.soc | 5 +++ 6 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 dts/arm/st/h5/stm32h523.dtsi create mode 100644 dts/arm/st/h5/stm32h523Xe.dtsi create mode 100644 soc/st/stm32/stm32h5x/Kconfig.defconfig.stm32h523xx diff --git a/dts/arm/st/h5/stm32h523.dtsi b/dts/arm/st/h5/stm32h523.dtsi new file mode 100644 index 0000000000000..5e18e8a5524a0 --- /dev/null +++ b/dts/arm/st/h5/stm32h523.dtsi @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2025 Filip Stojanovic + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/ { + soc { + compatible = "st,stm32h523", "st,stm32h5", "simple-bus"; + + gpiof: gpio@42021400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x42021400 0x400>; + clocks = <&rcc STM32_CLOCK(AHB2, 7)>; + }; + + fmc: memory-controller@47000400 { + compatible = "st,stm32-fmc"; + reg = <0x47000400 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 16)>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/st/h5/stm32h523Xe.dtsi b/dts/arm/st/h5/stm32h523Xe.dtsi new file mode 100644 index 0000000000000..fc122088d298c --- /dev/null +++ b/dts/arm/st/h5/stm32h523Xe.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2025 Filip Stojanovic + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/ { + sram1: memory@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(128)>; + zephyr,memory-region = "SRAM1"; + }; + + sram2: memory@20040000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20040000 DT_SIZE_K(80)>; + zephyr,memory-region = "SRAM2"; + }; + + sram3: memory@20050000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20050000 DT_SIZE_K(64)>; + zephyr,memory-region = "SRAM3"; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(512)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h5/stm32h533.dtsi b/dts/arm/st/h5/stm32h533.dtsi index a3a4c69d63f91..fc07f895adaed 100644 --- a/dts/arm/st/h5/stm32h533.dtsi +++ b/dts/arm/st/h5/stm32h533.dtsi @@ -3,25 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include + +#include / { soc { compatible = "st,stm32h533", "st,stm32h5", "simple-bus"; - - gpiof: gpio@42021400 { - compatible = "st,stm32-gpio"; - gpio-controller; - #gpio-cells = <2>; - reg = <0x42021400 0x400>; - clocks = <&rcc STM32_CLOCK(AHB2, 7U)>; - }; - - fmc: memory-controller@47000400 { - compatible = "st,stm32-fmc"; - reg = <0x47000400 0x400>; - clocks = <&rcc STM32_CLOCK(AHB4, 16U)>; - status = "disabled"; - }; }; }; diff --git a/soc/st/stm32/soc.yml b/soc/st/stm32/soc.yml index 76fd943ad3e16..e09cd9b1eba80 100644 --- a/soc/st/stm32/soc.yml +++ b/soc/st/stm32/soc.yml @@ -104,6 +104,7 @@ family: - name: stm32h5x socs: - name: stm32h503xx + - name: stm32h523xx - name: stm32h533xx - name: stm32h562xx - name: stm32h563xx diff --git a/soc/st/stm32/stm32h5x/Kconfig.defconfig.stm32h523xx b/soc/st/stm32/stm32h5x/Kconfig.defconfig.stm32h523xx new file mode 100644 index 0000000000000..42503ad05ddda --- /dev/null +++ b/soc/st/stm32/stm32h5x/Kconfig.defconfig.stm32h523xx @@ -0,0 +1,11 @@ +# STMicroelectronics STM32H523XX MCU + +# Copyright (c) Filip Stojanovic +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32H523XX + +config NUM_IRQS + default 133 + +endif # SOC_STM32H523XX diff --git a/soc/st/stm32/stm32h5x/Kconfig.soc b/soc/st/stm32/stm32h5x/Kconfig.soc index abc8b16f34c7a..1afb40f8c080c 100644 --- a/soc/st/stm32/stm32h5x/Kconfig.soc +++ b/soc/st/stm32/stm32h5x/Kconfig.soc @@ -14,6 +14,10 @@ config SOC_STM32H503XX bool select SOC_SERIES_STM32H5X +config SOC_STM32H523XX + bool + select SOC_SERIES_STM32H5X + config SOC_STM32H533XX bool select SOC_SERIES_STM32H5X @@ -32,6 +36,7 @@ config SOC_STM32H573XX config SOC default "stm32h503xx" if SOC_STM32H503XX + default "stm32h523xx" if SOC_STM32H523XX default "stm32h533xx" if SOC_STM32H533XX default "stm32h562xx" if SOC_STM32H562XX default "stm32h563xx" if SOC_STM32H563XX From 2ccab02419830cf3d6e760796ae02a0aebb7546d Mon Sep 17 00:00:00 2001 From: Filip Stojanovic Date: Tue, 22 Jul 2025 21:19:05 +0200 Subject: [PATCH 0024/1076] boards: weact: blackpill_h523ce: Add board support This adds support for the WeAct blackpill_h523ce board. Signed-off-by: Filip Stojanovic --- .../blackpill_h523ce/Kconfig.blackpill_h523ce | 5 + .../blackpill_h523ce/blackpill_h523ce.dts | 155 ++++++++++++++++++ .../blackpill_h523ce/blackpill_h523ce.yaml | 17 ++ .../blackpill_h523ce_defconfig | 16 ++ boards/weact/blackpill_h523ce/board.cmake | 9 + boards/weact/blackpill_h523ce/board.yml | 6 + .../doc/img/blackpill_h523ce.webp | Bin 0 -> 5908 bytes boards/weact/blackpill_h523ce/doc/index.rst | 107 ++++++++++++ 8 files changed, 315 insertions(+) create mode 100644 boards/weact/blackpill_h523ce/Kconfig.blackpill_h523ce create mode 100644 boards/weact/blackpill_h523ce/blackpill_h523ce.dts create mode 100644 boards/weact/blackpill_h523ce/blackpill_h523ce.yaml create mode 100644 boards/weact/blackpill_h523ce/blackpill_h523ce_defconfig create mode 100644 boards/weact/blackpill_h523ce/board.cmake create mode 100644 boards/weact/blackpill_h523ce/board.yml create mode 100644 boards/weact/blackpill_h523ce/doc/img/blackpill_h523ce.webp create mode 100644 boards/weact/blackpill_h523ce/doc/index.rst diff --git a/boards/weact/blackpill_h523ce/Kconfig.blackpill_h523ce b/boards/weact/blackpill_h523ce/Kconfig.blackpill_h523ce new file mode 100644 index 0000000000000..8b5c8ca65b54d --- /dev/null +++ b/boards/weact/blackpill_h523ce/Kconfig.blackpill_h523ce @@ -0,0 +1,5 @@ +# Copyright(c) 2025 Filip Stojanovic +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BLACKPILL_H523CE + select SOC_STM32H523XX diff --git a/boards/weact/blackpill_h523ce/blackpill_h523ce.dts b/boards/weact/blackpill_h523ce/blackpill_h523ce.dts new file mode 100644 index 0000000000000..b7914b2fe54b9 --- /dev/null +++ b/boards/weact/blackpill_h523ce/blackpill_h523ce.dts @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025 Filip Stojanovic + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "WeAct Studio Black Pill STM32H523 Board"; + compatible = "weact,blackpill-h523ce"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram1; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + user_led: led { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "User LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button: button { + label = "KEY"; + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &user_led; + sw0 = &user_button; + volt-sensor0 = &vref; + volt-sensor1 = &vbat; + }; +}; + +&timers3 { + status = "okay"; + st,prescaler = <24>; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch3_pb0 &tim3_ch4_pb1>; + pinctrl-names = "default"; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + status = "okay"; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_nss_pa4 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK(APB3, 21)>, <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +zephyr_udc0: &usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc1 { + clocks = <&rcc STM32_CLOCK(AHB2, 10)>, <&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>; + pinctrl-0 = <&adc1_inp1_pa1>; + pinctrl-names = "default"; + st,adc-clock-source = "ASYNC"; + st,adc-prescaler = <8>; + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +&pll { + div-m = <1>; + mul-n = <60>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&vbat { + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&rng { + status = "okay"; +}; diff --git a/boards/weact/blackpill_h523ce/blackpill_h523ce.yaml b/boards/weact/blackpill_h523ce/blackpill_h523ce.yaml new file mode 100644 index 0000000000000..c07069ca28f85 --- /dev/null +++ b/boards/weact/blackpill_h523ce/blackpill_h523ce.yaml @@ -0,0 +1,17 @@ +identifier: blackpill_h523ce +name: WeAct Studio Black Pill STM32H523 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 272 +flash: 512 +supported: + - gpio + - counter + - spi + - i2c + - uart + - pwm +vendor: weact diff --git a/boards/weact/blackpill_h523ce/blackpill_h523ce_defconfig b/boards/weact/blackpill_h523ce/blackpill_h523ce_defconfig new file mode 100644 index 0000000000000..d937ad2be9232 --- /dev/null +++ b/boards/weact/blackpill_h523ce/blackpill_h523ce_defconfig @@ -0,0 +1,16 @@ +# Copyright(c) 2025 Filip Stojanovic +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Serial drivers +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/weact/blackpill_h523ce/board.cmake b/boards/weact/blackpill_h523ce/board.cmake new file mode 100644 index 0000000000000..fcf4b775c158d --- /dev/null +++ b/boards/weact/blackpill_h523ce/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") +board_runner_args(jlink "--device=STM32H523CE" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/weact/blackpill_h523ce/board.yml b/boards/weact/blackpill_h523ce/board.yml new file mode 100644 index 0000000000000..70174f1bdaafb --- /dev/null +++ b/boards/weact/blackpill_h523ce/board.yml @@ -0,0 +1,6 @@ +board: + name: blackpill_h523ce + full_name: Black Pill STM32H523 + vendor: weact + socs: + - name: stm32h523xx diff --git a/boards/weact/blackpill_h523ce/doc/img/blackpill_h523ce.webp b/boards/weact/blackpill_h523ce/doc/img/blackpill_h523ce.webp new file mode 100644 index 0000000000000000000000000000000000000000..f8c58c89bd24783f04ec38217b59bbd641b192ac GIT binary patch literal 5908 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 q=cjhc&!~?gY!4=;4i%lnx&Q!+>bt@K literal 0 HcmV?d00001 diff --git a/boards/weact/blackpill_h523ce/doc/index.rst b/boards/weact/blackpill_h523ce/doc/index.rst new file mode 100644 index 0000000000000..dbd0ea928ec05 --- /dev/null +++ b/boards/weact/blackpill_h523ce/doc/index.rst @@ -0,0 +1,107 @@ +.. zephyr:board:: blackpill_h523ce + +Overview +******** + +The WeAct STM32H523CE Core Board is a low-cost and bare-bone development +board made in the famous "blackpill" package. It features the STM32H523CE, a +high-performance microcontroller based on an Arm Cortex-M33 processor. + +Hardware +******** + +The STM32H523CE-based Black Pill board provides the following hardware +components: + +- STM32H523CE in 48-pin package +- ARM 32-bit Cortex-M33 CPU with FPU +- 250 MHz max CPU frequency +- VDD from 1.7 V to 3.6 V +- 512 KB Flash +- 274 KB SRAM +- TIM +- ADC +- USART +- I2C +- SPI +- USB FS +- FDCAN +- RTC + +Supported Features +****************** + +.. zephyr:board-supported-hw:: + +Connections and IOs +******************* + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PA9 / PA10 +- I2C1 SCL/SDA : PB6 / PB7 +- SPI1 CS/SCK/MISO/MOSI : PA4 / PA5 / PA6 / PA7 (routed to footprint for external flash) +- PWM_3_CH3 : PB0 +- PWM_3_CH4 : PB1 +- ADC_1 : PA1 +- USER_PB : PA0 +- USER_LED : PC13 + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +There are 2 main entry points for flashing STM32H5X SoCs: one using the ROM +bootloader, and another by using the SWD debug port (which requires additional +hardware). Flashing using the ROM bootloader requires a special activation +pattern, which can be triggered by using the BOOT0 pin. + +Flashing +******** + +Installing dfu-util +------------------- + +It is recommended to use at least v0.8 of `dfu-util `_. The package available in +Debian/Ubuntu can be quite old, so you might have to build dfu-util from source. + +There is also a Windows version which works, but you may have to install the +right USB drivers with a tool like `Zadig `_. + +Flashing an Application +----------------------- + +Connect a USB-C cable and the board should power ON. Force the board into DFU mode +by keeping the BOOT0 switch pressed while pressing and releasing the NRST switch. + +The dfu-util runner is supported on this board and so a sample can be built and +tested easily. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: blackpill_h523ce + :goals: build flash + :gen-args: -DCONFIG_BOOT_DELAY=5000 + +Debugging +========= + +The board can be debugged by installing the included 100 mil (0.1 inch) header, +and attaching an SWD debugger to the 3V3 (3.3V), GND, SCK, and DIO +pins on that header. + +References +********** + +.. target-notes:: + +.. _WeAct Github: + https://github.com/WeActStudio/WeActStudio.STM32H523CoreBoard/tree/master + +.. _STM32H523CE website: + https://www.st.com/en/microcontrollers-microprocessors/stm32h523ce.html + +.. _STM32H523CE reference manual: + https://www.st.com/resource/en/reference_manual/rm0481-stm32h52333xx-stm32h56263xx-and-stm32h573xx-armbased-32bit-mcus-stmicroelectronics.pdf From 00d4ab1c9c3612caff7452a7103fc70ffbef8b3b Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Aug 2025 10:20:46 +0200 Subject: [PATCH 0025/1076] Bluetooth: Conn: LOG_DBG for buffer alloc fail Use LOG_DBG rather than LOG_WRN, as that is an expected scenario when using K_NO_WAIT (e.g. when sending GATT notifications), and it is better for higher layers to determine if this is indeed an error. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 00802d402b864..98fcf6615bf14 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1627,7 +1627,7 @@ struct net_buf *bt_conn_create_pdu_timeout(struct net_buf_pool *pool, } if (!buf) { - LOG_WRN("Unable to allocate buffer within timeout"); + LOG_DBG("Unable to allocate buffer within timeout"); return NULL; } From ace3a6013767c9688d6201afadf932f0b460ae1d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Aug 2025 10:19:06 +0200 Subject: [PATCH 0026/1076] Bluetooth: ATT: Change LOG_ERR to DBG when failing to allocate buffer For user-initiated requests like notifications, read and write requests, there will be an error code, so there does not need to be a generic LOG_ERR if these fail to be allocated. However if the response or (indication) confirmation PDUs fail to be allocated, these should still be logged as errors. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/att.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 3c707b4fdb276..82d82526b5b0c 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -748,7 +748,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t /* This will reserve headspace for lower layers */ buf = bt_l2cap_create_pdu_timeout(&att_pool, 0, timeout); if (!buf) { - LOG_ERR("Unable to allocate buffer for op 0x%02x", op); + LOG_DBG("Unable to allocate buffer for op 0x%02x", op); return NULL; } @@ -831,6 +831,7 @@ static void send_err_rsp(struct bt_att_chan *chan, uint8_t req, uint16_t handle, buf = bt_att_chan_create_pdu(chan, BT_ATT_OP_ERROR_RSP, sizeof(*rsp)); if (!buf) { + LOG_ERR("Unable to create err rsp PDU"); return; } @@ -2129,6 +2130,7 @@ static uint8_t att_write_rsp(struct bt_att_chan *chan, uint8_t req, uint8_t rsp, if (rsp) { data.buf = bt_att_chan_create_pdu(chan, rsp, 0); if (!data.buf) { + LOG_ERR("Unable to create rsp PDU"); return BT_ATT_ERR_INSUFFICIENT_RESOURCES; } } @@ -2720,6 +2722,7 @@ static uint8_t att_indicate(struct bt_att_chan *chan, struct net_buf *buf) buf = bt_att_chan_create_pdu(chan, BT_ATT_OP_CONFIRM, 0); if (!buf) { + LOG_ERR("Unable to create confirm PDU"); return 0; } @@ -3257,6 +3260,7 @@ static uint8_t att_req_retry(struct bt_att_chan *att_chan) buf = bt_att_chan_create_pdu(att_chan, req->att_op, req->len); if (!buf) { + LOG_ERR("Unable to create retry PDU (%u)", req->att_op); return BT_ATT_ERR_UNLIKELY; } From d3ffdf4b24eb60990814966dfe9aa18621d2e355 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Aug 2025 10:21:52 +0200 Subject: [PATCH 0027/1076] Bluetooth: GATT: Modify some LOG_WRN/ERR to LOG_DBG When an API function returns an appropriate error code, LOG_DBG is better suited than LOG_WRN or LOG_ERR as the caller can handle the return value. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/gatt.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 6161ed19ff31e..fd78edebc2c7e 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -1738,7 +1738,7 @@ int bt_gatt_service_register(struct bt_gatt_service *svc) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(gatt_flags, GATT_INITIALIZED) && !atomic_test_bit(gatt_sc.flags, SC_LOAD)) { - LOG_ERR("Can't register service after init and before settings are loaded."); + LOG_DBG("Can't register service after init and before settings are loaded."); return -EINVAL; } @@ -1842,7 +1842,7 @@ ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, } if (value_len != 0U && value == NULL) { - LOG_WRN("value_len of %u provided for NULL value", value_len); + LOG_DBG("value_len of %u provided for NULL value", value_len); return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); } @@ -2540,7 +2540,7 @@ static int gatt_notify(struct bt_conn *conn, uint16_t handle, /* Confirm that the connection has the correct level of security */ if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) { - LOG_WRN("Link is not encrypted"); + LOG_DBG("Link is not encrypted"); return -EPERM; } @@ -2550,7 +2550,7 @@ static int gatt_notify(struct bt_conn *conn, uint16_t handle, * but follows its spirit. */ if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_NOTIFY)) { - LOG_WRN("Device is not subscribed to characteristic"); + LOG_DBG("Device is not subscribed to characteristic"); return -EINVAL; } } @@ -2569,7 +2569,7 @@ static int gatt_notify(struct bt_conn *conn, uint16_t handle, buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY, sizeof(*nfy) + params->len); if (!buf) { - LOG_WRN("No buffer available to send notification"); + LOG_DBG("No buffer available to send notification"); return -ENOMEM; } @@ -2704,7 +2704,7 @@ static int gatt_indicate(struct bt_conn *conn, uint16_t handle, /* Confirm that the connection has the correct level of security */ if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) { - LOG_WRN("Link is not encrypted"); + LOG_DBG("Link is not encrypted"); return -EPERM; } @@ -2714,7 +2714,7 @@ static int gatt_indicate(struct bt_conn *conn, uint16_t handle, * but follows its spirit. */ if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_INDICATE)) { - LOG_WRN("Device is not subscribed to characteristic"); + LOG_DBG("Device is not subscribed to characteristic"); return -EINVAL; } } @@ -2734,7 +2734,7 @@ static int gatt_indicate(struct bt_conn *conn, uint16_t handle, buf = bt_att_create_pdu(conn, BT_ATT_OP_INDICATE, len); if (!buf) { - LOG_WRN("No buffer available to send indication"); + LOG_DBG("No buffer available to send indication"); bt_att_req_free(req); return -ENOMEM; } @@ -2827,7 +2827,7 @@ static uint8_t notify_cb(const struct bt_gatt_attr *attr, uint16_t handle, /* Confirm that the connection has the correct level of security */ if (bt_gatt_check_perm(conn, attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) { - LOG_WRN("Link is not encrypted"); + LOG_DBG("Link %p is not encrypted", (void *)conn); bt_conn_unref(conn); continue; } @@ -3028,7 +3028,7 @@ static int gatt_notify_multiple_verify_params(struct bt_conn *conn, if (bt_gatt_check_perm(conn, params[i].attr, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_READ_AUTHEN)) { - LOG_WRN("Link is not encrypted"); + LOG_DBG("Link %p is not encrypted", (void *)conn); return -EPERM; } @@ -4754,7 +4754,7 @@ int bt_gatt_discover(struct bt_conn *conn, case BT_GATT_DISCOVER_ATTRIBUTE: return gatt_find_info(conn, params); default: - LOG_ERR("Invalid discovery type: %u", params->type); + LOG_DBG("Invalid discovery type: %u", params->type); } return -EINVAL; @@ -5140,7 +5140,7 @@ int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle, write = net_buf_append_bytes(buf, length, data, K_NO_WAIT, NULL, NULL); if (write != length) { - LOG_WRN("Unable to allocate length %u: only %zu written", length, write); + LOG_DBG("Unable to allocate length %u: only %zu written", length, write); net_buf_unref(buf); return -ENOMEM; } From 04a15510a90b2eb3020a3782b36a13f96c45d9af Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Aug 2025 10:24:40 +0200 Subject: [PATCH 0028/1076] Bluetooth: ASCS: Use LOG_DBG when failing to alloc buffer for notification Since there is a retry mechanism implement, this is not something that the user needs to be warned about. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/ascs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 80ddeb7ff337d..3511401541af9 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -543,8 +543,9 @@ static void state_transition_work_handler(struct k_work *work) /* Reschedule the state transition */ err = k_work_reschedule(d_work, K_MSEC(retry_delay_ms)); if (err >= 0) { - LOG_WRN("Out of buffers for ase state notification. " - "Will retry in %dms", retry_delay_ms); + LOG_DBG("Out of buffers for ase state notification. " + "Will retry in %dms", + retry_delay_ms); return; } } From c9e1725665b88cf480903cfd7a287c70441195c2 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 21 Aug 2025 16:07:16 +0200 Subject: [PATCH 0029/1076] Bluetooth: GATT: ASSERT instead of LOG_DBG for write length check In bt_gatt_write_without_response_cb there is a check for write != length. However since the call to bt_att_create_pdu should ensure that this is possible, this should never happen. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/gatt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index fd78edebc2c7e..7131d2fc3d059 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -5108,7 +5108,7 @@ int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle, { struct net_buf *buf; struct bt_att_write_cmd *cmd; - size_t write; + __maybe_unused size_t write; __ASSERT(conn, "invalid parameters\n"); __ASSERT(handle, "invalid parameters\n"); @@ -5139,11 +5139,7 @@ int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle, cmd->handle = sys_cpu_to_le16(handle); write = net_buf_append_bytes(buf, length, data, K_NO_WAIT, NULL, NULL); - if (write != length) { - LOG_DBG("Unable to allocate length %u: only %zu written", length, write); - net_buf_unref(buf); - return -ENOMEM; - } + __ASSERT(write == length, "Unable to allocate length %u: only %zu written", length, write); LOG_DBG("handle 0x%04x length %u", handle, length); From 8c11033f59b5a1957f2087d01b322da277a314ad Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Thu, 21 Aug 2025 10:26:13 +0200 Subject: [PATCH 0030/1076] dts: arm: st: wba: temporary fix to build stm32wba5x boards Due to a mismatch in naming of debug jtrst pin name (compared to hal_stm32) all boards based on stm32wba5x are not compiling. This temporary fix will solve this issue until a systematic approach will be put in place. Signed-off-by: Alessandro Manganaro --- dts/arm/st/wba/stm32wba.dtsi | 3 ++- dts/arm/st/wba/stm32wba65.dtsi | 10 ++++++++++ west.yml | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index e67a069f1b1eb..beb7cf416674b 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -564,7 +564,8 @@ compatible = "swj-connector"; pinctrl-0 = <&debug_jtms_swdio_pa13 &debug_jtck_swclk_pa14 &debug_jtdi_pa15 &debug_jtdo_swo_pb3 - &debug_njtrst_pb4>; + /* temp fix to cover current wba5 pin naming */ + &debug_jtrst_pb4>; pinctrl-1 = <&analog_pa13 &analog_pa14 &analog_pa15 &analog_pb3 &analog_pb4>; pinctrl-names = "default", "sleep"; diff --git a/dts/arm/st/wba/stm32wba65.dtsi b/dts/arm/st/wba/stm32wba65.dtsi index 9a026d1bc8093..2ebebbd65d9dd 100644 --- a/dts/arm/st/wba/stm32wba65.dtsi +++ b/dts/arm/st/wba/stm32wba65.dtsi @@ -79,6 +79,16 @@ }; }; + /* + * Temporary revert of pinctrl-0 definition for stm3wba65 + * to fix issue on stm32wba5x based boards + */ + swj_port: swj_port { + pinctrl-0 = <&debug_jtms_swdio_pa13 &debug_jtck_swclk_pa14 + &debug_jtdi_pa15 &debug_jtdo_swo_pb3 + &debug_njtrst_pb4>; + }; + die_temp: dietemp { ts-cal1-addr = <0x0BFA0710>; ts-cal2-addr = <0x0BFA0742>; diff --git a/west.yml b/west.yml index f0b929d621ae2..1ff129b0a2927 100644 --- a/west.yml +++ b/west.yml @@ -245,7 +245,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: d46f8453c5ce28fb6aba7613de7ebc75bd8572c3 + revision: 611d54c237623ea71a367502bfbd736fc67ba15f path: modules/hal/stm32 groups: - hal From 88de138290b683c26abf81142756621a02169eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Aug 2025 10:46:14 +0200 Subject: [PATCH 0031/1076] include: gnss: dt-bindings: remove unused header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file contains macro definitions for baudrates that are not needed ; probably leftover from an earlier iteration of the binding that used an enum for the baudrate(?) Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 1 - include/zephyr/dt-bindings/gnss/u_blox_m8.h | 23 --------------------- 2 files changed, 24 deletions(-) delete mode 100644 include/zephyr/dt-bindings/gnss/u_blox_m8.h diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1f40198d499b3..0da42ed3ef40a 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1643,7 +1643,6 @@ Documentation Infrastructure: - include/zephyr/drivers/gnss/ - include/zephyr/gnss/ - dts/bindings/gnss/ - - include/zephyr/dt-bindings/gnss/ - tests/drivers/build_all/gnss/ - tests/drivers/gnss/ - tests/subsys/gnss/ diff --git a/include/zephyr/dt-bindings/gnss/u_blox_m8.h b/include/zephyr/dt-bindings/gnss/u_blox_m8.h deleted file mode 100644 index 38ab27eee00e1..0000000000000 --- a/include/zephyr/dt-bindings/gnss/u_blox_m8.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2024 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GNSS_U_BLOX_M8_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_GNSS_U_BLOX_M8_H_ - -#include - -/* UART Baudrate. */ -#define UBX_M8_UART_BAUDRATE_4800 0x00 -#define UBX_M8_UART_BAUDRATE_9600 0x01 -#define UBX_M8_UART_BAUDRATE_19200 0x02 -#define UBX_M8_UART_BAUDRATE_38400 0x03 -#define UBX_M8_UART_BAUDRATE_57600 0x04 -#define UBX_M8_UART_BAUDRATE_115200 0x05 -#define UBX_M8_UART_BAUDRATE_230400 0x06 -#define UBX_M8_UART_BAUDRATE_460800 0x07 -#define UBX_M8_UART_BAUDRATE_921600 0x08 - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GNSS_U_BLOX_M8_H_ */ From d8f35a5baa1ed8ef9950af9ef58b558de00c2597 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 15 Jul 2025 21:13:59 +0800 Subject: [PATCH 0032/1076] bluetooth: sdp: add avdtp protocol get the avdtp version through the bt_sdp_get_proto_param Signed-off-by: Mark Wang --- include/zephyr/bluetooth/classic/sdp.h | 1 + subsys/bluetooth/host/classic/sdp.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/classic/sdp.h b/include/zephyr/bluetooth/classic/sdp.h index 94c307a484d54..4414c37286839 100644 --- a/include/zephyr/bluetooth/classic/sdp.h +++ b/include/zephyr/bluetooth/classic/sdp.h @@ -639,6 +639,7 @@ int bt_sdp_discover_cancel(struct bt_conn *conn, /** @brief Protocols to be asked about specific parameters */ enum bt_sdp_proto { BT_SDP_PROTO_RFCOMM = 0x0003, + BT_SDP_PROTO_AVDTP = 0x0019, BT_SDP_PROTO_L2CAP = 0x0100, }; diff --git a/subsys/bluetooth/host/classic/sdp.c b/subsys/bluetooth/host/classic/sdp.c index 6ad7130188f00..f88ed3676f964 100644 --- a/subsys/bluetooth/host/classic/sdp.c +++ b/subsys/bluetooth/host/classic/sdp.c @@ -3200,7 +3200,8 @@ int bt_sdp_get_proto_param(const struct net_buf *buf, enum bt_sdp_proto proto, struct bt_sdp_uuid_desc pd; int res; - if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) { + if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP && + proto != BT_SDP_PROTO_AVDTP) { LOG_ERR("Invalid protocol specifier"); return -EINVAL; } @@ -3227,7 +3228,8 @@ int bt_sdp_get_addl_proto_param(const struct net_buf *buf, enum bt_sdp_proto pro struct bt_sdp_uuid_desc pd; int res; - if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) { + if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP && + proto != BT_SDP_PROTO_AVDTP) { LOG_ERR("Invalid protocol specifier"); return -EINVAL; } From 3544546356956b6031e2d4775e62ab9cbe74af65 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 15 Jul 2025 21:24:52 +0800 Subject: [PATCH 0033/1076] bluetooth: a2dp: implement the get_all_capabilities From avdtp spec, the get_all_capablities should be used if the avdtp version is v1.3, otherwise the get_capabilities should be used. Signed-off-by: Mark Wang --- include/zephyr/bluetooth/classic/a2dp.h | 9 + include/zephyr/bluetooth/classic/avdtp.h | 4 + subsys/bluetooth/host/classic/a2dp.c | 19 ++- subsys/bluetooth/host/classic/avdtp.c | 48 ++++-- .../bluetooth/host/classic/avdtp_internal.h | 3 +- subsys/bluetooth/host/classic/shell/a2dp.c | 19 ++- subsys/bluetooth/host/classic/shell/bredr.c | 160 +++++++++++++----- 7 files changed, 200 insertions(+), 62 deletions(-) diff --git a/include/zephyr/bluetooth/classic/a2dp.h b/include/zephyr/bluetooth/classic/a2dp.h index 985e5088a7838..cc56ea32c3e26 100644 --- a/include/zephyr/bluetooth/classic/a2dp.h +++ b/include/zephyr/bluetooth/classic/a2dp.h @@ -391,6 +391,15 @@ struct bt_a2dp_discover_param { * it save endpoint info internally. */ struct bt_avdtp_sep_info *seps_info; + /** The AVDTP version of the peer's A2DP sdp service. + * Stack uses it to determine using get_all_cap or get_cap cmd. When both + * versions are v1.3 or bigger version, get_all_cap is used, otherwise + * get_cap is used. + * It is the same value of the avdtp sepcificaiton's version value. + * For example: 0x0103 means version 1.3 + * If the value is 0 (unknown), stack process it as less than v1.3 + */ + uint16_t avdtp_version; /** The max count of seps (stream endpoint) that can be got in this call route */ uint8_t sep_count; }; diff --git a/include/zephyr/bluetooth/classic/avdtp.h b/include/zephyr/bluetooth/classic/avdtp.h index dd7307ae3748f..b68f19c16a638 100644 --- a/include/zephyr/bluetooth/classic/avdtp.h +++ b/include/zephyr/bluetooth/classic/avdtp.h @@ -15,6 +15,10 @@ extern "C" { #endif +#define AVDTP_VERSION_1_3 0x0103 /**< AVDTP version 1.3 value */ + +#define AVDTP_VERSION AVDTP_VERSION_1_3 /**< AVDTP version used by Zephyr */ + /** * @brief AVDTP error code */ diff --git a/subsys/bluetooth/host/classic/a2dp.c b/subsys/bluetooth/host/classic/a2dp.c index ec6e624205228..338e5fd36447a 100644 --- a/subsys/bluetooth/host/classic/a2dp.c +++ b/subsys/bluetooth/host/classic/a2dp.c @@ -125,8 +125,13 @@ static int a2dp_discovery_ind(struct bt_avdtp *session, uint8_t *errcode) } static int a2dp_get_capabilities_ind(struct bt_avdtp *session, struct bt_avdtp_sep *sep, - struct net_buf *rsp_buf, uint8_t *errcode) + struct net_buf *rsp_buf, bool get_all_caps, uint8_t *errcode) { + /* The Reporting, Recovery, Content Protection, Header Compression, Multiplexing and + * Delay Reporting services are not supported, so the same response is replied as + * get_capabilities. + */ + ARG_UNUSED(get_all_caps); struct bt_a2dp_ep *ep; __ASSERT(sep, "Invalid sep"); @@ -613,6 +618,17 @@ static int bt_a2dp_get_sep_caps(struct bt_a2dp *a2dp) a2dp->get_capabilities_param.req.func = bt_a2dp_get_capabilities_cb; a2dp->get_capabilities_param.stream_endpoint_id = a2dp->discover_cb_param->seps_info[a2dp->get_cap_index].id; + + /* The legacy Get Capabilities procedure is deprecated in cases + * where backwards compatibility with AVDTP 1.2 and earlier is irrelevant. + */ + if (AVDTP_VERSION >= AVDTP_VERSION_1_3 && + a2dp->discover_cb_param->avdtp_version >= AVDTP_VERSION_1_3) { + a2dp->get_capabilities_param.get_all_caps = true; + } else { + a2dp->get_capabilities_param.get_all_caps = false; + } + err = bt_avdtp_get_capabilities(&a2dp->session, &a2dp->get_capabilities_param); @@ -699,7 +715,6 @@ int bt_a2dp_discover(struct bt_a2dp *a2dp, struct bt_a2dp_discover_param *param) return -EBUSY; } - memset(&a2dp->discover_cb_param, 0U, sizeof(a2dp->discover_cb_param)); a2dp->discover_cb_param = param; a2dp->discover_param.req.func = bt_a2dp_discover_cb; diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index 082d5ed5ffcf7..67f39c133e527 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -356,7 +356,8 @@ static struct bt_avdtp_sep *avdtp_get_cmd_sep(struct net_buf *buf, uint8_t *erro return sep; } -static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid) +static void avdtp_get_caps_cmd_internal(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid, + bool get_all_caps) { int err = 0; struct net_buf *rsp_buf; @@ -369,12 +370,14 @@ static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf err = -ENOTSUP; } else { rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_ACCEPT, BT_AVDTP_PACKET_TYPE_SINGLE, + get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES : BT_AVDTP_GET_CAPABILITIES, tid); if (!rsp_buf) { return; } - err = session->ops->get_capabilities_ind(session, sep, rsp_buf, &error_code); + err = session->ops->get_capabilities_ind(session, sep, rsp_buf, get_all_caps, + &error_code); if (err) { net_buf_unref(rsp_buf); } @@ -382,6 +385,7 @@ static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf if (err) { rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_REJECT, BT_AVDTP_PACKET_TYPE_SINGLE, + get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES : BT_AVDTP_GET_CAPABILITIES, tid); if (!rsp_buf) { return; @@ -403,6 +407,17 @@ static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf } } +static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid) +{ + avdtp_get_caps_cmd_internal(session, buf, tid, false); +} + +static void avdtp_get_all_capabilities_cmd(struct bt_avdtp *session, + struct net_buf *buf, uint8_t tid) +{ + avdtp_get_caps_cmd_internal(session, buf, tid, true); +} + static void avdtp_get_capabilities_rsp(struct bt_avdtp *session, struct net_buf *buf, uint8_t msg_type) { @@ -1103,19 +1118,19 @@ void bt_avdtp_l2cap_disconnected(struct bt_l2cap_chan *chan) } void (*cmd_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid) = { - avdtp_discover_cmd, /* BT_AVDTP_DISCOVER */ - avdtp_get_capabilities_cmd, /* BT_AVDTP_GET_CAPABILITIES */ - avdtp_set_configuration_cmd, /* BT_AVDTP_SET_CONFIGURATION */ - NULL, /* BT_AVDTP_GET_CONFIGURATION */ - avdtp_re_configure_cmd, /* BT_AVDTP_RECONFIGURE */ - avdtp_open_cmd, /* BT_AVDTP_OPEN */ - avdtp_start_cmd, /* BT_AVDTP_START */ - avdtp_close_cmd, /* BT_AVDTP_CLOSE */ - avdtp_suspend_cmd, /* BT_AVDTP_SUSPEND */ - avdtp_abort_cmd, /* BT_AVDTP_ABORT */ - NULL, /* BT_AVDTP_SECURITY_CONTROL */ - NULL, /* BT_AVDTP_GET_ALL_CAPABILITIES */ - NULL, /* BT_AVDTP_DELAYREPORT */ + avdtp_discover_cmd, /* BT_AVDTP_DISCOVER */ + avdtp_get_capabilities_cmd, /* BT_AVDTP_GET_CAPABILITIES */ + avdtp_set_configuration_cmd, /* BT_AVDTP_SET_CONFIGURATION */ + NULL, /* BT_AVDTP_GET_CONFIGURATION */ + avdtp_re_configure_cmd, /* BT_AVDTP_RECONFIGURE */ + avdtp_open_cmd, /* BT_AVDTP_OPEN */ + avdtp_start_cmd, /* BT_AVDTP_START */ + avdtp_close_cmd, /* BT_AVDTP_CLOSE */ + avdtp_suspend_cmd, /* BT_AVDTP_SUSPEND */ + avdtp_abort_cmd, /* BT_AVDTP_ABORT */ + NULL, /* BT_AVDTP_SECURITY_CONTROL */ + avdtp_get_all_capabilities_cmd, /* BT_AVDTP_GET_ALL_CAPABILITIES */ + NULL, /* BT_AVDTP_DELAYREPORT */ }; void (*rsp_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t msg_type) = { @@ -1130,7 +1145,7 @@ void (*rsp_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t msg avdtp_suspend_rsp, /* BT_AVDTP_SUSPEND */ avdtp_abort_rsp, /* BT_AVDTP_ABORT */ NULL, /* BT_AVDTP_SECURITY_CONTROL */ - NULL, /* BT_AVDTP_GET_ALL_CAPABILITIES */ + avdtp_get_capabilities_rsp, /* BT_AVDTP_GET_ALL_CAPABILITIES */ NULL, /* BT_AVDTP_DELAYREPORT */ }; @@ -1436,6 +1451,7 @@ int bt_avdtp_get_capabilities(struct bt_avdtp *session, } buf = avdtp_create_pdu(BT_AVDTP_CMD, BT_AVDTP_PACKET_TYPE_SINGLE, + param->get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES : BT_AVDTP_GET_CAPABILITIES); if (!buf) { LOG_ERR("Error: No Buff available"); diff --git a/subsys/bluetooth/host/classic/avdtp_internal.h b/subsys/bluetooth/host/classic/avdtp_internal.h index 368dba6c278f0..10723b9cb8601 100644 --- a/subsys/bluetooth/host/classic/avdtp_internal.h +++ b/subsys/bluetooth/host/classic/avdtp_internal.h @@ -153,6 +153,7 @@ struct bt_avdtp_discover_params { struct bt_avdtp_get_capabilities_params { struct bt_avdtp_req req; uint8_t stream_endpoint_id; + bool get_all_caps; }; struct bt_avdtp_set_configuration_params { @@ -183,7 +184,7 @@ struct bt_avdtp_ops_cb { int (*discovery_ind)(struct bt_avdtp *session, uint8_t *errcode); int (*get_capabilities_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep, - struct net_buf *rsp_buf, uint8_t *errcode); + struct net_buf *rsp_buf, bool get_all_caps, uint8_t *errcode); int (*set_configuration_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep, uint8_t int_seid, struct net_buf *buf, uint8_t *errcode); diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 19e38e35094dc..14a40bb1e1ccf 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -99,7 +99,7 @@ static struct bt_sdp_attribute a2dp_sink_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ - BT_SDP_ARRAY_16(0x0100U) /* AVDTP version: 01 00 */ + BT_SDP_ARRAY_16(AVDTP_VERSION) /* AVDTP version: 01 03 */ }, ) }, @@ -168,7 +168,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), - BT_SDP_ARRAY_16(0x0100U) + BT_SDP_ARRAY_16(AVDTP_VERSION) }, ) }, @@ -193,7 +193,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = { }, ) ), - BT_SDP_SERVICE_NAME("A2DPSink"), + BT_SDP_SERVICE_NAME("A2DPSource"), BT_SDP_SUPPORTED_FEATURES(0x0001U), }; @@ -677,13 +677,22 @@ struct bt_a2dp_discover_param discover_param = { static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) { + int err = 0; + if (a2dp_initied == 0) { shell_print(sh, "need to register a2dp connection callbacks"); return -ENOEXEC; } if (default_a2dp != NULL) { - int err = bt_a2dp_discover(default_a2dp, &discover_param); + discover_param.avdtp_version = (uint16_t)shell_strtoul(argv[1], 0, &err); + if (err != 0) { + shell_error(sh, "failed to parse avdtp version: %d", err); + + return -ENOEXEC; + } + + err = bt_a2dp_discover(default_a2dp, &discover_param); if (err) { shell_error(sh, "discover fail"); @@ -798,7 +807,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds, cmd_register_ep, 3, 0), SHELL_CMD_ARG(connect, NULL, HELP_NONE, cmd_connect, 1, 0), SHELL_CMD_ARG(disconnect, NULL, HELP_NONE, cmd_disconnect, 1, 0), - SHELL_CMD_ARG(discover_peer_eps, NULL, HELP_NONE, cmd_get_peer_eps, 1, 0), + SHELL_CMD_ARG(discover_peer_eps, NULL, "", cmd_get_peer_eps, 2, 0), SHELL_CMD_ARG(configure, NULL, "\"configure/enable the stream\"", cmd_configure, 1, 0), SHELL_CMD_ARG(establish, NULL, "\"establish the stream\"", cmd_establish, 1, 0), SHELL_CMD_ARG(reconfigure, NULL, "\"reconfigure the stream\"", cmd_reconfigure, 1, 0), diff --git a/subsys/bluetooth/host/classic/shell/bredr.c b/subsys/bluetooth/host/classic/shell/bredr.c index 9b5544b5adad1..a3f57f25fe3b9 100644 --- a/subsys/bluetooth/host/classic/shell/bredr.c +++ b/subsys/bluetooth/host/classic/shell/bredr.c @@ -950,48 +950,122 @@ static uint8_t sdp_a2src_user(struct bt_conn *conn, struct bt_sdp_client_result conn_addr_str(conn, addr, sizeof(addr)); - if (result && result->resp_buf) { - bt_shell_print("SDP A2SRC data@%p (len %u) hint %u from remote %s", - result->resp_buf, result->resp_buf->len, result->next_record_hint, - addr); + if (result == NULL || result->resp_buf == NULL) { + bt_shell_print("No SDP A2SRC data from remote %s", addr); + goto done; + } - /* - * Focus to get BT_SDP_ATTR_PROTO_DESC_LIST attribute item to - * get A2SRC Server PSM Number. - */ - err = bt_sdp_get_proto_param(result->resp_buf, BT_SDP_PROTO_L2CAP, ¶m); - if (err < 0) { - bt_shell_error("A2SRC PSM Number not found, err %d", err); - goto done; - } + bt_shell_print("SDP A2SRC data@%p (len %u) hint %u from remote %s", + result->resp_buf, result->resp_buf->len, result->next_record_hint, + addr); - bt_shell_print("A2SRC Server PSM Number param 0x%04x", param); + /* + * Focus to get BT_SDP_ATTR_PROTO_DESC_LIST attribute item to + * get A2SRC Server PSM Number. + */ + err = bt_sdp_get_proto_param(result->resp_buf, BT_SDP_PROTO_L2CAP, ¶m); + if (err < 0) { + bt_shell_error("A2SRC PSM Number not found, err %d", err); + goto done; + } - /* - * Focus to get BT_SDP_ATTR_PROFILE_DESC_LIST attribute item to - * get profile version number. - */ - err = bt_sdp_get_profile_version(result->resp_buf, BT_SDP_ADVANCED_AUDIO_SVCLASS, - &version); - if (err < 0) { - bt_shell_error("A2SRC version not found, err %d", err); - goto done; - } - bt_shell_print("A2SRC version param 0x%04x", version); + bt_shell_print("A2SRC Server PSM Number param 0x%04x", param); - /* - * Focus to get BT_SDP_ATTR_SUPPORTED_FEATURES attribute item to - * get profile supported features mask. - */ - err = bt_sdp_get_features(result->resp_buf, &features); - if (err < 0) { - bt_shell_error("A2SRC Features not found, err %d", err); - goto done; - } - bt_shell_print("A2SRC Supported Features param 0x%04x", features); - } else { - bt_shell_print("No SDP A2SRC data from remote %s", addr); + err = bt_sdp_get_proto_param(result->resp_buf, BT_UUID_AVDTP_VAL, &version); + if (err < 0) { + bt_shell_error("A2SRC AVDTP version not found, err %d", err); + goto done; + } + + bt_shell_print("A2SRC Server AVDTP version 0x%04x", version); + + /* + * Focus to get BT_SDP_ATTR_PROFILE_DESC_LIST attribute item to + * get profile version number. + */ + err = bt_sdp_get_profile_version(result->resp_buf, BT_SDP_ADVANCED_AUDIO_SVCLASS, &version); + if (err < 0) { + bt_shell_error("A2SRC version not found, err %d", err); + goto done; + } + bt_shell_print("A2SRC version param 0x%04x", version); + + /* + * Focus to get BT_SDP_ATTR_SUPPORTED_FEATURES attribute item to + * get profile supported features mask. + */ + err = bt_sdp_get_features(result->resp_buf, &features); + if (err < 0) { + bt_shell_error("A2SRC Features not found, err %d", err); + goto done; } + bt_shell_print("A2SRC Supported Features param 0x%04x", features); + +done: + return BT_SDP_DISCOVER_UUID_CONTINUE; +} + +static uint8_t sdp_a2snk_user(struct bt_conn *conn, struct bt_sdp_client_result *result, + const struct bt_sdp_discover_params *params) +{ + char addr[BT_ADDR_STR_LEN]; + uint16_t param, version; + uint16_t features; + int err; + + conn_addr_str(conn, addr, sizeof(addr)); + + if (result == NULL || result->resp_buf == NULL) { + bt_shell_print("No SDP A2SNK data from remote %s", addr); + goto done; + } + + bt_shell_print("SDP A2SNK data@%p (len %u) hint %u from remote %s", + result->resp_buf, result->resp_buf->len, result->next_record_hint, + addr); + + /* + * Focus to get BT_SDP_ATTR_PROTO_DESC_LIST attribute item to + * get A2SNK Server PSM Number. + */ + err = bt_sdp_get_proto_param(result->resp_buf, BT_SDP_PROTO_L2CAP, ¶m); + if (err < 0) { + bt_shell_error("A2SNK PSM Number not found, err %d", err); + goto done; + } + + bt_shell_print("A2SNK Server PSM Number param 0x%04x", param); + + err = bt_sdp_get_proto_param(result->resp_buf, BT_UUID_AVDTP_VAL, &version); + if (err < 0) { + bt_shell_error("A2SNK AVDTP version not found, err %d", err); + goto done; + } + + bt_shell_print("A2SNK Server AVDTP version 0x%04x", version); + + /* + * Focus to get BT_SDP_ATTR_PROFILE_DESC_LIST attribute item to + * get profile version number. + */ + err = bt_sdp_get_profile_version(result->resp_buf, BT_SDP_ADVANCED_AUDIO_SVCLASS, &version); + if (err < 0) { + bt_shell_error("A2SNK version not found, err %d", err); + goto done; + } + bt_shell_print("A2SNK version param 0x%04x", version); + + /* + * Focus to get BT_SDP_ATTR_SUPPORTED_FEATURES attribute item to + * get profile supported features mask. + */ + err = bt_sdp_get_features(result->resp_buf, &features); + if (err < 0) { + bt_shell_error("A2SNK Features not found, err %d", err); + goto done; + } + bt_shell_print("A2SNK Supported Features param 0x%04x", features); + done: return BT_SDP_DISCOVER_UUID_CONTINUE; } @@ -1052,6 +1126,13 @@ static struct bt_sdp_discover_params discov_a2src = { .pool = &sdp_client_pool, }; +static struct bt_sdp_discover_params discov_a2snk = { + .type = BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR, + .uuid = BT_UUID_DECLARE_16(BT_SDP_AUDIO_SINK_SVCLASS), + .func = sdp_a2snk_user, + .pool = &sdp_client_pool, +}; + static struct bt_sdp_discover_params discov_pnp = { .type = BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR, .uuid = BT_UUID_DECLARE_16(BT_SDP_PNP_INFO_SVCLASS), @@ -1079,6 +1160,8 @@ static int cmd_sdp_find_record(const struct shell *sh, size_t argc, char *argv[] discov = discov_hfphf; } else if (!strcmp(action, "A2SRC")) { discov = discov_a2src; + } else if (!strcmp(action, "A2SNK")) { + discov = discov_a2snk; } else if (!strcmp(action, "PNP")) { discov = discov_pnp; } else { @@ -1490,7 +1573,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(br_cmds, SHELL_CMD(l2cap, &l2cap_cmds, HELP_NONE, cmd_default_handler), SHELL_CMD_ARG(oob, NULL, NULL, cmd_oob, 1, 0), SHELL_CMD_ARG(pscan, NULL, "", cmd_connectable, 2, 0), - SHELL_CMD_ARG(sdp-find, NULL, "", cmd_sdp_find_record, 2, 0), + SHELL_CMD_ARG(sdp-find, NULL, "", + cmd_sdp_find_record, 2, 0), SHELL_CMD_ARG(switch-role, NULL, "", cmd_switch_role, 2, 0), SHELL_CMD_ARG(set-role-switchable, NULL, "", cmd_set_role_switchable, 2, 0), From 63299bb68b5ec1529e37b2fc2557e9cd3bca6a46 Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Tue, 22 Jul 2025 07:19:06 +0200 Subject: [PATCH 0034/1076] drivers: ethernet: sy1xx: fix static prototype removed invalid arguments. Signed-off-by: Sven Ginka --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index ca7f51d3f6d85..c2dbe7a203b99 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -103,7 +103,7 @@ struct sy1xx_mac_dev_data { }; /* prototypes */ -static int sy1xx_mac_set_mac_addr(const struct device *dev, uint8_t *mac_addr); +static int sy1xx_mac_set_mac_addr(const struct device *dev); static int sy1xx_mac_set_promiscuous_mode(const struct device *dev, bool promiscuous_mode); static int sy1xx_mac_set_config(const struct device *dev, enum ethernet_config_type type, const struct ethernet_config *config); From a79e986e0385253ce43087198aa8537e7ea0d34a Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Thu, 21 Aug 2025 10:47:47 +0200 Subject: [PATCH 0035/1076] drivers: ethernet: sy1xx: fix warning casting the address to uint32_t removes the compiler warning. Signed-off-by: Sven Ginka --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index c2dbe7a203b99..a70ffc3b40bb2 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -312,7 +312,7 @@ static void sy1xx_mac_iface_init(struct net_if *iface) struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; struct sy1xx_mac_dev_data *const data = dev->data; - LOG_INF("Interface init %s (%.8x)", net_if_get_device(iface)->name, iface); + LOG_INF("Interface init %s (%p)", net_if_get_device(iface)->name, iface); data->iface = iface; From ddc4f5f0be865e55823b46e307f1d01ca5ce491e Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Thu, 21 Aug 2025 11:15:47 +0200 Subject: [PATCH 0036/1076] drivers: ethernet: sy1xx: fix random mac before that commit, random mac was used even when defining zephyr,random-mac-address to false. Signed-off-by: Sven Ginka --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index a70ffc3b40bb2..d254bb137343d 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -208,7 +208,6 @@ static int sy1xx_mac_start(const struct device *dev) sys_rand_get(&data->mac_addr, 6); /* Set MAC address locally administered, unicast (LAA) */ data->mac_addr[0] |= 0x02; - } sy1xx_mac_set_mac_addr(dev); @@ -571,7 +570,7 @@ const struct ethernet_api sy1xx_mac_driver_api = { .base_addr = DT_INST_REG_ADDR_BY_NAME(n, data), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .promiscuous_mode = DT_INST_PROP_OR(n, promiscuous_mode, false), \ - .use_zephyr_random_mac = DT_INST_NODE_HAS_PROP(n, zephyr_random_mac_address), \ + .use_zephyr_random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \ .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0, phy_handle))}; \ \ static struct sy1xx_mac_dma_buffers __attribute__((section(".udma_access"))) \ From 03f20f971255319aba71208f161b80ee865f761a Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Tue, 29 Jul 2025 13:53:47 +0200 Subject: [PATCH 0037/1076] rtio: Add Flush completion queue API Add API to flush completion queue. Signed-off-by: Armando Visconti --- include/zephyr/rtio/rtio.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 25b4beaa91242..ea4e638927ee9 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -1175,6 +1175,32 @@ static inline void rtio_cqe_release(struct rtio *r, struct rtio_cqe *cqe) rtio_cqe_pool_free(r->cqe_pool, cqe); } +/** + * @brief Flush completion queue + * + * @param r RTIO context + * @return The operation completion result + * @retval 0 if the queued operations completed with no error + * @retval <0 on error + */ +static inline int rtio_flush_completion_queue(struct rtio *r) +{ + struct rtio_cqe *cqe; + int res = 0; + + do { + cqe = rtio_cqe_consume(r); + if (cqe != NULL) { + if ((cqe->result < 0) && (res == 0)) { + res = cqe->result; + } + rtio_cqe_release(r, cqe); + } + } while (cqe != NULL); + + return res; +} + /** * @brief Compute the CQE flags from the rtio_iodev_sqe entry * From c4ddc85e6957506b20dff212187fc7a2efeecef8 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Fri, 15 Aug 2025 18:24:54 +0800 Subject: [PATCH 0038/1076] soc: it51xxx: Disable default 15K pull-down on GPF4/GPF5 When GPIOF4 and GPIOF5 are not used as USB alternate function, the default 15K pull-down should be disabled. Signed-off-by: Tim Lin --- soc/ite/ec/it51xxx/chip_chipregs.h | 10 ++++++++-- soc/ite/ec/it51xxx/soc.c | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/soc/ite/ec/it51xxx/chip_chipregs.h b/soc/ite/ec/it51xxx/chip_chipregs.h index 725a696e47443..f8e829a72dc3d 100644 --- a/soc/ite/ec/it51xxx/chip_chipregs.h +++ b/soc/ite/ec/it51xxx/chip_chipregs.h @@ -91,8 +91,12 @@ struct smfi_it51xxx_regs { struct gpio_it51xxx_regs { /* 0x00: General Control */ volatile uint8_t GPIO_GCR; - /* 0x01-CF: Reserved_01_cf */ - volatile uint8_t reserved_01_cf[207]; + /* 0x01-C1: Reserved_01_c1 */ + volatile uint8_t reserved_01_c1[193]; + /* 0xC2: General Control 35 */ + volatile uint8_t GPIO_GCR35; + /* 0xC3-CF: Reserved_c3_cf */ + volatile uint8_t reserved_c3_cf[13]; /* 0xD0: General Control 31 */ volatile uint8_t GPIO_GCR31; /* 0xD1: General Control 32 */ @@ -194,6 +198,8 @@ struct gpio_it51xxx_regs { /* 0x00: General Control */ #define IT51XXX_GPIO_LPCRSTEN (BIT(2) | BIT(1)) #define ITE_EC_GPIO_LPCRSTEN IT51XXX_GPIO_LPCRSTEN +/* 0xC2: General Control 35 */ +#define IT51XXX_GPIO_USBPDEN BIT(5) /* 0xF0: General Control 1 */ #define IT51XXX_GPIO_U2CTRL_SIN1_SOUT1_EN BIT(2) #define IT51XXX_GPIO_U1CTRL_SIN0_SOUT0_EN BIT(0) diff --git a/soc/ite/ec/it51xxx/soc.c b/soc/ite/ec/it51xxx/soc.c index cb1aa52bf7944..648e5cb39ce7e 100644 --- a/soc/ite/ec/it51xxx/soc.c +++ b/soc/ite/ec/it51xxx/soc.c @@ -117,6 +117,9 @@ void soc_prep_hook(void) struct gpio_ite_ec_regs *const gpio_regs = GPIO_ITE_EC_REGS_BASE; struct gctrl_ite_ec_regs *const gctrl_regs = GCTRL_ITE_EC_REGS_BASE; + /* USB pull down disable */ + gpio_regs->GPIO_GCR35 &= ~IT51XXX_GPIO_USBPDEN; + /* Set FSPI pins are tri-state */ sys_write8(sys_read8(IT51XXX_SMFI_FLHCTRL3R) | IT51XXX_SMFI_FFSPITRI, IT51XXX_SMFI_FLHCTRL3R); From f5bbdaf8e7fdb04d11834afc7aa807c5cb47e9a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 21 Aug 2025 14:00:48 +0200 Subject: [PATCH 0039/1076] drivers: ethernet: phy: select MDIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit devices on a bus are recomended to select its protocol, apply this to the eth phys on the mdio bus, so that they just work by enableing the device in the dts. Signed-off-by: Fin Maaß --- drivers/ethernet/phy/Kconfig | 18 ++++++++++-------- drivers/ethernet/phy/Kconfig.dm8806 | 2 +- drivers/ethernet/phy/Kconfig.microchip_t1s | 2 +- drivers/ethernet/phy/Kconfig.tja1103 | 2 +- drivers/ethernet/phy/Kconfig.tja11xx | 2 +- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 4caf58d1f5373..2b47a1932e33e 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -30,8 +30,9 @@ config PHY_INIT_PRIORITY config PHY_GENERIC_MII bool "Generic MII PHY Driver" - default y if DT_HAS_ETHERNET_PHY_ENABLED - depends on MDIO + default y + depends on DT_HAS_ETHERNET_PHY_ENABLED + select MDIO help This is a generic MII PHY interface that communicates with the PHY using the MDIO bus. @@ -40,6 +41,7 @@ config PHY_ADIN2111 bool "ADIN2111 PHY driver" default y depends on DT_HAS_ADI_ADIN2111_PHY_ENABLED || DT_HAS_ADI_ADIN1100_PHY_ENABLED + select MDIO help Enable ADIN2111 PHY driver. @@ -47,7 +49,7 @@ config PHY_MICROCHIP_KSZ8081 bool "Microchip KSZ8081 PHY Driver" default y depends on DT_HAS_MICROCHIP_KSZ8081_ENABLED - depends on MDIO + select MDIO depends on GPIO help Enable Microchip KSZ8081 Ethernet PHY Driver @@ -56,7 +58,7 @@ config PHY_MICROCHIP_VSC8541 bool "Microchip VSC8541 PHY Driver" default y depends on DT_HAS_MICROCHIP_VSC8541_ENABLED - depends on MDIO + select MDIO depends on GPIO help Enable Microchip VSC8541 Ethernet PHY Driver @@ -65,7 +67,7 @@ config PHY_TI_DP83825 bool "TI DP83825 PHY Driver" default y depends on DT_HAS_TI_DP83825_ENABLED - depends on MDIO + select MDIO depends on GPIO help Enable TI DP83825 Ethernet PHY Driver @@ -74,7 +76,7 @@ config PHY_TI_DP83867 bool "TI DP83867 PHY Driver" default y depends on DT_HAS_TI_DP83867_ENABLED - depends on MDIO + select MDIO depends on GPIO help Enable TI DP83867 Ethernet PHY Driver @@ -83,7 +85,7 @@ config PHY_REALTEK_RTL8211F bool "Realtek RTL8211F PHY Driver" default y depends on DT_HAS_REALTEK_RTL8211F_ENABLED - depends on MDIO + select MDIO depends on GPIO || (!$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),reset-gpios) && \ !$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),int-gpios)) help @@ -93,7 +95,7 @@ config PHY_QUALCOMM_AR8031 bool "Qualcomm Atheros AR8031 Ethernet PHY Driver" default y depends on DT_HAS_QCA_AR8031_ENABLED - depends on MDIO + select MDIO help Enable Qualcomm Atheros AR8031 Ethernet PHY Driver diff --git a/drivers/ethernet/phy/Kconfig.dm8806 b/drivers/ethernet/phy/Kconfig.dm8806 index e952420f7f0c9..a0713a7a28a3a 100644 --- a/drivers/ethernet/phy/Kconfig.dm8806 +++ b/drivers/ethernet/phy/Kconfig.dm8806 @@ -7,7 +7,7 @@ menuconfig PHY_DM8806 bool "Davicom PHY DM8806 driver" default y depends on DT_HAS_DAVICOM_DM8806_PHY_ENABLED - depends on MDIO + select MDIO help Enable driver for Davicom DM8806 PHY. diff --git a/drivers/ethernet/phy/Kconfig.microchip_t1s b/drivers/ethernet/phy/Kconfig.microchip_t1s index ae0b27b076ad9..a5d9e6008e4f1 100644 --- a/drivers/ethernet/phy/Kconfig.microchip_t1s +++ b/drivers/ethernet/phy/Kconfig.microchip_t1s @@ -5,7 +5,7 @@ config PHY_MICROCHIP_T1S bool "Microchip 10BASE-T1S Ethernet PHYs Driver" default y depends on DT_HAS_MICROCHIP_T1S_PHY_ENABLED - depends on MDIO + select MDIO select PHY_OA_TC14_PLCA_LIB help Enable Microchip's LAN8650/1 Rev.B0/B1 Internal PHYs and diff --git a/drivers/ethernet/phy/Kconfig.tja1103 b/drivers/ethernet/phy/Kconfig.tja1103 index e0a00955ce7a2..e7ee267df254c 100644 --- a/drivers/ethernet/phy/Kconfig.tja1103 +++ b/drivers/ethernet/phy/Kconfig.tja1103 @@ -7,7 +7,7 @@ menuconfig PHY_TJA1103 bool "TJA1103 PHY driver" default y depends on DT_HAS_NXP_TJA1103_ENABLED - depends on MDIO + select MDIO help Enable TJA1103 PHY driver. diff --git a/drivers/ethernet/phy/Kconfig.tja11xx b/drivers/ethernet/phy/Kconfig.tja11xx index b4cff9b74851b..995f13f3fd4dd 100644 --- a/drivers/ethernet/phy/Kconfig.tja11xx +++ b/drivers/ethernet/phy/Kconfig.tja11xx @@ -7,6 +7,6 @@ config PHY_TJA11XX bool "TJA11XX PHY driver" default y depends on DT_HAS_NXP_TJA11XX_ENABLED - depends on MDIO + select MDIO help Enable TJA11xx PHY driver. From e053f1aad50004c43ec1e62b18cf576ddf146913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 21 Aug 2025 14:02:51 +0200 Subject: [PATCH 0040/1076] drivers: ethernet: phy: select GPIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit devices on a bus are recomended to select its needed drivers, apply this to the eth phys that need gpios, so that they just work by enableing the device in the dts. Signed-off-by: Fin Maaß --- drivers/ethernet/phy/Kconfig | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 2b47a1932e33e..5cb3b336499e5 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -50,7 +50,8 @@ config PHY_MICROCHIP_KSZ8081 default y depends on DT_HAS_MICROCHIP_KSZ8081_ENABLED select MDIO - depends on GPIO + select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_MICROCHIP_KSZ8081),reset-gpios) || \ + $(dt_compat_any_has_prop,$(DT_COMPAT_MICROCHIP_KSZ8081),int-gpios)) help Enable Microchip KSZ8081 Ethernet PHY Driver @@ -59,7 +60,8 @@ config PHY_MICROCHIP_VSC8541 default y depends on DT_HAS_MICROCHIP_VSC8541_ENABLED select MDIO - depends on GPIO + select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_MICROCHIP_VSC8541),reset-gpios) || \ + $(dt_compat_any_has_prop,$(DT_COMPAT_MICROCHIP_VSC8541),int-gpios)) help Enable Microchip VSC8541 Ethernet PHY Driver @@ -68,7 +70,8 @@ config PHY_TI_DP83825 default y depends on DT_HAS_TI_DP83825_ENABLED select MDIO - depends on GPIO + select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_TI_DP83825),reset-gpios) || \ + $(dt_compat_any_has_prop,$(DT_COMPAT_TI_DP83825),int-gpios)) help Enable TI DP83825 Ethernet PHY Driver @@ -77,7 +80,8 @@ config PHY_TI_DP83867 default y depends on DT_HAS_TI_DP83867_ENABLED select MDIO - depends on GPIO + select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_TI_DP83867),reset-gpios) || \ + $(dt_compat_any_has_prop,$(DT_COMPAT_TI_DP83867),int-gpios)) help Enable TI DP83867 Ethernet PHY Driver @@ -86,8 +90,8 @@ config PHY_REALTEK_RTL8211F default y depends on DT_HAS_REALTEK_RTL8211F_ENABLED select MDIO - depends on GPIO || (!$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),reset-gpios) && \ - !$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),int-gpios)) + select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),reset-gpios) || \ + $(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),int-gpios)) help Enable Realtek RTL8211F Ethernet PHY Driver From 57c4a5572a7c37a1ef868a901d469d2db00443e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 21 Aug 2025 14:20:54 +0200 Subject: [PATCH 0041/1076] drivers: ethernet: remove select MDIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove `select MDIO` from the ethernet drivers, that don't directly use mdio and only use the ethernet phy api, now that the phys select MDIO Signed-off-by: Fin Maaß --- drivers/ethernet/Kconfig.adin2111 | 1 - drivers/ethernet/Kconfig.esp32 | 1 - drivers/ethernet/Kconfig.lan865x | 1 - drivers/ethernet/Kconfig.nxp_enet | 1 - drivers/ethernet/Kconfig.nxp_s32_netc | 1 - drivers/ethernet/Kconfig.renesas_ra | 1 - drivers/ethernet/Kconfig.sam_gmac | 1 - drivers/ethernet/Kconfig.stm32_hal | 1 - drivers/ethernet/Kconfig.sy1xx_mac | 1 - drivers/ethernet/eth_nxp_enet_qos/Kconfig | 1 - drivers/ethernet/intel/Kconfig.intel_igc | 1 - drivers/ethernet/nxp_imx_netc/Kconfig | 1 - 12 files changed, 12 deletions(-) diff --git a/drivers/ethernet/Kconfig.adin2111 b/drivers/ethernet/Kconfig.adin2111 index 2e1cbd8a0afdb..518035e74804f 100644 --- a/drivers/ethernet/Kconfig.adin2111 +++ b/drivers/ethernet/Kconfig.adin2111 @@ -6,7 +6,6 @@ menuconfig ETH_ADIN2111 default y depends on DT_HAS_ADI_ADIN2111_ENABLED || DT_HAS_ADI_ADIN1110_ENABLED select SPI - select MDIO imply CRC help The ADIN2111 is a low power, 2-port 10BASE-T1L transceiver diff --git a/drivers/ethernet/Kconfig.esp32 b/drivers/ethernet/Kconfig.esp32 index 35c07860f4ef3..ad2c8bfa0e79c 100644 --- a/drivers/ethernet/Kconfig.esp32 +++ b/drivers/ethernet/Kconfig.esp32 @@ -8,7 +8,6 @@ menuconfig ETH_ESP32 default y depends on SOC_SERIES_ESP32 depends on DT_HAS_ESPRESSIF_ESP32_ETH_ENABLED - select MDIO help Enable ESP32 Ethernet driver. diff --git a/drivers/ethernet/Kconfig.lan865x b/drivers/ethernet/Kconfig.lan865x index 347e73781523b..7f48550e5c4c0 100644 --- a/drivers/ethernet/Kconfig.lan865x +++ b/drivers/ethernet/Kconfig.lan865x @@ -6,7 +6,6 @@ menuconfig ETH_LAN865X default y depends on DT_HAS_MICROCHIP_LAN865X_ENABLED select SPI - select MDIO select NET_L2_ETHERNET_MGMT help The LAN865X is a low power, 10BASE-T1S transceiver compliant with diff --git a/drivers/ethernet/Kconfig.nxp_enet b/drivers/ethernet/Kconfig.nxp_enet index c035fbf686bf0..953ce84d51233 100644 --- a/drivers/ethernet/Kconfig.nxp_enet +++ b/drivers/ethernet/Kconfig.nxp_enet @@ -12,7 +12,6 @@ config ETH_NXP_ENET depends on DT_HAS_NXP_ENET_MAC_ENABLED select NOCACHE_MEMORY if CPU_HAS_DCACHE select ARM_MPU if CPU_CORTEX_M7 - select MDIO if DT_HAS_NXP_ENET_MDIO_ENABLED select NET_POWER_MANAGEMENT if (PM_DEVICE && SOC_FAMILY_KINETIS) select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL diff --git a/drivers/ethernet/Kconfig.nxp_s32_netc b/drivers/ethernet/Kconfig.nxp_s32_netc index bf5a85cb97260..17a0d1f6c56d6 100644 --- a/drivers/ethernet/Kconfig.nxp_s32_netc +++ b/drivers/ethernet/Kconfig.nxp_s32_netc @@ -7,7 +7,6 @@ menuconfig ETH_NXP_S32_NETC depends on (DT_HAS_NXP_S32_NETC_PSI_ENABLED || DT_HAS_NXP_S32_NETC_VSI_ENABLED) select MBOX select PINCTRL - select MDIO if DT_HAS_NXP_S32_NETC_PSI_ENABLED select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable Ethernet Switch and Controller (NETC) driver for NXP S32 SoCs. diff --git a/drivers/ethernet/Kconfig.renesas_ra b/drivers/ethernet/Kconfig.renesas_ra index a6c04e9392b17..c107d9acbd5bf 100644 --- a/drivers/ethernet/Kconfig.renesas_ra +++ b/drivers/ethernet/Kconfig.renesas_ra @@ -6,7 +6,6 @@ config ETH_RENESAS_RA default y depends on DT_HAS_RENESAS_RA_ETHERNET_ENABLED select USE_RA_FSP_ETHER - select MDIO help Enable Renesas RA Ethernet Driver. diff --git a/drivers/ethernet/Kconfig.sam_gmac b/drivers/ethernet/Kconfig.sam_gmac index 60403612bbb52..fed74b1ca40c2 100644 --- a/drivers/ethernet/Kconfig.sam_gmac +++ b/drivers/ethernet/Kconfig.sam_gmac @@ -10,7 +10,6 @@ menuconfig ETH_SAM_GMAC depends on DT_HAS_ATMEL_SAM_GMAC_ENABLED || \ DT_HAS_ATMEL_SAM0_GMAC_ENABLED select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT - select MDIO select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL help diff --git a/drivers/ethernet/Kconfig.stm32_hal b/drivers/ethernet/Kconfig.stm32_hal index fc9beba2d90fb..3fd26ab4adde0 100644 --- a/drivers/ethernet/Kconfig.stm32_hal +++ b/drivers/ethernet/Kconfig.stm32_hal @@ -14,7 +14,6 @@ menuconfig ETH_STM32_HAL select HWINFO select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL - select MDIO if DT_HAS_ST_STM32_MDIO_ENABLED imply CRC help Enable STM32 HAL based Ethernet driver. It is available for diff --git a/drivers/ethernet/Kconfig.sy1xx_mac b/drivers/ethernet/Kconfig.sy1xx_mac index 8493aa5305f54..58adf680e533f 100644 --- a/drivers/ethernet/Kconfig.sy1xx_mac +++ b/drivers/ethernet/Kconfig.sy1xx_mac @@ -5,7 +5,6 @@ config ETH_SY1XX bool "Sensry SY1XX Ethernet driver" default y depends on DT_HAS_SENSRY_SY1XX_MAC_ENABLED - select MDIO select PINCTRL help Enable Sensry SY1XX Ethernet MAC driver. diff --git a/drivers/ethernet/eth_nxp_enet_qos/Kconfig b/drivers/ethernet/eth_nxp_enet_qos/Kconfig index 2f14424499840..a5fab3d617fdd 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/Kconfig +++ b/drivers/ethernet/eth_nxp_enet_qos/Kconfig @@ -6,7 +6,6 @@ menuconfig ETH_NXP_ENET_QOS default y depends on DT_HAS_NXP_ENET_QOS_ENABLED select PINCTRL - select MDIO if DT_HAS_NXP_ENET_QOS_MDIO_ENABLED help Enable NXP ENET Ethernet Module Driver. This driver handles IP module level tasks. diff --git a/drivers/ethernet/intel/Kconfig.intel_igc b/drivers/ethernet/intel/Kconfig.intel_igc index a8d37b5adcfd1..c13f874adb0e2 100644 --- a/drivers/ethernet/intel/Kconfig.intel_igc +++ b/drivers/ethernet/intel/Kconfig.intel_igc @@ -5,7 +5,6 @@ menuconfig ETH_INTEL_IGC bool "Intel IGC MAC driver" default y depends on DT_HAS_INTEL_IGC_MAC_ENABLED - select MDIO select PCIE_MSI_MULTI_VECTOR select PCIE_MSI_X help diff --git a/drivers/ethernet/nxp_imx_netc/Kconfig b/drivers/ethernet/nxp_imx_netc/Kconfig index 6c2a3eff29e2b..0769dae16ac09 100644 --- a/drivers/ethernet/nxp_imx_netc/Kconfig +++ b/drivers/ethernet/nxp_imx_netc/Kconfig @@ -5,7 +5,6 @@ menuconfig ETH_NXP_IMX_NETC bool "NXP IMX Ethernet and Network Controller (NETC) driver" default y depends on DT_HAS_NXP_IMX_NETC_PSI_ENABLED - select MDIO select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT help Enable Ethernet and Network Controller (NETC) driver for NXP IMX SoCs. From b82c44ce2042701a825329227e7c7b6d913f6d0b Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Tue, 19 Aug 2025 16:21:54 +0200 Subject: [PATCH 0042/1076] boards: intel_adsp: set correct stack size for ACE30_WCL set correct stack size for ACE30_WCL Signed-off-by: Adrian Bonislawski --- boards/intel/adsp/Kconfig.defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/intel/adsp/Kconfig.defconfig b/boards/intel/adsp/Kconfig.defconfig index 8c804c48c7508..3feaea882ca26 100644 --- a/boards/intel/adsp/Kconfig.defconfig +++ b/boards/intel/adsp/Kconfig.defconfig @@ -21,5 +21,7 @@ config MAIN_STACK_SIZE default 4096 if BOARD_INTEL_ADSP_ACE30 default 4096 if BOARD_INTEL_ADSP_ACE30_PTL default 4096 if BOARD_INTEL_ADSP_ACE30_PTL_SIM + default 4096 if BOARD_INTEL_ADSP_ACE30_WCL + default 4096 if BOARD_INTEL_ADSP_ACE30_WCL_SIM endif # BOARD_INTEL_ADSP From 9cc01806c67e8c217438085a7d6a929c2f81eb31 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Fri, 22 Aug 2025 13:23:03 +0200 Subject: [PATCH 0043/1076] doc: Fix anchor element for Kconfig symbol location Fixes the element href assignment of the Kconfig symbol generation. Signed-off-by: Fabian Blatz --- doc/_extensions/zephyr/kconfig/static/kconfig.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs index 4f175f4c1cc9f..14c9ffb2f521c 100644 --- a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs +++ b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs @@ -316,10 +316,10 @@ function renderKconfigEntry(entry) { let locationPermalink = getGithubLink(entry.filename, entry.linenr, "blob", zephyr_version); if (locationPermalink) { - const locationPermalink = document.createElement('a'); - locationPermalink.href = locationPermalink; - locationPermalink.appendChild(locationElement); - renderKconfigPropLiteralElement(props, 'Location', locationPermalink); + const locationPermalinkElement = document.createElement('a'); + locationPermalinkElement.href = locationPermalink; + locationPermalinkElement.appendChild(locationElement); + renderKconfigPropLiteralElement(props, 'Location', locationPermalinkElement); } else { renderKconfigPropLiteralElement(props, 'Location', locationElement); } From da75828459debe48d4de27b6d8c1ab4a92fe163b Mon Sep 17 00:00:00 2001 From: Jonas Spinner Date: Mon, 25 Aug 2025 11:19:37 +0200 Subject: [PATCH 0044/1076] net: gptp: fix clock accuracy description Previously, the Kconfig option `NET_GPTP_CLOCK_ACCURACY_2_5MS` had a incorrect description "1.5ms". Signed-off-by: Jonas Spinner --- subsys/net/l2/ethernet/gptp/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/ethernet/gptp/Kconfig b/subsys/net/l2/ethernet/gptp/Kconfig index 01c15f02d37ad..68c751727d49e 100644 --- a/subsys/net/l2/ethernet/gptp/Kconfig +++ b/subsys/net/l2/ethernet/gptp/Kconfig @@ -75,7 +75,7 @@ config NET_GPTP_CLOCK_ACCURACY_1MS bool "1ms" config NET_GPTP_CLOCK_ACCURACY_2_5MS - bool "1.5ms" + bool "2.5ms" config NET_GPTP_CLOCK_ACCURACY_10MS bool "10ms" From 555ebf93badae578a42dfc58fbb50b9761103ebf Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 20 Aug 2025 16:49:17 +0200 Subject: [PATCH 0045/1076] doc: Bluetooth: CAP: Shell: Remove reference to name for adv The adv-create command no longer takes a name, and the shell documentation has been updated to reflect that. Instead the device name can be added via the adv-data command. Signed-off-by: Emil Gydesen --- doc/connectivity/bluetooth/shell/audio/cap.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/bluetooth/shell/audio/cap.rst b/doc/connectivity/bluetooth/shell/audio/cap.rst index a620981b60ca4..47ff4781e0cac 100644 --- a/doc/connectivity/bluetooth/shell/audio/cap.rst +++ b/doc/connectivity/bluetooth/shell/audio/cap.rst @@ -208,13 +208,15 @@ The following commands will setup a CAP broadcast source using the 16_2_1 preset bt init bap init - bt adv-create nconn-nscan ext-adv name + bt adv-create nconn-nscan ext-adv bt per-adv-param bap preset broadcast 16_2_1 cap_initiator ac_12 - bt adv-data discov + bt adv-data dev-name discov bt per-adv-data cap_initiator broadcast_start + bt adv-start + bt per-adv on The broadcast source is created by the :code:`cap_initiator ac_12`, :code:`cap_initiator ac_13`, From 5416b3a182e2a2bd50a1796b38c375f46c74c4ff Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 20 Aug 2025 16:50:53 +0200 Subject: [PATCH 0046/1076] doc: Bluetooth: GAP: Shell: Remove reference to name for adv The adv-create command no longer takes a name, and the shell documentation has been updated to reflect that. Signed-off-by: Emil Gydesen --- doc/connectivity/bluetooth/shell/host/gap.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connectivity/bluetooth/shell/host/gap.rst b/doc/connectivity/bluetooth/shell/host/gap.rst index 3e2e2f477bf11..c7c8753fbd187 100644 --- a/doc/connectivity/bluetooth/shell/host/gap.rst +++ b/doc/connectivity/bluetooth/shell/host/gap.rst @@ -185,7 +185,7 @@ Let's now have a look at some extended advertising features. To enable extended .. code-block:: console - uart:~$ bt adv-create conn-nscan ext-adv name-ad + uart:~$ bt adv-create conn-nscan ext-adv Created adv id: 0, adv: 0x200022f0 uart:~$ bt adv-start Advertiser[0] 0x200022f0 set started From 7ec51764d0faff7872b4ee9614af506963bb21cd Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 20 Aug 2025 16:51:20 +0200 Subject: [PATCH 0047/1076] Bluetooth: BAP: Shell: Print broadcast ID and broadcast name when scanning When scanning, the broadcast_scan_recv now prints the broadcast ID and the broadcast name (if found). Without this, it is not possible to use the shell to scan for an unknown broadcast ID or broadcast name. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/bap.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index dcad633fcfe9a..3e92d82c274d9 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -2384,7 +2384,7 @@ static uint16_t interval_to_sync_timeout(uint16_t interval) return (uint16_t)timeout; } -static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) +static bool scan_check_and_get_broadcast_values(struct bt_data *data, void *user_data) { struct bt_broadcast_info *sr_info = (struct bt_broadcast_info *)user_data; struct bt_uuid_16 adv_uuid; @@ -2427,17 +2427,11 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct sr_info.broadcast_id = BT_BAP_INVALID_BROADCAST_ID; - if ((auto_scan.broadcast_info.broadcast_id == BT_BAP_INVALID_BROADCAST_ID) && - (strlen(auto_scan.broadcast_info.broadcast_name) == 0U)) { - /* no op */ - return; - } - if (!passes_scan_filter(info, ad)) { return; } - bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&sr_info); + bt_data_parse(ad, scan_check_and_get_broadcast_values, (void *)&sr_info); /* Verify that it is a BAP broadcaster*/ if (sr_info.broadcast_id == BT_BAP_INVALID_BROADCAST_ID) { @@ -2446,6 +2440,15 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); + bt_shell_print("Found broadcaster with ID 0x%06X (%s) and addr %s and sid 0x%02X ", + sr_info.broadcast_id, sr_info.broadcast_name, addr_str, info->sid); + + if ((auto_scan.broadcast_info.broadcast_id == BT_BAP_INVALID_BROADCAST_ID) && + (strlen(auto_scan.broadcast_info.broadcast_name) == 0U)) { + /* no op */ + return; + } + if (sr_info.broadcast_id == auto_scan.broadcast_info.broadcast_id) { identified_broadcast = true; } else if ((strlen(auto_scan.broadcast_info.broadcast_name) != 0U) && @@ -2462,10 +2465,6 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct struct bt_le_per_adv_sync_param create_params = {0}; int err; - bt_shell_print( - "Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X ", - sr_info.broadcast_id, addr_str, info->sid); - err = bt_le_scan_stop(); if (err != 0) { bt_shell_error("Could not stop scan: %d", err); From bfaa1169e88ec608ba87503a5cc7769d54af6efd Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 20 Aug 2025 16:53:27 +0200 Subject: [PATCH 0048/1076] Bluetooth: BAP: Shell: Print generated broadcast ID Since the broadcast ID is generated at runtime, it is nice to get it printed so that it can be shared. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/bap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 3e92d82c274d9..f022f738204e9 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -4341,6 +4341,7 @@ static size_t nonconnectable_ad_data_add(struct bt_data *data_array, const size_ return 0; } + bt_shell_print("Generated broadcast_id 0x%06X", broadcast_id); sys_put_le24(broadcast_id, &ad_bap_broadcast_announcement[2]); data_array[ad_len].type = BT_DATA_SVC_DATA16; From 62c8ca3498ba0c8d02941d2124844faf3bda84cf Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 20 Aug 2025 16:54:03 +0200 Subject: [PATCH 0049/1076] Bluetooth: CAP: Shell: Print generated broadcast ID Since the broadcast ID is generated at runtime, it is nice to get it printed so that it can be shared. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/cap_initiator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/audio/shell/cap_initiator.c b/subsys/bluetooth/audio/shell/cap_initiator.c index d9a076984966e..1f628ef252578 100644 --- a/subsys/bluetooth/audio/shell/cap_initiator.c +++ b/subsys/bluetooth/audio/shell/cap_initiator.c @@ -1446,6 +1446,7 @@ static size_t nonconnectable_ad_data_add(struct bt_data *data_array, const size_ return 0; } + bt_shell_print("Generated broadcast_id 0x%06X", broadcast_id); sys_put_le24(broadcast_id, &ad_cap_broadcast_announcement[2]); data_array[0].type = BT_DATA_SVC_DATA16; From bffe74e5e8e4af2bfdf7d0b7830b3248ffe983fc Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 21 Aug 2025 15:30:11 +0200 Subject: [PATCH 0050/1076] tests: clock_control: stm32l0: Fix dts build due to missing hsi-div Following introduction of hsi-div on L0, upate hsi description on l0. Since this description is not compatible with l1 series anymore add a dedicated l0 test variant and matching overlay. Signed-off-by: Erwan Gouriou --- .../boards/l0_pll_32_hsi_16.overlay | 27 +++++++++++++++++++ .../stm32_common_core/testcase.yaml | 9 +++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/l0_pll_32_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/l0_pll_32_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/l0_pll_32_hsi_16.overlay new file mode 100644 index 0000000000000..36896295ca7c5 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/l0_pll_32_hsi_16.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after clear_clocks.overlay file. + */ + +&clk_hsi { + hsi-div = <1>; + status = "okay"; +}; + +&pll { + div = <2>; + mul = <4>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml index dbc0f6722eaa5..08b84a6577f92 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml @@ -133,11 +133,16 @@ tests: - nucleo_l073rz integration_platforms: - nucleo_l152re - drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hsi_16: + drivers.clock.stm32_clock_configuration.common_core.l0.sysclksrc_pll_32_hsi_16: + extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/l0_pll_32_hsi_16.overlay" + platform_allow: + - nucleo_l073rz + integration_platforms: + - nucleo_l073rz + drivers.clock.stm32_clock_configuration.common_core.l1.sysclksrc_pll_32_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_32_hsi_16.overlay" platform_allow: - nucleo_l152re - - nucleo_l073rz integration_platforms: - nucleo_l152re drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_msi_range6: From c74aaabaf6be277a2e9976e982e227f08b90684f Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 21 Aug 2025 16:41:50 +0200 Subject: [PATCH 0051/1076] drivers: flash: stm32 xspi: Flash has explicit erase Select FLASH_HAS_EXPLICIT_ERASE for STM32 XSPI driver. Signed-off-by: Erwan Gouriou --- drivers/flash/Kconfig.stm32_xspi | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/flash/Kconfig.stm32_xspi b/drivers/flash/Kconfig.stm32_xspi index 53a3f381af548..3374fec6c604d 100644 --- a/drivers/flash/Kconfig.stm32_xspi +++ b/drivers/flash/Kconfig.stm32_xspi @@ -15,6 +15,7 @@ config FLASH_STM32_XSPI select FLASH_JESD216 select FLASH_PAGE_LAYOUT select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select PINCTRL select DMA if $(DT_STM32_XSPI_HAS_DMA) select USE_STM32_HAL_DMA if $(DT_STM32_XSPI_HAS_DMA) From b49fa46d9dec33ebfb364090089324f0e151ec0c Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 21 Aug 2025 16:46:24 +0200 Subject: [PATCH 0052/1076] drivers: flash: stm32 o/xspi: Implement get_size() This api was missing from these driver. Add it. Signed-off-by: Erwan Gouriou --- drivers/flash/flash_stm32_ospi.c | 10 ++++++++++ drivers/flash/flash_stm32_xspi.c | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 7c0eee1234ad4..8f0f5f69e992e 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -1702,11 +1702,21 @@ static void flash_stm32_ospi_pages_layout(const struct device *dev, } #endif +static int flash_stm32_ospi_get_size(const struct device *dev, uint64_t *size) +{ + const struct flash_stm32_ospi_config *dev_cfg = dev->config; + + *size = (uint64_t)dev_cfg->flash_size; + + return 0; +} + static DEVICE_API(flash, flash_stm32_ospi_driver_api) = { .read = flash_stm32_ospi_read, .write = flash_stm32_ospi_write, .erase = flash_stm32_ospi_erase, .get_parameters = flash_stm32_ospi_get_parameters, + .get_size = flash_stm32_ospi_get_size, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_stm32_ospi_pages_layout, #endif diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index 6ff3262598502..6e9176640522b 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -1563,11 +1563,21 @@ static void flash_stm32_xspi_pages_layout(const struct device *dev, } #endif +static int flash_stm32_xspi_get_size(const struct device *dev, uint64_t *size) +{ + const struct flash_stm32_xspi_config *dev_cfg = dev->config; + + *size = (uint64_t)dev_cfg->flash_size; + + return 0; +} + static DEVICE_API(flash, flash_stm32_xspi_driver_api) = { .read = flash_stm32_xspi_read, .write = flash_stm32_xspi_write, .erase = flash_stm32_xspi_erase, .get_parameters = flash_stm32_xspi_get_parameters, + .get_size = flash_stm32_xspi_get_size, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_stm32_xspi_pages_layout, #endif From 4cd7d139fad2fc7fa20a8d1e181ec368326703bc Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 21 Aug 2025 16:49:10 +0200 Subject: [PATCH 0053/1076] tests: flash: Enable test on stm32n6570_dk Since no internal flash is available, provide the right configuration so the test can run on external flash for stm32n6570_dk. Signed-off-by: Erwan Gouriou --- tests/drivers/flash/common/Kconfig | 3 ++- .../flash/common/boards/stm32n6570_dk_stm32n657xx_sb.conf | 1 + tests/drivers/flash/common/src/main.c | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/flash/common/boards/stm32n6570_dk_stm32n657xx_sb.conf diff --git a/tests/drivers/flash/common/Kconfig b/tests/drivers/flash/common/Kconfig index 4cf79fc6d8b9a..eedc88c8e1bb8 100644 --- a/tests/drivers/flash/common/Kconfig +++ b/tests/drivers/flash/common/Kconfig @@ -8,7 +8,8 @@ DT_CHOSEN_Z_FLASH := zephyr,flash config TEST_DRIVER_FLASH_SIZE int "Size of flash device under test" - default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0) if SOC_FAMILY_STM32 + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0) \ + if (SOC_FAMILY_STM32 && !SOC_SERIES_STM32N6X) default -1 help Expected flash device size the test will validate against. If the flash driver does not diff --git a/tests/drivers/flash/common/boards/stm32n6570_dk_stm32n657xx_sb.conf b/tests/drivers/flash/common/boards/stm32n6570_dk_stm32n657xx_sb.conf new file mode 100644 index 0000000000000..be1ee4e81cbb4 --- /dev/null +++ b/tests/drivers/flash/common/boards/stm32n6570_dk_stm32n657xx_sb.conf @@ -0,0 +1 @@ +CONFIG_TEST_DRIVER_FLASH_SIZE=134217728 diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index ab0e63bb60924..ceaea76038c22 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -12,6 +12,8 @@ #if defined(CONFIG_NORDIC_QSPI_NOR) #define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor) +#elif defined(SOC_SERIES_STM32N6X) +#define TEST_AREA_DEV_NODE DT_INST(0, st_stm32_xspi_nor) #elif defined(CONFIG_FLASH_RENESAS_RA_OSPI_B) #define TEST_AREA_DEV_NODE DT_INST(0, renesas_ra_ospi_b_nor) #elif defined(CONFIG_SPI_NOR) @@ -26,6 +28,7 @@ * fixed-partition nodes. */ #ifdef TEST_AREA + #define TEST_AREA_OFFSET FIXED_PARTITION_OFFSET(TEST_AREA) #define TEST_AREA_SIZE FIXED_PARTITION_SIZE(TEST_AREA) #define TEST_AREA_MAX (TEST_AREA_OFFSET + TEST_AREA_SIZE) From 23e0d30a39c7d6bbbe9958f933a6824af0579e6c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 11 Jul 2025 11:22:30 +0200 Subject: [PATCH 0054/1076] Bluetooth: ISO: Expand defines and their text Add a few missing defines for limits used in ISO. Add missing units and provide the value in both hex and decimal (with units) for easier-to-read support. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/iso.h | 83 +++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index 5edebcab087ee..a414c4e678545 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -75,21 +75,21 @@ extern "C" { #define BT_ISO_DATA_PATH_VS_ID_MIN 0x01 /** The maximum value for vendor specific data path ID */ #define BT_ISO_DATA_PATH_VS_ID_MAX 0xFE -/** Minimum controller delay in microseconds (0 s) */ +/** Minimum controller delay in microseconds (0 us) */ #define BT_ISO_CONTROLLER_DELAY_MIN 0x000000 -/** Maximum controller delay in microseconds (4 s) */ +/** Maximum controller delay in microseconds (4,000,000 us) */ #define BT_ISO_CONTROLLER_DELAY_MAX 0x3D0900 -/** Minimum interval value in microseconds */ +/** Minimum interval value in microseconds (255 us) */ #define BT_ISO_SDU_INTERVAL_MIN 0x0000FFU -/** Maximum interval value in microseconds */ +/** Maximum interval value in microseconds (1,048,575 us) */ #define BT_ISO_SDU_INTERVAL_MAX 0x0FFFFFU -/** Minimum ISO interval (N * 1.25 ms) */ +/** Minimum ISO interval in units of 1.25 ms (5 ms) */ #define BT_ISO_ISO_INTERVAL_MIN 0x0004U -/** Maximum ISO interval (N * 1.25 ms) */ +/** Maximum ISO interval in units of 1.25 ms (4,000 ms) */ #define BT_ISO_ISO_INTERVAL_MAX 0x0C80U -/** Minimum latency value in milliseconds */ +/** Minimum latency value in milliseconds (5 ms) */ #define BT_ISO_LATENCY_MIN 0x0005 -/** Maximum latency value in milliseconds */ +/** Maximum latency value in milliseconds (4,000 ms)*/ #define BT_ISO_LATENCY_MAX 0x0FA0 /** Packets will be sent sequentially between the channels in the group */ #define BT_ISO_PACKING_SEQUENTIAL 0x00 @@ -99,62 +99,73 @@ extern "C" { #define BT_ISO_FRAMING_UNFRAMED 0x00 /** Packets are always framed */ #define BT_ISO_FRAMING_FRAMED 0x01 -/** Maximum number of isochronous channels in a single group */ +/** Maximum number of isochronous channels in a single group (31) */ #define BT_ISO_MAX_GROUP_ISO_COUNT 0x1F -/** Minimum SDU size */ +/** Minimum SDU size (1 octet) */ #define BT_ISO_MIN_SDU 0x0001 -/** Maximum SDU size */ +/** Maximum SDU size (4095 octets) */ #define BT_ISO_MAX_SDU 0x0FFF -/** Minimum PDU size */ +/** Minimum PDU size (0 octet) */ #define BT_ISO_CONNECTED_PDU_MIN 0x0000U -/** Minimum PDU size */ +/** Minimum PDU size (1 octet) */ #define BT_ISO_BROADCAST_PDU_MIN 0x0001U -/** Maximum PDU size */ +/** Maximum PDU size (251 octets) */ #define BT_ISO_PDU_MAX 0x00FBU -/** Minimum burst number */ +/** Minimum burst number (1) */ #define BT_ISO_BN_MIN 0x01U -/** Maximum burst number */ +/** Maximum burst number (15) */ #define BT_ISO_BN_MAX 0x0FU -/** Minimum flush timeout */ +/** Minimum flush timeout in multiples of ISO interval (1) */ #define BT_ISO_FT_MIN 0x01U -/** Maximum flush timeout */ +/** Maximum flush timeout in multiples of ISO interval (255) */ #define BT_ISO_FT_MAX 0xFFU -/** Minimum number of subevents */ +/** Minimum number of subevents (1) */ #define BT_ISO_NSE_MIN 0x01U -/** Maximum number of subevents */ +/** Maximum number of subevents (31) */ #define BT_ISO_NSE_MAX 0x1FU -/** Minimum BIG sync timeout value (N * 10 ms) */ +/** Minimum BIG sync timeout value in units of 10 ms (100 ms) */ #define BT_ISO_SYNC_TIMEOUT_MIN 0x000A -/** Maximum BIG sync timeout value (N * 10 ms) */ +/** Maximum BIG sync timeout value in units of 10 ms (163,840 ms) */ #define BT_ISO_SYNC_TIMEOUT_MAX 0x4000 /** Controller controlled maximum subevent count value */ #define BT_ISO_SYNC_MSE_ANY 0x00 -/** Minimum BIG sync maximum subevent count value */ +/** Minimum BIG sync maximum subevent count value (1) */ #define BT_ISO_SYNC_MSE_MIN 0x01 -/** Maximum BIG sync maximum subevent count value */ +/** Maximum BIG sync maximum subevent count value (31) */ #define BT_ISO_SYNC_MSE_MAX 0x1F -/** Maximum connected ISO retransmission value */ +/** Minimum connected ISO retransmission value (0) */ +#define BT_ISO_CONNECTED_RTN_MIN 0x00 +/** Maximum connected ISO retransmission value (255) */ #define BT_ISO_CONNECTED_RTN_MAX 0xFF -/** Maximum broadcast ISO retransmission value */ +/** Minimum broadcast ISO retransmission value (0) */ +#define BT_ISO_BROADCAST_RTN_MIN 0x00 +/** Maximum broadcast ISO retransmission value (30) */ #define BT_ISO_BROADCAST_RTN_MAX 0x1E -/** Broadcast code size */ -#define BT_ISO_BROADCAST_CODE_SIZE 16 -/** Lowest BIS index */ +/** Broadcast code size (16 octets) */ +#define BT_ISO_BROADCAST_CODE_SIZE 0x10 +/** Lowest BIS index (1) */ #define BT_ISO_BIS_INDEX_MIN 0x01 -/** Highest BIS index */ +/** Highest BIS index (31) */ #define BT_ISO_BIS_INDEX_MAX 0x1F -/** Minimum Immediate Repetition Count */ +/** Minimum Immediate Repetition Count (1) */ #define BT_ISO_IRC_MIN 0x01U -/** Maximum Immediate Repetition Count */ +/** Maximum Immediate Repetition Count (15) */ #define BT_ISO_IRC_MAX 0x0FU -/** Minimum pre-transmission offset */ +/** Minimum pre-transmission offset (0) */ #define BT_ISO_PTO_MIN 0x00U -/** Maximum pre-transmission offset */ +/** Maximum pre-transmission offset (15) */ #define BT_ISO_PTO_MAX 0x0FU /** No subinterval */ -#define BT_ISO_SUBINTERVAL_NONE 0x00000000U +#define BT_ISO_SUBINTERVAL_NONE 0x00000000U /** Unknown subinterval */ -#define BT_ISO_SUBINTERVAL_UNKNOWN 0xFFFFFFFFU +#define BT_ISO_SUBINTERVAL_UNKNOWN 0xFFFFFFFFU +/** Minimum subinterval in microseconds (400 us) */ +#define BT_ISO_SUBINTERVAL_MIN 0x00000190U +/** @brief Maximum subinterval in microseconds (3,999,999 us) + * + * This maximum depends on the ISO interval, as the subinterval shall be less than the ISO interval + */ +#define BT_ISO_SUBINTERVAL_MAX 0x00009C3FU /** * @brief Check if ISO BIS bitfield is valid (BT_ISO_BIS_INDEX_BIT(1)|..|BT_ISO_BIS_INDEX_BIT(31)) From fe645cd346e9c41c1837fbf543c315193eef8091 Mon Sep 17 00:00:00 2001 From: Ioannis Damigos Date: Mon, 25 Aug 2025 10:16:43 +0300 Subject: [PATCH 0055/1076] dts/bindings/bluetooth: Use IPC instead of deprecated IPM Use IPC in bt-hci-bus property instead of deprecated IPM. Signed-off-by: Ioannis Damigos --- dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml | 2 +- dts/bindings/bluetooth/nxp,hci-ble.yaml | 2 +- dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml | 2 +- dts/bindings/bluetooth/st,hci-stm32wba.yaml | 2 +- dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml b/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml index 47c62eeaab40c..0311b50fb6d86 100644 --- a/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml +++ b/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml @@ -8,6 +8,6 @@ properties: bt-hci-name: default: "BT ESP32" bt-hci-bus: - default: "ipm" + default: "ipc" bt-hci-quirks: default: ["no-auto-dle"] diff --git a/dts/bindings/bluetooth/nxp,hci-ble.yaml b/dts/bindings/bluetooth/nxp,hci-ble.yaml index 529e238b6ba67..8782699bcec98 100644 --- a/dts/bindings/bluetooth/nxp,hci-ble.yaml +++ b/dts/bindings/bluetooth/nxp,hci-ble.yaml @@ -11,4 +11,4 @@ properties: bt-hci-name: default: "BT NXP" bt-hci-bus: - default: "ipm" + default: "ipc" diff --git a/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml b/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml index 088a1f58f7b79..a05f9f5806934 100644 --- a/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml +++ b/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml @@ -8,4 +8,4 @@ properties: bt-hci-name: default: "BT DA1469x" bt-hci-bus: - default: "ipm" + default: "ipc" diff --git a/dts/bindings/bluetooth/st,hci-stm32wba.yaml b/dts/bindings/bluetooth/st,hci-stm32wba.yaml index 6b4fcc036d032..392a0743888b6 100644 --- a/dts/bindings/bluetooth/st,hci-stm32wba.yaml +++ b/dts/bindings/bluetooth/st,hci-stm32wba.yaml @@ -8,4 +8,4 @@ properties: bt-hci-name: default: "BT IPM" bt-hci-bus: - default: "ipm" + default: "ipc" diff --git a/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml b/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml index 5fb67d9f0434f..187f9171e03bc 100644 --- a/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml +++ b/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml @@ -14,6 +14,6 @@ properties: bt-hci-name: default: "BT IPM" bt-hci-bus: - default: "ipm" + default: "ipc" bt-hci-quirks: default: ["no-reset"] From 4920a6d7b15d605b85beda14020c4b1cc688adf7 Mon Sep 17 00:00:00 2001 From: Ioannis Damigos Date: Thu, 21 Aug 2025 14:16:08 +0300 Subject: [PATCH 0056/1076] bluetooth: hci: Remove deprecated IPM HCI bus Remove deprecated IPM HCI bus. Signed-off-by: Ioannis Damigos --- dts/bindings/bluetooth/bt-hci.yaml | 1 - include/zephyr/drivers/bluetooth.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/dts/bindings/bluetooth/bt-hci.yaml b/dts/bindings/bluetooth/bt-hci.yaml index 52d3f82e4ef42..e4869bd4a5d54 100644 --- a/dts/bindings/bluetooth/bt-hci.yaml +++ b/dts/bindings/bluetooth/bt-hci.yaml @@ -21,7 +21,6 @@ properties: - "i2c" - "smd" - "virtio" - - "ipm" # Deprecated. "ipc" should be used instead. - "ipc" bt-hci-quirks: type: string-array diff --git a/include/zephyr/drivers/bluetooth.h b/include/zephyr/drivers/bluetooth.h index 7e3a72be1fb90..b63c3ef6ae72a 100644 --- a/include/zephyr/drivers/bluetooth.h +++ b/include/zephyr/drivers/bluetooth.h @@ -72,8 +72,6 @@ enum bt_hci_bus { BT_HCI_BUS_SMD = 9, BT_HCI_BUS_VIRTIO = 10, BT_HCI_BUS_IPC = 11, - /* IPM is deprecated and simply an alias for IPC */ - BT_HCI_BUS_IPM = BT_HCI_BUS_IPC, }; #define BT_DT_HCI_QUIRK_OR(node_id, prop, idx) \ From 70c70fda243ebb7ad88c7508de78b93bda6581c0 Mon Sep 17 00:00:00 2001 From: Ioannis Damigos Date: Mon, 25 Aug 2025 10:51:07 +0300 Subject: [PATCH 0057/1076] doc/releases: Update migration guide regarding IPM HCI bus removal Update migration guide regarding IPM HCI bus removal. Signed-off-by: Ioannis Damigos --- doc/releases/migration-guide-4.3.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index b6fb69c1f08f4..f4a2b8e383136 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -95,6 +95,12 @@ Bluetooth Audio .. zephyr-keep-sorted-stop +Bluetooth HCI +============= + +* The deprecated ``ipm`` value was removed from ``bt-hci-bus`` devicetree property. + ``ipc`` should be used instead. + Ethernet ======== From 92d092f7153cc37275bb3880bd4e165ba3ee0d9a Mon Sep 17 00:00:00 2001 From: Ioannis Damigos Date: Thu, 21 Aug 2025 14:21:10 +0300 Subject: [PATCH 0058/1076] include: drivers: bluetooth: Use DT_ENUM_IDX_OR to get HCI bus from DT Use DT_ENUM_IDX_OR instead of DT_STRING_UPPER_TOKEN_OR to get HCI bus from DT, in order to avoid the expansion of UART/SPI/etc. macros when they exist in vendor's SoC headers. Fixes #93675 Signed-off-by: Ioannis Damigos fix --- include/zephyr/drivers/bluetooth.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/drivers/bluetooth.h b/include/zephyr/drivers/bluetooth.h index b63c3ef6ae72a..cea94d2da144f 100644 --- a/include/zephyr/drivers/bluetooth.h +++ b/include/zephyr/drivers/bluetooth.h @@ -87,8 +87,8 @@ enum bt_hci_bus { #define BT_DT_HCI_NAME_GET(node_id) DT_PROP_OR(node_id, bt_hci_name, "HCI") #define BT_DT_HCI_NAME_INST_GET(inst) BT_DT_HCI_NAME_GET(DT_DRV_INST(inst)) -#define BT_DT_HCI_BUS_GET(node_id) \ - UTIL_CAT(BT_HCI_BUS_, DT_STRING_UPPER_TOKEN_OR(node_id, bt_hci_bus, VIRTUAL)) +#define BT_DT_HCI_BUS_GET(node_id) DT_ENUM_IDX_OR(node_id, bt_hci_bus, BT_HCI_BUS_VIRTUAL) + #define BT_DT_HCI_BUS_INST_GET(inst) BT_DT_HCI_BUS_GET(DT_DRV_INST(inst)) typedef int (*bt_hci_recv_t)(const struct device *dev, struct net_buf *buf); From dcb472926ce6ba9af1557b2599806e419d08ae73 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 21 Aug 2025 17:43:27 -0500 Subject: [PATCH 0059/1076] include: zephyr: move disks directory to disk Move disks directory to disk to match with the naming of the driver class. This only affects the recently introduced header for STM32 disk drivers so it should be very low impact. Signed-off-by: Daniel DeGrasse --- drivers/disk/sdmmc_stm32.c | 2 +- include/zephyr/drivers/{disks => disk}/sdmmc_stm32.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename include/zephyr/drivers/{disks => disk}/sdmmc_stm32.h (85%) diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index 39304de569ac1..9ec59416a63d0 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/zephyr/drivers/disks/sdmmc_stm32.h b/include/zephyr/drivers/disk/sdmmc_stm32.h similarity index 85% rename from include/zephyr/drivers/disks/sdmmc_stm32.h rename to include/zephyr/drivers/disk/sdmmc_stm32.h index 6a76a693fb03a..ed132903d605a 100644 --- a/include/zephyr/drivers/disks/sdmmc_stm32.h +++ b/include/zephyr/drivers/disk/sdmmc_stm32.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_DRIVERS_DISKS_SDMMC_STM32_H_ -#define ZEPHYR_INCLUDE_DRIVERS_DISKS_SDMMC_STM32_H_ +#ifndef ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ +#define ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ #include #include @@ -28,4 +28,4 @@ */ void stm32_sdmmc_get_card_cid(const struct device *dev, uint32_t cid[4]); -#endif /* ZEPHYR_INCLUDE_DRIVERS_DISKS_SDMMC_STM32_H_ */ +#endif /* ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ */ From 489ea9df3111199bde35624d907bdbb6c13f59a6 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Aug 2025 14:16:42 +0200 Subject: [PATCH 0060/1076] samples: usb: legacy: disable next device stack explicitly Disable the new device stack explicitly to avoid build issues in CI. Signed-off-by: Johann Fischer --- samples/subsys/usb/legacy/audio_headphones_microphone/prj.conf | 1 + samples/subsys/usb/legacy/audio_headset/prj.conf | 1 + samples/subsys/usb/legacy/cdc_acm/prj.conf | 1 + samples/subsys/usb/legacy/console/prj.conf | 1 + samples/subsys/usb/legacy/dfu/prj.conf | 1 + samples/subsys/usb/legacy/hci_usb/prj.conf | 1 + samples/subsys/usb/legacy/hid-mouse/prj.conf | 1 + samples/subsys/usb/legacy/mass/prj.conf | 1 + samples/subsys/usb/legacy/netusb/prj.conf | 1 + samples/subsys/usb/legacy/webusb/prj.conf | 1 + 10 files changed, 10 insertions(+) diff --git a/samples/subsys/usb/legacy/audio_headphones_microphone/prj.conf b/samples/subsys/usb/legacy/audio_headphones_microphone/prj.conf index a532f9cb731f2..b8ac1e218f9e6 100644 --- a/samples/subsys/usb/legacy/audio_headphones_microphone/prj.conf +++ b/samples/subsys/usb/legacy/audio_headphones_microphone/prj.conf @@ -5,6 +5,7 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_DEPRECATION_TEST=y CONFIG_USB_DEVICE_PRODUCT="Zephyr USB audio sample" CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n #LOG subsystem related configs CONFIG_LOG=y diff --git a/samples/subsys/usb/legacy/audio_headset/prj.conf b/samples/subsys/usb/legacy/audio_headset/prj.conf index a532f9cb731f2..b8ac1e218f9e6 100644 --- a/samples/subsys/usb/legacy/audio_headset/prj.conf +++ b/samples/subsys/usb/legacy/audio_headset/prj.conf @@ -5,6 +5,7 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_DEPRECATION_TEST=y CONFIG_USB_DEVICE_PRODUCT="Zephyr USB audio sample" CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n #LOG subsystem related configs CONFIG_LOG=y diff --git a/samples/subsys/usb/legacy/cdc_acm/prj.conf b/samples/subsys/usb/legacy/cdc_acm/prj.conf index 1bc7989fb2865..3673d1e2b3616 100644 --- a/samples/subsys/usb/legacy/cdc_acm/prj.conf +++ b/samples/subsys/usb/legacy/cdc_acm/prj.conf @@ -10,3 +10,4 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_LINE_CTRL=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n diff --git a/samples/subsys/usb/legacy/console/prj.conf b/samples/subsys/usb/legacy/console/prj.conf index 485142c696bca..796f062848ed3 100644 --- a/samples/subsys/usb/legacy/console/prj.conf +++ b/samples/subsys/usb/legacy/console/prj.conf @@ -3,6 +3,7 @@ CONFIG_DEPRECATION_TEST=y CONFIG_USB_DEVICE_PRODUCT="Zephyr USB console sample" CONFIG_USB_DEVICE_PID=0x0004 CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n CONFIG_SERIAL=y CONFIG_CONSOLE=y diff --git a/samples/subsys/usb/legacy/dfu/prj.conf b/samples/subsys/usb/legacy/dfu/prj.conf index 34eb8ff8b1c26..9a9820e129614 100644 --- a/samples/subsys/usb/legacy/dfu/prj.conf +++ b/samples/subsys/usb/legacy/dfu/prj.conf @@ -15,3 +15,4 @@ CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n diff --git a/samples/subsys/usb/legacy/hci_usb/prj.conf b/samples/subsys/usb/legacy/hci_usb/prj.conf index 9268d21c5ef1f..9e484982cab35 100644 --- a/samples/subsys/usb/legacy/hci_usb/prj.conf +++ b/samples/subsys/usb/legacy/hci_usb/prj.conf @@ -6,6 +6,7 @@ CONFIG_DEPRECATION_TEST=y CONFIG_USB_DEVICE_PID=0x000B CONFIG_USB_DEVICE_BLUETOOTH=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n # We dont want any console or CDC ACM that may cause BlueZ to not detect hci_usb CONFIG_SERIAL=n diff --git a/samples/subsys/usb/legacy/hid-mouse/prj.conf b/samples/subsys/usb/legacy/hid-mouse/prj.conf index 068701a0a3530..e43ef0d6b8b26 100644 --- a/samples/subsys/usb/legacy/hid-mouse/prj.conf +++ b/samples/subsys/usb/legacy/hid-mouse/prj.conf @@ -4,6 +4,7 @@ CONFIG_USB_DEVICE_HID=y CONFIG_USB_DEVICE_PRODUCT="Zephyr HID mouse sample" CONFIG_USB_DEVICE_PID=0x0007 CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n CONFIG_LOG=y CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y diff --git a/samples/subsys/usb/legacy/mass/prj.conf b/samples/subsys/usb/legacy/mass/prj.conf index ddb8934c8dacd..134a003355fe9 100644 --- a/samples/subsys/usb/legacy/mass/prj.conf +++ b/samples/subsys/usb/legacy/mass/prj.conf @@ -11,5 +11,6 @@ CONFIG_USB_MASS_STORAGE=y CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n CONFIG_MAIN_STACK_SIZE=1536 diff --git a/samples/subsys/usb/legacy/netusb/prj.conf b/samples/subsys/usb/legacy/netusb/prj.conf index dd6dfb9ca231e..239322da2fac7 100644 --- a/samples/subsys/usb/legacy/netusb/prj.conf +++ b/samples/subsys/usb/legacy/netusb/prj.conf @@ -32,3 +32,4 @@ CONFIG_USB_DEVICE_STACK=y CONFIG_DEPRECATION_TEST=y CONFIG_USB_DEVICE_NETWORK_ECM=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n diff --git a/samples/subsys/usb/legacy/webusb/prj.conf b/samples/subsys/usb/legacy/webusb/prj.conf index 93aab862650f7..03fc4cbca43b7 100644 --- a/samples/subsys/usb/legacy/webusb/prj.conf +++ b/samples/subsys/usb/legacy/webusb/prj.conf @@ -8,6 +8,7 @@ CONFIG_USB_DEVICE_PID=0x000A CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_LINE_CTRL=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n +CONFIG_USB_DEVICE_STACK_NEXT=n CONFIG_LOG=y CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y From ec9488ceaac3ade5e11091d8cfdec2ffaba898c0 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Aug 2025 15:21:32 +0200 Subject: [PATCH 0061/1076] samples: usb: explicitly disable initialization at boot To avoid conflicts with boards using the CDC ACM serial backend, explicitly disable initialization at boot. Similar to commit 11c7371f99ba ("samples: Explicitly disable boot USB device support init at boot") addressing it for the legacy device stack. Signed-off-by: Johann Fischer --- samples/bluetooth/hci_usb/prj.conf | 1 + samples/net/sockets/echo_server/overlay-usbd.conf | 1 + samples/net/sockets/http_server/overlay-usbd.conf | 1 + samples/net/zperf/overlay-usbd.conf | 1 + samples/subsys/dap/prj.conf | 1 + samples/subsys/tracing/prj_usb_ctf.conf | 1 + samples/subsys/usb/cdc_acm/prj.conf | 1 + samples/subsys/usb/cdc_acm_bridge/prj.conf | 1 + samples/subsys/usb/dfu/prj.conf | 1 + samples/subsys/usb/hid-keyboard/prj.conf | 1 + samples/subsys/usb/hid-mouse/prj.conf | 1 + samples/subsys/usb/mass/prj.conf | 1 + samples/subsys/usb/midi/prj.conf | 1 + samples/subsys/usb/shell/prj.conf | 1 + samples/subsys/usb/testusb/prj.conf | 1 + samples/subsys/usb/uac2_explicit_feedback/prj.conf | 1 + samples/subsys/usb/uac2_implicit_feedback/prj.conf | 1 + samples/subsys/usb/uvc/prj.conf | 1 + samples/subsys/usb/webusb/prj.conf | 1 + 19 files changed, 19 insertions(+) diff --git a/samples/bluetooth/hci_usb/prj.conf b/samples/bluetooth/hci_usb/prj.conf index f3ee01fd7e4cf..0415cb8f63d48 100644 --- a/samples/bluetooth/hci_usb/prj.conf +++ b/samples/bluetooth/hci_usb/prj.conf @@ -5,6 +5,7 @@ CONFIG_CONSOLE=n CONFIG_UART_CONSOLE=n CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_SAMPLE_USBD_PID=0x000B CONFIG_SAMPLE_USBD_PRODUCT="Zephyr USBD BT HCI" CONFIG_USBD_BT_HCI=y diff --git a/samples/net/sockets/echo_server/overlay-usbd.conf b/samples/net/sockets/echo_server/overlay-usbd.conf index 8f04cb281865a..9d72348c96b10 100644 --- a/samples/net/sockets/echo_server/overlay-usbd.conf +++ b/samples/net/sockets/echo_server/overlay-usbd.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_WRN=y diff --git a/samples/net/sockets/http_server/overlay-usbd.conf b/samples/net/sockets/http_server/overlay-usbd.conf index 20abbfb4fc2cf..c5f6f044fe84c 100644 --- a/samples/net/sockets/http_server/overlay-usbd.conf +++ b/samples/net/sockets/http_server/overlay-usbd.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_WRN=y diff --git a/samples/net/zperf/overlay-usbd.conf b/samples/net/zperf/overlay-usbd.conf index 6451b7e0566ec..cb305ed53a20a 100644 --- a/samples/net/zperf/overlay-usbd.conf +++ b/samples/net/zperf/overlay-usbd.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_WRN=y diff --git a/samples/subsys/dap/prj.conf b/samples/subsys/dap/prj.conf index 062bec175698d..23cdef69a6a3a 100644 --- a/samples/subsys/dap/prj.conf +++ b/samples/subsys/dap/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_SAMPLE_USBD_PRODUCT="Zephyr CMSIS-DAP" CONFIG_SAMPLE_USBD_PID=0x0204 CONFIG_SAMPLE_USBD_20_EXTENSION_DESC=y diff --git a/samples/subsys/tracing/prj_usb_ctf.conf b/samples/subsys/tracing/prj_usb_ctf.conf index d1de19087b241..d2141aad2f6f2 100644 --- a/samples/subsys/tracing/prj_usb_ctf.conf +++ b/samples/subsys/tracing/prj_usb_ctf.conf @@ -1,5 +1,6 @@ CONFIG_GPIO=y CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_TRACING=y CONFIG_TRACING_CTF=y diff --git a/samples/subsys/usb/cdc_acm/prj.conf b/samples/subsys/usb/cdc_acm/prj.conf index e0012027ec6aa..6efc9dbd04e64 100644 --- a/samples/subsys/usb/cdc_acm/prj.conf +++ b/samples/subsys/usb/cdc_acm/prj.conf @@ -4,6 +4,7 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_LINE_CTRL=y CONFIG_USBD_CDC_ACM_CLASS=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_ERR=y diff --git a/samples/subsys/usb/cdc_acm_bridge/prj.conf b/samples/subsys/usb/cdc_acm_bridge/prj.conf index e9aa6fc7d2a92..9142082353f2e 100644 --- a/samples/subsys/usb/cdc_acm_bridge/prj.conf +++ b/samples/subsys/usb/cdc_acm_bridge/prj.conf @@ -6,6 +6,7 @@ CONFIG_SERIAL=y CONFIG_UART_LINE_CTRL=y CONFIG_UART_USE_RUNTIME_CONFIGURE=y CONFIG_USBD_CDC_ACM_CLASS=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_SAMPLE_USBD_PID=0x0001 CONFIG_SAMPLE_USBD_PRODUCT="USBD CDC ACM bridge sample" diff --git a/samples/subsys/usb/dfu/prj.conf b/samples/subsys/usb/dfu/prj.conf index 4ac6e6dd8d2ee..2a32656bc41d0 100644 --- a/samples/subsys/usb/dfu/prj.conf +++ b/samples/subsys/usb/dfu/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_DFU=y CONFIG_LOG=y diff --git a/samples/subsys/usb/hid-keyboard/prj.conf b/samples/subsys/usb/hid-keyboard/prj.conf index a854a502f0683..253afb370a449 100644 --- a/samples/subsys/usb/hid-keyboard/prj.conf +++ b/samples/subsys/usb/hid-keyboard/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_HID_SUPPORT=y CONFIG_LOG=y diff --git a/samples/subsys/usb/hid-mouse/prj.conf b/samples/subsys/usb/hid-mouse/prj.conf index 9c8894b2126c6..396728521b9b1 100644 --- a/samples/subsys/usb/hid-mouse/prj.conf +++ b/samples/subsys/usb/hid-mouse/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_HID_SUPPORT=y CONFIG_LOG=y diff --git a/samples/subsys/usb/mass/prj.conf b/samples/subsys/usb/mass/prj.conf index dd9d784070de5..5ff15b40f6c20 100644 --- a/samples/subsys/usb/mass/prj.conf +++ b/samples/subsys/usb/mass/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_STDOUT_CONSOLE=y CONFIG_SERIAL=y diff --git a/samples/subsys/usb/midi/prj.conf b/samples/subsys/usb/midi/prj.conf index fdc77affb2302..02e2d52c7edd3 100644 --- a/samples/subsys/usb/midi/prj.conf +++ b/samples/subsys/usb/midi/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_MIDI2_CLASS=y CONFIG_SAMPLE_USBD_PRODUCT="USBD MIDI Sample" diff --git a/samples/subsys/usb/shell/prj.conf b/samples/subsys/usb/shell/prj.conf index 03d6eb8f1bbec..905c6bff9fe95 100644 --- a/samples/subsys/usb/shell/prj.conf +++ b/samples/subsys/usb/shell/prj.conf @@ -1,5 +1,6 @@ CONFIG_SHELL=y CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_SHELL=y CONFIG_USBD_LOOPBACK_CLASS=y CONFIG_UDC_BUF_POOL_SIZE=4096 diff --git a/samples/subsys/usb/testusb/prj.conf b/samples/subsys/usb/testusb/prj.conf index fcbf19c62e8d8..252faabe900db 100644 --- a/samples/subsys/usb/testusb/prj.conf +++ b/samples/subsys/usb/testusb/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_LOOPBACK_CLASS=y CONFIG_UDC_BUF_POOL_SIZE=4096 diff --git a/samples/subsys/usb/uac2_explicit_feedback/prj.conf b/samples/subsys/usb/uac2_explicit_feedback/prj.conf index 3979a5190e6c1..a0426650c030c 100644 --- a/samples/subsys/usb/uac2_explicit_feedback/prj.conf +++ b/samples/subsys/usb/uac2_explicit_feedback/prj.conf @@ -2,6 +2,7 @@ CONFIG_I2S=y #USB related configs CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_AUDIO2_CLASS=y CONFIG_SAMPLE_USBD_PID=0x000E CONFIG_SAMPLE_USBD_PRODUCT="UAC2 explicit feedback sample" diff --git a/samples/subsys/usb/uac2_implicit_feedback/prj.conf b/samples/subsys/usb/uac2_implicit_feedback/prj.conf index 61d654a3b3ad2..110ae08914007 100644 --- a/samples/subsys/usb/uac2_implicit_feedback/prj.conf +++ b/samples/subsys/usb/uac2_implicit_feedback/prj.conf @@ -2,6 +2,7 @@ CONFIG_I2S=y #USB related configs CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_USBD_AUDIO2_CLASS=y CONFIG_SAMPLE_USBD_PID=0x000F CONFIG_SAMPLE_USBD_PRODUCT="UAC2 implicit feedback sample" diff --git a/samples/subsys/usb/uvc/prj.conf b/samples/subsys/usb/uvc/prj.conf index e6da900d7d1c9..96fcda5182b77 100644 --- a/samples/subsys/usb/uvc/prj.conf +++ b/samples/subsys/usb/uvc/prj.conf @@ -8,6 +8,7 @@ CONFIG_USBD_LOG_LEVEL_WRN=y CONFIG_USBD_VIDEO_CLASS=y CONFIG_USBD_VIDEO_LOG_LEVEL_WRN=y CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_VIDEO=y CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=2 CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=24576 diff --git a/samples/subsys/usb/webusb/prj.conf b/samples/subsys/usb/webusb/prj.conf index 1c730a0ec56a3..d2b65dc7fae7d 100644 --- a/samples/subsys/usb/webusb/prj.conf +++ b/samples/subsys/usb/webusb/prj.conf @@ -1,4 +1,5 @@ CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_WRN=y From 8b065f91835fae183620db06a0f55c03d7df4283 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Aug 2025 17:02:19 +0200 Subject: [PATCH 0062/1076] samples: cdc_acm: set CDC ACM log level to OFF When building for the board with a serial backend, a warning will appear regarding the log level of the CDC ACM implementation. Set it to "OFF" to avoid CI failures. Signed-off-by: Johann Fischer --- samples/subsys/usb/cdc_acm/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/usb/cdc_acm/prj.conf b/samples/subsys/usb/cdc_acm/prj.conf index 6efc9dbd04e64..9a52c07728a32 100644 --- a/samples/subsys/usb/cdc_acm/prj.conf +++ b/samples/subsys/usb/cdc_acm/prj.conf @@ -9,7 +9,7 @@ CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_ERR=y CONFIG_UDC_DRIVER_LOG_LEVEL_ERR=y -CONFIG_USBD_CDC_ACM_LOG_LEVEL_ERR=y +CONFIG_USBD_CDC_ACM_LOG_LEVEL_OFF=y CONFIG_SAMPLE_USBD_PID=0x0001 CONFIG_SAMPLE_USBD_PRODUCT="USBD CDC ACM sample" From 6f57a7a3f3c9fb7efa2d71d5d2091f83b8e91292 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Aug 2025 17:05:56 +0200 Subject: [PATCH 0063/1076] boards: replace test feature usb_device with usbd for some boards Replace test feature usb_device with usbd for boards that use the CDC ACM serial backend. Otherwise, Twister could use these boards with deprecated legacy samples, but the build would fail due to warnings about the CDC ACM log level. Signed-off-by: Johann Fischer --- boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml | 2 +- .../adafruit_feather_nrf52840_nrf52840_sense.yaml | 2 +- .../adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml | 2 +- .../adafruit_feather_nrf52840_nrf52840_uf2.yaml | 2 +- boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml | 2 +- .../portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.yaml | 2 +- .../portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml | 2 +- boards/atmarktechno/degu_evk/degu_evk.yaml | 2 +- boards/ct/ctcc/ctcc_nrf52840.yaml | 2 +- boards/ezurio/bl654_usb/bl654_usb.yaml | 2 +- boards/ezurio/bl654_usb/bl654_usb_nrf52840_bare.yaml | 2 +- .../nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml | 2 +- boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml | 2 +- boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml | 2 +- boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840_bare.yaml | 2 +- boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml | 2 +- boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml | 2 +- boards/others/promicro_nrf52840/promicro_nrf52840.yaml | 2 +- .../promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml | 2 +- .../raytac_mdbt50q_cx_40_dongle_nrf52840.yaml | 2 +- boards/seeed/wio_terminal/wio_terminal.yaml | 2 +- boards/seeed/xiao_ble/xiao_ble.yaml | 2 +- boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml index 31369a0280cf1..2f9551d9ae007 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml @@ -7,7 +7,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - watchdog - counter diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml index 236e5aafd0732..b1e358d8ce6d9 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml @@ -7,7 +7,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - watchdog - counter diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml index 3756dc3c2a44e..8033b1a7c270a 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml @@ -7,7 +7,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - watchdog - counter diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml index c61e5ae36f93c..968b30bd6d4fd 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml @@ -7,7 +7,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - watchdog - counter diff --git a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml index 79072d2d015f1..f954fc16b41c5 100644 --- a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml +++ b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml @@ -15,6 +15,6 @@ supported: - i2c - pwm - spi - - usb_device + - usbd - watchdog vendor: adafruit diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.yaml index 7dc36b141900d..bd7d06eb249f1 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.yaml @@ -14,5 +14,5 @@ supported: - spi - qspi - memc - - usb_device + - usbd vendor: arduino diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml index 456ae5871e3b0..7a5d5bdf95577 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml @@ -15,5 +15,5 @@ supported: - qspi - memc - usb_cdc - - usb_device + - usbd vendor: arduino diff --git a/boards/atmarktechno/degu_evk/degu_evk.yaml b/boards/atmarktechno/degu_evk/degu_evk.yaml index 3fd220f4df26f..8d946e8ee5a85 100644 --- a/boards/atmarktechno/degu_evk/degu_evk.yaml +++ b/boards/atmarktechno/degu_evk/degu_evk.yaml @@ -7,5 +7,5 @@ toolchain: supported: - i2c - adc - - usb_device + - usbd vendor: atmarktechno diff --git a/boards/ct/ctcc/ctcc_nrf52840.yaml b/boards/ct/ctcc/ctcc_nrf52840.yaml index 332273c3a4257..6ca082d8d2765 100644 --- a/boards/ct/ctcc/ctcc_nrf52840.yaml +++ b/boards/ct/ctcc/ctcc_nrf52840.yaml @@ -8,7 +8,7 @@ toolchain: supported: - ble - gpio - - usb_device + - usbd - watchdog - counter vendor: ct diff --git a/boards/ezurio/bl654_usb/bl654_usb.yaml b/boards/ezurio/bl654_usb/bl654_usb.yaml index 660ee57e4672a..4551f47dd61b2 100644 --- a/boards/ezurio/bl654_usb/bl654_usb.yaml +++ b/boards/ezurio/bl654_usb/bl654_usb.yaml @@ -8,7 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: - - usb_device + - usbd - ble - pwm - watchdog diff --git a/boards/ezurio/bl654_usb/bl654_usb_nrf52840_bare.yaml b/boards/ezurio/bl654_usb/bl654_usb_nrf52840_bare.yaml index 4d92d331a2fd6..e3bd3adcc9f64 100644 --- a/boards/ezurio/bl654_usb/bl654_usb_nrf52840_bare.yaml +++ b/boards/ezurio/bl654_usb/bl654_usb_nrf52840_bare.yaml @@ -8,7 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: - - usb_device + - usbd - ble - pwm - watchdog diff --git a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml index f0fa9668e557f..a261191604149 100644 --- a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml +++ b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml @@ -8,7 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: - - usb_device + - usbd - ble - watchdog - counter diff --git a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml index 361df15777756..7c2e100373059 100644 --- a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml +++ b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml @@ -12,5 +12,5 @@ supported: - gpio - i2c - spi - - usb_device + - usbd vendor: mikroe diff --git a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml index 7eb89aa894b48..d12aca5fc52f7 100644 --- a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml +++ b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - pwm - spi diff --git a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840_bare.yaml b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840_bare.yaml index 516cd385264e9..7ab56a99e46bd 100644 --- a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840_bare.yaml +++ b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840_bare.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - pwm - spi diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml index 568512216bdfb..ea3c467ee0dea 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml @@ -13,6 +13,6 @@ supported: - i2c - pwm - watchdog - - usb_device + - usbd - netif:openthread vendor: nordic diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml index e672b5080c4b0..8d1b8e4c677c9 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml @@ -12,7 +12,7 @@ supported: - i2c - pwm - watchdog - - usb_device + - usbd - netif:openthread vendor: nordic sysbuild: true diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840.yaml b/boards/others/promicro_nrf52840/promicro_nrf52840.yaml index 0f8ccd9b1a283..ef54516b38766 100644 --- a/boards/others/promicro_nrf52840/promicro_nrf52840.yaml +++ b/boards/others/promicro_nrf52840/promicro_nrf52840.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - pwm - spi diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml index 7aa472b784d35..f5228a763eda2 100644 --- a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb supported: - adc - - usb_device + - usbd - ble - pwm - spi diff --git a/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml b/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml index 90e1c1cde5107..e383fe5550ea2 100644 --- a/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml +++ b/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml @@ -12,7 +12,7 @@ toolchain: - zephyr - gnuarmemb supported: - - usb_device + - usbd - usb_cdc - ble - pwm diff --git a/boards/seeed/wio_terminal/wio_terminal.yaml b/boards/seeed/wio_terminal/wio_terminal.yaml index a5445ae3cd036..aa8118b0e6446 100644 --- a/boards/seeed/wio_terminal/wio_terminal.yaml +++ b/boards/seeed/wio_terminal/wio_terminal.yaml @@ -15,6 +15,6 @@ supported: - i2c - pwm - spi - - usb_device + - usbd - watchdog vendor: seeed diff --git a/boards/seeed/xiao_ble/xiao_ble.yaml b/boards/seeed/xiao_ble/xiao_ble.yaml index a6482108e38d7..fea7a4fa769f9 100644 --- a/boards/seeed/xiao_ble/xiao_ble.yaml +++ b/boards/seeed/xiao_ble/xiao_ble.yaml @@ -16,7 +16,7 @@ supported: - i2s - pwm - spi - - usb_device + - usbd - watchdog - netif:openthread - xiao_adc diff --git a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml index 9275e38f7f69f..7edb8000612df 100644 --- a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml +++ b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml @@ -16,7 +16,7 @@ supported: - i2s - pwm - spi - - usb_device + - usbd - watchdog - netif:openthread - xiao_adc From b318fb3fc3f4aae93c1c30989b2a51ca72a3df73 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 21 Aug 2025 17:56:07 +0200 Subject: [PATCH 0064/1076] boards: remove test feature usb_cdc The test feature USB_CDC is not required or used in any of the USB samples or tests, yet it mysteriously appears again and again for various boards. Follow-up on commit ef784cd3fd88 ("boards: remove test feature usb_cdc and usb") Signed-off-by: Johann Fischer --- .../portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml | 1 - .../raytac_mdbt50q_cx_40_dongle_nrf52840.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml index 7a5d5bdf95577..a5e81cd574ea4 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.yaml @@ -14,6 +14,5 @@ supported: - spi - qspi - memc - - usb_cdc - usbd vendor: arduino diff --git a/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml b/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml index e383fe5550ea2..d5ecd05ff73ee 100644 --- a/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml +++ b/boards/raytac/mdbt50q_cx_40_dongle/raytac_mdbt50q_cx_40_dongle_nrf52840.yaml @@ -13,7 +13,6 @@ toolchain: - gnuarmemb supported: - usbd - - usb_cdc - ble - pwm - watchdog From b10204b36dc5fe92dd2c998dce69866d8b06f900 Mon Sep 17 00:00:00 2001 From: Jannik Woernle Date: Tue, 29 Jul 2025 17:22:59 +0000 Subject: [PATCH 0065/1076] kernel: k_pipe: Fixed initializer order Changed order of Z_PIPE_INITIALIZER to match with k_pipe struct Signed-off-by: Jannik Woernle --- include/zephyr/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a6aa3dddf1182..858e0a952ba09 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5436,11 +5436,11 @@ struct k_pipe { */ #define Z_PIPE_INITIALIZER(obj, pipe_buffer, pipe_buffer_size) \ { \ + .waiting = 0, \ .buf = RING_BUF_INIT(pipe_buffer, pipe_buffer_size), \ .data = Z_WAIT_Q_INIT(&obj.data), \ .space = Z_WAIT_Q_INIT(&obj.space), \ .flags = PIPE_FLAG_OPEN, \ - .waiting = 0, \ Z_POLL_EVENT_OBJ_INIT(obj) \ } /** From 009114a60712a98625f14bc09d11f434a103ca97 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Thu, 21 Aug 2025 04:55:47 +0200 Subject: [PATCH 0066/1076] modules: hostap: flush all unused BSS entries before 11V roaming For 11V roaming, it attempts to use previously received scan results, if they are recent enough to be used for connection. If wifi driver does not keep the previous scan results, it will failed to find the bss entry. Fix: flush all unused BSS entries, for 11V roaming, don't try to use recent scan results. Signed-off-by: Gang Li --- modules/hostap/src/supp_api.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 5b40834d0b843..1a8e2b1c03b70 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -1908,6 +1908,11 @@ int supplicant_btm_query(const struct device *dev, uint8_t reason) goto out; } + /* Flush all unused BSS entries */ + if (!wpa_cli_cmd_v("bss_flush")) { + goto out; + } + if (!wpa_cli_cmd_v("wnm_bss_query %d", reason)) { goto out; } From 895ba04b32ec919f2d99cff6895678d3553b14da Mon Sep 17 00:00:00 2001 From: Make Shi Date: Tue, 17 Jun 2025 08:12:29 +0800 Subject: [PATCH 0067/1076] Bluetooth: AVCTP: Refactors the AVCTP to support multiple L2CAP PSMs - This patch refactors the AVCTP layer to support multiple L2CAP PSMs - Introduced bt_avctp_server structure for dynamic L2CAP server registration and new server register apis - Added k_sem protected server list to support multiple AVCTP servers Signed-off-by: Make Shi --- subsys/bluetooth/host/classic/avctp.c | 161 +++++++++--------- .../bluetooth/host/classic/avctp_internal.h | 57 ++++++- 2 files changed, 138 insertions(+), 80 deletions(-) diff --git a/subsys/bluetooth/host/classic/avctp.c b/subsys/bluetooth/host/classic/avctp.c index 939361552b577..eb5d9ce48b6cf 100644 --- a/subsys/bluetooth/host/classic/avctp.c +++ b/subsys/bluetooth/host/classic/avctp.c @@ -31,8 +31,9 @@ LOG_MODULE_REGISTER(bt_avctp); #define AVCTP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_avctp, br_chan.chan) - -static const struct bt_avctp_event_cb *event_cb; +/* L2CAP Server list */ +static sys_slist_t avctp_l2cap_server = SYS_SLIST_STATIC_INIT(&avctp_l2cap_server); +static struct k_sem avctp_server_lock; static void avctp_l2cap_connected(struct bt_l2cap_chan *chan) { @@ -80,7 +81,6 @@ static int avctp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) struct bt_avctp *session = AVCTP_CHAN(chan); struct bt_avctp_header *hdr = (void *)buf->data; uint8_t tid; - bt_avctp_pkt_type_t pkt_type; bt_avctp_cr_t cr; int err; @@ -90,46 +90,34 @@ static int avctp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) } tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(hdr); - pkt_type = BT_AVCTP_HDR_GET_PACKET_TYPE(hdr); cr = BT_AVCTP_HDR_GET_CR(hdr); - switch (pkt_type) { - case BT_AVCTP_PKT_TYPE_SINGLE: - break; - case BT_AVCTP_PKT_TYPE_START: - case BT_AVCTP_PKT_TYPE_CONTINUE: - case BT_AVCTP_PKT_TYPE_END: - default: - LOG_ERR("fragmented AVCTP message is not supported, pkt_type = %d", pkt_type); - return -EINVAL; + LOG_DBG("AVCTP msg received, cr:0x%X, tid:0x%X, pid: 0x%04X", + cr, tid, sys_be16_to_cpu(hdr->pid)); + + if (sys_be16_to_cpu(hdr->pid) == session->pid) { + return session->ops->recv(session, buf); } - switch (hdr->pid) { -#if defined(CONFIG_BT_AVRCP) - case sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS): - break; -#endif - default: - LOG_ERR("unsupported AVCTP PID received: 0x%04x", sys_be16_to_cpu(hdr->pid)); - if (cr == BT_AVCTP_CMD) { - rsp = bt_avctp_create_pdu(session, BT_AVCTP_RESPONSE, - BT_AVCTP_PKT_TYPE_SINGLE, BT_AVCTP_IPID_INVALID, - tid, hdr->pid); - if (!rsp) { - return -ENOMEM; - } - - err = bt_avctp_send(session, rsp); - if (err < 0) { - net_buf_unref(rsp); - LOG_ERR("AVCTP send fail, err = %d", err); - return err; - } + LOG_ERR("unsupported AVCTP PID received: 0x%04x", sys_be16_to_cpu(hdr->pid)); + if (cr == BT_AVCTP_CMD) { + rsp = bt_avctp_create_pdu(session, BT_AVCTP_RESPONSE, + BT_AVCTP_PKT_TYPE_SINGLE, BT_AVCTP_IPID_INVALID, + tid, hdr->pid); + if (rsp == NULL) { + __ASSERT(0, "Failed to create AVCTP response PDU"); + return -ENOMEM; } - return 0; /* No need to report to the upper layer */ - } - return session->ops->recv(session, buf); + err = bt_avctp_send(session, rsp); + if (err < 0) { + net_buf_unref(rsp); + LOG_ERR("AVCTP send fail, err = %d", err); + bt_avctp_disconnect(session); + return err; + } + } + return 0; /* No need to report to the upper layer */ } static const struct bt_l2cap_chan_ops ops = { @@ -139,17 +127,14 @@ static const struct bt_l2cap_chan_ops ops = { .recv = avctp_l2cap_recv, }; -int bt_avctp_connect(struct bt_conn *conn, struct bt_avctp *session) +int bt_avctp_connect(struct bt_conn *conn, uint16_t psm, struct bt_avctp *session) { if (!session) { return -EINVAL; } - session->br_chan.rx.mtu = BT_L2CAP_RX_MTU; session->br_chan.chan.ops = &ops; - session->br_chan.required_sec_level = BT_SECURITY_L2; - - return bt_l2cap_chan_connect(conn, &session->br_chan.chan, BT_L2CAP_PSM_AVCTP); + return bt_l2cap_chan_connect(conn, &session->br_chan.chan, psm); } int bt_avctp_disconnect(struct bt_avctp *session) @@ -163,6 +148,19 @@ int bt_avctp_disconnect(struct bt_avctp *session) return bt_l2cap_chan_disconnect(&session->br_chan.chan); } +void bt_avctp_set_header(struct bt_avctp_header *avctp_hdr, bt_avctp_cr_t cr, + bt_avctp_pkt_type_t pkt_type, bt_avctp_ipid_t ipid, + uint8_t tid, uint16_t pid) +{ + LOG_DBG(""); + + BT_AVCTP_HDR_SET_TRANSACTION_LABLE(avctp_hdr, tid); + BT_AVCTP_HDR_SET_PACKET_TYPE(avctp_hdr, pkt_type); + BT_AVCTP_HDR_SET_CR(avctp_hdr, cr); + BT_AVCTP_HDR_SET_IPID(avctp_hdr, ipid); + avctp_hdr->pid = pid; +} + struct net_buf *bt_avctp_create_pdu(struct bt_avctp *session, bt_avctp_cr_t cr, bt_avctp_pkt_type_t pkt_type, bt_avctp_ipid_t ipid, uint8_t tid, uint16_t pid) @@ -179,11 +177,7 @@ struct net_buf *bt_avctp_create_pdu(struct bt_avctp *session, bt_avctp_cr_t cr, } hdr = net_buf_add(buf, sizeof(*hdr)); - BT_AVCTP_HDR_SET_TRANSACTION_LABLE(hdr, tid); - BT_AVCTP_HDR_SET_PACKET_TYPE(hdr, pkt_type); - BT_AVCTP_HDR_SET_CR(hdr, cr); - BT_AVCTP_HDR_SET_IPID(hdr, ipid); - hdr->pid = pid; + bt_avctp_set_header(hdr, cr, pkt_type, ipid, tid, pid); LOG_DBG("cr:0x%lX, tid:0x%02lX", BT_AVCTP_HDR_GET_CR(hdr), BT_AVCTP_HDR_GET_TRANSACTION_LABLE(hdr)); @@ -195,63 +189,78 @@ int bt_avctp_send(struct bt_avctp *session, struct net_buf *buf) return bt_l2cap_chan_send(&session->br_chan.chan, buf); } -int bt_avctp_register(const struct bt_avctp_event_cb *cb) -{ - LOG_DBG(""); - - if (event_cb) { - return -EALREADY; - } - - event_cb = cb; - - return 0; -} - static int avctp_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server, struct bt_l2cap_chan **chan) { struct bt_avctp *session = NULL; + struct bt_avctp_server *avctp_server; int err; LOG_DBG("conn %p", conn); - if (!event_cb) { - LOG_WRN("AVCTP server is unsupported"); - return -ENOTSUP; + avctp_server = CONTAINER_OF(server, struct bt_avctp_server, l2cap); + + k_sem_take(&avctp_server_lock, K_FOREVER); + + if (!sys_slist_find(&avctp_l2cap_server, &avctp_server->node, NULL)) { + LOG_WRN("Invalid l2cap server"); + k_sem_give(&avctp_server_lock); + return -EINVAL; } + k_sem_give(&avctp_server_lock); + /* Get the AVCTP session from upper layer */ - err = event_cb->accept(conn, &session); + err = avctp_server->accept(conn, &session); if (err < 0) { - LOG_ERR("Get the AVCTP session failed %d", err); + LOG_ERR("Incoming connection rejected"); return err; } - session->br_chan.rx.mtu = BT_L2CAP_RX_MTU; - session->br_chan.psm = BT_L2CAP_PSM_AVCTP; session->br_chan.chan.ops = &ops; *chan = &session->br_chan.chan; return 0; } -int bt_avctp_init(void) +int bt_avctp_server_register(struct bt_avctp_server *server) { int err; - static struct bt_l2cap_server avctp_l2cap = { - .psm = BT_L2CAP_PSM_AVCTP, - .sec_level = BT_SECURITY_L2, - .accept = avctp_l2cap_accept, - }; - LOG_DBG(""); - /* Register AVCTP PSM with L2CAP */ - err = bt_l2cap_br_server_register(&avctp_l2cap); + if ((server == NULL) || (server->accept == NULL)) { + LOG_DBG("Invalid parameter"); + return -EINVAL; + } + + k_sem_take(&avctp_server_lock, K_FOREVER); + + if (sys_slist_find(&avctp_l2cap_server, &server->node, NULL)) { + LOG_WRN("L2CAP server has been registered"); + k_sem_give(&avctp_server_lock); + return -EEXIST; + } + + server->l2cap.accept = avctp_l2cap_accept; + err = bt_l2cap_br_server_register(&server->l2cap); if (err < 0) { LOG_ERR("AVCTP L2CAP registration failed %d", err); + k_sem_give(&avctp_server_lock); + return err; } + LOG_DBG("Register L2CAP server %p", server); + sys_slist_append(&avctp_l2cap_server, &server->node); + + k_sem_give(&avctp_server_lock); + return err; } + +int bt_avctp_init(void) +{ + LOG_DBG("Initializing AVCTP"); + /* Locking semaphore initialized to 1 (unlocked) */ + k_sem_init(&avctp_server_lock, 1, 1); + return 0; +} diff --git a/subsys/bluetooth/host/classic/avctp_internal.h b/subsys/bluetooth/host/classic/avctp_internal.h index 280622be438a1..a9d3fc5c89e32 100644 --- a/subsys/bluetooth/host/classic/avctp_internal.h +++ b/subsys/bluetooth/host/classic/avctp_internal.h @@ -9,8 +9,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define BT_L2CAP_PSM_AVCTP 0x0017 - typedef enum __packed { BT_AVCTP_IPID_NONE = 0b0, BT_AVCTP_IPID_INVALID = 0b1, @@ -82,6 +80,52 @@ struct bt_avctp_ops_cb { struct bt_avctp { struct bt_l2cap_br_chan br_chan; const struct bt_avctp_ops_cb *ops; + uint16_t pid; /** Profile Identifier */ +}; + +/** + * @brief AVCTP L2CAP Server structure + * + * This structure defines the L2CAP server used for AVCTP over L2CAP transport. + */ +struct bt_avctp_server { + /** + * @brief L2CAP server parameters + * + * This field is used to register the L2CAP server. The `psm` field can be set + * to a specific value (not recommended), or set to 0 to allow automatic PSM + * allocation during registration via @ref bt_avctp_server_register. + * + * The `sec_level` field specifies the minimum required security level. + * + * @note The `struct bt_l2cap_server::accept` callback of `l2cap` can not be used + * by AVCTP applications. Instead, use the `struct bt_avctp_server::accept` + * callback defined in this structure. + */ + struct bt_l2cap_server l2cap; + + /** + * @brief Accept callback for incoming AVCTP connections + * + * This callback is invoked when a new incoming AVCTP connection is received. + * The application is responsible for authorizing the connection and allocating + * a new AVCTP session object. + * + * @warning The caller must ensure that the parent object of the AVCTP session + * is properly zero-initialized before use. + * + * @param conn The Bluetooth connection requesting authorization. + * @param session Pointer to receive the allocated AVCTP session object. + * + * @retval 0 Success. + * @retval -ENOMEM No available space for a new session. + * @retval -EACCES Connection not authorized by the application. + * @retval -EPERM Encryption key size is insufficient. + */ + int (*accept)(struct bt_conn *conn, struct bt_avctp **session); + + /** @brief Internal node for list management */ + sys_snode_t node; }; struct bt_avctp_event_cb { @@ -92,10 +136,10 @@ struct bt_avctp_event_cb { int bt_avctp_init(void); /* Application register with AVCTP layer */ -int bt_avctp_register(const struct bt_avctp_event_cb *cb); +int bt_avctp_server_register(struct bt_avctp_server *server); /* AVCTP connect */ -int bt_avctp_connect(struct bt_conn *conn, struct bt_avctp *session); +int bt_avctp_connect(struct bt_conn *conn, uint16_t psm, struct bt_avctp *session); /* AVCTP disconnect */ int bt_avctp_disconnect(struct bt_avctp *session); @@ -105,5 +149,10 @@ struct net_buf *bt_avctp_create_pdu(struct bt_avctp *session, bt_avctp_cr_t cr, bt_avctp_pkt_type_t pkt_type, bt_avctp_ipid_t ipid, uint8_t tid, uint16_t pid); +/* Set AVCTP header */ +void bt_avctp_set_header(struct bt_avctp_header *avctp_hdr, bt_avctp_cr_t cr, + bt_avctp_pkt_type_t pkt_type, bt_avctp_ipid_t ipid, + uint8_t tid, uint16_t pid); + /* Send AVCTP PDU */ int bt_avctp_send(struct bt_avctp *session, struct net_buf *buf); From b923bde676a4b65f615fcee2fdf2466908a8018f Mon Sep 17 00:00:00 2001 From: Make Shi Date: Tue, 12 Aug 2025 17:08:15 +0800 Subject: [PATCH 0068/1076] bluetooth: avrcp: provide an API for net buffer allocation Add bt_avrcp_create_pdu() to allocate net_buf with protocol headroom. Signed-off-by: Make Shi --- include/zephyr/bluetooth/classic/avrcp.h | 13 +++++++++++++ subsys/bluetooth/host/classic/avrcp.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/include/zephyr/bluetooth/classic/avrcp.h b/include/zephyr/bluetooth/classic/avrcp.h index 35c41318acc3e..07de71af81ad6 100644 --- a/include/zephyr/bluetooth/classic/avrcp.h +++ b/include/zephyr/bluetooth/classic/avrcp.h @@ -264,6 +264,19 @@ int bt_avrcp_connect(struct bt_conn *conn); */ int bt_avrcp_disconnect(struct bt_conn *conn); +/** + * @brief Allocate a net_buf for AVRCP PDU transmission, reserving headroom + * for AVRCP, AVRCTP, L2CAP, and ACL headers. + * + * This function allocates a buffer from the specified pool and reserves + * sufficient headroom for protocol headers required by AVRCP over Bluetooth. + * + * @param pool The buffer pool to allocate from. + * + * @return A newly allocated net_buf with reserved headroom. + */ +struct net_buf *bt_avrcp_create_pdu(struct net_buf_pool *pool); + /** @brief Register callback. * * Register AVRCP callbacks to monitor the state and interact with the remote device. diff --git a/subsys/bluetooth/host/classic/avrcp.c b/subsys/bluetooth/host/classic/avrcp.c index 16ba1bdc3ee69..92f4cb61e338d 100644 --- a/subsys/bluetooth/host/classic/avrcp.c +++ b/subsys/bluetooth/host/classic/avrcp.c @@ -814,6 +814,14 @@ int bt_avrcp_disconnect(struct bt_conn *conn) return err; } +struct net_buf *bt_avrcp_create_pdu(struct net_buf_pool *pool) +{ + return bt_conn_create_pdu(pool, + sizeof(struct bt_l2cap_hdr) + + sizeof(struct bt_avctp_header) + + sizeof(struct bt_avrcp_header)); +} + int bt_avrcp_ct_get_cap(struct bt_avrcp_ct *ct, uint8_t tid, uint8_t cap_id) { struct net_buf *buf; From 240ad5cedc254ef36bb57f84996926aa3d362b46 Mon Sep 17 00:00:00 2001 From: Make Shi Date: Wed, 18 Jun 2025 16:38:40 +0800 Subject: [PATCH 0069/1076] bluetooth: avrcp: Add support for AVRCP browsing - AVRCP SDP record updates for browsing channel - L2CAP setup for AVCTP browsing channel, and add connect/disconnect - Add SetBrowsedPlayer browsing command handling Signed-off-by: Make Shi --- include/zephyr/bluetooth/classic/avrcp.h | 250 ++++++++- subsys/bluetooth/host/classic/Kconfig | 8 + subsys/bluetooth/host/classic/avrcp.c | 517 +++++++++++++++++- .../bluetooth/host/classic/avrcp_internal.h | 28 +- 4 files changed, 788 insertions(+), 15 deletions(-) diff --git a/include/zephyr/bluetooth/classic/avrcp.h b/include/zephyr/bluetooth/classic/avrcp.h index 07de71af81ad6..9db8448d99bd8 100644 --- a/include/zephyr/bluetooth/classic/avrcp.h +++ b/include/zephyr/bluetooth/classic/avrcp.h @@ -141,6 +141,124 @@ typedef enum __packed { BT_AVRCP_BUTTON_RELEASED = 1, } bt_avrcp_button_state_t; +/** + * @brief AVRCP status and error codes. + * + * These status codes are used in AVRCP responses to indicate the result of a command. + */ +typedef enum __packed { + /** Invalid command. + * Valid for Commands: All + */ + BT_AVRCP_STATUS_INVALID_COMMAND = 0x00, + + /** Invalid parameter. + * Valid for Commands: All + */ + BT_AVRCP_STATUS_INVALID_PARAMETER = 0x01, + + /** Parameter content error. + * Valid for Commands: All + */ + BT_AVRCP_STATUS_PARAMETER_CONTENT_ERROR = 0x02, + + /** Internal error. + * Valid for Commands: All + */ + BT_AVRCP_STATUS_INTERNAL_ERROR = 0x03, + + /** Operation completed without error. + * Valid for Commands: All except where the response CType is AV/C REJECTED + */ + BT_AVRCP_STATUS_OPERATION_COMPLETED = 0x04, + + /** The UIDs on the device have changed. + * Valid for Commands: All + */ + BT_AVRCP_STATUS_UID_CHANGED = 0x05, + + /** The Direction parameter is invalid. + * Valid for Commands: ChangePath + */ + BT_AVRCP_STATUS_INVALID_DIRECTION = 0x07, + + /** The UID provided does not refer to a folder item. + * Valid for Commands: ChangePath + */ + BT_AVRCP_STATUS_NOT_A_DIRECTORY = 0x08, + + /** The UID provided does not refer to any currently valid item. + * Valid for Commands: ChangePath, PlayItem, AddToNowPlaying, GetItemAttributes + */ + BT_AVRCP_STATUS_DOES_NOT_EXIST = 0x09, + + /** Invalid scope. + * Valid for Commands: GetFolderItems, PlayItem, AddToNowPlayer, GetItemAttributes, + * GetTotalNumberOfItems + */ + BT_AVRCP_STATUS_INVALID_SCOPE = 0x0a, + + /** Range out of bounds. + * Valid for Commands: GetFolderItems + */ + BT_AVRCP_STATUS_RANGE_OUT_OF_BOUNDS = 0x0b, + + /** Folder item is not playable. + * Valid for Commands: Play Item, AddToNowPlaying + */ + BT_AVRCP_STATUS_FOLDER_ITEM_IS_NOT_PLAYABLE = 0x0c, + + /** Media in use. + * Valid for Commands: PlayItem, AddToNowPlaying + */ + BT_AVRCP_STATUS_MEDIA_IN_USE = 0x0d, + + /** Now Playing List full. + * Valid for Commands: AddToNowPlaying + */ + BT_AVRCP_STATUS_NOW_PLAYING_LIST_FULL = 0x0e, + + /** Search not supported. + * Valid for Commands: Search + */ + BT_AVRCP_STATUS_SEARCH_NOT_SUPPORTED = 0x0f, + + /** Search in progress. + * Valid for Commands: Search + */ + BT_AVRCP_STATUS_SEARCH_IN_PROGRESS = 0x10, + + /** The specified Player Id does not refer to a valid player. + * Valid for Commands: SetAddressedPlayer, SetBrowsedPlayer + */ + BT_AVRCP_STATUS_INVALID_PLAYER_ID = 0x11, + + /** Player not browsable. + * Valid for Commands: SetBrowsedPlayer + */ + BT_AVRCP_STATUS_PLAYER_NOT_BROWSABLE = 0x12, + + /** Player not addressed. + * Valid for Commands: Search, SetBrowsedPlayer + */ + BT_AVRCP_STATUS_PLAYER_NOT_ADDRESSED = 0x13, + + /** No valid search results. + * Valid for Commands: GetFolderItems + */ + BT_AVRCP_STATUS_NO_VALID_SEARCH_RESULTS = 0x14, + + /** No available players. + * Valid for Commands: ALL + */ + BT_AVRCP_STATUS_NO_AVAILABLE_PLAYERS = 0x15, + + /** Addressed player changed. + * Valid for Commands: All Register Notification commands + */ + BT_AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED = 0x16, +} bt_avrcp_status_t; + /** @brief AVRCP CT structure */ struct bt_avrcp_ct; /** @brief AVRCP TG structure */ @@ -167,13 +285,34 @@ struct bt_avrcp_passthrough_rsp { uint8_t byte0; /**< [7]: state_flag, [6:0]: opid */ uint8_t data_len; uint8_t data[]; -}; +} __packed; struct bt_avrcp_get_cap_rsp { uint8_t cap_id; /**< bt_avrcp_cap_t */ uint8_t cap_cnt; /**< number of items contained in *cap */ uint8_t cap[]; /**< 1 or 3 octets each depends on cap_id */ -}; +} __packed; + +/** @brief AVRCP Character Set IDs */ +typedef enum __packed { + BT_AVRCP_CHARSET_UTF8 = 0x006a, +} bt_avrcp_charset_t; + +/** @brief get folder name (response) */ +struct bt_avrcp_folder_name { + uint16_t folder_name_len; + uint8_t folder_name[]; +} __packed; + +/** @brief Set browsed player response structure */ +struct bt_avrcp_set_browsed_player_rsp { + uint8_t status; /**< Status see bt_avrcp_status_t.*/ + uint16_t uid_counter; /**< UID counter */ + uint32_t num_items; /**< Number of items in the folder */ + uint16_t charset_id; /**< Character set ID */ + uint8_t folder_depth; /**< Folder depth */ + struct bt_avrcp_folder_name folder_names[0]; /**< Folder names data */ +} __packed; struct bt_avrcp_ct_cb { /** @brief An AVRCP CT connection has been established. @@ -195,6 +334,25 @@ struct bt_avrcp_ct_cb { */ void (*disconnected)(struct bt_avrcp_ct *ct); + /** @brief An AVRCP CT browsing connection has been established. + * + * This callback notifies the application of an avrcp browsing connection, + * i.e., an AVCTP browsing L2CAP connection. + * + * @param conn Connection object. + * @param ct AVRCP CT connection object. + */ + void (*browsing_connected)(struct bt_conn *conn, struct bt_avrcp_ct *ct); + + /** @brief An AVRCP CT browsing connection has been disconnected. + * + * This callback notifies the application that an avrcp browsing connection + * has been disconnected. + * + * @param ct AVRCP CT connection object. + */ + void (*browsing_disconnected)(struct bt_avrcp_ct *ct); + /** @brief Callback function for bt_avrcp_get_cap(). * * Called when the get capabilities process is completed. @@ -239,6 +397,19 @@ struct bt_avrcp_ct_cb { */ void (*passthrough_rsp)(struct bt_avrcp_ct *ct, uint8_t tid, bt_avrcp_rsp_t result, const struct bt_avrcp_passthrough_rsp *rsp); + + /** @brief Callback function for bt_avrcp_ct_set_browsed_player(). + * + * Called when the set browsed player process is completed. + * + * @param ct AVRCP CT connection object. + * @param tid The transaction label of the response. + * @param buf The response buffer containing the set browsed player response data. + * The application can parse this payload according to the format defined in + * @ref bt_avrcp_set_browsed_player_rsp. Note that the data is encoded in + * big-endian format. + */ + void (*browsed_player_rsp)(struct bt_avrcp_ct *ct, uint8_t tid, struct net_buf *buf); }; /** @brief Connect AVRCP. @@ -277,6 +448,27 @@ int bt_avrcp_disconnect(struct bt_conn *conn); */ struct net_buf *bt_avrcp_create_pdu(struct net_buf_pool *pool); +/** @brief Connect AVRCP browsing channel. + * + * This function is to be called after the AVRCP control channel is established. + * The API is to be used to establish AVRCP browsing connection between devices. + * + * @param conn Pointer to bt_conn structure. + * + * @return 0 in case of success or error code in case of error. + */ +int bt_avrcp_browsing_connect(struct bt_conn *conn); + +/** @brief Disconnect AVRCP browsing channel. + * + * This function close AVCTP browsing channel L2CAP connection. + * + * @param conn Pointer to bt_conn structure. + * + * @return 0 in case of success or error code in case of error. + */ +int bt_avrcp_browsing_disconnect(struct bt_conn *conn); + /** @brief Register callback. * * Register AVRCP callbacks to monitor the state and interact with the remote device. @@ -339,6 +531,18 @@ int bt_avrcp_ct_get_subunit_info(struct bt_avrcp_ct *ct, uint8_t tid); int bt_avrcp_ct_passthrough(struct bt_avrcp_ct *ct, uint8_t tid, uint8_t opid, uint8_t state, const uint8_t *payload, uint8_t len); +/** @brief Set browsed player. + * + * This function sets the browsed player on the remote device. + * + * @param ct The AVRCP CT instance. + * @param tid The transaction label of the response, valid from 0 to 15. + * @param player_id The player ID to be set as browsed player. + * + * @return 0 in case of success or error code in case of error. + */ +int bt_avrcp_ct_set_browsed_player(struct bt_avrcp_ct *ct, uint8_t tid, uint16_t player_id); + struct bt_avrcp_tg_cb { /** @brief An AVRCP TG connection has been established. * @@ -367,6 +571,35 @@ struct bt_avrcp_tg_cb { * @param tg AVRCP TG connection object. */ void (*unit_info_req)(struct bt_avrcp_tg *tg, uint8_t tid); + + /** @brief An AVRCP TG browsing connection has been established. + * + * This callback notifies the application of an avrcp browsing connection, + * i.e., an AVCTP browsing L2CAP connection. + * + * @param conn Connection object. + * @param tg AVRCP TG connection object. + */ + void (*browsing_connected)(struct bt_conn *conn, struct bt_avrcp_tg *tg); + + /** @brief An AVRCP TG browsing connection has been disconnected. + * + * This callback notifies the application that an avrcp browsing connection + * has been disconnected. + * + * @param tg AVRCP TG connection object. + */ + void (*browsing_disconnected)(struct bt_avrcp_tg *tg); + + /** @brief Set browsed player request callback. + * + * This callback is called whenever an AVRCP set browsed player request is received. + * + * @param tg AVRCP TG connection object. + * @param tid The transaction label of the request. + * @param player_id The player ID to be set as browsed player. + */ + void (*set_browsed_player_req)(struct bt_avrcp_tg *tg, uint8_t tid, uint16_t player_id); }; /** @brief Register callback. @@ -391,6 +624,19 @@ int bt_avrcp_tg_register_cb(const struct bt_avrcp_tg_cb *cb); */ int bt_avrcp_tg_send_unit_info_rsp(struct bt_avrcp_tg *tg, uint8_t tid, struct bt_avrcp_unit_info_rsp *rsp); + +/** @brief Send the set browsed player response. + * + * This function is called by the application to send the set browsed player response. + * + * @param tg The AVRCP TG instance. + * @param tid The transaction label of the response, valid from 0 to 15. + * @param buf The response buffer containing the set browsed player response data. + * + * @return 0 in case of success or error code in case of error. + */ +int bt_avrcp_tg_send_set_browsed_player_rsp(struct bt_avrcp_tg *tg, uint8_t tid, + struct net_buf *buf); #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/classic/Kconfig b/subsys/bluetooth/host/classic/Kconfig index 21a46b313fa01..e8f56dd5f780c 100644 --- a/subsys/bluetooth/host/classic/Kconfig +++ b/subsys/bluetooth/host/classic/Kconfig @@ -485,6 +485,14 @@ config BT_AVRCP_CONTROLLER help This option enables the AVRCP profile controller function +config BT_AVRCP_BROWSING + bool "Bluetooth AVRCP Browsing channel support [EXPERIMENTAL]" + select EXPERIMENTAL + select BT_L2CAP_ENH_RET + help + This option enables support for the AVRCP Browsing channel + over Bluetooth BR/EDR. + endif # BT_AVRCP config BT_PAGE_TIMEOUT diff --git a/subsys/bluetooth/host/classic/avrcp.c b/subsys/bluetooth/host/classic/avrcp.c index 92f4cb61e338d..be67a3566530d 100644 --- a/subsys/bluetooth/host/classic/avrcp.c +++ b/subsys/bluetooth/host/classic/avrcp.c @@ -35,6 +35,8 @@ struct bt_avrcp { struct bt_avctp session; /* ACL connection handle */ struct bt_conn *acl_conn; + + struct bt_avctp browsing_session; }; struct bt_avrcp_ct { @@ -50,7 +52,14 @@ struct avrcp_handler { void (*func)(struct bt_avrcp *avrcp, uint8_t tid, struct net_buf *buf); }; +struct avrcp_pdu_handler { + bt_avrcp_pdu_id_t pdu_id; + uint8_t min_len; + int (*func)(struct bt_avrcp *avrcp, uint8_t tid, struct net_buf *buf); +}; + #define AVRCP_AVCTP(_avctp) CONTAINER_OF(_avctp, struct bt_avrcp, session) +#define AVRCP_BROW_AVCTP(_avctp) CONTAINER_OF(_avctp, struct bt_avrcp, browsing_session) /* * This macros returns true if the CT/TG has been initialized, which @@ -66,6 +75,10 @@ static struct bt_avrcp avrcp_connection[CONFIG_BT_MAX_CONN]; static struct bt_avrcp_ct bt_avrcp_ct_pool[CONFIG_BT_MAX_CONN]; static struct bt_avrcp_tg bt_avrcp_tg_pool[CONFIG_BT_MAX_CONN]; +static struct bt_avctp_server avctp_server; +#if defined(CONFIG_BT_AVRCP_BROWSING) +static struct bt_avctp_server avctp_browsing_server; +#endif /* CONFIG_BT_AVRCP_BROWSING */ #if defined(CONFIG_BT_AVRCP_TARGET) static struct bt_sdp_attribute avrcp_tg_attrs[] = { BT_SDP_NEW_SERVICE, @@ -108,7 +121,42 @@ static struct bt_sdp_attribute avrcp_tg_attrs[] = { }, ) ), - /* C1: Browsing not supported */ + /* Browsing channel */ +#if defined(CONFIG_BT_AVRCP_BROWSING) + BT_SDP_LIST( + BT_SDP_ATTR_ADD_PROTO_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 18), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVRCP_BROWSING) + }) + }, + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(AVCTP_VER_1_4) + }) + }) + }) + ), +#endif /* CONFIG_BT_AVRCP_BROWSING */ /* C2: Cover Art not supported */ BT_SDP_LIST( BT_SDP_ATTR_PROFILE_DESC_LIST, @@ -129,7 +177,7 @@ static struct bt_sdp_attribute avrcp_tg_attrs[] = { }, ) ), - BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2), + BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2 | AVRCP_BROWSING_ENABLE), /* O: Provider Name not presented */ BT_SDP_SERVICE_NAME("AVRCP Target"), }; @@ -186,7 +234,43 @@ static struct bt_sdp_attribute avrcp_ct_attrs[] = { }, ) ), - /* C1: Browsing not supported */ + /* Browsing channel */ +#if defined(CONFIG_BT_AVRCP_BROWSING) + BT_SDP_LIST( + BT_SDP_ATTR_ADD_PROTO_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 18), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVRCP_BROWSING) + }) + }, + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(AVCTP_VER_1_4) + }) + }) + }) + ), +#endif /* CONFIG_BT_AVRCP_BROWSING */ + /* C2: Cover Art not supported */ BT_SDP_LIST( BT_SDP_ATTR_PROFILE_DESC_LIST, BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8), @@ -206,8 +290,7 @@ static struct bt_sdp_attribute avrcp_ct_attrs[] = { }, ) ), - BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2), - /* O: Provider Name not presented */ + BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2 | AVRCP_BROWSING_ENABLE), BT_SDP_SERVICE_NAME("AVRCP Controller"), }; @@ -410,6 +493,34 @@ static int avrcp_send(struct bt_avrcp *avrcp, struct net_buf *buf) return 0; } +static struct net_buf *avrcp_create_browsing_pdu(struct bt_avrcp *avrcp, uint8_t tid, + bt_avctp_cr_t cr) +{ + return bt_avctp_create_pdu(&(avrcp->browsing_session), cr, BT_AVCTP_PKT_TYPE_SINGLE, + BT_AVCTP_IPID_NONE, tid, + sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS)); +} + +static int avrcp_browsing_send(struct bt_avrcp *avrcp, struct net_buf *buf) +{ + int err; + struct bt_avctp_header *avctp_hdr = (struct bt_avctp_header *)(buf->data); + struct bt_avrcp_avc_brow_pdu *hdr = + (struct bt_avrcp_avc_brow_pdu *)(buf->data + sizeof(*avctp_hdr)); + uint8_t tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(avctp_hdr); + bt_avctp_cr_t cr = BT_AVCTP_HDR_GET_CR(avctp_hdr); + + LOG_DBG("AVRCP browsing send cr:0x%X, tid:0x%X, pdu_id:0x%02X\n", cr, tid, + hdr->pdu_id); + err = bt_avctp_send(&(avrcp->browsing_session), buf); + if (err < 0) { + LOG_ERR("AVCTP browsing send fail, err = %d", err); + return err; + } + + return 0; +} + static int bt_avrcp_send_unit_info_err_rsp(struct bt_avrcp *avrcp, uint8_t tid) { struct net_buf *buf; @@ -701,6 +812,15 @@ static int avrcp_recv(struct bt_avctp *session, struct net_buf *buf) return 0; } +static void init_avctp_control_channel(struct bt_avctp *session) +{ + LOG_DBG("session %p", session); + + session->br_chan.rx.mtu = BT_L2CAP_RX_MTU; + session->br_chan.required_sec_level = BT_SECURITY_L2; + session->pid = BT_SDP_AV_REMOTE_SVCLASS; +} + static const struct bt_avctp_ops_cb avctp_ops = { .connected = avrcp_connected, .disconnected = avrcp_disconnected, @@ -720,6 +840,7 @@ static int avrcp_accept(struct bt_conn *conn, struct bt_avctp **session) return -EALREADY; } + init_avctp_control_channel(&(avrcp->session)); *session = &(avrcp->session); avrcp->session.ops = &avctp_ops; avrcp->acl_conn = bt_conn_ref(conn); @@ -729,21 +850,235 @@ static int avrcp_accept(struct bt_conn *conn, struct bt_avctp **session) return 0; } -static struct bt_avctp_event_cb avctp_cb = { - .accept = avrcp_accept, +#if defined(CONFIG_BT_AVRCP_BROWSING) +static void init_avctp_browsing_channel(struct bt_avctp *session) +{ + LOG_DBG("session %p", session); + + session->br_chan.rx.mtu = BT_L2CAP_RX_MTU; + session->br_chan.required_sec_level = BT_SECURITY_L2; + session->br_chan.rx.optional = false; + session->br_chan.rx.max_window = CONFIG_BT_L2CAP_MAX_WINDOW_SIZE; + session->br_chan.rx.max_transmit = 3; + session->br_chan.rx.mode = BT_L2CAP_BR_LINK_MODE_ERET; + session->br_chan.tx.monitor_timeout = CONFIG_BT_L2CAP_BR_MONITOR_TIMEOUT; + session->pid = BT_SDP_AV_REMOTE_SVCLASS; +} + +/* The AVCTP L2CAP channel established */ +static void browsing_avrcp_connected(struct bt_avctp *session) +{ + struct bt_avrcp *avrcp = AVRCP_BROW_AVCTP(session); + + if ((avrcp_ct_cb != NULL) && (avrcp_ct_cb->browsing_connected != NULL)) { + avrcp_ct_cb->browsing_connected(session->br_chan.chan.conn, get_avrcp_ct(avrcp)); + } + + if ((avrcp_tg_cb != NULL) && (avrcp_tg_cb->browsing_connected != NULL)) { + avrcp_tg_cb->browsing_connected(session->br_chan.chan.conn, get_avrcp_tg(avrcp)); + } +} + +/* The AVCTP L2CAP channel released */ +static void browsing_avrcp_disconnected(struct bt_avctp *session) +{ + struct bt_avrcp *avrcp = AVRCP_BROW_AVCTP(session); + + if ((avrcp_ct_cb != NULL) && (avrcp_ct_cb->disconnected != NULL)) { + avrcp_ct_cb->browsing_disconnected(get_avrcp_ct(avrcp)); + } + if ((avrcp_tg_cb != NULL) && (avrcp_tg_cb->disconnected != NULL)) { + avrcp_tg_cb->browsing_disconnected(get_avrcp_tg(avrcp)); + } +} + +static int avrcp_ct_handle_set_browsed_player(struct bt_avrcp *avrcp, + uint8_t tid, struct net_buf *buf) +{ + if ((avrcp_ct_cb == NULL) || (avrcp_ct_cb->browsed_player_rsp == NULL)) { + return -EINVAL; + } + + avrcp_ct_cb->browsed_player_rsp(get_avrcp_ct(avrcp), tid, buf); + + return 0; +} + +static const struct avrcp_pdu_handler rsp_brow_handlers[] = { + {BT_AVRCP_PDU_ID_SET_BROWSED_PLAYER, sizeof(struct bt_avrcp_set_browsed_player_rsp), + avrcp_ct_handle_set_browsed_player}, +}; + +static int avrcp_tg_handle_set_browsed_player_req(struct bt_avrcp *avrcp, + uint8_t tid, struct net_buf *buf) +{ + uint16_t player_id; + struct net_buf *rsp_buf; + int err; + + if ((avrcp_tg_cb == NULL) || (avrcp_tg_cb->set_browsed_player_req == NULL)) { + goto error_rsp; + } + + player_id = net_buf_pull_be16(buf); + + LOG_DBG("Set browsed player request: player_id=0x%04x", player_id); + + avrcp_tg_cb->set_browsed_player_req(get_avrcp_tg(avrcp), tid, player_id); + return 0; + +error_rsp: + rsp_buf = bt_avrcp_create_pdu(NULL); + __ASSERT(rsp_buf != NULL, "Failed to allocate response buffer"); + + if (net_buf_tailroom(rsp_buf) < sizeof(uint8_t)) { + LOG_ERR("Insufficient space in response buffer"); + net_buf_unref(rsp_buf); + return -ENOMEM; + } + net_buf_add_u8(rsp_buf, BT_AVRCP_STATUS_INTERNAL_ERROR); + + err = bt_avrcp_tg_send_set_browsed_player_rsp(get_avrcp_tg(avrcp), tid, rsp_buf); + if (err < 0) { + LOG_ERR("Failed to send browsed player error response (err: %d)", err); + net_buf_unref(rsp_buf); + } + return err; +} + +static const struct avrcp_pdu_handler cmd_brow_handlers[] = { + {BT_AVRCP_PDU_ID_SET_BROWSED_PLAYER, sizeof(uint16_t), + avrcp_tg_handle_set_browsed_player_req}, }; +static int handle_pdu(struct bt_avrcp *avrcp, uint8_t tid, struct net_buf *buf, + uint8_t pdu_id, const struct avrcp_pdu_handler *handlers, size_t num_handlers) +{ + for (size_t i = 0; i < num_handlers; i++) { + const struct avrcp_pdu_handler *handler = &handlers[i]; + + if (handler->pdu_id != pdu_id) { + continue; + } + + if (buf->len < handler->min_len) { + LOG_ERR("Too small (%u bytes) pdu_id 0x%02x", buf->len, pdu_id); + return -EINVAL; + } + + return handler->func(avrcp, tid, buf); + } + + return -EOPNOTSUPP; +} + +static int browsing_avrcp_recv(struct bt_avctp *session, struct net_buf *buf) +{ + struct bt_avrcp *avrcp = AVRCP_BROW_AVCTP(session); + struct bt_avctp_header *avctp_hdr; + bt_avctp_pkt_type_t pkt_type; + struct bt_avrcp_avc_brow_pdu *brow; + uint8_t tid; + bt_avctp_cr_t cr; + + if (buf->len < sizeof(*avctp_hdr) + sizeof(struct bt_avrcp_avc_brow_pdu)) { + LOG_ERR("Invalid AVRCP browsing header received: buffer too short (%u)", buf->len); + return -EMSGSIZE; + } + + avctp_hdr = net_buf_pull_mem(buf, sizeof(*avctp_hdr)); + pkt_type = BT_AVCTP_HDR_GET_PACKET_TYPE(avctp_hdr); + tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(avctp_hdr); + cr = BT_AVCTP_HDR_GET_CR(avctp_hdr); + + brow = net_buf_pull_mem(buf, sizeof(struct bt_avrcp_avc_brow_pdu)); + + if (pkt_type != BT_AVCTP_PKT_TYPE_SINGLE) { + LOG_ERR("Invalid packet type: 0x%02X", pkt_type); + return -EINVAL; + } + + if (avctp_hdr->pid != sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS)) { + return -EINVAL; /* Ignore other profile */ + } + + if (buf->len != sys_be16_to_cpu(brow->param_len)) { + LOG_ERR("Invalid AVRCP browsing PDU length: expected %u, got %u", + sys_be16_to_cpu(brow->param_len), buf->len); + return -EMSGSIZE; + } + + LOG_DBG("AVRCP browsing msg received, cr:0x%X, tid:0x%X, pdu_id:0x%02X", cr, + tid, brow->pdu_id); + + if (cr == BT_AVCTP_RESPONSE) { + return handle_pdu(avrcp, tid, buf, brow->pdu_id, rsp_brow_handlers, + ARRAY_SIZE(rsp_brow_handlers)); + } + + return handle_pdu(avrcp, tid, buf, brow->pdu_id, cmd_brow_handlers, + ARRAY_SIZE(cmd_brow_handlers)); +} + +static const struct bt_avctp_ops_cb browsing_avctp_ops = { + .connected = browsing_avrcp_connected, + .disconnected = browsing_avrcp_disconnected, + .recv = browsing_avrcp_recv, +}; + +static int avrcp_browsing_accept(struct bt_conn *conn, struct bt_avctp **session) +{ + struct bt_avrcp *avrcp; + + avrcp = avrcp_get_connection(conn); + if (avrcp == NULL) { + LOG_ERR("Cannot allocate memory"); + return -ENOTCONN; + } + + if (avrcp->acl_conn == NULL) { + LOG_ERR("The control channel not established"); + return -ENOTCONN; + } + + if (avrcp->browsing_session.br_chan.chan.conn != NULL) { + LOG_ERR("Browsing session already connected"); + return -EALREADY; + } + + init_avctp_browsing_channel(&(avrcp->browsing_session)); + avrcp->browsing_session.ops = &browsing_avctp_ops; + *session = &(avrcp->browsing_session); + + LOG_DBG("browsing_session: %p", &(avrcp->browsing_session)); + + return 0; +} +#endif /* CONFIG_BT_AVRCP_BROWSING */ + int bt_avrcp_init(void) { int err; /* Register event handlers with AVCTP */ - err = bt_avctp_register(&avctp_cb); + avctp_server.l2cap.psm = BT_L2CAP_PSM_AVRCP; + avctp_server.accept = avrcp_accept; + err = bt_avctp_server_register(&avctp_server); if (err < 0) { LOG_ERR("AVRCP registration failed"); return err; } +#if defined(CONFIG_BT_AVRCP_BROWSING) + avctp_browsing_server.l2cap.psm = BT_L2CAP_PSM_AVRCP_BROWSING; + avctp_browsing_server.accept = avrcp_browsing_accept; + err = bt_avctp_server_register(&avctp_browsing_server); + if (err < 0) { + LOG_ERR("AVRCP browsing registration failed"); + return err; + } +#endif /* CONFIG_BT_AVRCP_BROWSING */ + #if defined(CONFIG_BT_AVRCP_TARGET) bt_sdp_register_service(&avrcp_tg_rec); #endif /* CONFIG_BT_AVRCP_CONTROLLER */ @@ -781,7 +1116,8 @@ int bt_avrcp_connect(struct bt_conn *conn) } avrcp->session.ops = &avctp_ops; - err = bt_avctp_connect(conn, &(avrcp->session)); + init_avctp_control_channel(&(avrcp->session)); + err = bt_avctp_connect(conn, BT_L2CAP_PSM_AVRCP, &(avrcp->session)); if (err < 0) { /* If error occurs, undo the saving and return the error */ memset(avrcp, 0, sizeof(struct bt_avrcp)); @@ -805,6 +1141,15 @@ int bt_avrcp_disconnect(struct bt_conn *conn) return -ENOTCONN; } + if (avrcp->browsing_session.br_chan.chan.conn != NULL) { + /* If browsing session is still active, disconnect it first */ + err = bt_avrcp_browsing_disconnect(conn); + if (err < 0) { + LOG_ERR("Browsing session disconnect failed: %d", err); + return err; + } + } + err = bt_avctp_disconnect(&(avrcp->session)); if (err < 0) { LOG_DBG("AVCTP Disconnect failed"); @@ -822,6 +1167,61 @@ struct net_buf *bt_avrcp_create_pdu(struct net_buf_pool *pool) sizeof(struct bt_avrcp_header)); } +#if defined(CONFIG_BT_AVRCP_BROWSING) +int bt_avrcp_browsing_connect(struct bt_conn *conn) +{ + struct bt_avrcp *avrcp; + int err; + + avrcp = avrcp_get_connection(conn); + if (avrcp == NULL) { + LOG_ERR("Cannot allocate memory"); + return -ENOTCONN; + } + + if (avrcp->acl_conn == NULL) { + LOG_ERR("The control channel not established"); + return -ENOTCONN; + } + + if (avrcp->browsing_session.br_chan.chan.conn != NULL) { + return -EALREADY; + } + + avrcp->browsing_session.ops = &browsing_avctp_ops; + init_avctp_browsing_channel(&(avrcp->browsing_session)); + err = bt_avctp_connect(conn, BT_L2CAP_PSM_AVRCP_BROWSING, &(avrcp->browsing_session)); + if (err < 0) { + LOG_ERR("AVCTP browsing connect failed"); + return err; + } + + LOG_DBG("Browsing connection request sent"); + + return 0; +} + +int bt_avrcp_browsing_disconnect(struct bt_conn *conn) +{ + int err; + struct bt_avrcp *avrcp; + + avrcp = avrcp_get_connection(conn); + if (avrcp == NULL) { + LOG_ERR("Get avrcp connection failure"); + return -ENOTCONN; + } + + err = bt_avctp_disconnect(&(avrcp->browsing_session)); + if (err < 0) { + LOG_ERR("AVCTP browsing disconnect failed"); + return err; + } + + return err; +} +#endif /* CONFIG_BT_AVRCP_BROWSING */ + int bt_avrcp_ct_get_cap(struct bt_avrcp_ct *ct, uint8_t tid, uint8_t cap_id) { struct net_buf *buf; @@ -927,6 +1327,51 @@ int bt_avrcp_ct_passthrough(struct bt_avrcp_ct *ct, uint8_t tid, uint8_t opid, u return avrcp_send(ct->avrcp, buf); } +#if defined(CONFIG_BT_AVRCP_BROWSING) +int bt_avrcp_ct_set_browsed_player(struct bt_avrcp_ct *ct, uint8_t tid, uint16_t player_id) +{ + struct net_buf *buf; + struct bt_avrcp_avc_brow_pdu *pdu; + int err; + + if ((ct == NULL) || (ct->avrcp == NULL)) { + return -EINVAL; + } + + if (!IS_CT_ROLE_SUPPORTED()) { + return -ENOTSUP; + } + + if (ct->avrcp->browsing_session.br_chan.chan.conn == NULL) { + LOG_ERR("Browsing session not connected"); + return -ENOTCONN; + } + + buf = avrcp_create_browsing_pdu(ct->avrcp, tid, BT_AVCTP_CMD); + if (buf == NULL) { + return -ENOMEM; + } + + if (net_buf_tailroom(buf) < sizeof(*pdu) + sizeof(player_id)) { + LOG_ERR("Not enough tailroom in buffer for browsing PDU"); + net_buf_unref(buf); + return -ENOMEM; + } + + pdu = net_buf_add(buf, sizeof(*pdu)); + pdu->pdu_id = BT_AVRCP_PDU_ID_SET_BROWSED_PLAYER; + pdu->param_len = sys_cpu_to_be16(sizeof(player_id)); + net_buf_add_be16(buf, player_id); + + err = avrcp_browsing_send(ct->avrcp, buf); + if (err < 0) { + LOG_ERR("Failed to send AVRCP browsing PDU (err: %d)", err); + net_buf_unref(buf); + } + return err; +} +#endif /* CONFIG_BT_AVRCP_BROWSING */ + int bt_avrcp_ct_register_cb(const struct bt_avrcp_ct_cb *cb) { if (!cb) { @@ -985,3 +1430,57 @@ int bt_avrcp_tg_send_unit_info_rsp(struct bt_avrcp_tg *tg, uint8_t tid, return avrcp_send(tg->avrcp, buf); } + +#if defined(CONFIG_BT_AVRCP_BROWSING) +int bt_avrcp_tg_send_set_browsed_player_rsp(struct bt_avrcp_tg *tg, uint8_t tid, + struct net_buf *buf) +{ + struct bt_avrcp_avc_brow_pdu *hdr; + struct bt_avctp_header *avctp_hdr; + uint16_t param_len; + int err; + + if ((tg == NULL) || (tg->avrcp == NULL) || (buf == NULL)) { + LOG_ERR("Invalid AVRCP target"); + return -EINVAL; + } + + if (!IS_TG_ROLE_SUPPORTED()) { + LOG_ERR("Target role not supported"); + return -ENOTSUP; + } + + if (tg->avrcp->browsing_session.br_chan.chan.conn == NULL) { + LOG_ERR("Browsing session not connected"); + return -ENOTCONN; + } + + param_len = buf->len; + + if (net_buf_headroom(buf) < sizeof(struct bt_avrcp_avc_brow_pdu)) { + LOG_ERR("Not enough headroom in buffer for bt_avrcp_avc_brow_pdu"); + return -ENOMEM; + } + hdr = net_buf_push(buf, sizeof(struct bt_avrcp_avc_brow_pdu)); + memset(hdr, 0, sizeof(struct bt_avrcp_avc_brow_pdu)); + hdr->pdu_id = BT_AVRCP_PDU_ID_SET_BROWSED_PLAYER; + hdr->param_len = sys_cpu_to_be16(param_len); + + if (net_buf_headroom(buf) < sizeof(struct bt_avctp_header)) { + LOG_ERR("Not enough headroom in buffer for bt_avctp_header"); + return -ENOMEM; + } + avctp_hdr = net_buf_push(buf, sizeof(struct bt_avctp_header)); + memset(avctp_hdr, 0, sizeof(struct bt_avctp_header)); + + bt_avctp_set_header(avctp_hdr, BT_AVCTP_RESPONSE, BT_AVCTP_PKT_TYPE_SINGLE, + BT_AVCTP_IPID_NONE, tid, + sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS)); + + err = avrcp_browsing_send(tg->avrcp, buf); + if (err < 0) { + LOG_ERR("Failed to send AVRCP browsing PDU (err: %d)", err); + } + return err; +} +#endif /* CONFIG_BT_AVRCP_BROWSING */ diff --git a/subsys/bluetooth/host/classic/avrcp_internal.h b/subsys/bluetooth/host/classic/avrcp_internal.h index d1c84986c4b40..2a14317c30c72 100644 --- a/subsys/bluetooth/host/classic/avrcp_internal.h +++ b/subsys/bluetooth/host/classic/avrcp_internal.h @@ -12,10 +12,15 @@ #define AVCTP_VER_1_4 (0x0104u) #define AVRCP_VER_1_6 (0x0106u) -#define AVRCP_CAT_1 BIT(0) /* Player/Recorder */ -#define AVRCP_CAT_2 BIT(1) /* Monitor/Amplifier */ -#define AVRCP_CAT_3 BIT(2) /* Tuner */ -#define AVRCP_CAT_4 BIT(3) /* Menu */ +#define AVRCP_CAT_1 BIT(0) /* Player/Recorder */ +#define AVRCP_CAT_2 BIT(1) /* Monitor/Amplifier */ +#define AVRCP_CAT_3 BIT(2) /* Tuner */ +#define AVRCP_CAT_4 BIT(3) /* Menu */ +#define AVRCP_PLAYER_APPLICATION_SETTINGS BIT(4) /* Bit 0 must also be set */ +#define AVRCP_GROUP_NAVIGATION BIT(5) /* Bit 0 must also be set */ +#define AVRCP_BROWSING_SUPPORT BIT(6) +#define AVRCP_MULTIPLE_MEDIA_PLAYERS BIT(7) +#define AVRCP_COVER_ART_SUPPORT BIT(8) #define AVRCP_SUBUNIT_PAGE (0) /* Fixed value according to AVRCP */ #define AVRCP_SUBUNIT_EXTENSION_CODE (7) /* Fixed value according to TA Document 2001012 */ @@ -23,6 +28,15 @@ #define BT_AVRCP_UNIT_INFO_RSP_SIZE (5) #define BT_AVRCP_SUBUNIT_INFO_RSP_SIZE (5) +#define BT_L2CAP_PSM_AVRCP 0x0017 +#define BT_L2CAP_PSM_AVRCP_BROWSING 0x001b + +#if defined(CONFIG_BT_AVRCP_BROWSING) +#define AVRCP_BROWSING_ENABLE AVRCP_BROWSING_SUPPORT +#else +#define AVRCP_BROWSING_ENABLE 0 +#endif /* CONFIG_BT_AVRCP_BROWSING */ + typedef enum __packed { BT_AVRCP_SUBUNIT_ID_ZERO = 0x0, BT_AVRCP_SUBUNIT_ID_IGNORE = 0x7, @@ -122,6 +136,12 @@ struct bt_avrcp_avc_pdu { uint8_t param[]; } __packed; +struct bt_avrcp_avc_brow_pdu { + uint8_t pdu_id; + uint16_t param_len; + uint8_t param[]; +} __packed; + /** The 4-bit command type or the 4-bit response code. */ #define BT_AVRCP_HDR_GET_CTYPE_OR_RSP(hdr) FIELD_GET(GENMASK(3, 0), ((hdr)->byte0)) /** Taken together, the subunit_type and subunit_ID fields define the command recipient’s address From 9cfbed62df6ea2c1b1004067b8fa5f3fab1322df Mon Sep 17 00:00:00 2001 From: Make Shi Date: Tue, 22 Jul 2025 16:23:59 +0800 Subject: [PATCH 0070/1076] Bluetooth: Shell: AVRCP: Shell interface for browsing support - Add shell interface for browsing connect and disconnect testing and SetBrowsedPlayer command testing. Signed-off-by: Make Shi --- subsys/bluetooth/host/classic/shell/avrcp.c | 280 ++++++++++++++++++++ 1 file changed, 280 insertions(+) diff --git a/subsys/bluetooth/host/classic/shell/avrcp.c b/subsys/bluetooth/host/classic/shell/avrcp.c index 91eebe7ab1e1d..9bdc245980019 100644 --- a/subsys/bluetooth/host/classic/shell/avrcp.c +++ b/subsys/bluetooth/host/classic/shell/avrcp.c @@ -29,6 +29,12 @@ #include "host/shell/bt.h" #include "common/bt_shell_private.h" +NET_BUF_POOL_DEFINE(avrcp_tx_pool, CONFIG_BT_MAX_CONN, + BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + +#define FOLDER_NAME_HEX_BUF_LEN 80 + struct bt_avrcp_ct *default_ct; struct bt_avrcp_tg *default_tg; static bool avrcp_ct_registered; @@ -60,6 +66,16 @@ static void avrcp_ct_disconnected(struct bt_avrcp_ct *ct) default_ct = NULL; } +static void avrcp_ct_browsing_connected(struct bt_conn *conn, struct bt_avrcp_ct *ct) +{ + bt_shell_print("AVRCP CT browsing connected"); +} + +static void avrcp_ct_browsing_disconnected(struct bt_avrcp_ct *ct) +{ + bt_shell_print("AVRCP CT browsing disconnected"); +} + static void avrcp_get_cap_rsp(struct bt_avrcp_ct *ct, uint8_t tid, const struct bt_avrcp_get_cap_rsp *rsp) { @@ -115,13 +131,70 @@ static void avrcp_passthrough_rsp(struct bt_avrcp_ct *ct, uint8_t tid, bt_avrcp_ } } +static void avrcp_browsed_player_rsp(struct bt_avrcp_ct *ct, uint8_t tid, + struct net_buf *buf) +{ + struct bt_avrcp_set_browsed_player_rsp *rsp; + struct bt_avrcp_folder_name *folder_name; + + rsp = net_buf_pull_mem(buf, sizeof(*rsp)); + if (rsp->status != BT_AVRCP_STATUS_OPERATION_COMPLETED) { + bt_shell_print("AVRCP set browsed player failed, tid = %d, status = 0x%02x", + tid, rsp->status); + return; + } + + bt_shell_print("AVRCP set browsed player success, tid = %d", tid); + bt_shell_print(" UID Counter: %u", sys_be16_to_cpu(rsp->uid_counter)); + bt_shell_print(" Number of Items: %u", sys_be32_to_cpu(rsp->num_items)); + bt_shell_print(" Charset ID: 0x%04X", sys_be16_to_cpu(rsp->charset_id)); + bt_shell_print(" Folder Depth: %u", rsp->folder_depth); + + while (buf->len > 0) { + if (buf->len < sizeof(struct bt_avrcp_folder_name)) { + bt_shell_print("incompleted message"); + break; + } + folder_name = net_buf_pull_mem(buf, sizeof(struct bt_avrcp_folder_name)); + folder_name->folder_name_len = sys_be16_to_cpu(folder_name->folder_name_len); + if (buf->len < folder_name->folder_name_len) { + bt_shell_print("incompleted message for folder_name"); + break; + } + net_buf_pull_mem(buf, folder_name->folder_name_len); + + if (sys_be16_to_cpu(rsp->charset_id) == BT_AVRCP_CHARSET_UTF8) { + bt_shell_print("Raw folder name:"); + for (int i = 0; i < folder_name->folder_name_len; i++) { + bt_shell_print("%c", folder_name->folder_name[i]); + } + } else { + bt_shell_print(" Get folder Name : "); + bt_shell_hexdump(folder_name->folder_name, folder_name->folder_name_len); + } + if (rsp->folder_depth > 0) { + rsp->folder_depth--; + } else { + bt_shell_warn("Folder depth is mismatched with received data"); + break; + } + } + + if (rsp->folder_depth > 0) { + bt_shell_print("folder depth mismatch: expected 0, got %u", rsp->folder_depth); + } +} + static struct bt_avrcp_ct_cb app_avrcp_ct_cb = { .connected = avrcp_ct_connected, .disconnected = avrcp_ct_disconnected, + .browsing_connected = avrcp_ct_browsing_connected, + .browsing_disconnected = avrcp_ct_browsing_disconnected, .get_cap_rsp = avrcp_get_cap_rsp, .unit_info_rsp = avrcp_unit_info_rsp, .subunit_info_rsp = avrcp_subunit_info_rsp, .passthrough_rsp = avrcp_passthrough_rsp, + .browsed_player_rsp = avrcp_browsed_player_rsp, }; static void avrcp_tg_connected(struct bt_conn *conn, struct bt_avrcp_tg *tg) @@ -136,16 +209,36 @@ static void avrcp_tg_disconnected(struct bt_avrcp_tg *tg) default_tg = NULL; } +static void avrcp_tg_browsing_connected(struct bt_conn *conn, struct bt_avrcp_tg *tg) +{ + bt_shell_print("AVRCP TG browsing connected"); +} + static void avrcp_unit_info_req(struct bt_avrcp_tg *tg, uint8_t tid) { bt_shell_print("AVRCP unit info request received"); tg_tid = tid; } +static void avrcp_tg_browsing_disconnected(struct bt_avrcp_tg *tg) +{ + bt_shell_print("AVRCP TG browsing disconnected"); +} + +static void avrcp_set_browsed_player_req(struct bt_avrcp_tg *tg, uint8_t tid, + uint16_t player_id) +{ + bt_shell_print("AVRCP set browsed player request received, player_id = %u", player_id); + tg_tid = tid; +} + static struct bt_avrcp_tg_cb app_avrcp_tg_cb = { .connected = avrcp_tg_connected, .disconnected = avrcp_tg_disconnected, + .browsing_connected = avrcp_tg_browsing_connected, + .browsing_disconnected = avrcp_tg_browsing_disconnected, .unit_info_req = avrcp_unit_info_req, + .set_browsed_player_req = avrcp_set_browsed_player_req, }; static int register_ct_cb(const struct shell *sh) @@ -256,6 +349,53 @@ static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[]) return 0; } +static int cmd_browsing_connect(const struct shell *sh, int32_t argc, char *argv[]) +{ + int err; + + if (!avrcp_ct_registered && register_ct_cb(sh) != 0) { + return -ENOEXEC; + } + + if (default_conn == NULL) { + shell_error(sh, "BR/EDR not connected"); + return -ENOEXEC; + } + + err = bt_avrcp_browsing_connect(default_conn); + if (err < 0) { + shell_error(sh, "fail to connect AVRCP browsing"); + } else { + shell_print(sh, "AVRCP browsing connect request sent"); + } + + return err; +} + +static int cmd_browsing_disconnect(const struct shell *sh, int32_t argc, char *argv[]) +{ + int err; + + if (default_conn == NULL) { + shell_print(sh, "Not connected"); + return -ENOEXEC; + } + + if ((default_ct != NULL) || (default_tg != NULL)) { + err = bt_avrcp_browsing_disconnect(default_conn); + if (err < 0) { + shell_error(sh, "fail to disconnect AVRCP browsing"); + } else { + shell_print(sh, "AVRCP browsing disconnect request sent"); + } + } else { + shell_error(sh, "AVRCP is not connected"); + err = -ENOEXEC; + } + + return err; +} + static int cmd_get_unit_info(const struct shell *sh, int32_t argc, char *argv[]) { if (!avrcp_ct_registered && register_ct_cb(sh) != 0) { @@ -364,6 +504,139 @@ static int cmd_get_cap(const struct shell *sh, int32_t argc, char *argv[]) return 0; } +static int cmd_set_browsed_player(const struct shell *sh, int32_t argc, char *argv[]) +{ + uint16_t player_id; + int err; + + if (!avrcp_ct_registered && register_ct_cb(sh) != 0) { + return -ENOEXEC; + } + + if (default_ct == NULL) { + shell_error(sh, "AVRCP is not connected"); + return -ENOEXEC; + } + + player_id = (uint16_t)strtoul(argv[1], NULL, 0); + + err = bt_avrcp_ct_set_browsed_player(default_ct, get_next_tid(), player_id); + if (err < 0) { + shell_error(sh, "fail to set browsed player"); + } else { + shell_print(sh, "AVRCP send set browsed player req"); + } + + return 0; +} + +static int cmd_send_set_browsed_player_rsp(const struct shell *sh, int32_t argc, char *argv[]) +{ + struct bt_avrcp_set_browsed_player_rsp *rsp; + struct bt_avrcp_folder_name *folder_name; + char *folder_name_str = "Music"; + uint8_t folder_name_hex[FOLDER_NAME_HEX_BUF_LEN]; + uint16_t folder_name_len = 0; + struct net_buf *buf; + uint16_t param_len; + int err; + + if (!avrcp_tg_registered && register_tg_cb(sh) != 0) { + return -ENOEXEC; + } + + if (default_tg == NULL) { + shell_error(sh, "AVRCP TG is not connected"); + return -ENOEXEC; + } + + buf = bt_avrcp_create_pdu(&avrcp_tx_pool); + if (buf == NULL) { + shell_error(sh, "Failed to allocate buffer for AVRCP browsing response"); + return -ENOMEM; + } + + if (net_buf_tailroom(buf) < sizeof(struct bt_avrcp_set_browsed_player_rsp)) { + shell_error(sh, "Not enough tailroom in buffer for browsed player rsp"); + goto failed; + } + + rsp = net_buf_add(buf, sizeof(*rsp)); + /* Set default rsp */ + rsp->status = BT_AVRCP_STATUS_OPERATION_COMPLETED; + rsp->uid_counter = sys_cpu_to_be16(0x0001U); + rsp->num_items = sys_cpu_to_be32(100U); + rsp->charset_id = sys_cpu_to_be16(BT_AVRCP_CHARSET_UTF8); + rsp->folder_depth = 1; + + /* Parse command line arguments or use default values */ + if (argc >= 2) { + rsp->status = (uint8_t)strtoul(argv[1], NULL, 0); + } + + if (argc >= 3) { + rsp->uid_counter = sys_cpu_to_be16((uint16_t)strtoul(argv[2], NULL, 0)); + } + + if (argc >= 4) { + rsp->num_items = sys_cpu_to_be32((uint32_t)strtoul(argv[3], NULL, 0)); + } + + if (argc >= 5) { + rsp->charset_id = sys_cpu_to_be16((uint16_t)strtoul(argv[4], NULL, 0)); + } + + if (rsp->charset_id == sys_cpu_to_be16(BT_AVRCP_CHARSET_UTF8)) { + if (argc >= 6) { + folder_name_str = argv[5]; + } + folder_name_len = strlen(folder_name_str); + } else { + if (argc >= 6) { + folder_name_len = hex2bin(argv[5], strlen(argv[5]), folder_name_hex, + sizeof(folder_name_hex)); + if (folder_name_len == 0) { + shell_error(sh, "Failed to get folder_name from %s", argv[5]); + } + } else { + shell_error(sh, "Please input hex string for folder_name"); + goto failed; + } + } + + param_len = folder_name_len + sizeof(struct bt_avrcp_folder_name); + if (net_buf_tailroom(buf) < param_len) { + shell_error(sh, "Not enough tailroom in buffer for param"); + goto failed; + } + + folder_name = net_buf_add(buf, sizeof(*folder_name)); + folder_name->folder_name_len = sys_cpu_to_be16(folder_name_len); + if (rsp->charset_id == sys_cpu_to_be16(BT_AVRCP_CHARSET_UTF8)) { + net_buf_add_mem(buf, folder_name_str, folder_name_len); + } else { + net_buf_add_mem(buf, folder_name_hex, folder_name_len); + } + + err = bt_avrcp_tg_send_set_browsed_player_rsp(default_tg, tg_tid, buf); + if (err == 0) { + shell_print(sh, "Send set browsed player response, status = 0x%02x", rsp->status); + } else { + shell_error(sh, "Failed to send set browsed player response, err = %d", err); + goto failed; + } + + return 0; +failed: + net_buf_unref(buf); + return -ENOEXEC; +} + +#define HELP_BROWSED_PLAYER_RSP \ + "Send SetBrowsedPlayer response\n" \ + "Usage: send_browsed_player_rsp [status] [uid_counter] [num_items] " \ + "[charset_id] [folder_name]" + SHELL_STATIC_SUBCMD_SET_CREATE( ct_cmds, SHELL_CMD_ARG(register_cb, NULL, "register avrcp ct callbacks", cmd_register_ct_cb, 1, 0), @@ -373,12 +646,16 @@ SHELL_STATIC_SUBCMD_SET_CREATE( 0), SHELL_CMD_ARG(play, NULL, "request a play at the remote player", cmd_play, 1, 0), SHELL_CMD_ARG(pause, NULL, "request a pause at the remote player", cmd_pause, 1, 0), + SHELL_CMD_ARG(set_browsed_player, NULL, "set browsed player ", + cmd_set_browsed_player, 2, 0), SHELL_SUBCMD_SET_END); SHELL_STATIC_SUBCMD_SET_CREATE( tg_cmds, SHELL_CMD_ARG(register_cb, NULL, "register avrcp tg callbacks", cmd_register_tg_cb, 1, 0), SHELL_CMD_ARG(send_unit_rsp, NULL, "send unit info response", cmd_send_unit_info_rsp, 1, 0), + SHELL_CMD_ARG(send_browsed_player_rsp, NULL, HELP_BROWSED_PLAYER_RSP, + cmd_send_set_browsed_player_rsp, 1, 5), SHELL_SUBCMD_SET_END); static int cmd_avrcp(const struct shell *sh, size_t argc, char **argv) @@ -398,6 +675,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE( avrcp_cmds, SHELL_CMD_ARG(connect, NULL, "connect AVRCP", cmd_connect, 1, 0), SHELL_CMD_ARG(disconnect, NULL, "disconnect AVRCP", cmd_disconnect, 1, 0), + SHELL_CMD_ARG(browsing_connect, NULL, "connect browsing AVRCP", cmd_browsing_connect, 1, 0), + SHELL_CMD_ARG(browsing_disconnect, NULL, "disconnect browsing AVRCP", + cmd_browsing_disconnect, 1, 0), SHELL_CMD(ct, &ct_cmds, "AVRCP CT shell commands", cmd_avrcp), SHELL_CMD(tg, &tg_cmds, "AVRCP TG shell commands", cmd_avrcp), SHELL_SUBCMD_SET_END); From 72a3f7e4c9ed5a0222b90fa489ff08736a745ad9 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Thu, 3 Jul 2025 19:46:47 +0530 Subject: [PATCH 0071/1076] drivers: wifi: siwx91x: Add support for setting regulatory domain Add support for configuring the regulatory domain (region code) to ensure the device operates in compliance with local RF regulations. The region must be set before the Wi-Fi interface becomes active i.e., before scan or connection in STA mode, or before starting in AP mode. Since the SDK does not support setting the country code directly, the driver maps country codes to region codes Signed-off-by: Arunmani Alagarsamy --- drivers/wifi/siwx91x/siwx91x_wifi.c | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index 5e3650d04dda4..8b94ac4b05b3e 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -24,6 +24,44 @@ LOG_MODULE_REGISTER(siwx91x_wifi); NET_BUF_POOL_FIXED_DEFINE(siwx91x_tx_pool, 1, _NET_ETH_MAX_FRAME_SIZE, 0, NULL); +typedef struct { + const char *const *codes; + size_t num_codes; + sl_wifi_region_code_t region_code; +} region_map_t; + +static const char *const us_codes[] = { + "AE", "AR", "AS", "BB", "BM", "BR", "BS", "CA", "CO", "CR", "CU", "CX", + "DM", "DO", "EC", "FM", "GD", "GY", "GU", "HN", "HT", "JM", "KY", "LB", + "LK", "MH", "MN", "MP", "MO", "MY", "NI", "PA", "PE", "PG", "PH", "PK", + "PR", "PW", "PY", "SG", "MX", "SV", "TC", "TH", "TT", "US", "UY", "VE", + "VI", "VN", "VU", "00" + /* Map "00" (world domain) to US region, + * as using the world domain is not recommended + */ +}; +static const char *const eu_codes[] = { + "AD", "AF", "AI", "AL", "AM", "AN", "AT", "AW", "AU", "AZ", "BA", "BE", + "BG", "BH", "BL", "BT", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", + "FR", "GB", "GE", "GF", "GL", "GP", "GR", "GT", "HK", "HR", "HU", "ID", + "IE", "IL", "IN", "IR", "IS", "IT", "JO", "KH", "FI", "KN", "KW", "KZ", + "LC", "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MF", "MT", "MV", "MQ", + "NL", "NO", "NZ", "OM", "PF", "PL", "PM", "PT", "QA", "RO", "RS", "RU", + "SA", "SE", "SI", "SK", "SR", "SY", "TR", "TW", "UA", "UZ", "VC", "WF", + "WS", "YE", "RE", "YT" +}; +static const char *const jp_codes[] = {"BD", "BN", "BO", "CL", "BZ", "JP", "NP"}; +static const char *const kr_codes[] = {"KR", "KP"}; +static const char *const cn_codes[] = {"CN"}; + +static const region_map_t region_maps[] = { + {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US}, + {eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU}, + {jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP}, + {kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR}, + {cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN}, +}; + static int siwx91x_sl_to_z_mode(sl_wifi_interface_t interface) { switch (interface) { @@ -369,6 +407,45 @@ static int siwx91x_get_version(const struct device *dev, struct wifi_version *pa return 0; } +sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code) +{ + __ASSERT(country_code, "country_code cannot be NULL"); + + ARRAY_FOR_EACH(region_maps, i) { + for (size_t j = 0; j < region_maps[i].num_codes; j++) { + if (memcmp(country_code, region_maps[i].codes[j], + WIFI_COUNTRY_CODE_LEN) == 0) { + return region_maps[i].region_code; + } + } + } + return SL_WIFI_DEFAULT_REGION; +} + +static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain) +{ + sl_wifi_operation_mode_t oper_mode = sli_get_opermode(); + sl_wifi_region_code_t region_code; + int ret; + + __ASSERT(reg_domain, "reg_domain cannot be NULL"); + + if (reg_domain->oper == WIFI_MGMT_SET) { + region_code = siwx91x_map_country_code_to_region(reg_domain->country_code); + ret = sl_si91x_set_device_region(oper_mode, SL_WIFI_BAND_MODE_2_4GHZ, region_code); + if (ret) { + LOG_ERR("Failed to set device region: %x", ret); + return -EINVAL; + } + + if (region_code == SL_WIFI_DEFAULT_REGION) { + LOG_INF("Country code not supported, using default region"); + } + } + + return 0; +} + static void siwx91x_iface_init(struct net_if *iface) { const struct siwx91x_config *siwx91x_cfg = iface->if_dev->dev->config; @@ -432,6 +509,7 @@ static const struct wifi_mgmt_ops siwx91x_mgmt = { .get_stats = siwx91x_stats, #endif .get_version = siwx91x_get_version, + .reg_domain = siwx91x_wifi_reg_domain, }; static const struct net_wifi_mgmt_offload siwx91x_api = { From eac7784574c8d1a945f342910ef0eee7818b7c16 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Fri, 11 Jul 2025 12:01:21 +0530 Subject: [PATCH 0072/1076] soc: silabs: siwg917: Relocate country code mapping function Moved the `siwx91x_map_country_code_to_region()` function from the Wi-Fi driver source file to nwp.c. This change prepares the codebase for upcoming enhancements related to the regulatory domain GET operation. Signed-off-by: Arunmani Alagarsamy --- drivers/wifi/siwx91x/siwx91x_wifi.c | 53 ------------------------- soc/silabs/silabs_siwx91x/siwg917/nwp.c | 53 +++++++++++++++++++++++++ soc/silabs/silabs_siwx91x/siwg917/nwp.h | 13 ++++++ 3 files changed, 66 insertions(+), 53 deletions(-) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index 8b94ac4b05b3e..8753446656aef 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -24,44 +24,6 @@ LOG_MODULE_REGISTER(siwx91x_wifi); NET_BUF_POOL_FIXED_DEFINE(siwx91x_tx_pool, 1, _NET_ETH_MAX_FRAME_SIZE, 0, NULL); -typedef struct { - const char *const *codes; - size_t num_codes; - sl_wifi_region_code_t region_code; -} region_map_t; - -static const char *const us_codes[] = { - "AE", "AR", "AS", "BB", "BM", "BR", "BS", "CA", "CO", "CR", "CU", "CX", - "DM", "DO", "EC", "FM", "GD", "GY", "GU", "HN", "HT", "JM", "KY", "LB", - "LK", "MH", "MN", "MP", "MO", "MY", "NI", "PA", "PE", "PG", "PH", "PK", - "PR", "PW", "PY", "SG", "MX", "SV", "TC", "TH", "TT", "US", "UY", "VE", - "VI", "VN", "VU", "00" - /* Map "00" (world domain) to US region, - * as using the world domain is not recommended - */ -}; -static const char *const eu_codes[] = { - "AD", "AF", "AI", "AL", "AM", "AN", "AT", "AW", "AU", "AZ", "BA", "BE", - "BG", "BH", "BL", "BT", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", - "FR", "GB", "GE", "GF", "GL", "GP", "GR", "GT", "HK", "HR", "HU", "ID", - "IE", "IL", "IN", "IR", "IS", "IT", "JO", "KH", "FI", "KN", "KW", "KZ", - "LC", "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MF", "MT", "MV", "MQ", - "NL", "NO", "NZ", "OM", "PF", "PL", "PM", "PT", "QA", "RO", "RS", "RU", - "SA", "SE", "SI", "SK", "SR", "SY", "TR", "TW", "UA", "UZ", "VC", "WF", - "WS", "YE", "RE", "YT" -}; -static const char *const jp_codes[] = {"BD", "BN", "BO", "CL", "BZ", "JP", "NP"}; -static const char *const kr_codes[] = {"KR", "KP"}; -static const char *const cn_codes[] = {"CN"}; - -static const region_map_t region_maps[] = { - {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US}, - {eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU}, - {jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP}, - {kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR}, - {cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN}, -}; - static int siwx91x_sl_to_z_mode(sl_wifi_interface_t interface) { switch (interface) { @@ -407,21 +369,6 @@ static int siwx91x_get_version(const struct device *dev, struct wifi_version *pa return 0; } -sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code) -{ - __ASSERT(country_code, "country_code cannot be NULL"); - - ARRAY_FOR_EACH(region_maps, i) { - for (size_t j = 0; j < region_maps[i].num_codes; j++) { - if (memcmp(country_code, region_maps[i].codes[j], - WIFI_COUNTRY_CODE_LEN) == 0) { - return region_maps[i].region_code; - } - } - } - return SL_WIFI_DEFAULT_REGION; -} - static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain) { sl_wifi_operation_mode_t oper_mode = sli_get_opermode(); diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.c b/soc/silabs/silabs_siwx91x/siwg917/nwp.c index 4c760d4d92b0e..5d6ffa5931a98 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/nwp.c @@ -32,6 +32,59 @@ BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(255) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319)); +typedef struct { + const char *const *codes; + size_t num_codes; + sl_wifi_region_code_t region_code; +} region_map_t; + +static const char *const us_codes[] = { + "AE", "AR", "AS", "BB", "BM", "BR", "BS", "CA", "CO", "CR", "CU", "CX", + "DM", "DO", "EC", "FM", "GD", "GY", "GU", "HN", "HT", "JM", "KY", "LB", + "LK", "MH", "MN", "MP", "MO", "MY", "NI", "PA", "PE", "PG", "PH", "PK", + "PR", "PW", "PY", "SG", "MX", "SV", "TC", "TH", "TT", "US", "UY", "VE", + "VI", "VN", "VU", "00" + /* Map "00" (world domain) to US region, + * as using the world domain is not recommended + */ +}; +static const char *const eu_codes[] = { + "AD", "AF", "AI", "AL", "AM", "AN", "AT", "AW", "AU", "AZ", "BA", "BE", + "BG", "BH", "BL", "BT", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", + "FR", "GB", "GE", "GF", "GL", "GP", "GR", "GT", "HK", "HR", "HU", "ID", + "IE", "IL", "IN", "IR", "IS", "IT", "JO", "KH", "FI", "KN", "KW", "KZ", + "LC", "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MF", "MT", "MV", "MQ", + "NL", "NO", "NZ", "OM", "PF", "PL", "PM", "PT", "QA", "RO", "RS", "RU", + "SA", "SE", "SI", "SK", "SR", "SY", "TR", "TW", "UA", "UZ", "VC", "WF", + "WS", "YE", "RE", "YT" +}; +static const char *const jp_codes[] = {"BD", "BN", "BO", "CL", "BZ", "JP", "NP"}; +static const char *const kr_codes[] = {"KR", "KP"}; +static const char *const cn_codes[] = {"CN"}; + +static const region_map_t region_maps[] = { + {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US}, + {eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU}, + {jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP}, + {kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR}, + {cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN}, +}; + +sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code) +{ + __ASSERT(country_code, "country_code cannot be NULL"); + + ARRAY_FOR_EACH(region_maps, i) { + for (size_t j = 0; j < region_maps[i].num_codes; j++) { + if (memcmp(country_code, region_maps[i].codes[j], + WIFI_COUNTRY_CODE_LEN) == 0) { + return region_maps[i].region_code; + } + } + } + return SL_WIFI_DEFAULT_REGION; +} + static void siwx91x_apply_sram_config(sl_si91x_boot_configuration_t *boot_config) { /* The size does not match exactly because 1 KB is reserved at the start of the RAM */ diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.h b/soc/silabs/silabs_siwx91x/siwg917/nwp.h index 978d7c44ec2ec..0c236d334231b 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.h +++ b/soc/silabs/silabs_siwx91x/siwg917/nwp.h @@ -24,4 +24,17 @@ */ int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta); +/** + * @brief Map an ISO/IEC 3166-1 alpha-2 country code to a Wi-Fi region code. + * + * This function maps a 2-character country code (e.g., "US", "FR", "JP") + * to the corresponding region code defined in the SDK (sl_wifi_region_code_t). + * If the country is not explicitly listed, it defaults to the US region. + * + * @param[in] country_code Pointer to a 2-character ISO country code. + * + * @return Corresponding sl_wifi_region_code_t value. + */ +sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code); + #endif From 06158853c32ac67b8b497a79bbad13515e738207 Mon Sep 17 00:00:00 2001 From: Arunmani Alagarsamy Date: Tue, 8 Jul 2025 08:48:32 +0530 Subject: [PATCH 0073/1076] drivers: wifi: siwx91x: Add support for regulatory domain GET Added support for retrieving the regulatory domain information from the siwx91x driver. Since the SDK does not provide a GET API for region details, the driver now stores the country code and reuse the configuration `sli_si91x_set_region_ap_request_t` to get the channel information. This stored data is returned when a GET operation is requested. Signed-off-by: Arunmani Alagarsamy --- drivers/wifi/siwx91x/siwx91x_wifi.c | 54 +++++++++++++++++++++++++ soc/silabs/silabs_siwx91x/siwg917/nwp.c | 50 ++++++++++++++++++++--- soc/silabs/silabs_siwx91x/siwg917/nwp.h | 32 +++++++++++++++ 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index 8753446656aef..c90d87b625846 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -19,6 +19,7 @@ #include "sl_wifi_callback_framework.h" #define SIWX91X_DRIVER_VERSION KERNEL_VERSION_STRING +#define MAX_24GHZ_CHANNELS 14 LOG_MODULE_REGISTER(siwx91x_wifi); @@ -369,10 +370,43 @@ static int siwx91x_get_version(const struct device *dev, struct wifi_version *pa return 0; } +static int map_sdk_region_to_zephyr_channel_info(const sli_si91x_set_region_ap_request_t *sdk_reg, + struct wifi_reg_chan_info *z_chan_info, + size_t *num_channels) +{ + uint8_t first_channel = sdk_reg->channel_info[0].first_channel; + uint8_t channel; + uint16_t freq; + + *num_channels = sdk_reg->channel_info[0].no_of_channels; + if (*num_channels > MAX_24GHZ_CHANNELS) { + return -EOVERFLOW; + } + + for (int idx = 0; idx < *num_channels; idx++) { + channel = first_channel + idx; + freq = 2407 + channel * 5; + + if (freq > 2472) { + freq = 2484; /* channel 14 */ + } + + z_chan_info[idx].center_frequency = freq; + z_chan_info[idx].max_power = sdk_reg->channel_info[0].max_tx_power; + z_chan_info[idx].supported = 1; + z_chan_info[idx].passive_only = 0; + z_chan_info[idx].dfs = 0; + } + + return 0; +} + static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain) { + const sli_si91x_set_region_ap_request_t *sdk_reg = NULL; sl_wifi_operation_mode_t oper_mode = sli_get_opermode(); sl_wifi_region_code_t region_code; + const char *country_code; int ret; __ASSERT(reg_domain, "reg_domain cannot be NULL"); @@ -386,8 +420,28 @@ static int siwx91x_wifi_reg_domain(const struct device *dev, struct wifi_reg_dom } if (region_code == SL_WIFI_DEFAULT_REGION) { + siwx91x_store_country_code(DEFAULT_COUNTRY_CODE); LOG_INF("Country code not supported, using default region"); + } else { + siwx91x_store_country_code(reg_domain->country_code); } + } else if (reg_domain->oper == WIFI_MGMT_GET) { + country_code = siwx91x_get_country_code(); + memcpy(reg_domain->country_code, country_code, WIFI_COUNTRY_CODE_LEN); + region_code = siwx91x_map_country_code_to_region(country_code); + + sdk_reg = siwx91x_find_sdk_region_table(region_code); + if (!sdk_reg) { + return -ENOENT; + } + + ret = map_sdk_region_to_zephyr_channel_info(sdk_reg, reg_domain->chan_info, + ®_domain->num_channels); + if (ret) { + return ret; + } + } else { + return -EINVAL; } return 0; diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.c b/soc/silabs/silabs_siwx91x/siwg917/nwp.c index 5d6ffa5931a98..01019a4c1ddcf 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/nwp.c @@ -32,10 +32,19 @@ BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(255) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319)); +extern const sli_si91x_set_region_ap_request_t default_US_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_EU_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_JP_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_KR_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_SG_region_2_4GHZ_configurations; +extern const sli_si91x_set_region_ap_request_t default_CN_region_2_4GHZ_configurations; + +static char current_country_code[WIFI_COUNTRY_CODE_LEN]; typedef struct { const char *const *codes; size_t num_codes; sl_wifi_region_code_t region_code; + const sli_si91x_set_region_ap_request_t *sdk_reg; } region_map_t; static const char *const us_codes[] = { @@ -63,13 +72,31 @@ static const char *const kr_codes[] = {"KR", "KP"}; static const char *const cn_codes[] = {"CN"}; static const region_map_t region_maps[] = { - {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US}, - {eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU}, - {jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP}, - {kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR}, - {cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN}, + {us_codes, ARRAY_SIZE(us_codes), SL_WIFI_REGION_US, + &default_US_region_2_4GHZ_configurations}, + {eu_codes, ARRAY_SIZE(eu_codes), SL_WIFI_REGION_EU, + &default_EU_region_2_4GHZ_configurations}, + {jp_codes, ARRAY_SIZE(jp_codes), SL_WIFI_REGION_JP, + &default_JP_region_2_4GHZ_configurations}, + {kr_codes, ARRAY_SIZE(kr_codes), SL_WIFI_REGION_KR, + &default_KR_region_2_4GHZ_configurations}, + {cn_codes, ARRAY_SIZE(cn_codes), SL_WIFI_REGION_CN, + &default_CN_region_2_4GHZ_configurations}, }; +int siwx91x_store_country_code(const char *country_code) +{ + __ASSERT(country_code, "country_code cannot be NULL"); + + memcpy(current_country_code, country_code, WIFI_COUNTRY_CODE_LEN); + return 0; +} + +const char *siwx91x_get_country_code(void) +{ + return current_country_code; +} + sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code) { __ASSERT(country_code, "country_code cannot be NULL"); @@ -85,6 +112,16 @@ sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_cod return SL_WIFI_DEFAULT_REGION; } +const sli_si91x_set_region_ap_request_t *siwx91x_find_sdk_region_table(uint8_t region_code) +{ + ARRAY_FOR_EACH(region_maps, i) { + if (region_maps[i].region_code == region_code) { + return region_maps[i].sdk_reg; + } + } + return NULL; +} + static void siwx91x_apply_sram_config(sl_si91x_boot_configuration_t *boot_config) { /* The size does not match exactly because 1 KB is reserved at the start of the RAM */ @@ -214,8 +251,8 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w bool hidden_ssid, uint8_t max_num_sta) { sl_wifi_device_configuration_t default_config = { + .region_code = siwx91x_map_country_code_to_region(DEFAULT_COUNTRY_CODE), .band = SL_SI91X_WIFI_BAND_2_4GHZ, - .region_code = DEFAULT_REGION, .boot_option = LOAD_NWP_FW, .boot_config = { .feature_bit_map = SL_SI91X_FEAT_SECURITY_OPEN | SL_SI91X_FEAT_WPS_DISABLE | @@ -246,6 +283,7 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w return -EINVAL; } + siwx91x_store_country_code(DEFAULT_COUNTRY_CODE); siwx91x_apply_sram_config(boot_config); switch (wifi_oper_mode) { diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp.h b/soc/silabs/silabs_siwx91x/siwg917/nwp.h index 0c236d334231b..f67b5f83f5889 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/nwp.h +++ b/soc/silabs/silabs_siwx91x/siwg917/nwp.h @@ -8,6 +8,7 @@ #include "sl_wifi.h" #define SIWX91X_INTERFACE_MASK (0x03) +#define DEFAULT_COUNTRY_CODE "00" /** * @brief Switch the Wi-Fi operating mode. @@ -37,4 +38,35 @@ int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num */ sl_wifi_region_code_t siwx91x_map_country_code_to_region(const char *country_code); +/** + * @brief Get the default SDK region configuration for a region code. + * + * Looks up the given sl_wifi_region_code_t and returns the corresponding + * SDK region configuration, or NULL if not found. + * + * @param[in] region_code Wi-Fi region code (SL_WIFI_REGION_*). + * + * @return Pointer to SDK region configuration, or NULL if unsupported. + */ +const sli_si91x_set_region_ap_request_t *siwx91x_find_sdk_region_table(uint8_t region_code); + +/** + * @brief Store the country code internally for GET operation. + * + * This function saves the provided country code to a static internal buffer. + * + * @param[in] country_code Pointer to a 2-character ISO country code. + */ +int siwx91x_store_country_code(const char *country_code); + +/** + * @brief Retrieve the currently stored country code. + * + * This function returns a pointer to the internally stored 2-character + * country code set by store_country_code(). + * + * @return Pointer to the stored country code string. + */ +const char *siwx91x_get_country_code(void); + #endif From 5f9d20cf38fd9e7a15641b874781d52fb2757cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 21 Aug 2025 13:56:22 +0200 Subject: [PATCH 0074/1076] tests: drivers: comparator: gpio_loopback: Update SNIPPET_ROOT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When SNIPPET is added to the build, it is added to all images. But not all images have the test directory added to their SNIPPET_ROOT, so we also update the SNIPPET_ROOT. This allows, for instance, the uicr image of nrf54H to find this snippet. Ref: NCSDK-NONE Signed-off-by: Sebastian Bøe --- tests/drivers/comparator/gpio_loopback/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index bf0e7d127a0c2..ad25bd224b0e8 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -18,6 +18,7 @@ tests: - frdm_ke15z drivers.comparator.gpio_loopback.nrf_comp: extra_args: + - SNIPPET_ROOT="." - SNIPPET="gpio_loopback_nrf_comp" platform_allow: - nrf5340dk/nrf5340/cpuapp @@ -27,6 +28,7 @@ tests: - ophelia4ev/nrf54l15/cpuapp drivers.comparator.gpio_loopback.nrf_lpcomp: extra_args: + - SNIPPET_ROOT="." - SNIPPET="gpio_loopback_nrf_lpcomp" platform_allow: - nrf5340dk/nrf5340/cpuapp From ae191f66c91505c1ece9f622459696714d114c1f Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Mon, 4 Aug 2025 12:08:04 +0200 Subject: [PATCH 0075/1076] soc: nordic: uicr: Populate UICR.VERSION field in gen_uicr.py Set the VERSION field to 2.0 in gen_uicr.py to indicate the version of the format the script produces blobs for. This is required for forwards compatibility with newer versions of IronSide SE. Signed-off-by: Jonathan Nilsen --- soc/nordic/common/uicr/gen_uicr.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/soc/nordic/common/uicr/gen_uicr.py b/soc/nordic/common/uicr/gen_uicr.py index 50f96eab566f7..5888786e928fe 100644 --- a/soc/nordic/common/uicr/gen_uicr.py +++ b/soc/nordic/common/uicr/gen_uicr.py @@ -17,6 +17,10 @@ from elftools.elf.elffile import ELFFile from intelhex import IntelHex +# The UICR format version produced by this script +UICR_FORMAT_VERSION_MAJOR = 2 +UICR_FORMAT_VERSION_MINOR = 0 + # Name of the ELF section containing PERIPHCONF entries. # Must match the name used in the linker script. PERIPHCONF_SECTION = "uicr_periphconf_entry" @@ -45,6 +49,14 @@ class PeriphconfEntry(c.LittleEndianStructure): PERIPHCONF_ENTRY_SIZE = c.sizeof(PeriphconfEntry) +class Version(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("MINOR", c.c_uint16), + ("MAJOR", c.c_uint16), + ] + + class Approtect(c.LittleEndianStructure): _pack_ = 1 _fields_ = [ @@ -104,7 +116,7 @@ class Mpcconf(c.LittleEndianStructure): class Uicr(c.LittleEndianStructure): _pack_ = 1 _fields_ = [ - ("VERSION", c.c_uint32), + ("VERSION", Version), ("RESERVED", c.c_uint32), ("LOCK", c.c_uint32), ("RESERVED1", c.c_uint32), @@ -171,6 +183,9 @@ def main() -> None: init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4) uicr = Uicr.from_buffer_copy(init_values) + uicr.VERSION.MAJOR = UICR_FORMAT_VERSION_MAJOR + uicr.VERSION.MINOR = UICR_FORMAT_VERSION_MINOR + kconfig_str = args.in_config.read() kconfig = parse_kconfig(kconfig_str) From ac851ca1601b385e38a1f6062d24dc407664dfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 21 Aug 2025 12:15:29 +0200 Subject: [PATCH 0076/1076] soc: nordic: uicr: Reorganize how gen_uicr.py is invoked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorganize how gen_uicr.py is invoked. Instead of invoking it from one of the Zephyr images we invoke it from a new special Zephyr image called uicr. This uicr Zephyr image is flashed in the same way as normal Zephyr images so special handling in the runner is no longer necessary. Also, we simplify gen_uicr.py by moving parsing of Kconfig/DT from gen_uicr.py to CMake. Signed-off-by: Sebastian Bøe --- scripts/ci/check_compliance.py | 1 + scripts/west_commands/runners/nrf_common.py | 20 --- soc/nordic/Kconfig.sysbuild | 1 + soc/nordic/common/CMakeLists.txt | 4 +- soc/nordic/common/uicr/CMakeLists.txt | 30 ---- soc/nordic/common/uicr/Kconfig | 22 +-- soc/nordic/common/uicr/Kconfig.sysbuild | 9 ++ soc/nordic/common/uicr/gen_uicr.py | 134 +++++++++--------- .../common/uicr/gen_uicr/CMakeLists.txt | 99 +++++++++++++ soc/nordic/common/uicr/gen_uicr/Kconfig | 14 ++ soc/nordic/common/uicr/gen_uicr/prj.conf | 1 + .../uicr/gen_uicr/zephyr/CMakeLists.txt | 22 +++ soc/nordic/common/uicr/sysbuild.cmake | 11 ++ soc/nordic/sysbuild.cmake | 4 + 14 files changed, 231 insertions(+), 141 deletions(-) create mode 100644 soc/nordic/common/uicr/Kconfig.sysbuild create mode 100644 soc/nordic/common/uicr/gen_uicr/CMakeLists.txt create mode 100644 soc/nordic/common/uicr/gen_uicr/Kconfig create mode 100644 soc/nordic/common/uicr/gen_uicr/prj.conf create mode 100644 soc/nordic/common/uicr/gen_uicr/zephyr/CMakeLists.txt create mode 100644 soc/nordic/common/uicr/sysbuild.cmake diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 138b484e9a566..9993c7320d4dd 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1250,6 +1250,7 @@ def check_no_undef_outside_kconfig(self, kconf): "FOO_LOG_LEVEL", "FOO_SETTING_1", "FOO_SETTING_2", + "GEN_UICR_GENERATE_PERIPHCONF", # Used in specialized build tool, not part of main Kconfig "HEAP_MEM_POOL_ADD_SIZE_", # Used as an option matching prefix "HUGETLBFS", # Linux, in boards/xtensa/intel_adsp_cavs25/doc "IAR_BUFFERED_WRITE", diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index a7401084ef31e..8a69c65bb2be0 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -433,26 +433,6 @@ def program_hex(self): core='Application', ) - if self.build_conf.getboolean("CONFIG_NRF_HALTIUM_GENERATE_UICR"): - zephyr_build_dir = Path(self.cfg.build_dir) / 'zephyr' - - self.op_program( - str(zephyr_build_dir / 'uicr.hex'), - 'ERASE_NONE', - None, - defer=True, - core='Application', - ) - - if self.build_conf.getboolean("CONFIG_NRF_HALTIUM_UICR_PERIPHCONF"): - self.op_program( - str(zephyr_build_dir / 'periphconf.hex'), - 'ERASE_NONE', - None, - defer=True, - core='Application', - ) - if not self.erase and regtool_generated_uicr: self.exec_op('erase', core=core, kind='uicr') else: diff --git a/soc/nordic/Kconfig.sysbuild b/soc/nordic/Kconfig.sysbuild index a726d20c464be..040a04203bf11 100644 --- a/soc/nordic/Kconfig.sysbuild +++ b/soc/nordic/Kconfig.sysbuild @@ -4,5 +4,6 @@ config HAS_NORDIC_VPR_LAUNCHER_IMAGE bool +rsource "common/uicr/Kconfig.sysbuild" rsource "common/vpr/Kconfig.sysbuild" orsource "*/Kconfig.sysbuild" diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index 825be4842fb72..04f0c1a3219c4 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -3,9 +3,7 @@ add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) -if(CONFIG_NRF_PERIPHCONF_SECTION OR CONFIG_NRF_HALTIUM_GENERATE_UICR) - add_subdirectory(uicr) -endif() +add_subdirectory(uicr) # Let SystemInit() be called in place of soc_reset_hook() by default. zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") diff --git a/soc/nordic/common/uicr/CMakeLists.txt b/soc/nordic/common/uicr/CMakeLists.txt index 0bde6b47f5766..1ec3a35c56658 100644 --- a/soc/nordic/common/uicr/CMakeLists.txt +++ b/soc/nordic/common/uicr/CMakeLists.txt @@ -4,33 +4,3 @@ if(CONFIG_NRF_PERIPHCONF_SECTION) zephyr_linker_sources(SECTIONS uicr.ld) endif() - -if(CONFIG_NRF_HALTIUM_GENERATE_UICR) - if(CONFIG_NRF_PERIPHCONF_SECTION) - set(in_periphconf_elf_arg - --in-periphconf-elf $ - ) - endif() - - if(CONFIG_NRF_HALTIUM_UICR_PERIPHCONF) - set(periphconf_hex_file ${PROJECT_BINARY_DIR}/periphconf.hex) - set(out_periphconf_hex_arg - --out-periphconf-hex ${periphconf_hex_file} - ) - list(APPEND optional_byproducts ${periphconf_hex_file}) - endif() - - set(uicr_hex_file ${PROJECT_BINARY_DIR}/uicr.hex) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/gen_uicr.py - --in-config ${DOTCONFIG} - --in-edt-pickle ${EDT_PICKLE} - ${in_periphconf_elf_arg} - ${out_periphconf_hex_arg} - --out-uicr-hex ${uicr_hex_file} - ) - set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts - ${uicr_hex_file} ${optional_byproducts} - ) -endif() diff --git a/soc/nordic/common/uicr/Kconfig b/soc/nordic/common/uicr/Kconfig index f132510a7a5d0..3c4c6c8219b6b 100644 --- a/soc/nordic/common/uicr/Kconfig +++ b/soc/nordic/common/uicr/Kconfig @@ -1,29 +1,9 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config NRF_HALTIUM_GENERATE_UICR - bool "Generate UICR file" - depends on SOC_NRF54H20_CPUAPP - default y - help - Generate UICR HEX file. - -if NRF_HALTIUM_GENERATE_UICR - -config NRF_HALTIUM_UICR_PERIPHCONF - bool "Initialize global domain peripherals" - default y - help - Generates a blob containing static global domain peripheral initialization - values extracted from the build artifacts, and configures UICR.PERIPHCONF - to point at the blob. The initialization values are then loaded ahead of - ahead of the application boot. - -endif - config NRF_PERIPHCONF_SECTION bool "Populate global peripheral initialization section" - default y if SOC_NRF54H20_CPUAPP + default y if SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD depends on LINKER_DEVNULL_SUPPORT imply LINKER_DEVNULL_MEMORY help diff --git a/soc/nordic/common/uicr/Kconfig.sysbuild b/soc/nordic/common/uicr/Kconfig.sysbuild new file mode 100644 index 0000000000000..eb885beaaaf7d --- /dev/null +++ b/soc/nordic/common/uicr/Kconfig.sysbuild @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config NRF_HALTIUM_GENERATE_UICR + bool "Generate UICR file" + depends on SOC_SERIES_NRF54HX + default y + help + Generate UICR HEX file. diff --git a/soc/nordic/common/uicr/gen_uicr.py b/soc/nordic/common/uicr/gen_uicr.py index 5888786e928fe..9914a8515a8d5 100644 --- a/soc/nordic/common/uicr/gen_uicr.py +++ b/soc/nordic/common/uicr/gen_uicr.py @@ -7,11 +7,7 @@ import argparse import ctypes as c -import math -import pickle -import re import sys -from collections import defaultdict from itertools import groupby from elftools.elf.elffile import ELFFile @@ -25,11 +21,6 @@ # Must match the name used in the linker script. PERIPHCONF_SECTION = "uicr_periphconf_entry" -# Expected nodelabel of the UICR devicetree node, used to extract its location from the devicetree. -UICR_NODELABEL = "uicr" -# Nodelabel of the PERIPHCONF devicetree node, used to extract its location from the devicetree. -PERIPHCONF_NODELABEL = "periphconf_partition" - # Common values for representing enabled/disabled in the UICR format. ENABLED_VALUE = 0xFFFF_FFFF DISABLED_VALUE = 0xBD23_28A8 @@ -141,18 +132,6 @@ def main() -> None: "peripherals, and to protect the device in various ways." ), ) - parser.add_argument( - "--in-config", - required=True, - type=argparse.FileType("r"), - help="Path to the .config file from the application build", - ) - parser.add_argument( - "--in-edt-pickle", - required=True, - type=argparse.FileType("rb"), - help="Path to the edt.pickle file from the application build", - ) parser.add_argument( "--in-periphconf-elf", dest="in_periphconf_elfs", @@ -165,71 +144,103 @@ def main() -> None: "by ascending address and cleared of duplicate entries." ), ) + parser.add_argument( + "--out-merged-hex", + required=True, + type=argparse.FileType("w", encoding="utf-8"), + help="Path to write the merged UICR+PERIPHCONF HEX file to", + ) parser.add_argument( "--out-uicr-hex", required=True, type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the generated UICR HEX file to", + help="Path to write the UICR-only HEX file to", ) parser.add_argument( "--out-periphconf-hex", - default=None, type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the generated PERIPHCONF HEX file to", + help="Path to write the PERIPHCONF-only HEX file to", + ) + parser.add_argument( + "--periphconf-address", + default=None, + type=lambda s: int(s, 0), + help="Absolute flash address of the PERIPHCONF partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--periphconf-size", + default=None, + type=lambda s: int(s, 0), + help="Size in bytes of the PERIPHCONF partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--uicr-address", + required=True, + type=lambda s: int(s, 0), + help="Absolute flash address of the UICR region (decimal or 0x-prefixed hex)", ) args = parser.parse_args() try: + # Validate argument dependencies + if args.out_periphconf_hex: + if args.periphconf_address is None: + raise ScriptError( + "--periphconf-address is required when --out-periphconf-hex is used" + ) + if args.periphconf_size is None: + raise ScriptError("--periphconf-size is required when --out-periphconf-hex is used") + init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4) uicr = Uicr.from_buffer_copy(init_values) uicr.VERSION.MAJOR = UICR_FORMAT_VERSION_MAJOR uicr.VERSION.MINOR = UICR_FORMAT_VERSION_MINOR - kconfig_str = args.in_config.read() - kconfig = parse_kconfig(kconfig_str) + # Process periphconf data first and configure UICR completely before creating hex objects + periphconf_hex = IntelHex() - edt = pickle.load(args.in_edt_pickle) + if args.out_periphconf_hex: + periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs) - try: - periphconf_partition = edt.label2node[PERIPHCONF_NODELABEL] - except LookupError as e: - raise ScriptError( - "Failed to find a PERIPHCONF partition in the devicetree. " - f"Expected a DT node with label '{PERIPHCONF_NODELABEL}'." - ) from e + padding_len = args.periphconf_size - len(periphconf_combined) + periphconf_final = periphconf_combined + bytes([0xFF for _ in range(padding_len)]) - flash_base_address = periphconf_partition.flash_controller.regs[0].addr - periphconf_address = flash_base_address + periphconf_partition.regs[0].addr - periphconf_size = periphconf_partition.regs[0].size + # Add periphconf data to periphconf hex object + periphconf_hex.frombytes(periphconf_final, offset=args.periphconf_address) - periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs) - padding_len = periphconf_size - len(periphconf_combined) - periphconf_final = periphconf_combined + bytes([0xFF for _ in range(padding_len)]) - - if kconfig.get("CONFIG_NRF_HALTIUM_UICR_PERIPHCONF") == "y": + # Configure UICR with periphconf settings uicr.PERIPHCONF.ENABLE = ENABLED_VALUE - uicr.PERIPHCONF.ADDRESS = periphconf_address - uicr.PERIPHCONF.MAXCOUNT = math.floor(periphconf_size / 8) + uicr.PERIPHCONF.ADDRESS = args.periphconf_address + + # MAXCOUNT is given in number of 8-byte peripheral + # configuration entries and periphconf_size is given in + # bytes. When setting MAXCOUNT based on the + # periphconf_size we must first assert that + # periphconf_size has not been misconfigured. + if args.periphconf_size % 8 != 0: + raise ScriptError( + f"args.periphconf_size was {args.periphconf_size}, but must be divisible by 8" + ) - try: - uicr_node = edt.label2node[UICR_NODELABEL] - except LookupError as e: - raise ScriptError( - "Failed to find UICR node in the devicetree. " - f"Expected a DT node with label '{UICR_NODELABEL}'." - ) from e + uicr.PERIPHCONF.MAXCOUNT = args.periphconf_size // 8 + # Create UICR hex object with final UICR data uicr_hex = IntelHex() - uicr_hex.frombytes(bytes(uicr), offset=uicr_node.regs[0].addr) + uicr_hex.frombytes(bytes(uicr), offset=args.uicr_address) - uicr_hex.write_hex_file(args.out_uicr_hex) + # Create merged hex by combining UICR and periphconf hex objects + merged_hex = IntelHex() + merged_hex.fromdict(uicr_hex.todict()) - if args.out_periphconf_hex is not None: - periphconf_hex = IntelHex() - periphconf_hex.frombytes(periphconf_final, offset=periphconf_address) + if args.out_periphconf_hex: periphconf_hex.write_hex_file(args.out_periphconf_hex) + merged_hex.fromdict(periphconf_hex.todict()) + + merged_hex.write_hex_file(args.out_merged_hex) + uicr_hex.write_hex_file(args.out_uicr_hex) + except ScriptError as e: print(f"Error: {e!s}") sys.exit(1) @@ -270,16 +281,5 @@ def extract_and_combine_periphconfs(elf_files: list[argparse.FileType]) -> bytes return bytes(final_periphconf) -def parse_kconfig(content: str) -> dict[str, str | None]: - result = defaultdict(None) - match_iter = re.finditer( - r"^(?P(SB_)?CONFIG_[^=\s]+)=(?P[^\s#])+$", content, re.MULTILINE - ) - for match in match_iter: - result[match["config"]] = match["value"] - - return result - - if __name__ == "__main__": main() diff --git a/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt new file mode 100644 index 0000000000000..e0002e4e84726 --- /dev/null +++ b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# The code in this CMakeLists.txt constructs the arguments for gen_uicr.py +# and creates a flashable zephyr.hex file containing UICR data (no C code compiled) +# + +cmake_minimum_required(VERSION 3.20.0) + +# Instead of adding all of Zephyr we add just the subset that is +# required to generate uicr.hex. +# +# The generation of uicr.hex is configured by this image, so we +# include modules from zephyr_default up until kconfig. + +find_package(Zephyr + COMPONENTS zephyr_default:kconfig + REQUIRED HINTS $ENV{ZEPHYR_BASE} + ) + +project(uicr) + +# Function to compute partition absolute address and size from devicetree +function(compute_partition_address_and_size partition_nodelabel output_address_var output_size_var) + dt_nodelabel(partition_path NODELABEL ${partition_nodelabel} REQUIRED) + dt_reg_addr(partition_offset PATH ${partition_path} REQUIRED) + dt_reg_size(partition_size PATH ${partition_path} REQUIRED) + + # Calculate absolute partition address + math(EXPR partition_address "${CONFIG_FLASH_BASE_ADDRESS} + ${partition_offset}" OUTPUT_FORMAT HEXADECIMAL) + + # Set output variables in parent scope + set(${output_address_var} ${partition_address} PARENT_SCOPE) + set(${output_size_var} ${partition_size} PARENT_SCOPE) +endfunction() + +# Use CMAKE_VERBOSE_MAKEFILE to silence an unused-variable warning. +if(CMAKE_VERBOSE_MAKEFILE) +endif() + +set(periphconf_args) +set(periphconf_elfs) +set(merged_hex_file ${APPLICATION_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.hex) +set(uicr_hex_file ${APPLICATION_BINARY_DIR}/zephyr/uicr.hex) +set(periphconf_hex_file ${APPLICATION_BINARY_DIR}/zephyr/periphconf.hex) + +# Get UICR absolute address from this image's devicetree +dt_nodelabel(uicr_path NODELABEL "uicr" REQUIRED) +dt_reg_addr(UICR_ADDRESS PATH ${uicr_path} REQUIRED) + +if(CONFIG_GEN_UICR_GENERATE_PERIPHCONF) + # gen_uicr.py parses all zephyr.elf files. To find these files (which + # have not been built yet) we scan sibling build directories for + # zephyr.dts + get_filename_component(SYSBUILD_DIR ${APPLICATION_BINARY_DIR} DIRECTORY) + file(GLOB _siblings LIST_DIRECTORIES true "${SYSBUILD_DIR}/*") + foreach(_dir ${_siblings}) + get_filename_component(_name ${_dir} NAME) + if(_name STREQUAL "uicr") + # This image is an exception to the rule. It has a zephyr.dts, but + # no zephyr.elf + continue() + endif() + + if(EXISTS ${_dir}/zephyr/zephyr.dts) + list(APPEND periphconf_elfs ${_dir}/zephyr/zephyr.elf) + endif() + endforeach() + + # Compute PERIPHCONF absolute address and size from this image's devicetree + compute_partition_address_and_size("periphconf_partition" PERIPHCONF_ADDRESS PERIPHCONF_SIZE) + + # Set up periphconf arguments for gen_uicr.py + list(APPEND periphconf_args --periphconf-address ${PERIPHCONF_ADDRESS}) + list(APPEND periphconf_args --periphconf-size ${PERIPHCONF_SIZE}) + list(APPEND periphconf_args --out-periphconf-hex ${periphconf_hex_file}) + + foreach(elf ${periphconf_elfs}) + list(APPEND periphconf_args --in-periphconf-elf ${elf}) + endforeach() +endif(CONFIG_GEN_UICR_GENERATE_PERIPHCONF) + +# Generate hex files (merged, uicr-only, and periphconf-only) +add_custom_command( + OUTPUT ${merged_hex_file} ${uicr_hex_file} ${periphconf_hex_file} + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src + ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/soc/nordic/common/uicr/gen_uicr.py + --uicr-address ${UICR_ADDRESS} + --out-merged-hex ${merged_hex_file} + --out-uicr-hex ${uicr_hex_file} + ${periphconf_args} + DEPENDS ${periphconf_elfs} + WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} + COMMENT "Using gen_uicr.py to generate ${merged_hex_file} from ${periphconf_elfs}" +) + +# Add zephyr subdirectory to handle flash configuration with correct paths +add_subdirectory(zephyr) + +add_custom_target(gen_uicr ALL DEPENDS ${merged_hex_file}) diff --git a/soc/nordic/common/uicr/gen_uicr/Kconfig b/soc/nordic/common/uicr/gen_uicr/Kconfig new file mode 100644 index 0000000000000..9d483e737d43d --- /dev/null +++ b/soc/nordic/common/uicr/gen_uicr/Kconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "UICR generator options" + +config GEN_UICR_GENERATE_PERIPHCONF + bool "Generate PERIPHCONF hex alongside UICR" + default y + help + When enabled, the UICR generator will emit periphconf.hex in addition to uicr.hex. + +endmenu + +source "Kconfig.zephyr" diff --git a/soc/nordic/common/uicr/gen_uicr/prj.conf b/soc/nordic/common/uicr/gen_uicr/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/soc/nordic/common/uicr/gen_uicr/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/soc/nordic/common/uicr/gen_uicr/zephyr/CMakeLists.txt b/soc/nordic/common/uicr/gen_uicr/zephyr/CMakeLists.txt new file mode 100644 index 0000000000000..1d02066401611 --- /dev/null +++ b/soc/nordic/common/uicr/gen_uicr/zephyr/CMakeLists.txt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Flash configuration for UICR domain +# This subdirectory ensures runners.yaml is generated in the correct location + +# Manually include board configuration to enable automatic runners.yaml generation +include(${BOARD_DIR}/board.cmake OPTIONAL) + +# Create the runners_yaml_props_target that flash system expects +add_custom_target(runners_yaml_props_target) + +# Set hex_file property to point to zephyr.hex in this directory +set_target_properties(runners_yaml_props_target PROPERTIES + hex_file "zephyr.hex" +) + +# Override the runners.yaml path to use CMAKE_CURRENT_BINARY_DIR instead of PROJECT_BINARY_DIR +# This ensures runners.yaml is generated at build/uicr/zephyr/ where west expects it +set(PROJECT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +# Include flash support to automatically generate runners.yaml +include(${ZEPHYR_BASE}/cmake/flash/CMakeLists.txt) diff --git a/soc/nordic/common/uicr/sysbuild.cmake b/soc/nordic/common/uicr/sysbuild.cmake new file mode 100644 index 0000000000000..167ac7c64a2d1 --- /dev/null +++ b/soc/nordic/common/uicr/sysbuild.cmake @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Add UICR generator as a utility image +ExternalZephyrProject_Add( + APPLICATION uicr + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/gen_uicr +) + +# Ensure UICR is configured and built after the default image so EDT/ELFs exist. +sysbuild_add_dependencies(CONFIGURE uicr ${DEFAULT_IMAGE}) +add_dependencies(uicr ${DEFAULT_IMAGE}) diff --git a/soc/nordic/sysbuild.cmake b/soc/nordic/sysbuild.cmake index 03db1a5ad18e4..631c79d57fc6f 100644 --- a/soc/nordic/sysbuild.cmake +++ b/soc/nordic/sysbuild.cmake @@ -29,3 +29,7 @@ if(SB_CONFIG_VPR_LAUNCHER) sysbuild_cache_set(VAR ${image}_SNIPPET APPEND REMOVE_DUPLICATES ${launcher_snippet}) endif() + +if(SB_CONFIG_NRF_HALTIUM_GENERATE_UICR) + include(${CMAKE_CURRENT_LIST_DIR}/common/uicr/sysbuild.cmake) +endif() From 5ce9d0c621434c4505b63fdd4e5b2c6024bd69cf Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Aug 2025 10:20:31 +0200 Subject: [PATCH 0077/1076] Bluetooth: Controller: Fix extended scanning assert on invalid chan_idx Fix extended scanning assert on invalid chan_idx received in the aux pointer structure. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_scan_aux.c | 3 ++- subsys/bluetooth/controller/ll_sw/pdu.h | 1 + subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 11 ++++++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index 89e5fffc331e9..0680d49fbf261 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -170,7 +170,8 @@ uint8_t lll_scan_aux_setup(struct pdu_adv *pdu, uint8_t pdu_phy, /* No need to scan further if no aux_ptr filled */ aux_ptr = (void *)pri_dptr; if (unlikely(!pri_hdr->aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) || - (PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED))) { + (PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED) || + (aux_ptr->chan_idx >= CHM_USED_COUNT_MAX))) { return 0; } diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index e1edced699787..430704c84514f 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -210,6 +210,7 @@ /* Channel Map Unused channels count minimum */ #define CHM_USED_COUNT_MIN 2U +#define CHM_USED_COUNT_MAX 37U /* Channel Map hop count minimum and maximum */ #define CHM_HOP_COUNT_MIN 5U diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 84f0ff6e2b7e7..5de8457c8d02b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -584,8 +584,9 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) */ if (!aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) || is_scan_req || (PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED) || - (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && - PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) == EXT_ADV_AUX_PHY_LE_CODED)) { + (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && + PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) == EXT_ADV_AUX_PHY_LE_CODED) || + (aux_ptr->chan_idx >= CHM_USED_COUNT_MAX)) { if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) { struct ll_sync_set *sync_set; @@ -1988,9 +1989,9 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) */ if (!aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr) || is_scan_req || (PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) > EXT_ADV_AUX_PHY_LE_CODED) || - (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && - PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) == EXT_ADV_AUX_PHY_LE_CODED)) { - + (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && + PDU_ADV_AUX_PTR_PHY_GET(aux_ptr) == EXT_ADV_AUX_PHY_LE_CODED) || + (aux_ptr->chan_idx >= CHM_USED_COUNT_MAX)) { if (is_scan_req) { LL_ASSERT(chain && chain->rx_last); From 3461135d02f0ed02f2314debf32a3bb12585bd62 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 13 Feb 2025 05:58:58 +0100 Subject: [PATCH 0078/1076] Bluetooth: Controller: Fix assertion in scan aux release Fix assertion under race conditions where LLL scheduling did not have an auxiliary context assigned but when node rx is released an auxiliary context is picked from the scan context that has no parent assigned yet due to a previously assigned auxiliary context to the scan context was not cleared. Relates to commit 49642efa41c8 ("Bluetooth: Controller: Fix regression in scan aux release"). Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_scan_aux.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 5de8457c8d02b..36ca38496c421 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -847,6 +847,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) if (unlikely(scan->is_stop)) { goto ull_scan_aux_rx_flush; } + + /* Remove auxiliary context association with scan context so + * that LLL can differentiate it to being ULL scheduling. + */ + if ((lll != NULL) && (lll->lll_aux == lll_aux)) { + lll->lll_aux = NULL; + } } else { struct ll_sync_set *sync_set; @@ -1423,6 +1430,11 @@ static void flush(void *param) scan = HDR_LLL2ULL(lll); scan = ull_scan_is_valid_get(scan); if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || scan) { + /* Remove auxiliary context association with scan context */ + if (lll->lll_aux == &aux->lll) { + lll->lll_aux = NULL; + } + #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) lll->scan_aux_score = aux->lll.hdr.score; #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ From 028eec235ee485dc087d50a006b7e4251be3a1e3 Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Fri, 22 Aug 2025 06:36:18 +0000 Subject: [PATCH 0079/1076] manifest: Update nrf_wifi revision to fix raw tx Fix TX buffer issue for raw tx. Signed-off-by: Kapil Bhatt --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 1ff129b0a2927..d9d268d771150 100644 --- a/west.yml +++ b/west.yml @@ -334,7 +334,7 @@ manifest: revision: 40403f5f2805cca210d2a47c8717d89c4e816cda path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: 787eea1a3c8dd13c86214e204a919e6f9bcebf91 + revision: 5fffeab6496932abb10f9dae53ed3686967aa050 path: modules/lib/nrf_wifi - name: open-amp revision: c30a6d8b92fcebdb797fc1a7698e8729e250f637 From 092347cdb1ede22061d6affe09ebdf91e8f37626 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Wed, 20 Aug 2025 13:00:23 +0530 Subject: [PATCH 0080/1076] driver: nrf_wifi: TWT setup duration Build time configuration option to set TWT setup duration. If AP does not respond to TWT setup request for this period, STA will timeout and report setup failure. Signed-off-by: Ajay Parida --- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 10 ++++++++++ drivers/wifi/nrf_wifi/src/wifi_mgmt.c | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index 4b3bb0d41ca25..9b37c302872b8 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -934,4 +934,14 @@ config NRF_WIFI_DYNAMIC_ED help This option enables support for proprietary algorithm to enhance performance in high-traffic channels. + +config NRF_WIFI_TWT_SETUP_TIMEOUT_MS + int "TWT setup timeout (ms)" + range 100 10000 + default 250 + help + Timeout duration (in milliseconds) for the TWT setup procedure. + The STA will transmit a TWT setup request every 100 milliseconds, + continuing until this timeout value is reached. If no response is + received before the timeout expires, the TWT setup is considered failed. endif # WIFI_NRF70 diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c index e9755e80013eb..e48ae31734a73 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c @@ -564,6 +564,7 @@ int nrf_wifi_set_twt(const struct device *dev, twt_info.dialog_token = twt_params->dialog_token; twt_info.twt_wake_ahead_duration = twt_params->setup.twt_wake_ahead_duration; + twt_info.twt_req_timeout = CONFIG_NRF_WIFI_TWT_SETUP_TIMEOUT_MS; status = nrf_wifi_sys_fmac_twt_setup(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, From 181e544550d999ef71046b03817c981602309985 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 22 Aug 2025 09:30:13 +0200 Subject: [PATCH 0081/1076] drivers: i2c: stm32: sync stm32_v2 RTIO on PM runtime state Always call pm_device_runtime_get() when registering a target even if the device is not wakeup capable to prevent I2C target not being function if the device goes into a SoC Stop mode. This change ports into the STM32 v2 RTIO driver the change made in the non-RTIO driver through commit 67f80e35b861 ("i2c: stm32: always call runtime_get when registering targets"). Signed-off-by: Etienne Carriere --- drivers/i2c/i2c_ll_stm32_v2_rtio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32_v2_rtio.c b/drivers/i2c/i2c_ll_stm32_v2_rtio.c index 3bb4614b56d3c..971e4c814cc4f 100644 --- a/drivers/i2c/i2c_ll_stm32_v2_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_v2_rtio.c @@ -210,9 +210,10 @@ int i2c_stm32_target_register(const struct device *dev, } #if defined(CONFIG_PM_DEVICE_RUNTIME) + /* Mark device as active */ + (void)pm_device_runtime_get(dev); + if (pm_device_wakeup_is_capable(dev)) { - /* Mark device as active */ - (void)pm_device_runtime_get(dev); /* Enable wake-up from stop */ LOG_DBG("i2c: enabling wakeup from stop"); LL_I2C_EnableWakeUpFromStop(cfg->i2c); @@ -303,11 +304,12 @@ int i2c_stm32_target_unregister(const struct device *dev, /* Disable wake-up from STOP */ LOG_DBG("i2c: disabling wakeup from stop"); LL_I2C_DisableWakeUpFromStop(i2c); - /* Release the device */ - (void)pm_device_runtime_put(dev); } #endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */ + /* Release the device */ + (void)pm_device_runtime_put(dev); + data->slave_attached = false; return 0; From e29ebbe13cb09ab3d0d5c555bedcab278dc1eddc Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 22 Aug 2025 09:33:43 +0200 Subject: [PATCH 0082/1076] drivers: i2c: stm32: drop few redundant guards in RTIO driver Drop few CONFIG_PM_DEVICE_RUNTIME guards, the pm_device_runtime functions they are masking are no-op automatically when the corresponding config option is not selected. This change is related to the change made in the STM32 non-RTIO driver trough commit 4f3523d9afce ("i2c: stm32: drop few redundant guards"). Signed-off-by: Etienne Carriere --- drivers/i2c/i2c_ll_stm32_rtio.c | 2 -- drivers/i2c/i2c_ll_stm32_v2_rtio.c | 4 ---- 2 files changed, 6 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32_rtio.c b/drivers/i2c/i2c_ll_stm32_rtio.c index 6b150c1d5619b..d42c20fc9ded7 100644 --- a/drivers/i2c/i2c_ll_stm32_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_rtio.c @@ -269,9 +269,7 @@ static int i2c_stm32_init(const struct device *dev) return ret; } -#ifdef CONFIG_PM_DEVICE_RUNTIME (void)pm_device_runtime_enable(dev); -#endif return 0; } diff --git a/drivers/i2c/i2c_ll_stm32_v2_rtio.c b/drivers/i2c/i2c_ll_stm32_v2_rtio.c index 971e4c814cc4f..d52b806de1e76 100644 --- a/drivers/i2c/i2c_ll_stm32_v2_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_v2_rtio.c @@ -209,7 +209,6 @@ int i2c_stm32_target_register(const struct device *dev, return ret; } -#if defined(CONFIG_PM_DEVICE_RUNTIME) /* Mark device as active */ (void)pm_device_runtime_get(dev); @@ -218,7 +217,6 @@ int i2c_stm32_target_register(const struct device *dev, LOG_DBG("i2c: enabling wakeup from stop"); LL_I2C_EnableWakeUpFromStop(cfg->i2c); } -#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */ LL_I2C_Enable(i2c); @@ -299,13 +297,11 @@ int i2c_stm32_target_unregister(const struct device *dev, LL_I2C_Disable(i2c); -#if defined(CONFIG_PM_DEVICE_RUNTIME) if (pm_device_wakeup_is_capable(dev)) { /* Disable wake-up from STOP */ LOG_DBG("i2c: disabling wakeup from stop"); LL_I2C_DisableWakeUpFromStop(i2c); } -#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */ /* Release the device */ (void)pm_device_runtime_put(dev); From 5ff3dbeeee2225bf959c1502d2c30f87f9932b86 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 22 Aug 2025 09:43:48 +0200 Subject: [PATCH 0083/1076] drivers: i2c: stm32: exclude stm32f7 family for PM in RTIO driver Exclude STM32F7 SoC series from PM support since that SoC doees not yet manage power management in Zephyr and HAL API functions LL_I2C_EnableWakeUpFromStop() and LL_I2C_DisableWakeUpFromStop() are not implemented in the H7 HAL/LL drivers. This change ports into the STM32 RTIO driver the change made in the non-RTIO driver through commit 1804eb7bc340 ("drivers: i2c: stm32: exclude stm32f7 family for PM"). Signed-off-by: Etienne Carriere --- drivers/i2c/i2c_ll_stm32_v2_rtio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c_ll_stm32_v2_rtio.c b/drivers/i2c/i2c_ll_stm32_v2_rtio.c index d52b806de1e76..269288055ece8 100644 --- a/drivers/i2c/i2c_ll_stm32_v2_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_v2_rtio.c @@ -212,11 +212,13 @@ int i2c_stm32_target_register(const struct device *dev, /* Mark device as active */ (void)pm_device_runtime_get(dev); +#if !defined(CONFIG_SOC_SERIES_STM32F7X) if (pm_device_wakeup_is_capable(dev)) { /* Enable wake-up from stop */ LOG_DBG("i2c: enabling wakeup from stop"); LL_I2C_EnableWakeUpFromStop(cfg->i2c); } +#endif /* !CONFIG_SOC_SERIES_STM32F7X */ LL_I2C_Enable(i2c); @@ -297,11 +299,13 @@ int i2c_stm32_target_unregister(const struct device *dev, LL_I2C_Disable(i2c); +#if !defined(CONFIG_SOC_SERIES_STM32F7X) if (pm_device_wakeup_is_capable(dev)) { /* Disable wake-up from STOP */ LOG_DBG("i2c: disabling wakeup from stop"); LL_I2C_DisableWakeUpFromStop(i2c); } +#endif /* !CONFIG_SOC_SERIES_STM32F7X */ /* Release the device */ (void)pm_device_runtime_put(dev); From ddc4479243180d93c4a453b905e1985194d16333 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Fri, 4 Jul 2025 09:44:18 +0200 Subject: [PATCH 0084/1076] shell: mqtt: use topic levels Change topic from _rx (and tx) to /sh/rx. This allows use of wildcards. E.g. subscribe to all devices "+/sh/tx". Level "sh" is added to the topic to make it less generic and prevent potential clashes with other topics. The topic part after is configurable via Kconfig. Signed-off-by: Jeppe Odgaard --- doc/releases/migration-guide-4.3.rst | 10 ++++++++++ include/zephyr/shell/shell_mqtt.h | 7 ++++--- subsys/shell/backends/Kconfig.backends | 12 ++++++++++++ subsys/shell/backends/shell_mqtt.c | 6 ++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index f4a2b8e383136..1780561878562 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -152,6 +152,16 @@ Logging used. The new script supports the same functionality (and more), but requires different command line arguments when invoked. +Shell +===== + +* The MQTT topics related to :kconfig:option:`SHELL_BACKEND_MQTT` have been renamed. Renamed + ``_rx`` to ``/sh/rx`` and ``_tx`` to ``/sh/rx``. The + part after the ```` is now configurable via :kconfig:option:`SHELL_MQTT_TOPIC_RX_ID` + and :kconfig:option:`SHELL_MQTT_TOPIC_TX_ID`. This allows keeping the previous topics for backward + compatibility. + (:github:`92677`). + .. zephyr-keep-sorted-stop Modules diff --git a/include/zephyr/shell/shell_mqtt.h b/include/zephyr/shell/shell_mqtt.h index 92ce6987efefc..4a96f9f0eac5d 100644 --- a/include/zephyr/shell/shell_mqtt.h +++ b/include/zephyr/shell/shell_mqtt.h @@ -25,7 +25,8 @@ extern "C" { #define SH_MQTT_BUFFER_SIZE 64 #define DEVICE_ID_BIN_MAX_SIZE 3 #define DEVICE_ID_HEX_MAX_SIZE ((DEVICE_ID_BIN_MAX_SIZE * 2) + 1) -#define SH_MQTT_TOPIC_MAX_SIZE DEVICE_ID_HEX_MAX_SIZE + 3 +#define SH_MQTT_TOPIC_RX_MAX_SIZE DEVICE_ID_HEX_MAX_SIZE + sizeof(CONFIG_SHELL_MQTT_TOPIC_RX_ID) +#define SH_MQTT_TOPIC_TX_MAX_SIZE DEVICE_ID_HEX_MAX_SIZE + sizeof(CONFIG_SHELL_MQTT_TOPIC_TX_ID) extern const struct shell_transport_api shell_mqtt_transport_api; @@ -40,8 +41,8 @@ struct shell_mqtt_tx_buf { /** MQTT-based shell transport. */ struct shell_mqtt { char device_id[DEVICE_ID_HEX_MAX_SIZE]; - char sub_topic[SH_MQTT_TOPIC_MAX_SIZE]; - char pub_topic[SH_MQTT_TOPIC_MAX_SIZE]; + char sub_topic[SH_MQTT_TOPIC_RX_MAX_SIZE]; + char pub_topic[SH_MQTT_TOPIC_TX_MAX_SIZE]; /** Handler function registered by shell. */ shell_transport_handler_t shell_handler; diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index c68ec201197c2..7973b4586b161 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -348,6 +348,18 @@ config SHELL_MQTT_LISTEN_TIMEOUT_MS help Time to listen for incoming packets in milliseconds. +config SHELL_MQTT_TOPIC_RX_ID + string "MQTT topic receive identifier" + default "/sh/rx" + help + String used as receive identifier in the MQTT topic. + +config SHELL_MQTT_TOPIC_TX_ID + string "MQTT topic transmit identifier" + default "/sh/tx" + help + String used as transmit identifier in the MQTT topic. + module = SHELL_BACKEND_MQTT default-timeout = 100 source "subsys/shell/Kconfig.template.shell_log_queue_timeout" diff --git a/subsys/shell/backends/shell_mqtt.c b/subsys/shell/backends/shell_mqtt.c index dcc7f83812e2f..7588fa25a012a 100644 --- a/subsys/shell/backends/shell_mqtt.c +++ b/subsys/shell/backends/shell_mqtt.c @@ -657,8 +657,10 @@ static int init(const struct shell_transport *transport, const void *config, LOG_DBG("Client ID is %s", sh->device_id); - (void)snprintf(sh->pub_topic, SH_MQTT_TOPIC_MAX_SIZE, "%s_tx", sh->device_id); - (void)snprintf(sh->sub_topic, SH_MQTT_TOPIC_MAX_SIZE, "%s_rx", sh->device_id); + (void)snprintf(sh->pub_topic, SH_MQTT_TOPIC_TX_MAX_SIZE, "%s" CONFIG_SHELL_MQTT_TOPIC_TX_ID, + sh->device_id); + (void)snprintf(sh->sub_topic, SH_MQTT_TOPIC_RX_MAX_SIZE, "%s" CONFIG_SHELL_MQTT_TOPIC_RX_ID, + sh->device_id); ring_buf_init(&sh->rx_rb, RX_RB_SIZE, sh->rx_rb_buf); From a8c8f7f2b81d0dcb5d5f48492723c457fc76af31 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Fri, 8 Aug 2025 11:41:20 +0200 Subject: [PATCH 0085/1076] shell: mqtt: select NET_CONNECTION_MANAGER Replace `select NET_MGMT` and `select NET_MGMT_EVENT` with `select NET_CONNECTION_MANAGER` to get L4 events. Signed-off-by: Jeppe Odgaard --- subsys/shell/backends/Kconfig.backends | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/shell/backends/Kconfig.backends b/subsys/shell/backends/Kconfig.backends index 7973b4586b161..ebeb4792bf19d 100644 --- a/subsys/shell/backends/Kconfig.backends +++ b/subsys/shell/backends/Kconfig.backends @@ -288,8 +288,7 @@ config SHELL_BACKEND_MQTT select DNS_RESOLVER select HWINFO select MQTT_LIB - select NET_MGMT - select NET_MGMT_EVENT + select NET_CONNECTION_MANAGER help Enable MQTT backend. From 33da9bfd926dc71af28b043c1bda900cb5f91d27 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Fri, 22 Aug 2025 15:12:17 +0200 Subject: [PATCH 0086/1076] drivers: spi: silabs: Add missing iodev_submit implementation Series 2 EUSART and SiWx91x GSPI drivers were missing the `iodev_submit` member from their API structs, leading to null pointer dereference if CONFIG_SPI_RTIO was used. Signed-off-by: Aksel Skauge Mellbye --- drivers/spi/spi_silabs_eusart.c | 4 ++++ drivers/spi/spi_silabs_siwx91x_gspi.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/spi/spi_silabs_eusart.c b/drivers/spi/spi_silabs_eusart.c index 71fedef029230..49963776247f6 100644 --- a/drivers/spi/spi_silabs_eusart.c +++ b/drivers/spi/spi_silabs_eusart.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -728,6 +729,9 @@ static DEVICE_API(spi, spi_silabs_eusart_api) = { .transceive = spi_silabs_eusart_transceive_sync, #ifdef CONFIG_SPI_ASYNC .transceive_async = spi_silabs_eusart_transceive_async, +#endif +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, #endif .release = spi_silabs_eusart_release, }; diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 79d5f7b81bd6e..2fb7e06dd549f 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -624,6 +625,9 @@ static DEVICE_API(spi, gspi_siwx91x_driver_api) = { .transceive = gspi_siwx91x_transceive_sync, #ifdef CONFIG_SPI_ASYNC .transceive_async = gspi_siwx91x_transceive_async, +#endif +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, #endif .release = gspi_siwx91x_release, }; From ebab75bb73a852c18dbd4a84f553ef3d01064fee Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Tue, 5 Nov 2024 17:20:49 -0800 Subject: [PATCH 0087/1076] nvs: support sector_size of 64KB Allows NVS to work with flash device configured to use only 64KB block erase. Due to how addresses are encoded internally in NVS, 64KB is the maximum sector size. Add a test for this during mount. Add a native_sim unit test case for 64kb erase block size Signed-off-by: Mike J. Chen --- include/zephyr/fs/nvs.h | 2 +- subsys/fs/nvs/nvs.c | 7 ++++ subsys/fs/nvs/nvs_priv.h | 2 + .../native_sim_64kb_erase_block.overlay | 41 +++++++++++++++++++ tests/subsys/fs/nvs/src/main.c | 37 +++++++++++++---- tests/subsys/fs/nvs/testcase.yaml | 3 ++ 6 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 tests/subsys/fs/nvs/boards/native_sim_64kb_erase_block.overlay diff --git a/include/zephyr/fs/nvs.h b/include/zephyr/fs/nvs.h index df70b64f58bce..f654933166f9e 100644 --- a/include/zephyr/fs/nvs.h +++ b/include/zephyr/fs/nvs.h @@ -48,7 +48,7 @@ struct nvs_fs { /** Data write address */ uint32_t data_wra; /** File system is split into sectors, each sector must be multiple of erase-block-size */ - uint16_t sector_size; + uint32_t sector_size; /** Number of sectors in the file system */ uint16_t sector_count; /** Flag indicating if the file system is initialized */ diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 2e553fdbf554f..8a710d570fb12 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -1025,6 +1025,13 @@ int nvs_mount(struct nvs_fs *fs) return -EINVAL; } + /* check that sector size is not greater than max */ + if (fs->sector_size > NVS_MAX_SECTOR_SIZE) { + LOG_ERR("Sector size %u too large, maximum is %zu", + fs->sector_size, NVS_MAX_SECTOR_SIZE); + return -EINVAL; + } + /* check that sector size is a multiple of pagesize */ rc = flash_get_page_info_by_offs(fs->flash_device, fs->offset, &info); if (rc) { diff --git a/subsys/fs/nvs/nvs_priv.h b/subsys/fs/nvs/nvs_priv.h index 53f109ee13201..0c302d132f6ca 100644 --- a/subsys/fs/nvs/nvs_priv.h +++ b/subsys/fs/nvs/nvs_priv.h @@ -21,6 +21,8 @@ extern "C" { #define ADDR_SECT_SHIFT 16 #define ADDR_OFFS_MASK 0x0000FFFF +#define NVS_MAX_SECTOR_SIZE KB(64) + /* * Status return values */ diff --git a/tests/subsys/fs/nvs/boards/native_sim_64kb_erase_block.overlay b/tests/subsys/fs/nvs/boards/native_sim_64kb_erase_block.overlay new file mode 100644 index 0000000000000..2079b50ceab20 --- /dev/null +++ b/tests/subsys/fs/nvs/boards/native_sim_64kb_erase_block.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + erase-block-size = <0x10000>; + + /* + * Delete old partitions that were not aligned on 64kb addresses and + * create new ones that are aligned. + */ + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00070000>; + }; + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 0x00070000>; + }; + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0x00020000>; + }; + storage_partition: partition@110000 { + label = "storage"; + reg = <0x00110000 0x00050000>; + }; + }; +}; diff --git a/tests/subsys/fs/nvs/src/main.c b/tests/subsys/fs/nvs/src/main.c index a3d35ca823edf..3d2254ada9294 100644 --- a/tests/subsys/fs/nvs/src/main.c +++ b/tests/subsys/fs/nvs/src/main.c @@ -96,7 +96,14 @@ ZTEST_SUITE(nvs, NULL, setup, before, after, NULL); ZTEST_F(nvs, test_nvs_mount) { int err; + size_t orig_sector_size = fixture->fs.sector_size; + fixture->fs.sector_size = KB(128); + err = nvs_mount(&fixture->fs); + zassert_true(err == -EINVAL, + "nvs_mount did not return expected err for invalid sector_size"); + + fixture->fs.sector_size = orig_sector_size; err = nvs_mount(&fixture->fs); zassert_true(err == 0, "nvs_mount call failure: %d", err); } @@ -307,7 +314,7 @@ static void write_content(uint16_t max_id, uint16_t begin, uint16_t end, for (uint16_t i = begin; i < end; i++) { uint8_t id = (i % max_id); - uint8_t id_data = id + max_id * (i / max_id); + uint8_t id_data = id + max_id * ((i % 256) / max_id); memset(buf, id_data, sizeof(buf)); @@ -346,13 +353,25 @@ ZTEST_F(nvs, test_nvs_gc_3sectors) const uint16_t max_id = 10; /* 50th write will trigger 1st GC. */ - const uint16_t max_writes = 51; + uint16_t max_writes = 51; /* 75th write will trigger 2st GC. */ - const uint16_t max_writes_2 = 51 + 25; + uint16_t max_writes_2 = 51 + 25; /* 100th write will trigger 3st GC. */ - const uint16_t max_writes_3 = 51 + 25 + 25; + uint16_t max_writes_3 = 51 + 25 + 25; /* 125th write will trigger 4st GC. */ - const uint16_t max_writes_4 = 51 + 25 + 25 + 25; + uint16_t max_writes_4 = 51 + 25 + 25 + 25; + + if (fixture->fs.sector_size == KB(64)) { + /* write 1637 will trigger 1st GC. */ + /* write 3274 will trigger 2nd GC. */ + max_writes = 3275; + /* write 4911 will trigger 3rd GC. */ + max_writes_2 = 3275 + 1637; + /* write 6548 will trigger 4th GC. */ + max_writes_3 = 3275 + 1637 + 1637; + /* write 8185 will trigger 5th GC. */ + max_writes_4 = 3275 + 1637 + 1637 + 1637; + } fixture->fs.sector_count = 3; @@ -361,7 +380,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors) zassert_equal(fixture->fs.ate_wra >> ADDR_SECT_SHIFT, 0, "unexpected write sector"); - /* Trigger 1st GC */ + /* Trigger 1st and 2nd GC */ write_content(max_id, 0, max_writes, &fixture->fs); /* sector sequence: empty,closed, write */ @@ -376,7 +395,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors) "unexpected write sector"); check_content(max_id, &fixture->fs); - /* Trigger 2nd GC */ + /* Trigger 3rd GC */ write_content(max_id, max_writes, max_writes_2, &fixture->fs); /* sector sequence: write, empty, closed */ @@ -391,7 +410,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors) "unexpected write sector"); check_content(max_id, &fixture->fs); - /* Trigger 3rd GC */ + /* Trigger 4th GC */ write_content(max_id, max_writes_2, max_writes_3, &fixture->fs); /* sector sequence: closed, write, empty */ @@ -406,7 +425,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors) "unexpected write sector"); check_content(max_id, &fixture->fs); - /* Trigger 4th GC */ + /* Trigger 5th GC */ write_content(max_id, max_writes_3, max_writes_4, &fixture->fs); /* sector sequence: empty,closed, write */ diff --git a/tests/subsys/fs/nvs/testcase.yaml b/tests/subsys/fs/nvs/testcase.yaml index c796cda1307b0..34b28ab30e623 100644 --- a/tests/subsys/fs/nvs/testcase.yaml +++ b/tests/subsys/fs/nvs/testcase.yaml @@ -28,3 +28,6 @@ tests: - CONFIG_NVS_LOOKUP_CACHE=y - CONFIG_NVS_LOOKUP_CACHE_SIZE=64 platform_allow: native_sim + filesystem.nvs.64kb_erase_block: + extra_args: DTC_OVERLAY_FILE=boards/native_sim_64kb_erase_block.overlay + platform_allow: native_sim From 3a8846e947cf5140a4983f192583588aae017149 Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Fri, 22 Aug 2025 15:15:46 +0200 Subject: [PATCH 0088/1076] Bluetooth: Document bt_conn_le_cs_mode and clarify encoding notes Add API documentation for `bt_conn_le_cs_mode` and internal extractors for main and sub-mode parts. Clarify that the enum values are an internal encoding, not a stable API, and that the sub-mode extractor maps 0 to HCI 0xFF (unused) for a compact representation. Also mark the extractors as private helpers and tighten wording for developer clarity. Signed-off-by: Aleksander Wasaznik --- include/zephyr/bluetooth/conn.h | 50 ++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index b1b7377ba5117..7af6d1efca319 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -519,24 +519,60 @@ struct bt_conn_le_cs_fae_table { int8_t *remote_fae_table; }; +/** @brief Extract main mode part from @ref bt_conn_le_cs_mode + * + * @private + * + * @param x @ref bt_conn_le_cs_mode value + * @retval 1 Matches @ref BT_HCI_OP_LE_CS_MAIN_MODE_1 (0x01) + * @retval 2 Matches @ref BT_HCI_OP_LE_CS_MAIN_MODE_2 (0x02) + * @retval 3 Matches @ref BT_HCI_OP_LE_CS_MAIN_MODE_3 (0x03) + * + * @note Returned values match the HCI main mode values. + */ #define BT_CONN_LE_CS_MODE_MAIN_MODE_PART(x) ((x) & 0x3) + +/** @brief Extract sub-mode part from @ref bt_conn_le_cs_mode + * + * @private + * + * @param x @ref bt_conn_le_cs_mode value + * @retval 0 Internal encoding for @ref BT_HCI_OP_LE_CS_SUB_MODE_UNUSED (0xFF) + * @retval 1 Matches @ref BT_HCI_OP_LE_CS_SUB_MODE_1 (0x01) + * @retval 2 Matches @ref BT_HCI_OP_LE_CS_SUB_MODE_2 (0x02) + * @retval 3 Matches @ref BT_HCI_OP_LE_CS_SUB_MODE_3 (0x03) + * + * @note The value 0 encodes HCI 0xFF. This allows @ref bt_conn_le_cs_mode to + * fit in one byte. To obtain the HCI sub-mode value, use `(sub_mode == 0 ? 0xFF + * : sub_mode)`, where `sub_mode` is the value returned by this macro. + */ #define BT_CONN_LE_CS_MODE_SUB_MODE_PART(x) (((x) >> 4) & 0x3) -/** Channel sounding main and sub mode */ +/** @brief Channel sounding mode (main and sub-mode) + * + * Represents the combination of Channel Sounding (CS) main mode and sub-mode. + * + * @note The underlying numeric values are an internal encoding and are + * not stable API. Do not assume a direct concatenation of HCI values + * when inspecting the raw enum value. + * + * @sa BT_CONN_LE_CS_MODE_MAIN_MODE_PART + * @sa BT_CONN_LE_CS_MODE_SUB_MODE_PART + */ enum bt_conn_le_cs_mode { - /** Mode-1 (RTT) Main Mode, Unused Sub Mode */ + /** Main mode 1 (RTT), sub-mode: unused */ BT_CONN_LE_CS_MAIN_MODE_1_NO_SUB_MODE = BT_HCI_OP_LE_CS_MAIN_MODE_1, - /** Mode-2 (PBR) Main Mode, Unused Sub Mode */ + /** Main mode 2 (PBR), sub-mode: unused */ BT_CONN_LE_CS_MAIN_MODE_2_NO_SUB_MODE = BT_HCI_OP_LE_CS_MAIN_MODE_2, - /** Mode-3 (RTT and PBR) Main Mode, Unused Sub Mode */ + /** Main mode 3 (RTT and PBR), sub-mode: unused */ BT_CONN_LE_CS_MAIN_MODE_3_NO_SUB_MODE = BT_HCI_OP_LE_CS_MAIN_MODE_3, - /** Mode-2 (PBR) Main Mode, Mode-1 (RTT) Sub Mode */ + /** Main mode 2 (PBR), sub-mode 1 (RTT) */ BT_CONN_LE_CS_MAIN_MODE_2_SUB_MODE_1 = BT_HCI_OP_LE_CS_MAIN_MODE_2 | (BT_HCI_OP_LE_CS_SUB_MODE_1 << 4), - /** Mode-2 (PBR) Main Mode, Mode-3 (RTT and PBR) Sub Mode */ + /** Main mode 2 (PBR), sub-mode 3 (RTT and PBR) */ BT_CONN_LE_CS_MAIN_MODE_2_SUB_MODE_3 = BT_HCI_OP_LE_CS_MAIN_MODE_2 | (BT_HCI_OP_LE_CS_SUB_MODE_3 << 4), - /** Mode-3 (RTT and PBR) Main Mode, Mode-2 (PBR) Sub Mode */ + /** Main mode 3 (RTT and PBR), sub-mode 2 (PBR) */ BT_CONN_LE_CS_MAIN_MODE_3_SUB_MODE_2 = BT_HCI_OP_LE_CS_MAIN_MODE_3 | (BT_HCI_OP_LE_CS_SUB_MODE_2 << 4), }; From 7f68a73c8e4db94e83e3bde78bb03133db590e63 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:05:29 -0300 Subject: [PATCH 0089/1076] west.yml: hal_espressif: Update for ESP32-H2 support Update HAL for ESP32-H2 support. Signed-off-by: Raffael Rostagno --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d9d268d771150..57a41bb050324 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: aa5443a4eea6a49d58f808f41bceb5de19678fa6 + revision: b04879d5bfc73eaed2a00e6827f346a9c2b88d5c path: modules/hal/espressif west-commands: west/west-commands.yml groups: From 5a84b68e61a4158e8b70cd9095afad698ce82bd1 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:39:45 -0300 Subject: [PATCH 0090/1076] bindings: clock: intmux: pinctrl: esp32h2: Add defines Add defines for clock, interrupt management and pin control. Signed-off-by: Raffael Rostagno --- .../zephyr/dt-bindings/clock/esp32h2_clock.h | 89 ++++ .../interrupt-controller/esp-esp32h2-intmux.h | 82 +++ .../dt-bindings/pinctrl/esp32h2-gpio-sigmap.h | 260 ++++++++++ .../dt-bindings/pinctrl/esp32h2-pinctrl.h | 480 ++++++++++++++++++ 4 files changed, 911 insertions(+) create mode 100644 include/zephyr/dt-bindings/clock/esp32h2_clock.h create mode 100644 include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h create mode 100644 include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h create mode 100644 include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h diff --git a/include/zephyr/dt-bindings/clock/esp32h2_clock.h b/include/zephyr/dt-bindings/clock/esp32h2_clock.h new file mode 100644 index 0000000000000..0ef72eb34e65f --- /dev/null +++ b/include/zephyr/dt-bindings/clock/esp32h2_clock.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ + +/* Supported CPU clock Sources */ +#define ESP32_CPU_CLK_SRC_XTAL 0U +#define ESP32_CPU_CLK_SRC_PLL 1U +#define ESP32_CLK_SRC_RC_FAST 2U +#define ESP32_CPU_CLK_SRC_FLASH_PLL 3U + +/* Supported CPU frequencies */ +#define ESP32_CLK_CPU_PLL_48M 48000000 +#define ESP32_CLK_CPU_FLASH_PLL_64M 64000000 +#define ESP32_CLK_CPU_PLL_96M 96000000 +#define ESP32_CLK_CPU_RC_FAST_FREQ 8500000 + +/* Supported XTAL Frequencies */ +#define ESP32_CLK_XTAL_32M 32000000 + +/* Supported RTC fast clock sources */ +#define ESP32_RTC_FAST_CLK_SRC_RC_FAST 0 +#define ESP32_RTC_FAST_CLK_SRC_XTAL_D2 1 + +/* Supported RTC slow clock frequencies */ +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW 0 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K 1 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K 2 +#define ESP32_RTC_SLOW_CLK_32K_EXT_OSC 9 + +/* RTC slow clock frequencies */ +#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ 136000 +#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K_FREQ 32768 +#define ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ 32768 + +/* Modules IDs + * These IDs are actually offsets in CLK and RST Control registers. + * These IDs shouldn't be changed unless there is a Hardware change + * from Espressif. + * + * Basic Modules + * Registers: DPORT_PERIP_CLK_EN_REG, DPORT_PERIP_RST_EN_REG + */ +#define ESP32_LEDC_MODULE 0 +#define ESP32_UART0_MODULE 1 +#define ESP32_UART1_MODULE 2 +#define ESP32_USB_DEVICE_MODULE 3 +#define ESP32_I2C0_MODULE 4 +#define ESP32_I2C1_MODULE 5 +#define ESP32_I2S1_MODULE 6 +#define ESP32_TIMG0_MODULE 7 +#define ESP32_TIMG1_MODULE 8 +#define ESP32_UHCI0_MODULE 9 +#define ESP32_RMT_MODULE 10 +#define ESP32_PCNT_MODULE 11 +#define ESP32_SPI_MODULE 12 +#define ESP32_SPI2_MODULE 13 +#define ESP32_TWAI0_MODULE 14 +#define ESP32_RNG_MODULE 15 +#define ESP32_RSA_MODULE 16 +#define ESP32_AES_MODULE 17 +#define ESP32_SHA_MODULE 18 +#define ESP32_ECC_MODULE 19 +#define ESP32_HMAC_MODULE 20 +#define ESP32_DS_MODULE 21 +#define ESP32_ECDSA_MODULE 22 +#define ESP32_GDMA_MODULE 23 +#define ESP32_MCPWM0_MODULE 24 +#define ESP32_ETM_MODULE 25 +#define ESP32_PARLIO_MODULE 26 +#define ESP32_SYSTIMER_MODULE 27 +#define ESP32_SARADC_MODULE 28 +#define ESP32_TEMPSENSOR_MODULE 29 +#define ESP32_REGDMA_MODULE 30 +/* Peripherals clock managed by the modem_clock driver must be listed last */ +#define ESP32_BT_MODULE 31 +#define ESP32_IEEE802154_MODULE 32 +#define ESP32_COEX_MODULE 33 +#define ESP32_PHY_MODULE 34 +#define ESP32_ANA_I2C_MASTER_MODULE 35 +#define ESP32_MODEM_ETM_MODULE 36 +#define ESP32_MODEM_ADC_COMMON_FE_MODULE 37 +#define ESP32_MODULE_MAX 38 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32H2_H_ */ diff --git a/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h new file mode 100644 index 0000000000000..febe62c3ce060 --- /dev/null +++ b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32h2-intmux.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ + +#define PMU_INTR_SOURCE 0 +#define EFUSE_INTR_SOURCE 1 +#define LP_RTC_TIMER_INTR_SOURCE 2 +#define LP_BLE_TIMER_INTR_SOURCE 3 +#define LP_WDT_INTR_SOURCE 4 +#define LP_PERI_TIMEOUT_INTR_SOURCE 5 +#define LP_APM_M0_INTR_SOURCE 6 +#define FROM_CPU_INTR0_SOURCE 7 +#define FROM_CPU_INTR1_SOURCE 8 +#define FROM_CPU_INTR2_SOURCE 9 +#define FROM_CPU_INTR3_SOURCE 10 +#define ASSIST_DEBUG_INTR_SOURCE 11 +#define TRACE_INTR_SOURCE 12 +#define CACHE_INTR_SOURCE 13 +#define CPU_PERI_TIMEOUT_INTR_SOURCE 14 +#define BT_MAC_INTR_SOURCE 15 +#define BT_BB_INTR_SOURCE 16 +#define BT_BB_NMI_INTR_SOURCE 17 +#define COEX_INTR_SOURCE 18 +#define BLE_TIMER_INTR_SOURCE 19 +#define BLE_SEC_INTR_SOURCE 20 +#define ZB_MAC_INTR_SOURCE 21 +#define GPIO_INTR_SOURCE 22 +#define GPIO_NMI_SOURCE 23 +#define PAU_INTR_SOURCE 24 +#define HP_PERI_TIMEOUT_INTR_SOURCE 25 +#define HP_APM_M0_INTR_SOURCE 26 +#define HP_APM_M1_INTR_SOURCE 27 +#define HP_APM_M2_INTR_SOURCE 28 +#define HP_APM_M3_INTR_SOURCE 29 +#define MSPI_INTR_SOURCE 30 +#define I2S1_INTR_SOURCE 31 +#define UHCI0_INTR_SOURCE 32 +#define UART0_INTR_SOURCE 33 +#define UART1_INTR_SOURCE 34 +#define LEDC_INTR_SOURCE 35 +#define TWAI0_INTR_SOURCE 36 +#define USB_SERIAL_JTAG_INTR_SOURCE 37 +#define RMT_INTR_SOURCE 38 +#define I2C_EXT0_INTR_SOURCE 39 +#define I2C_EXT1_INTR_SOURCE 40 +#define TG0_T0_LEVEL_INTR_SOURCE 41 +#define TG0_WDT_LEVEL_INTR_SOURCE 42 +#define TG1_T0_LEVEL_INTR_SOURCE 43 +#define TG1_WDT_LEVEL_INTR_SOURCE 44 +#define SYSTIMER_TARGET0_EDGE_INTR_SOURCE 45 +#define SYSTIMER_TARGET1_EDGE_INTR_SOURCE 46 +#define SYSTIMER_TARGET2_EDGE_INTR_SOURCE 47 +#define APB_ADC_INTR_SOURCE 48 +#define MCPWM0_INTR_SOURCE 49 +#define PCNT_INTR_SOURCE 50 +#define PARL_IO_TX_INTR_SOURCE 51 +#define PARL_IO_RX_INTR_SOURCE 52 +#define DMA_IN_CH0_INTR_SOURCE 53 +#define DMA_IN_CH1_INTR_SOURCE 54 +#define DMA_IN_CH2_INTR_SOURCE 55 +#define DMA_OUT_CH0_INTR_SOURCE 56 +#define DMA_OUT_CH1_INTR_SOURCE 57 +#define DMA_OUT_CH2_INTR_SOURCE 58 +#define GSPI2_INTR_SOURCE 59 +#define AES_INTR_SOURCE 60 +#define SHA_INTR_SOURCE 61 +#define RSA_INTR_SOURCE 62 +#define ECC_INTR_SOURCE 63 +#define ECDSA_INTR_SOURCE 64 +#define MAX_INTR_SOURCE 65 + +/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */ +#define IRQ_DEFAULT_PRIORITY 0 + +#define ESP_INTR_FLAG_SHARED (1 << 8) /* Interrupt can be shared between ISRs */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32H2_INTMUX_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h b/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h new file mode 100644 index 0000000000000..f27fbeab0c8cc --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/esp32h2-gpio-sigmap.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ + +#define ESP_NOSIG ESP_SIG_INVAL + +#define ESP_EXT_ADC_START 0 +#define ESP_LEDC_LS_SIG_OUT0 0 +#define ESP_MODEM_DIAG0 0 +#define ESP_LEDC_LS_SIG_OUT1 1 +#define ESP_MODEM_DIAG1 1 +#define ESP_LEDC_LS_SIG_OUT2 2 +#define ESP_MODEM_DIAG2 2 +#define ESP_LEDC_LS_SIG_OUT3 3 +#define ESP_MODEM_DIAG3 3 +#define ESP_LEDC_LS_SIG_OUT4 4 +#define ESP_MODEM_DIAG4 4 +#define ESP_LEDC_LS_SIG_OUT5 5 +#define ESP_MODEM_DIAG5 5 +#define ESP_U0RXD_IN 6 +#define ESP_U0TXD_OUT 6 +#define ESP_U0CTS_IN 7 +#define ESP_U0RTS_OUT 7 +#define ESP_U0DSR_IN 8 +#define ESP_U0DTR_OUT 8 +#define ESP_U1RXD_IN 9 +#define ESP_U1TXD_OUT 9 +#define ESP_U1CTS_IN 10 +#define ESP_U1RTS_OUT 10 +#define ESP_MODEM_DIAG6 10 +#define ESP_U1DSR_IN 11 +#define ESP_U1DTR_OUT 11 +#define ESP_I2S_MCLK_IN 12 +#define ESP_I2S_MCLK_OUT 12 +#define ESP_I2SO_BCK_IN 13 +#define ESP_I2SO_BCK_OUT 13 +#define ESP_I2SO_WS_IN 14 +#define ESP_I2SO_WS_OUT 14 +#define ESP_I2SI_SD_IN 15 +#define ESP_I2SO_SD_OUT 15 +#define ESP_I2SI_BCK_IN 16 +#define ESP_I2SI_BCK_OUT 16 +#define ESP_I2SI_WS_IN 17 +#define ESP_I2SI_WS_OUT 17 +#define ESP_I2SO_SD1_OUT 18 +#define ESP_USB_JTAG_TDO_BRIDGE 19 +#define ESP_USB_JTAG_TRST 19 +#define ESP_CPU_TESTBUS0 20 +#define ESP_CPU_TESTBUS1 21 +#define ESP_CPU_TESTBUS2 22 +#define ESP_CPU_TESTBUS3 23 +#define ESP_CPU_TESTBUS4 24 +#define ESP_CPU_TESTBUS5 25 +#define ESP_CPU_TESTBUS6 26 +#define ESP_CPU_TESTBUS7 27 +#define ESP_CPU_GPIO_IN0 28 +#define ESP_CPU_GPIO_OUT0 28 +#define ESP_CPU_GPIO_IN1 29 +#define ESP_CPU_GPIO_OUT1 29 +#define ESP_CPU_GPIO_IN2 30 +#define ESP_CPU_GPIO_OUT2 30 +#define ESP_CPU_GPIO_IN3 31 +#define ESP_CPU_GPIO_OUT3 31 +#define ESP_CPU_GPIO_IN4 32 +#define ESP_CPU_GPIO_OUT4 32 +#define ESP_CPU_GPIO_IN5 33 +#define ESP_CPU_GPIO_OUT5 33 +#define ESP_CPU_GPIO_IN6 34 +#define ESP_CPU_GPIO_OUT6 34 +#define ESP_CPU_GPIO_IN7 35 +#define ESP_CPU_GPIO_OUT7 35 +#define ESP_USB_JTAG_TCK 36 +#define ESP_USB_JTAG_TMS 37 +#define ESP_USB_JTAG_TDI 38 +#define ESP_USB_JTAG_TDO 39 +#define ESP_USB_EXTPHY_VP 40 +#define ESP_USB_EXTPHY_OEN 40 +#define ESP_USB_EXTPHY_VM 41 +#define ESP_USB_EXTPHY_SPEED 41 +#define ESP_USB_EXTPHY_RCV 42 +#define ESP_USB_EXTPHY_VPO 42 +#define ESP_USB_EXTPHY_VMO 43 +#define ESP_USB_EXTPHY_SUSPND 44 +#define ESP_I2CEXT0_SCL_IN 45 +#define ESP_I2CEXT0_SCL_OUT 45 +#define ESP_I2CEXT0_SDA_IN 46 +#define ESP_I2CEXT0_SDA_OUT 46 +#define ESP_PARL_RX_DATA0 47 +#define ESP_PARL_TX_DATA0 47 +#define ESP_PARL_RX_DATA1 48 +#define ESP_PARL_TX_DATA1 48 +#define ESP_PARL_RX_DATA2 49 +#define ESP_PARL_TX_DATA2 49 +#define ESP_PARL_RX_DATA3 50 +#define ESP_PARL_TX_DATA3 50 +#define ESP_PARL_RX_DATA4 51 +#define ESP_PARL_TX_DATA4 51 +#define ESP_PARL_RX_DATA5 52 +#define ESP_PARL_TX_DATA5 52 +#define ESP_PARL_RX_DATA6 53 +#define ESP_PARL_TX_DATA6 53 +#define ESP_PARL_RX_DATA7 54 +#define ESP_PARL_TX_DATA7 54 +#define ESP_I2CEXT1_SCL_IN 55 +#define ESP_I2CEXT1_SCL_OUT 55 +#define ESP_I2CEXT1_SDA_IN 56 +#define ESP_I2CEXT1_SDA_OUT 56 +#define ESP_CTE_ANT0 57 +#define ESP_CTE_ANT1 58 +#define ESP_CTE_ANT2 59 +#define ESP_CTE_ANT3 60 +#define ESP_CTE_ANT4 61 +#define ESP_CTE_ANT5 62 +#define ESP_FSPICLK_IN 63 +#define ESP_FSPICLK_OUT 63 +#define ESP_FSPIQ_IN 64 +#define ESP_FSPIQ_OUT 64 +#define ESP_FSPID_IN 65 +#define ESP_FSPID_OUT 65 +#define ESP_FSPIHD_IN 66 +#define ESP_FSPIHD_OUT 66 +#define ESP_FSPIWP_IN 67 +#define ESP_FSPIWP_OUT 67 +#define ESP_FSPICS0_IN 68 +#define ESP_FSPICS0_OUT 68 +#define ESP_MODEM_DIAG7 68 +#define ESP_PARL_RX_CLK_IN 69 +#define ESP_PARL_RX_CLK_OUT 69 +#define ESP_PARL_TX_CLK_IN 70 +#define ESP_PARL_TX_CLK_OUT 70 +#define ESP_RMT_SIG_IN0 71 +#define ESP_RMT_SIG_OUT0 71 +#define ESP_MODEM_DIAG8 71 +#define ESP_RMT_SIG_IN1 72 +#define ESP_RMT_SIG_OUT1 72 +#define ESP_MODEM_DIAG9 72 +#define ESP_TWAI_RX 73 +#define ESP_TWAI_TX 73 +#define ESP_MODEM_DIAG10 73 +#define ESP_TWAI_BUS_OFF_ON 74 +#define ESP_MODEM_DIAG11 74 +#define ESP_TWAI_CLKOUT 75 +#define ESP_MODEM_DIAG12 75 +#define ESP_TWAI_STANDBY 76 +#define ESP_MODEM_DIAG13 76 +#define ESP_CTE_ANT6 77 +#define ESP_CTE_ANT7 78 +#define ESP_CTE_ANT8 79 +#define ESP_CTE_ANT9 80 +#define ESP_EXTERN_PRIORITY_I 81 +#define ESP_EXTERN_PRIORITY_O 81 +#define ESP_EXTERN_ACTIVE_I 82 +#define ESP_EXTERN_ACTIVE_O 82 +#define ESP_GPIO_SD0_OUT 83 +#define ESP_GPIO_SD1_OUT 84 +#define ESP_GPIO_SD2_OUT 85 +#define ESP_GPIO_SD3_OUT 86 +#define ESP_PWM0_SYNC0_IN 87 +#define ESP_PWM0_OUT0A 87 +#define ESP_MODEM_DIAG14 87 +#define ESP_PWM0_SYNC1_IN 88 +#define ESP_PWM0_OUT0B 88 +#define ESP_MODEM_DIAG15 88 +#define ESP_PWM0_SYNC2_IN 89 +#define ESP_PWM0_OUT1A 89 +#define ESP_MODEM_DIAG16 89 +#define ESP_PWM0_F0_IN 90 +#define ESP_PWM0_OUT1B 90 +#define ESP_MODEM_DIAG17 90 +#define ESP_PWM0_F1_IN 91 +#define ESP_PWM0_OUT2A 91 +#define ESP_MODEM_DIAG18 91 +#define ESP_PWM0_F2_IN 92 +#define ESP_PWM0_OUT2B 92 +#define ESP_MODEM_DIAG19 92 +#define ESP_PWM0_CAP0_IN 93 +#define ESP_ANT_SEL0 93 +#define ESP_PWM0_CAP1_IN 94 +#define ESP_ANT_SEL1 94 +#define ESP_PWM0_CAP2_IN 95 +#define ESP_ANT_SEL2 95 +#define ESP_ANT_SEL3 96 +#define ESP_SIG_IN_FUNC_97 97 +#define ESP_SIG_IN_FUNC97 97 +#define ESP_SIG_IN_FUNC_98 98 +#define ESP_SIG_IN_FUNC98 98 +#define ESP_SIG_IN_FUNC_99 99 +#define ESP_SIG_IN_FUNC99 99 +#define ESP_SIG_IN_FUNC_100 100 +#define ESP_SIG_IN_FUNC100 100 +#define ESP_PCNT_SIG_CH0_IN0 101 +#define ESP_FSPICS1_OUT 101 +#define ESP_MODEM_DIAG20 101 +#define ESP_PCNT_SIG_CH1_IN0 102 +#define ESP_FSPICS2_OUT 102 +#define ESP_MODEM_DIAG21 102 +#define ESP_PCNT_CTRL_CH0_IN0 103 +#define ESP_FSPICS3_OUT 103 +#define ESP_MODEM_DIAG22 103 +#define ESP_PCNT_CTRL_CH1_IN0 104 +#define ESP_FSPICS4_OUT 104 +#define ESP_MODEM_DIAG23 104 +#define ESP_PCNT_SIG_CH0_IN1 105 +#define ESP_FSPICS5_OUT 105 +#define ESP_MODEM_DIAG24 105 +#define ESP_PCNT_SIG_CH1_IN1 106 +#define ESP_CTE_ANT10 106 +#define ESP_PCNT_CTRL_CH0_IN1 107 +#define ESP_CTE_ANT11 107 +#define ESP_PCNT_CTRL_CH1_IN1 108 +#define ESP_CTE_ANT12 108 +#define ESP_PCNT_SIG_CH0_IN2 109 +#define ESP_CTE_ANT13 109 +#define ESP_PCNT_SIG_CH1_IN2 110 +#define ESP_CTE_ANT14 110 +#define ESP_PCNT_CTRL_CH0_IN2 111 +#define ESP_CTE_ANT15 111 +#define ESP_PCNT_CTRL_CH1_IN2 112 +#define ESP_MODEM_DIAG25 112 +#define ESP_PCNT_SIG_CH0_IN3 113 +#define ESP_MODEM_DIAG26 113 +#define ESP_PCNT_SIG_CH1_IN3 114 +#define ESP_SPICLK_OUT 114 +#define ESP_PCNT_CTRL_CH0_IN3 115 +#define ESP_SPICS0_OUT 115 +#define ESP_MODEM_DIAG27 115 +#define ESP_PCNT_CTRL_CH1_IN3 116 +#define ESP_SPICS1_OUT 116 +#define ESP_MODEM_DIAG28 116 +#define ESP_GPIO_EVENT_MATRIX_IN0 117 +#define ESP_GPIO_TASK_MATRIX_OUT0 117 +#define ESP_GPIO_EVENT_MATRIX_IN1 118 +#define ESP_GPIO_TASK_MATRIX_OUT1 118 +#define ESP_GPIO_EVENT_MATRIX_IN2 119 +#define ESP_GPIO_TASK_MATRIX_OUT2 119 +#define ESP_GPIO_EVENT_MATRIX_IN3 120 +#define ESP_GPIO_TASK_MATRIX_OUT3 120 +#define ESP_SPIQ_IN 121 +#define ESP_SPIQ_OUT 121 +#define ESP_SPID_IN 122 +#define ESP_SPID_OUT 122 +#define ESP_SPIHD_IN 123 +#define ESP_SPIHD_OUT 123 +#define ESP_SPIWP_IN 124 +#define ESP_SPIWP_OUT 124 +#define ESP_CLK_OUT_OUT1 125 +#define ESP_MODEM_DIAG29 125 +#define ESP_CLK_OUT_OUT2 126 +#define ESP_MODEM_DIAG30 126 +#define ESP_CLK_OUT_OUT3 127 +#define ESP_MODEM_DIAG31 127 +#define ESP_SIG_GPIO_OUT 128 +#define ESP_GPIO_MAP_DATE 0x2201120 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_GPIO_SIGMAP_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h new file mode 100644 index 0000000000000..91d6c2f5872a7 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * NOTE: Autogenerated file using esp_genpinctrl.py + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ + +/* UART0_CTS */ +#define UART0_CTS_GPIO0 ESP32_PINMUX(0, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO1 ESP32_PINMUX(1, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO2 ESP32_PINMUX(2, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO3 ESP32_PINMUX(3, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO4 ESP32_PINMUX(4, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO5 ESP32_PINMUX(5, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO8 ESP32_PINMUX(8, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO9 ESP32_PINMUX(9, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO10 ESP32_PINMUX(10, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO11 ESP32_PINMUX(11, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO12 ESP32_PINMUX(12, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO13 ESP32_PINMUX(13, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO14 ESP32_PINMUX(14, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO22 ESP32_PINMUX(22, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO23 ESP32_PINMUX(23, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO24 ESP32_PINMUX(24, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO25 ESP32_PINMUX(25, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO26 ESP32_PINMUX(26, ESP_U0CTS_IN, ESP_NOSIG) + +#define UART0_CTS_GPIO27 ESP32_PINMUX(27, ESP_U0CTS_IN, ESP_NOSIG) + +/* UART0_DSR */ +#define UART0_DSR_GPIO0 ESP32_PINMUX(0, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO1 ESP32_PINMUX(1, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO2 ESP32_PINMUX(2, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO3 ESP32_PINMUX(3, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO4 ESP32_PINMUX(4, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO5 ESP32_PINMUX(5, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO8 ESP32_PINMUX(8, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO9 ESP32_PINMUX(9, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO10 ESP32_PINMUX(10, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO11 ESP32_PINMUX(11, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO12 ESP32_PINMUX(12, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO13 ESP32_PINMUX(13, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO14 ESP32_PINMUX(14, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO22 ESP32_PINMUX(22, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO23 ESP32_PINMUX(23, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO24 ESP32_PINMUX(24, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO25 ESP32_PINMUX(25, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO26 ESP32_PINMUX(26, ESP_U0DSR_IN, ESP_NOSIG) + +#define UART0_DSR_GPIO27 ESP32_PINMUX(27, ESP_U0DSR_IN, ESP_NOSIG) + +/* UART0_DTR */ +#define UART0_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0DTR_OUT) + +#define UART0_DTR_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0DTR_OUT) + +/* UART0_RTS */ +#define UART0_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0RTS_OUT) + +#define UART0_RTS_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0RTS_OUT) + +/* UART0_RX */ +#define UART0_RX_GPIO0 ESP32_PINMUX(0, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO1 ESP32_PINMUX(1, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO2 ESP32_PINMUX(2, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO3 ESP32_PINMUX(3, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO4 ESP32_PINMUX(4, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO5 ESP32_PINMUX(5, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO8 ESP32_PINMUX(8, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO9 ESP32_PINMUX(9, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO10 ESP32_PINMUX(10, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO11 ESP32_PINMUX(11, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO12 ESP32_PINMUX(12, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO13 ESP32_PINMUX(13, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO14 ESP32_PINMUX(14, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO22 ESP32_PINMUX(22, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO23 ESP32_PINMUX(23, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO24 ESP32_PINMUX(24, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO25 ESP32_PINMUX(25, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO26 ESP32_PINMUX(26, ESP_U0RXD_IN, ESP_NOSIG) + +#define UART0_RX_GPIO27 ESP32_PINMUX(27, ESP_U0RXD_IN, ESP_NOSIG) + +/* UART0_TX */ +#define UART0_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U0TXD_OUT) + +#define UART0_TX_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U0TXD_OUT) + +/* UART1_CTS */ +#define UART1_CTS_GPIO0 ESP32_PINMUX(0, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO1 ESP32_PINMUX(1, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO2 ESP32_PINMUX(2, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO3 ESP32_PINMUX(3, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO4 ESP32_PINMUX(4, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO5 ESP32_PINMUX(5, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO8 ESP32_PINMUX(8, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO9 ESP32_PINMUX(9, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO10 ESP32_PINMUX(10, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO11 ESP32_PINMUX(11, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO12 ESP32_PINMUX(12, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO13 ESP32_PINMUX(13, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO14 ESP32_PINMUX(14, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO22 ESP32_PINMUX(22, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO23 ESP32_PINMUX(23, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO24 ESP32_PINMUX(24, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO25 ESP32_PINMUX(25, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO26 ESP32_PINMUX(26, ESP_U1CTS_IN, ESP_NOSIG) + +#define UART1_CTS_GPIO27 ESP32_PINMUX(27, ESP_U1CTS_IN, ESP_NOSIG) + +/* UART1_DSR */ +#define UART1_DSR_GPIO0 ESP32_PINMUX(0, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO1 ESP32_PINMUX(1, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO2 ESP32_PINMUX(2, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO3 ESP32_PINMUX(3, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO4 ESP32_PINMUX(4, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO5 ESP32_PINMUX(5, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO8 ESP32_PINMUX(8, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO9 ESP32_PINMUX(9, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO10 ESP32_PINMUX(10, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO11 ESP32_PINMUX(11, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO12 ESP32_PINMUX(12, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO13 ESP32_PINMUX(13, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO14 ESP32_PINMUX(14, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO22 ESP32_PINMUX(22, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO23 ESP32_PINMUX(23, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO24 ESP32_PINMUX(24, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO25 ESP32_PINMUX(25, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO26 ESP32_PINMUX(26, ESP_U1DSR_IN, ESP_NOSIG) + +#define UART1_DSR_GPIO27 ESP32_PINMUX(27, ESP_U1DSR_IN, ESP_NOSIG) + +/* UART1_DTR */ +#define UART1_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1DTR_OUT) + +#define UART1_DTR_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1DTR_OUT) + +/* UART1_RTS */ +#define UART1_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1RTS_OUT) + +#define UART1_RTS_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1RTS_OUT) + +/* UART1_RX */ +#define UART1_RX_GPIO0 ESP32_PINMUX(0, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO1 ESP32_PINMUX(1, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO2 ESP32_PINMUX(2, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO3 ESP32_PINMUX(3, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO4 ESP32_PINMUX(4, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO5 ESP32_PINMUX(5, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO8 ESP32_PINMUX(8, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO9 ESP32_PINMUX(9, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO10 ESP32_PINMUX(10, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO11 ESP32_PINMUX(11, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO12 ESP32_PINMUX(12, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO13 ESP32_PINMUX(13, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO14 ESP32_PINMUX(14, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO22 ESP32_PINMUX(22, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO23 ESP32_PINMUX(23, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO24 ESP32_PINMUX(24, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO25 ESP32_PINMUX(25, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO26 ESP32_PINMUX(26, ESP_U1RXD_IN, ESP_NOSIG) + +#define UART1_RX_GPIO27 ESP32_PINMUX(27, ESP_U1RXD_IN, ESP_NOSIG) + +/* UART1_TX */ +#define UART1_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_U1TXD_OUT) + +#define UART1_TX_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_U1TXD_OUT) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_ESP32H2_PINCTRL_H_ */ From 5bd4741c839f7dee3a3575e88e88ef185b8efd61 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 29 Jul 2025 14:21:12 -0300 Subject: [PATCH 0091/1076] soc: esp32h2: Add initial support Add initial support files for ESP32-H2 SoC. Signed-off-by: Raffael Rostagno --- .../espressif/esp32h2/esp32h2_common.dtsi | 211 +++++ .../espressif/esp32h2/esp32h2_mini_h2.dtsi | 12 + .../espressif/esp32h2/esp32h2_mini_h4.dtsi | 12 + .../esp32h2/esp32h2_wroom_02c_h2.dtsi | 12 + .../esp32h2/esp32h2_wroom_02c_h4.dtsi | 12 + soc/espressif/common/Kconfig.defconfig | 7 +- soc/espressif/common/Kconfig.esptool | 5 +- soc/espressif/common/Kconfig.flash | 2 +- soc/espressif/esp32h2/CMakeLists.txt | 12 + soc/espressif/esp32h2/Kconfig | 16 + soc/espressif/esp32h2/Kconfig.defconfig | 18 + soc/espressif/esp32h2/Kconfig.soc | 38 + soc/espressif/esp32h2/default.ld | 870 ++++++++++++++++++ soc/espressif/esp32h2/hw_init.c | 98 ++ soc/espressif/esp32h2/mcuboot.ld | 275 ++++++ soc/espressif/esp32h2/memory.h | 69 ++ soc/espressif/esp32h2/pinctrl_soc.h | 76 ++ soc/espressif/esp32h2/soc.c | 57 ++ soc/espressif/esp32h2/soc.h | 61 ++ soc/espressif/esp32h2/soc_irq.S | 15 + soc/espressif/esp32h2/vectors.S | 35 + soc/espressif/soc.yml | 3 + 22 files changed, 1911 insertions(+), 5 deletions(-) create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_common.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi create mode 100644 dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi create mode 100644 soc/espressif/esp32h2/CMakeLists.txt create mode 100644 soc/espressif/esp32h2/Kconfig create mode 100644 soc/espressif/esp32h2/Kconfig.defconfig create mode 100644 soc/espressif/esp32h2/Kconfig.soc create mode 100644 soc/espressif/esp32h2/default.ld create mode 100644 soc/espressif/esp32h2/hw_init.c create mode 100644 soc/espressif/esp32h2/mcuboot.ld create mode 100644 soc/espressif/esp32h2/memory.h create mode 100644 soc/espressif/esp32h2/pinctrl_soc.h create mode 100644 soc/espressif/esp32h2/soc.c create mode 100644 soc/espressif/esp32h2/soc.h create mode 100644 soc/espressif/esp32h2/soc_irq.S create mode 100644 soc/espressif/esp32h2/vectors.S diff --git a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi new file mode 100644 index 0000000000000..0b9f8f96dd140 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + die-temp0 = &coretemp; + }; + + chosen { + zephyr,entropy = &trng0; + zephyr,flash-controller = &flash; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "espressif,riscv"; + riscv,isa = "rv32imac_zicsr"; + reg = <0>; + clock-source = ; + clock-frequency = ; + xtal-freq = ; + }; + }; + + pinctrl: pin-controller { + compatible = "espressif,esp32-pinctrl"; + status = "okay"; + }; + + clock: clock { + compatible = "espressif,esp32-clock"; + fast-clk-src = ; + slow-clk-src = ; + #clock-cells = <1>; + status = "okay"; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + sramhp: memory@40800000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x40800000 DT_SIZE_K(320)>; + zephyr,memory-region = "SRAMHP"; + }; + + sramlp: memory@50000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x50000000 DT_SIZE_K(4)>; + zephyr,memory-region = "SRAMLP"; + }; + + intc: interrupt-controller@60010000 { + compatible = "espressif,esp32-intc"; + #address-cells = <0>; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x60010000 DT_SIZE_K(4)>; + status = "okay"; + }; + + systimer0: systimer@6000b000 { + compatible = "espressif,esp32-systimer"; + reg = <0x6000B000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-parent = <&intc>; + status = "okay"; + }; + + timer0: counter@60009000 { + compatible = "espressif,esp32-timer"; + reg = <0x60009000 DT_SIZE_K(4)>; + clocks = <&clock ESP32_TIMG0_MODULE>; + group = <0>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + + counter { + compatible = "espressif,esp32-counter"; + status = "disabled"; + }; + }; + + timer1: counter@6000a000 { + compatible = "espressif,esp32-timer"; + reg = <0x6000A000 DT_SIZE_K(4)>; + clocks = <&clock ESP32_TIMG1_MODULE>; + group = <1>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + + counter { + compatible = "espressif,esp32-counter"; + status = "disabled"; + }; + }; + + rtc_timer: rtc_timer@600b0c00 { + compatible = "espressif,esp32-rtc_timer"; + reg = <0x600B0C00 DT_SIZE_K(1)>; + clocks = <&clock ESP32_MODULE_MAX>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + trng0: trng@600b2808 { + compatible = "espressif,esp32-trng"; + reg = <0x600B2808 0x4>; + clocks = <&clock ESP32_RNG_MODULE>; + status = "disabled"; + }; + + wdt0: watchdog@60009048 { + compatible = "espressif,esp32-watchdog"; + reg = <0x60009048 0x20>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_TIMG0_MODULE>; + status = "disabled"; + }; + + wdt1: watchdog@6000a048 { + compatible = "espressif,esp32-watchdog"; + reg = <0x6000A048 0x20>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_TIMG1_MODULE>; + status = "disabled"; + }; + + flash: flash-controller@60002000 { + compatible = "espressif,esp32-flash-controller"; + reg = <0x60002000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <4>; + /* Flash size is specified in SOC/SIP dtsi */ + }; + }; + + coretemp: coretemp@6000e058 { + compatible = "espressif,esp32-temp"; + friendly-name = "coretemp"; + reg = <0x6000E058 0x4>; + status = "disabled"; + }; + + gpio0: gpio@60091000 { + compatible = "espressif,esp32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x60091000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-parent = <&intc>; + ngpios = <32>; + gpio-reserved-ranges = + <6 2>, /* GPIO6–7 */ + <15 7>, /* GPIO15–21 */ + <28 4>; /* GPIO28–31 */ + }; + + uart0: uart@60000000 { + compatible = "espressif,esp32-uart"; + reg = <0x60000000 DT_SIZE_K(4)>; + status = "disabled"; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_UART0_MODULE>; + }; + + uart1: uart@60001000 { + compatible = "espressif,esp32-uart"; + reg = <0x60001000 DT_SIZE_K(4)>; + status = "disabled"; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_UART1_MODULE>; + }; + }; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi new file mode 100644 index 0000000000000..e67b0e6475ad4 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_mini_h2.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 2MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(2)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi new file mode 100644 index 0000000000000..e4de9fd312f97 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_mini_h4.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 4MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(4)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi new file mode 100644 index 0000000000000..e67b0e6475ad4 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h2.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 2MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(2)>; +}; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi new file mode 100644 index 0000000000000..e4de9fd312f97 --- /dev/null +++ b/dts/riscv/espressif/esp32h2/esp32h2_wroom_02c_h4.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include "esp32h2_common.dtsi" + +/* 4MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(4)>; +}; diff --git a/soc/espressif/common/Kconfig.defconfig b/soc/espressif/common/Kconfig.defconfig index 23924f8612133..337895ded15d7 100644 --- a/soc/espressif/common/Kconfig.defconfig +++ b/soc/espressif/common/Kconfig.defconfig @@ -1,7 +1,7 @@ -# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 +if SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32H2 config GEN_ISR_TABLES default y if !SOC_ESP32C6_LPCORE @@ -30,6 +30,7 @@ config XTAL_FREQ_HZ config SYS_CLOCK_HW_CYCLES_PER_SEC default 10400000 if XTAL_FREQ_HZ = 26000000 + default 16000000 if XTAL_FREQ_HZ = 32000000 default 16000000 if XTAL_FREQ_HZ = 40000000 config SYS_CLOCK_TICKS_PER_SEC @@ -51,7 +52,7 @@ config ROM_START_OFFSET endif # BOOTLOADER_MCUBOOT -endif # SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 +endif # SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32H2 if SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 diff --git a/soc/espressif/common/Kconfig.esptool b/soc/espressif/common/Kconfig.esptool index c62fad44f0b8a..09684e3985c66 100644 --- a/soc/espressif/common/Kconfig.esptool +++ b/soc/espressif/common/Kconfig.esptool @@ -85,6 +85,7 @@ config ESPTOOLPY_FLASHMODE choice ESPTOOLPY_FLASHFREQ prompt "Flash SPI speed" default ESPTOOLPY_FLASHFREQ_40M if SOC_SERIES_ESP32 + default ESPTOOLPY_FLASHFREQ_48M if SOC_SERIES_ESP32H2 default ESPTOOLPY_FLASHFREQ_60M if SOC_SERIES_ESP32C2 default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT @@ -107,7 +108,8 @@ config ESPTOOLPY_FLASHFREQ_80M config ESPTOOLPY_FLASHFREQ_60M bool "60 MHz" - +config ESPTOOLPY_FLASHFREQ_48M + bool "48 MHz" config ESPTOOLPY_FLASHFREQ_40M bool "40 MHz" @@ -133,6 +135,7 @@ config ESPTOOLPY_FLASHFREQ default '80m' if ESPTOOLPY_FLASHFREQ_120M default '80m' if ESPTOOLPY_FLASHFREQ_80M default '60m' if ESPTOOLPY_FLASHFREQ_60M + default '48m' if ESPTOOLPY_FLASHFREQ_48M default '40m' if ESPTOOLPY_FLASHFREQ_40M default '26m' if ESPTOOLPY_FLASHFREQ_26M default '20m' if ESPTOOLPY_FLASHFREQ_20M diff --git a/soc/espressif/common/Kconfig.flash b/soc/espressif/common/Kconfig.flash index d38da38c79735..949d7f5d750ec 100644 --- a/soc/espressif/common/Kconfig.flash +++ b/soc/espressif/common/Kconfig.flash @@ -94,7 +94,7 @@ config BOOTLOADER_FLASH_XMC_SUPPORT choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" default BOOTLOADER_VDDSDIO_BOOST_1_9V - depends on !SOC_SERIES_ESP32C2 && !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6 + depends on !SOC_SERIES_ESP32C2 && !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6 && !SOC_SERIES_ESP32H2 help If this option is enabled, and VDDSDIO LDO is set to 1.8V (using eFuse or MTDI bootstrapping pin), bootloader will change LDO settings to diff --git a/soc/espressif/esp32h2/CMakeLists.txt b/soc/espressif/esp32h2/CMakeLists.txt new file mode 100644 index 0000000000000..0248ccef51e47 --- /dev/null +++ b/soc/espressif/esp32h2/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + vectors.S + soc_irq.S + soc.c + ../common/loader.c + ) + +zephyr_include_directories(.) + +zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c) diff --git a/soc/espressif/esp32h2/Kconfig b/soc/espressif/esp32h2/Kconfig new file mode 100644 index 0000000000000..e5974e87a7923 --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32H2 + select RISCV + select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + select DYNAMIC_INTERRUPTS + select CLOCK_CONTROL + select PINCTRL + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select HAS_ESPRESSIF_HAL diff --git a/soc/espressif/esp32h2/Kconfig.defconfig b/soc/espressif/esp32h2/Kconfig.defconfig new file mode 100644 index 0000000000000..558dff5b6df9c --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32H2 + +config NUM_IRQS + default 32 + +config FLASH_SIZE + default $(dt_node_reg_size_int,/soc/flash-controller@60002000/flash@0,0) + +config FLASH_BASE_ADDRESS + default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) + +config MAIN_STACK_SIZE + default 2048 + +endif # SOC_SERIES_ESP32H2 diff --git a/soc/espressif/esp32h2/Kconfig.soc b/soc/espressif/esp32h2/Kconfig.soc new file mode 100644 index 0000000000000..c1f76ae06833d --- /dev/null +++ b/soc/espressif/esp32h2/Kconfig.soc @@ -0,0 +1,38 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32H2 + bool + select SOC_FAMILY_ESPRESSIF_ESP32 + +config SOC_ESP32_H2_MINI_H2 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_MINI_H4 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_WROOM_02C_H2 + bool + select SOC_ESP32H2 + +config SOC_ESP32_H2_WROOM_02C_H4 + bool + select SOC_ESP32H2 + +config SOC_ESP32H2 + bool + select SOC_SERIES_ESP32H2 + +config SOC_SERIES + default "esp32h2" if SOC_SERIES_ESP32H2 + +config SOC + default "esp32h2" if SOC_ESP32H2 + +config SOC_PART_NUMBER + default "ESP32_H2_MINI_1_H2S" if SOC_ESP32_H2_MINI_H2 + default "ESP32_H2_MINI_1_H4S" if SOC_ESP32_H2_MINI_H4 + default "ESP32_H2_WROOM_02C_H2S" if SOC_ESP32_H2_WROOM_02C_H2 + default "ESP32_H2_WROOM_02C_H4S" if SOC_ESP32_H2_WROOM_02C_H4 diff --git a/soc/espressif/esp32h2/default.ld b/soc/espressif/esp32h2/default.ld new file mode 100644 index 0000000000000..c933a43425801 --- /dev/null +++ b/soc/espressif/esp32h2/default.ld @@ -0,0 +1,870 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "memory.h" + +/* The "user_sram_end" represents the 2nd stage bootloader + * "iram_loader_seg" start address (that should not be overlapped). + * If no bootloader is used, we can extend it to gain more user ram. + */ +#ifdef CONFIG_ESP_SIMPLE_BOOT +user_sram_end = DRAM_BUFFERS_START; +#else +user_sram_end = BOOTLOADER_IRAM_LOADER_SEG_START; +#endif + +/* User available memory segments */ +user_sram_org = HPSRAM_START; +user_sram_size = (user_sram_end - user_sram_org); + +/* Aliases */ +#define FLASH_CODE_REGION irom0_0_seg +#define RODATA_REGION drom0_0_seg +#define RAMABLE_REGION sram0_0_seg +#define ROMABLE_REGION FLASH + +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion + +#undef GROUP_NOLOAD_LINK_IN +#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion + +/* Flash segments (rodata and text) should be mapped in the virtual address spaces. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_DATA_PROLOGUE +#define SECTION_DATA_PROLOGUE(name, options, align) name options : ALIGN_WITH_INPUT + +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + +/* Global symbols required for espressif hal build */ +MEMORY +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 +#else + /* Make safety margin in the FLASH memory size so the + * (esp_img_header + (n*esp_seg_headers)) would fit */ + FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 +#endif + + sram0_0_seg(RW): org = user_sram_org, len = user_sram_size + + irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN + drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN + + lp_ram_seg(RW): org = LPSRAM_IRAM_START, + len = 0x4000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of lp_ram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of LP memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* The lines below define location alias for .rtc.data section + * H2 has no distinguished LP(RTC) fast and slow memory sections, + * instead, there is a unified LP_RAM section + * Thus, the following region segments are + * not configurable like on other targets + */ +REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); +REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +/* Heap size calculations */ +_heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; + +SECTIONS +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + /* Reserve space for MCUboot header in the binary */ + .mcuboot_header : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + .metadata : + { + /* 0. Magic byte for load header */ + LONG(0xace637d3) + + /* 1. Application entry point address */ + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * 2. Destination address (VMA) for IRAM region + * 3. Flash offset (LMA) for start of IRAM region + * 4. Size of IRAM region + */ + LONG(ADDR(.iram0.text)) + LONG(LOADADDR(.iram0.text)) + LONG(LOADADDR(.iram0.data) - LOADADDR(.iram0.text)) + + /* DRAM metadata: + * 5. Destination address (VMA) for DRAM region + * 6. Flash offset (LMA) for start of DRAM region + * 7. Size of DRAM region + */ + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + + /* LP_IRAM metadata: + * 8. Destination address (VMA) for LP_IRAM region + * 9. Flash offset (LMA) for start of LP_IRAM region + * 10. Size of LP_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* LP_DATA metadata: + * 11. Destination address (VMA) for LP_DRAM region + * 12. Flash offset (LMA) for start of LP_DRAM region + * 13. Size of LP_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) + } > metadata +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + + #include + +#ifdef CONFIG_LLEXT + #include +#endif + + /* --- START OF RTC --- */ + .rtc.text : + { + . = ALIGN(4); + _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + *(.rtc.entry.text) + *(.rtc.literal .rtc.literal.* .rtc.text .rtc.text.*) + . = ALIGN(4); + _rtc_text_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /* This section located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4); + _rtc_force_fast_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /* RTC data section holds data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + _rtc_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *(.rtc.bss .rtc.bss.*) + _rtc_bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_ram_seg) + + /* This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * User data marked with RTC_NOINIT_ATTR will be placed + * into this section. See the file "esp_attr.h" for more information. + */ + .rtc_noinit (NOLOAD) : + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_ram_seg) + + /* This section located in RTC SLOW Memory area. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4); + _rtc_force_slow_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) + + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + _rtc_reserved_end = ABSOLUTE(.); + } GROUP_LINK_IN(lp_reserved_seg) +#endif + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + _rtc_fast_length = (_rtc_force_fast_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.") + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.") + + /* --- END OF RTC --- */ + + /* --- START OF IRAM --- */ + + .iram0.text : ALIGN(4) + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + + _init_end = ABSOLUTE(.); + _iram_text_start = ABSOLUTE(.); + + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *libzephyr.a:panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:console_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:hw_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_random.*(.literal .text .literal.* .text.*) + + *libarch__riscv__core.a:(.literal .text .literal.* .text.*) + *libkernel.a:(.literal .text .literal.* .text.*) + *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) + *libdrivers__timer.a:esp32h2_sys_timer.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_core.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_complete.*(.literal .text .literal.* .text.*) + *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) + *libzephyr.a:log_msg.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_list.*(.literal .text .literal.* .text.*) + *libdrivers__console.a:uart_console.*(.literal.console_out .text.console_out) + *libzephyr.a:log_output.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*) + *libzephyr.a:rtc_*.*(.literal .text .literal.* .text.*) + *libzephyr.a:periph_ctrl.*(.literal .text .literal.* .text.*) + *libzephyr.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) + *libgcov.a:(.literal .text .literal.* .text.*) + *libphy.a:( .phyiram .phyiram.*) + *librtc.a:(.literal .text .literal.* .text.*) + + /* [mapping:hal] */ + *libzephyr.a:efuse_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:cache_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:ledc_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:i2c_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + *libzephyr.a:modem_clock_hal.*(.literal .literal.* .text .text.*) + *libzephyr.a:modem_clock.*(.literal .literal.* .text .text.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.literal .literal.* .text .text.*) + + /* [mapping:log] */ + *(.literal.esp_log_write .text.esp_log_write) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_log_impl_lock .text.esp_log_impl_lock) + *(.literal.esp_log_impl_lock_timeout .text.esp_log_impl_lock_timeout) + *(.literal.esp_log_impl_unlock .text.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_gd.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_generic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_issi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_th.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_winbond.*(.literal .literal.* .text .text.*) + *libzephyr.a:memspi_host_driver.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_ops.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_err.*(.literal .literal.* .text .text.*) + *(.literal.esp_system_abort .text.esp_system_abort) + + /* [mapping:esp_hw_support] */ + *(.literal.esp_cpu_stall .text.esp_cpu_stall) + *(.literal.esp_cpu_unstall .text.esp_cpu_unstall) + *(.literal.esp_cpu_reset .text.esp_cpu_reset) + *(.literal.esp_cpu_wait_for_intr .text.esp_cpu_wait_for_intr) + *(.literal.esp_cpu_compare_and_set .text.esp_cpu_compare_and_set) + *(.literal.esp_gpio_reserve_pins .text.esp_gpio_reserve_pins) + *(.literal.esp_gpio_is_pin_reserved .text.esp_gpio_is_pin_reserved) + *(.literal.rtc_vddsdio_get_config .text.rtc_vddsdio_get_config) + *(.literal.rtc_vddsdio_set_config .text.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_param.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:systimer.*(.literal .literal.* .text .text.*) + *(.literal.sar_periph_ctrl_power_enable .text.sar_periph_ctrl_power_enable) + + /* [mapping:soc_pm] */ + *(.literal.GPIO_HOLD_MASK .text.GPIO_HOLD_MASK) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_crc.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_sys.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_uart.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_efuse.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_wdt.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_regi2c_esp32h2.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.literal .literal.* .text .text.*) + *libzephyr.a:cache_utils.*(.literal .text .literal.* .text.*) + + . = ALIGN(4) + 16; + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + .loader.text : + { + . = ALIGN(4); + _loader_text_start = ABSOLUTE(.); + *libzephyr.a:bootloader_clock_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_wdt.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_random.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_efuse.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_utility.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_sha.*(.literal .text .literal.* .text.*) + + *libzephyr.a:esp_image_format.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_ops.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_encrypt.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_partitions.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_qio_mode.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_hal_common.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_flash_api.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_flash_spi_init.*(.literal .text .literal.* .text.*) + + *libzephyr.a:esp_efuse_table.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_fields.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_api.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_utility.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_efuse_api_key_esp32xx.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) + *libzephyr.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) + + *libzephyr.a:cpu_region_protect.*(.literal .text .literal.* .text.*) + + /* TODO: optimise */ + *libzephyr.a:esp_gpio_reserve.*(.literal .text .literal.* .text.*) + + . = ALIGN(4) + 16; + _loader_text_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + .iram0.text_end (NOLOAD) : + { + /* H2 memprot requires 512 B alignment for split lines */ + . = ALIGN(16); + _iram_text_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + .iram0.data : + { + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + . = ALIGN(16) + 16; + } GROUP_LINK_IN(RAMABLE_REGION) + + /* --- END OF IRAM --- */ + + /* --- START OF DRAM --- */ + + .dram0.data : + { + . = ALIGN(4); + _data_start = ABSOLUTE(.); + __data_start = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + +#ifdef CONFIG_RISCV_GP + . = ALIGN(8); + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + + /* All dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libkernel.a:fatal.*(.rodata .rodata.* .srodata .srodata.*) + *libkernel.a:init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:periph_ctrl.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_flash_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:console_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:hw_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:soc_random.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:cache_utils.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:hal] */ + *libzephyr.a:efuse_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:mmu_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cache_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:ledc_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:i2c_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:wdt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:modem_clock_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:modem_clock.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:log] */ + *(.rodata.esp_log_write) + *(.rodata.esp_log_timestamp) + *(.rodata.esp_log_early_timestamp) + *(.rodata.esp_log_impl_lock) + *(.rodata.esp_log_impl_lock_timeout) + *(.rodata.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_gd.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_generic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_issi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_th.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_winbond.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:memspi_host_driver.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_brownout_hook.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_wrap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + *libzephyr.a:flash_qio_mode.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_hw_support] */ + *(.rodata.esp_cpu_stall) + *(.rodata.esp_cpu_unstall) + *(.rodata.esp_cpu_reset) + *(.rodata.esp_cpu_wait_for_intr) + *(.rodata.esp_cpu_compare_and_set) + *(.rodata.esp_gpio_reserve_pins) + *(.rodata.esp_gpio_is_pin_reserved) + *(.rodata.rtc_vddsdio_get_config) + *(.rodata.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer.*(.rodata .rodata.* .srodata .srodata.*) + *(.rodata.sar_periph_ctrl_power_enable) + *libzephyr.a:pmu_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:pmu_param.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.rodata .rodata.*) + *libzephyr.a:esp_err.*(.rodata .rodata.*) + *(.rodata.esp_system_abort) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_crc.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_sys.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_spiflash.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_efuse.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_systimer.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_regi2c_esp32h2.*(.rodata .rodata.* .srodata .srodata.*) + + *libphy.a:(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + /* Secondary loader sections */ + .loader.data : + { + . = ALIGN(4); + _loader_data_start = ABSOLUTE(.); + *libzephyr.a:bootloader_clock_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_wdt.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_flash.*(.srodata .srodata.* .rodata .rodata.*) + *libzephyr.a:bootloader_clock_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_common_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_panic.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:cpu_region_protect.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_mmap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:esp_gpio_reserve.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_common.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_api.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_spi_init.*(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(16); + _loader_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + #include + #include + #include + #include + + /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ + #pragma push_macro("GROUP_ROM_LINK_IN") + #undef GROUP_ROM_LINK_IN + #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN + #include + #pragma pop_macro("GROUP_ROM_LINK_IN") + + .dram0.end : + { + . = ALIGN(4); + _data_end = ABSOLUTE(.); + __data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + __bss_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (16); + __bss_end = ABSOLUTE(.); + _bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Provide total SRAM usage, including IRAM and DRAM */ + _image_ram_start = _iram_start; + #include + + ASSERT(((_end - ORIGIN(sram0_0_seg)) <= LENGTH(sram0_0_seg)), "SRAM code/data does not fit.") + + /* --- END OF DRAM --- */ + + /* --- START OF .flash.text --- */ + + .flash.align_text (NOLOAD): + { + /* Subsequent segment lma align */ + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_irom_start = LOADADDR(.flash.text); + _image_irom_size = SIZEOF(.flash.text); + _image_irom_vaddr = ADDR(.flash.text); + + .flash.text : ALIGN(0x10) + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + _instruction_reserved_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); + __rom_region_start = ABSOLUTE(.); + + *(.literal .text .literal.* .text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + + *(.fini.literal) + *(.fini) + + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _instruction_reserved_end = ABSOLUTE(.); + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); + __rom_region_end = ABSOLUTE(.); + _etext = .; + + } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) + + /* --- END OF .flash.text --- */ + + /* --- START OF .rodata --- */ + + /* Align next section to 64k to allow mapping */ + .flash.align_rom (NOLOAD) : + { + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_drom_start = LOADADDR(.flash.rodata); + _image_drom_size = _image_rodata_end - _image_rodata_start; + _image_drom_vaddr = ADDR(.flash.rodata); + + .flash.rodata : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); + _image_rodata_start = ABSOLUTE(.); + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + __rodata_region_start = ABSOLUTE(.); + + . = ALIGN(4); + #include + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + __rodata_region_end = .; + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /* Create an explicit section at the end of all the data that shall be mapped into drom. + * This is used to calculate the size of the _image_drom_size variable */ + .flash.rodata_end : ALIGN(0x10) + { + . = ALIGN(4); + _rodata_reserved_end = ABSOLUTE(.); + _image_rodata_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + + /* --- END OF .rodata --- */ + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + + #include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32h2/hw_init.c b/soc/espressif/esp32h2/hw_init.c new file mode 100644 index 0000000000000..3eaf036e68e77 --- /dev/null +++ b/soc/espressif/esp32h2/hw_init.c @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hw_init.h" +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +const static char *TAG = "hw_init"; + +int hardware_init(void) +{ + int err = 0; + + soc_hw_init(); + + ana_reset_config(); + super_wdt_auto_feed(); + + /* By default, these access path filters are enable and allow the + * access to masters only if they are in TEE mode. Since all masters + * except HP CPU boots in REE mode, default setting of these filters + * will deny the access to all masters except HP CPU. + * So, at boot disabling these filters. They will enable as per the + * use case by TEE initialization code. + */ + REG_WRITE(LP_APM_FUNC_CTRL_REG, 0); + REG_WRITE(LP_APM0_FUNC_CTRL_REG, 0); + REG_WRITE(HP_APM_FUNC_CTRL_REG, 0); + +#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE + esp_cpu_configure_region_protection(); +#endif + + bootloader_clock_configure(); + +#ifdef CONFIG_ESP_CONSOLE + /* initialize console, from now on, we can log */ + esp_console_init(); + print_banner(); +#endif /* CONFIG_ESP_CONSOLE */ + + cache_hal_init(); + mmu_hal_init(); + + flash_update_id(); + + err = bootloader_flash_xmc_startup(); + if (err != 0) { + ESP_EARLY_LOGE(TAG, "failed when running XMC startup flow, reboot!"); + return err; + } + + err = read_bootloader_header(); + if (err != 0) { + return err; + } + + err = check_bootloader_validity(); + if (err != 0) { + return err; + } + + err = init_spi_flash(); + if (err != 0) { + return err; + } + + check_wdt_reset(); + config_wdt(); + + soc_random_enable(); + + return 0; +} diff --git a/soc/espressif/esp32h2/mcuboot.ld b/soc/espressif/esp32h2/mcuboot.ld new file mode 100644 index 0000000000000..4856d6d3dac60 --- /dev/null +++ b/soc/espressif/esp32h2/mcuboot.ld @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "memory.h" + +/* Disable all romable LMA */ +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion + +#define RAMABLE_REGION dram_seg +#define RODATA_REGION dram_seg +#define ROMABLE_REGION dram_seg + +/* Global symbols required for espressif hal build */ +MEMORY +{ + iram_seg (RX) : org = BOOTLOADER_IRAM_SEG_START, + len = BOOTLOADER_IRAM_SEG_LEN + iram_loader_seg (RX) : org = BOOTLOADER_IRAM_LOADER_SEG_START, + len = BOOTLOADER_IRAM_LOADER_SEG_LEN + dram_seg (RW) : org = BOOTLOADER_DRAM_SEG_START, + len = BOOTLOADER_DRAM_SEG_LEN + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +SECTIONS +{ + .iram0.loader_text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + + *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) + *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) + *libkernel.a:device.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) + + *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) + *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_system_abort .text.esp_system_abort) + + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram0.text : + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + _iram_text_start = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + + /* H2 memprot requires 512 B alignment for split lines */ + . = ALIGN (16); + _init_end = ABSOLUTE(.); + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + + *(.literal .text .literal.* .text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + __text_region_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } > iram_seg + + .dram0.data : + { + . = ALIGN(4); + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) +#ifdef CONFIG_RISCV_GP + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *libzephyr.a:mmu_hal.*(.rodata .rodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.*) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + + #include + . = ALIGN(4); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + *(.rodata) + *(.rodata.*) + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + __rodata_region_end = .; + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + _thread_local_end = ABSOLUTE(.); + /* _rodata_reserved_end = ABSOLUTE(.); */ + . = ALIGN(4); + } > dram_seg + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + + .noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } > dram_seg + + /* Shared RAM */ + .bss (NOLOAD): + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + __bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end = ABSOLUTE(.); + _bss_end = ABSOLUTE(.); + } > dram_seg + + /* linker rel sections*/ + #include + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + +#include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32h2/memory.h b/soc/espressif/esp32h2/memory.h new file mode 100644 index 0000000000000..61db5c3bfc126 --- /dev/null +++ b/soc/espressif/esp32h2/memory.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/* LP-SRAM (4kB) memory */ +#define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp)) +#define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp)) + +/* HP-SRAM (320kB) memory */ +#define HPSRAM_START DT_REG_ADDR(DT_NODELABEL(sramhp)) +#define HPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramhp)) +#define HPSRAM_DRAM_START HPSRAM_START +#define HPSRAM_IRAM_START HPSRAM_START +/* ICache size is fixed to 16KB on ESP32-H2 */ +#define ICACHE_SIZE 0x4000 + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-H2 ROM static data usage is as follows: + * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4084f380 - 0x4084fee0: ROM .bss and .data (reclaimable) + * - 0x4084fee0 - 0x40850000: ROM .bss and .data (cannot be freed) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4084d380). + */ + +#define DRAM_BUFFERS_START 0x4083ba78 +#define DRAM_BUFFERS_END 0x4084d380 +#define DRAM_STACK_START DRAM_BUFFERS_END +#define DRAM_ROM_BSS_DATA_START 0x4084f380 + +/* Set the limit for the application runtime dynamic allocations */ +#define DRAM_RESERVED_START DRAM_BUFFERS_END + +/* For safety margin between bootloader data section and startup stacks */ +#define BOOTLOADER_STACK_OVERHEAD 0x0 +/* These lengths can be adjusted, if necessary: FIXME: optimize ram usage */ +#define BOOTLOADER_DRAM_SEG_LEN 0xA000 +#define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x3000 +#define BOOTLOADER_IRAM_SEG_LEN 0xC000 + +/* Base address used for calculating memory layout + * counted from Dbus backwards and back to the Ibus + */ +#define BOOTLOADER_USER_SRAM_END (DRAM_BUFFERS_START - BOOTLOADER_STACK_OVERHEAD) + +/* Start of the lower region is determined by region size and the end of the higher region */ +#define BOOTLOADER_IRAM_LOADER_SEG_START (BOOTLOADER_USER_SRAM_END - BOOTLOADER_IRAM_LOADER_SEG_LEN) +#define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN) +#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_IRAM_SEG_START - BOOTLOADER_DRAM_SEG_LEN) + +/* Flash */ +#ifdef CONFIG_FLASH_SIZE +#define FLASH_SIZE CONFIG_FLASH_SIZE +#else +#define FLASH_SIZE 0x400000 +#endif + +/* Cached memory */ +#define CACHE_ALIGN CONFIG_MMU_PAGE_SIZE +#define IROM_SEG_ORG 0x42000000 +#define IROM_SEG_LEN FLASH_SIZE +#define DROM_SEG_ORG 0x42800000 +#define DROM_SEG_LEN FLASH_SIZE diff --git a/soc/espressif/esp32h2/pinctrl_soc.h b/soc/espressif/esp32h2/pinctrl_soc.h new file mode 100644 index 0000000000000..ac1bfba5b4b92 --- /dev/null +++ b/soc/espressif/esp32h2/pinctrl_soc.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * ESP32H2 SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ + +#include +#include + +#include + +/** @cond INTERNAL_HIDDEN */ + +/** Type for ESP32 pin. */ +typedef struct pinctrl_soc_pin { + /** Pinmux settings (pin, direction and signal). */ + uint32_t pinmux; + /** Pincfg settings (bias). */ + uint32_t pincfg; +} pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize pinmux field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx) DT_PROP_BY_IDX(node_id, prop, idx) + +/** + * @brief Utility macro to initialize pincfg field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_ESP32_PINCFG_INIT(node_id) \ + (((ESP32_NO_PULL * DT_PROP(node_id, bias_disable)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PULL_UP * DT_PROP(node_id, bias_pull_up)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PULL_DOWN * DT_PROP(node_id, bias_pull_down)) << ESP32_PIN_BIAS_SHIFT) | \ + ((ESP32_PUSH_PULL * DT_PROP(node_id, drive_push_pull)) << ESP32_PIN_DRV_SHIFT) | \ + ((ESP32_OPEN_DRAIN * DT_PROP(node_id, drive_open_drain)) << ESP32_PIN_DRV_SHIFT) | \ + ((ESP32_PIN_OUT_HIGH * DT_PROP(node_id, output_high)) << ESP32_PIN_OUT_SHIFT) | \ + ((ESP32_PIN_OUT_LOW * DT_PROP(node_id, output_low)) << ESP32_PIN_OUT_SHIFT) | \ + ((ESP32_PIN_OUT_EN * DT_PROP(node_id, output_enable)) << ESP32_PIN_EN_DIR_SHIFT) | \ + ((ESP32_PIN_IN_EN * DT_PROP(node_id, input_enable)) << ESP32_PIN_EN_DIR_SHIFT)) + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + {.pinmux = Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx), \ + .pincfg = Z_PINCTRL_ESP32_PINCFG_INIT(node_id)}, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +#endif /* ZEPHYR_SOC_RISCV_ESP32H2_PINCTRL_SOC_H_ */ diff --git a/soc/espressif/esp32h2/soc.c b/soc/espressif/esp32h2/soc.c new file mode 100644 index 0000000000000..47d417a2c21f5 --- /dev/null +++ b/soc/espressif/esp32h2/soc.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void esp_reset_reason_init(void); + +void IRAM_ATTR __esp_platform_app_start(void) +{ + esp_reset_reason_init(); + + esp_timer_early_init(); + + esp_flash_config(); + + esp_efuse_init_virtual(); + + /* Start Zephyr */ + z_cstart(); + + CODE_UNREACHABLE; +} + +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ + /* Start Zephyr */ + z_cstart(); + + CODE_UNREACHABLE; +} + +/* Boot-time static default printk handler, possibly to be overridden later. */ +int IRAM_ATTR arch_printk_char_out(int c) +{ + if (c == '\n') { + esp_rom_uart_tx_one_char('\r'); + } + esp_rom_uart_tx_one_char(c); + return 0; +} + +void sys_arch_reboot(int type) +{ + esp_restart(); +} diff --git a/soc/espressif/esp32h2/soc.h b/soc/espressif/esp32h2/soc.h new file mode 100644 index 0000000000000..b7590d4c7d0e0 --- /dev/null +++ b/soc/espressif/esp32h2/soc.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_H__ +#define __SOC_H__ + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include +#include +#include +#endif + +/* ECALL Exception numbers */ +#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ +#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ + +/* Interrupt Mask */ +#define SOC_MCAUSE_IRQ_MASK (1 << 31) +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF + +#ifndef _ASMLANGUAGE + +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); + +static inline uint32_t esp_core_id(void) +{ + return 0; +} + +extern void esp_reset_reason_init(void); +extern void esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num); +extern void esp_rom_intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num); +extern void esp_rom_uart_attach(void); +extern void esp_rom_uart_tx_wait_idle(uint8_t uart_no); +extern int esp_rom_uart_tx_one_char(uint8_t chr); +extern int esp_rom_gpio_matrix_in(uint32_t gpio, uint32_t signal_index, bool inverted); +extern int esp_rom_gpio_matrix_out(uint32_t gpio, uint32_t signal_index, bool out_inverted, + bool out_enabled_inverted); +extern void esp_rom_ets_set_user_start(uint32_t start); +extern void esprv_intc_int_set_threshold(int priority_threshold); +uint32_t soc_intr_get_next_source(void); +extern void esp_rom_Cache_Resume_ICache(uint32_t autoload); +extern int esp_rom_Cache_Invalidate_Addr(uint32_t addr, uint32_t size); +extern uint32_t esp_rom_Cache_Suspend_ICache(void); +extern void esp_rom_Cache_Invalidate_ICache_All(void); +extern int esp_rom_Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, + uint32_t psize, uint32_t num, uint32_t fixed); +extern int esp_rom_Cache_Ibus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, + uint32_t psize, uint32_t num, uint32_t fixed); + +#endif /* _ASMLANGUAGE */ + +#endif /* __SOC_H__ */ diff --git a/soc/espressif/esp32h2/soc_irq.S b/soc/espressif/esp32h2/soc_irq.S new file mode 100644 index 0000000000000..90c016792fd31 --- /dev/null +++ b/soc/espressif/esp32h2/soc_irq.S @@ -0,0 +1,15 @@ +/* Copyright 2025 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_handle_irq) + +SECTION_FUNC(exception.other, __soc_handle_irq) + + /* int status clearing is done at ISR */ + ret diff --git a/soc/espressif/esp32h2/vectors.S b/soc/espressif/esp32h2/vectors.S new file mode 100644 index 0000000000000..1e1910ea602d2 --- /dev/null +++ b/soc/espressif/esp32h2/vectors.S @@ -0,0 +1,35 @@ +/* Copyright 2025 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/interrupt_reg.h" +#include "riscv/rvruntime-frames.h" +#include "soc/soc_caps.h" +#include + +/* Imports */ +GTEXT(_isr_wrapper) + + /* This is the vector table. MTVEC points here. + * + * Use 4-byte intructions here. 1 instruction = 1 entry of the table. + * The CPU jumps to MTVEC (i.e. the first entry) in case of an exception, + * and (MTVEC & 0xfffffffc) + (mcause & 0x7fffffff) * 4, in case of an interrupt. + * + * Note: for our CPU, we need to place this on a 256-byte boundary, as CPU + * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). + */ + + .global _vector_table + .section .exception_vectors.text + .balign 0x100 + .type _vector_table, @function + +_vector_table: + .option push + .option norvc + .rept (32) + j _isr_wrapper /* 32 identical entries, all pointing to the interrupt handler */ + .endr diff --git a/soc/espressif/soc.yml b/soc/espressif/soc.yml index cd20df8a60b1c..a883b3b792810 100644 --- a/soc/espressif/soc.yml +++ b/soc/espressif/soc.yml @@ -28,3 +28,6 @@ family: cpuclusters: - name: hpcore - name: lpcore + - name: esp32h2 + socs: + - name: esp32h2 From 6293140ff61e835dc7c7e993572b50d09ba6dfdd Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 29 Jul 2025 17:31:14 -0300 Subject: [PATCH 0092/1076] drivers: clock_control: esp32h2: Add support Add clock control support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/clock_control/clock_control_esp32.c | 85 +++++++++++++++---- .../clock_control/esp32_clock_control.h | 4 +- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index 48a72c9967e77..beb7b794c9743 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -49,6 +49,18 @@ #include #include #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#define DT_CPU_COMPAT espressif_riscv +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif #include @@ -85,10 +97,13 @@ static bool reset_reason_is_cpu_reset(void) return false; } -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) static void esp32_clock_perip_init(void) { soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get(); + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + +#if defined(CONFIG_SOC_SERIES_ESP32C6) modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)((rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW @@ -101,19 +116,36 @@ static void esp32_clock_perip_init(void) : MODEM_CLOCK_LPCLK_SRC_RC_SLOW); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); - - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + esp_sleep_pd_domain_t pu_domain = + (esp_sleep_pd_domain_t)((rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) + ? ESP_PD_DOMAIN_XTAL32K + : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) + ? ESP_PD_DOMAIN_RC32K + : ESP_PD_DOMAIN_MAX); + esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON); +#endif if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) && (rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT)) { +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + periph_ll_disable_clk_set_rst(PERIPH_UART0_MODULE); +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 periph_ll_disable_clk_set_rst(PERIPH_UART1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_I2C0_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32H2) + periph_ll_disable_clk_set_rst(PERIPH_I2C1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_RMT_MODULE); periph_ll_disable_clk_set_rst(PERIPH_LEDC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_TIMG1_MODULE); periph_ll_disable_clk_set_rst(PERIPH_TWAI0_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_TWAI1_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_I2S1_MODULE); periph_ll_disable_clk_set_rst(PERIPH_PCNT_MODULE); periph_ll_disable_clk_set_rst(PERIPH_ETM_MODULE); @@ -124,17 +156,24 @@ static void esp32_clock_perip_init(void) periph_ll_disable_clk_set_rst(PERIPH_TEMPSENSOR_MODULE); periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); +#if defined(CONFIG_SOC_SERIES_ESP32H2) + periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE); +#endif REG_CLR_BIT(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); +#if defined(CONFIG_SOC_SERIES_ESP32C6) REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN); +#endif REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN); @@ -150,8 +189,9 @@ static void esp32_clock_perip_init(void) (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT)) { +#if defined(CONFIG_SOC_SERIES_ESP32C6) periph_ll_disable_clk_set_rst(PERIPH_LP_I2C0_MODULE); - +#endif CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_RNG_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_LP_UART_CK_EN); CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_OTP_DBG_CK_EN); @@ -544,7 +584,7 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) { -#if !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C6) && !defined(CONFIG_SOC_SERIES_ESP32H2) soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V; #else soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk; @@ -600,7 +640,7 @@ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) return -ENODEV; } } -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { rtc_clk_rc32k_enable(true); } @@ -642,11 +682,21 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf #if defined(CONFIG_SOC_SERIES_ESP32C6) rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); - REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, rtc_clk_cfg.clk_8m_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); - REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, rtc_clk_cfg.rc32k_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OC_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0); +#else + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, rtc_clk_cfg.clk_8m_dfreq); +#endif + +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) + REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, rtc_clk_cfg.clk_8m_dfreq); + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, rtc_clk_cfg.rc32k_dfreq); uint32_t hp_cali_dbias = get_act_hp_dbias(); uint32_t lp_cali_dbias = get_act_lp_dbias(); @@ -657,15 +707,11 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - -#else - REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, rtc_clk_cfg.slow_clk_dcap); - REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, rtc_clk_cfg.clk_8m_dfreq); #endif #if defined(CONFIG_SOC_SERIES_ESP32) REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, rtc_clk_cfg.clk_8m_div - 1); -#elif defined(CONFIG_SOC_SERIES_ESP32C6) +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) clk_ll_rc_fast_tick_conf(); esp_rom_uart_tx_wait_idle(0); @@ -678,7 +724,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf rtc_clk_8m_divider_set(rtc_clk_cfg.clk_8m_clk_div); #endif -#if !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C6) && !defined(CONFIG_SOC_SERIES_ESP32H2) /* Reset (disable) i2c internal bus for all regi2c registers */ regi2c_ctrl_ll_i2c_reset(); /* Enable the internal bus used to configure BBPLL */ @@ -699,7 +745,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf * to make it run at 80MHz after the switch. PLL = 480MHz, so divider is 6. */ clk_ll_mspi_fast_set_hs_divider(6); -#else +#elif !defined(CONFIG_SOC_SERIES_ESP32H2) rtc_clk_apb_freq_update(rtc_clk_cfg.xtal_freq * MHZ(1)); #endif @@ -719,7 +765,8 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf old_config.freq_mhz); #if defined(CONFIG_ESP_CONSOLE_UART) -#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C6) +#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C6) && \ + !defined(CONFIG_SOC_SERIES_ESP32H2) #if defined(CONFIG_MCUBOOT) && defined(ESP_ROM_UART_CLK_IS_XTAL) uint32_t uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); #else @@ -775,7 +822,9 @@ static int clock_control_esp32_init(const struct device *dev) if (rst_reas == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } -#else /* CONFIG_SOC_SERIES_ESP32C6 */ +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + pmu_init(); +#else /* CONFIG_SOC_SERIES_ESP32C6 || CONFIG_SOC_SERIES_ESP32H2 */ rtc_config_t rtc_cfg = RTC_CONFIG_DEFAULT(); #if !defined(CONFIG_SOC_SERIES_ESP32) @@ -788,7 +837,7 @@ static int clock_control_esp32_init(const struct device *dev) } #endif /* !CONFIG_SOC_SERIES_ESP32 */ rtc_init(rtc_cfg); -#endif /* CONFIG_SOC_SERIES_ESP32C6 */ +#endif /* CONFIG_SOC_SERIES_ESP32C6 || CONFIG_SOC_SERIES_ESP32H2 */ ret = esp32_cpu_clock_configure(&cfg->cpu); if (ret) { diff --git a/include/zephyr/drivers/clock_control/esp32_clock_control.h b/include/zephyr/drivers/clock_control/esp32_clock_control.h index eb6bebc138ef8..a56e9142e9d5d 100644 --- a/include/zephyr/drivers/clock_control/esp32_clock_control.h +++ b/include/zephyr/drivers/clock_control/esp32_clock_control.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,8 @@ #include #elif defined(CONFIG_SOC_SERIES_ESP32C6) #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include #endif /* CONFIG_SOC_SERIES_ESP32xx */ #define ESP32_CLOCK_CONTROL_SUBSYS_CPU 50 From 9d257c362f698f7fd17d00292736ba48525d5347 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 10:16:44 -0300 Subject: [PATCH 0093/1076] drivers: pinctrl: esp32h2: Add support Add pinctrl support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/pinctrl/pinctrl_esp32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl_esp32.c b/drivers/pinctrl/pinctrl_esp32.c index 4ed39229d5625..eacf62a668135 100644 --- a/drivers/pinctrl/pinctrl_esp32.c +++ b/drivers/pinctrl/pinctrl_esp32.c @@ -23,8 +23,8 @@ #define in in.data #define out_w1ts out_w1ts.val #define out_w1tc out_w1tc.val -#elif CONFIG_SOC_SERIES_ESP32C6 -/* gpio structs in esp32c6 are also different */ +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) +/* gpio structs in esp32c6/h2 are also different */ #define out out.out_data_orig #define in in.in_data_next #define out_w1ts out_w1ts.val From 270307f61d9ebfbc8fe912807304d6aec5da9f16 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:41:29 -0300 Subject: [PATCH 0094/1076] drivers: gpio: esp32h2: Add support Add gpio support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/gpio/gpio_esp32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_esp32.c b/drivers/gpio/gpio_esp32.c index 289565302bffd..33d7396997520 100644 --- a/drivers/gpio/gpio_esp32.c +++ b/drivers/gpio/gpio_esp32.c @@ -44,8 +44,8 @@ LOG_MODULE_REGISTER(gpio_esp32, CONFIG_LOG_DEFAULT_LEVEL); #define out_w1tc out_w1tc.val /* arch_curr_cpu() is not available for riscv based chips */ #define ESP32_CPU_ID() 0 -#elif defined(CONFIG_SOC_SERIES_ESP32C6) -/* gpio structs in esp32c6 are also different */ +#elif defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) +/* gpio structs in esp32c6/h2 are also different */ #define out out.out_data_orig #define in in.in_data_next #define out_w1ts out_w1ts.val From d1ecc51dcd690c5ce1876db613982eb38e8a2f6d Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:41:52 -0300 Subject: [PATCH 0095/1076] drivers: uart: esp32h2: Add support Add UART support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/serial/uart_esp32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index bf519b041943e..32505a4750cf5 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -33,6 +33,10 @@ #include #include #include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include +#include +#include #endif #ifdef CONFIG_UART_ASYNC_API #include From 36c528316d4f88e50bd2771d5b97a2be343ace1f Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 14:42:19 -0300 Subject: [PATCH 0096/1076] drivers: systimer: esp32h2: Add support Add systimer support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/timer/Kconfig.esp32 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.esp32 b/drivers/timer/Kconfig.esp32 index ff10f017866d7..1a61d02d46966 100644 --- a/drivers/timer/Kconfig.esp32 +++ b/drivers/timer/Kconfig.esp32 @@ -1,11 +1,13 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Cadence Design Systems, Inc. # Copyright (c) 2019 Intel Corp. +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 config ESP32_SYS_TIMER bool "ESP32 sys-timer support (ESP32Cx series)" - depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || (SOC_SERIES_ESP32C6 && !SOC_ESP32C6_LPCORE) + depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || \ + (SOC_SERIES_ESP32C6 && !SOC_ESP32C6_LPCORE) || SOC_SERIES_ESP32H2 default y select TICKLESS_CAPABLE select TIMER_HAS_64BIT_CYCLE_COUNTER From 1bd2734991cc07b3bdbfd1d2a221ac791c4079b2 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 11:43:02 -0300 Subject: [PATCH 0097/1076] drivers: wdt: esp32h2: Add support Add WDT support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/watchdog/wdt_esp32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_esp32.c b/drivers/watchdog/wdt_esp32.c index acaf7d7ce0c31..c045d8922bab9 100644 --- a/drivers/watchdog/wdt_esp32.c +++ b/drivers/watchdog/wdt_esp32.c @@ -7,7 +7,7 @@ #define DT_DRV_COMPAT espressif_esp32_watchdog -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(CONFIG_SOC_SERIES_ESP32C6) || defined(CONFIG_SOC_SERIES_ESP32H2) #include #else #include From c5770e1b14cac846d9ce9eb1a1a0c5a9825eda80 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 6 Aug 2025 11:59:21 -0300 Subject: [PATCH 0098/1076] drivers: hwinfo: esp32h2: Add support Add hwinfo support for ESP32-H2. Signed-off-by: Raffael Rostagno --- drivers/hwinfo/hwinfo_esp32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hwinfo/hwinfo_esp32.c b/drivers/hwinfo/hwinfo_esp32.c index 5a453a000518d..39fbc5b18691b 100644 --- a/drivers/hwinfo/hwinfo_esp32.c +++ b/drivers/hwinfo/hwinfo_esp32.c @@ -18,6 +18,9 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) #if defined(CONFIG_SOC_SERIES_ESP32C2) uint32_t rdata1 = sys_read32(EFUSE_RD_BLK2_DATA0_REG); uint32_t rdata2 = sys_read32(EFUSE_RD_BLK2_DATA1_REG); +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + uint32_t rdata1 = sys_read32(EFUSE_RD_MAC_SYS_0_REG); + uint32_t rdata2 = sys_read32(EFUSE_RD_MAC_SYS_1_REG); #elif !defined(CONFIG_SOC_SERIES_ESP32) uint32_t rdata1 = sys_read32(EFUSE_RD_MAC_SPI_SYS_0_REG); uint32_t rdata2 = sys_read32(EFUSE_RD_MAC_SPI_SYS_1_REG); From ebd1b1c44be3b69c6fa116963d866d61a2801e6e Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 30 Jul 2025 15:13:34 -0300 Subject: [PATCH 0099/1076] boards: esp32h2_devkitm: Add initial support Add initial support for esp32h2_devkitm. Signed-off-by: Raffael Rostagno --- boards/espressif/esp32h2_devkitm/Kconfig | 6 + .../esp32h2_devkitm/Kconfig.esp32h2_devkitm | 7 + .../esp32h2_devkitm/Kconfig.sysbuild | 10 ++ boards/espressif/esp32h2_devkitm/board.cmake | 9 ++ boards/espressif/esp32h2_devkitm/board.yml | 6 + .../doc/img/esp32h2_devkitm.webp | Bin 0 -> 37406 bytes .../espressif/esp32h2_devkitm/doc/index.rst | 124 ++++++++++++++++++ .../esp32h2_devkitm-pinctrl.dtsi | 23 ++++ .../esp32h2_devkitm/esp32h2_devkitm.dts | 62 +++++++++ .../esp32h2_devkitm/esp32h2_devkitm.yaml | 13 ++ .../esp32h2_devkitm/esp32h2_devkitm_defconfig | 6 + .../esp32h2_devkitm/support/openocd.cfg | 4 + 12 files changed, 270 insertions(+) create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm create mode 100644 boards/espressif/esp32h2_devkitm/Kconfig.sysbuild create mode 100644 boards/espressif/esp32h2_devkitm/board.cmake create mode 100644 boards/espressif/esp32h2_devkitm/board.yml create mode 100644 boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp create mode 100644 boards/espressif/esp32h2_devkitm/doc/index.rst create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml create mode 100644 boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig create mode 100644 boards/espressif/esp32h2_devkitm/support/openocd.cfg diff --git a/boards/espressif/esp32h2_devkitm/Kconfig b/boards/espressif/esp32h2_devkitm/Kconfig new file mode 100644 index 0000000000000..c96fa92d3431f --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 diff --git a/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm b/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm new file mode 100644 index 0000000000000..905e66f73c662 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig.esp32h2_devkitm @@ -0,0 +1,7 @@ +# ESP32-H2 DevKitM board configuration + +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32H2_DEVKITM + select SOC_ESP32_H2_MINI_H4 diff --git a/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild b/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild new file mode 100644 index 0000000000000..95e4e1d103975 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/espressif/esp32h2_devkitm/board.cmake b/boards/espressif/esp32h2_devkitm/board.cmake new file mode 100644 index 0000000000000..2f04d1fe8861e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/espressif/esp32h2_devkitm/board.yml b/boards/espressif/esp32h2_devkitm/board.yml new file mode 100644 index 0000000000000..55e4ccba12051 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/board.yml @@ -0,0 +1,6 @@ +board: + name: esp32h2_devkitm + full_name: ESP32-H2-DevKitM + vendor: espressif + socs: + - name: esp32h2 diff --git a/boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp b/boards/espressif/esp32h2_devkitm/doc/img/esp32h2_devkitm.webp new file mode 100644 index 0000000000000000000000000000000000000000..187f8192d5fb2cc7adb6f63405ae5029e54dc04f GIT binary patch literal 37406 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�#j#mra-{G?T#m9 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 K000000002{%U1#b literal 0 HcmV?d00001 diff --git a/boards/espressif/esp32h2_devkitm/doc/index.rst b/boards/espressif/esp32h2_devkitm/doc/index.rst new file mode 100644 index 0000000000000..5e653fbf564c4 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/doc/index.rst @@ -0,0 +1,124 @@ +.. zephyr:board:: esp32h2_devkitm + +Overview +******** + +ESP32-H2-DevKitM-1 is an entry-level development board based on the ESP32-H2-MINI-1 module, +which integrates Bluetooth® Low Energy (LE) and IEEE 802.15.4 connectivity. It features +the ESP32-H2 SoC — a 32-bit RISC-V core designed for low-power, secure wireless communication, +supporting Bluetooth 5 (LE), Bluetooth Mesh, Thread, Matter, and Zigbee protocols. +This module is ideal for a wide range of low-power IoT applications. + +For details on getting started, check `ESP32-H2-DevKitM-1`_. + +Hardware +******** + +ESP32-H2 combines IEEE 802.15.4 connectivity with Bluetooth 5 (LE). The SoC is powered by +a single-core, 32-bit RISC-V microcontroller that can be clocked up to 96 MHz. The ESP32-H2 has +been designed to ensure low power consumption and security for connected devices. ESP32-H2 has +320 KB of SRAM with 16 KB of Cache, 128 KB of ROM, 4 KB LP of memory, and a built-in 2 MB or 4 MB +SiP flash. It has 19 programmable GPIOs with support for ADC, SPI, UART, I2C, I2S, RMT, GDMA +and LED PWM. + +Most of ESP32-H2-DevKitM-1's I/O pins are broken out to the pin headers on both sides for easy +interfacing. Developers can either connect peripherals with jumper wires or mount the board +on a breadboard. + +ESP32-H2 main features: + +- RISC-V 32-bit single-core microprocessor +- 320 KB of internal RAM +- 4 KB LP Memory +- Bluetooth LE: Bluetooth 5.3 certified +- IEEE 802.15.4 (Zigbee and Thread) +- 19 programmable GPIOs +- Numerous peripherals (details below) + +Digital interfaces: + +- 19x GPIOs +- 2x UART +- 2x I2C +- 1x General-purpose SPI +- 1x I2S +- 1x Pulse counter +- 1x USB Serial/JTAG controller +- 1x TWAI® controller, compatible with ISO 11898-1 (CAN Specification 2.0) +- 1x LED PWM controller, up to 6 channels +- 1x Motor Control PWM (MCPWM) +- 1x Remote Control peripheral (RMT), with up to 2 TX and 2 RX channels +- 1x Parallel IO interface (PARLIO) +- General DMA controller (GDMA), with 3 transmit channels and 3 receive channels +- Event Task Matrix (ETM) + +Analog interfaces: + +- 1x 12-bit SAR ADCs, up to 5 channels +- 1x Temperature sensor (die) + +Timers: + +- 1x 52-bit system timer +- 2x 54-bit general-purpose timers +- 3x Watchdog timers + +Low Power: + +- Four power modes designed for typical scenarios: Active, Modem-sleep, Light-sleep, Deep-sleep + +Security: + +- Secure boot +- Flash encryption +- 4-Kbit OTP, up to 1792 bits for users +- Cryptographic hardware acceleration: (AES-128/256, ECC, HMAC, RSA, SHA, Digital signature, Hash) +- Random number generator (RNG) + +For detailed information, check the datasheet at `ESP32-H2 Datasheet`_ or the Technical Reference +Manual at `ESP32-H2 Technical Reference Manual`_. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +System requirements +******************* + +Espressif HAL requires Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Runners +******* + +.. zephyr:board-supported-runners:: + +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing + +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants + +Debugging +********* + +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging + +References +********** + +.. target-notes:: + +.. _`ESP32-H2-DevKitM-1`: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32h2/esp32-h2-devkitm-1/user_guide.html +.. _`ESP32-H2 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf +.. _`ESP32-H2 Technical Reference Manual`: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi new file mode 100644 index 0000000000000..52206c1e66ba3 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts new file mode 100644 index 0000000000000..c05e910198a8e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.dts @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "esp32h2_devkitm-pinctrl.dtsi" +#include +#include + +/ { + model = "Espressif ESP32H2-DevkitM"; + compatible = "espressif,esp32h2"; + + chosen { + zephyr,sram = &sramhp; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + sw0 = &user_button1; + watchdog0 = &wdt0; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button1: button_1 { + label = "User SW1"; + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&coretemp { + status = "okay"; +}; diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml new file mode 100644 index 0000000000000..06c340f11efb7 --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml @@ -0,0 +1,13 @@ +identifier: esp32h2_devkitm/esp32h2 +name: ESP32-H2-DevKitM +vendor: espressif +type: mcu +arch: riscv +toolchain: + - zephyr +supported: + - gpio + - watchdog + - uart + - counter + - entropy diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig new file mode 100644 index 0000000000000..187793c76e8cc --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/espressif/esp32h2_devkitm/support/openocd.cfg b/boards/espressif/esp32h2_devkitm/support/openocd.cfg new file mode 100644 index 0000000000000..5dac2bad03f9e --- /dev/null +++ b/boards/espressif/esp32h2_devkitm/support/openocd.cfg @@ -0,0 +1,4 @@ +# ESP32H2 has built-in JTAG interface over USB port in pins GPIO26/GPIO27 (D-/D+). +set ESP_RTOS none + +source [find board/esp32h2-builtin.cfg] From c7a295b068c2a38d7adaa70b14dddc2a03e40ccd Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:00:11 -0300 Subject: [PATCH 0100/1076] tests: clock: esp32h2: Add testcase Render test settings more generic regarding clock options, in order to better support new devices. Add ESP32-H2 testcase to rtc_clk suite. Signed-off-by: Raffael Rostagno --- .../espressif/rtc_clk/src/rtc_clk_test.c | 35 +++++++++++++------ tests/boards/espressif/rtc_clk/testcase.yaml | 1 + 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c index 41071af768f7e..6933849e3942f 100644 --- a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c +++ b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,8 +15,7 @@ #define DT_CPU_COMPAT espressif_xtensa_lx6 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) #define DT_CPU_COMPAT espressif_xtensa_lx7 -#elif defined(CONFIG_SOC_SERIES_ESP32C2) || defined(CONFIG_SOC_SERIES_ESP32C3) || \ - defined(CONFIG_SOC_SERIES_ESP32C6) +#elif defined(CONFIG_RISCV) #define DT_CPU_COMPAT espressif_riscv #endif @@ -74,14 +73,22 @@ ZTEST(rtc_clk, test_cpu_xtal_src) } uint32_t rtc_pll_src_freq_mhz[] = { +#if defined(ESP32_CLK_CPU_PLL_48M) + ESP32_CLK_CPU_PLL_48M, +#endif +#if defined(ESP32_CLK_CPU_PLL_80M) ESP32_CLK_CPU_PLL_80M, -#if defined(CONFIG_SOC_SERIES_ESP32C2) +#endif +#if defined(ESP32_CLK_CPU_PLL_96M) + ESP32_CLK_CPU_PLL_96M, +#endif +#if defined(ESP32_CLK_CPU_PLL_120M) ESP32_CLK_CPU_PLL_120M, -#else +#endif +#if defined(ESP32_CLK_CPU_PLL_160M) ESP32_CLK_CPU_PLL_160M, #endif -#if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C3) && \ - !defined(CONFIG_SOC_SERIES_ESP32C6) +#if defined(ESP32_CLK_CPU_PLL_240M) ESP32_CLK_CPU_PLL_240M, #endif }; @@ -159,10 +166,13 @@ ZTEST(rtc_clk, test_rtc_fast_src) } uint32_t rtc_rtc_slow_clk_src[] = { +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_SLOW) ESP32_RTC_SLOW_CLK_SRC_RC_SLOW, -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC32K) ESP32_RTC_SLOW_CLK_SRC_RC32K, -#else +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256) ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256, #endif #if CONFIG_FIXTURE_XTAL @@ -171,10 +181,13 @@ uint32_t rtc_rtc_slow_clk_src[] = { }; uint32_t rtc_rtc_slow_clk_src_freq[] = { +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ, -#if defined(CONFIG_SOC_SERIES_ESP32C6) +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ, -#else +#endif +#if defined(ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256_FREQ) ESP32_RTC_SLOW_CLK_SRC_RC_FAST_D256_FREQ, #endif #if CONFIG_FIXTURE_XTAL diff --git a/tests/boards/espressif/rtc_clk/testcase.yaml b/tests/boards/espressif/rtc_clk/testcase.yaml index 1090148d4661f..3cbc65b01b604 100644 --- a/tests/boards/espressif/rtc_clk/testcase.yaml +++ b/tests/boards/espressif/rtc_clk/testcase.yaml @@ -7,6 +7,7 @@ tests: - esp32_devkitc/esp32/procpu - esp32c3_devkitm - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm - esp32s2_saola - esp32s3_devkitm/esp32s3/procpu boards.esp32.rtc_clk.xtal: From 4cad8d65ffe4aa23aae1c45ffccac4c90a3fbc57 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Tue, 5 Aug 2025 14:26:54 -0300 Subject: [PATCH 0101/1076] tests: drivers: uart: esp32h2: Add test config Add test config for ESP32-H2. Signed-off-by: Raffael Rostagno --- .../uart/uart_elementary/socs/esp32h2.overlay | 28 +++++++++++++++++++ .../uart/uart_elementary/testcase.yaml | 1 + 2 files changed, 29 insertions(+) create mode 100644 tests/drivers/uart/uart_elementary/socs/esp32h2.overlay diff --git a/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay b/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay new file mode 100644 index 0000000000000..62292552f6d47 --- /dev/null +++ b/tests/drivers/uart/uart_elementary/socs/esp32h2.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = , + ; + input-enable; + output-high; + }; + group2 { + pinmux = , + ; + output-enable; + bias-pull-up; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + current-speed = <115200>; +}; diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index cbf222fa72cf7..d1da7ca19489a 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -22,6 +22,7 @@ tests: - esp8684_devkitm - esp32c3_devkitm - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm - esp32s2_saola - esp32s3_devkitm/esp32s3/procpu integration_platforms: From 2643ea23c0b5d8ba6a3811417b1ab1b5472f3751 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Wed, 13 Aug 2025 10:04:58 -0300 Subject: [PATCH 0102/1076] tests: drivers: counter: esp32h2: Add config Add test config for ESP32-H2. Signed-off-by: Raffael Rostagno --- .../counter/counter_basic_api/socs/esp32h2.overlay | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay diff --git a/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay b/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay new file mode 100644 index 0000000000000..654ca2b00155f --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/socs/esp32h2.overlay @@ -0,0 +1,13 @@ +&timer0 { + status = "okay"; + counter { + status = "okay"; + }; +}; + +&timer1 { + status = "okay"; + counter { + status = "okay"; + }; +}; From efacee0145ae180759518e04ef9218ced9437989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Phil=C3=A9mon=20Jaermann?= Date: Fri, 22 Aug 2025 17:10:46 +0200 Subject: [PATCH 0103/1076] drivers: gnss: Correctly set the 1 bit bitfield is_tracked/corrected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, if a SV is tracked, we try to store: flags & BIT(3) -> 0b1000 -> least significant bit 0 is stored. Same is valid for the is_corrected field. Use double negation to treat any non-zero value as true. Signed-off-by: Philémon Jaermann --- drivers/gnss/gnss_ubx_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gnss/gnss_ubx_common.c b/drivers/gnss/gnss_ubx_common.c index 73998442562e1..35d0769098cbf 100644 --- a/drivers/gnss/gnss_ubx_common.c +++ b/drivers/gnss/gnss_ubx_common.c @@ -136,8 +136,8 @@ void gnss_ubx_common_satellite_callback(struct modem_ubx *ubx, const struct ubx_ .elevation = ubx_sat->sat[i].elevation, .azimuth = ubx_sat->sat[i].azimuth, .system = gnss_system, - .is_tracked = (ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_SV_USED), - .is_corrected = (ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_RTCM_CORR_USED) + .is_tracked = !!(ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_SV_USED), + .is_corrected = !!(ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_RTCM_CORR_USED) }; data->satellites.data[i] = sat; From 8ea45f3a72460b64d7828c6819ab73a1275c3e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 18:21:32 +0200 Subject: [PATCH 0104/1076] doc: groups.dox: add device management group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that subsystems such as MCUmgr, EC Host Command, etc. are grouped under a Device Management group instead of showing up as top-level "OS Services". Signed-off-by: Benjamin Cabé --- doc/_doxygen/groups.dox | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/_doxygen/groups.dox b/doc/_doxygen/groups.dox index 94d6be6db0fae..603791b3fd468 100644 --- a/doc/_doxygen/groups.dox +++ b/doc/_doxygen/groups.dox @@ -9,15 +9,6 @@ @defgroup os_services Operating System Services @brief Operating System Services @{ - -@brief MCUmgr -@defgroup mcumgr MCUmgr -@{ -@defgroup mcumgr_transport Transport layers -@{ -@} -@} - @} @brief Device Driver APIs @@ -48,6 +39,21 @@ @{ @} +@brief Device Management +@defgroup device_mgmt Device Management +@ingroup os_services +@{ +@} + +@brief MCUmgr +@defgroup mcumgr MCUmgr +@ingroup device_mgmt + +@brief Transport layers for MCUmgr: SMP, UART, etc. +@defgroup mcumgr_transport Transport layers +@{ +@} + @brief Connectivity @defgroup connectivity Connectivity @{ From 98b006566da7480f327f5c564a5d16bdfd8d5701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 18:32:22 +0200 Subject: [PATCH 0105/1076] include: ec_host_cmd: doxygen improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add some missing docs - make sure API guarded by Kconfig is showing up in the docs - show EC Host Command docs in the Device Management group - re-arrange groups for backends and simulator API Signed-off-by: Benjamin Cabé --- include/zephyr/mgmt/ec_host_cmd/backend.h | 24 +++-- include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h | 96 ++++++++++++++----- include/zephyr/mgmt/ec_host_cmd/simulator.h | 18 +++- 3 files changed, 101 insertions(+), 37 deletions(-) diff --git a/include/zephyr/mgmt/ec_host_cmd/backend.h b/include/zephyr/mgmt/ec_host_cmd/backend.h index 66f04e97868f4..c0c4b9f643508 100644 --- a/include/zephyr/mgmt/ec_host_cmd/backend.h +++ b/include/zephyr/mgmt/ec_host_cmd/backend.h @@ -7,11 +7,19 @@ /** * @file * @brief Public APIs for Host Command backends that respond to host commands + * @ingroup ec_host_cmd_backend */ #ifndef ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_BACKEND_H_ #define ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_BACKEND_H_ +/** + * @brief Interface to EC Host Command backends + * @defgroup ec_host_cmd_backend Backends + * @ingroup ec_host_cmd_interface + * @{ + */ + #include #include #include @@ -22,20 +30,16 @@ extern "C" { #endif +/** + * @brief EC Host Command Backend + */ struct ec_host_cmd_backend { - /** API provided by the backed. */ + /** API provided by the backend. */ const struct ec_host_cmd_backend_api *api; - /** Context for the backed. */ + /** Context for the backend. */ void *ctx; }; -/** - * @brief EC Host Command Interface - * @defgroup ec_host_cmd_interface EC Host Command Interface - * @ingroup io_interfaces - * @{ - */ - /** * @brief Context for host command backend and handler to pass rx data. */ @@ -58,7 +62,7 @@ struct ec_host_cmd_rx_ctx { */ struct ec_host_cmd_tx_buf { /** - * Data to write to the host The buffer is provided by the handler if + * Data to write to the host. The buffer is provided by the handler if * CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE > 0. Otherwise, the backend should provide * the buffer on its own and overwrites @a buf pointer and @a len_max * in the init function. diff --git a/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h b/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h index 9a01116c9e4af..f08639383bc7c 100644 --- a/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h +++ b/include/zephyr/mgmt/ec_host_cmd/ec_host_cmd.h @@ -12,7 +12,7 @@ * @defgroup ec_host_cmd_interface EC Host Command Interface * @since 2.4 * @version 0.1.0 - * @ingroup io_interfaces + * @ingroup device_mgmt * @{ */ @@ -72,24 +72,54 @@ enum ec_host_cmd_status { EC_HOST_CMD_MAX = UINT16_MAX /* Force enum to be 16 bits. */ } __packed; +/** + * @brief Host command log levels + */ enum ec_host_cmd_log_level { - EC_HOST_CMD_DEBUG_OFF, /* No Host Command debug output */ - EC_HOST_CMD_DEBUG_NORMAL, /* Normal output mode; skips repeated commands */ - EC_HOST_CMD_DEBUG_EVERY, /* Print every command */ - EC_HOST_CMD_DEBUG_PARAMS, /* ... and print params for request/response */ - EC_HOST_CMD_DEBUG_MODES /* Number of host command debug modes */ + EC_HOST_CMD_DEBUG_OFF, /**< No Host Command debug output */ + EC_HOST_CMD_DEBUG_NORMAL, /**< Normal output mode; skips repeated commands */ + EC_HOST_CMD_DEBUG_EVERY, /**< Print every command */ + EC_HOST_CMD_DEBUG_PARAMS, /**< ... and print params for request/response */ + EC_HOST_CMD_DEBUG_MODES /**< Number of host command debug modes */ }; +/** + * @brief Host command state + */ enum ec_host_cmd_state { - EC_HOST_CMD_STATE_DISABLED = 0, - EC_HOST_CMD_STATE_RECEIVING, - EC_HOST_CMD_STATE_PROCESSING, - EC_HOST_CMD_STATE_SENDING, + EC_HOST_CMD_STATE_DISABLED = 0, /**< Host command subsystem is disabled */ + EC_HOST_CMD_STATE_RECEIVING, /**< Receiving command data from host */ + EC_HOST_CMD_STATE_PROCESSING, /**< Processing received command */ + EC_HOST_CMD_STATE_SENDING, /**< Sending response to host */ }; +/** + * @brief User callback function type for host command reception + * + * This callback is invoked after a host command is received and validated + * but before command processing begins. It allows user code to perform + * custom actions based on the received command. + * + * @param rx_ctx Pointer to the receive context containing command data + * @param user_data User-defined data pointer passed during callback registration + */ typedef void (*ec_host_cmd_user_cb_t)(const struct ec_host_cmd_rx_ctx *rx_ctx, void *user_data); + +/** + * @brief In-progress callback function type + * + * This callback is executed asynchronously for commands that return + * EC_HOST_CMD_IN_PROGRESS status. It allows long-running operations + * to complete in the background. + * + * @param user_data User-provided data passed to the callback + * @return Final status code for the command + */ typedef enum ec_host_cmd_status (*ec_host_cmd_in_progress_cb_t)(void *user_data); +/** + * Host command context structure + */ struct ec_host_cmd { struct ec_host_cmd_rx_ctx rx_ctx; struct ec_host_cmd_tx_buf tx; @@ -138,7 +168,19 @@ struct ec_host_cmd_handler_args { uint16_t output_buf_size; }; +/** + * @brief Host command handler callback function type + * + * This callback is invoked to process a host command that matches the handler's + * command ID and version. The handler processes the incoming command data and + * generates a response. + * + * @param args Pointer to an @ref ec_host_cmd_handler_args structure containing command data and + * buffers + * @return Status code indicating the result of command processing + */ typedef enum ec_host_cmd_status (*ec_host_cmd_handler_cb)(struct ec_host_cmd_handler_args *args); + /** * @brief Structure use for statically registering host command handlers */ @@ -334,38 +376,44 @@ const struct ec_host_cmd *ec_host_cmd_get_hc(void); FUNC_NORETURN void ec_host_cmd_task(void); #endif -#ifdef CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS +#if defined(CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS) || defined(__DOXYGEN__) /** - * @brief Check if a Host Command that sent EC_HOST_CMD_IN_PROGRESS status has ended. + * @brief Check if a Host Command that sent @ref EC_HOST_CMD_IN_PROGRESS status has ended. + * + * A Host Command that sends @ref EC_HOST_CMD_IN_PROGRESS status doesn't send a final result. + * The final result can be obtained with the @ref ec_host_cmd_send_in_progress_status function. * - * A Host Command that sends EC_HOST_CMD_IN_PROGRESS status doesn't send a final result. - * The final result can be get with the ec_host_cmd_send_in_progress_status function. + * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS} * * @retval true if the Host Command endded */ bool ec_host_cmd_send_in_progress_ended(void); /** - * @brief Get final result of a last Host Command that has sent EC_HOST_CMD_IN_PROGRESS status. + * @brief Get final result of a last Host Command that has sent @ref EC_HOST_CMD_IN_PROGRESS status. * - * A Host Command that sends EC_HOST_CMD_IN_PROGRESS status doesn't send a final result. - * Get the saved status with this function. The status can be get only once. Further calls return - * EC_HOST_CMD_UNAVAILABLE. + * A Host Command that sends @ref EC_HOST_CMD_IN_PROGRESS status doesn't send a final result. + * Get the saved status with this function. The status can be obtained only once. Further calls + * return @ref EC_HOST_CMD_UNAVAILABLE. * * Saving status of Host Commands that send response data is not supported. * + * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS} + * * @retval The final status or EC_HOST_CMD_UNAVAILABLE if not available. */ enum ec_host_cmd_status ec_host_cmd_send_in_progress_status(void); /** - * @brief Continue processing a handler in callback after returning EC_HOST_CMD_IN_PROGRESS. + * @brief Continue processing a handler in callback after returning @ref EC_HOST_CMD_IN_PROGRESS. + * + * A Host Command handler may return the @ref EC_HOST_CMD_IN_PROGRESS, but needs to continue work. + * This function should be called before returning @ref EC_HOST_CMD_IN_PROGRESS with a callback that + * will be executed. The return status of the callback will be stored and can be obtained with the + * @ref ec_host_cmd_send_in_progress_status function. The @ref ec_host_cmd_send_in_progress_ended + * function can be used to check if the callback has ended. * - * A Host Command handler may return the EC_HOST_CMD_IN_PROGRESS, but needs to continue work. - * This function should be called before returning EC_HOST_CMD_IN_PROGRESS with a callback that - * will be executed. The return status of the callback will be stored and can be get with the - * ec_host_cmd_send_in_progress_status function. The ec_host_cmd_send_in_progress_ended function - * can be used to check if the callback has ended. + * @kconfig_dep{CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS} * * @param[in] cb A callback to be called after returning from a command handler. * @param[in] user_data User data to be passed to the callback. diff --git a/include/zephyr/mgmt/ec_host_cmd/simulator.h b/include/zephyr/mgmt/ec_host_cmd/simulator.h index f6110740a9f30..3fe1afd13951e 100644 --- a/include/zephyr/mgmt/ec_host_cmd/simulator.h +++ b/include/zephyr/mgmt/ec_host_cmd/simulator.h @@ -4,13 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_SIMULATOR_H_ -#define ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_SIMULATOR_H_ - /** * @file * @brief Header for commands to interact with the simulator outside of normal * device interface. + * @ingroup ec_host_cmd_simulator + */ + +#ifndef ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_SIMULATOR_H_ +#define ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_SIMULATOR_H_ + +/** + * @brief Interface to EC Host Command Simulator + * @defgroup ec_host_cmd_simulator Simulator + * @ingroup ec_host_cmd_interface + * @{ */ /* For ec_host_cmd_backend_api_send function pointer type */ @@ -45,4 +53,8 @@ void ec_host_cmd_backend_sim_install_send_cb(ec_host_cmd_backend_api_send cb, */ int ec_host_cmd_backend_sim_data_received(const uint8_t *buffer, size_t len); +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_MGMT_EC_HOST_CMD_SIMULATOR_H_ */ From 382ce7cbd345e3ac1874a2c01c43fd20c65a198a Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Fri, 22 Aug 2025 12:31:40 -0300 Subject: [PATCH 0106/1076] drivers: mcpwm: esp32: Fix duty rounding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Duty value in the driver is calculated from timer cycles, which can introduce precision loss when converting from pwm_set() to pwm_set_cycles(). To avoid truncating values with a fractional part ≥ 0.5 and further drifting the effective duty, round the computed duty to the nearest integer. Signed-off-by: Raffael Rostagno --- drivers/pwm/pwm_mc_esp32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pwm/pwm_mc_esp32.c b/drivers/pwm/pwm_mc_esp32.c index 2e15355a64253..9bbeebbbf44c0 100644 --- a/drivers/pwm/pwm_mc_esp32.c +++ b/drivers/pwm/pwm_mc_esp32.c @@ -252,9 +252,7 @@ static int mcpwm_esp32_set_cycles(const struct device *dev, uint32_t channel_idx return ret; } - double duty_cycle = (double)pulse_cycles * 100 / (double)period_cycles; - - channel->duty = (uint32_t)duty_cycle; + channel->duty = DIV_ROUND_CLOSEST((uint64_t)pulse_cycles * 100ULL, period_cycles); channel->inverted = (flags & PWM_POLARITY_INVERTED); From 794446717087b40ea400323091675d783e573a11 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 25 Aug 2025 10:09:11 +0200 Subject: [PATCH 0107/1076] drivers: ethernet: xilinx: remove unused data variable Clean up unused variable 'data' in eth_xilinx_axienet.c. Signed-off-by: Michal Simek --- drivers/ethernet/eth_xilinx_axienet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ethernet/eth_xilinx_axienet.c b/drivers/ethernet/eth_xilinx_axienet.c index 4bf3e96846898..3e61a3216c8e7 100644 --- a/drivers/ethernet/eth_xilinx_axienet.c +++ b/drivers/ethernet/eth_xilinx_axienet.c @@ -388,7 +388,6 @@ static int xilinx_axienet_get_config(const struct device *dev, enum ethernet_con struct ethernet_config *config) { const struct xilinx_axienet_config *dev_config = dev->config; - const struct xilinx_axienet_data *data = dev->data; switch (type) { case ETHERNET_CONFIG_TYPE_RX_CHECKSUM_SUPPORT: From a7527b1bf7ecdbec4cf3e9964b05d2825bae7d4c Mon Sep 17 00:00:00 2001 From: Ephraim Westenberger Date: Thu, 14 Aug 2025 17:25:40 +0200 Subject: [PATCH 0108/1076] soc: Add support for the bgm240sa22vna module Silicon Labs controller with integrated radio each rely on a specific binary blob (RAIL library) for using the EFR32 radio subsystem. This commit adds support for the Silicon Labs BGM240SA22VNA SoC. Signed-off-by: Ephraim Westenberger --- dts/arm/silabs/xg24/bgm240sa22vna.dtsi | 25 +++++++++++++++++++++++++ dts/arm/silabs/xg24/efr32bg24.dtsi | 7 +++++++ soc/silabs/silabs_s2/xg24/Kconfig | 5 +++++ soc/silabs/silabs_s2/xg24/Kconfig.soc | 13 +++++++++++++ soc/silabs/soc.yml | 3 +++ west.yml | 2 +- 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 dts/arm/silabs/xg24/bgm240sa22vna.dtsi create mode 100644 dts/arm/silabs/xg24/efr32bg24.dtsi diff --git a/dts/arm/silabs/xg24/bgm240sa22vna.dtsi b/dts/arm/silabs/xg24/bgm240sa22vna.dtsi new file mode 100644 index 0000000000000..b06af075d3743 --- /dev/null +++ b/dts/arm/silabs/xg24/bgm240sa22vna.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Fr. Sauter AG + * Copyright (c) 2025 Silicon Laboratories Inc. + * Copyright (c) 2025 Ephraim Westenberger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + compatible = "silabs,bgm240sa22vna", "silabs,efr32bg24", "silabs,xg24", + "silabs,efr32", "simple-bus"; + }; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1536)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; diff --git a/dts/arm/silabs/xg24/efr32bg24.dtsi b/dts/arm/silabs/xg24/efr32bg24.dtsi new file mode 100644 index 0000000000000..bb3c4651d2b87 --- /dev/null +++ b/dts/arm/silabs/xg24/efr32bg24.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/silabs/silabs_s2/xg24/Kconfig b/soc/silabs/silabs_s2/xg24/Kconfig index 4ad62fb3e61ab..e42474c1d4857 100644 --- a/soc/silabs/silabs_s2/xg24/Kconfig +++ b/soc/silabs/silabs_s2/xg24/Kconfig @@ -1,5 +1,6 @@ # Copyright (c) 2020 TriaGnoSys GmbH # Copyright (c) 2025 Silicon Laboratories Inc. +# Copyright (c) 2025 Ephraim Westenberger # SPDX-License-Identifier: Apache-2.0 config SOC_SILABS_XG24 @@ -25,3 +26,7 @@ config SOC_SERIES_EFR32MG24 config SOC_SERIES_MGM24 select SILABS_DEVICE_IS_MODULE select SOC_GECKO_HAS_RADIO + +config SOC_SERIES_BGM24 + select SILABS_DEVICE_IS_MODULE + select SOC_GECKO_HAS_RADIO diff --git a/soc/silabs/silabs_s2/xg24/Kconfig.soc b/soc/silabs/silabs_s2/xg24/Kconfig.soc index 4c798257e14d8..059589101f91c 100644 --- a/soc/silabs/silabs_s2/xg24/Kconfig.soc +++ b/soc/silabs/silabs_s2/xg24/Kconfig.soc @@ -1,5 +1,6 @@ # Copyright (c) 2020 TriaGnoSys GmbH # Copyright (c) 2025 Silicon Laboratories Inc. +# Copyright (c) 2025 Ephraim Westenberger # SPDX-License-Identifier: Apache-2.0 config SOC_SILABS_XG24 @@ -20,6 +21,12 @@ config SOC_SERIES_MGM24 help Silicon Labs MGM240 (Mighty Gecko) Series MCU modules +config SOC_SERIES_BGM24 + bool + select SOC_SILABS_XG24 + help + Silicon Labs BGM240 Series MCU modules + config SOC_EFR32MG24B020F1536IM40 bool select SOC_SERIES_EFR32MG24 @@ -44,9 +51,14 @@ config SOC_MGM240PB32VNA bool select SOC_SERIES_MGM24 +config SOC_BGM240SA22VNA + bool + select SOC_SERIES_BGM24 + config SOC_SERIES default "efr32mg24" if SOC_SERIES_EFR32MG24 default "mgm24" if SOC_SERIES_MGM24 + default "bgm24" if SOC_SERIES_BGM24 config SOC default "efr32mg24b220f1536im48" if SOC_EFR32MG24B220F1536IM48 @@ -55,3 +67,4 @@ config SOC default "efr32mg24b020f1536im40" if SOC_EFR32MG24B020F1536IM40 default "mgm240sd22vna" if SOC_MGM240SD22VNA default "mgm240pb32vna" if SOC_MGM240PB32VNA + default "bgm240sa22vna" if SOC_BGM240SA22VNA diff --git a/soc/silabs/soc.yml b/soc/silabs/soc.yml index a6d139cb19462..5a06c6e4225a1 100644 --- a/soc/silabs/soc.yml +++ b/soc/silabs/soc.yml @@ -67,6 +67,9 @@ family: - name: efr32mg24b310f1536im48 - name: efr32mg24b210f1536im48 - name: efr32mg24b020f1536im40 + - name: bgm24 + socs: + - name: bgm240sa22vna - name: mgm24 socs: - name: mgm240sd22vna diff --git a/west.yml b/west.yml index 57a41bb050324..ec143c671bbda 100644 --- a/west.yml +++ b/west.yml @@ -235,7 +235,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 13343bccf850eb7b6541f6e71a8d2a880209850b + revision: 0b58229357750b8bd0ce52e514c54ace6abcfeba path: modules/hal/silabs groups: - hal From 5aa89556fbfcfc28f9ad37e9ec6a696d93aa9c09 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 19 Aug 2025 19:36:53 -0500 Subject: [PATCH 0109/1076] samples: Fix confusing openamp sample doc A lot of users seem to be confused by this sample when they try to do west debug. This is because Zephyr currently does not support flashing all the cores from a sysbuild automatically when doing a west debug command. So west flash needs to be done prior to a west debug command. The README previously actually said the step by step instructions are to do the build, then immediately west debug, which would cause faulting and crashing, so change the instructions goal to be a flash, and put a note about needing to flash before debugging. Signed-off-by: Declan Snyder --- samples/subsys/ipc/openamp/README.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/samples/subsys/ipc/openamp/README.rst b/samples/subsys/ipc/openamp/README.rst index 9f3416ade7f84..9d6ae7aa7a7a1 100644 --- a/samples/subsys/ipc/openamp/README.rst +++ b/samples/subsys/ipc/openamp/README.rst @@ -9,16 +9,21 @@ Overview This application demonstrates how to use OpenAMP with Zephyr. It is designed to demonstrate how to integrate OpenAMP with Zephyr both from a build perspective -and code. Note that the remote and primary core images can be flashed +and code. + +Note that the remote and primary core images can be flashed independently, but sysbuild must be used in order to build the images. +Both cores must be flashed prior to using ``west debug`` on either core. +It is suggested to use ``west flash`` to do this as shown below. + Building the application for lpcxpresso54114_m4 *********************************************** .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: lpcxpresso54114/lpc54114/m4 - :goals: debug + :goals: flash :west-args: --sysbuild Building the application for lpcxpresso55s69/lpc55s69/cpu0 @@ -27,7 +32,7 @@ Building the application for lpcxpresso55s69/lpc55s69/cpu0 .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: lpcxpresso55s69/lpc55s69/cpu0 - :goals: debug + :goals: flash :west-args: --sysbuild Building the application for mps2/an521/cpu0 @@ -36,7 +41,7 @@ Building the application for mps2/an521/cpu0 .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: mps2/an521/cpu0 - :goals: debug + :goals: flash :west-args: --sysbuild Building the application for v2m_musca_b1/musca_b1 @@ -45,7 +50,7 @@ Building the application for v2m_musca_b1/musca_b1 .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: v2m_musca_b1/musca_b1 - :goals: debug + :goals: flash :west-args: --sysbuild Building the application for mimxrt1170_evk_cm7 @@ -54,7 +59,7 @@ Building the application for mimxrt1170_evk_cm7 .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: mimxrt1170_evk_cm7 - :goals: debug + :goals: flash :west-args: --sysbuild Building the application for frdm_mcxn947/mcxn947/cpu0 @@ -63,7 +68,7 @@ Building the application for frdm_mcxn947/mcxn947/cpu0 .. zephyr-app-commands:: :zephyr-app: samples/subsys/ipc/openamp :board: frdm_mcxn947/mcxn947/cpu0 - :goals: debug + :goals: flash :west-args: --sysbuild Open a serial terminal (minicom, putty, etc.) and connect the board with the From 0f7b1033d5c8709413c7734b5fcaed1e6fc63ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Aug 2025 22:25:45 +0200 Subject: [PATCH 0110/1076] include: sensing: doc: sensor types doxygen fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add missing docs, group types using `@name` Signed-off-by: Benjamin Cabé --- include/zephyr/sensing/sensing_sensor_types.h | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/include/zephyr/sensing/sensing_sensor_types.h b/include/zephyr/sensing/sensing_sensor_types.h index de9328c7b2189..359d2fc4ba04e 100644 --- a/include/zephyr/sensing/sensing_sensor_types.h +++ b/include/zephyr/sensing/sensing_sensor_types.h @@ -20,35 +20,50 @@ */ /** - * sensor category light + * @name Light sensors + * @{ */ + +/** Sensor type for ambient light sensors. */ #define SENSING_SENSOR_TYPE_LIGHT_AMBIENTLIGHT 0x41 +/** @} */ + /** - * sensor category motion + * @name Motion sensors + * @{ */ -/* Sensor type for 3D accelerometers. */ + +/** Sensor type for 3D accelerometers. */ #define SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D 0x73 -/* Sensor type for 3D gyrometers. */ +/** Sensor type for 3D gyrometers. */ #define SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D 0x76 -/* Sensor type for motion detectors. */ +/** Sensor type for motion detectors. */ #define SENSING_SENSOR_TYPE_MOTION_MOTION_DETECTOR 0x77 +/** Sensor type for uncalibrated 3D accelerometers. */ +#define SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D 0x240 +/** Sensor type for hinge angle sensors. */ +#define SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE 0x20B +/** @} */ /** - * sensor category other + * @name Other sensors + * @{ */ -#define SENSING_SENSOR_TYPE_OTHER_CUSTOM 0xE1 -/* Sensor type for uncalibrated 3D accelerometers. */ -#define SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D 0x240 -/* Sensor type for hinge angle sensors. */ -#define SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE 0x20B +/** Sensor type for custom sensors. */ +#define SENSING_SENSOR_TYPE_OTHER_CUSTOM 0xE1 + +/** @} */ /** * @brief Sensor type for all sensors. * * This macro defines the sensor type for all sensors. + * + * @note This value is not a valid sensor type and is used as a sentinel value to indicate all + * sensor types. */ #define SENSING_SENSOR_TYPE_ALL 0xFFFF From 0928c70f193bd51fe84439cb9c85241941c680d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Aug 2025 22:25:08 +0200 Subject: [PATCH 0111/1076] include: sensing: doc: documentation improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move sensing documentation in the "OS Services" group and clean up group declarations - Add missing documentation for the Sensing Subsystem API and complete existing docs when it was too terse - Other grammar/cosmetic improvements Signed-off-by: Benjamin Cabé --- doc/services/sensing/index.rst | 3 - include/zephyr/sensing/sensing.h | 102 ++++++++++++------ include/zephyr/sensing/sensing_datatypes.h | 9 +- include/zephyr/sensing/sensing_sensor.h | 14 +-- include/zephyr/sensing/sensing_sensor_types.h | 7 +- 5 files changed, 80 insertions(+), 55 deletions(-) diff --git a/doc/services/sensing/index.rst b/doc/services/sensing/index.rst index 976599826d8fa..db661c31a3c67 100644 --- a/doc/services/sensing/index.rst +++ b/doc/services/sensing/index.rst @@ -246,7 +246,4 @@ See the example :zephyr_file:`samples/subsys/sensing/simple/boards/native_sim.ov API Reference ************* -.. doxygengroup:: sensing_sensor_types -.. doxygengroup:: sensing_datatypes .. doxygengroup:: sensing_api -.. doxygengroup:: sensing_sensor diff --git a/include/zephyr/sensing/sensing.h b/include/zephyr/sensing/sensing.h index 96fb119b0ed54..725f3a6bba8ba 100644 --- a/include/zephyr/sensing/sensing.h +++ b/include/zephyr/sensing/sensing.h @@ -8,32 +8,26 @@ #define ZEPHYR_INCLUDE_SENSING_H_ /** - * @defgroup sensing Sensing - * @defgroup sensing_api Sensing Subsystem API - * @ingroup sensing - * @defgroup sensing_sensor_types Sensor Types - * @ingroup sensing - * @defgroup sensing_datatypes Data Types - * @ingroup sensing + * @defgroup sensing_api Sensing + * @brief High-level sensor framework. + * @ingroup os_services + * + * The Sensing subsystem provides a high-level API for applications to discover sensors, open sensor + * instances, configure reporting behavior, and receive sampled data via callbacks. + * For low-level sensor access, see @ref sensor_interface. + * + * @{ */ #include #include #include -/** - * @brief Sensing Subsystem API - * @addtogroup sensing_api - * @{ - */ - #ifdef __cplusplus extern "C" { #endif - /** - * @struct sensing_sensor_version * @brief Sensor Version */ struct sensing_sensor_version { @@ -49,8 +43,13 @@ struct sensing_sensor_version { }; /** - * @brief Macro to create a sensor version value. + * @brief Build a packed @ref sensing_sensor_version value. * + * @param _major Major version. + * @param _minor Minor version. + * @param _hotfix Hotfix version. + * @param _build Build number. + * @return 32-bit packed version value */ #define SENSING_SENSOR_VERSION(_major, _minor, _hotfix, _build) \ (FIELD_PREP(GENMASK(31, 24), _major) | \ @@ -58,33 +57,43 @@ struct sensing_sensor_version { FIELD_PREP(GENMASK(15, 8), _hotfix) | \ FIELD_PREP(GENMASK(7, 0), _build)) +/** + * @name Sensor reporting flags + * @{ + */ /** - * @brief Sensor flag indicating if this sensor is on event reporting data. + * @brief Sensor flag indicating if this sensor is reporting data on event. * * Reporting sensor data when the sensor event occurs, such as a motion detect sensor reporting * a motion or motionless detected event. + * + * @note Mutually exclusive with \ref SENSING_SENSOR_FLAG_REPORT_ON_CHANGE */ #define SENSING_SENSOR_FLAG_REPORT_ON_EVENT BIT(0) /** - * @brief Sensor flag indicating if this sensor is on change reporting data. + * @brief Sensor flag indicating if this sensor is reporting data on change. * * Reporting sensor data when the sensor data changes. * - * Exclusive with \ref SENSING_SENSOR_FLAG_REPORT_ON_EVENT + * @note Mutually exclusive with \ref SENSING_SENSOR_FLAG_REPORT_ON_EVENT */ #define SENSING_SENSOR_FLAG_REPORT_ON_CHANGE BIT(1) +/** @} */ + /** - * @brief SENSING_SENSITIVITY_INDEX_ALL indicating sensitivity of each data field should be set + * @brief Sentinel index meaning "apply to all data fields". * + * Used with sensitivity configuration where a sensor provides multiple fields in a single sample. */ #define SENSING_SENSITIVITY_INDEX_ALL -1 /** - * @brief Sensing subsystem sensor state. + * @brief Sensor state. * + * This enumeration defines the possible states of a sensor. */ enum sensing_sensor_state { SENSING_SENSOR_STATE_READY = 0, /**< The sensor is ready. */ @@ -92,32 +101,53 @@ enum sensing_sensor_state { }; /** - * @brief Sensing subsystem sensor config attribute + * @brief Sensor configuration attribute. * + * This enumeration defines the possible attributes of a sensor configuration. */ enum sensing_sensor_attribute { - /** The interval attribute of a sensor configuration. */ + /** + * Reporting interval between samples, in microseconds (us). + * + * See @ref sensing_sensor_config::interval. + */ SENSING_SENSOR_ATTRIBUTE_INTERVAL = 0, - /** The sensitivity attribute of a sensor configuration. */ + + /** + * Per-field sensitivity threshold. + * + * See @ref sensing_sensor_config::sensitivity. + */ SENSING_SENSOR_ATTRIBUTE_SENSITIVITY = 1, - /** The latency attribute of a sensor configuration. */ + + /** + * Maximum batching latency, in microseconds (us). + * + * See @ref sensing_sensor_config::latency. + */ SENSING_SENSOR_ATTRIBUTE_LATENCY = 2, - /** The maximum number of attributes that a sensor configuration can have. */ + + /** Number of supported attributes. */ SENSING_SENSOR_ATTRIBUTE_MAX, }; /** - * @brief Define Sensing subsystem sensor handle + * @brief Opaque handle to an opened sensor instance. * + * A valid handle is obtained from @ref sensing_open_sensor or @ref sensing_open_sensor_by_dt and + * must be closed with @ref sensing_close_sensor when no longer needed. */ typedef void *sensing_sensor_handle_t; /** - * @brief Sensor data event receive callback. + * @brief Data event callback signature. * - * @param handle The sensor instance handle. - * @param buf The data buffer with sensor data. - * @param context User provided context pointer. + * The Sensing subsystem invokes this callback to deliver buffered samples for the opened sensor. + * + * @param handle Sensor instance handle passed to @ref sensing_open_sensor. + * @param buf Pointer to a sensor-type-specific sample buffer; see @ref sensing_datatypes and + * @ref sensing_sensor_types. + * @param context User context pointer as provided in @ref sensing_callback_list::context. */ typedef void (*sensing_data_event_t)( sensing_sensor_handle_t handle, @@ -125,9 +155,7 @@ typedef void (*sensing_data_event_t)( void *context); /** - * @struct sensing_sensor_info - * @brief Sensor basic constant information - * + * @brief Read-only description of a sensor instance. */ struct sensing_sensor_info { /** Name of the sensor instance */ @@ -154,9 +182,13 @@ struct sensing_sensor_info { * @brief Sensing subsystem event callback list * */ + +/** + * @brief Callback registration for a sensor instance. + */ struct sensing_callback_list { sensing_data_event_t on_data_event; /**< Callback function for a sensor data event. */ - void *context; /**< Associated context with on_data_event */ + void *context; /**< Context that will be passed to the callback. */ }; /** diff --git a/include/zephyr/sensing/sensing_datatypes.h b/include/zephyr/sensing/sensing_datatypes.h index b18b22b41800a..ad77733ca96eb 100644 --- a/include/zephyr/sensing/sensing_datatypes.h +++ b/include/zephyr/sensing/sensing_datatypes.h @@ -11,14 +11,15 @@ #include /** - * @brief Data Types - * @addtogroup sensing_datatypes + * @defgroup sensing_datatypes Data Types + * @ingroup sensing_api + * @brief Sensor data structures used by the sensing subsystem + * * @{ */ /** - * @struct sensing_sensor_value_header - * @brief sensor value header + * @brief Common header for all sensor value payloads. * * Each sensor value data structure should have this header * diff --git a/include/zephyr/sensing/sensing_sensor.h b/include/zephyr/sensing/sensing_sensor.h index 2c5e526f760b6..de7fe6c9e3b84 100644 --- a/include/zephyr/sensing/sensing_sensor.h +++ b/include/zephyr/sensing/sensing_sensor.h @@ -13,15 +13,9 @@ #include /** - * @defgroup sensing_sensor Sensing Sensor API - * @ingroup sensing - * @defgroup sensing_sensor_callbacks Sensor Callbacks - * @ingroup sensing_sensor - */ - -/** - * @brief Sensing Sensor API - * @addtogroup sensing_sensor + * @brief Interfaces to manipulate sensors in the sensing subsystem + * @defgroup sensing_sensor Sensors (Sensing) + * @ingroup sensing_api * @{ */ @@ -390,7 +384,7 @@ extern const struct rtio_iodev_api __sensing_iodev_api; SENSING_SENSORS_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) /** - * @brief Get reporter handles of a given sensor instance by sensor type. + * @brief Get reporter handles of a given sensor instance by sensor type. * * @param dev The sensor instance device structure. * @param type The given type, \ref SENSING_SENSOR_TYPE_ALL to get reporters diff --git a/include/zephyr/sensing/sensing_sensor_types.h b/include/zephyr/sensing/sensing_sensor_types.h index 359d2fc4ba04e..5469e09d7f482 100644 --- a/include/zephyr/sensing/sensing_sensor_types.h +++ b/include/zephyr/sensing/sensing_sensor_types.h @@ -8,14 +8,15 @@ #define ZEPHYR_INCLUDE_SENSING_SENSOR_TYPES_H_ /** - * @brief Sensor Types Definition + * @defgroup sensing_sensor_types Sensor Types (Sensing) + * @ingroup sensing_api + * + * @brief Sensor type identifiers used by the sensing subsystem. * * Sensor types definition followed HID standard. * https://usb.org/sites/default/files/hutrr39b_0.pdf * * TODO: will add more types - * - * @addtogroup sensing_sensor_types * @{ */ From b50b5b4f4ea1495b7eb8a56559349a1439659082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Tue, 26 Aug 2025 15:02:07 +0200 Subject: [PATCH 0112/1076] boards: nordic: nrf54lm20dk: Add usbd to supported features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 'usbd' to the list of features supported by nrf54lm20dk. Signed-off-by: Sebastian Głąb --- boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.yaml b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.yaml index 765845fa27f06..e5a2b89087de7 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.yaml +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.yaml @@ -20,4 +20,5 @@ supported: - i2s - pwm - spi + - usbd - watchdog From bf892ffe2994ee9c5f19719c8bb3c49b6f7a3a11 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 21 Jul 2025 11:19:02 -0700 Subject: [PATCH 0113/1076] tests: disk/disk_performance: add CONFIG_NVME for qemu_x86_64 qemu_x86_64 has NVME disk as overlay so we need to enable kconfig CONFIG_NVME or else it would fail to compile. Signed-off-by: Daniel Leung --- tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf b/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf index 0c14f763bf95d..64343c52aad37 100644 --- a/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf +++ b/tests/drivers/disk/disk_performance/boards/qemu_x86_64.conf @@ -3,3 +3,4 @@ CONFIG_PCIE=y CONFIG_PCIE_MSI=y CONFIG_PCIE_MSI_X=y CONFIG_PCIE_MSI_MULTI_VECTOR=y +CONFIG_NVME=y From d4b4da94e7a8f0cc5cf545e33c98a7ee1621f0ed Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 21 Jul 2025 10:54:56 -0700 Subject: [PATCH 0114/1076] x86: fix return for arch_pcie_msi_vectors_allocate() arch_pcie_msi_vectors_allocate() has a return type of uint8_t. One of the error path returns -1 which would result in 255 being returned. So fix that by returning 0 instead, as there is no vector being allocated anyway. Signed-off-by: Daniel Leung --- arch/x86/core/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index 878e6886d7b8f..3086413a8369b 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -260,7 +260,7 @@ uint8_t arch_pcie_msi_vectors_allocate(unsigned int priority, } if ((irq == PCIE_CONF_INTR_IRQ_NONE) || (irq == -1)) { - return -1; + return 0; } vector = z_x86_allocate_vector(priority, prev_vector); From fe5f8e0737aa9599011c7e50c760e571a95e32d7 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 21 Jul 2025 11:14:58 -0700 Subject: [PATCH 0115/1076] x86: pcie: fix allocating 1 vector under MSI-X Fix an issue where 1 vector is being requested when MSI-X is enabled. The previous logic always assumed the PCIE device has only fixed or single MSI when we are requesting 1 vector, which is not entirely correct. So if there is no vector allocated already, try to allocate one. Fixes #93319 Signed-off-by: Daniel Leung --- arch/x86/core/pcie.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index 3086413a8369b..cf298cc1f9cfa 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -249,12 +249,18 @@ uint8_t arch_pcie_msi_vectors_allocate(unsigned int priority, for (i = 0; i < n_vector; i++) { if (n_vector == 1) { - /* This path is taken by PCIE device with fixed - * or single MSI: IRQ has been already allocated - * and/or set on the PCIe bus. Thus we only require - * to get it. + /* For PCIE device with fixed or single MSI: IRQ has + * been already allocated and/or set on the PCIe bus. + * We only need to retrieve it. */ irq = pcie_get_irq(vectors->bdf); + + /* If that is not the case, we will need to allocate + * IRQ before proceeding. + */ + if (irq == PCIE_CONF_INTR_IRQ_NONE) { + irq = arch_irq_allocate(); + } } else { irq = arch_irq_allocate(); } From 231d59f890f47e804f8fac90aed3778470d41c82 Mon Sep 17 00:00:00 2001 From: WenBin Zhang Date: Sat, 23 Aug 2025 18:32:39 +0800 Subject: [PATCH 0116/1076] samples: zperf: Improve TCP performance For TCP, CONFIG_PICOLIBC_USE_MODULE=y has a significant impact on performance. Use nucleo_h743zi board with loopback: ``` before: tcp upload: 49.35 Mbps/s after: tcp upload: 56.52 Mbps/s ``` Use nucleo_h743zi board, default config: ``` before: tcp upload: 71.3Mbps/s tcp download: 75.11 Mbps/s after: tcp upload: 75.3Mbps/s tcp download: 94.39 Mbps/s ``` Use nucleo_h743zi board, with tx async mode #93965: ``` before: tcp upload: 71.3Mbps/s tcp download: 75.11 Mbps/s after: tcp upload: 92.9Mbps/s tcp download: 94.5Mbps/s ``` Signed-off-by: WenBin Zhang --- samples/net/zperf/prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/net/zperf/prj.conf b/samples/net/zperf/prj.conf index 59bfa7adb8bf7..129260a113ac7 100644 --- a/samples/net/zperf/prj.conf +++ b/samples/net/zperf/prj.conf @@ -44,3 +44,6 @@ CONFIG_SHELL_CMDS_RESIZE=n CONFIG_CACHE_MANAGEMENT=y CONFIG_SPEED_OPTIMIZATIONS=y CONFIG_TIMESLICING=n + +# For speed optimizations +CONFIG_PICOLIBC_USE_MODULE=y From 3c8eeeaebb824344fc8d16afc2763b28c40a93b6 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sat, 23 Aug 2025 20:31:52 +0200 Subject: [PATCH 0117/1076] samples: settings: handle failures If we cannot initialize settings subsystem, it does not make much sense to do calls into it. This leads to uninitialized variables being printed and generally makes it hard to tell whether or not the sample runs with the given config. Signed-off-by: Dmitrii Sharshakov --- samples/subsys/settings/src/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/samples/subsys/settings/src/main.c b/samples/subsys/settings/src/main.c index 761c911827338..e1fb1cf299f38 100644 --- a/samples/subsys/settings/src/main.c +++ b/samples/subsys/settings/src/main.c @@ -418,7 +418,7 @@ static void example_without_handler(void) } } -static void example_initialization(void) +static int example_initialization(void) { int rc; @@ -450,7 +450,7 @@ static void example_initialization(void) rc = settings_subsys_init(); if (rc) { printk("settings subsys initialization: fail (err %d)\n", rc); - return; + return rc; } printk("settings subsys initialization: OK.\n"); @@ -459,10 +459,13 @@ static void example_initialization(void) if (rc) { printk("subtree <%s> handler registered: fail (err %d)\n", alpha_handler.name, rc); + return rc; } printk("subtree <%s> handler registered: OK\n", alpha_handler.name); printk("subtree has static handler\n"); + + return 0; } static void example_delete(void) @@ -542,7 +545,9 @@ int main(void) printk("\n*** Settings usage example ***\n\n"); /* settings initialization */ - example_initialization(); + if (example_initialization() != 0) { + return 0; + } for (i = 0; i < 6; i++) { printk("\n##############\n"); From d7d5aeb800ed164c63cc8c1090221594415f72c0 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Sun, 24 Aug 2025 12:30:53 -0400 Subject: [PATCH 0118/1076] drivers: spi: spi_pico_pio: Prevent dma_config check if DMA is not enabled At this moment, DMA for SPI 3-wire half-duplex operation is not supported by the pio driver. A check was implemented there to prevent user from enabling DMA, but wasn't bypassed when CONFIG_SPI_RPI_PICO_PIO_DMA is not enabled at all, under which the `dma_config` structure isn't defined at all. Fixed #94897. Signed-off-by: Terry Geng --- drivers/spi/spi_rpi_pico_pio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi_rpi_pico_pio.c b/drivers/spi/spi_rpi_pico_pio.c index 6421ec6d16ec6..6bd4848a00d00 100644 --- a/drivers/spi/spi_rpi_pico_pio.c +++ b/drivers/spi/spi_rpi_pico_pio.c @@ -320,10 +320,12 @@ static int spi_pico_pio_configure(const struct spi_pico_pio_config *dev_cfg, #if SPI_RPI_PICO_PIO_HALF_DUPLEX_ENABLED if (spi_cfg->operation & SPI_HALF_DUPLEX) { +#if defined(CONFIG_SPI_RPI_PICO_PIO_DMA) if (dev_cfg->dma_config.dev) { LOG_ERR("DMA not supported in 3-wire operation"); return -ENOTSUP; } +#endif if ((cpol != 0) || (cpha != 0)) { LOG_ERR("Only mode (0, 0) supported in 3-wire SIO"); From 2802a9a6f3ccfe530a79a8b5ffd78a892d4e499a Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Sun, 24 Aug 2025 17:50:10 -0300 Subject: [PATCH 0119/1076] drivers: flash: esp32: handle zero-length reads as no-op Add a guard clause in flash_esp32_read() to return 0 when the requested length is zero. This avoids unnecessary operations and aligns with expected flash API behavior, where reading zero bytes is treated as a no-op. Signed-off-by: Sylvio Alves --- drivers/flash/flash_esp32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index cb123a3349a8d..f638cbc819bf6 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -89,6 +89,10 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe { int ret = 0; + if (length == 0U) { + return 0; + } + #ifdef CONFIG_MCUBOOT uint8_t *dest_ptr = (uint8_t *)buffer; size_t remaining = length; From a02be914ca7e648ef96641806eb4d176cc14621c Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Wed, 20 Aug 2025 13:38:11 +0700 Subject: [PATCH 0120/1076] drivers: gpio: Add select PINCTRL for renesas_ra_ioport Add select PINCTRL for renesas_ra_ioport Signed-off-by: Khoa Nguyen --- drivers/gpio/Kconfig.renesas_ra_ioport | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/Kconfig.renesas_ra_ioport b/drivers/gpio/Kconfig.renesas_ra_ioport index 0aff2565c5acf..6d2db6ba24665 100644 --- a/drivers/gpio/Kconfig.renesas_ra_ioport +++ b/drivers/gpio/Kconfig.renesas_ra_ioport @@ -5,6 +5,7 @@ config GPIO_RA_IOPORT bool "Renesas RA GPIO IO port driver" default y depends on DT_HAS_RENESAS_RA_GPIO_IOPORT_ENABLED + select PINCTRL help Enable the Renesas RA GPIO IO port driver. From fba3a1e314d4df1c9cc4d5b18075651fc27ba7cb Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 25 Aug 2025 14:10:17 +0800 Subject: [PATCH 0121/1076] boards: nxp: Use the mcxa346 linkserver for mcxa266 The frdm-mcxa266 linkserver is not ready now, temporarily use the frdm-mcxa346 linkserver. Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxa266/board.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/frdm_mcxa266/board.cmake b/boards/nxp/frdm_mcxa266/board.cmake index 361bb67183382..0b36efc599994 100644 --- a/boards/nxp/frdm_mcxa266/board.cmake +++ b/boards/nxp/frdm_mcxa266/board.cmake @@ -5,7 +5,7 @@ # board_runner_args(jlink "--device=MCXA266") -board_runner_args(linkserver "--device=MCXA266:FRDM-MCXA266") +board_runner_args(linkserver "--device=MCXA346:FRDM-MCXA346") board_runner_args(pyocd "--target=mcxa266") include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) From eb7e08641d943be7fed9f84ca00b07b76bbee30d Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 21 Aug 2025 15:33:19 +0100 Subject: [PATCH 0122/1076] docs: contribution, style: specify that tabs are 8 characters GitHub, in a moment of infinite wisdom, decided to change the default tab from eight to four characters. According to the GitHub announcement the problem that the change addressed is that "many users are unaware that tab size can be adjusted in their settings". As a result now users with this so called "improved" setting sees a different indentation from all other users. Help GitHub in their awareness mission, by making the users aware that tab size can (or rather, has to) be adjusted in their settings to the previous default, by mentioning it in the contribution guideline. Call it out in the quick style guide too since it's not the default anymore. Link: https://github.blog/changelog/2025-08-07-default-tab-size-changed-from-eight-to-four/ Signed-off-by: Fabio Baltieri --- doc/contribute/guidelines.rst | 13 +++++++++++++ doc/contribute/style/code.rst | 1 + 2 files changed, 14 insertions(+) diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 640ea4abc1e3b..8fb1725a9a5ed 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -358,6 +358,19 @@ If in doubt, it's advisable to explore existing Pull Requests within the Zephyr repository. Use the search filters and labels to locate PRs related to changes similar to the ones you are proposing. +.. note:: + GitHub's default code UI uses 4-character tabs. However, Zephyr follows the + `Linux kernel coding style`_, which uses 8-character tabs. + + To ensure your view of the code is consistent with other developers, please + go to your `user preferences on GitHub`_ and change the tab width to 8 spaces. + +.. _Linux kernel coding style: + https://kernel.org/doc/html/latest/process/coding-style.html#indentation + +.. _user preferences on GitHub: + https://github.com/settings/appearance + .. _commit-guidelines: Commit Message Guidelines diff --git a/doc/contribute/style/code.rst b/doc/contribute/style/code.rst index 59a363ee50949..4fd45c7708210 100644 --- a/doc/contribute/style/code.rst +++ b/doc/contribute/style/code.rst @@ -16,6 +16,7 @@ subsystem, etc). In general, follow the `Linux kernel coding style`_, with the following exceptions and clarifications: +* Tabs are 8 characters. * Use `snake case`_ for code and variables. * The line length is 100 columns or fewer. In the documentation, longer lines for URL references are an allowed exception. From ba30c7b4e8f5f3bd1c6434ebd1ea2a9eaa6cb1a5 Mon Sep 17 00:00:00 2001 From: Maksymilian Goryszewski Date: Thu, 14 Aug 2025 11:45:08 +0200 Subject: [PATCH 0123/1076] lib: posix: fs: Basic fstat() using seek and tell Implement limited posix fstat() Signed-off-by: Maksymilian Goryszewski --- lib/posix/options/fs.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/posix/options/fs.c b/lib/posix/options/fs.c index 45028248608f7..23d4cf669f6b8 100644 --- a/lib/posix/options/fs.c +++ b/lib/posix/options/fs.c @@ -154,6 +154,35 @@ static int fs_ioctl_vmeth(void *obj, unsigned int request, va_list args) struct posix_fs_desc *ptr = obj; switch (request) { + case ZFD_IOCTL_STAT: { + struct stat *buf = va_arg(args, struct stat *); + long offset = fs_tell(&ptr->file); + long current; + + if (offset < 0) { + return offset; + } + + memset(buf, 0, sizeof(struct stat)); + + rc = fs_seek(&ptr->file, 0, FS_SEEK_END); + if (rc < 0) { + return rc; + } + + current = fs_tell(&ptr->file); + if (current >= 0) { + buf->st_size = current; + buf->st_mode = ptr->is_dir ? S_IFDIR : S_IFREG; + } + + rc = fs_seek(&ptr->file, offset, FS_SEEK_SET); + + if (current < 0) { + rc = current; + } + break; + } case ZFD_IOCTL_FSYNC: { rc = fs_sync(&ptr->file); break; From 90723c86ed7f4166bb94cbf2c65f1e127e51977d Mon Sep 17 00:00:00 2001 From: Maksymilian Goryszewski Date: Thu, 14 Aug 2025 15:56:46 +0200 Subject: [PATCH 0124/1076] tests: posix: fs: Added fstat tests Test posix fstat() function Signed-off-by: Maksymilian Goryszewski --- tests/posix/fs/src/test_fs_stat.c | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/posix/fs/src/test_fs_stat.c b/tests/posix/fs/src/test_fs_stat.c index 9aa7db128917e..2850368de4af4 100644 --- a/tests/posix/fs/src/test_fs_stat.c +++ b/tests/posix/fs/src/test_fs_stat.c @@ -105,3 +105,60 @@ ZTEST(posix_fs_stat_test, test_fs_stat_dir) /* note: for posix compatibility should should actually work */ zassert_not_equal(0, stat(TEST_ROOT, &buf)); } + +/** + * @brief Test fstat command on file + * + * @details Tests file in root, file in directroy, and empty file + */ +ZTEST(posix_fs_stat_test, test_fs_fstat_file) +{ + struct stat buf; + + int test_file_fd = open(TEST_FILE, O_RDONLY); + int dir_file_fd = open(TEST_DIR_FILE, O_RDONLY); + int empty_file_fd = open(TEST_EMPTY_FILE, O_RDONLY); + + zassert_not_equal(-1, test_file_fd); + zassert_equal(0, fstat(test_file_fd, &buf)); + zassert_equal(TEST_FILE_SIZE, buf.st_size); + zassert_equal(S_IFREG, buf.st_mode); + close(test_file_fd); + + zassert_not_equal(-1, dir_file_fd); + zassert_equal(0, fstat(dir_file_fd, &buf)); + zassert_equal(TEST_DIR_FILE_SIZE, buf.st_size); + zassert_equal(S_IFREG, buf.st_mode); + close(dir_file_fd); + + zassert_not_equal(-1, empty_file_fd); + zassert_equal(0, fstat(empty_file_fd, &buf)); + zassert_equal(0, buf.st_size); + zassert_equal(S_IFREG, buf.st_mode); + close(empty_file_fd); +} + +/** + * @brief Test fstat command on dir + * + * @details Tests if we can retrieve stastics for a directory. + */ +ZTEST(posix_fs_stat_test, test_fs_fstat_dir) +{ + struct stat buf; + + int fd = open(TEST_DIR, O_RDONLY); + + /* + * if this failed it means open doesn't support directories + * so skip the rest of the test + */ + if (fd == -1) { + ztest_test_skip(); + } + + zassert_equal(0, fstat(fd, &buf)); + zassert_equal(0, buf.st_size); + zassert_equal(S_IFDIR, buf.st_mode); + close(fd); +} From cbc2b3b540f17b271b235b75c580e43ae778376a Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Tue, 19 Aug 2025 11:07:44 +0200 Subject: [PATCH 0125/1076] shell: mqtt: remove username and password preprocessor checks `#ifdef` will always evaluate to true when used on string Kconfig options. Therefore username and password is set to "" if unset in Kconfig which is not an issue. Signed-off-by: Jeppe Odgaard --- subsys/shell/backends/shell_mqtt.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/subsys/shell/backends/shell_mqtt.c b/subsys/shell/backends/shell_mqtt.c index 7588fa25a012a..5b9b452f720b1 100644 --- a/subsys/shell/backends/shell_mqtt.c +++ b/subsys/shell/backends/shell_mqtt.c @@ -26,18 +26,6 @@ LOG_MODULE_REGISTER(shell_mqtt, CONFIG_SHELL_MQTT_LOG_LEVEL); #define PROCESS_INTERVAL K_MSEC(CONFIG_SHELL_MQTT_WORK_DELAY_MS) #define SHELL_MQTT_WORKQ_STACK_SIZE 2048 -#ifdef CONFIG_SHELL_MQTT_SERVER_USERNAME -#define MQTT_USERNAME CONFIG_SHELL_MQTT_SERVER_USERNAME -#else -#define MQTT_USERNAME NULL -#endif /* CONFIG_SHELL_MQTT_SERVER_USERNAME */ - -#ifdef CONFIG_SHELL_MQTT_SERVER_PASSWORD -#define MQTT_PASSWORD CONFIG_SHELL_MQTT_SERVER_PASSWORD -#else -#define MQTT_PASSWORD NULL -#endif /*SHELL_MQTT_SERVER_PASSWORD */ - struct shell_mqtt *sh_mqtt; K_KERNEL_STACK_DEFINE(sh_mqtt_workq_stack, SHELL_MQTT_WORKQ_STACK_SIZE); @@ -187,10 +175,10 @@ static void client_init(struct shell_mqtt *sh) static struct mqtt_utf8 password; static struct mqtt_utf8 username; - password.utf8 = (uint8_t *)MQTT_PASSWORD; - password.size = strlen(MQTT_PASSWORD); - username.utf8 = (uint8_t *)MQTT_USERNAME; - username.size = strlen(MQTT_USERNAME); + password.utf8 = (uint8_t *)CONFIG_SHELL_MQTT_SERVER_PASSWORD; + password.size = strlen(CONFIG_SHELL_MQTT_SERVER_PASSWORD); + username.utf8 = (uint8_t *)CONFIG_SHELL_MQTT_SERVER_USERNAME; + username.size = strlen(CONFIG_SHELL_MQTT_SERVER_USERNAME); mqtt_client_init(&sh->mqtt_cli); From 79e4b31d8f6caa25d3938ef68f9f89f654d36843 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:09:23 +0800 Subject: [PATCH 0126/1076] hal_nxp: Add KPP driver support. Add KPP driver support. Signed-off-by: Qiang Zhang --- modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 658bebf1bbae8..62c55bf75a73f 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -135,6 +135,7 @@ set_variable_ifdef(CONFIG_TRDC_MCUX_TRDC_1 CONFIG_MCUX_COMPONENT_driver.trd set_variable_ifdef(CONFIG_S3MU_MCUX_S3MU CONFIG_MCUX_COMPONENT_driver.s3mu) set_variable_ifdef(CONFIG_DAI_NXP_MICFIL CONFIG_MCUX_COMPONENT_driver.pdm) set_variable_ifdef(CONFIG_PINCTRL_NXP_PORT CONFIG_MCUX_COMPONENT_driver.port) +set_variable_ifdef(CONFIG_INPUT_MCUX_KPP CONFIG_MCUX_COMPONENT_driver.kpp) set_variable_ifdef(CONFIG_DMA_NXP_EDMA CONFIG_MCUX_COMPONENT_driver.edma_soc_rev2) set_variable_ifdef(CONFIG_COUNTER_MCUX_SNVS_SRTC CONFIG_MCUX_COMPONENT_driver.snvs_lp) set_variable_ifdef(CONFIG_DISPLAY_MCUX_DCNANO_LCDIF CONFIG_MCUX_COMPONENT_driver.lcdif) From 0887ccd66027d648d784b1d50c16a0e4dea414af Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:08:03 +0800 Subject: [PATCH 0127/1076] clock: Add KPP clock support for ccm. Add KPP clock support for ccm. Signed-off-by: Qiang Zhang --- drivers/clock_control/clock_control_mcux_ccm_rev2.c | 6 ++++++ include/zephyr/dt-bindings/clock/imx_ccm_rev2.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/drivers/clock_control/clock_control_mcux_ccm_rev2.c b/drivers/clock_control/clock_control_mcux_ccm_rev2.c index 1c2d0363feddf..be7085db8b7bc 100644 --- a/drivers/clock_control/clock_control_mcux_ccm_rev2.c +++ b/drivers/clock_control/clock_control_mcux_ccm_rev2.c @@ -299,6 +299,12 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, break; #endif +#ifdef CONFIG_INPUT_MCUX_KPP + case IMX_CCM_KPP_CLK: + clock_root = kCLOCK_CpuClk; + break; +#endif + default: return -EINVAL; } diff --git a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h index 6df244712536e..a83de65a7060c 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h @@ -155,6 +155,9 @@ #define IMX_CCM_LPIT2_CLK 0x2301UL #define IMX_CCM_LPIT3_CLK 0x2302UL +/* KPP */ +#define IMX_CCM_KPP_CLK 0x2400UL + /* QTMR */ #define IMX_CCM_QTMR_CLK 0x6000UL #define IMX_CCM_QTMR1_CLK 0x6000UL From 2441e76ad0ae8e32d80efa73b22e394790ffd4ef Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:06:16 +0800 Subject: [PATCH 0128/1076] driver: input: Add support for KPP driver. Added support for KPP driver. Signed-off-by: Qiang Zhang --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.mcux_kpp | 16 +++ drivers/input/input_mcux_kpp.c | 191 +++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 drivers/input/Kconfig.mcux_kpp create mode 100644 drivers/input/input_mcux_kpp.c diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 1677514593cc1..5007123095602 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT51XXX_KBD input_ite_it51xxx_kbd. zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT8801_KBD input_ite_it8801_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT8XXX2_KBD input_ite_it8xxx2_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_KBD_MATRIX input_kbd_matrix.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_MCUX_KPP input_mcux_kpp.c) zephyr_library_sources_ifdef(CONFIG_INPUT_MODULINO_BUTTONS input_modulino_buttons.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NUNCHUK input_nunchuk.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e4c83af5350bc..be547866a417e 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -26,6 +26,7 @@ source "drivers/input/Kconfig.it51xxx" source "drivers/input/Kconfig.it8801" source "drivers/input/Kconfig.it8xxx2" source "drivers/input/Kconfig.kbd_matrix" +source "drivers/input/Kconfig.mcux_kpp" source "drivers/input/Kconfig.modulino" source "drivers/input/Kconfig.npcx" source "drivers/input/Kconfig.nunchuk" diff --git a/drivers/input/Kconfig.mcux_kpp b/drivers/input/Kconfig.mcux_kpp new file mode 100644 index 0000000000000..00cf2998bf9f0 --- /dev/null +++ b/drivers/input/Kconfig.mcux_kpp @@ -0,0 +1,16 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_MCUX_KPP + bool "KPP driver" + default y + depends on DT_HAS_NXP_MCUX_KPP_ENABLED + help + Enable the driver of keypad port. + +config INPUT_KPP_PERIOD_MS + int "Sample period" + default 10 + depends on INPUT_MCUX_KPP + help + Sample period in milliseconds when the key is pressed. diff --git a/drivers/input/input_mcux_kpp.c b/drivers/input/input_mcux_kpp.c new file mode 100644 index 0000000000000..df206a8ee2d73 --- /dev/null +++ b/drivers/input/input_mcux_kpp.c @@ -0,0 +1,191 @@ +/* + * Copyright 2025, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(kpp, CONFIG_INPUT_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_mcux_kpp + +#define INPUT_KPP_COLUMNNUM_MAX KPP_KEYPAD_COLUMNNUM_MAX +#define INPUT_KPP_ROWNUM_MAX KPP_KEYPAD_ROWNUM_MAX +#define INPUT_KPP_ROWNUM_MAX KPP_KEYPAD_ROWNUM_MAX + +struct kpp_config { + KPP_Type *base; + const struct device *ccm_dev; + clock_control_subsys_t clk_sub_sys; + const struct pinctrl_dev_config *pcfg; +}; + +struct kpp_data { + uint32_t clock_rate; + struct k_work_delayable work; + uint8_t read_keys_old[KPP_KEYPAD_COLUMNNUM_MAX]; + uint8_t read_keys_new[KPP_KEYPAD_COLUMNNUM_MAX]; + uint8_t key_pressed_number; + const struct device *dev; +}; + +static void get_source_clk_rate(const struct device *dev, uint32_t *clk_rate) +{ + const struct kpp_config *dev_cfg = dev->config; + const struct device *ccm_dev = dev_cfg->ccm_dev; + clock_control_subsys_t clk_sub_sys = dev_cfg->clk_sub_sys; + + if (!device_is_ready(ccm_dev)) { + LOG_ERR("CCM driver is not installed"); + *clk_rate = 0; + return; + } + + clock_control_get_rate(ccm_dev, clk_sub_sys, clk_rate); +} + +static void kpp_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct kpp_data *drv_data = CONTAINER_OF(dwork, struct kpp_data, work); + const struct device *dev = drv_data->dev; + const struct kpp_config *config = dev->config; + + uint8_t read_keys_new[KPP_KEYPAD_COLUMNNUM_MAX]; + + /* Read the key press data */ + KPP_keyPressScanning(config->base, read_keys_new, drv_data->clock_rate); + + /* Analyze the keypad data */ + for (int col = 0; col < INPUT_KPP_COLUMNNUM_MAX; col++) { + if (drv_data->read_keys_old[col] == read_keys_new[col]) { + continue; + } + for (int row = 0; row < INPUT_KPP_ROWNUM_MAX; row++) { + if (((drv_data->read_keys_old[col] ^ read_keys_new[col]) + & BIT(row)) == 0) { + continue; + } + if ((read_keys_new[col] & BIT(row)) != 0) { + /* Key press event */ + KPP_SetSynchronizeChain(config->base, + kKPP_ClearKeyDepressSyncChain); + input_report_abs(dev, INPUT_ABS_X, col, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, row, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); + drv_data->key_pressed_number++; + } else { + /* Key release event */ + KPP_SetSynchronizeChain(config->base, + kKPP_SetKeyReleasesSyncChain); + input_report_abs(dev, INPUT_ABS_X, col, false, K_FOREVER); + input_report_abs(dev, INPUT_ABS_Y, row, false, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); + drv_data->key_pressed_number--; + } + drv_data->read_keys_old[col] = read_keys_new[col]; + } + } + + if (drv_data->key_pressed_number == 0U) { + KPP_ClearStatusFlag(config->base, kKPP_keyDepressInterrupt | + kKPP_keyReleaseInterrupt); + KPP_EnableInterrupts(config->base, kKPP_keyDepressInterrupt); + } else { + k_work_schedule(&drv_data->work, K_MSEC(CONFIG_INPUT_KPP_PERIOD_MS)); + } +} + +static void kpp_isr(const struct device *dev) +{ + const struct kpp_config *config = dev->config; + struct kpp_data *drv_data = dev->data; + + uint16_t status = KPP_GetStatusFlag(config->base); + + if ((status & kKPP_keyDepressInterrupt) == 0) { + LOG_ERR("No key press or release detected"); + return; + } + + drv_data->key_pressed_number = 0; + /* Disable interrupts. */ + KPP_DisableInterrupts(config->base, kKPP_keyDepressInterrupt | + kKPP_keyReleaseInterrupt); + /* Clear status. */ + KPP_ClearStatusFlag(config->base, kKPP_keyDepressInterrupt | + kKPP_keyReleaseInterrupt); + /* Key depress report */ + k_work_schedule(&drv_data->work, K_MSEC(0)); +} + +static int input_kpp_init(const struct device *dev) +{ + const struct kpp_config *config = dev->config; + struct kpp_data *drv_data = dev->data; + kpp_config_t kppConfig; + + if (!device_is_ready(config->ccm_dev)) { + LOG_ERR("CCM driver is not installed"); + return -ENODEV; + } + + int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + + if (ret < 0) { + LOG_ERR("Failed to configure pin"); + return ret; + } + + kppConfig.activeRow = 0xFF; + kppConfig.activeColumn = 0xFF; + kppConfig.interrupt = kKPP_keyDepressInterrupt; + + KPP_Init(config->base, &kppConfig); + + get_source_clk_rate(dev, &drv_data->clock_rate); + + drv_data->dev = dev; + + /* Read the key press data */ + KPP_keyPressScanning(config->base, drv_data->read_keys_old, drv_data->clock_rate); + + k_work_init_delayable(&drv_data->work, kpp_work_handler); + + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), + kpp_isr, DEVICE_DT_INST_GET(0), 0); + return 0; +} + +#define INPUT_KPP_INIT(n) \ + static struct kpp_data kpp_data_##n; \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct kpp_config kpp_config_##n = { \ + .base = (KPP_Type *)DT_INST_REG_ADDR(n), \ + .clk_sub_sys = \ + (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name), \ + .ccm_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + input_kpp_init, \ + NULL, \ + &kpp_data_##n, \ + &kpp_config_##n, \ + POST_KERNEL, \ + CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(INPUT_KPP_INIT) From 55adebb51b72e4fe86a07fd151543f19c0926730 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:10:14 +0800 Subject: [PATCH 0129/1076] dts: add KPP driver bindings. add KPP driver bindings. Signed-off-by: Qiang Zhang --- dts/arm/nxp/nxp_rt118x.dtsi | 10 ++++++++++ dts/bindings/input/nxp,mcux-kpp.yaml | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 dts/bindings/input/nxp,mcux-kpp.yaml diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 62b296d666b19..acc4acfd88121 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -1253,6 +1253,16 @@ #size-cells = <0>; }; + kpp: kpp@2a00000 { + compatible = "nxp,mcux-kpp"; + reg = <0x2A00000 0x1000>; + interrupts = <211 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_KPP_CLK 0x0 0>; + }; + lpspi2: spi@4370000 { compatible = "nxp,lpspi"; reg = <0x4370000 0x4000>; diff --git a/dts/bindings/input/nxp,mcux-kpp.yaml b/dts/bindings/input/nxp,mcux-kpp.yaml new file mode 100644 index 0000000000000..fc4181537a958 --- /dev/null +++ b/dts/bindings/input/nxp,mcux-kpp.yaml @@ -0,0 +1,18 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP KPP controller + +compatible: "nxp,mcux-kpp" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true From be362de579ff28446e80e139b09f7a0d966b2c14 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:11:16 +0800 Subject: [PATCH 0130/1076] boards: nxp: add kpp peripheral to mimxrt1180_evk. add kpp peripheral to mimxrt1180_evk. Signed-off-by: Qiang Zhang --- boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts | 4 ++++ boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml | 1 + boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts | 4 ++++ boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml | 1 + 4 files changed, 10 insertions(+) diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts index e6d9905bedaf9..9ac6bcd04cb7a 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts @@ -102,3 +102,7 @@ zephyr_udc1: &usb2{ tx-cal-45-dp-ohms = <6>; tx-cal-45-dm-ohms = <6>; }; + +&kpp { + status = "okay"; +}; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml index bd7fedb8e97b3..9534ab199b1dd 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml @@ -31,4 +31,5 @@ supported: - usbd - sdhc - dac + - kpp vendor: nxp diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts index 4a5a7ab25c173..4ff556d70f400 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts @@ -100,3 +100,7 @@ zephyr_udc1: &usb2{ tx-cal-45-dp-ohms = <6>; tx-cal-45-dm-ohms = <6>; }; + +&kpp { + status = "okay"; +}; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml index 6ec060575dc8c..5de44c44d720a 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml @@ -28,4 +28,5 @@ supported: - spi - uart - dac + - kpp vendor: nxp From d350cde656721999469607b0737b3b59e21a2d0d Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 17 Jul 2025 20:04:00 +0800 Subject: [PATCH 0131/1076] test: added input_dume test implementation. added gpio_kpp test implementation. Signed-off-by: Qiang Zhang --- .../mimxrt1180_evk_mimxrt1189_cm33.overlay | 31 +++++++++++++++++++ .../mimxrt1180_evk_mimxrt1189_cm7.overlay | 31 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay create mode 100644 samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay diff --git a/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..2fe4739c5b43a --- /dev/null +++ b/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,31 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + kpp = &kpp; + }; +}; + +&pinctrl { + kpp_default: kpp_default { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_00_kpp_row7 + &iomuxc_gpio_sd_b1_01_kpp_col7 + &iomuxc_gpio_sd_b1_02_kpp_row6 + &iomuxc_gpio_sd_b1_03_kpp_col6>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; +}; + +&kpp { + pinctrl-0 = <&kpp_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..2fe4739c5b43a --- /dev/null +++ b/samples/subsys/input/input_dump/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,31 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + kpp = &kpp; + }; +}; + +&pinctrl { + kpp_default: kpp_default { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_00_kpp_row7 + &iomuxc_gpio_sd_b1_01_kpp_col7 + &iomuxc_gpio_sd_b1_02_kpp_row6 + &iomuxc_gpio_sd_b1_03_kpp_col6>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; +}; + +&kpp { + pinctrl-0 = <&kpp_default>; + pinctrl-names = "default"; + status = "okay"; +}; From e0fcfa1be9e0806635826af4ca79da416cb474a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Tue, 1 Jul 2025 13:53:22 +0200 Subject: [PATCH 0132/1076] samples: subsys: usb: hid-keyboard: Confirm operation with console MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use console logs to determine if sample operates correctly. Signed-off-by: Sebastian Głąb --- samples/subsys/usb/hid-keyboard/sample.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/samples/subsys/usb/hid-keyboard/sample.yaml b/samples/subsys/usb/hid-keyboard/sample.yaml index 6161ff90c2cf0..f53ae514f97c6 100644 --- a/samples/subsys/usb/hid-keyboard/sample.yaml +++ b/samples/subsys/usb/hid-keyboard/sample.yaml @@ -1,11 +1,17 @@ sample: name: USB HID keyboard sample common: - harness: button filter: dt_alias_exists("sw0") and dt_alias_exists("led0") depends_on: - usbd - gpio + tags: usb + timeout: 15 + harness: console + harness_config: + type: one_line + regex: + - "HID keyboard sample is initialized" integration_platforms: - nrf52840dk/nrf52840 - nrf54h20dk/nrf54h20/cpuapp @@ -17,17 +23,13 @@ common: - samd21_xpro - same54_xpro tests: - sample.usbd.hid-keyboard: - tags: usb + sample.usbd.hid-keyboard: {} sample.usbd.hid-keyboard.out-report: - tags: usb extra_args: - EXTRA_DTC_OVERLAY_FILE="out_report.overlay" sample.usbd.hid-keyboard.large-report: - tags: usb extra_args: - EXTRA_DTC_OVERLAY_FILE="large_in_report.overlay" sample.usbd.hid-keyboard.large-out-report: - tags: usb extra_args: - EXTRA_DTC_OVERLAY_FILE="large_out_report.overlay" From dd95a7d83debfa08c4517aa04f3fdc8a519c7e2b Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 5 Aug 2025 09:33:38 +0200 Subject: [PATCH 0133/1076] Revert "boards: nordic: nrf54l10_cpuapp_ns: Add workaround for partitions" This reverts commit 002838ab9ef526c882225504bda0ef86ff577455. Signed-off-by: Georgios Vasilakis --- boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts | 3 --- boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts | 3 --- 2 files changed, 6 deletions(-) diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts index 39a986ae2b670..02d900390cca9 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts @@ -59,9 +59,6 @@ }; &cpuapp_rram { - /* TODO: revert this hack when TF-M update is available that fixes partition sizes */ - reg = <0x0 DT_SIZE_K(1022)>; - partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts index cd644d845d5e5..f1aa851ed2d9a 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts @@ -58,9 +58,6 @@ }; &cpuapp_rram { - /* TODO: revert this hack when TF-M update is available that fixes partition sizes */ - reg = <0x0 DT_SIZE_K(1022)>; - partitions { compatible = "fixed-partitions"; #address-cells = <1>; From 9f0d2770f1ce544a0287d90731d0babed67f0972 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 5 Aug 2025 09:43:53 +0200 Subject: [PATCH 0134/1076] boards: nordic: Fix RRAM size for nRF54l10 NS The nRF54L1 has 1012 KB RRAM and not 1022 KB as it was set before. This adjusts the NS target with the correct size. Signed-off-by: Georgios Vasilakis --- .../nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts | 12 ++++++------ .../nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts index f1aa851ed2d9a..cfb02b6817a5e 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts @@ -31,8 +31,8 @@ / { /* * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support. - * - Lowest 96 kB SRAM allocated to Secure image (sram0_s). - * - Upper 96 kB SRAM allocated to Non-Secure image (sram0_ns). + * - Lowest 72 kB SRAM allocated to Secure image (sram0_s). + * - Upper 72 kB SRAM allocated to Non-Secure image (sram0_ns). * * nRF54L10 has 192 kB of volatile memory (SRAM) but the last 42kB are reserved for * the FLPR MCU. @@ -62,7 +62,7 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - /* nRF54L10 has 1022 kB of non volatile memory (RRAM) but the + /* nRF54L10 has 1012 kB of non volatile memory (RRAM) but the * last 62kB are reserved for the FLPR MCU. * * This static layout needs to be the same with the upstream TF-M layout in the @@ -91,12 +91,12 @@ slot0_ns_partition: partition@6A000 { label = "image-0-nonsecure"; - reg = <0x0006A000 DT_SIZE_K(504)>; + reg = <0x0006A000 DT_SIZE_K(494)>; }; - storage_partition: partition@E8000 { + storage_partition: partition@E5800 { label = "storage"; - reg = <0x000E8000 DT_SIZE_K(32)>; + reg = <0x000E5800 DT_SIZE_K(32)>; }; }; }; diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.yaml b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.yaml index 9f42daedf4e35..22fbcbc32c3c4 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.yaml +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb - zephyr ram: 192 -flash: 1022 +flash: 1012 supported: - adc - gpio From fdf55fe460a21678c019a055d2a6b5e5abb2b10d Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 5 Aug 2025 10:20:47 +0200 Subject: [PATCH 0135/1076] manifest: Bring TF-M with fixed nRF54L10 NS RRAM size Corrects the RRAM size in the TF-M repo. Signed-off-by: Georgios Vasilakis --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ec143c671bbda..7bf652bf2ef3f 100644 --- a/west.yml +++ b/west.yml @@ -361,7 +361,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: 021e2bbd50c215e41710a72e05abce3224f074a7 + revision: cc800268f79779fa674b7085ecf507eb95b83ff9 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 7f9459571ad66f921ba48d56dcaddae1d603a233 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 5 Aug 2025 10:47:53 +0200 Subject: [PATCH 0136/1076] boards: ezurio: Fix RRAM size for nRF54l10 NS The nRF54L1 has 1012 KB RRAM and not 1022 KB as it was set before. This adjusts the NS target RRAM size for the relevant Ezurio boards which use the nRF54L10. Signed-off-by: Georgios Vasilakis --- .../bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts | 12 ++++++------ .../bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts index 02d900390cca9..e7883bcbfaba8 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts @@ -32,8 +32,8 @@ / { /* * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support. - * - Lowest 96 kB SRAM allocated to Secure image (sram0_s). - * - Upper 96 kB SRAM allocated to Non-Secure image (sram0_ns). + * - Lowest 72 kB SRAM allocated to Secure image (sram0_s). + * - Upper 72 kB SRAM allocated to Non-Secure image (sram0_ns). * * nRF54L10 has 192 kB of volatile memory (SRAM) but the last 42kB are reserved for * the FLPR MCU. @@ -63,7 +63,7 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - /* nRF54L10 has 1022 kB of non volatile memory (RRAM) but the + /* nRF54L10 has 1012 kB of non volatile memory (RRAM) but the * last 62kB are reserved for the FLPR MCU. * * This static layout needs to be the same with the upstream TF-M layout in the @@ -92,12 +92,12 @@ slot0_ns_partition: partition@6A000 { label = "image-0-nonsecure"; - reg = <0x0006A000 DT_SIZE_K(504)>; + reg = <0x0006A000 DT_SIZE_K(494)>; }; - storage_partition: partition@E8000 { + storage_partition: partition@E5800 { label = "storage"; - reg = <0x000E8000 DT_SIZE_K(32)>; + reg = <0x000E5800 DT_SIZE_K(32)>; }; }; }; diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.yaml b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.yaml index d2ad19f03c4a9..19bb368fc6134 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.yaml +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.yaml @@ -11,7 +11,7 @@ toolchain: - zephyr sysbuild: true ram: 192 -flash: 1022 +flash: 1012 supported: - adc - gpio From 5245307512a07e0e489fb920c27d3f102ba3fca1 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 25 Aug 2025 13:48:06 +0800 Subject: [PATCH 0137/1076] Bluetooth: GATT: Check len of response before parsing response PDU In function `parse_read_by_uuid()`, the response length is not checked before parsing the response PDU. There is a potential issue that the `len` will be underflowed if the `len` is less than the size of `struct bt_att_data`. Check the length before parsing the response PDU. If the length is less then the size of `struct bt_att_data`, notify the upper layer with the error `BT_ATT_ERR_INVALID_PDU` and stop the parsing. Signed-off-by: Lyle Zhu --- include/zephyr/bluetooth/gatt.h | 5 +++++ subsys/bluetooth/host/gatt.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 2c7d36a67588e..17b125d602c5f 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -1897,6 +1897,9 @@ struct bt_gatt_read_params; * When reading using by_uuid, `params->start_handle` is the attribute handle * for this `data` item. * + * If the received data length is invalid, the callback will called with the + * error @ref BT_ATT_ERR_INVALID_PDU. + * * @param conn Connection object. * @param err ATT error code. * @param params Read parameters used. @@ -2005,6 +2008,8 @@ struct bt_gatt_read_params { * The Response comes in callback @p params->func. The callback is run from * the context specified by 'config BT_RECV_CONTEXT'. * @p params must remain valid until start of callback. + * If the received data length is invalid, the callback @p params->func will + * called with the error @ref BT_ATT_ERR_INVALID_PDU. * * @param conn Connection object. * @param params Read parameters. diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 7131d2fc3d059..0770d6a407bb0 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -4776,6 +4776,15 @@ static void parse_read_by_uuid(struct bt_conn *conn, uint16_t handle; uint16_t len; + len = MIN(rsp->len, length); + if (len < sizeof(struct bt_att_data)) { + LOG_WRN("Bad peer: ATT read-by-uuid rsp: invalid ATTR PDU len %u", len); + params->func(conn, BT_ATT_ERR_INVALID_PDU, params, NULL, 0); + return; + } + + len -= sizeof(struct bt_att_data); + handle = sys_le16_to_cpu(data->handle); /* Handle 0 is invalid */ @@ -4784,8 +4793,6 @@ static void parse_read_by_uuid(struct bt_conn *conn, return; } - len = rsp->len > length ? length - 2 : rsp->len - 2; - LOG_DBG("handle 0x%04x len %u value %u", handle, rsp->len, len); if (!IN_RANGE(handle, req_start_handle, req_end_handle)) { From 993713a47f810f165eb39ac61f29fe5e51414e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Aug 2025 14:22:18 +0200 Subject: [PATCH 0138/1076] include: lorawan: remove ifdef-ry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not KConfig-gate function declarations as per Zephyr's API guidelines Signed-off-by: Benjamin Cabé --- include/zephyr/lorawan/lorawan.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/zephyr/lorawan/lorawan.h b/include/zephyr/lorawan/lorawan.h index 9f8688189cbe8..c50ccb3b316d2 100644 --- a/include/zephyr/lorawan/lorawan.h +++ b/include/zephyr/lorawan/lorawan.h @@ -454,8 +454,6 @@ int lorawan_device_time_get(uint32_t *gps_time); */ int lorawan_request_link_check(bool force_request); -#ifdef CONFIG_LORAWAN_APP_CLOCK_SYNC - /** * @brief Run Application Layer Clock Synchronization service * @@ -484,10 +482,6 @@ int lorawan_clock_sync_run(void); */ int lorawan_clock_sync_get(uint32_t *gps_time); -#endif /* CONFIG_LORAWAN_APP_CLOCK_SYNC */ - -#ifdef CONFIG_LORAWAN_FRAG_TRANSPORT - /** * @brief Register a handle descriptor callback function. * @@ -513,8 +507,6 @@ void lorawan_frag_transport_register_descriptor_callback(transport_descriptor_cb */ int lorawan_frag_transport_run(void (*transport_finished_cb)(void)); -#endif /* CONFIG_LORAWAN_FRAG_TRANSPORT */ - #ifdef __cplusplus } #endif From 6aa3e9e9726f767b98005ec1592b457bd5d3f579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 26 Aug 2025 14:24:36 +0200 Subject: [PATCH 0139/1076] include: lorawan: document deps of clock sync and frag transport APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Doxygen tags giving users an indication that some API will only be available if the corresponding Kconfig option is enabled. Signed-off-by: Benjamin Cabé --- include/zephyr/lorawan/lorawan.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/zephyr/lorawan/lorawan.h b/include/zephyr/lorawan/lorawan.h index c50ccb3b316d2..21df1ceb28d31 100644 --- a/include/zephyr/lorawan/lorawan.h +++ b/include/zephyr/lorawan/lorawan.h @@ -458,12 +458,15 @@ int lorawan_request_link_check(bool force_request); * @brief Run Application Layer Clock Synchronization service * * This service sends out its current time in a regular interval (configurable - * via Kconfig) and receives a correction offset from the application server if - * the clock deviation is considered too large. + * via Kconfig, using @kconfig{CONFIG_LORAWAN_APP_CLOCK_SYNC_PERIODICITY}) and + * receives a correction offset from the application server if the clock + * deviation is considered too large. * * Clock synchronization is required for firmware upgrades over multicast * sessions, but can also be used independent of a FUOTA process. * + * @kconfig_dep{CONFIG_LORAWAN_APP_CLOCK_SYNC} + * * @return 0 if successful, negative errno otherwise. */ int lorawan_clock_sync_run(void); @@ -476,6 +479,8 @@ int lorawan_clock_sync_run(void); * The GPS epoch started on 1980-01-06T00:00:00Z, but has since diverged * from UTC, as it does not consider corrections like leap seconds. * + * @kconfig_dep{CONFIG_LORAWAN_APP_CLOCK_SYNC} + * * @param gps_time Synchronized time in GPS epoch format truncated to 32-bit. * * @return 0 if successful, -EAGAIN if the clock is not yet synchronized. @@ -489,7 +494,9 @@ int lorawan_clock_sync_get(uint32_t *gps_time); * whenever a FragSessionSetupReq is received and Descriptor field should be * handled. * - * @param transport_descriptor_cb Callback for notification. + * @kconfig_dep{CONFIG_LORAWAN_FRAG_TRANSPORT} + * + * @param cb Callback for notification. */ void lorawan_frag_transport_register_descriptor_callback(transport_descriptor_cb cb); @@ -501,6 +508,8 @@ void lorawan_frag_transport_register_descriptor_callback(transport_descriptor_cb * * After all fragments have been received, the provided callback is invoked. * + * @kconfig_dep{CONFIG_LORAWAN_FRAG_TRANSPORT} + * * @param transport_finished_cb Callback for notification of finished data transfer. * * @return 0 if successful, negative errno otherwise. From 7305de28dbf5fa7f4746b4d6a114f86e083dfbbe Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 25 Aug 2025 17:01:55 +0800 Subject: [PATCH 0140/1076] board: imx95_evk: fix jlink device id Device ID should be MIMX9596 for i.MX95 EVK board. Signed-off-by: Jiafei Pan --- boards/nxp/imx95_evk/board.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/imx95_evk/board.cmake b/boards/nxp/imx95_evk/board.cmake index daca6ade79faf..691814e7f94f7 100644 --- a/boards/nxp/imx95_evk/board.cmake +++ b/boards/nxp/imx95_evk/board.cmake @@ -21,6 +21,6 @@ if(CONFIG_BOARD_NXP_SPSDK_IMAGE OR (DEFINED ENV{USE_NXP_SPSDK_IMAGE} endif() if(CONFIG_SOC_MIMX9596_A55) - board_runner_args(jlink "--device=MIMX9556_A55_0" "--no-reset" "--flash-sram") + board_runner_args(jlink "--device=MIMX9596_A55_0" "--no-reset" "--flash-sram") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) endif() From cb1b569fc38476984adbf50364f28f7bb60817b5 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Mon, 25 Aug 2025 15:46:50 +0200 Subject: [PATCH 0141/1076] boards: nrf9280pdk: disable IEEE 802.15.4 support nRF92 series is not supported in the IEEE 802.15.4 stack yet, so remove it from the board for now. Signed-off-by: Bernt Johan Damslora --- boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts index f4cce12f4b1a0..6e5c5e00197f4 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts @@ -24,7 +24,6 @@ zephyr,flash = &mram1x; zephyr,sram = &cpuapp_data; zephyr,shell-uart = &uart136; - zephyr,ieee802154 = &cpuapp_ieee802154; zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; }; @@ -278,10 +277,6 @@ ipc0: &cpuapp_cpurad_ipc { }; }; -&cpuapp_ieee802154 { - status = "okay"; -}; - zephyr_udc0: &usbhs { status = "okay"; }; From 46e9b4a6af9a82b6d69d6db1346c675bfddc629b Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Wed, 20 Aug 2025 17:21:05 +0200 Subject: [PATCH 0142/1076] boards: nrf9280pdk: Add revision 0.2.0 Add revision support and overlays for rev. 0.2.0. Signed-off-by: Bernt Johan Damslora --- boards/nordic/nrf9280pdk/board.yml | 7 +++ .../nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi | 53 +++++++++++++++++++ .../nrf9280pdk_nrf9280_cpuapp_0_2_0.overlay | 52 ++++++++++++++++++ .../nrf9280pdk_nrf9280_cpuppr_0_2_0.overlay | 7 +++ .../nrf9280pdk_nrf9280_cpurad_0_2_0.overlay | 7 +++ 5 files changed, 126 insertions(+) create mode 100644 boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi create mode 100644 boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp_0_2_0.overlay create mode 100644 boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuppr_0_2_0.overlay create mode 100644 boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad_0_2_0.overlay diff --git a/boards/nordic/nrf9280pdk/board.yml b/boards/nordic/nrf9280pdk/board.yml index 2cce133d95c36..274b9a84a7b7c 100644 --- a/boards/nordic/nrf9280pdk/board.yml +++ b/boards/nordic/nrf9280pdk/board.yml @@ -9,3 +9,10 @@ board: cpucluster: cpuppr - name: iron cpucluster: cpuapp + revision: + format: major.minor.patch + default: 0.2.0 + exact: false + revisions: + - name: 0.1.0 + - name: 0.2.0 diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi new file mode 100644 index 0000000000000..41ca41e073e47 --- /dev/null +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart135_default: uart135_default { + group1 { + psels = , + ; + }; + + group3 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart135_sleep: uart135_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; + + /omit-if-no-ref/ uart136_default: uart136_default { + group1 { + psels = , + ; + }; + + group3 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart136_sleep: uart136_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp_0_2_0.overlay b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp_0_2_0.overlay new file mode 100644 index 0000000000000..4fa3f667eadda --- /dev/null +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp_0_2_0.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi" + +/ { + aliases { + pwm-led0 = &pwm_led2; /* Alias for compatibility with samples that use pwm-led0 */ + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio9 0 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + + led1: led_1 { + gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + + led2: led_2 { + gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + + led3: led_3 { + gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + /delete-node/ pwm_led_0; + + /* + * There is no valid hardware configuration to pass PWM signal on pins 0 and 1. + * First valid config is P9.2. This corresponds to LED 2. + * Signal on PWM130's channel 0 can be passed directly on GPIO Port 9 pin 2. + */ + pwm_led2: pwm_led_2 { + pwms = <&pwm130 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; +}; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuppr_0_2_0.overlay b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuppr_0_2_0.overlay new file mode 100644 index 0000000000000..f2d986e6cb065 --- /dev/null +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuppr_0_2_0.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi" diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad_0_2_0.overlay b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad_0_2_0.overlay new file mode 100644 index 0000000000000..f2d986e6cb065 --- /dev/null +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad_0_2_0.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf9280pdk_nrf9280-pinctrl_0_2_0.dtsi" From 20360ff4da0b63b569db26bb55a9f256b038baaa Mon Sep 17 00:00:00 2001 From: Sean Kyer Date: Thu, 21 Aug 2025 09:18:20 -0700 Subject: [PATCH 0143/1076] settings: Remove default selection of TF-M ITS backend Remove the default selection of SETTINGS_TFM_ITS when TFM_PARTITION_INTERNAL_TRUSTED_STORAGE is enabled which caused this backend to be built when it was not intended. Signed-off-by: Sean Kyer --- subsys/settings/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig index 2e75286550e98..bdd80149e887a 100644 --- a/subsys/settings/Kconfig +++ b/subsys/settings/Kconfig @@ -44,7 +44,6 @@ choice SETTINGS_BACKEND default SETTINGS_NVS if NVS default SETTINGS_FCB if FCB default SETTINGS_FILE if FILE_SYSTEM - default SETTINGS_TFM_ITS if TFM_PARTITION_INTERNAL_TRUSTED_STORAGE default SETTINGS_RETENTION if SETTINGS_SUPPORTED_RETENTION default SETTINGS_NONE help From 102ce2ac3b5cfea8ba812ad184be61c2b0b5eba4 Mon Sep 17 00:00:00 2001 From: Sean Kyer Date: Thu, 21 Aug 2025 09:20:39 -0700 Subject: [PATCH 0144/1076] tests: settings: ITS: Explicitly enable TF-M ITS Explicitly enable the TF-M ITS backend for the settings subsystem in the settings its test. Signed-off-by: Sean Kyer --- tests/subsys/settings/its/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/settings/its/prj.conf b/tests/subsys/settings/its/prj.conf index 7d9f4339bb6cd..e03e76747ba34 100644 --- a/tests/subsys/settings/its/prj.conf +++ b/tests/subsys/settings/its/prj.conf @@ -9,4 +9,5 @@ CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE=y CONFIG_TFM_ITS_MAX_ASSET_SIZE_OVERRIDE=y CONFIG_TFM_ITS_MAX_ASSET_SIZE=1024 CONFIG_SETTINGS=y +CONFIG_SETTINGS_TFM_ITS=y CONFIG_SETTINGS_RUNTIME=y From 3a54a4d1239fbe795af978d4c75cd91b87fd73cd Mon Sep 17 00:00:00 2001 From: Sean Kyer Date: Thu, 21 Aug 2025 09:22:25 -0700 Subject: [PATCH 0145/1076] settings: Add EXPERIMENTAL to TF-M ITS backend Add select EXPERIMENTAL to the TF-M ITS backend of the settings subsystem. Signed-off-by: Sean Kyer --- subsys/settings/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig index bdd80149e887a..617d311335ff4 100644 --- a/subsys/settings/Kconfig +++ b/subsys/settings/Kconfig @@ -127,6 +127,7 @@ config SETTINGS_CUSTOM config SETTINGS_TFM_ITS bool "Internal Trusted Storage (ITS) settings backend" depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE + select EXPERIMENTAL help Enables Internal Trusted Storage (ITS) Settings backend. Intended for use with boards using TF-M which cannot make use of persistent storage otherwise. From e7b49592b2e5ef3f691b816e417d1116ab5ea37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 18 Aug 2025 11:24:46 +0200 Subject: [PATCH 0146/1076] include: drivers: swdp: Add missing doxygen comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the documentation of swdp.h Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/swdp.h | 64 +++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/include/zephyr/drivers/swdp.h b/include/zephyr/drivers/swdp.h index d742280e883f9..6ea8e854cec09 100644 --- a/include/zephyr/drivers/swdp.h +++ b/include/zephyr/drivers/swdp.h @@ -18,28 +18,76 @@ extern "C" { #endif -/* SWDP packet request bits */ +/** + * @defgroup swdp_interface SWDP Interface + * @since 3.7 + * @version 0.1.0 + * @ingroup io_interfaces + * @{ + */ + +/** + * @name SWD Packet Request Bits + * + * Bit definitions for SWD packet request fields. + * These bits are used to construct the 8-bit request packet header sent during an SWD transaction. + * + * @{ + */ + +/** Access Port (AP) or Debug Port (DP). 1 = AP, 0 = DP */ #define SWDP_REQUEST_APnDP BIT(0) +/** Read (1) or Write (0) operation */ #define SWDP_REQUEST_RnW BIT(1) +/** Address bit 2 for register selection */ #define SWDP_REQUEST_A2 BIT(2) +/** Address bit 3 for register selection */ #define SWDP_REQUEST_A3 BIT(3) -/* SWDP acknowledge response bits */ +/** @} */ + +/** + * @name SWD Acknowledge (ACK) Response Bits + * + * Bit definitions for SWD acknowledge response fields. + * These bits are used to indicate the result of an SWD transaction. + * + * @{ + */ + +/** Transaction completed successfully */ #define SWDP_ACK_OK BIT(0) +/** Target requests to retry the transaction later */ #define SWDP_ACK_WAIT BIT(1) +/** Target detected a fault condition */ #define SWDP_ACK_FAULT BIT(2) -/* SWDP transfer or parity error */ +/** @} */ + +/** Transfer or parity error detected during transaction */ #define SWDP_TRANSFER_ERROR BIT(3) -/* SWDP Interface pins */ +/** + * @name SWDP Interface Pin Definitions + * + * Pin identifiers for SWDP interface control. + * These constants define bit positions for controlling individual pins in the SWDP interface. + * + * @{ + */ + +/** Serial Wire Clock (SWCLK) pin identifier */ #define SWDP_SWCLK_PIN 0U +/** Serial Wire Data Input/Output (SWDIO) pin identifier */ #define SWDP_SWDIO_PIN 1U +/** Active-low reset (nRESET) pin identifier */ #define SWDP_nRESET_PIN 7U -/* - * Serial Wire Interface (SWDP) driver API. - * This is the mandatory API any Serial Wire driver needs to expose. +/** @} */ + +/** + * Serial Wire Debug Port (SWDP) driver API. + * This is the mandatory API any Serial Wire Debug Port driver needs to expose. */ struct swdp_api { /** @@ -148,4 +196,6 @@ struct swdp_api { } #endif +/** @} */ + #endif /* ZEPHYR_INCLUDE_SWDP_H_ */ From 5d9353b1fa8fb7f238d3484d0f813eb402f133b2 Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Wed, 6 Aug 2025 10:57:22 +0800 Subject: [PATCH 0147/1076] dts: arm: nxp: update nxp_rw6xx_common.dtsi for usb host. Add usbh node. Signed-off-by: Aiden Hu --- dts/arm/nxp/nxp_rw6xx_common.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index c855185c9ce0c..70278c757ce41 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -248,6 +248,15 @@ status = "disabled"; }; + usbh: usbh@145000 { + compatible = "nxp,uhc-ehci"; + reg = <0x145000 0x200>; + interrupts = <50 1>; + interrupt-names = "usb_otg"; + power-domains = <&power_mode3_domain>; + status = "disabled"; + }; + flexcomm0: flexcomm@106000 { compatible = "nxp,lpc-flexcomm"; reg = <0x106000 0x1000>; From d560f54e9f72acfbea9c1336f3f4b7ddd34d973b Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Wed, 6 Aug 2025 09:34:39 +0800 Subject: [PATCH 0148/1076] soc: nxp: rw: update soc.c of rw for usb clock usb clock enablement for UHC NXP EHCI on rw. Signed-off-by: Aiden Hu --- soc/nxp/rw/soc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/soc/nxp/rw/soc.c b/soc/nxp/rw/soc.c index 86bc4c904d9f9..166c6008310e2 100644 --- a/soc/nxp/rw/soc.c +++ b/soc/nxp/rw/soc.c @@ -277,7 +277,8 @@ __weak __ramfunc void clock_init(void) #endif /* CONFIG_COUNTER_MCUX_CTIMER || CONFIG_PWM_MCUX_CTIMER */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb_otg)) && \ - (CONFIG_USB_DC_NXP_EHCI || CONFIG_UDC_NXP_EHCI) + (CONFIG_USB_DC_NXP_EHCI || CONFIG_UDC_NXP_EHCI) || \ + (CONFIG_UHC_NXP_EHCI) /* Enable system xtal from Analog */ SYSCTL2->ANA_GRP_CTRL |= SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK; /* reset USB */ From 2dd8570eecea0bae4a11ab30dc42695ec20e723c Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Tue, 19 Aug 2025 17:34:54 +0800 Subject: [PATCH 0149/1076] modules: hal_nxp: mcux: update macros for usb host EHCI Change the default value for QH/QTD/ITD/SITD of usb host ehci. Signed-off-by: Aiden Hu --- .../hal_nxp/mcux/mcux-sdk-ng/middleware/usb_host_config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_host_config.h b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_host_config.h index bf5f058abebd5..16a5f19beeef1 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_host_config.h +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/usb_host_config.h @@ -16,10 +16,10 @@ #ifdef CONFIG_UHC_NXP_EHCI #define USB_HOST_CONFIG_EHCI (2U) #define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U) -#define USB_HOST_CONFIG_EHCI_MAX_QH (8U) -#define USB_HOST_CONFIG_EHCI_MAX_QTD (8U) -#define USB_HOST_CONFIG_EHCI_MAX_ITD (0U) -#define USB_HOST_CONFIG_EHCI_MAX_SITD (0U) +#define USB_HOST_CONFIG_EHCI_MAX_QH (16U) +#define USB_HOST_CONFIG_EHCI_MAX_QTD (16U) +#define USB_HOST_CONFIG_EHCI_MAX_ITD (16U) +#define USB_HOST_CONFIG_EHCI_MAX_SITD (16U) #else #define USB_HOST_CONFIG_EHCI (0U) #endif /* CONFIG_USB_DC_NXP_EHCI */ From b714ea3484bf13e310c8b11d55d444f0615d4f9c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Aug 2025 17:01:03 +0200 Subject: [PATCH 0150/1076] Bluetooth: Shell: Increment SID per set Instead of always using SID=0 for advertising sets (which can be tricky if there are multiple advertising sets using the same SID and address), the SID will be incremented and wrap around when reaching the max to reduce the risk of 2 or more sets having the same SID. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/shell/bt.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index 9ecb9ff148d9d..18c6c70b1b605 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -6,12 +6,13 @@ /* * Copyright (c) 2017 Intel Corporation - * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2018-2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include #include @@ -2241,9 +2242,10 @@ static int cmd_directed_adv(const struct shell *sh, #endif /* CONFIG_BT_PERIPHERAL */ #if defined(CONFIG_BT_EXT_ADV) -static bool adv_param_parse(size_t argc, char *argv[], - struct bt_le_adv_param *param) +static bool parse_and_set_adv_param(size_t argc, char *argv[], struct bt_le_adv_param *param) { + static uint8_t next_adv_sid = BT_GAP_SID_MIN; + memset(param, 0, sizeof(struct bt_le_adv_param)); if (!strcmp(argv[1], "conn-scan")) { @@ -2312,7 +2314,7 @@ static bool adv_param_parse(size_t argc, char *argv[], } param->id = selected_id; - param->sid = 0; + param->sid = next_adv_sid++; if (param->peer && !(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) { param->interval_min = 0; @@ -2322,6 +2324,10 @@ static bool adv_param_parse(size_t argc, char *argv[], param->interval_max = BT_GAP_ADV_FAST_INT_MAX_2; } + if (next_adv_sid > BT_GAP_SID_MAX) { + next_adv_sid = BT_GAP_SID_MIN; + } + return true; } @@ -2332,7 +2338,7 @@ static int cmd_adv_create(const struct shell *sh, size_t argc, char *argv[]) uint8_t adv_index; int err; - if (!adv_param_parse(argc, argv, ¶m)) { + if (!parse_and_set_adv_param(argc, argv, ¶m)) { shell_help(sh); return -ENOEXEC; } @@ -2363,7 +2369,7 @@ static int cmd_adv_param(const struct shell *sh, size_t argc, char *argv[]) struct bt_le_adv_param param; int err; - if (!adv_param_parse(argc, argv, ¶m)) { + if (!parse_and_set_adv_param(argc, argv, ¶m)) { shell_help(sh); return -ENOEXEC; } From bbcbcbfc413fb3c9448eb238ace8c0e03e425651 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Aug 2025 17:04:37 +0200 Subject: [PATCH 0151/1076] Bluetooth: Adv: Store SID and expose via adv_info Store the SID in the advertising set, and let it be possible to get it again via bt_le_ext_adv_get_info. The SID may be used by higher layers to shared information about the advertising set. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/bluetooth.h | 3 +++ subsys/bluetooth/host/adv.c | 2 ++ subsys/bluetooth/host/hci_core.h | 3 +++ subsys/bluetooth/host/shell/bt.c | 2 +- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index b1b4482c5c1cd..1656f1f568447 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -1620,6 +1620,9 @@ struct bt_le_ext_adv_info { /** Currently selected Transmit Power (dBM). */ int8_t tx_power; + /** Advertising Set ID */ + uint8_t sid; + /** Current local advertising address used. */ const bt_addr_le_t *addr; diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 0f18149b134ef..e908e8ffa5dce 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1495,6 +1495,7 @@ int bt_le_ext_adv_get_info(const struct bt_le_ext_adv *adv, } info->id = adv->id; + info->sid = adv->sid; info->tx_power = adv->tx_power; info->addr = &adv->random_addr; @@ -1546,6 +1547,7 @@ int bt_le_ext_adv_create(const struct bt_le_adv_param *param, } adv->id = param->id; + adv->sid = param->sid; adv->cb = cb; err = le_ext_adv_param_set(adv, param, false); diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 5a193dfea6968..53a155adf123a 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -184,6 +184,9 @@ struct bt_le_ext_adv { /* TX Power in use by the controller */ int8_t tx_power; + + /* Advertising Set ID */ + uint8_t sid; #endif /* defined(CONFIG_BT_EXT_ADV) */ struct k_work_delayable lim_adv_timeout_work; diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index 18c6c70b1b605..a09afe4e3e5cb 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -2654,7 +2654,7 @@ static int cmd_adv_info(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "Advertiser[%d] %p", selected_adv, adv); - shell_print(sh, "Id: %d, TX power: %d dBm", info.id, info.tx_power); + shell_print(sh, "Id: %d, SID %u, TX power: %d dBm", info.id, info.sid, info.tx_power); shell_print(sh, "Adv state: %d", info.ext_adv_state); print_le_addr("Address", info.addr); From 5cd678a68ae89e594227ced307cadc5cea267069 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Aug 2025 17:06:01 +0200 Subject: [PATCH 0152/1076] doc: releases: Document new field sid in bt_le_ext_adv_info Add entry for the new field, `sid`, in the bt_le_ext_adv_info struct. Signed-off-by: Emil Gydesen --- doc/releases/release-notes-4.3.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/release-notes-4.3.rst b/doc/releases/release-notes-4.3.rst index a44210c132135..2589585f4ebf6 100644 --- a/doc/releases/release-notes-4.3.rst +++ b/doc/releases/release-notes-4.3.rst @@ -97,6 +97,7 @@ New APIs and options * :c:struct:`bt_iso_unicast_info` now contains a ``cig_id`` and a ``cis_id`` field * :c:struct:`bt_iso_broadcaster_info` now contains a ``big_handle`` and a ``bis_number`` field * :c:struct:`bt_iso_sync_receiver_info` now contains a ``big_handle`` and a ``bis_number`` field + * :c:struct:`bt_le_ext_adv_info` now contains an ``sid`` field with the Advertising Set ID. * Display From ef700ec525727cd2cc838b2877a82a2f093a8a9c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Aug 2025 17:09:01 +0200 Subject: [PATCH 0153/1076] Bluetooth: CAP: Remove sid from u->b handover params The SID is now gettable via bt_le_ext_adv_get_info. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/cap.h | 3 --- subsys/bluetooth/audio/cap_handover.c | 3 +-- subsys/bluetooth/audio/cap_internal.h | 2 -- tests/bsim/bluetooth/audio/src/cap_handover_central_test.c | 1 - 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/zephyr/bluetooth/audio/cap.h b/include/zephyr/bluetooth/audio/cap.h index 358167a30959a..9976cd1a31e7b 100644 --- a/include/zephyr/bluetooth/audio/cap.h +++ b/include/zephyr/bluetooth/audio/cap.h @@ -830,9 +830,6 @@ struct bt_cap_handover_unicast_to_broadcast_param { */ struct bt_le_ext_adv *ext_adv; - /** The SID of the advertising set. */ - uint8_t sid; - /** The periodic advertising interval configured for the advertising set. */ uint16_t pa_interval; diff --git a/subsys/bluetooth/audio/cap_handover.c b/subsys/bluetooth/audio/cap_handover.c index 61a395b61a6bb..8e985c83096bd 100644 --- a/subsys/bluetooth/audio/cap_handover.c +++ b/subsys/bluetooth/audio/cap_handover.c @@ -191,7 +191,7 @@ void bt_cap_handover_unicast_to_broadcast_reception_start(void) } member_param->addr = bt_addr_le_any; - member_param->adv_sid = proc_param->unicast_to_broadcast.sid; + member_param->adv_sid = adv_info.sid; member_param->pa_interval = proc_param->unicast_to_broadcast.pa_interval; member_param->broadcast_id = proc_param->unicast_to_broadcast.broadcast_id; bt_addr_le_copy(&member_param->addr, adv_info.addr); @@ -632,7 +632,6 @@ int bt_cap_handover_unicast_to_broadcast( proc_param->unicast_to_broadcast.unicast_group = param->unicast_group; proc_param->unicast_to_broadcast.ext_adv = param->ext_adv; proc_param->unicast_to_broadcast.type = param->type; - proc_param->unicast_to_broadcast.sid = param->sid; proc_param->unicast_to_broadcast.pa_interval = param->pa_interval; proc_param->unicast_to_broadcast.broadcast_id = param->broadcast_id; diff --git a/subsys/bluetooth/audio/cap_internal.h b/subsys/bluetooth/audio/cap_internal.h index 4ce4d34ff037c..19dbe3eab40f4 100644 --- a/subsys/bluetooth/audio/cap_internal.h +++ b/subsys/bluetooth/audio/cap_internal.h @@ -190,8 +190,6 @@ struct bt_cap_handover_proc_param { /* Set type */ enum bt_cap_set_type type; - /* The SID of the ext_adv */ - uint8_t sid; /* The PA interval of the ext_adv */ uint16_t pa_interval; /* The broadcast ID the broadcast source will use */ diff --git a/tests/bsim/bluetooth/audio/src/cap_handover_central_test.c b/tests/bsim/bluetooth/audio/src/cap_handover_central_test.c index e6c3236f43f6b..9c972b223cf8a 100644 --- a/tests/bsim/bluetooth/audio/src/cap_handover_central_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_handover_central_test.c @@ -659,7 +659,6 @@ static void handover_unicast_to_broadcast(struct bt_cap_unicast_group *unicast_g param.unicast_group = unicast_group; param.broadcast_create_param = &create_param; param.ext_adv = ext_adv; - param.sid = 0x00; param.pa_interval = BT_BAP_PA_INTERVAL_UNKNOWN; param.broadcast_id = 0x123456; From 56b0e3eb34812a11d15956337ca0faff595beabb Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 25 Aug 2025 17:13:30 +0200 Subject: [PATCH 0154/1076] Bluetooth: Host: Rearrange fields in bt_le_ext_adv Move the CONFIG_BT_EXT_ADV fields up and have the 2 8-bit values first, so they can be placed in the same word as the previous 2 when applicable. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/hci_core.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 53a155adf123a..315db2d388846 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -171,24 +171,25 @@ struct bt_le_ext_adv { /* Advertising handle */ uint8_t handle; - /* Current local Random Address */ - bt_addr_le_t random_addr; - - /* Current target address */ - bt_addr_le_t target_addr; - - ATOMIC_DEFINE(flags, BT_ADV_NUM_FLAGS); - #if defined(CONFIG_BT_EXT_ADV) - const struct bt_le_ext_adv_cb *cb; - /* TX Power in use by the controller */ int8_t tx_power; /* Advertising Set ID */ uint8_t sid; + + /* Callbacks for the advertising set */ + const struct bt_le_ext_adv_cb *cb; #endif /* defined(CONFIG_BT_EXT_ADV) */ + /* Current local Random Address */ + bt_addr_le_t random_addr; + + /* Current target address */ + bt_addr_le_t target_addr; + + ATOMIC_DEFINE(flags, BT_ADV_NUM_FLAGS); + struct k_work_delayable lim_adv_timeout_work; /** The options used to set the parameters for this advertising set From 808a87769c3d07c38d1a585826162b97963e7360 Mon Sep 17 00:00:00 2001 From: Khaoula Bidani Date: Mon, 25 Aug 2025 18:00:29 +0200 Subject: [PATCH 0155/1076] samples: boards: st: power_mgmt: fix compilation issue Fix compilation issue in test overlay nucleo_wba55cg.overlay Signed-off-by: Khaoula Bidani --- .../st/power_mgmt/wkup_pins/boards/nucleo_wba55cg.overlay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/st/power_mgmt/wkup_pins/boards/nucleo_wba55cg.overlay b/samples/boards/st/power_mgmt/wkup_pins/boards/nucleo_wba55cg.overlay index d4d0cca1806c8..66b94ab492161 100644 --- a/samples/boards/st/power_mgmt/wkup_pins/boards/nucleo_wba55cg.overlay +++ b/samples/boards/st/power_mgmt/wkup_pins/boards/nucleo_wba55cg.overlay @@ -6,7 +6,7 @@ / { aliases { - wkup-src = &button_0; + wkup-src = &user_button_1; }; }; From 647142fac32d61a5efc0ad4b03eb6cee09835804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 27 Aug 2025 00:05:43 +0200 Subject: [PATCH 0156/1076] doc: update putty.software hyperlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Main putty website's official URL is https://putty.website Signed-off-by: Benjamin Cabé --- boards/snps/em_starterkit/doc/index.rst | 2 +- boards/snps/emsdp/doc/index.rst | 2 +- boards/snps/hsdk/doc/index.rst | 2 +- boards/snps/hsdk4xd/doc/index.rst | 2 +- boards/snps/iotdk/doc/index.rst | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/snps/em_starterkit/doc/index.rst b/boards/snps/em_starterkit/doc/index.rst index cbb669a573636..372b61bc43827 100644 --- a/boards/snps/em_starterkit/doc/index.rst +++ b/boards/snps/em_starterkit/doc/index.rst @@ -310,6 +310,6 @@ References .. _Digilent Pmod Modules: http://store.digilentinc.com/pmod-modules -.. _Putty website: http://www.putty.org +.. _Putty website: https://www.putty.software .. _ARC EM Starter Kit User Guide: https://www.synopsys.com/dw/ipdir.php?ds=arc_em_starter_kit diff --git a/boards/snps/emsdp/doc/index.rst b/boards/snps/emsdp/doc/index.rst index d880a6ad6da70..f6123b90f6769 100644 --- a/boards/snps/emsdp/doc/index.rst +++ b/boards/snps/emsdp/doc/index.rst @@ -278,4 +278,4 @@ References http://store.digilentinc.com/pmod-modules .. _Putty website: - http://www.putty.org + https://www.putty.software diff --git a/boards/snps/hsdk/doc/index.rst b/boards/snps/hsdk/doc/index.rst index 9e5dee7556c60..c41bb517a87bc 100644 --- a/boards/snps/hsdk/doc/index.rst +++ b/boards/snps/hsdk/doc/index.rst @@ -521,4 +521,4 @@ References .. _Digilent Pmod Modules: http://store.digilentinc.com/pmod-modules -.. _Putty website: http://www.putty.org +.. _Putty website: https://www.putty.software diff --git a/boards/snps/hsdk4xd/doc/index.rst b/boards/snps/hsdk4xd/doc/index.rst index 52e88da142a41..2e45e3dff118a 100644 --- a/boards/snps/hsdk4xd/doc/index.rst +++ b/boards/snps/hsdk4xd/doc/index.rst @@ -550,4 +550,4 @@ References .. _Digilent Pmod Modules: http://store.digilentinc.com/pmod-modules -.. _Putty website: http://www.putty.org +.. _Putty website: https://www.putty.software diff --git a/boards/snps/iotdk/doc/index.rst b/boards/snps/iotdk/doc/index.rst index d038451dd05b0..8d23a3746c41b 100644 --- a/boards/snps/iotdk/doc/index.rst +++ b/boards/snps/iotdk/doc/index.rst @@ -192,4 +192,4 @@ References .. _Digilent Pmod Modules: http://store.digilentinc.com/pmod-modules -.. _Putty website: http://www.putty.org +.. _Putty website: https://www.putty.software From af4cbdcf318145ba19f9451f2e85c3c42257e5bb Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Fri, 22 Aug 2025 12:40:05 +0200 Subject: [PATCH 0157/1076] drivers: adc: gecko: Fix error return values Enable the adc_error_cases test on Series 2 devices and change the return values in the driver for unsupported configurations to what the test expects. Ensure that the resolution configuration in the test is valid such that the invalid buffer test correctly receives -ENOMEM. Signed-off-by: Aksel Skauge Mellbye --- drivers/adc/iadc_gecko.c | 6 +++--- .../adc_error_cases/boards/xg24_rb4187c.overlay | 17 +++++++++++++++++ .../adc_error_cases/boards/xg27_dk2602a.overlay | 17 +++++++++++++++++ .../adc_error_cases/boards/xg29_rb4412a.overlay | 17 +++++++++++++++++ .../adc/adc_error_cases/src/adc_error_cases.c | 8 +++++++- tests/drivers/adc/adc_error_cases/testcase.yaml | 3 +++ 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/drivers/adc/adc_error_cases/boards/xg24_rb4187c.overlay create mode 100644 tests/drivers/adc/adc_error_cases/boards/xg27_dk2602a.overlay create mode 100644 tests/drivers/adc/adc_error_cases/boards/xg29_rb4412a.overlay diff --git a/drivers/adc/iadc_gecko.c b/drivers/adc/iadc_gecko.c index 876da1d7c735f..818183c328dd6 100644 --- a/drivers/adc/iadc_gecko.c +++ b/drivers/adc/iadc_gecko.c @@ -127,7 +127,7 @@ static int start_read(const struct device *dev, const struct adc_sequence *seque if (sequence->oversampling) { LOG_ERR("Oversampling is not supported"); - return -ENOTSUP; + return -EINVAL; } /* Check resolution setting */ @@ -331,7 +331,7 @@ static int adc_gecko_channel_setup(const struct device *dev, break; default: LOG_ERR("unsupported channel gain '%d'", channel_cfg->gain); - return -ENOTSUP; + return -EINVAL; } /* Setup reference */ @@ -353,7 +353,7 @@ static int adc_gecko_channel_setup(const struct device *dev, default: LOG_ERR("unsupported channel reference type '%d'", channel_cfg->reference); - return -ENOTSUP; + return -EINVAL; } channel_config->initialized = true; diff --git a/tests/drivers/adc/adc_error_cases/boards/xg24_rb4187c.overlay b/tests/drivers/adc/adc_error_cases/boards/xg24_rb4187c.overlay new file mode 100644 index 0000000000000..707d618084d3d --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/boards/xg24_rb4187c.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc = &adc0; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; diff --git a/tests/drivers/adc/adc_error_cases/boards/xg27_dk2602a.overlay b/tests/drivers/adc/adc_error_cases/boards/xg27_dk2602a.overlay new file mode 100644 index 0000000000000..707d618084d3d --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/boards/xg27_dk2602a.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc = &adc0; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; diff --git a/tests/drivers/adc/adc_error_cases/boards/xg29_rb4412a.overlay b/tests/drivers/adc/adc_error_cases/boards/xg29_rb4412a.overlay new file mode 100644 index 0000000000000..707d618084d3d --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/boards/xg29_rb4412a.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc = &adc0; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; diff --git a/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c b/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c index 0cfdf890d7b74..754d2ad98d7bf 100644 --- a/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c +++ b/tests/drivers/adc/adc_error_cases/src/adc_error_cases.c @@ -24,11 +24,17 @@ static const struct adc_channel_cfg valid_channel_cfg = { #endif }; +#if defined(CONFIG_SOC_FAMILY_SILABS_S2) +#define VALID_RESOLUTION 12 +#else +#define VALID_RESOLUTION 10 +#endif + static const struct adc_sequence valid_seq = { .buffer = m_sample_buffer, .buffer_size = BUFFER_LEN * sizeof(m_sample_buffer), .options = NULL, - .resolution = 10, + .resolution = VALID_RESOLUTION, .oversampling = 0, .channels = 1, }; diff --git a/tests/drivers/adc/adc_error_cases/testcase.yaml b/tests/drivers/adc/adc_error_cases/testcase.yaml index d9d389ab78adb..4b12c904460a2 100644 --- a/tests/drivers/adc/adc_error_cases/testcase.yaml +++ b/tests/drivers/adc/adc_error_cases/testcase.yaml @@ -12,3 +12,6 @@ tests: - nrf54lm20dk/nrf54lm20a/cpuapp - nrf54h20dk/nrf54h20/cpuapp - ophelia4ev/nrf54l15/cpuapp + - xg24_rb4187c + - xg27_dk2602a + - xg29_rb4412a From bbd44612659becc0d3e9e11419df3f3b30710ef8 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:12:13 +0200 Subject: [PATCH 0158/1076] tests: drivers: watchdog: Support window.min Add test flag to support running error case test on devices with support for window.min Signed-off-by: Aksel Skauge Mellbye --- tests/drivers/watchdog/wdt_error_cases/src/main.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index 935d8dd95a0fb..15666d1a77f74 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -36,6 +36,7 @@ #define WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED BIT(5) #define WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED BIT(6) #define WDT_FEED_CAN_STALL BIT(7) +#define WDT_WINDOW_MIN_SUPPORTED BIT(8) /* Common for all targets: */ #define DEFAULT_WINDOW_MAX (500U) @@ -276,12 +277,14 @@ ZTEST(wdt_coverage, test_04w_wdt_install_timeout_with_invalid_window) /* ----------------- window.min * Check that window.min can't be different than 0 */ - m_cfg_wdt0.window.min = 1U; - ret = wdt_install_timeout(wdt, &m_cfg_wdt0); - zassert_true(ret == -EINVAL, - "Calling wdt_install_timeout with window.min = 1 should return -EINVAL (-22), " - "got unexpected value of %d", - ret); + if (!(WDT_TEST_FLAGS & WDT_WINDOW_MIN_SUPPORTED)) { + m_cfg_wdt0.window.min = 1U; + ret = wdt_install_timeout(wdt, &m_cfg_wdt0); + zassert_true(ret == -EINVAL, + "Calling wdt_install_timeout with window.min = 1 should return -EINVAL (-22), " + "got unexpected value of %d", + ret); + } /* Set default window.min */ m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN; From b2e21d57d0ae0ad465ed8e6c1e61fcc803adfcdb Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:14:45 +0200 Subject: [PATCH 0159/1076] tests: drivers: watchdog: Support devices with limited timeouts Support running the error case test on devices with a limited number of timeouts. Signed-off-by: Aksel Skauge Mellbye --- tests/drivers/watchdog/wdt_error_cases/src/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index 15666d1a77f74..bd20501063e8a 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -326,6 +326,11 @@ ZTEST(wdt_coverage, test_04wm_wdt_install_timeout_with_multiple_timeout_values) ztest_test_skip(); } + if (MAX_INSTALLABLE_TIMEOUTS < 2) { + /* Skip this test because two timeouts aren't supported */ + ztest_test_skip(); + } + m_cfg_wdt0.callback = NULL; m_cfg_wdt0.flags = DEFAULT_FLAGS; m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX; From 9a9bc105564e71262f7bd4dd26ecdb18576fadd8 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:15:54 +0200 Subject: [PATCH 0160/1076] tests: drivers: watchdog: Support requiring PM for pause test Some devices require PM to go to sufficiently deep sleep modes for the watchdog to get paused using WDT_OPT_PAUSE_IN_SLEEP. Signed-off-by: Aksel Skauge Mellbye --- tests/drivers/watchdog/wdt_error_cases/src/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index bd20501063e8a..5cba4c9bc913a 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -37,6 +37,7 @@ #define WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED BIT(6) #define WDT_FEED_CAN_STALL BIT(7) #define WDT_WINDOW_MIN_SUPPORTED BIT(8) +#define WDT_OPT_PAUSE_IN_SLEEP_REQUIRES_PM BIT(9) /* Common for all targets: */ #define DEFAULT_WINDOW_MAX (500U) @@ -436,6 +437,11 @@ ZTEST(wdt_coverage, test_06b_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_functional) ztest_test_skip(); } + if ((WDT_TEST_FLAGS & WDT_OPT_PAUSE_IN_SLEEP_REQUIRES_PM) && !IS_ENABLED(CONFIG_PM)) { + /* Skip this test because WDT_OPT_PAUSE_IN_SLEEP can't be tested without PM. */ + ztest_test_skip(); + } + /* When test fails, watchdog sets m_test_06b_value to TEST_06B_TAG in WDT callback * wdt_test_06b_cb. Then, target is reset. Check value of m_test_06b_value to prevent reset * loop on this test. From 39e468b0f6a7cb1ca10e6e5bc6d186ecabe3c203 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:18:52 +0200 Subject: [PATCH 0161/1076] dts: arm: silabs: xg27: Fix wdog0 unit address The wdog0 unit address and reg entry pointed to the secure alias, while the SMU was configured to expect the non-secure alias. Signed-off-by: Aksel Skauge Mellbye --- dts/arm/silabs/xg27/xg27.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/silabs/xg27/xg27.dtsi b/dts/arm/silabs/xg27/xg27.dtsi index 023551e2db70d..c408f97c2ab88 100644 --- a/dts/arm/silabs/xg27/xg27.dtsi +++ b/dts/arm/silabs/xg27/xg27.dtsi @@ -462,9 +462,9 @@ status = "disabled"; }; - wdog0: wdog@4a018000 { + wdog0: wdog@5a018000 { compatible = "silabs,gecko-wdog"; - reg = <0x4A018000 0x3028>; + reg = <0x5A018000 0x3028>; interrupts = <49 2>; clocks = <&cmu CLOCK_WDOG0 CLOCK_BRANCH_WDOG0CLK>; peripheral-id = <0>; From de1ef0a56c3693f5201ea481bdd3fb01e31b5672 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:23:38 +0200 Subject: [PATCH 0162/1076] tests: drivers: watchdog: Enable tests for xg24 and xg27 Enable watchdog tests for representative xg24 and xg27 boards. Signed-off-by: Aksel Skauge Mellbye --- .../dev_kits/xg27_dk2602a/xg27_dk2602a.yaml | 1 + .../watchdog/wdt_basic_reset_none/testcase.yaml | 5 ++++- tests/drivers/watchdog/wdt_error_cases/src/main.c | 15 +++++++++++++++ .../watchdog/wdt_error_cases/testcase.yaml | 8 ++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml index 8f8bfd19fb278..73d0ba0dc8d69 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml @@ -16,4 +16,5 @@ supported: - clock_control - comparator - adc + - watchdog vendor: silabs diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml index cbe43b7ad893c..1e6ae08b31a18 100644 --- a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml @@ -3,7 +3,10 @@ tests: drivers.watchdog.reset_none: - filter: dt_compat_enabled("nxp,s32-swt") or dt_compat_enabled("renesas,ra-wdt") + filter: | + dt_compat_enabled("nxp,s32-swt") + or dt_compat_enabled("renesas,ra-wdt") + or dt_compat_enabled("silabs,gecko-wdog") integration_platforms: - s32z2xxdc2/s32z270/rtu0 tags: diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index 5cba4c9bc913a..c1c62f7d41cf2 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -54,6 +54,21 @@ #define MAX_INSTALLABLE_TIMEOUTS (8) #define WDT_WINDOW_MAX_ALLOWED (0x07CFFFFFU) #define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG) +#elif defined(CONFIG_SOC_FAMILY_SILABS_S2) +#if defined(WDOG_CFG_EM1RUN) +#define WDT_TEST_FLAG_SLEEP_REQUIRES_PM 0 +#else +#define WDT_TEST_FLAG_SLEEP_REQUIRES_PM WDT_OPT_PAUSE_IN_SLEEP_REQUIRES_PM +#endif +#define WDT_TEST_FLAGS \ + (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_NONE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \ + WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED | \ + WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED | WDT_WINDOW_MIN_SUPPORTED | \ + WDT_TEST_FLAG_SLEEP_REQUIRES_PM) +#define DEFAULT_FLAGS (WDT_FLAG_RESET_NONE) +#define MAX_INSTALLABLE_TIMEOUTS (1) +#define WDT_WINDOW_MAX_ALLOWED (0x40001U) +#define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG) #else /* By default run most of the error checks. * See Readme.txt on how to align test scope for the specific target. diff --git a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml index 438b59e927171..5325d73a88ce6 100644 --- a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml +++ b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml @@ -17,7 +17,15 @@ tests: - nrf9280pdk/nrf9280/cpurad - ophelia4ev/nrf54l15/cpuapp - raytac_an54l15q_db/nrf54l15/cpuapp + - xg24_rb4187c + - xg27_dk2602a integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp - raytac_an54l15q_db/nrf54l15/cpuapp + drivers.watchdog.wdt_error_cases_pm: + platform_allow: + - xg24_rb4187c + - xg27_dk2602a + extra_configs: + - CONFIG_PM=y From 3f7e614da6af589bcc3348c3a45154d58feea007 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 00:27:23 +0200 Subject: [PATCH 0163/1076] drivers: watchdog: gecko: Fix API corner cases Properly return the correct error codes when the watchdog API is misused. Fail timeout install if WDT_FLAG_RESET_CPU_CORE is set, a watchdog reset will at a minimum cause a soft reset of the entire SoC. Signed-off-by: Aksel Skauge Mellbye --- drivers/watchdog/wdt_gecko.c | 40 ++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/wdt_gecko.c b/drivers/watchdog/wdt_gecko.c index 7ec18a9a5747e..f9f8f857f063d 100644 --- a/drivers/watchdog/wdt_gecko.c +++ b/drivers/watchdog/wdt_gecko.c @@ -87,12 +87,25 @@ static int wdt_gecko_convert_window(uint32_t window, uint32_t period) return idx; } +static bool wdt_gecko_is_enabled(WDOG_TypeDef *wdog) +{ +#if defined(CONFIG_SOC_FAMILY_SILABS_S2) + return FIELD_GET(WDOG_EN_EN, wdog->EN); +#else + return FIELD_GET(WDOG_CTRL_EN, wdog->CTRL); +#endif +} + static int wdt_gecko_setup(const struct device *dev, uint8_t options) { const struct wdt_gecko_cfg *config = dev->config; struct wdt_gecko_data *data = dev->data; WDOG_TypeDef *wdog = config->base; + if (wdt_gecko_is_enabled(wdog)) { + return -EBUSY; + } + if (!data->timeout_installed) { LOG_ERR("No valid timeouts installed"); return -EINVAL; @@ -134,8 +147,14 @@ static int wdt_gecko_disable(const struct device *dev) struct wdt_gecko_data *data = dev->data; WDOG_TypeDef *wdog = config->base; - WDOGn_Enable(wdog, false); + /* Always uninstall timeouts, independent of watchdog enable state */ data->timeout_installed = false; + + if (!wdt_gecko_is_enabled(wdog)) { + return -EFAULT; + } + + WDOGn_Enable(wdog, false); LOG_DBG("Disabled the watchdog"); return 0; @@ -144,10 +163,16 @@ static int wdt_gecko_disable(const struct device *dev) static int wdt_gecko_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) { + const struct wdt_gecko_cfg *config = dev->config; struct wdt_gecko_data *data = dev->data; - data->wdog_config = (WDOG_Init_TypeDef)WDOG_INIT_DEFAULT; uint32_t installed_timeout; + data->wdog_config = (WDOG_Init_TypeDef)WDOG_INIT_DEFAULT; + + if (wdt_gecko_is_enabled(config->base)) { + return -EBUSY; + } + if (data->timeout_installed) { LOG_ERR("No more timeouts can be installed"); return -ENOMEM; @@ -189,13 +214,12 @@ static int wdt_gecko_install_timeout(const struct device *dev, /* Set mode of watchdog and callback */ switch (cfg->flags) { case WDT_FLAG_RESET_SOC: - case WDT_FLAG_RESET_CPU_CORE: if (cfg->callback != NULL) { LOG_ERR("Reset mode with callback not supported\n"); return -ENOTSUP; } data->wdog_config.resetDisable = false; - LOG_DBG("Configuring reset CPU/SoC mode\n"); + LOG_DBG("Configuring reset SoC mode\n"); break; case WDT_FLAG_RESET_NONE: @@ -204,6 +228,10 @@ static int wdt_gecko_install_timeout(const struct device *dev, LOG_DBG("Configuring non-reset mode\n"); break; + case WDT_FLAG_RESET_CPU_CORE: + LOG_ERR("CPU core only reset not supported"); + return -ENOTSUP; + default: LOG_ERR("Unsupported watchdog config flag"); return -EINVAL; @@ -224,6 +252,10 @@ static int wdt_gecko_feed(const struct device *dev, int channel_id) return -EINVAL; } + if (!wdt_gecko_is_enabled(wdog)) { + return -EINVAL; + } + WDOGn_Feed(wdog); LOG_DBG("Fed the watchdog"); From b83267dba0be01bf90ec818a1329addaefade0d4 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 25 Aug 2025 23:48:25 +0200 Subject: [PATCH 0164/1076] drivers: serial: silabs_usart: Fix configure error cases Enable uart_elementary test and fix edge cases where the configure function did not return the appropriate error code when given invalid parity or flow control parameters. Signed-off-by: Aksel Skauge Mellbye --- drivers/serial/uart_silabs_usart.c | 8 +++ .../boards/xg24_rb4187c.overlay | 60 +++++++++++++++++++ .../uart/uart_elementary/testcase.yaml | 1 + 3 files changed, 69 insertions(+) create mode 100644 tests/drivers/uart/uart_elementary/boards/xg24_rb4187c.overlay diff --git a/drivers/serial/uart_silabs_usart.c b/drivers/serial/uart_silabs_usart.c index 739628cf78837..1ae9caa48ba08 100644 --- a/drivers/serial/uart_silabs_usart.c +++ b/drivers/serial/uart_silabs_usart.c @@ -982,11 +982,19 @@ static int uart_silabs_configure(const struct device *dev, return -ENOSYS; } + if (cfg->parity > UART_CFG_PARITY_SPACE) { + return -EINVAL; + } + if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR || cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485) { return -ENOSYS; } + if (cfg->flow_ctrl > UART_CFG_FLOW_CTRL_RS485) { + return -EINVAL; + } + *data->uart_cfg = *cfg; USART_Enable(base, usartDisable); diff --git a/tests/drivers/uart/uart_elementary/boards/xg24_rb4187c.overlay b/tests/drivers/uart/uart_elementary/boards/xg24_rb4187c.overlay new file mode 100644 index 0000000000000..af0bf4be88ad4 --- /dev/null +++ b/tests/drivers/uart/uart_elementary/boards/xg24_rb4187c.overlay @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025, Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &eusart0; + zephyr,shell-uart = &eusart0; + zephyr,uart-pipe = &eusart0; + }; +}; + +/* + * Connect EXP4 (PC1) and EXP6 (PC2) of the Expansion Pin header + */ + +&pinctrl { + eusart0_default: eusart0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + usart0_default: usart0_default { + group0 { + pins = ; /* WPK EXP4 (PC1) */ + drive-push-pull; + output-high; + }; + group1 { + pins = ; /* WPK EXP6 (PC2) */ + input-enable; + silabs,input-filter; + }; + }; +}; + +dut: &usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&eusart0 { + compatible = "silabs,eusart-uart"; + current-speed = <115200>; + pinctrl-0 = <&eusart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index d1da7ca19489a..d779a45355882 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -25,6 +25,7 @@ tests: - esp32h2_devkitm - esp32s2_saola - esp32s3_devkitm/esp32s3/procpu + - xg24_rb4187c integration_platforms: - nrf54h20dk/nrf54h20/cpuapp drivers.uart.uart_elementary_dual_nrf54h: From 2768acb8567d909aebea9ef6d0cd4d4c7b8cc5e1 Mon Sep 17 00:00:00 2001 From: Cheng Chang Date: Fri, 22 Aug 2025 15:24:38 +0800 Subject: [PATCH 0165/1076] bluetooth: host: avdtp: Fix command and response format error There are three aspects of changes involved: 1. The format of Service Category should be checked in set configuration cmd and error code and Service Category should be detailed in response. 2. There is no INT Stream Endpoint ID in re_config cmd,. 3. Fail ACP SEID should be added to start and suspend rej rsp. Signed-off-by: Cheng Chang --- include/zephyr/bluetooth/classic/avdtp.h | 8 + subsys/bluetooth/host/classic/a2dp.c | 4 +- subsys/bluetooth/host/classic/avdtp.c | 144 ++++++++++++++++-- .../bluetooth/host/classic/avdtp_internal.h | 50 +++++- 4 files changed, 188 insertions(+), 18 deletions(-) diff --git a/include/zephyr/bluetooth/classic/avdtp.h b/include/zephyr/bluetooth/classic/avdtp.h index b68f19c16a638..8756516d0bd0d 100644 --- a/include/zephyr/bluetooth/classic/avdtp.h +++ b/include/zephyr/bluetooth/classic/avdtp.h @@ -124,6 +124,14 @@ enum bt_avdtp_service_category { BT_AVDTP_SERVICE_DELAY_REPORTING = 0x08, }; +/** @brief service category Recovery Capabilities type*/ +enum bt_avdtp_recovery_type { + /** Forbidden */ + BT_AVDTP_RECOVERY_TYPE_FORBIDDEN = 0x00, + /** RFC2733 */ + BT_ADVTP_RECOVERY_TYPE_RFC2733 = 0x01, +}; + /** @brief AVDTP Stream End Point */ struct bt_avdtp_sep { /** Stream End Point information */ diff --git a/subsys/bluetooth/host/classic/a2dp.c b/subsys/bluetooth/host/classic/a2dp.c index 338e5fd36447a..ba66eda50c6f5 100644 --- a/subsys/bluetooth/host/classic/a2dp.c +++ b/subsys/bluetooth/host/classic/a2dp.c @@ -368,11 +368,11 @@ static int a2dp_set_config_ind(struct bt_avdtp *session, struct bt_avdtp_sep *se return a2dp_process_config_ind(session, sep, int_seid, buf, errcode, false); } -static int a2dp_re_config_ind(struct bt_avdtp *session, struct bt_avdtp_sep *sep, uint8_t int_seid, +static int a2dp_re_config_ind(struct bt_avdtp *session, struct bt_avdtp_sep *sep, struct net_buf *buf, uint8_t *errcode) { __ASSERT(sep, "Invalid sep"); - return a2dp_process_config_ind(session, sep, int_seid, buf, errcode, true); + return a2dp_process_config_ind(session, sep, 0, buf, errcode, true); } #if defined(CONFIG_BT_A2DP_SINK) diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index 67f39c133e527..e217570bfa2f6 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -436,6 +436,99 @@ static void avdtp_get_capabilities_rsp(struct bt_avdtp *session, struct net_buf } } +struct bt_avdtp_service_category_handler { + uint8_t min_len; + uint8_t max_len; + bool reconfig_support; + uint8_t err_code; + uint8_t (*handler)(struct net_buf *buf); +}; + +uint8_t bt_avdtp_check_media_recovery_type(struct net_buf *buf) +{ + struct bt_avdtp_recovery_capabilities *cap + = (struct bt_avdtp_recovery_capabilities *)buf->data; + + if (cap->recovery_type != BT_AVDTP_RECOVERY_TYPE_FORBIDDEN && + cap->recovery_type != BT_ADVTP_RECOVERY_TYPE_RFC2733) { + return BT_AVDTP_BAD_RECOVERY_TYPE; + } + return BT_AVDTP_SUCCESS; +} + +static struct bt_avdtp_service_category_handler category_handler[] = { + {0, 0, false, 0, NULL}, /*None*/ + {0, 0, false, BT_AVDTP_BAD_MEDIA_TRANSPORT_FORMAT, + NULL}, /*BT_AVDTP_SERVICE_MEDIA_TRANSPORT*/ + {0, 0, false, BT_AVDTP_BAD_LENGTH, NULL}, /*BT_AVDTP_SERVICE_REPORTING*/ + {sizeof(struct bt_avdtp_recovery_capabilities), + sizeof(struct bt_avdtp_recovery_capabilities), false, BT_AVDTP_BAD_RECOVERY_FORMAT, + bt_avdtp_check_media_recovery_type}, /*BT_AVDTP_SERVICE_MEDIA_RECOVERY*/ + {sizeof(struct bt_avdtp_content_protection_capabilities), UINT8_MAX, + true, BT_AVDTP_BAD_CP_FORMAT, NULL}, /*BT_AVDTP_SERVICE_CONTENT_PROTECTION*/ + {sizeof(struct bt_avdtp_header_compression_capabilities), + sizeof(struct bt_avdtp_header_compression_capabilities), + false, BT_AVDTP_BAD_LENGTH, NULL}, /*BT_AVDTP_SERVICE_HEADER_COMPRESSION*/ + {sizeof(struct bt_avdtp_multiplexing_capabilities), + sizeof(struct bt_avdtp_multiplexing_capabilities), + false, BT_AVDTP_BAD_MULTIPLEXING_FORMAT, NULL}, /*BT_AVDTP_SERVICE_MULTIPLEXING*/ + {sizeof(struct bt_avdtp_media_codec_capabilities), UINT8_MAX, + true, BT_AVDTP_BAD_LENGTH, NULL}, /*BT_AVDTP_SERVICE_MEDIA_CODEC*/ + {0, 0, 0, BT_AVDTP_BAD_LENGTH, NULL}, /*BT_AVDTP_SERVICE_DELAY_REPORTING*/ +}; + +uint8_t bt_avdtp_check_service_category(struct net_buf *buf, uint8_t *service_category, + bool reconfig) +{ + struct bt_avdtp_generic_service_cap *hdr; + uint8_t err; + struct bt_avdtp_service_category_handler *handler; + struct net_buf_simple_state state; + + if (buf->len == 0U) { + LOG_DBG("Error: buf not valid"); + return BT_AVDTP_BAD_LENGTH; + } + + while (buf->len > 0U) { + if (buf->len < sizeof(*hdr)) { + LOG_DBG("Error: buf not valid"); + return BT_AVDTP_BAD_LENGTH; + } + + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + *service_category = hdr->service_category; + + if (hdr->service_category != 0 && + hdr->service_category < ARRAY_SIZE(category_handler)) { + handler = &category_handler[hdr->service_category]; + + if (hdr->losc > buf->len || hdr->losc > handler->max_len || + hdr->losc < handler->min_len) { + return handler->err_code; + } + + if (!handler->reconfig_support && reconfig) { + return BT_AVDTP_INVALID_CAPABILITIES; + } + + if (handler->handler != NULL) { + net_buf_simple_save(&buf->b, &state); + err = handler->handler(buf); + net_buf_simple_restore(&buf->b, &state); + if (err != BT_AVDTP_SUCCESS) { + return err; + } + } + net_buf_pull_mem(buf, hdr->losc); + } else { + return BT_AVDTP_BAD_SERV_CATEGORY; + } + } + + return BT_AVDTP_SUCCESS; +} + static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid, bool reconfig) { @@ -443,6 +536,8 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net struct bt_avdtp_sep *sep; struct net_buf *rsp_buf; uint8_t avdtp_err_code = 0; + struct net_buf_simple_state state; + uint8_t service_category = 0; sep = avdtp_get_cmd_sep(buf, &avdtp_err_code); avdtp_sep_lock(sep); @@ -453,6 +548,9 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net err = -ENOTSUP; } else if (reconfig && session->ops->re_configuration_ind == NULL) { err = -ENOTSUP; + } else if (!reconfig && sep->sep_info.inuse == 1) { + avdtp_err_code = BT_AVDTP_SEP_IN_USE; + err = -EBUSY; } else { uint8_t expected_state; @@ -466,17 +564,29 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net err = -ENOTSUP; avdtp_err_code = BT_AVDTP_BAD_STATE; } else if (buf->len >= 1U) { - uint8_t int_seid; + uint8_t int_seid = 0; + uint8_t err_code = 0; /* INT Stream Endpoint ID */ - int_seid = net_buf_pull_u8(buf) >> 2; - if (!reconfig) { - err = session->ops->set_configuration_ind(session, sep, int_seid, - buf, &avdtp_err_code); + /* int seid not in reconfig cmd*/ + int_seid = net_buf_pull_u8(buf) >> 2; + } + net_buf_simple_save(&buf->b, &state); + err_code = bt_avdtp_check_service_category(buf, &service_category, + reconfig); + net_buf_simple_restore(&buf->b, &state); + if (err_code) { + avdtp_err_code = err_code; + err = -ENOTSUP; } else { - err = session->ops->re_configuration_ind(session, sep, int_seid, - buf, &avdtp_err_code); + if (!reconfig) { + err = session->ops->set_configuration_ind( + session, sep, int_seid, buf, &avdtp_err_code); + } else { + err = session->ops->re_configuration_ind(session, sep, buf, + &avdtp_err_code); + } } } else { LOG_WRN("Invalid INT SEID"); @@ -499,8 +609,8 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net } LOG_DBG("set configuration err code:%d", avdtp_err_code); - /* Service Category: Media Codec */ - net_buf_add_u8(rsp_buf, BT_AVDTP_SERVICE_MEDIA_CODEC); + /* error Service Category*/ + net_buf_add_u8(rsp_buf, service_category); /* ERROR CODE */ net_buf_add_u8(rsp_buf, avdtp_err_code); } @@ -705,6 +815,7 @@ static void avdtp_start_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8 } LOG_DBG("start err code:%d", avdtp_err_code); + net_buf_add_u8(rsp_buf, sep->sep_info.id << 2); net_buf_add_u8(rsp_buf, avdtp_err_code); } @@ -860,6 +971,7 @@ static void avdtp_suspend_cmd(struct bt_avdtp *session, struct net_buf *buf, uin } LOG_DBG("suspend err code:%d", avdtp_err_code); + net_buf_add_u8(rsp_buf, sep->sep_info.id << 2); net_buf_add_u8(rsp_buf, avdtp_err_code); } @@ -1555,12 +1667,14 @@ static int avdtp_process_configure_command(struct bt_avdtp *session, uint8_t cmd /* Body of the message */ /* ACP Stream Endpoint ID */ net_buf_add_u8(buf, (param->acp_stream_ep_id << 2U)); - /* INT Stream Endpoint ID */ - net_buf_add_u8(buf, (param->int_stream_endpoint_id << 2U)); - /* Service Category: Media Transport */ - net_buf_add_u8(buf, BT_AVDTP_SERVICE_MEDIA_TRANSPORT); - /* LOSC */ - net_buf_add_u8(buf, 0); + if (cmd == BT_AVDTP_SET_CONFIGURATION) { + /* INT Stream Endpoint ID */ + net_buf_add_u8(buf, (param->int_stream_endpoint_id << 2U)); + /* Service Category: Media Transport */ + net_buf_add_u8(buf, BT_AVDTP_SERVICE_MEDIA_TRANSPORT); + /* LOSC */ + net_buf_add_u8(buf, 0); + } /* Service Category: Media Codec */ net_buf_add_u8(buf, BT_AVDTP_SERVICE_MEDIA_CODEC); /* LOSC */ diff --git a/subsys/bluetooth/host/classic/avdtp_internal.h b/subsys/bluetooth/host/classic/avdtp_internal.h index 10723b9cb8601..951e1a11d9cfc 100644 --- a/subsys/bluetooth/host/classic/avdtp_internal.h +++ b/subsys/bluetooth/host/classic/avdtp_internal.h @@ -174,6 +174,54 @@ struct bt_avdtp_ctrl_params { uint8_t acp_stream_ep_id; }; +struct bt_avdtp_generic_service_cap { + uint8_t service_category; + uint8_t losc; +} __packed; + +/* avdtp service capabilities*/ +struct bt_avdtp_recovery_capabilities { + uint8_t recovery_type; + uint8_t MRWS; + uint8_t MNMP; +} __packed; + +struct bt_avdtp_media_codec_capabilities { + uint8_t media_type; + uint8_t media_code_type; + uint8_t media_codec_spec_info[0]; +} __packed; + +struct bt_avdtp_content_protection_capabilities { + uint8_t cp_type_lsb; + uint8_t cp_type_msb; + uint8_t cp_type_spec_value[0]; +} __packed; + +struct bt_avdtp_header_compression_capabilities { +#ifdef CONFIG_LITTLE_ENDIAN + uint8_t reserved : 5; + uint8_t recovery : 1; + uint8_t media : 1; + uint8_t backch : 1; +#else + uint8_t backch : 1; + uint8_t media : 1; + uint8_t recovery : 1; + uint8_t reserved : 5; +#endif /* CONFIG_LITTLE_ENDIAN */ +} __packed; + +struct bt_avdtp_multiplexing_capabilities { + uint8_t frag; + uint8_t tsid_media; + uint8_t tcid_media; + uint8_t tsid_reporting; + uint8_t tcid_reporting; + uint8_t tsid_recovery; + uint8_t tcid_recovery; +} __packed; + struct bt_avdtp_ops_cb { void (*connected)(struct bt_avdtp *session); @@ -190,7 +238,7 @@ struct bt_avdtp_ops_cb { uint8_t int_seid, struct net_buf *buf, uint8_t *errcode); int (*re_configuration_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep, - uint8_t int_seid, struct net_buf *buf, uint8_t *errcode); + struct net_buf *buf, uint8_t *errcode); int (*open_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep, uint8_t *errcode); From 8bbc05df71c4f776446dc65028e63c8d95254196 Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Tue, 26 Aug 2025 10:12:26 +0800 Subject: [PATCH 0166/1076] Bluetooth: Host: direction: correct the cte_req_enable opcode The opcode of hci_df_set_conn_cte_req_enable command should be BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE (0x2056). Signed-off-by: Aaron Ye --- subsys/bluetooth/host/direction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/direction.c b/subsys/bluetooth/host/direction.c index 73a196a8e20b4..b17f7fa08ab66 100644 --- a/subsys/bluetooth/host/direction.c +++ b/subsys/bluetooth/host/direction.c @@ -822,7 +822,7 @@ static int hci_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable, bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_REQ_ENABLED, enable); - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS, buf, &rsp); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE, buf, &rsp); if (err) { return err; } From 2c63115f515c5c3f244d08de8eb7d991a98fa46c Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Tue, 26 Aug 2025 12:03:10 +0800 Subject: [PATCH 0167/1076] drivers: bluetooth: hci: add close function for Ambiq Apollo4 series This commit adds close function support for Ambiq Apollo4 series SoC so the bt_disable() API can be used. Signed-off-by: Aaron Ye --- drivers/bluetooth/hci/apollox_blue.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci/apollox_blue.c b/drivers/bluetooth/hci/apollox_blue.c index 9a4bf5440d87d..40283894f8032 100644 --- a/drivers/bluetooth/hci/apollox_blue.c +++ b/drivers/bluetooth/hci/apollox_blue.c @@ -343,9 +343,23 @@ int bt_apollo_controller_init(spi_transmit_fun transmit) int bt_apollo_controller_deinit(void) { - int ret = -ENOTSUP; + int ret = 0; -#if (CONFIG_SOC_SERIES_APOLLO3X) +#if (CONFIG_SOC_SERIES_APOLLO4X) + /* Keep the Controller in resetting state */ + gpio_pin_set_dt(&rst_gpio, 1); + + /* Disable XO32MHz */ + clock_control_off(clk32m_dev, (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE); + /* Disable XO32kHz */ + clock_control_off(clk32k_dev, (clock_control_subsys_t)CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL); + + /* Disable GPIOs */ + gpio_pin_configure_dt(&irq_gpio, GPIO_DISCONNECTED); + gpio_pin_configure_dt(&clkreq_gpio, GPIO_DISCONNECTED); + gpio_remove_callback(clkreq_gpio.port, &clkreq_gpio_cb); + gpio_remove_callback(irq_gpio.port, &irq_gpio_cb); +#elif (CONFIG_SOC_SERIES_APOLLO3X) irq_disable(DT_IRQN(SPI_DEV_NODE)); ret = am_apollo3_bt_controller_deinit(); @@ -355,7 +369,9 @@ int bt_apollo_controller_deinit(void) ret = -EPERM; LOG_ERR("BT controller deinitialization fails"); } -#endif /* CONFIG_SOC_SERIES_APOLLO3X */ +#else + ret = -ENOTSUP; +#endif /* CONFIG_SOC_SERIES_APOLLO4X */ return ret; } From 0d46a934171a11d0fe08ea2a615f79a92ac0ab9b Mon Sep 17 00:00:00 2001 From: Aaron Ye Date: Tue, 26 Aug 2025 11:07:40 +0800 Subject: [PATCH 0168/1076] drivers: bluetooth: hci: stop rx thread when closes the HCI Stops the RX thread when closes the HCI for Ambiq HCI driver Signed-off-by: Aaron Ye --- drivers/bluetooth/hci/hci_ambiq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/hci/hci_ambiq.c b/drivers/bluetooth/hci/hci_ambiq.c index 3757806b1e53b..b870a50da21ce 100644 --- a/drivers/bluetooth/hci/hci_ambiq.c +++ b/drivers/bluetooth/hci/hci_ambiq.c @@ -395,6 +395,9 @@ static int bt_apollo_close(const struct device *dev) return ret; } + /* Stop RX thread */ + k_thread_abort(&spi_rx_thread_data); + hci->recv = NULL; return ret; From d4db7f62ec9d9bf2fc4bd7a18495cb9a99061da6 Mon Sep 17 00:00:00 2001 From: Bastien Beauchamp Date: Tue, 19 Aug 2025 11:20:48 -0400 Subject: [PATCH 0169/1076] soc: silabs: add a config for low latency interrupt on Sliabs S2 devices The high frequency clock was always restored before handling the interrupts to make sure that the system clock is as expected. However, the response time to interrupt when we were in EM2 was a between 300 and 600 us. By default, we use the low interrupt latency. Signed-off-by: Bastien Beauchamp --- soc/silabs/Kconfig | 7 +++++++ soc/silabs/common/soc_power_pmgr.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/soc/silabs/Kconfig b/soc/silabs/Kconfig index 28676194b495d..1bc6ca673f993 100644 --- a/soc/silabs/Kconfig +++ b/soc/silabs/Kconfig @@ -153,6 +153,13 @@ config SOC_GECKO_PM_BACKEND_EMU help Implement PM using direct calls to EMU driver in emlib +config SOC_SILABS_PM_LOW_INTERRUPT_LATENCY + bool "Low interrupt latency mode" + default y if SOC_GECKO_PM_BACKEND_PMGR + help + Enabling low interrupt latency allows interrupts to be executed + before the high frequency clock is restored after sleep. + endif # PM config SOC_GECKO_EMU_DCDC diff --git a/soc/silabs/common/soc_power_pmgr.c b/soc/silabs/common/soc_power_pmgr.c index 443e289cda780..5f9d1909b4840 100644 --- a/soc/silabs/common/soc_power_pmgr.c +++ b/soc/silabs/common/soc_power_pmgr.c @@ -87,6 +87,7 @@ bool sl_power_manager_is_ok_to_sleep(void) return true; } +#if !defined(CONFIG_SOC_SILABS_PM_LOW_INTERRUPT_LATENCY) /* This function is called by sl_power_manager_sleep() right after it was woken up from WFI. */ void sli_power_manager_on_wakeup(void) { @@ -98,6 +99,7 @@ void sli_power_manager_on_wakeup(void) sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1); sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); } +#endif /** * Some SiLabs blobs, such as RAIL, call directly into sl_power_manager, and From 0f948aba744a9eb3fbc4a65265fce0544d026c44 Mon Sep 17 00:00:00 2001 From: Bastien Beauchamp Date: Tue, 19 Aug 2025 11:24:05 -0400 Subject: [PATCH 0170/1076] simplicity_sdk: Patch in sl_power_manager_hal_s2.c Patch needed to fix a bug where the SLEEPDEEP bit is not cleared properly after a wakeup from EM2. Signed-off-by: Bastien Beauchamp --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 7bf652bf2ef3f..deeeb6e2e57d8 100644 --- a/west.yml +++ b/west.yml @@ -235,7 +235,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 0b58229357750b8bd0ce52e514c54ace6abcfeba + revision: 54cdbdb79c1ccd99b62a93d3af6caff79ab66197 path: modules/hal/silabs groups: - hal From ad849debeedaa276e4b8a6d479f2436b434b0b62 Mon Sep 17 00:00:00 2001 From: Bastien Beauchamp Date: Thu, 21 Aug 2025 08:24:44 -0400 Subject: [PATCH 0171/1076] pm: skip min_residency_ticks calculation if input is 0 In the default PM policy, the function k_us_to_ticks_ceil32() is used and does calculation using 64-bit integers which can be slow and avoidable if the input is 0. Signed-off-by: Bastien Beauchamp --- subsys/pm/policy/policy_default.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/subsys/pm/policy/policy_default.c b/subsys/pm/policy/policy_default.c index 7c917264e78f5..fd1976c93f7cf 100644 --- a/subsys/pm/policy/policy_default.c +++ b/subsys/pm/policy/policy_default.c @@ -25,10 +25,13 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) for (uint32_t i = 0; i < num_cpu_states; i++) { const struct pm_state_info *state = &cpu_states[i]; - uint32_t min_residency_ticks; + uint32_t min_residency_ticks = 0; + uint32_t min_residency_us = state->min_residency_us + state->exit_latency_us; - min_residency_ticks = - k_us_to_ticks_ceil32(state->min_residency_us + state->exit_latency_us); + /* If the input is zero, avoid 64-bit conversion from microseconds to ticks. */ + if (min_residency_us > 0) { + min_residency_ticks = k_us_to_ticks_ceil32(min_residency_us); + } if (ticks < min_residency_ticks) { /* If current state has higher residency then use the previous state; */ From a4fde2d2055dd58c5ea4593ef3a85a84dedd777b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 Aug 2025 10:47:45 -0700 Subject: [PATCH 0172/1076] linker/xt-ld: Compute crtbegin/crtend paths in toolchain_linker_finalize The computation of paths to crtbegin.o and crtend.o must be delayed until after the compiler_file_path function has been defined. The toolchain_linker_finalize function is where these are supposed to get set now. Signed-off-by: Keith Packard --- cmake/linker/xt-ld/target.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/linker/xt-ld/target.cmake b/cmake/linker/xt-ld/target.cmake index bdaf9829fcdd2..949787836adc9 100644 --- a/cmake/linker/xt-ld/target.cmake +++ b/cmake/linker/xt-ld/target.cmake @@ -11,8 +11,6 @@ find_program(CMAKE_LINKER xt-ld ${LD_SEARCH_PATH}) set_ifndef(LINKERFLAGPREFIX -Wl) -compiler_file_path(crtbegin.o CRTBEGIN_PATH) -compiler_file_path(crtend.o CRTEND_PATH) if(CONFIG_CPP_EXCEPTIONS AND CRTBEGIN_PATH AND CRTEND_PATH) # When building with C++ Exceptions, it is important that crtbegin and crtend # are linked at specific locations. @@ -156,6 +154,10 @@ macro(toolchain_linker_finalize) set(CMAKE_ASM_LINK_EXECUTABLE " ${common_link}") set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") set(CMAKE_CXX_LINK_EXECUTABLE " ${common_link}") + + compiler_file_path(crtbegin.o CRTBEGIN_PATH) + compiler_file_path(crtend.o CRTEND_PATH) + endmacro() # Function to map compiler flags into suitable linker flags From 2299f9add6866e32c4eabc165cdd2ebd2fe0e71b Mon Sep 17 00:00:00 2001 From: Jacob Wienecke Date: Wed, 27 Aug 2025 14:10:14 -0500 Subject: [PATCH 0173/1076] boards: mimxrt1010_evk: doc: fix debug connector number The debug connector designation for JTAG/SWD is J55. J16 is for OPENSDA "OPENDBG INTERFACE JTAG CONNECTOR" Signed-off-by: Jacob Wienecke --- boards/nxp/mimxrt1010_evk/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mimxrt1010_evk/doc/index.rst b/boards/nxp/mimxrt1010_evk/doc/index.rst index 66809750946ea..c34f2f6fb4fb8 100644 --- a/boards/nxp/mimxrt1010_evk/doc/index.rst +++ b/boards/nxp/mimxrt1010_evk/doc/index.rst @@ -141,7 +141,7 @@ Configuring a Debug Probe ========================= For the RT1010, J61/J62 are the SWD isolation jumpers, J22 is the DFU -mode jumper, and J16 is the 10 pin JTAG/SWD header. +mode jumper, and J55 is the 10 pin JTAG/SWD header. .. include:: ../../common/rt1xxx-lpclink2-debug.rst :start-after: rt1xxx-lpclink2-probes From 714cbd85eccafa6ecfb96759d3a1bf728e610208 Mon Sep 17 00:00:00 2001 From: Alex Fabre Date: Tue, 26 Aug 2025 10:09:21 +0200 Subject: [PATCH 0174/1076] log: backend: net: add const qualifier to hostname When setting the net log hostname, the string content is not modified. Signed-off-by: Alex Fabre --- include/zephyr/logging/log_backend_net.h | 2 +- subsys/logging/backends/log_backend_net.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/logging/log_backend_net.h b/include/zephyr/logging/log_backend_net.h index 4aafb1deb7f57..71b22e1e0e9e0 100644 --- a/include/zephyr/logging/log_backend_net.h +++ b/include/zephyr/logging/log_backend_net.h @@ -65,7 +65,7 @@ bool log_backend_net_set_ip(const struct sockaddr *addr); * @param len Length of the hostname array. */ #if defined(CONFIG_NET_HOSTNAME_ENABLE) -void log_backend_net_hostname_set(char *hostname, size_t len); +void log_backend_net_hostname_set(const char *hostname, size_t len); #else static inline void log_backend_net_hostname_set(const char *hostname, size_t len) { diff --git a/subsys/logging/backends/log_backend_net.c b/subsys/logging/backends/log_backend_net.c index b0e3ca5c42587..4470d9c3392c8 100644 --- a/subsys/logging/backends/log_backend_net.c +++ b/subsys/logging/backends/log_backend_net.c @@ -295,7 +295,7 @@ bool log_backend_net_set_ip(const struct sockaddr *addr) } #if defined(CONFIG_NET_HOSTNAME_ENABLE) -void log_backend_net_hostname_set(char *hostname, size_t len) +void log_backend_net_hostname_set(const char *hostname, size_t len) { (void)strncpy(dev_hostname, hostname, MIN(len, MAX_HOSTNAME_LEN)); log_output_hostname_set(&log_output_net, dev_hostname); From 455b0eeb7f864873ca568253c691fa935d27aa47 Mon Sep 17 00:00:00 2001 From: Steffen Jahnke Date: Tue, 26 Aug 2025 09:01:04 +0000 Subject: [PATCH 0175/1076] boards: panasonic: Update naming PAN B611 Evaluation Board The PAN B511 evaluation board is a development tool for the nRF54L15 from Nordic Semiconductor. Due to marketing reasons the naming was adjusted from panb511 to panb611. Signed-off-by: Steffen Jahnke --- boards/deprecated.cmake | 3 ++ .../panasonic/panb511evb/Kconfig.panb511evb | 7 ----- .../{panb511evb => panb611evb}/Kconfig | 6 ++-- .../Kconfig.defconfig | 8 ++--- .../panasonic/panb611evb/Kconfig.panb611evb | 7 +++++ .../{panb511evb => panb611evb}/board.cmake | 2 +- .../{panb511evb => panb611evb}/board.yml | 28 +++++++++--------- .../doc/img/panb611evb.webp} | Bin .../{panb511evb => panb611evb}/doc/index.rst | 20 ++++++------- .../panb611evb_nrf54l15-pinctrl.dtsi} | 0 .../panb611evb_nrf54l15_common.dtsi} | 2 +- .../panb611evb_nrf54l15_cpuapp.dts} | 6 ++-- .../panb611evb_nrf54l15_cpuapp.yaml} | 4 +-- .../panb611evb_nrf54l15_cpuapp_common.dtsi} | 2 +- .../panb611evb_nrf54l15_cpuapp_defconfig} | 0 .../panb611evb_nrf54l15_cpuapp_ns.dts} | 6 ++-- .../panb611evb_nrf54l15_cpuapp_ns.yaml} | 4 +-- .../panb611evb_nrf54l15_cpuapp_ns_defconfig} | 0 .../panb611evb_nrf54l15_cpuflpr.dts} | 6 ++-- .../panb611evb_nrf54l15_cpuflpr.yaml} | 4 +-- .../panb611evb_nrf54l15_cpuflpr_defconfig} | 0 .../panb611evb_nrf54l15_cpuflpr_xip.dts} | 2 +- .../panb611evb_nrf54l15_cpuflpr_xip.yaml} | 4 +-- ...panb611evb_nrf54l15_cpuflpr_xip_defconfig} | 0 .../support/nrf54l15_cpuflpr.JLinkScript | 0 doc/_scripts/redirects.py | 1 + doc/releases/migration-guide-4.3.rst | 2 ++ doc/releases/release-notes-4.1.rst | 2 +- ...lay => panb611evb_nrf54l15_cpuapp.overlay} | 0 ... => panb611evb_nrf54l15_cpuapp_df.overlay} | 0 samples/drivers/watchdog/sample.yaml | 8 ++--- tests/drivers/adc/adc_api/testcase.yaml | 4 +-- .../watchdog/wdt_basic_api/testcase.yaml | 8 ++--- 33 files changed, 76 insertions(+), 70 deletions(-) delete mode 100644 boards/panasonic/panb511evb/Kconfig.panb511evb rename boards/panasonic/{panb511evb => panb611evb}/Kconfig (89%) rename boards/panasonic/{panb511evb => panb611evb}/Kconfig.defconfig (81%) create mode 100644 boards/panasonic/panb611evb/Kconfig.panb611evb rename boards/panasonic/{panb511evb => panb611evb}/board.cmake (92%) rename boards/panasonic/{panb511evb => panb611evb}/board.yml (50%) rename boards/panasonic/{panb511evb/doc/img/panb511evb.webp => panb611evb/doc/img/panb611evb.webp} (100%) rename boards/panasonic/{panb511evb => panb611evb}/doc/index.rst (57%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15-pinctrl.dtsi => panb611evb/panb611evb_nrf54l15-pinctrl.dtsi} (100%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_common.dtsi => panb611evb/panb611evb_nrf54l15_common.dtsi} (98%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp.dts => panb611evb/panb611evb_nrf54l15_cpuapp.dts} (68%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp.yaml => panb611evb/panb611evb_nrf54l15_cpuapp.yaml} (79%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi => panb611evb/panb611evb_nrf54l15_cpuapp_common.dtsi} (97%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp_defconfig => panb611evb/panb611evb_nrf54l15_cpuapp_defconfig} (100%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp_ns.dts => panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts} (90%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp_ns.yaml => panb611evb/panb611evb_nrf54l15_cpuapp_ns.yaml} (74%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuapp_ns_defconfig => panb611evb/panb611evb_nrf54l15_cpuapp_ns_defconfig} (100%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr.dts => panb611evb/panb611evb_nrf54l15_cpuflpr.dts} (86%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr.yaml => panb611evb/panb611evb_nrf54l15_cpuflpr.yaml} (69%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig => panb611evb/panb611evb_nrf54l15_cpuflpr_defconfig} (100%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts => panb611evb/panb611evb_nrf54l15_cpuflpr_xip.dts} (82%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml => panb611evb/panb611evb_nrf54l15_cpuflpr_xip.yaml} (69%) rename boards/panasonic/{panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig => panb611evb/panb611evb_nrf54l15_cpuflpr_xip_defconfig} (100%) rename boards/panasonic/{panb511evb => panb611evb}/support/nrf54l15_cpuflpr.JLinkScript (100%) rename samples/bluetooth/hci_uart/boards/{panb511evb_nrf54l15_cpuapp.overlay => panb611evb_nrf54l15_cpuapp.overlay} (100%) rename samples/bluetooth/hci_uart/boards/{panb511evb_nrf54l15_cpuapp_df.overlay => panb611evb_nrf54l15_cpuapp_df.overlay} (100%) diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index c2d72844f5af7..1cc3856cee8ad 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -46,6 +46,9 @@ set(mimxrt1060_evkb_DEPRECATED set(neorv32_DEPRECATED neorv32/neorv32/up5kdemo ) +set(panb511evb_DEPRECATED + panb611evb +) set(xiao_esp32c6_DEPRECATED xiao_esp32c6/esp32c6/hpcore ) diff --git a/boards/panasonic/panb511evb/Kconfig.panb511evb b/boards/panasonic/panb511evb/Kconfig.panb511evb deleted file mode 100644 index 12878fd47d4a0..0000000000000 --- a/boards/panasonic/panb511evb/Kconfig.panb511evb +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_PANB511EVB - select SOC_NRF54L15_CPUAPP if BOARD_PANB511EVB_NRF54L15_CPUAPP || BOARD_PANB511EVB_NRF54L15_CPUAPP_NS - select SOC_NRF54L15_CPUFLPR if BOARD_PANB511EVB_NRF54L15_CPUFLPR || \ - BOARD_PANB511EVB_NRF54L15_CPUFLPR_XIP diff --git a/boards/panasonic/panb511evb/Kconfig b/boards/panasonic/panb611evb/Kconfig similarity index 89% rename from boards/panasonic/panb511evb/Kconfig rename to boards/panasonic/panb611evb/Kconfig index 7b00e24412160..93fcd9b78f980 100644 --- a/boards/panasonic/panb511evb/Kconfig +++ b/boards/panasonic/panb611evb/Kconfig @@ -1,9 +1,9 @@ # Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH # SPDX-License-Identifier: Apache-2.0 -# PANB511EVB configuration +# PANB611EVB configuration -if BOARD_PANB511EVB_NRF54L15_CPUAPP_NS +if BOARD_PANB611EVB_NRF54L15_CPUAPP_NS DT_NRF_MPC := $(dt_nodelabel_path,nrf_mpc) @@ -27,4 +27,4 @@ config NRF_TRUSTZONE_RAM_REGION_SIZE This abstraction allows us to configure TrustZone without depending on peripheral specific symbols. -endif # BOARD_PANB511EVB_NRF54L15_CPUAPP_NS +endif # BOARD_PANB611EVB_NRF54L15_CPUAPP_NS diff --git a/boards/panasonic/panb511evb/Kconfig.defconfig b/boards/panasonic/panb611evb/Kconfig.defconfig similarity index 81% rename from boards/panasonic/panb511evb/Kconfig.defconfig rename to boards/panasonic/panb611evb/Kconfig.defconfig index 595e01692ccf7..6ad6d9426dbf0 100644 --- a/boards/panasonic/panb511evb/Kconfig.defconfig +++ b/boards/panasonic/panb611evb/Kconfig.defconfig @@ -5,14 +5,14 @@ DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition -if BOARD_PANB511EVB_NRF54L15_CPUAPP +if BOARD_PANB611EVB_NRF54L15_CPUAPP config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT -endif # BOARD_PANB511EVB_NRF54L15_CPUAPP +endif # BOARD_PANB611EVB_NRF54L15_CPUAPP -if BOARD_PANB511EVB_NRF54L15_CPUAPP_NS +if BOARD_PANB611EVB_NRF54L15_CPUAPP_NS config HAS_BT_CTLR default BT @@ -28,4 +28,4 @@ config FLASH_LOAD_SIZE config BUILD_WITH_TFM default y -endif # BOARD_PANB511EVB_NRF54L15_CPUAPP_NS +endif # BOARD_PANB611EVB_NRF54L15_CPUAPP_NS diff --git a/boards/panasonic/panb611evb/Kconfig.panb611evb b/boards/panasonic/panb611evb/Kconfig.panb611evb new file mode 100644 index 0000000000000..d941810714d7a --- /dev/null +++ b/boards/panasonic/panb611evb/Kconfig.panb611evb @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PANB611EVB + select SOC_NRF54L15_CPUAPP if BOARD_PANB611EVB_NRF54L15_CPUAPP || BOARD_PANB611EVB_NRF54L15_CPUAPP_NS + select SOC_NRF54L15_CPUFLPR if BOARD_PANB611EVB_NRF54L15_CPUFLPR || \ + BOARD_PANB611EVB_NRF54L15_CPUFLPR_XIP diff --git a/boards/panasonic/panb511evb/board.cmake b/boards/panasonic/panb611evb/board.cmake similarity index 92% rename from boards/panasonic/panb511evb/board.cmake rename to boards/panasonic/panb611evb/board.cmake index d6d51e58a39f6..3a7eb3103be84 100644 --- a/boards/panasonic/panb511evb/board.cmake +++ b/boards/panasonic/panb611evb/board.cmake @@ -7,7 +7,7 @@ elseif(CONFIG_SOC_NRF54L15_CPUFLPR) board_runner_args(jlink "--device=nRF54L15_RV32") endif() -if(CONFIG_BOARD_PANB511EVB_NRF54L15_CPUAPP_NS) +if(CONFIG_BOARD_PANB611EVB_NRF54L15_CPUAPP_NS) set(TFM_PUBLIC_KEY_FORMAT "full") endif() diff --git a/boards/panasonic/panb511evb/board.yml b/boards/panasonic/panb611evb/board.yml similarity index 50% rename from boards/panasonic/panb511evb/board.yml rename to boards/panasonic/panb611evb/board.yml index 6e2d60bf4a079..365e6156d5eaa 100644 --- a/boards/panasonic/panb511evb/board.yml +++ b/boards/panasonic/panb611evb/board.yml @@ -1,6 +1,6 @@ board: - name: panb511evb - full_name: PAN B511 Evaluation Board + name: panb611evb + full_name: PAN B611 Evaluation Board vendor: panasonic socs: - name: nrf54l15 @@ -18,10 +18,10 @@ runners: run: first groups: - boards: - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns - - panb511evb/nrf54l15/cpuflpr - - panb511evb/nrf54l15/cpuflpr/xip + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuflpr + - panb611evb/nrf54l15/cpuflpr/xip '--erase': - runners: - nrfjprog @@ -30,10 +30,10 @@ runners: run: first groups: - boards: - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns - - panb511evb/nrf54l15/cpuflpr - - panb511evb/nrf54l15/cpuflpr/xip + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuflpr + - panb611evb/nrf54l15/cpuflpr/xip '--reset': - runners: - nrfjprog @@ -42,7 +42,7 @@ runners: run: last groups: - boards: - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns - - panb511evb/nrf54l15/cpuflpr - - panb511evb/nrf54l15/cpuflpr/xip + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuflpr + - panb611evb/nrf54l15/cpuflpr/xip diff --git a/boards/panasonic/panb511evb/doc/img/panb511evb.webp b/boards/panasonic/panb611evb/doc/img/panb611evb.webp similarity index 100% rename from boards/panasonic/panb511evb/doc/img/panb511evb.webp rename to boards/panasonic/panb611evb/doc/img/panb611evb.webp diff --git a/boards/panasonic/panb511evb/doc/index.rst b/boards/panasonic/panb611evb/doc/index.rst similarity index 57% rename from boards/panasonic/panb511evb/doc/index.rst rename to boards/panasonic/panb611evb/doc/index.rst index 25920e774820d..e9cf2d9778fc8 100644 --- a/boards/panasonic/panb511evb/doc/index.rst +++ b/boards/panasonic/panb611evb/doc/index.rst @@ -1,19 +1,19 @@ -.. zephyr:board:: panb511evb +.. zephyr:board:: panb611evb Overview ******** -The PAN B511 Evaluation Board (panb511evb) is a development tool -for the PAN B511 module which is based on the nRF54L15 chipset +The PAN B611 Evaluation Board (panb611evb) is a development tool +for the PAN B611 module which is based on the nRF54L15 chipset from Nordic Semiconductor. -More information about the PAN B511 Module Variants and Evaluation Board can be found +More information about the PAN B611 Module Variants and Evaluation Board can be found on the `product website`_. Usage ***** -You can find the `panb511evb user guide`_ for the PAN B511 Evaluation Board in the +You can find the `panb611evb user guide`_ for the PAN B611 Evaluation Board in the `Panasonic Wireless Connectivity Development Hub`_. The User Guide contains (amongst other things) detailed information about @@ -26,15 +26,15 @@ The User Guide contains (amongst other things) detailed information about and other things. -The schematics for the PANB511 Evaluation Boards are available in the -`download section PANB511`_ of the `Panasonic Wireless Connectivity Development Hub`_. +The schematics for the PANB611 Evaluation Boards are available in the +`download section PANB611`_ of the `Panasonic Wireless Connectivity Development Hub`_. Programming and Debugging ************************* .. zephyr:board-supported-runners:: -Applications for the ``panb511evb/nrf54l15/cpuapp`` board target can +Applications for the ``panb611evb/nrf54l15/cpuapp`` board target can be built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. @@ -42,5 +42,5 @@ building and running. .. target-notes:: .. _product website: https://industry.panasonic.eu/products/devices/wireless-connectivity/bluetooth-low-energy-modules .. _Panasonic Wireless Connectivity Development Hub: https://pideu.panasonic.de/development-hub/ -.. _panb511evb user guide: https://pideu.panasonic.de/development-hub/panb511/evaluation_board/user_guide/ -.. _download section PANB511: https://pideu.panasonic.de/development-hub/panb511/downloads/ +.. _panb611evb user guide: https://pideu.panasonic.de/development-hub/panb611/evaluation_board/user_guide/ +.. _download section PANB611: https://pideu.panasonic.de/development-hub/panb611/downloads/ diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15-pinctrl.dtsi b/boards/panasonic/panb611evb/panb611evb_nrf54l15-pinctrl.dtsi similarity index 100% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15-pinctrl.dtsi rename to boards/panasonic/panb611evb/panb611evb_nrf54l15-pinctrl.dtsi diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi b/boards/panasonic/panb611evb/panb611evb_nrf54l15_common.dtsi similarity index 98% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_common.dtsi index fc300f888b92a..c819084978e22 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_common.dtsi @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "panb511evb_nrf54l15-pinctrl.dtsi" +#include "panb611evb_nrf54l15-pinctrl.dtsi" / { leds { diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts similarity index 68% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts index 04616affd1461..25b838667289d 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts @@ -7,11 +7,11 @@ /dts-v1/; #include -#include "panb511evb_nrf54l15_cpuapp_common.dtsi" +#include "panb611evb_nrf54l15_cpuapp_common.dtsi" / { - compatible = "panasonic-industrial-devices-europe-gmbh,panb511evb-cpuapp"; - model = "Panasonic PAN B511 EVB nRF54L15 Application MCU"; + compatible = "panasonic-industrial-devices-europe-gmbh,panb611evb-cpuapp"; + model = "Panasonic PAN B611 EVB nRF54L15 Application MCU"; chosen { zephyr,code-partition = &slot0_partition; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.yaml similarity index 79% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.yaml index db252d56047d3..3bfef0b99b527 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.yaml @@ -1,8 +1,8 @@ # Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH # SPDX-License-Identifier: Apache-2.0 -identifier: panb511evb/nrf54l15/cpuapp -name: PANB511-EVB-nRF54l15-Application +identifier: panb611evb/nrf54l15/cpuapp +name: PANB611-EVB-nRF54l15-Application type: mcu arch: arm toolchain: diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_common.dtsi similarity index 97% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_common.dtsi index 634f758d531a7..ba978a5412866 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_common.dtsi @@ -6,7 +6,7 @@ /* This file is common to the secure and non-secure domain */ -#include "panb511evb_nrf54l15_common.dtsi" +#include "panb611evb_nrf54l15_common.dtsi" / { chosen { diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_defconfig b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_defconfig similarity index 100% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_defconfig rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_defconfig diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts similarity index 90% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.dts rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts index 4f5ea30331650..cebc30ff08996 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts @@ -9,11 +9,11 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 #include -#include "panb511evb_nrf54l15_cpuapp_common.dtsi" +#include "panb611evb_nrf54l15_cpuapp_common.dtsi" / { - model = "Panasonic PAN B511 EVB nRF54L15 Application MCU"; - compatible = "panasonic-industrial-devices-europe-gmbh,panb511evb-cpuapp"; + model = "Panasonic PAN B611 EVB nRF54L15 Application MCU"; + compatible = "panasonic-industrial-devices-europe-gmbh,panb611evb-cpuapp"; chosen { zephyr,code-partition = &slot0_ns_partition; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.yaml b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.yaml similarity index 74% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.yaml rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.yaml index 2a092dea13dff..dee107967bfc5 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns.yaml +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.yaml @@ -1,8 +1,8 @@ # Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH # SPDX-License-Identifier: Apache-2.0 -identifier: panb511evb/nrf54l15/cpuapp/ns -name: PANB511-EVB-nRF54l15-Application-Non-Secure +identifier: panb611evb/nrf54l15/cpuapp/ns +name: PANB611-EVB-nRF54l15-Application-Non-Secure type: mcu arch: arm toolchain: diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns_defconfig b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns_defconfig similarity index 100% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_ns_defconfig rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns_defconfig diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.dts similarity index 86% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.dts index 5a238b48a6ba1..bd40a2f837be4 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.dts @@ -6,11 +6,11 @@ /dts-v1/; #include -#include "panb511evb_nrf54l15_common.dtsi" +#include "panb611evb_nrf54l15_common.dtsi" / { - model = "Panasonic PAN B511 EVB nRF54L15 FLPR MCU"; - compatible = "panasonic-industrial-devices-europe-gmbh,panb511evb-cpuflpr"; + model = "Panasonic PAN B611 EVB nRF54L15 FLPR MCU"; + compatible = "panasonic-industrial-devices-europe-gmbh,panb611evb-cpuflpr"; chosen { zephyr,console = &uart20; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.yaml similarity index 69% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.yaml index 481fcb00bd05d..d99c2f99aee62 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr.yaml @@ -1,8 +1,8 @@ # Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH # SPDX-License-Identifier: Apache-2.0 -identifier: panb511evb/nrf54l15/cpuflpr -name: PANB511-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor +identifier: panb611evb/nrf54l15/cpuflpr +name: PANB611-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor type: mcu arch: riscv toolchain: diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_defconfig similarity index 100% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_defconfig diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.dts similarity index 82% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.dts index f14f44e097597..7c506af954912 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.dts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "panb511evb_nrf54l15_cpuflpr.dts" +#include "panb611evb_nrf54l15_cpuflpr.dts" &cpuflpr_sram { reg = <0x2002f000 DT_SIZE_K(68)>; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.yaml similarity index 69% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.yaml index e54c5a7b9fdd6..ec4984b963bf8 100644 --- a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip.yaml @@ -1,8 +1,8 @@ # Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH # SPDX-License-Identifier: Apache-2.0 -identifier: panb511evb/nrf54l15/cpuflpr/xip -name: PANB511-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor (RRAM XIP) +identifier: panb611evb/nrf54l15/cpuflpr/xip +name: PANB611-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor (RRAM XIP) type: mcu arch: riscv toolchain: diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip_defconfig similarity index 100% rename from boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig rename to boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuflpr_xip_defconfig diff --git a/boards/panasonic/panb511evb/support/nrf54l15_cpuflpr.JLinkScript b/boards/panasonic/panb611evb/support/nrf54l15_cpuflpr.JLinkScript similarity index 100% rename from boards/panasonic/panb511evb/support/nrf54l15_cpuflpr.JLinkScript rename to boards/panasonic/panb611evb/support/nrf54l15_cpuflpr.JLinkScript diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index 79174d1d0d988..a2d25040d0d4c 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -17,6 +17,7 @@ ('application/index', 'develop/application/index'), ('boards/arduino/uno_r4_minima/doc/index', 'boards/arduino/uno_r4/doc/index'), ('boards/nordic/nrf54l20pdk/doc/index', 'boards/nordic/nrf54lm20dk/doc/index'), + ('boards/panasonic/panb511evb/doc/index', 'boards/panasonic/panb611evb/doc/index'), ('boards/phytec/mimx8mm_phyboard_polis/doc/index', 'boards/phytec/phyboard_polis/doc/index'), ('boards/phytec/mimx8mp_phyboard_pollux/doc/index', 'boards/phytec/phyboard_pollux/doc/index'), ('boards/rak/index', 'boards/rakwireless/index'), diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index 1780561878562..9c20e47a5e7c7 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -34,6 +34,8 @@ Boards * NXP ``frdm_mcxa166`` is renamed to ``frdm_mcxa346``. * NXP ``frdm_mcxa276`` is renamed to ``frdm_mcxa266``. +* Panasonic ``panb511evb`` is renamed to ``panb611evb``. + Device Drivers and Devicetree ***************************** diff --git a/doc/releases/release-notes-4.1.rst b/doc/releases/release-notes-4.1.rst index e23bdb695f3c6..7d850846d3ffb 100644 --- a/doc/releases/release-notes-4.1.rst +++ b/doc/releases/release-notes-4.1.rst @@ -446,7 +446,7 @@ New Boards * Panasonic Corporation - * :zephyr:board:`panb511evb` (``panb511evb``) + * PAN B511 Evaluation Board (``panb511evb``) * Peregrine Consultoria e Servicos diff --git a/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp.overlay b/samples/bluetooth/hci_uart/boards/panb611evb_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp.overlay rename to samples/bluetooth/hci_uart/boards/panb611evb_nrf54l15_cpuapp.overlay diff --git a/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp_df.overlay b/samples/bluetooth/hci_uart/boards/panb611evb_nrf54l15_cpuapp_df.overlay similarity index 100% rename from samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp_df.overlay rename to samples/bluetooth/hci_uart/boards/panb611evb_nrf54l15_cpuapp_df.overlay diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index 75b9f45977892..a1069108fb058 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -22,10 +22,10 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns - - panb511evb/nrf54l15/cpuflpr - - panb511evb/nrf54l15/cpuflpr/xip + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuflpr + - panb611evb/nrf54l15/cpuflpr/xip - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns diff --git a/tests/drivers/adc/adc_api/testcase.yaml b/tests/drivers/adc/adc_api/testcase.yaml index 652c3e12a85cb..f0592b4c056ab 100644 --- a/tests/drivers/adc/adc_api/testcase.yaml +++ b/tests/drivers/adc/adc_api/testcase.yaml @@ -9,8 +9,8 @@ tests: min_flash: 40 platform_exclude: - nucleo_u031r8 - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 550424dc95017..01b8e6d833a8f 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -21,10 +21,10 @@ tests: - mps2/an383 - mps2/an386 - mps2/an500 - - panb511evb/nrf54l15/cpuapp - - panb511evb/nrf54l15/cpuapp/ns - - panb511evb/nrf54l15/cpuflpr - - panb511evb/nrf54l15/cpuflpr/xip + - panb611evb/nrf54l15/cpuapp + - panb611evb/nrf54l15/cpuapp/ns + - panb611evb/nrf54l15/cpuflpr + - panb611evb/nrf54l15/cpuflpr/xip - mimxrt700_evk/mimxrt798s/cm33_cpu1 - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns From 5ca5966f19f9fe88b1c801d02098d7af29f22fdc Mon Sep 17 00:00:00 2001 From: Ta Minh Nhat Date: Wed, 26 Mar 2025 13:32:38 +0700 Subject: [PATCH 0176/1076] board: renesas: Change default pwm in Renesas RA6 boards Change default pwm to pwm0 to avoid pin conflict with ethernet phy. Signed-off-by: Ta Minh Nhat --- boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi | 8 ++++---- boards/renesas/ek_ra6m4/ek_ra6m4.dts | 4 ++-- boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi | 8 ++++---- boards/renesas/ek_ra6m5/ek_ra6m5.dts | 4 ++-- samples/boards/renesas/elc/boards/ek_ra6m4.overlay | 4 ++-- samples/boards/renesas/elc/boards/ek_ra6m5.overlay | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi index 081e3a74621bf..0abb9ba3402e1 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi @@ -55,11 +55,11 @@ }; }; - pwm1_default: pwm1_default { + pwm0_default: pwm0_default { group1 { - /* GTIOC1A GTIOC1B */ - psels = , - ; + /* GTIOC0A GTIOC0B */ + psels = , + ; }; }; diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.dts b/boards/renesas/ek_ra6m4/ek_ra6m4.dts index c6ed4cbcff021..19a1ecfc2aa95 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.dts +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.dts @@ -238,8 +238,8 @@ status = "okay"; }; -&pwm1 { - pinctrl-0 = <&pwm1_default>; +&pwm0 { + pinctrl-0 = <&pwm0_default>; pinctrl-names = "default"; interrupts = <63 1>, <64 1>; interrupt-names = "gtioca", "overflow"; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi index 203730f335e21..22d8aae8184fb 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi @@ -62,11 +62,11 @@ }; }; - pwm1_default: pwm1_default { + pwm0_default: pwm0_default { group1 { - /* GTIOC1A GTIOC1B */ - psels = , - ; + /* GTIOC0A GTIOC0B */ + psels = , + ; }; }; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5.dts b/boards/renesas/ek_ra6m5/ek_ra6m5.dts index ef397309a0cc7..d02ff32608da6 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5.dts +++ b/boards/renesas/ek_ra6m5/ek_ra6m5.dts @@ -249,8 +249,8 @@ status = "okay"; }; -&pwm1 { - pinctrl-0 = <&pwm1_default>; +&pwm0 { + pinctrl-0 = <&pwm0_default>; pinctrl-names = "default"; interrupts = <63 1>, <64 1>; interrupt-names = "gtioca", "overflow"; diff --git a/samples/boards/renesas/elc/boards/ek_ra6m4.overlay b/samples/boards/renesas/elc/boards/ek_ra6m4.overlay index 65847b9cde38a..c0a12ebcde08f 100644 --- a/samples/boards/renesas/elc/boards/ek_ra6m4.overlay +++ b/samples/boards/renesas/elc/boards/ek_ra6m4.overlay @@ -9,7 +9,7 @@ / { aliases { - pwm-gen = &pwm1; + pwm-gen = &pwm0; pwm-cap = &pwm4; elc-link = &elc; }; @@ -33,7 +33,7 @@ status = "okay"; }; -&pwm1 { +&pwm0 { renesas-elcs = <&elc RA_ELC_PERIPHERAL_GPT_A RA_ELC_EVENT_ELC_SOFTWARE_EVENT_0>, <&elc RA_ELC_PERIPHERAL_GPT_B RA_ELC_EVENT_ELC_SOFTWARE_EVENT_1>; renesas-elc-names = "start", "stop"; diff --git a/samples/boards/renesas/elc/boards/ek_ra6m5.overlay b/samples/boards/renesas/elc/boards/ek_ra6m5.overlay index 65847b9cde38a..c0a12ebcde08f 100644 --- a/samples/boards/renesas/elc/boards/ek_ra6m5.overlay +++ b/samples/boards/renesas/elc/boards/ek_ra6m5.overlay @@ -9,7 +9,7 @@ / { aliases { - pwm-gen = &pwm1; + pwm-gen = &pwm0; pwm-cap = &pwm4; elc-link = &elc; }; @@ -33,7 +33,7 @@ status = "okay"; }; -&pwm1 { +&pwm0 { renesas-elcs = <&elc RA_ELC_PERIPHERAL_GPT_A RA_ELC_EVENT_ELC_SOFTWARE_EVENT_0>, <&elc RA_ELC_PERIPHERAL_GPT_B RA_ELC_EVENT_ELC_SOFTWARE_EVENT_1>; renesas-elc-names = "start", "stop"; From 222bb2995c554a30fac2b1fa29dec6e9032f1acc Mon Sep 17 00:00:00 2001 From: Ta Minh Nhat Date: Wed, 26 Mar 2025 14:12:38 +0700 Subject: [PATCH 0177/1076] test: pwm: Change pwm channel pwm_loopback test Change default pwm to pwm0 in ek_ra6m4, ek_ra6m5 to avoid pin conflict with ethernet phy. Signed-off-by: Ta Minh Nhat --- tests/drivers/pwm/pwm_loopback/boards/ek_ra6m4.overlay | 2 +- tests/drivers/pwm/pwm_loopback/boards/ek_ra6m5.overlay | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m4.overlay b/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m4.overlay index 077b7bdd4062f..bb7ed90c9e071 100644 --- a/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m4.overlay +++ b/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m4.overlay @@ -11,7 +11,7 @@ pwm_loopback_0 { compatible = "test-pwm-loopback"; /* first index must be a 32-Bit timer */ - pwms = <&pwm1 0 0 PWM_POLARITY_NORMAL>, + pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>, <&pwm4 0 0 PWM_POLARITY_NORMAL>; }; }; diff --git a/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m5.overlay b/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m5.overlay index 077b7bdd4062f..bb7ed90c9e071 100644 --- a/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m5.overlay +++ b/tests/drivers/pwm/pwm_loopback/boards/ek_ra6m5.overlay @@ -11,7 +11,7 @@ pwm_loopback_0 { compatible = "test-pwm-loopback"; /* first index must be a 32-Bit timer */ - pwms = <&pwm1 0 0 PWM_POLARITY_NORMAL>, + pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>, <&pwm4 0 0 PWM_POLARITY_NORMAL>; }; }; From 4228444dd12332bc75b680ae24bd5421365970f6 Mon Sep 17 00:00:00 2001 From: Ta Minh Nhat Date: Fri, 11 Apr 2025 17:49:04 +0700 Subject: [PATCH 0178/1076] driver: ethernet: Add ethernet driver support for ra6m4 and ra6m5 Add ethernet support for RA6M4, RA6M5. Add soc script for generating Renesas Partition Data (RFP file). Signed-off-by: Ta Minh Nhat Singed-off-by: Duy Nguyen --- drivers/ethernet/Kconfig.renesas_ra | 6 ++ drivers/ethernet/eth_renesas_ra.c | 29 ++++-- soc/renesas/ra/Kconfig | 13 +++ soc/renesas/ra/ra6m4/CMakeLists.txt | 21 +++- soc/renesas/ra/ra6m4/Kconfig | 2 + soc/renesas/ra/ra6m4/linker.ld | 61 ++++++++++++ soc/renesas/ra/ra6m5/CMakeLists.txt | 21 +++- soc/renesas/ra/ra6m5/Kconfig | 2 + soc/renesas/ra/ra6m5/linker.ld | 61 ++++++++++++ soc/renesas/ra/tools/gen_rpd.py | 144 ++++++++++++++++++++++++++++ 10 files changed, 349 insertions(+), 11 deletions(-) create mode 100644 soc/renesas/ra/ra6m4/linker.ld create mode 100644 soc/renesas/ra/ra6m5/linker.ld create mode 100644 soc/renesas/ra/tools/gen_rpd.py diff --git a/drivers/ethernet/Kconfig.renesas_ra b/drivers/ethernet/Kconfig.renesas_ra index c107d9acbd5bf..30dd333a575b9 100644 --- a/drivers/ethernet/Kconfig.renesas_ra +++ b/drivers/ethernet/Kconfig.renesas_ra @@ -32,4 +32,10 @@ config ETH_RENESAS_RX_BUF_NUM default 4 range 1 8 +config ETH_RENESAS_RA_USE_NS_BUF + bool "Use non-secure section for buffers" + default y if SOC_SERIES_RA6M5 || SOC_SERIES_RA6M4 + depends on CPU_HAS_TEE + depends on !ARM_SECURE_FIRMWARE && !ARM_NONSECURE_FIRMWARE + endif diff --git a/drivers/ethernet/eth_renesas_ra.c b/drivers/ethernet/eth_renesas_ra.c index 161deb5f1529e..a0fd19e9d811c 100644 --- a/drivers/ethernet/eth_renesas_ra.c +++ b/drivers/ethernet/eth_renesas_ra.c @@ -12,7 +12,7 @@ #define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL #include -LOG_MODULE_REGISTER(LOG_MODULE_NAME); +LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL); #include #include @@ -66,11 +66,24 @@ struct renesas_ra_eth_config { const struct device *phy_dev; }; +/* + * In some Renesas SoCs, Ethernet peripheral is always a non-secure bus master. + * In that case, placing the Ethernet buffer in non-secure RAM is necessary. + */ +#define ETHER_BUFFER_ALIGN(s) static __aligned(s) +#if defined(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) +#define ETHER_BUFFER_PLACE_IN_SECTION __attribute__((section(".ns_buffer.eth"))) +#else +#define ETHER_BUFFER_PLACE_IN_SECTION +#endif + #define DECLARE_ETHER_RX_BUFFER(idx, _) \ - static __aligned(32) uint8_t g_ether0_ether_rx_buffer##idx[ETHER_BUF_SIZE]; + ETHER_BUFFER_ALIGN(32) \ + uint8_t g_ether0_ether_rx_buffer##idx[ETHER_BUF_SIZE] ETHER_BUFFER_PLACE_IN_SECTION; #define DECLARE_ETHER_TX_BUFFER(idx, _) \ - static __aligned(32) uint8_t g_ether0_ether_tx_buffer##idx[ETHER_BUF_SIZE]; + ETHER_BUFFER_ALIGN(32) \ + uint8_t g_ether0_ether_tx_buffer##idx[ETHER_BUF_SIZE] ETHER_BUFFER_PLACE_IN_SECTION; #define DECLARE_ETHER_RX_BUFFER_PTR(idx, _) (uint8_t *)&g_ether0_ether_rx_buffer##idx[0] @@ -83,10 +96,12 @@ uint8_t *pp_g_ether0_ether_buffers[ETHER_TOTAL_BUF_NUM] = { LISTIFY(CONFIG_ETH_RENESAS_RX_BUF_NUM, DECLARE_ETHER_RX_BUFFER_PTR, (,)), LISTIFY(CONFIG_ETH_RENESAS_TX_BUF_NUM, DECLARE_ETHER_TX_BUFFER_PTR, (,)) }; -static __aligned(16) ether_instance_descriptor_t - g_ether0_tx_descriptors[CONFIG_ETH_RENESAS_TX_BUF_NUM]; -static __aligned(16) ether_instance_descriptor_t - g_ether0_rx_descriptors[CONFIG_ETH_RENESAS_RX_BUF_NUM]; +ETHER_BUFFER_ALIGN(16) +ether_instance_descriptor_t + g_ether0_tx_descriptors[CONFIG_ETH_RENESAS_TX_BUF_NUM] ETHER_BUFFER_PLACE_IN_SECTION; +ETHER_BUFFER_ALIGN(16) +ether_instance_descriptor_t + g_ether0_rx_descriptors[CONFIG_ETH_RENESAS_RX_BUF_NUM] ETHER_BUFFER_PLACE_IN_SECTION; const ether_extended_cfg_t g_ether0_extended_cfg_t = { .p_rx_descriptors = g_ether0_rx_descriptors, diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index c3651008a4198..f7fb24c03f4c3 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -9,6 +9,19 @@ if SOC_FAMILY_RENESAS_RA config SERIES_SPECIFIC_SOC_INIT bool "Use series specific initialize" +config OUTPUT_RPD + bool "Build a Renesas Partition Data in rpd format" + depends on CPU_HAS_RENESAS_RA_IDAU + help + Build a partition data zephyr/zephyr.rpd in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. + +config CPU_HAS_RENESAS_RA_IDAU + bool + select CPU_HAS_TEE + help + MCU implements the ARM Implementation-Defined Attribution Unit (IDAU). + rsource "*/Kconfig" endif # SOC_FAMILY_RENESAS_RA diff --git a/soc/renesas/ra/ra6m4/CMakeLists.txt b/soc/renesas/ra/ra6m4/CMakeLists.txt index f8147e8059102..6b526e37972f0 100644 --- a/soc/renesas/ra/ra6m4/CMakeLists.txt +++ b/soc/renesas/ra/ra6m4/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -10,4 +10,21 @@ zephyr_sources( zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + # In ra6m4 ethernet peripheral is always non-secure, even in flat project. + # Use this linker script to place ethernet buffer in non-secure RAM. + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") + + if(CONFIG_OUTPUT_RPD) + # Generate zephyr.rpd file + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${SOC_FULL_DIR}/tools/gen_rpd.py + --kernel ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} + --output-rpd ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd + $<$:--verbose> + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + endif() +else() + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/renesas/ra/ra6m4/Kconfig b/soc/renesas/ra/ra6m4/Kconfig index dec6aba2581e9..89e6dfb300666 100644 --- a/soc/renesas/ra/ra6m4/Kconfig +++ b/soc/renesas/ra/ra6m4/Kconfig @@ -5,6 +5,7 @@ config SOC_SERIES_RA6M4 select ARM select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU + select CPU_HAS_RENESAS_RA_IDAU select HAS_RENESAS_RA_FSP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select CPU_CORTEX_M_HAS_DWT @@ -15,3 +16,4 @@ config SOC_SERIES_RA6M4 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m4/linker.ld b/soc/renesas/ra/ra6m4/linker.ld new file mode 100644 index 0000000000000..3f8937e4c94e4 --- /dev/null +++ b/soc/renesas/ra/ra6m4/linker.ld @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +FLASH_START = CONFIG_FLASH_BASE_ADDRESS; +FLASH_LENGTH = (CONFIG_FLASH_SIZE * 1K); +FLASH_END = FLASH_START + FLASH_LENGTH; + +DATA_FLASH_START = DT_REG_ADDR(DT_NODELABEL(flash1)); +DATA_FLASH_LENGTH = DT_REG_SIZE(DT_NODELABEL(flash1)); +DATA_FLASH_END = DATA_FLASH_START + DATA_FLASH_LENGTH; + +RAM_START = CONFIG_SRAM_BASE_ADDRESS; +RAM_LENGTH = (CONFIG_SRAM_SIZE * 1K); +RAM_END = RAM_START + RAM_LENGTH; + +ETH_BUFFER_LENGTH = ((CONFIG_ETH_RENESAS_TX_BUF_NUM + CONFIG_ETH_RENESAS_RX_BUF_NUM) * 1552); +ETH_BUFFER_START = RAM_START + RAM_LENGTH - ETH_BUFFER_LENGTH; +NS_RAM_REGION_LENGTH = ALIGN(ETH_BUFFER_LENGTH, 8K); +NS_RAM_REGION_START = RAM_START + RAM_LENGTH - NS_RAM_REGION_LENGTH; + +#if !defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_NONSECURE_FIRMWARE) + /* + * Boundaries setting in flat project. + * Set entire code flash as secure. + * Set entire data flash as secure. + * These symbols used by partition tool. + */ + + __FLASH_S = ABSOLUTE(FLASH_START); + __FLASH_NSC = ABSOLUTE(FLASH_END); + __FLASH_NS = ABSOLUTE(FLASH_END); + + __DATA_FLASH_S = ABSOLUTE(DATA_FLASH_START); + __DATA_FLASH_NS = ABSOLUTE(DATA_FLASH_END); + + __RAM_S = ORIGIN(RAM); + __RAM_NSC = ABSOLUTE(NS_RAM_REGION_START); + __RAM_NS = ABSOLUTE(NS_RAM_REGION_START); +#else + /* + * Boundaries setting in TrustZone project is not implemented. + */ +#endif + +SECTIONS +{ + /* Create section in non-secure RAM for ethernet buffer */ + SECTION_PROLOGUE(.ns_buffer,(NOLOAD),) + { + . = ABSOLUTE(ETH_BUFFER_START & 0xFFFFFFE0); + KEEP(*(.ns_buffer*)) + } GROUP_NOLOAD_LINK_IN(RAM, RAM) +} diff --git a/soc/renesas/ra/ra6m5/CMakeLists.txt b/soc/renesas/ra/ra6m5/CMakeLists.txt index f8147e8059102..9fa4169634759 100644 --- a/soc/renesas/ra/ra6m5/CMakeLists.txt +++ b/soc/renesas/ra/ra6m5/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -10,4 +10,21 @@ zephyr_sources( zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + # In ra6m5 ethernet peripheral is always non-secure, even in flat project. + # Use this linker script to place ethernet buffer in non-secure RAM. + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") + + if(CONFIG_OUTPUT_RPD) + # Generate zephyr.rpd file + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${SOC_FULL_DIR}/tools/gen_rpd.py + --kernel ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} + --output-rpd ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd + $<$:--verbose> + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + endif() +else() + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/renesas/ra/ra6m5/Kconfig b/soc/renesas/ra/ra6m5/Kconfig index 792239394c72c..ef8a383948909 100644 --- a/soc/renesas/ra/ra6m5/Kconfig +++ b/soc/renesas/ra/ra6m5/Kconfig @@ -5,6 +5,7 @@ config SOC_SERIES_RA6M5 select ARM select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU + select CPU_HAS_RENESAS_RA_IDAU select HAS_RENESAS_RA_FSP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select CPU_CORTEX_M_HAS_DWT @@ -15,3 +16,4 @@ config SOC_SERIES_RA6M5 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m5/linker.ld b/soc/renesas/ra/ra6m5/linker.ld new file mode 100644 index 0000000000000..3f8937e4c94e4 --- /dev/null +++ b/soc/renesas/ra/ra6m5/linker.ld @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +FLASH_START = CONFIG_FLASH_BASE_ADDRESS; +FLASH_LENGTH = (CONFIG_FLASH_SIZE * 1K); +FLASH_END = FLASH_START + FLASH_LENGTH; + +DATA_FLASH_START = DT_REG_ADDR(DT_NODELABEL(flash1)); +DATA_FLASH_LENGTH = DT_REG_SIZE(DT_NODELABEL(flash1)); +DATA_FLASH_END = DATA_FLASH_START + DATA_FLASH_LENGTH; + +RAM_START = CONFIG_SRAM_BASE_ADDRESS; +RAM_LENGTH = (CONFIG_SRAM_SIZE * 1K); +RAM_END = RAM_START + RAM_LENGTH; + +ETH_BUFFER_LENGTH = ((CONFIG_ETH_RENESAS_TX_BUF_NUM + CONFIG_ETH_RENESAS_RX_BUF_NUM) * 1552); +ETH_BUFFER_START = RAM_START + RAM_LENGTH - ETH_BUFFER_LENGTH; +NS_RAM_REGION_LENGTH = ALIGN(ETH_BUFFER_LENGTH, 8K); +NS_RAM_REGION_START = RAM_START + RAM_LENGTH - NS_RAM_REGION_LENGTH; + +#if !defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_NONSECURE_FIRMWARE) + /* + * Boundaries setting in flat project. + * Set entire code flash as secure. + * Set entire data flash as secure. + * These symbols used by partition tool. + */ + + __FLASH_S = ABSOLUTE(FLASH_START); + __FLASH_NSC = ABSOLUTE(FLASH_END); + __FLASH_NS = ABSOLUTE(FLASH_END); + + __DATA_FLASH_S = ABSOLUTE(DATA_FLASH_START); + __DATA_FLASH_NS = ABSOLUTE(DATA_FLASH_END); + + __RAM_S = ORIGIN(RAM); + __RAM_NSC = ABSOLUTE(NS_RAM_REGION_START); + __RAM_NS = ABSOLUTE(NS_RAM_REGION_START); +#else + /* + * Boundaries setting in TrustZone project is not implemented. + */ +#endif + +SECTIONS +{ + /* Create section in non-secure RAM for ethernet buffer */ + SECTION_PROLOGUE(.ns_buffer,(NOLOAD),) + { + . = ABSOLUTE(ETH_BUFFER_START & 0xFFFFFFE0); + KEEP(*(.ns_buffer*)) + } GROUP_NOLOAD_LINK_IN(RAM, RAM) +} diff --git a/soc/renesas/ra/tools/gen_rpd.py b/soc/renesas/ra/tools/gen_rpd.py new file mode 100644 index 0000000000000..d9e1155ca83f0 --- /dev/null +++ b/soc/renesas/ra/tools/gen_rpd.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Renesas Electronics Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Generate a Renesas Partition Device File (RPD) for RA family + +RFP is used by Renesas Flash Programmer or Renesas Partition Manager. +""" + +import argparse +import os +import sys + +from elftools.elf.elffile import ELFFile + + +def debug(text): + """Display debug message if --verbose""" + if args.verbose: + sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n") + + +def error(text): + """Display error message""" + sys.stderr.write(os.path.basename(sys.argv[0]) + ": " + text + "\n") + + +def exit(text): + """Exit program with an error message""" + sys.exit(os.path.basename(sys.argv[0]) + ": " + text + "\n") + + +class ZephyrElf: + """ + Represents memory symbols in an elf file. + """ + + def __init__(self): + """ + Initialize the IDAU object with given parameters + These values refer to HM under security section + """ + self.ram_s_start = 0 + self.ram_s_size = 0 + self.ram_c_start = 0 + self.ram_c_size = 0 + self.flash_s_start = 0 + self.flash_s_size = 0 + self.flash_c_start = 0 + self.flash_c_size = 0 + self.data_flash_s_start = 0 + self.data_flash_s_size = 0 + + def read_symbol(self, symbols, name): + """Reads a symbols from symbol table and returns its address""" + try: + sym = symbols.get_symbol_by_name(name) + address = sym[0]["st_value"] + except Exception as e: + error(f"Could not find symbol {name} in ELF file {e}") + debug(f"Found symbol {name} at 0x{address:x}") + return address + + def parse(self, path): + """Reads IDAU configuration from elf file""" + if not os.path.exists(path): + exit("Invalid kernel path") + + with open(path, "rb") as f: + elf = ELFFile(f) + try: + symtab = elf.get_section_by_name(".symtab") + # Read memory symbols + code_flash_s = self.read_symbol(symtab, "__FLASH_S") + code_flash_nsc = self.read_symbol(symtab, "__FLASH_NSC") + code_flash_ns = self.read_symbol(symtab, "__FLASH_NS") + data_flash_s = self.read_symbol(symtab, "__DATA_FLASH_S") + data_flash_ns = self.read_symbol(symtab, "__DATA_FLASH_NS") + sram_s = self.read_symbol(symtab, "__RAM_S") + sram_nsc = self.read_symbol(symtab, "__RAM_NSC") + sram_ns = self.read_symbol(symtab, "__RAM_NS") + + self.ram_s_start = sram_s + self.ram_s_size = sram_nsc - sram_s + self.ram_c_start = sram_nsc + self.ram_c_size = sram_ns - sram_nsc + + self.flash_s_start = code_flash_s + self.flash_s_size = code_flash_nsc - code_flash_s + self.flash_c_start = code_flash_nsc + self.flash_c_size = code_flash_ns - code_flash_nsc + + self.data_flash_s_start = data_flash_s + self.data_flash_s_size = data_flash_ns - data_flash_s + + except Exception as e: + exit(f"Could not find symbol table in ELF file {e}") + + +def parse_args(): + """Parse command line arguments""" + global args + + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + allow_abbrev=False, + ) + + parser.add_argument("-k", "--kernel", required=True, help="Zephyr kernel image") + parser.add_argument( + "-v", "--verbose", action="store_true", help="Print extra debugging information" + ) + parser.add_argument("-o", "--output-rpd", required=True, help="output RPD file") + + args = parser.parse_args() + + +def main(): + parse_args() + + # Read boundary setting from elf file + elf_parser = ZephyrElf() + elf_parser.parse(args.kernel) + + with open(args.output_rpd, "w") as rpd: + rpd.write(f"RAM_S_START=0x{elf_parser.ram_s_start:X}\n") + rpd.write(f"RAM_S_SIZE=0x{elf_parser.ram_s_size:X}\n") + rpd.write(f"RAM_C_START=0x{elf_parser.ram_c_start:X}\n") + rpd.write(f"RAM_C_SIZE=0x{elf_parser.ram_c_size:X}\n") + + rpd.write(f"FLASH_S_START=0x{elf_parser.flash_s_start:X}\n") + rpd.write(f"FLASH_S_SIZE=0x{elf_parser.flash_s_size:X}\n") + rpd.write(f"FLASH_C_START=0x{elf_parser.flash_c_start:X}\n") + rpd.write(f"FLASH_C_SIZE=0x{elf_parser.flash_c_size:X}\n") + + rpd.write(f"DATA_FLASH_S_START=0x{elf_parser.data_flash_s_start:X}\n") + rpd.write(f"DATA_FLASH_S_SIZE=0x{elf_parser.data_flash_s_size:X}\n") + + +if __name__ == "__main__": + main() From 652d822203ee707514d01a5de80ee90d5b5c08a0 Mon Sep 17 00:00:00 2001 From: Ta Minh Nhat Date: Fri, 11 Apr 2025 17:56:27 +0700 Subject: [PATCH 0179/1076] west: runner: rfp: support memory partition for rfp runner Add rfp runner support for ek_ra6m4 and ek_ra6m5. Add memory partition for rfp runner. Signed-off-by: Ta Minh Nhat --- boards/renesas/ek_ra6m4/board.cmake | 6 ++ boards/renesas/ek_ra6m5/board.cmake | 6 ++ scripts/west_commands/runners/rfp.py | 28 +++++++ scripts/west_commands/tests/test_rfp.py | 107 +++++++++++++++++++++++- 4 files changed, 146 insertions(+), 1 deletion(-) diff --git a/boards/renesas/ek_ra6m4/board.cmake b/boards/renesas/ek_ra6m4/board.cmake index e6b80a0fddd51..7ccecc26e799f 100644 --- a/boards/renesas/ek_ra6m4/board.cmake +++ b/boards/renesas/ek_ra6m4/board.cmake @@ -3,6 +3,12 @@ board_runner_args(jlink "--device=R7FA6M4AF") board_runner_args(pyocd "--target=R7FA6M4AF") +if(CONFIG_OUTPUT_RPD) + board_runner_args(rfp "--device=RA" "--tool=jlink" "--interface=swd" "--erase" "--rpd-file=${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd") +else() + board_runner_args(rfp "--device=RA" "--tool=jlink" "--interface=swd" "--erase") +endif() include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/rfp.board.cmake) diff --git a/boards/renesas/ek_ra6m5/board.cmake b/boards/renesas/ek_ra6m5/board.cmake index aecd6957c40a9..aab8f4e14acc0 100644 --- a/boards/renesas/ek_ra6m5/board.cmake +++ b/boards/renesas/ek_ra6m5/board.cmake @@ -3,6 +3,12 @@ board_runner_args(jlink "--device=R7FA6M5BH") board_runner_args(pyocd "--target=R7FA6M5BH") +if(CONFIG_OUTPUT_RPD) + board_runner_args(rfp "--device=RA" "--tool=jlink" "--interface=swd" "--erase" "--rpd-file=${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd") +else() + board_runner_args(rfp "--device=RA" "--tool=jlink" "--interface=swd" "--erase") +endif() include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/rfp.board.cmake) diff --git a/scripts/west_commands/runners/rfp.py b/scripts/west_commands/runners/rfp.py index 0e885b9805b58..f619f151570be 100644 --- a/scripts/west_commands/runners/rfp.py +++ b/scripts/west_commands/runners/rfp.py @@ -46,6 +46,7 @@ def __init__( port=DEFAULT_RFP_PORT, tool=None, interface=None, + rpd_file=None, speed=None, ): super().__init__(cfg) @@ -57,6 +58,7 @@ def __init__( self.tool = tool self.interface = interface self.device = device + self.rpd_file = rpd_file self.speed = speed @classmethod @@ -88,6 +90,10 @@ def do_add_parser(cls, parser): '--interface', help='selects the communications interface (uart, swd)', ) + parser.add_argument( + '--rpd-file', + help='path to renesas partition data zephyr.rpd', + ) parser.add_argument('--device', help='Specify the device type to pass to rfp-cli') parser.add_argument('--verify', action='store_true', help='if given, verify after flash') parser.add_argument('--speed', help='Specify the serial port speed') @@ -101,6 +107,7 @@ def do_create(cls, cfg, args): port=args.port, tool=args.tool, interface=args.interface, + rpd_file=args.rpd_file, erase=args.erase, speed=args.speed, verify=args.verify, @@ -126,6 +133,9 @@ def default_rfp(): def do_run(self, command, **kwargs): if command == 'flash': + if self.rpd_file is not None: + self.do_partition(**kwargs) + self.do_flash(**kwargs) else: self.logger.error("Unsuppported command") @@ -165,3 +175,21 @@ def do_flash(self, **kwargs): cmd = self.rfp_cmd + connection + device + load_image self.check_call(cmd) + + def do_partition(self): + self.require(self.rfp_cmd[0]) + + rpd_path = self.rpd_file + + self.logger.info(f'Partition file: {rpd_path}') + + device = ['-device', self.device] + + connection = ['-tool', self.tool] + + flash_option = ['-fo'] + flash_option += ['boundary-file', rpd_path] + flash_option += ['-p'] + + cmd = self.rfp_cmd + device + connection + flash_option + self.check_call(cmd) diff --git a/scripts/west_commands/tests/test_rfp.py b/scripts/west_commands/tests/test_rfp.py index 9d27a5b1a8c27..3a2dd38147c4a 100644 --- a/scripts/west_commands/tests/test_rfp.py +++ b/scripts/west_commands/tests/test_rfp.py @@ -11,8 +11,11 @@ TEST_RFP_PORT = 'test-rfp-serial' TEST_RFP_PORT_SPEED = '115200' +TEST_RFP_TOOL = 'jlink' +TEST_RFP_INTERFACE = 'swd' TEST_RFP_DEVICE = 'RA' TEST_RFP_USR_LOCAL_RFP_CLI = '/usr/local/bin/rfp-cli' +TEST_RFP_RPD_FILE = 'test-zephyr.rpd' EXPECTED_COMMANDS = [ [ @@ -93,6 +96,37 @@ ], ] +EXPECTED_COMMANDS_WITH_JLINK_HARDWARE = [ + [ + TEST_RFP_USR_LOCAL_RFP_CLI, + '-tool', + TEST_RFP_TOOL, + '-interface', + TEST_RFP_INTERFACE, + '-device', + TEST_RFP_DEVICE, + '-run', + '-erase', + '-p', + '-file', + RC_KERNEL_HEX, + ], +] + +EXPECTED_COMMANDS_WITH_PARTITION_DATA = [ + [ + TEST_RFP_USR_LOCAL_RFP_CLI, + '-device', + TEST_RFP_DEVICE, + '-tool', + TEST_RFP_TOOL, + '-fo', + 'boundary-file', + TEST_RFP_RPD_FILE, + '-p', + ], +] + def require_patch(program): assert program in ['rfp', 'rfp-cli', TEST_RFP_USR_LOCAL_RFP_CLI] @@ -102,7 +136,7 @@ def require_patch(program): def os_path_isfile_patch(filename): - if filename == RC_KERNEL_HEX: + if filename == RC_KERNEL_HEX or TEST_RFP_RPD_FILE: return True return os_path_isfile(filename) @@ -260,3 +294,74 @@ def test_rfp_create_with_rfp_cli(dr, cc, req, runner_config, tmpdir): with patch('os.path.isfile', side_effect=os_path_isfile_patch): runner.run('flash') assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS_WITH_RFP_CLI] + + +@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) +@patch('runners.core.ZephyrBinaryRunner.check_call') +@patch('runners.rfp.RfpBinaryRunner.default_rfp') +def test_rfp_create_with_jlink_hardware(dr, cc, req, runner_config, tmpdir): + """ + Test commands using a jlink hardware. + + Input: + --rfp-cli /usr/local/bin/rfp-cli + + Output: + /usr/local/bin/rfp-cli + """ + args = [ + '--device', + str(TEST_RFP_DEVICE), + '--tool', + str(TEST_RFP_TOOL), + '--interface', + str(TEST_RFP_INTERFACE), + '--erase', + '--rfp-cli', + str(TEST_RFP_USR_LOCAL_RFP_CLI), + ] + parser = argparse.ArgumentParser(allow_abbrev=False) + RfpBinaryRunner.add_parser(parser) + arg_namespace = parser.parse_args(args) + runner = RfpBinaryRunner.create(runner_config, arg_namespace) + with patch('os.path.isfile', side_effect=os_path_isfile_patch): + runner.run('flash') + assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS_WITH_JLINK_HARDWARE] + + +@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) +@patch('runners.core.ZephyrBinaryRunner.check_call') +@patch('runners.rfp.RfpBinaryRunner.default_rfp') +def test_rfp_create_with_partition_data(dr, cc, req, runner_config, tmpdir): + """ + Test commands using reresas partition data. + + Input: + --rfp-cli /usr/local/bin/rfp-cli + + Output: + /usr/local/bin/rfp-cli + """ + args = [ + '--device', + str(TEST_RFP_DEVICE), + '--tool', + str(TEST_RFP_TOOL), + '--interface', + str(TEST_RFP_INTERFACE), + '--rpd-file', + str(TEST_RFP_RPD_FILE), + '--erase', + '--rfp-cli', + str(TEST_RFP_USR_LOCAL_RFP_CLI), + ] + parser = argparse.ArgumentParser(allow_abbrev=False) + RfpBinaryRunner.add_parser(parser) + arg_namespace = parser.parse_args(args) + print(runner_config) + runner = RfpBinaryRunner.create(runner_config, arg_namespace) + with patch('os.path.isfile', side_effect=os_path_isfile_patch): + runner.run('flash') + print(cc.call_args_list) + assert [cc.call_args_list[0]] == [call(x) for x in EXPECTED_COMMANDS_WITH_PARTITION_DATA] + assert [cc.call_args_list[1]] == [call(x) for x in EXPECTED_COMMANDS_WITH_JLINK_HARDWARE] From 23fdb9e0700330b9c70ab9082f1abb6af65dd1ac Mon Sep 17 00:00:00 2001 From: Ta Minh Nhat Date: Fri, 11 Apr 2025 18:05:42 +0700 Subject: [PATCH 0180/1076] board: renesas: Add ethernet support for ek_ra6m4 and ek_ra6m5 Add ethernet support for ek_ra6m4, ek_ra6m5. Signed-off-by: Ta Minh Nhat --- boards/renesas/ek_ra6m4/Kconfig.defconfig | 16 ++++++++ boards/renesas/ek_ra6m4/doc/index.rst | 37 ++++++++++++++++++- boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi | 16 ++++++++ boards/renesas/ek_ra6m4/ek_ra6m4.dts | 18 +++++++++ boards/renesas/ek_ra6m5/Kconfig.defconfig | 16 ++++++++ boards/renesas/ek_ra6m5/doc/index.rst | 37 ++++++++++++++++++- boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi | 16 ++++++++ boards/renesas/ek_ra6m5/ek_ra6m5.dts | 18 +++++++++ 8 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 boards/renesas/ek_ra6m4/Kconfig.defconfig create mode 100644 boards/renesas/ek_ra6m5/Kconfig.defconfig diff --git a/boards/renesas/ek_ra6m4/Kconfig.defconfig b/boards/renesas/ek_ra6m4/Kconfig.defconfig new file mode 100644 index 0000000000000..823d16c796cfb --- /dev/null +++ b/boards/renesas/ek_ra6m4/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EK_RA6M4 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +config OUTPUT_RPD + default y + +endif # NETWORKING + +endif # BOARD_EK_RA6M4 diff --git a/boards/renesas/ek_ra6m4/doc/index.rst b/boards/renesas/ek_ra6m4/doc/index.rst index 2dce8bb0fc632..d954c2b8156a6 100644 --- a/boards/renesas/ek_ra6m4/doc/index.rst +++ b/boards/renesas/ek_ra6m4/doc/index.rst @@ -89,6 +89,28 @@ built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. +.. note:: + + In applications using ethernet, ethernet buffers must be placed in non-secure RAM. + This requires configuration of the Implementation Defined Attribution Unit (IDAU), + which must be applied by partition memory using Renesas Flash Programmer. + +Partition Memory +================ + +Renesas Flash Programmer is available at (`Renesas Flash Programmer Download`_). +Once downloaded and installed, check rfp-cli is available or set rfp-cli path manually. + +Renesas partition data file will be available at build/zephyr/zephyr.rpd. +Connect jumper J6 then run Renesas Flash Programmer. + +To partition memory manually, execute: + + .. code-block:: console + + # From the root of the zephyr repository + rfp-cli -device ra -tool jlink -fo boundary-file build/zephyr/zephyr.rpd -p + Flashing ======== @@ -101,12 +123,18 @@ To flash the program to board 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M4 - User's Manual`_ -3. Execute west command +3. Execute west command to flash using jlink runner .. code-block:: console west flash -r jlink +4. Or flash using rfp runner, this will partition memory then flash zephyr image. + + .. code-block:: console + + west flash -r rfp + Debugging ========= @@ -128,6 +156,7 @@ References ********** - `EK-RA6M4 Website`_ - `RA6M4 MCU group Website`_ +- `RA6 Ethernet Controller configuration`_ .. _EK-RA6M4 Website: https://www.renesas.com/us/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m4-evaluation-kit-ra6m4-mcu-group @@ -143,3 +172,9 @@ References .. _Segger Ozone Download: https://www.segger.com/downloads/jlink#Ozone + +.. _Renesas Flash Programmer Download: + https://www.renesas.com/en/software-tool/renesas-flash-programmer-programming-gui + +.. _RA6 Ethernet Controller configuration: + https://www.renesas.com/en/blogs/configuration-issues-ra6-ethernet-controller#document diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi index 0abb9ba3402e1..386bba98e2f31 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi @@ -70,4 +70,20 @@ drive-strength = "high"; }; }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.dts b/boards/renesas/ek_ra6m4/ek_ra6m4.dts index 19a1ecfc2aa95..f9626c4d3ba68 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.dts +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.dts @@ -290,3 +290,21 @@ arduino_spi: &spi0 {}; &wdt { status = "okay"; }; + +ð { + local-mac-address = [74 90 50 B0 6D 5D]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra6m5/Kconfig.defconfig b/boards/renesas/ek_ra6m5/Kconfig.defconfig new file mode 100644 index 0000000000000..f1d9177c32091 --- /dev/null +++ b/boards/renesas/ek_ra6m5/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EK_RA6M5 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +config OUTPUT_RPD + default y + +endif # NETWORKING + +endif # BOARD_EK_RA6M5 diff --git a/boards/renesas/ek_ra6m5/doc/index.rst b/boards/renesas/ek_ra6m5/doc/index.rst index 4d3691ee6f968..996a1c0c10f08 100644 --- a/boards/renesas/ek_ra6m5/doc/index.rst +++ b/boards/renesas/ek_ra6m5/doc/index.rst @@ -87,6 +87,28 @@ built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. +.. note:: + + In applications using ethernet, ethernet buffers must be placed in non-secure RAM. + This requires configuration of the Implementation Defined Attribution Unit (IDAU), + which must be applied by partition memory using Renesas Flash Programmer. + +Partition Memory +================ + +Renesas Flash Programmer is available at (`Renesas Flash Programmer Download`_). +Once downloaded and installed, check rfp-cli is available or set rfp-cli path manually. + +Renesas partition data file will be available at build/zephyr/zephyr.rpd. +Connect jumper J6 then run Renesas Flash Programmer. + +To partition memory manually, execute: + + .. code-block:: console + + # From the root of the zephyr repository + rfp-cli -device ra -tool jlink -fo boundary-file build/zephyr/zephyr.rpd -p + Flashing ======== @@ -99,12 +121,18 @@ To flash the program to board 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M5 - User's Manual`_ -3. Execute west command +3. Execute west command to flash using jlink runner .. code-block:: console west flash -r jlink +4. Or flash using rfp runner, this will partition memory then flash zephyr image. + + .. code-block:: console + + west flash -r rfp + Debugging ========= @@ -126,6 +154,7 @@ References ********** - `EK-RA6M5 Website`_ - `RA6M5 MCU group Website`_ +- `RA6 Ethernet Controller configuration`_ .. _EK-RA6M5 Website: https://www.renesas.com/us/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m5-evaluation-kit-ra6m5-mcu-group @@ -141,3 +170,9 @@ References .. _Segger Ozone Download: https://www.segger.com/downloads/jlink#Ozone + +.. _Renesas Flash Programmer Download: + https://www.renesas.com/en/software-tool/renesas-flash-programmer-programming-gui + +.. _RA6 Ethernet Controller configuration: + https://www.renesas.com/en/blogs/configuration-issues-ra6-ethernet-controller#document diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi index 22d8aae8184fb..c3aa33e07fe96 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi @@ -77,4 +77,20 @@ drive-strength = "high"; }; }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5.dts b/boards/renesas/ek_ra6m5/ek_ra6m5.dts index d02ff32608da6..4e19851ad9663 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5.dts +++ b/boards/renesas/ek_ra6m5/ek_ra6m5.dts @@ -291,3 +291,21 @@ arduino_spi: &spi0 {}; &wdt { status = "okay"; }; + +ð { + local-mac-address = [74 90 50 B0 6D 5C]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0>; + status = "okay"; + }; +}; From d71b4a1938fa6d642a97bdad63cbf996289014a2 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Sun, 22 Jun 2025 16:16:07 +0700 Subject: [PATCH 0181/1076] boards: shields: add support for rtk0eg0019b01002bj shield Add Capacitive Touch Application Board RTK0EG0019B01002BJ Signed-off-by: The Nguyen --- .../rtk0eg0019b01002bj/Kconfig.defconfig | 10 ++ .../shields/rtk0eg0019b01002bj/Kconfig.shield | 5 + .../doc/img/rtk0eg0019b01002bj.webp | Bin 0 -> 32580 bytes .../shields/rtk0eg0019b01002bj/doc/index.rst | 110 ++++++++++++++++++ .../rtk0eg0019b01002bj.overlay | 92 +++++++++++++++ boards/shields/rtk0eg0019b01002bj/shield.yml | 7 ++ .../gpio/renesas-rtk0eg0019b01002bj.h | 20 ++++ 7 files changed, 244 insertions(+) create mode 100644 boards/shields/rtk0eg0019b01002bj/Kconfig.defconfig create mode 100644 boards/shields/rtk0eg0019b01002bj/Kconfig.shield create mode 100644 boards/shields/rtk0eg0019b01002bj/doc/img/rtk0eg0019b01002bj.webp create mode 100644 boards/shields/rtk0eg0019b01002bj/doc/index.rst create mode 100644 boards/shields/rtk0eg0019b01002bj/rtk0eg0019b01002bj.overlay create mode 100644 boards/shields/rtk0eg0019b01002bj/shield.yml create mode 100644 include/zephyr/dt-bindings/gpio/renesas-rtk0eg0019b01002bj.h diff --git a/boards/shields/rtk0eg0019b01002bj/Kconfig.defconfig b/boards/shields/rtk0eg0019b01002bj/Kconfig.defconfig new file mode 100644 index 0000000000000..2da067cd79a92 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if INPUT_RENESAS_RA_CTSU + +config INPUT_RENESAS_RA_CTSU_NUM_SELF_ELEMENTS + default 12 + depends on !INPUT_RENESAS_RA_QE_TOUCH_CFG + +endif # INPUT_RENESAS_RA_CTSU diff --git a/boards/shields/rtk0eg0019b01002bj/Kconfig.shield b/boards/shields/rtk0eg0019b01002bj/Kconfig.shield new file mode 100644 index 0000000000000..7d5e30c1e4245 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RTK0EG0019B01002BJ + def_bool $(shields_list_contains,rtk0eg0019b01002bj) diff --git a/boards/shields/rtk0eg0019b01002bj/doc/img/rtk0eg0019b01002bj.webp b/boards/shields/rtk0eg0019b01002bj/doc/img/rtk0eg0019b01002bj.webp new file mode 100644 index 0000000000000000000000000000000000000000..371248495a84ee52a5a0aaca5b4e414e98a397e4 GIT binary patch literal 32580 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 T`@8rb<2SMWwRp#0)Be8z(ngas literal 0 HcmV?d00001 diff --git a/boards/shields/rtk0eg0019b01002bj/doc/index.rst b/boards/shields/rtk0eg0019b01002bj/doc/index.rst new file mode 100644 index 0000000000000..83fa5d1b73910 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/doc/index.rst @@ -0,0 +1,110 @@ +.. _rtk0eg0019b01002bj: + +RTK0EG0019B01002BJ Capacitive Touch Application Shield +###################################################### + +Overview +******** + +The RTK0EG0019B01002BJ Capacitive Touch Application Shield is designed to work with the Renesas +Capacitive Touch Evaluation Kit. + +The shield features a variety of touch sensors, including buttons, sliders, and wheels, making it +an ideal platform for developing touch-based applications. + +.. figure:: img/rtk0eg0019b01002bj.webp + :width: 300 + :align: center + + RTK0EG0019B01002BJ Capacitive Touch Application Shield (Credit: Renesas Electronics Corporation) + +Pins Assignment of the RTK0EG0019B01002BJ Shield +================================================ + +Application Header 1 (CN1) +-------------------------- + ++---------+-------------+---------+-------------+ +| CN1 Pin | Function | CN1 Pin | Function | ++=========+=============+=========+=============+ +| 15 | VCC | 16 | GND | ++---------+-------------+---------+-------------+ +| 13 | LED_ROW0 | 14 | LED_ROW1 | ++---------+-------------+---------+-------------+ +| 11 | LED_ROW2 | 12 | LED_ROW3 | ++---------+-------------+---------+-------------+ +| 9 | N/C | 10 | N/C | ++---------+-------------+---------+-------------+ +| 7 | LED_COL3 | 8 | N/C | ++---------+-------------+---------+-------------+ +| 5 | LED_COL1 | 6 | LED_COL2 | ++---------+-------------+---------+-------------+ +| 3 | N/C | 4 | LED_COL0 | ++---------+-------------+---------+-------------+ +| 1 | N/C | 2 | N/C | ++---------+-------------+---------+-------------+ + +Application Header 2 (CN2) +-------------------------- + ++---------+-------------------+---------+-------------------+ +| CN2 Pin | Touch Electrode | CN2 Pin | Touch Electrode | ++=========+===================+=========+===================+ +| 39 | N/C | 40 | TSCAP | ++---------+-------------------+---------+-------------------+ +| 37 | N/C | 38 | N/C | ++---------+-------------------+---------+-------------------+ +| 35 | N/C | 36 | TS-W1 | ++---------+-------------------+---------+-------------------+ +| 33 | N/C | 34 | TS-W2 | ++---------+-------------------+---------+-------------------+ +| 31 | TS-W3 | 32 | N/C | ++---------+-------------------+---------+-------------------+ +| 29 | N/C | 30 | N/C | ++---------+-------------------+---------+-------------------+ +| 27 | N/C | 28 | TS-W4 | ++---------+-------------------+---------+-------------------+ +| 25 | N/C | 26 | N/C | ++---------+-------------------+---------+-------------------+ +| 23 | N/C | 24 | N/C | ++---------+-------------------+---------+-------------------+ +| 21 | N/C | 22 | SHIELD-W1 | ++---------+-------------------+---------+-------------------+ +| 19 | N/C | 20 | N/C | ++---------+-------------------+---------+-------------------+ +| 17 | N/C | 18 | N/C | ++---------+-------------------+---------+-------------------+ +| 15 | N/C | 16 | N/C | ++---------+-------------------+---------+-------------------+ +| 13 | N/C | 14 | N/C | ++---------+-------------------+---------+-------------------+ +| 11 | N/C | 12 | N/C | ++---------+-------------------+---------+-------------------+ +| 9 | TS-B1 | 10 | TS-B2 | ++---------+-------------------+---------+-------------------+ +| 7 | SHIELD-B1 | 8 | TS-B3 | ++---------+-------------------+---------+-------------------+ +| 5 | TS-S1 | 6 | SHIELD-S1 | ++---------+-------------------+---------+-------------------+ +| 3 | TS-S3 | 4 | TS-S2 | ++---------+-------------------+---------+-------------------+ +| 1 | TS-S5 | 2 | TS-S4 | ++---------+-------------------+---------+-------------------+ + +Programming +*********** + +Set ``--shield rtk0eg0019b01002bj`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/shields/rtk0eg0019b01002bj + :board: rssk_ra2l1 + :shield: rtk0eg0019b01002bj + :goals: build + +References +********** +- `Capacitive Touch Evaluation System for RA2L1`_ + +.. _Capacitive Touch Evaluation System for RA2L1: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/rtk0eg0022s01001bj-capacitive-touch-evaluation-system-ra2l1 diff --git a/boards/shields/rtk0eg0019b01002bj/rtk0eg0019b01002bj.overlay b/boards/shields/rtk0eg0019b01002bj/rtk0eg0019b01002bj.overlay new file mode 100644 index 0000000000000..3bdf0c34b5f60 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/rtk0eg0019b01002bj.overlay @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + rtk0eg0019b01002bj_cn1: rtk0eg0019b01002bj-cn1 { + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + }; + + zephyr,user { + rtk0eg0019b01002bj-led-row-gpios = + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_ROW0 GPIO_ACTIVE_LOW>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_ROW1 GPIO_ACTIVE_LOW>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_ROW2 GPIO_ACTIVE_LOW>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_ROW3 GPIO_ACTIVE_LOW>; + rtk0eg0019b01002bj-led-col-gpios = + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_COL0 GPIO_ACTIVE_HIGH>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_COL1 GPIO_ACTIVE_HIGH>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_COL2 GPIO_ACTIVE_HIGH>, + <&rtk0eg0019b01002bj_cn1 RTK0EG0019B01002BJ_CN1_LED_COL3 GPIO_ACTIVE_HIGH>; + }; +}; + +&rtk0eg0019b01002bj_ctsu { + status = "okay"; + + group1 { + ctsuchac = <0x01 0x0E 0x00 0x00 0x00>; + ctsuchtrc = <0x01 0x00 0x00 0x00 0x00>; + rx-count = <3>; + tx-count = <0>; + status = "okay"; + + rtk0eg0019b01002bj_bt1: button1 { + compatible = "renesas,ra-ctsu-button"; + elements = <2>; + event-code = ; + status = "okay"; + }; + + rtk0eg0019b01002bj_bt2: button2 { + compatible = "renesas,ra-ctsu-button"; + elements = <1>; + event-code = ; + status = "okay"; + }; + + rtk0eg0019b01002bj_bt3: button3 { + compatible = "renesas,ra-ctsu-button"; + elements = <0>; + event-code = ; + status = "okay"; + }; + }; + + group2 { + ctsuchac = <0xF4 0x01 0x00 0x00 0x00>; + ctsuchtrc = <0x00 0x01 0x00 0x00 0x00>; + rx-count = <5>; + tx-count = <0>; + status = "okay"; + + rtk0eg0019b01002bj_slider: slider { + compatible = "renesas,ra-ctsu-slider"; + elements = <1>, <0>, <2>, <4>, <3>; + threshold = <703>; + event-code = ; + status = "okay"; + }; + }; + + group3 { + ctsuchac = <0x00 0x40 0xA4 0x00 0x01>; + ctsuchtrc = <0x00 0x40 0x00 0x00 0x00>; + rx-count = <4>; + tx-count = <0>; + status = "okay"; + + rtk0eg0019b01002bj_wheel: wheel { + compatible = "renesas,ra-ctsu-wheel"; + elements = <0>, <1>, <2>, <3>; + event-code = ; + status = "okay"; + }; + }; +}; diff --git a/boards/shields/rtk0eg0019b01002bj/shield.yml b/boards/shields/rtk0eg0019b01002bj/shield.yml new file mode 100644 index 0000000000000..fe1b02b9ed3a9 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/shield.yml @@ -0,0 +1,7 @@ +shield: + name: rtk0eg0019b01002bj + full_name: RTK0EG0019B01002BJ Capacitive Touch Application Shield + vendor: renesas + supported_features: + - input + - gpio diff --git a/include/zephyr/dt-bindings/gpio/renesas-rtk0eg0019b01002bj.h b/include/zephyr/dt-bindings/gpio/renesas-rtk0eg0019b01002bj.h new file mode 100644 index 0000000000000..e4ccdc6cdb68f --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/renesas-rtk0eg0019b01002bj.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RTK0EG0019B01002BJ_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RTK0EG0019B01002BJ_H_ + +#define RTK0EG0019B01002BJ_CN1_LED_ROW0 13 +#define RTK0EG0019B01002BJ_CN1_LED_ROW1 14 +#define RTK0EG0019B01002BJ_CN1_LED_ROW2 11 +#define RTK0EG0019B01002BJ_CN1_LED_ROW3 12 + +#define RTK0EG0019B01002BJ_CN1_LED_COL0 4 +#define RTK0EG0019B01002BJ_CN1_LED_COL1 5 +#define RTK0EG0019B01002BJ_CN1_LED_COL2 6 +#define RTK0EG0019B01002BJ_CN1_LED_COL3 7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RTK0EG0019B01002BJ_H_ */ From f78752d90211cd96a1762319c4d6c5bd4e97d74d Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Wed, 25 Jun 2025 12:44:17 +0700 Subject: [PATCH 0182/1076] boards: renesas: rssk_ra2l1: enable Cap Touch Shield support This commit to enable rssk_ra2l1 build with rtk0eg0019b01002bj shield. Signed-off-by: The Nguyen --- .../rssk_ra2l1/rssk_ra2l1-pinctrl.dtsi | 21 +++++ boards/renesas/rssk_ra2l1/rssk_ra2l1.dts | 45 ++++++++++ .../rtk0eg0019b01002bj/boards/rssk_ra2l1.conf | 4 + .../boards/rssk_ra2l1.overlay | 83 +++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.conf create mode 100644 boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.overlay diff --git a/boards/renesas/rssk_ra2l1/rssk_ra2l1-pinctrl.dtsi b/boards/renesas/rssk_ra2l1/rssk_ra2l1-pinctrl.dtsi index 8002bddb3475a..2602d22f2f70b 100644 --- a/boards/renesas/rssk_ra2l1/rssk_ra2l1-pinctrl.dtsi +++ b/boards/renesas/rssk_ra2l1/rssk_ra2l1-pinctrl.dtsi @@ -12,4 +12,25 @@ ; }; }; + + ctsu_default: ctsu_default { + group1 { + psels = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; + }; }; diff --git a/boards/renesas/rssk_ra2l1/rssk_ra2l1.dts b/boards/renesas/rssk_ra2l1/rssk_ra2l1.dts index 101dd455936bf..4998b0948b6fb 100644 --- a/boards/renesas/rssk_ra2l1/rssk_ra2l1.dts +++ b/boards/renesas/rssk_ra2l1/rssk_ra2l1.dts @@ -12,6 +12,7 @@ #include #include +#include #include "rssk_ra2l1-pinctrl.dtsi" / { @@ -62,6 +63,28 @@ sw1 = &button1; watchdog0 = &wdt; }; + + rtk0eg0019b01002bj_cn1: rtk0eg0019b01002bj-cn1 { + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , + ; + }; +}; + +&ioport0 { + status = "okay"; +}; + +&ioport1 { + status = "okay"; }; &ioport2 { @@ -72,6 +95,18 @@ status = "okay"; }; +&ioport4 { + status = "okay"; +}; + +&ioport5 { + status = "okay"; +}; + +&ioport7 { + status = "okay"; +}; + &port_irq0 { interrupts = <8 3>; status = "okay"; @@ -98,3 +133,13 @@ &wdt { status = "okay"; }; + +&ctsu { + pinctrl-0 = <&ctsu_default>; + pinctrl-names = "default"; + interrupts = <5 3>, <6 3>, <7 3>; + interrupt-names = "ctsuwr", "ctsurd", "ctsufn"; + tscap-gpios = <&ioport1 12 0>; +}; + +rtk0eg0019b01002bj_ctsu: &ctsu {}; diff --git a/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.conf b/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.conf new file mode 100644 index 0000000000000..e4cd90fa23eb0 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_INPUT_RENESAS_RA_DEVICE_VCC=5000 diff --git a/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.overlay b/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.overlay new file mode 100644 index 0000000000000..f33505d135e15 --- /dev/null +++ b/boards/shields/rtk0eg0019b01002bj/boards/rssk_ra2l1.overlay @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rtk0eg0019b01002bj_ctsu { + clock-div = <1>; + pwr-supply-sel = "internal-power"; + pwr-supply-sel2 = "pwr-supply-sel"; + atune1 = "normal"; + atune12 = <40>; + measure-mode = "self-multi-scan"; + po-sel = "same-pulse"; + status = "okay"; + + group1 { + ssdiv = "4.00", "4.00", "4.00"; + so = <0x03B>, <0x059>, <0x049>; + snum = <0x07>, <0x07>, <0x07>; + sdpa = <0x0F>, <0x0F>, <0x0F>; + num-moving-avg = <4>; + on-freq = <3>; + off-freq = <3>; + drift-freq = <255>; + cancel-freq = <0>; + status = "okay"; + + button1 { + threshold = <769>; + hysteresis = <38>; + status = "okay"; + }; + + button2 { + threshold = <740>; + hysteresis = <37>; + status = "okay"; + }; + + button3 { + threshold = <784>; + hysteresis = <39>; + status = "okay"; + }; + }; + + group2 { + ssdiv = "4.00", "4.00", "4.00", "4.00", "4.00"; + so = <0x02B>, <0x03B>, <0x036>, <0x03B>, <0x03A>; + snum = <0x07>, <0x07>, <0x07>, <0x07>, <0x07>; + sdpa = <0x0F>, <0x0F>, <0x0F>, <0x0F>, <0x0F>; + num-moving-avg = <4>; + on-freq = <3>; + off-freq = <3>; + drift-freq = <255>; + cancel-freq = <0>; + status = "okay"; + + slider { + threshold = <573>; + status = "okay"; + }; + }; + + group3 { + ssdiv = "4.00", "4.00", "4.00", "4.00"; + so = <0x047>, <0x046>, <0x049>, <0x040>; + snum = <0x07>, <0x07>, <0x07>, <0x07>; + sdpa = <0x0F>, <0x0F>, <0x0F>, <0x0F>; + num-moving-avg = <4>; + on-freq = <3>; + off-freq = <3>; + drift-freq = <255>; + cancel-freq = <0>; + status = "okay"; + + wheel { + threshold = <711>; + status = "okay"; + }; + }; +}; From 7ca1eceb3970a5826ff7c0ac7da2a55ad70dfaca Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Sun, 22 Jun 2025 15:38:53 +0700 Subject: [PATCH 0183/1076] samples: shields: add rtk0eg0019b01002bj sample First commit to add rtk0eg0019b01002bj shield sample Signed-off-by: The Nguyen --- .../shields/rtk0eg0019b01002bj/CMakeLists.txt | 13 + samples/shields/rtk0eg0019b01002bj/README.rst | 116 +++++ samples/shields/rtk0eg0019b01002bj/prj.conf | 9 + .../shields/rtk0eg0019b01002bj/sample.yaml | 9 + samples/shields/rtk0eg0019b01002bj/src/main.c | 190 ++++++++ .../rtk0eg0019b01002bj/src/qe_touch_config.c | 407 ++++++++++++++++++ .../rtk0eg0019b01002bj/src/qe_touch_config.h | 27 ++ .../rtk0eg0019b01002bj/src/qe_touch_define.h | 58 +++ 8 files changed, 829 insertions(+) create mode 100644 samples/shields/rtk0eg0019b01002bj/CMakeLists.txt create mode 100644 samples/shields/rtk0eg0019b01002bj/README.rst create mode 100644 samples/shields/rtk0eg0019b01002bj/prj.conf create mode 100644 samples/shields/rtk0eg0019b01002bj/sample.yaml create mode 100644 samples/shields/rtk0eg0019b01002bj/src/main.c create mode 100644 samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.c create mode 100644 samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.h create mode 100644 samples/shields/rtk0eg0019b01002bj/src/qe_touch_define.h diff --git a/samples/shields/rtk0eg0019b01002bj/CMakeLists.txt b/samples/shields/rtk0eg0019b01002bj/CMakeLists.txt new file mode 100644 index 0000000000000..d5f0ae5608398 --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(rtk0eg0019b01002bj) + +target_sources(app PRIVATE src/main.c) + +if(CONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG) + zephyr_include_directories(src) + zephyr_sources(src/qe_touch_config.c) +endif() diff --git a/samples/shields/rtk0eg0019b01002bj/README.rst b/samples/shields/rtk0eg0019b01002bj/README.rst new file mode 100644 index 0000000000000..9bd72e670b1df --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/README.rst @@ -0,0 +1,116 @@ +.. zephyr:code-sample:: rtk0eg0019b01002bj + :name: RTK0EG0019B01002BJ Capacitive Touch Application Shield + :relevant-api: input_interface renesas_ra_ctsu_interface + + Interact with the Capacitive Touch Sensor and LED matrix on the RTK0EG0019B01002BJ shield + +Overview +******** + +This sample demonstrates the usage of the Capacitive Touch Sensor using the +:ref:`rtk0eg0019b01002bj` with `Renesas Capacitive Touch Sensor Solutions`_. + +Requirements +************ + +A Renesas Capacitive Touch Evaluation Kit is needed to run this sample. It includes: + +- A MCU board which support CTSU driver (for example: RSSK-RA2L1). +- A RTK0EG0019B01002BJ Touch Application board. + +Building and Running +******************** + +Build and flash with default settings for shield +================================================ +The :ref:`rtk0eg0019b01002bj` comes with a default DTS configuration that is tuned in advance to +make it ready for development. + +Build and flash as follows, changing ``rssk_ra2l1`` for your board: + +.. zephyr-app-commands:: + :zephyr-app: samples/shields/rtk0eg0019b01002bj + :board: rssk_ra2l1 + :shield: rtk0eg0019b01002bj + :goals: build flash + :compact: + +After startup, all LEDs on the shield will blink 5 times to indicate that the +application has started. + +You can monitor input events through the console output. Additionally, the LED +corresponding to the touched sensor will turn on when you touch it. + +.. code-block:: console + + *** Booting Zephyr OS build v4.1.0-6697-gdc27367ff627 *** + rtk0eg0019b01002bj sample started + I: input event: dev=button1 type= 1 code= 11 value=0 + I: input event: dev=wheel type= 3 code= 8 value=61 + I: input event: dev=wheel type= 3 code= 8 value=67 + I: input event: dev=wheel type= 3 code= 8 value=82 + I: input event: dev=wheel type= 3 code= 8 value=111 + I: input event: dev=wheel type= 3 code= 8 value=124 + I: input event: dev=wheel type= 3 code= 8 value=134 + I: input event: dev=slider type= 3 code= 6 value=0 + I: input event: dev=slider type= 3 code= 6 value=2 + I: input event: dev=slider type= 3 code= 6 value=4 + I: input event: dev=slider type= 3 code= 6 value=6 + I: input event: dev=slider type= 3 code= 6 value=10 + I: input event: dev=slider type= 3 code= 6 value=23 + I: input event: dev=slider type= 3 code= 6 value=26 + I: input event: dev=slider type= 3 code= 6 value=27 + I: input event: dev=slider type= 3 code= 6 value=28 + +(Advanced) Using Configuration Output Generated by Renesas QE Capacitive Touch Workflow +======================================================================================= +This section is for advanced users who do not want to use the default configuration for the Cap +Touch shield and would like to tune configuration parameters manually themselves using the +`Renesas Development Assistance Tool for Capacitive Touch Sensors`_. + +Requirements +------------ + +- `e² studio`_ with Renesas QE Capacitive Touch plugin installed: recommended 2025-04.1 version +- `RA Flexible Software Package`_: recommended FSP v5.8.0 or newer + +Building and flashing with generated tuning code +------------------------------------------------ + + 1. Follow steps 6.1 to 6.5 of `Using QE and FSP to Develop Capacitive Touch Applications`_. + + 2. At step 8 in 6.5 Tuning the Capacitive Touch Interface Using QE for Capacitive Touch Plug-in, + select 'Specify an output folder' and choose this application's subfolder. + + 3. Update the include path to qe_touch_config.h and qe_touch_define.h, and add qe_touch_config.c + to the build sources in your application's CMake. + + 4. Build and flash the application with the command below: + +.. zephyr-app-commands:: + :zephyr-app: samples/shields/rtk0eg0019b01002bj + :board: rssk_ra2l1 + :shield: rtk0eg0019b01002bj + :gen-args: -DCONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG=y + :goals: build flash + :compact: + +References +********** +- `Renesas Capacitive Touch Sensor Solutions`_ +- `Renesas Development Assistance Tool for Capacitive Touch Sensors`_ + +.. _Renesas Capacitive Touch Sensor Solutions: + https://www.renesas.com/en/key-technologies/hmi/capacitive-touch-sensor-solutions + +.. _Renesas Development Assistance Tool for Capacitive Touch Sensors: + https://www.renesas.com/en/software-tool/qe-capacitive-touch-development-assistance-tool-capacitive-touch-sensors + +.. _Using QE and FSP to Develop Capacitive Touch Applications: + https://www.renesas.com/en/document/apn/using-qe-and-fsp-develop-capacitive-touch-applications?r=1170071 + +.. _e² studio: + https://www.renesas.com/en/software-tool/e-studio + +.. _RA Flexible Software Package: + https://www.renesas.com/en/software-tool/flexible-software-package diff --git a/samples/shields/rtk0eg0019b01002bj/prj.conf b/samples/shields/rtk0eg0019b01002bj/prj.conf new file mode 100644 index 0000000000000..12b75f7b1df0b --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/prj.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y + +CONFIG_INPUT=y +CONFIG_INPUT_EVENT_DUMP=y +CONFIG_GPIO=y diff --git a/samples/shields/rtk0eg0019b01002bj/sample.yaml b/samples/shields/rtk0eg0019b01002bj/sample.yaml new file mode 100644 index 0000000000000..3b6911e20ccff --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: RTK0EG0019B01002BJ Capacitive Touch Application Shield +tests: + sample.shields.rtk0eg0019b01002bj: + harness: shield + tags: shield + platform_allow: + - rssk_ra2l1 + extra_args: SHIELD=rtk0eg0019b01002bj diff --git a/samples/shields/rtk0eg0019b01002bj/src/main.c b/samples/shields/rtk0eg0019b01002bj/src/main.c new file mode 100644 index 0000000000000..de9356fdeac72 --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/src/main.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG +#include "qe_touch_config.h" +#endif /* CONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG*/ + +#define BUTTON1 DT_NODELABEL(rtk0eg0019b01002bj_bt1) +#define BUTTON2 DT_NODELABEL(rtk0eg0019b01002bj_bt2) +#define BUTTON3 DT_NODELABEL(rtk0eg0019b01002bj_bt3) +#define SLIDER DT_NODELABEL(rtk0eg0019b01002bj_slider) +#define WHEEL DT_NODELABEL(rtk0eg0019b01002bj_wheel) + +#define QE_TOUCH_CFG1 DT_CHILD(DT_NODELABEL(rtk0eg0019b01002bj_ctsu), group1) +#define QE_TOUCH_CFG2 DT_CHILD(DT_NODELABEL(rtk0eg0019b01002bj_ctsu), group2) +#define QE_TOUCH_CFG3 DT_CHILD(DT_NODELABEL(rtk0eg0019b01002bj_ctsu), group3) + +#define NUM_ROWS DT_PROP_LEN(DT_PATH(zephyr_user), rtk0eg0019b01002bj_led_row_gpios) +#define NUM_COLS DT_PROP_LEN(DT_PATH(zephyr_user), rtk0eg0019b01002bj_led_col_gpios) + +#define LED_MATRIX_ROWS(idx, nodeid) \ + GPIO_DT_SPEC_GET_BY_IDX(nodeid, rtk0eg0019b01002bj_led_row_gpios, idx) +#define LED_MATRIX_COLS(idx, nodeid) \ + GPIO_DT_SPEC_GET_BY_IDX(nodeid, rtk0eg0019b01002bj_led_col_gpios, idx) + +#define BUTTON_LED_NUM (3U) + +#define SLIDER_LED_NUM (5U) +#define SLIDER_RESOLUTION (100) + +#define WHEEL_LED_NUM (8U) +#define WHEEL_RESOLUTION_DEGREE (360) + +static const struct gpio_dt_spec led_row[NUM_ROWS] = { + LISTIFY(NUM_ROWS, LED_MATRIX_ROWS, (,), DT_PATH(zephyr_user)), +}; + +static const struct gpio_dt_spec led_col[NUM_COLS] = { + LISTIFY(NUM_COLS, LED_MATRIX_COLS, (,), DT_PATH(zephyr_user)), +}; + +static const unsigned int wheel_leds_lut[WHEEL_LED_NUM] = {0, 1, 2, 3, 4, 5, 6, 7}; +static const unsigned int slider_leds_lut[SLIDER_LED_NUM] = {8, 9, 10, 11, 12}; +static const unsigned int button_leds_lut[BUTTON_LED_NUM] = {13, 14, 15}; + +static void rtk0eg0019b01002bj_led_output(unsigned int led_idx, bool on) +{ + /* Refer to RTK0EG0022S01001BJ - Design Package for the Touch Application board layout */ + static const unsigned int led_map[NUM_ROWS * NUM_COLS][2] = { + {0, 0}, {1, 0}, {2, 0}, {3, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, + }; + const struct gpio_dt_spec *p_led_row = &led_row[led_map[led_idx][0]]; + const struct gpio_dt_spec *p_led_col = &led_col[led_map[led_idx][1]]; + + gpio_pin_set_dt(p_led_row, on ? 1 : 0); + gpio_pin_set_dt(p_led_col, on ? 1 : 0); +} + +static void rtk0eg0019b01002bj_led_init(void) +{ + for (int i = 0; i < NUM_ROWS; i++) { + gpio_pin_configure_dt(&led_row[i], GPIO_OUTPUT_INACTIVE); + } + + for (int i = 0; i < NUM_COLS; i++) { + gpio_pin_configure_dt(&led_col[i], GPIO_OUTPUT_INACTIVE); + } +} + +static void blink_leds(unsigned int duration_ms) +{ + for (int i = 0; i < 5; i++) { + /* Turn all LEDs ON */ + for (int j = 0; j < NUM_ROWS * NUM_COLS; j++) { + rtk0eg0019b01002bj_led_output(j, true); + } + k_msleep(duration_ms); + + /* Turn all LEDs OFF */ + for (int j = 0; j < NUM_ROWS * NUM_COLS; j++) { + rtk0eg0019b01002bj_led_output(j, false); + } + k_msleep(duration_ms); + } +} + +static inline unsigned int wheel_get_current_step(unsigned int value) +{ + return (value * WHEEL_LED_NUM) / WHEEL_RESOLUTION_DEGREE; +} + +static inline unsigned int slider_get_current_step(unsigned int value) +{ + return (value * SLIDER_LED_NUM) / SLIDER_RESOLUTION; +} + +static void rtk0eg0019b01002bj_evt_handler(struct input_event *evt, void *user_data) +{ + unsigned int led_idx; + + /* Set all LEDs to OFF */ + for (int i = 0; i < NUM_ROWS * NUM_COLS; i++) { + rtk0eg0019b01002bj_led_output(i, false); + } + + switch (evt->code) { + case INPUT_KEY_0: { + led_idx = button_leds_lut[0]; + break; + } + case INPUT_KEY_1: { + led_idx = button_leds_lut[1]; + break; + } + case INPUT_KEY_2: { + led_idx = button_leds_lut[2]; + break; + } + case INPUT_ABS_WHEEL: { + led_idx = wheel_get_current_step(evt->value) + wheel_leds_lut[0]; + break; + } + case INPUT_ABS_THROTTLE: { + led_idx = slider_get_current_step(evt->value) + slider_leds_lut[0]; + break; + } + default: + /* Unexpected event */ + return; + } + + rtk0eg0019b01002bj_led_output(led_idx, true); +} + +INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(BUTTON1), rtk0eg0019b01002bj_evt_handler, NULL, button1); +INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(BUTTON2), rtk0eg0019b01002bj_evt_handler, NULL, button2); +INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(BUTTON3), rtk0eg0019b01002bj_evt_handler, NULL, button3); +INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(SLIDER), rtk0eg0019b01002bj_evt_handler, NULL, slider); +INPUT_CALLBACK_DEFINE_NAMED(DEVICE_DT_GET(WHEEL), rtk0eg0019b01002bj_evt_handler, NULL, wheel); + +int main(void) +{ +#ifdef CONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG + const struct device *qe_touch_cfg1 = DEVICE_DT_GET(QE_TOUCH_CFG1); + const struct device *qe_touch_cfg2 = DEVICE_DT_GET(QE_TOUCH_CFG2); + const struct device *qe_touch_cfg3 = DEVICE_DT_GET(QE_TOUCH_CFG3); + int ret; +#endif + rtk0eg0019b01002bj_led_init(); + + /* Blink all leds 5 times, each time is 200ms */ + blink_leds(200); + +#ifdef CONFIG_INPUT_RENESAS_RA_QE_TOUCH_CFG + ret = renesas_ra_ctsu_group_configure( + qe_touch_cfg1, (struct renesas_ra_ctsu_touch_cfg *)&g_qe_touch_instance_config01); + if (ret < 0) { + printk("Failed to configure QE Touch Group 1: %d\n", ret); + return ret; + } + + ret = renesas_ra_ctsu_group_configure( + qe_touch_cfg2, (struct renesas_ra_ctsu_touch_cfg *)&g_qe_touch_instance_config02); + if (ret < 0) { + printk("Failed to configure QE Touch Group 2: %d\n", ret); + return ret; + } + + ret = renesas_ra_ctsu_group_configure( + qe_touch_cfg3, (struct renesas_ra_ctsu_touch_cfg *)&g_qe_touch_instance_config03); + if (ret < 0) { + printk("Failed to configure QE Touch Group 3: %d\n", ret); + return ret; + } +#endif + + printk("rtk0eg0019b01002bj sample started\n"); + return 0; +} diff --git a/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.c b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.c new file mode 100644 index 0000000000000..0dc0eff0c5d19 --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.c @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Generated content from Renesas QE Capacitive Touch */ + +#include "qe_touch_config.h" + +volatile uint8_t g_qe_touch_flag; +volatile ctsu_event_t g_qe_ctsu_event; + +void qe_touch_callback(touch_callback_args_t *p_args) +{ + g_qe_touch_flag = 1; + g_qe_ctsu_event = p_args->event; +} + +/* CTSU Related Information for [CONFIG01] configuration. */ + +const ctsu_element_cfg_t g_qe_ctsu_element_cfg_config01[] = { + {.ssdiv = CTSU_SSDIV_4000, .so = 0x000, .snum = 0x07, .sdpa = 0x1F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x00F, .snum = 0x07, .sdpa = 0x1F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x007, .snum = 0x07, .sdpa = 0x1F}, +}; + +const ctsu_cfg_t g_qe_ctsu_cfg_config01 = { + .cap = CTSU_CAP_SOFTWARE, + + .txvsel = CTSU_TXVSEL_INTERNAL_POWER, + .txvsel2 = CTSU_TXVSEL_MODE, + + .atune12 = CTSU_ATUNE12_40UA, + .md = CTSU_MODE_SELF_MULTI_SCAN, + .posel = CTSU_POSEL_SAME_PULSE, + + .ctsuchac0 = 0x01, /* ch0-ch7 enable mask */ + .ctsuchac1 = 0x0E, /* ch8-ch15 enable mask */ + .ctsuchac2 = 0x00, /* ch16-ch23 enable mask */ + .ctsuchac3 = 0x00, /* ch24-ch31 enable mask */ + .ctsuchac4 = 0x00, /* ch32-ch39 enable mask */ + .ctsuchtrc0 = 0x01, /* ch0-ch7 mutual tx mask */ + .ctsuchtrc1 = 0x00, /* ch8-ch15 mutual tx mask */ + .ctsuchtrc2 = 0x00, /* ch16-ch23 mutual tx mask */ + .ctsuchtrc3 = 0x00, /* ch24-ch31 mutual tx mask */ + .ctsuchtrc4 = 0x00, /* ch32-ch39 mutual tx mask */ + .num_rx = 3, + .num_tx = 0, + .p_elements = g_qe_ctsu_element_cfg_config01, + +#if (CTSU_TARGET_VALUE_CONFIG_SUPPORT == 1) + .tuning_self_target_value = 4608, + .tuning_mutual_target_value = 10240, +#endif + + .num_moving_average = 4, + .p_callback = &qe_touch_callback, +#if (CTSU_CFG_DTC_SUPPORT_ENABLE == 1) + .p_transfer_tx = &g_transfer0, + .p_transfer_rx = &g_transfer1, +#else + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, +#endif + + .write_irq = CTSU_WRITE_IRQn, + .read_irq = CTSU_READ_IRQn, + .end_irq = CTSU_END_IRQn, + +}; + +ctsu_instance_ctrl_t g_qe_ctsu_ctrl_config01; + +const ctsu_instance_t g_qe_ctsu_instance_config01 = { + .p_ctrl = &g_qe_ctsu_ctrl_config01, + .p_cfg = &g_qe_ctsu_cfg_config01, + .p_api = &g_ctsu_on_ctsu, +}; + +/* Touch Related Information for [CONFIG01] configuration. */ + +#define QE_TOUCH_CONFIG01_NUM_BUTTONS (3) +#define QE_TOUCH_CONFIG01_NUM_SLIDERS (0) +#define QE_TOUCH_CONFIG01_NUM_WHEELS (0) +#define QE_TOUCH_CONFIG01_NUM_TOUCH_PADS (0) + +#if (QE_TOUCH_CONFIG01_NUM_BUTTONS != 0) +const touch_button_cfg_t g_qe_touch_button_cfg_config01[] = { + { + .elem_index = 2, + .threshold = 261, + .hysteresis = 13, + }, + { + .elem_index = 1, + .threshold = 226, + .hysteresis = 11, + }, + { + .elem_index = 0, + .threshold = 306, + .hysteresis = 15, + }, +}; +#endif + +#if (QE_TOUCH_CONFIG01_NUM_SLIDERS != 0) +const touch_slider_cfg_t g_qe_touch_slider_cfg_config01[] = {NULL}; +#endif + +#if (QE_TOUCH_CONFIG01_NUM_WHEELS != 0) +const touch_wheel_cfg_t g_qe_touch_wheel_cfg_config01[] = {NULL}; +#endif + +#if (QE_TOUCH_CONFIG01_NUM_TOUCH_PADS != 0) +const touch_pad_cfg_t g_qe_touch_touch_pad_cfg_config01 = {NULL}; +#endif + +const touch_cfg_t g_qe_touch_cfg_config01 = { + .p_buttons = g_qe_touch_button_cfg_config01, + .p_sliders = NULL, + .p_wheels = NULL, +#if (TOUCH_CFG_PAD_ENABLE != 0) + .p_pad = NULL, +#endif + .num_buttons = QE_TOUCH_CONFIG01_NUM_BUTTONS, + .num_sliders = QE_TOUCH_CONFIG01_NUM_SLIDERS, + .num_wheels = QE_TOUCH_CONFIG01_NUM_WHEELS, + + .number = 0, +#if ((TOUCH_CFG_UART_MONITOR_SUPPORT == 1) || (TOUCH_CFG_UART_TUNING_SUPPORT == 1)) + .p_uart_instance = &g_uart_qe, +#else + .p_uart_instance = NULL, +#endif + + .on_freq = 3, + .off_freq = 3, + .drift_freq = 255, + .cancel_freq = 0, + + .p_ctsu_instance = &g_qe_ctsu_instance_config01, +}; + +touch_instance_ctrl_t g_qe_touch_ctrl_config01; + +const touch_instance_t g_qe_touch_instance_config01 = { + .p_ctrl = &g_qe_touch_ctrl_config01, + .p_cfg = &g_qe_touch_cfg_config01, + .p_api = &g_touch_on_ctsu, +}; + +/* CTSU Related Information for [CONFIG02] configuration. */ + +const ctsu_element_cfg_t g_qe_ctsu_element_cfg_config02[] = { + {.ssdiv = CTSU_SSDIV_4000, .so = 0x021, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x032, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x02C, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x034, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x032, .snum = 0x07, .sdpa = 0x0F}, +}; + +const ctsu_cfg_t g_qe_ctsu_cfg_config02 = { + .cap = CTSU_CAP_SOFTWARE, + + .txvsel = CTSU_TXVSEL_INTERNAL_POWER, + .txvsel2 = CTSU_TXVSEL_MODE, + + .atune12 = CTSU_ATUNE12_40UA, + .md = CTSU_MODE_SELF_MULTI_SCAN, + .posel = CTSU_POSEL_SAME_PULSE, + + .ctsuchac0 = 0xF4, /* ch0-ch7 enable mask */ + .ctsuchac1 = 0x01, /* ch8-ch15 enable mask */ + .ctsuchac2 = 0x00, /* ch16-ch23 enable mask */ + .ctsuchac3 = 0x00, /* ch24-ch31 enable mask */ + .ctsuchac4 = 0x00, /* ch32-ch39 enable mask */ + .ctsuchtrc0 = 0x00, /* ch0-ch7 mutual tx mask */ + .ctsuchtrc1 = 0x01, /* ch8-ch15 mutual tx mask */ + .ctsuchtrc2 = 0x00, /* ch16-ch23 mutual tx mask */ + .ctsuchtrc3 = 0x00, /* ch24-ch31 mutual tx mask */ + .ctsuchtrc4 = 0x00, /* ch32-ch39 mutual tx mask */ + .num_rx = 5, + .num_tx = 0, + .p_elements = g_qe_ctsu_element_cfg_config02, + +#if (CTSU_TARGET_VALUE_CONFIG_SUPPORT == 1) + .tuning_self_target_value = 4608, + .tuning_mutual_target_value = 10240, +#endif + + .num_moving_average = 4, + .p_callback = &qe_touch_callback, +#if (CTSU_CFG_DTC_SUPPORT_ENABLE == 1) + .p_transfer_tx = &g_transfer0, + .p_transfer_rx = &g_transfer1, +#else + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, +#endif + + .write_irq = CTSU_WRITE_IRQn, + .read_irq = CTSU_READ_IRQn, + .end_irq = CTSU_END_IRQn, + +}; + +ctsu_instance_ctrl_t g_qe_ctsu_ctrl_config02; + +const ctsu_instance_t g_qe_ctsu_instance_config02 = { + .p_ctrl = &g_qe_ctsu_ctrl_config02, + .p_cfg = &g_qe_ctsu_cfg_config02, + .p_api = &g_ctsu_on_ctsu, +}; + +/* Touch Related Information for [CONFIG02] configuration. */ + +#define QE_TOUCH_CONFIG02_NUM_BUTTONS (0) +#define QE_TOUCH_CONFIG02_NUM_SLIDERS (1) +#define QE_TOUCH_CONFIG02_NUM_WHEELS (0) +#define QE_TOUCH_CONFIG02_NUM_TOUCH_PADS (0) + +#if (QE_TOUCH_CONFIG02_NUM_BUTTONS != 0) +const touch_button_cfg_t g_qe_touch_button_cfg_config02[] = {NULL}; +#endif + +const uint8_t g_qe_touch_elem_slider_config02_slider00[] = {1, 0, 2, 4, 3}; + +#if (QE_TOUCH_CONFIG02_NUM_SLIDERS != 0) +const touch_slider_cfg_t g_qe_touch_slider_cfg_config02[] = { + { + .p_elem_index = g_qe_touch_elem_slider_config02_slider00, + .num_elements = 5, + .threshold = 570, + }, +}; +#endif + +#if (QE_TOUCH_CONFIG02_NUM_WHEELS != 0) +const touch_wheel_cfg_t g_qe_touch_wheel_cfg_config02[] = {NULL}; +#endif + +#if (QE_TOUCH_CONFIG02_NUM_TOUCH_PADS != 0) +const touch_pad_cfg_t g_qe_touch_touch_pad_cfg_config02 = {NULL}; +#endif + +const touch_cfg_t g_qe_touch_cfg_config02 = { + .p_buttons = NULL, + .p_sliders = g_qe_touch_slider_cfg_config02, + .p_wheels = NULL, +#if (TOUCH_CFG_PAD_ENABLE != 0) + .p_pad = NULL, +#endif + .num_buttons = QE_TOUCH_CONFIG02_NUM_BUTTONS, + .num_sliders = QE_TOUCH_CONFIG02_NUM_SLIDERS, + .num_wheels = QE_TOUCH_CONFIG02_NUM_WHEELS, + + .number = 1, +#if ((TOUCH_CFG_UART_MONITOR_SUPPORT == 1) || (TOUCH_CFG_UART_TUNING_SUPPORT == 1)) + .p_uart_instance = &g_uart_qe, +#else + .p_uart_instance = NULL, +#endif + + .on_freq = 3, + .off_freq = 3, + .drift_freq = 255, + .cancel_freq = 0, + + .p_ctsu_instance = &g_qe_ctsu_instance_config02, +}; + +touch_instance_ctrl_t g_qe_touch_ctrl_config02; + +const touch_instance_t g_qe_touch_instance_config02 = { + .p_ctrl = &g_qe_touch_ctrl_config02, + .p_cfg = &g_qe_touch_cfg_config02, + .p_api = &g_touch_on_ctsu, +}; + +/* CTSU Related Information for [CONFIG03] configuration. */ + +const ctsu_element_cfg_t g_qe_ctsu_element_cfg_config03[] = { + {.ssdiv = CTSU_SSDIV_4000, .so = 0x03F, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x03D, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x041, .snum = 0x07, .sdpa = 0x0F}, + {.ssdiv = CTSU_SSDIV_4000, .so = 0x037, .snum = 0x07, .sdpa = 0x0F}, +}; + +const ctsu_cfg_t g_qe_ctsu_cfg_config03 = { + .cap = CTSU_CAP_SOFTWARE, + + .txvsel = CTSU_TXVSEL_INTERNAL_POWER, + .txvsel2 = CTSU_TXVSEL_MODE, + + .atune12 = CTSU_ATUNE12_40UA, + .md = CTSU_MODE_SELF_MULTI_SCAN, + .posel = CTSU_POSEL_SAME_PULSE, + + .ctsuchac0 = 0x00, /* ch0-ch7 enable mask */ + .ctsuchac1 = 0x40, /* ch8-ch15 enable mask */ + .ctsuchac2 = 0xA4, /* ch16-ch23 enable mask */ + .ctsuchac3 = 0x00, /* ch24-ch31 enable mask */ + .ctsuchac4 = 0x01, /* ch32-ch39 enable mask */ + .ctsuchtrc0 = 0x00, /* ch0-ch7 mutual tx mask */ + .ctsuchtrc1 = 0x40, /* ch8-ch15 mutual tx mask */ + .ctsuchtrc2 = 0x00, /* ch16-ch23 mutual tx mask */ + .ctsuchtrc3 = 0x00, /* ch24-ch31 mutual tx mask */ + .ctsuchtrc4 = 0x00, /* ch32-ch39 mutual tx mask */ + .num_rx = 4, + .num_tx = 0, + .p_elements = g_qe_ctsu_element_cfg_config03, + +#if (CTSU_TARGET_VALUE_CONFIG_SUPPORT == 1) + .tuning_self_target_value = 4608, + .tuning_mutual_target_value = 10240, +#endif + + .num_moving_average = 4, + .p_callback = &qe_touch_callback, +#if (CTSU_CFG_DTC_SUPPORT_ENABLE == 1) + .p_transfer_tx = &g_transfer0, + .p_transfer_rx = &g_transfer1, +#else + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, +#endif + + .write_irq = CTSU_WRITE_IRQn, + .read_irq = CTSU_READ_IRQn, + .end_irq = CTSU_END_IRQn, + +}; + +ctsu_instance_ctrl_t g_qe_ctsu_ctrl_config03; + +const ctsu_instance_t g_qe_ctsu_instance_config03 = { + .p_ctrl = &g_qe_ctsu_ctrl_config03, + .p_cfg = &g_qe_ctsu_cfg_config03, + .p_api = &g_ctsu_on_ctsu, +}; + +/* Touch Related Information for [CONFIG03] configuration. */ + +#define QE_TOUCH_CONFIG03_NUM_BUTTONS (0) +#define QE_TOUCH_CONFIG03_NUM_SLIDERS (0) +#define QE_TOUCH_CONFIG03_NUM_WHEELS (1) +#define QE_TOUCH_CONFIG03_NUM_TOUCH_PADS (0) + +#if (QE_TOUCH_CONFIG03_NUM_BUTTONS != 0) +const touch_button_cfg_t g_qe_touch_button_cfg_config03[] = {NULL}; +#endif + +#if (QE_TOUCH_CONFIG03_NUM_SLIDERS != 0) +const touch_slider_cfg_t g_qe_touch_slider_cfg_config03[] = {NULL}; +#endif + +const uint8_t g_qe_touch_elem_wheel_config03_wheel00[] = {0, 1, 2, 3}; + +#if (QE_TOUCH_CONFIG03_NUM_WHEELS != 0) +const touch_wheel_cfg_t g_qe_touch_wheel_cfg_config03[] = { + { + .p_elem_index = g_qe_touch_elem_wheel_config03_wheel00, + .num_elements = 4, + .threshold = 585, + }, +}; +#endif + +#if (QE_TOUCH_CONFIG03_NUM_TOUCH_PADS != 0) +const touch_pad_cfg_t g_qe_touch_touch_pad_cfg_config03 = {NULL}; +#endif + +const touch_cfg_t g_qe_touch_cfg_config03 = { + .p_buttons = NULL, + .p_sliders = NULL, + .p_wheels = g_qe_touch_wheel_cfg_config03, +#if (TOUCH_CFG_PAD_ENABLE != 0) + .p_pad = NULL, +#endif + .num_buttons = QE_TOUCH_CONFIG03_NUM_BUTTONS, + .num_sliders = QE_TOUCH_CONFIG03_NUM_SLIDERS, + .num_wheels = QE_TOUCH_CONFIG03_NUM_WHEELS, + + .number = 2, +#if ((TOUCH_CFG_UART_MONITOR_SUPPORT == 1) || (TOUCH_CFG_UART_TUNING_SUPPORT == 1)) + .p_uart_instance = &g_uart_qe, +#else + .p_uart_instance = NULL, +#endif + + .on_freq = 3, + .off_freq = 3, + .drift_freq = 255, + .cancel_freq = 0, + + .p_ctsu_instance = &g_qe_ctsu_instance_config03, +}; + +touch_instance_ctrl_t g_qe_touch_ctrl_config03; + +const touch_instance_t g_qe_touch_instance_config03 = { + .p_ctrl = &g_qe_touch_ctrl_config03, + .p_cfg = &g_qe_touch_cfg_config03, + .p_api = &g_touch_on_ctsu, +}; diff --git a/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.h b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.h new file mode 100644 index 0000000000000..943c478b8f777 --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_config.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef QE_TOUCH_CONFIG_H +#define QE_TOUCH_CONFIG_H + +/* Generated content from Renesas QE Capacitive Touch */ + +#include "hal_data.h" +#include "qe_touch_define.h" + +extern const ctsu_instance_t g_qe_ctsu_instance_config01; +extern const ctsu_instance_t g_qe_ctsu_instance_config02; +extern const ctsu_instance_t g_qe_ctsu_instance_config03; +extern const touch_instance_t g_qe_touch_instance_config01; +extern const touch_instance_t g_qe_touch_instance_config02; +extern const touch_instance_t g_qe_touch_instance_config03; + +extern volatile uint8_t g_qe_touch_flag; +extern volatile ctsu_event_t g_qe_ctsu_event; + +extern void qe_touch_callback(touch_callback_args_t *p_args); + +#endif /* QE_TOUCH_CONFIG_H */ diff --git a/samples/shields/rtk0eg0019b01002bj/src/qe_touch_define.h b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_define.h new file mode 100644 index 0000000000000..acc40851ce262 --- /dev/null +++ b/samples/shields/rtk0eg0019b01002bj/src/qe_touch_define.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef QE_TOUCH_DEFINE_H +#define QE_TOUCH_DEFINE_H + +/* Generated content from Renesas QE Capacitive Touch */ + +#define QE_TOUCH_VERSION (0x0410) + +#define CTSU_CFG_NUM_SELF_ELEMENTS (12) + +#define CTSU_CFG_NUM_MUTUAL_ELEMENTS (0) +#define CTSU_CFG_NUM_CFC (0) +#define CTSU_CFG_NUM_CFC_TX (0) + +#define TOUCH_CFG_MONITOR_ENABLE (1) +#define TOUCH_CFG_NUM_BUTTONS (3) +#define TOUCH_CFG_NUM_SLIDERS (1) +#define TOUCH_CFG_NUM_WHEELS (1) +#define TOUCH_CFG_PAD_ENABLE (0) + +#define QE_TOUCH_MACRO_CTSU_IP_KIND (2) + +#define CTSU_CFG_VCC_MV (5000) +#define CTSU_CFG_LOW_VOLTAGE_MODE (0) + +#define CTSU_CFG_PCLK_DIVISION (0) + +#define CTSU_CFG_TSCAP_PORT (0x010C) + +#define CTSU_CFG_NUM_SUMULTI (3) +#define CTSU_CFG_SUMULTI0 (0x3F) +#define CTSU_CFG_SUMULTI1 (0x36) +#define CTSU_CFG_SUMULTI2 (0x48) + +#define CTSU_CFG_CALIB_RTRIM_SUPPORT (0) +#define CTSU_CFG_TEMP_CORRECTION_SUPPORT (0) +#define CTSU_CFG_TEMP_CORRECTION_TS (0) +#define CTSU_CFG_TEMP_CORRECTION_TIME (0) + +#define CTSU_CFG_TARGET_VALUE_QE_SUPPORT (1) + +#define CTSU_CFG_MAJORITY_MODE (1) +#define CTSU_CFG_NUM_AUTOJUDGE_SELF_ELEMENTS (0) +#define CTSU_CFG_NUM_AUTOJUDGE_MUTUAL_ELEMENTS (0) + +#define CONFIG01_INDEX_BUTTON00 (2) +#define CONFIG01_MASK_BUTTON00 (1ULL << CONFIG01_INDEX_BUTTON00) +#define CONFIG01_INDEX_BUTTON01 (1) +#define CONFIG01_MASK_BUTTON01 (1ULL << CONFIG01_INDEX_BUTTON01) +#define CONFIG01_INDEX_BUTTON02 (0) +#define CONFIG01_MASK_BUTTON02 (1ULL << CONFIG01_INDEX_BUTTON02) + +#endif /* QE_TOUCH_DEFINE_H */ From 34559177318733f51d7be882defae38950ec9050 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Mon, 28 Jul 2025 12:55:25 +0200 Subject: [PATCH 0184/1076] soc: nordic: ironside: run clang-format on some files Format a few files with clang-format. Signed-off-by: Jonathan Nilsen --- soc/nordic/ironside/include/nrf_ironside/dvfs.h | 15 +++++++-------- soc/nordic/ironside/include/nrf_ironside/update.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/soc/nordic/ironside/include/nrf_ironside/dvfs.h b/soc/nordic/ironside/include/nrf_ironside/dvfs.h index e2cb03c249e0a..f48c8a6344a28 100644 --- a/soc/nordic/ironside/include/nrf_ironside/dvfs.h +++ b/soc/nordic/ironside/include/nrf_ironside/dvfs.h @@ -31,19 +31,19 @@ enum ironside_dvfs_oppoint { */ /** The requested DVFS oppoint is not allowed. */ -#define IRONSIDE_DVFS_ERROR_WRONG_OPPOINT (1) +#define IRONSIDE_DVFS_ERROR_WRONG_OPPOINT (1) /** Waiting for mutex lock timed out, or hardware is busy. */ -#define IRONSIDE_DVFS_ERROR_BUSY (2) +#define IRONSIDE_DVFS_ERROR_BUSY (2) /** There is configuration error in the DVFS service. */ -#define IRONSIDE_DVFS_ERROR_OPPOINT_DATA (3) +#define IRONSIDE_DVFS_ERROR_OPPOINT_DATA (3) /** The caller does not have permission to change the DVFS oppoint. */ -#define IRONSIDE_DVFS_ERROR_PERMISSION (4) +#define IRONSIDE_DVFS_ERROR_PERMISSION (4) /** The requested DVFS oppoint is already set, no change needed. */ #define IRONSIDE_DVFS_ERROR_NO_CHANGE_NEEDED (5) /** The operation timed out, possibly due to a hardware issue. */ -#define IRONSIDE_DVFS_ERROR_TIMEOUT (6) +#define IRONSIDE_DVFS_ERROR_TIMEOUT (6) /** The DVFS oppoint change operation is not allowed in the ISR context. */ -#define IRONSIDE_DVFS_ERROR_ISR_NOT_ALLOWED (7) +#define IRONSIDE_DVFS_ERROR_ISR_NOT_ALLOWED (7) /** * @} @@ -80,8 +80,7 @@ int ironside_dvfs_change_oppoint(enum ironside_dvfs_oppoint dvfs_oppoint); */ static inline bool ironside_dvfs_is_oppoint_valid(enum ironside_dvfs_oppoint dvfs_oppoint) { - if (dvfs_oppoint != IRONSIDE_DVFS_OPP_HIGH && - dvfs_oppoint != IRONSIDE_DVFS_OPP_MEDLOW && + if (dvfs_oppoint != IRONSIDE_DVFS_OPP_HIGH && dvfs_oppoint != IRONSIDE_DVFS_OPP_MEDLOW && dvfs_oppoint != IRONSIDE_DVFS_OPP_LOW) { return false; } diff --git a/soc/nordic/ironside/include/nrf_ironside/update.h b/soc/nordic/ironside/include/nrf_ironside/update.h index 8152a77f5f7c9..c0f021a91ed55 100644 --- a/soc/nordic/ironside/include/nrf_ironside/update.h +++ b/soc/nordic/ironside/include/nrf_ironside/update.h @@ -40,7 +40,7 @@ /* Index of the update blob pointer within the service buffer. */ #define IRONSIDE_UPDATE_SERVICE_UPDATE_PTR_IDX (0) /* Index of the return code within the service buffer. */ -#define IRONSIDE_UPDATE_SERVICE_RETCODE_IDX (0) +#define IRONSIDE_UPDATE_SERVICE_RETCODE_IDX (0) /** * @brief IronSide update blob. From 613dcf327e57df8ff576c95e081bfbcca118517d Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 31 Jul 2025 15:26:21 +0800 Subject: [PATCH 0185/1076] Bluetooth: Classic: SCO: Get SCO conn info Save the air_mode to SCO connect object. Add a structure `struct bt_conn_sco_info` to return the SCO conn info. Return SCO info through `struct bt_conn_sco_info` when calling the function `bt_conn_get_info()`. Signed-off-by: Lyle Zhu --- include/zephyr/bluetooth/conn.h | 8 ++++++ subsys/bluetooth/host/classic/br.c | 6 +++++ subsys/bluetooth/host/classic/shell/hfp.c | 32 +++++++++++++++++++++++ subsys/bluetooth/host/conn.c | 4 +++ subsys/bluetooth/host/conn_internal.h | 2 ++ 5 files changed, 52 insertions(+) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 7af6d1efca319..6a4b7c238c898 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -929,6 +929,12 @@ struct bt_conn_br_info { const bt_addr_t *dst; /**< Destination (Remote) BR/EDR address */ }; +/** SCO Connection Info Structure */ +struct bt_conn_sco_info { + uint8_t link_type; /**< SCO link type */ + uint8_t air_mode; /**< SCO air mode (codec type) */ +}; + enum { BT_CONN_ROLE_CENTRAL = 0, BT_CONN_ROLE_PERIPHERAL = 1, @@ -995,6 +1001,8 @@ struct bt_conn_info { struct bt_conn_le_info le; /** BR/EDR Connection specific Info. */ struct bt_conn_br_info br; + /** SCO Connection specific Info. */ + struct bt_conn_sco_info sco; }; /** Connection state. */ enum bt_conn_state state; diff --git a/subsys/bluetooth/host/classic/br.c b/subsys/bluetooth/host/classic/br.c index f9265dc948bad..23a43a01959b3 100644 --- a/subsys/bluetooth/host/classic/br.c +++ b/subsys/bluetooth/host/classic/br.c @@ -211,6 +211,12 @@ void bt_hci_synchronous_conn_complete(struct net_buf *buf) } sco_conn->handle = handle; + sco_conn->sco.air_mode = evt->air_mode; + + if (sco_conn->sco.link_type != evt->link_type) { + LOG_WRN("link type mismatch %u != %u", sco_conn->sco.link_type, evt->link_type); + sco_conn->sco.link_type = evt->link_type; + } bt_conn_set_state(sco_conn, BT_CONN_CONNECTED); bt_conn_unref(sco_conn); } diff --git a/subsys/bluetooth/host/classic/shell/hfp.c b/subsys/bluetooth/host/classic/shell/hfp.c index 7911394e60910..7b19ad0ea46b2 100644 --- a/subsys/bluetooth/host/classic/shell/hfp.c +++ b/subsys/bluetooth/host/classic/shell/hfp.c @@ -86,6 +86,9 @@ static void hf_disconnected(struct bt_hfp_hf *hf) static void hf_sco_connected(struct bt_hfp_hf *hf, struct bt_conn *sco_conn) { + struct bt_conn_info info; + uint16_t handle; + bt_shell_print("HF SCO connected %p", sco_conn); if (hf_sco_conn != NULL) { @@ -94,6 +97,19 @@ static void hf_sco_connected(struct bt_hfp_hf *hf, struct bt_conn *sco_conn) } hf_sco_conn = bt_conn_ref(sco_conn); + if (bt_hci_get_conn_handle(sco_conn, &handle) < 0) { + bt_shell_warn("Failed to get SCO connection handle"); + return; + } + + if (bt_conn_get_info(sco_conn, &info) < 0) { + bt_shell_warn("Failed to get SCO connection info"); + return; + } + bt_shell_print("HF SCO info:"); + bt_shell_print(" SCO handle 0x%04X", handle); + bt_shell_print(" SCO air mode %u", info.sco.air_mode); + bt_shell_print(" SCO link type %u", info.sco.link_type); } static void hf_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) @@ -1064,6 +1080,9 @@ static void ag_disconnected(struct bt_hfp_ag *ag) static void ag_sco_connected(struct bt_hfp_ag *ag, struct bt_conn *sco_conn) { + struct bt_conn_info info; + uint16_t handle; + bt_shell_print("AG SCO connected %p", sco_conn); if (hfp_ag_sco_conn != NULL) { @@ -1072,6 +1091,19 @@ static void ag_sco_connected(struct bt_hfp_ag *ag, struct bt_conn *sco_conn) } hfp_ag_sco_conn = bt_conn_ref(sco_conn); + if (bt_hci_get_conn_handle(sco_conn, &handle) < 0) { + bt_shell_warn("Failed to get SCO connection handle"); + return; + } + + if (bt_conn_get_info(sco_conn, &info) < 0) { + bt_shell_warn("Failed to get SCO connection info"); + return; + } + bt_shell_print("AG SCO info:"); + bt_shell_print(" SCO handle 0x%04X", handle); + bt_shell_print(" SCO air mode %u", info.sco.air_mode); + bt_shell_print(" SCO link type %u", info.sco.link_type); } static void ag_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 98fcf6615bf14..f3abf67d4fb6d 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2876,6 +2876,10 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info) case BT_CONN_TYPE_BR: info->br.dst = &conn->br.dst; return 0; + case BT_CONN_TYPE_SCO: + info->sco.air_mode = conn->sco.air_mode; + info->sco.link_type = conn->sco.link_type; + return 0; #endif #if defined(CONFIG_BT_ISO) case BT_CONN_TYPE_ISO: diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 33323ee732919..c64ad277b4f8f 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -167,6 +167,8 @@ struct bt_conn_sco { uint16_t pkt_type; uint8_t dev_class[3]; uint8_t link_type; + /* Reference to BT_HCI_CODING_FORMAT_* */ + uint8_t air_mode; }; struct bt_conn_iso { From 53a07893d5570be02a74e6a6f7ae21d7721b43bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20St=C4=99pnicki?= Date: Thu, 3 Jul 2025 12:28:09 +0200 Subject: [PATCH 0186/1076] boards: nordic: nrf54h20dk: ipc to cpusys with unbound MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unbound feature in IPC with cpusys will be enabled by default. This is needed to enable IPC link renewal. If unbound is not needed then it can be disabled in overlay, sysctrl will detect if it is present. Signed-off-by: Łukasz Stępnicki --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi index f31d909b6f94a..f7e7d63d548de 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi @@ -32,6 +32,7 @@ cpuapp_cpusys_ipc: ipc-2-12 { compatible = "zephyr,ipc-icmsg"; + unbound = "enable"; status = "disabled"; dcache-alignment = <32>; mboxes = <&cpuapp_bellboard 6>, @@ -56,6 +57,7 @@ cpurad_cpusys_ipc: ipc-3-12 { compatible = "zephyr,ipc-icmsg"; + unbound = "enable"; status = "disabled"; dcache-alignment = <32>; mboxes = <&cpurad_bellboard 6>, From c1d28a4ea70df8dae41fc9160b27c34174ab9f1f Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Fri, 22 Aug 2025 14:05:57 +0200 Subject: [PATCH 0187/1076] manifest: update hal_nordic revision to integrate nrfx 3.14.0 New nrfx release contains MDK 8.72.2 and various fixes for nRF devices. Signed-off-by: Nikodem Kastelik --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index deeeb6e2e57d8..cae08c1b47d8f 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: a6579483deb33112cc763d05a4a3f8085883c1ac + revision: 54f33f10a0b826174fb145f155afa61ce5a44b93 path: modules/hal/nordic groups: - hal From a9eadb411d29edbf05fe53c15072a6d0296136e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Wed, 30 Jul 2025 08:10:15 +0200 Subject: [PATCH 0188/1076] soc: nordic: nrf54l: remove redundant inclusion of GLITCHDET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GLITCHDET is not used in this file and causes issues for devices without GLITCHDET. Signed-off-by: Michał Stasiak --- soc/nordic/nrf54l/soc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/soc/nordic/nrf54l/soc.c b/soc/nordic/nrf54l/soc.c index 85043985e51f6..76225d70ab74f 100644 --- a/soc/nordic/nrf54l/soc.c +++ b/soc/nordic/nrf54l/soc.c @@ -29,7 +29,6 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); !defined(__ZEPHYR__) #include -#include #include #include #include From 2939ccdf42b9f1467b6c4dbf6149f1ff04795f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Wed, 13 Aug 2025 12:05:48 +0200 Subject: [PATCH 0189/1076] drivers: adc: adc_nrfx_saadc: add nRF54LS05B analog pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added array of analong pins for nRF54LS05B. Signed-off-by: Michał Stasiak --- drivers/adc/adc_nrfx_saadc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 614973261746f..06035e2c3c5d4 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -76,6 +76,13 @@ static const uint32_t saadc_psels[NRF_SAADC_AIN7 + 1] = { [NRF_SAADC_AIN6] = NRF_PIN_PORT_TO_PIN_NUMBER(11U, 1), [NRF_SAADC_AIN7] = NRF_PIN_PORT_TO_PIN_NUMBER(12U, 1), }; +#elif defined(NRF54LS05B_ENGA_XXAA) +static const uint32_t saadc_psels[NRF_SAADC_AIN3 + 1] = { + [NRF_SAADC_AIN0] = NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), + [NRF_SAADC_AIN1] = NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), + [NRF_SAADC_AIN2] = NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1), + [NRF_SAADC_AIN3] = NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1), +}; #endif #else From 73fbdbe1e705c9538f892843a6a521856c3c1e10 Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Tue, 26 Aug 2025 13:30:26 +0200 Subject: [PATCH 0190/1076] Bluetooth: document bt_addr_le_is_resolved() I believe there is some confusion about what this function does. This function is doing some type-bending, so it's extra important to document it. Signed-off-by: Aleksander Wasaznik --- subsys/bluetooth/host/addr_internal.h | 38 ++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/addr_internal.h b/subsys/bluetooth/host/addr_internal.h index e61f62a5714d2..b079c704dac31 100644 --- a/subsys/bluetooth/host/addr_internal.h +++ b/subsys/bluetooth/host/addr_internal.h @@ -11,4 +11,40 @@ void bt_addr_le_copy_resolved(bt_addr_le_t *dst, const bt_addr_le_t *src); -bool bt_addr_le_is_resolved(const bt_addr_le_t *addr); +/** + * @brief Determine whether an HCI LE event address was resolved by the Controller + * + * This helper inspects an HCI LE event address field and reports whether the + * Controller resolved a Resolvable Private Address (RPA) to an identity address + * when producing the event. + * + * @warning The parameter is not a regular application-layer @ref bt_addr_le_t. + * It must be the address field taken directly from an HCI LE event structure. + * In those events, the address "type" uses the Identity Address values to + * indicate that resolution has occurred; this function only checks that bit. + * Do not use this with any @ref bt_addr_le_t obtained from Zephyr host APIs. + * + * The complete (at time of writing) list of events that contain at least one field like this: + * - LE Advertising Report event (@ref bt_hci_evt_le_advertising_report) + * - LE Enhanced Connection Complete event (@ref bt_hci_evt_le_enh_conn_complete) + * - LE Directed Advertising Report event (@ref bt_hci_evt_le_direct_adv_report) + * - LE Extended Advertising Report event (@ref bt_hci_evt_le_ext_advertising_report) + * - LE Scan Request Received event (@ref bt_hci_evt_le_scan_req_received) + * - LE Periodic Advertising Sync Transfer Received event (@ref bt_hci_evt_le_past_received_v2) + * - LE Monitored Advertisers Report event + * + * @note The exact "potentially resolved address field" type is not a distinct + * type in the Core Specification; it is inferred from the common layout of the + * events above. This function only inspects the address type; it does not perform + * address resolution nor consult the resolve list. + * + * @param hci_addr_field_value Address field taken directly from an HCI LE event + * @retval true The Controller resolved the address (the on-air RPA matched an + * IRK in the Controller's resolve list) + * @retval false The address was not resolved by the Controller (resolution + * disabled or no match) + * + * @see bt_addr_le_copy_resolved() to convert a HCI event address type to a + * regular @ref bt_addr_le_t. + */ +bool bt_addr_le_is_resolved(const bt_addr_le_t *hci_addr_field_value); From 5eeddab16757e08d0ea5699689751bf648a53b7c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 26 Aug 2025 05:52:15 -0600 Subject: [PATCH 0191/1076] scripts: west: flash: Fix RFP runner platform check Adjust the RFP runner platform check to properly handle Darwin or Windows and skip setting a default RPF port on those two platforms. Signed-off-by: Peter Johanson --- scripts/west_commands/runners/rfp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/runners/rfp.py b/scripts/west_commands/runners/rfp.py index f619f151570be..940f24adbf9f6 100644 --- a/scripts/west_commands/runners/rfp.py +++ b/scripts/west_commands/runners/rfp.py @@ -12,7 +12,7 @@ from runners.core import RunnerCaps, ZephyrBinaryRunner -if platform.system() == 'Darwin' or 'Windows': +if platform.system() in {'Darwin', 'Windows'}: DEFAULT_RFP_PORT = None else: DEFAULT_RFP_PORT = '/dev/ttyACM0' From 4b272e0b33a57c394153a61b53cad00f1514fd5f Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Jul 2025 09:03:52 +0200 Subject: [PATCH 0192/1076] Bluetooth: Controller: Fix missing radio status reset Fix missing radio status reset on early abort of central and peripheral prepare. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 25f46d3a0ec6a..fd1aca9065183 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -805,6 +805,8 @@ void lll_isr_early_abort(void *param) { int err; + radio_status_reset(); + radio_isr_set(isr_race, param); if (!radio_is_idle()) { radio_disable(); From 355648a69f5137c68d86fe577ddb256e7da74d12 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Jul 2025 09:03:52 +0200 Subject: [PATCH 0193/1076] Bluetooth: Controller: Fix missing radio tmr status reset Fix missing radio tmr status reset on radio_disable call, without this which disables PPI/DPPI caused under race conditions the radio to transition into Tx or Rx state and put the Controller's state out of sync with the Radio peripherals internal state. The symptoms being that the Central role was not transmitting in the next interval; also, caused the defer iterations to reach maximum events being enqueued in the pipeline, and manifesting as large CPU overheads in redundant prepare of deferred events. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 81df96981dd2a..646b1a8a3383e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -573,6 +573,9 @@ void radio_disable(void) hal_radio_sw_switch_cleanup(); #endif /* !CONFIG_BT_CTLR_TIFS_HW */ + /* Reset/disable PPI/DPPI */ + radio_tmr_status_reset(); + NRF_RADIO->SHORTS = 0; nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); } From fe7675e20998837b554e14a4512689e486a4a704 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 23 Aug 2025 16:48:12 +0200 Subject: [PATCH 0194/1076] Bluetooth: Controller: Fix assertion due to cleared pending radio IRQ Fix assertion on scan disable observed in BabbleSIM audio tests due to clearing of pending radio IRQ under race conditions between scanning being stopped by application and scanning stopped on central connection setup. irq_enable/disable is not needed either as radio_isr_set is always called from Radio or LLL execution context which are co-operative with each other at same execution priority. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 8 -------- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 646b1a8a3383e..c881263d9a24a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -155,15 +155,8 @@ void isr_radio(void) void radio_isr_set(radio_isr_cb_t cb, void *param) { - irq_disable(HAL_RADIO_IRQn); - isr_cb_param = param; isr_cb = cb; - - nrf_radio_int_enable(NRF_RADIO, HAL_RADIO_INTENSET_DISABLED_Msk); - - NVIC_ClearPendingIRQ(HAL_RADIO_IRQn); - irq_enable(HAL_RADIO_IRQn); } void radio_setup(void) @@ -197,7 +190,6 @@ void radio_setup(void) void radio_reset(void) { - irq_disable(HAL_RADIO_IRQn); /* nRF SoC generic radio reset/initializations * Note: Only registers whose bits are partially modified across diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index fd1aca9065183..ed482b3981ae9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -307,6 +307,9 @@ int lll_init(void) #endif #endif /* !CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS */ + /* Enable Radio interrupt on radio state disabled; after tx or rx or explicitly disabled */ + nrf_radio_int_enable(NRF_RADIO, HAL_RADIO_INTENSET_DISABLED_Msk); + /* Enable IRQs */ irq_enable(HAL_RADIO_IRQn); irq_enable(HAL_RTC_IRQn); From 66d85b448bd32e17728ab8fce9afffcc36979661 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 22 Aug 2025 15:31:50 +0200 Subject: [PATCH 0195/1076] Bluetooth: Controller: Fix assertion establishing connection Fix an assertion detecting delayed prepare establishing an ACL connection due to scanner or advertiser not disabled immediately when scheduling the first connection event. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_scan.c | 15 ++++++++++++++ .../ll_sw/nordic/lll/lll_scan_aux.c | 20 +++++++++++++++++++ subsys/bluetooth/controller/ll_sw/ull_conn.c | 6 ++++++ .../bluetooth/controller/ll_sw/ull_scan_aux.c | 9 ++++++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index 8aedcd44a4f88..4f2d6607fbf56 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -1109,6 +1109,21 @@ static void isr_done_cleanup(void *param) } #endif /* CONFIG_BT_CTLR_ADV_EXT */ + /* Lets tail chain the execution of LLL disable of any scan event in the pipeline if scan + * role is to be stopped. + * This is for the case of connection setup or the duration has expired. + */ + if (lll->is_stop != 0U) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; + uint32_t ret; + + mfy.param = param; + + ret = mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_LLL, 1U, &mfy); + LL_ASSERT(!ret); + } + lll_isr_cleanup(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index 0680d49fbf261..248f609c6943d 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -687,6 +687,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) static void isr_done(void *param) { + struct lll_scan *scan_lll = NULL; struct lll_sync *lll; uint8_t is_lll_scan; @@ -694,6 +695,9 @@ static void isr_done(void *param) if (param) { lll = ull_scan_aux_lll_parent_get(param, &is_lll_scan); + if (is_lll_scan) { + scan_lll = (void *)lll; + } } else { lll = NULL; } @@ -727,6 +731,21 @@ static void isr_done(void *param) #endif /* CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS */ } + /* Lets tail chain the execution of LLL disable of any scan event in the pipeline if scan + * role is to be stopped. + * This is for the case of connection setup or the duration has expired. + */ + if ((scan_lll != NULL) && (scan_lll->is_stop != 0U)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; + uint32_t ret; + + mfy.param = scan_lll; + + ret = mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_LLL, 1U, &mfy); + LL_ASSERT(!ret); + } + lll_isr_cleanup(param); } @@ -917,6 +936,7 @@ static void isr_rx(struct lll_scan *lll, struct lll_scan_aux *lll_aux, radio_isr_set(isr_done, lll->lll_aux); } } + radio_disable(); } diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 39043a5a17bac..d59c7b317d8b9 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -909,6 +909,12 @@ void ull_conn_setup(memq_link_t *rx_link, struct node_rx_pdu *rx) LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = rx; hdr->disabled_cb = conn_setup_adv_scan_disabled_cb; + + /* NOTE: we are not forcing a lll_disable, in case of initiator + * we need let the CONNECT_IND PDU be transmitted. There + * is a possibility that a new scan window is in the LLL + * pipeline, it has to be disabled. + */ } else { conn_setup_adv_scan_disabled_cb(rx); } diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 36ca38496c421..953575885bc5a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -1387,6 +1387,10 @@ static void flush_safe(void *param) LL_ASSERT(!hdr->disabled_cb); hdr->disabled_param = aux; hdr->disabled_cb = done_disabled_cb; + + /* NOTE: we are not forcing a lll_disable, we will let window + * close at its duration or when preempted. + */ } } @@ -2620,10 +2624,13 @@ static void flush_safe(void *param) /* If chain is active we need to flush from disabled callback */ if (chain_is_in_list(scan_aux_set.active_chains, chain) && ull_ref_get(&scan_aux_set.ull)) { - chain->next = scan_aux_set.flushing_chains; scan_aux_set.flushing_chains = chain; scan_aux_set.ull.disabled_cb = done_disabled_cb; + + /* NOTE: we are not forcing a lll_disable, we will let window + * close at its duration or when preempted. + */ } else { flush(chain); } From e94d9c78117d08aad946d4a713e53d7704a23213 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 4 Aug 2025 20:12:01 +0200 Subject: [PATCH 0196/1076] Bluetooth: Controller: Fix event overhead check for single timer use Single timer use needs additional event overhead to start radio to ensure the software switch implementation executing in radio completion ISR can correctly set the tIFS switching after a maximum radio ISR latency. The latency value shall be the used additional overhead so that there is no spurious tIFS switch before radio ISR executes. The additional event overhead value is not considered in the event overhead check. Relates to commit 37bf99eee743 ("Bluetooth: Controller: Fix radio_tmr_start_us for single timer use"). Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index ed482b3981ae9..2f68855d4f8f7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -640,7 +640,8 @@ uint32_t lll_preempt_calc(struct ull_hdr *ull, uint8_t ticker_id, return 0; } - diff += HAL_TICKER_CNTR_CMP_OFFSET_MIN; + diff += HAL_TICKER_CNTR_CMP_OFFSET_MIN + + HAL_TICKER_US_TO_TICKS_CEIL(HAL_RADIO_ISR_LATENCY_MAX_US); if (diff > HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US)) { /* TODO: for Low Latency Feature with Advanced XTAL feature. * 1. Release retained HF clock. From 043dee2919adc6a55ca38794e20425dbf7bdc12e Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 22 Aug 2025 15:34:20 +0200 Subject: [PATCH 0197/1076] Bluetooth: Controller: Move declaration close to locality of reference Move the declaration code to locality of reference and be consistent in how the code pattern is, related to calling LLL disable. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_central.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 000f1640223f7..396560bd64663 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -1007,8 +1007,6 @@ static void ticker_op_stop_scan_cb(uint32_t status, void *param) #if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED) static void ticker_op_stop_scan_other_cb(uint32_t status, void *param) { - static memq_link_t link; - static struct mayfly mfy = {0, 0, &link, NULL, NULL}; struct ll_scan_set *scan; struct ull_hdr *hdr; @@ -1027,11 +1025,13 @@ static void ticker_op_stop_scan_other_cb(uint32_t status, void *param) */ scan = param; hdr = &scan->ull; - mfy.param = &scan->lll; if (ull_ref_get(hdr)) { + static memq_link_t link; + static struct mayfly mfy = {0, 0, &link, NULL, lll_disable}; uint32_t ret; - mfy.fp = lll_disable; + mfy.param = &scan->lll; + ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_LLL, 0, &mfy); LL_ASSERT(!ret); From 3e2beedb210af6dfaf7c5c3665f581e9f4bff75c Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 23 Aug 2025 10:49:08 +0200 Subject: [PATCH 0198/1076] Bluetooth: Controller: Minor update adding comments Minor update adding comments in the implementation. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 2 ++ subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c | 3 +++ subsys/bluetooth/controller/ll_sw/ull.c | 11 ++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index c881263d9a24a..433b0fe8791d3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -150,6 +150,8 @@ void isr_radio(void) { if (radio_has_disabled()) { isr_cb(isr_cb_param); + } else { + /* Nothing to do here, we shall not get spurious Radio IRQ */ } } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 2f68855d4f8f7..495c72bbf8cb3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -528,6 +528,9 @@ int lll_done(void *param) param = event.curr.param; event.curr.param = NULL; + /* Resume events will have set event.curr.param to NULL, these + * should not generate done events. + */ if (param) { ull = HDR_LLL2ULL(param); } else { diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 83af68020ef36..b5d3705cd3363 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2021,6 +2021,7 @@ int ull_disable(void *lll) struct ull_hdr *hdr; struct k_sem sem; uint32_t ret; + int err; hdr = HDR_LLL2ULL(lll); if (!ull_ref_get(hdr)) { @@ -2053,7 +2054,12 @@ int ull_disable(void *lll) &mfy); LL_ASSERT(!ret); - return k_sem_take(&sem, ULL_DISABLE_TIMEOUT); + err = k_sem_take(&sem, ULL_DISABLE_TIMEOUT); + if (err != 0) { + return err; + } + + return 0; } void *ull_pdu_rx_alloc_peek(uint8_t count) @@ -3028,6 +3034,9 @@ static inline void rx_demux_event_done(memq_link_t *link, if (ull_hdr) { LL_ASSERT(ull_ref_get(ull_hdr)); ull_ref_dec(ull_hdr); + } else { + /* No reference count decrement, event placed back as resume event in the pipeline. + */ } /* Process role dependent event done */ From daffb534ba75f85f2432ecb078170b795263985d Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Jul 2025 14:16:13 +0200 Subject: [PATCH 0199/1076] Bluetooth: Controller: Remove duplicate define CONN_DATA_BUFFERS Remove duplicate define CONN_DATA_BUFFERS and use CONFIG_BT_BUF_ACL_TX_COUNT instead. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index d59c7b317d8b9..c25977526716a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -130,23 +130,18 @@ static uint8_t force_md_cnt_calc(struct lll_conn *lll_conn, uint32_t tx_rate); (LL_LENGTH_OCTETS_TX_MAX + \ BT_CTLR_USER_TX_BUFFER_OVERHEAD)) -#define CONN_DATA_BUFFERS CONFIG_BT_BUF_ACL_TX_COUNT - -static MFIFO_DEFINE(conn_tx, sizeof(struct lll_tx), CONN_DATA_BUFFERS); +static MFIFO_DEFINE(conn_tx, sizeof(struct lll_tx), CONFIG_BT_BUF_ACL_TX_COUNT); static MFIFO_DEFINE(conn_ack, sizeof(struct lll_tx), - (CONN_DATA_BUFFERS + - LLCP_TX_CTRL_BUF_COUNT)); + (CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT)); static struct { void *free; - uint8_t pool[CONN_TX_BUF_SIZE * CONN_DATA_BUFFERS]; + uint8_t pool[CONN_TX_BUF_SIZE * CONFIG_BT_BUF_ACL_TX_COUNT]; } mem_conn_tx; static struct { void *free; - uint8_t pool[sizeof(memq_link_t) * - (CONN_DATA_BUFFERS + - LLCP_TX_CTRL_BUF_COUNT)]; + uint8_t pool[sizeof(memq_link_t) * (CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT)]; } mem_link_tx; #if defined(CONFIG_BT_CTLR_DATA_LENGTH) @@ -1702,14 +1697,11 @@ static int init_reset(void) } /* Initialize tx pool. */ - mem_init(mem_conn_tx.pool, CONN_TX_BUF_SIZE, CONN_DATA_BUFFERS, - &mem_conn_tx.free); + mem_init(mem_conn_tx.pool, CONN_TX_BUF_SIZE, CONFIG_BT_BUF_ACL_TX_COUNT, &mem_conn_tx.free); /* Initialize tx link pool. */ mem_init(mem_link_tx.pool, sizeof(memq_link_t), - (CONN_DATA_BUFFERS + - LLCP_TX_CTRL_BUF_COUNT), - &mem_link_tx.free); + (CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT), &mem_link_tx.free); /* Initialize control procedure system. */ ull_cp_init(); From 4d91a84b4bb6a66f7ce1998c76db163f1bd5c6a2 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Jul 2025 14:16:23 +0200 Subject: [PATCH 0200/1076] tests: bsim: Bluetooth: Add param update to throughput test Add connection parameter update to throughput test to cover any connection timeout performing connection update while subjected to high throughput scenarios. Signed-off-by: Vinayak Kariappa Chettimada --- samples/bluetooth/central_gatt_write/Kconfig | 5 + .../central_gatt_write/Kconfig.gatt_write | 8 + .../src/central_gatt_write.c | 6 + .../src/gatt_write_common.c | 197 +++++++++++++++--- .../bluetooth/peripheral_gatt_write/Kconfig | 5 + .../src/peripheral_gatt_write.c | 34 +++ .../compile.nrf5340bsim_nrf5340_cpuapp.sh | 1 + .../compile.nrf54l15bsim_nrf54l15_cpuapp.sh | 1 + tests/bsim/bluetooth/ll/compile.sh | 1 + tests/bsim/bluetooth/ll/throughput/Kconfig | 19 ++ .../ll/throughput/overlay-no_phy_update.conf | 2 + tests/bsim/bluetooth/ll/throughput/src/main.c | 23 +- .../ll/throughput/tests_scripts/gatt_write.sh | 5 +- .../tests_scripts/gatt_write_no_phy_update.sh | 24 +++ 14 files changed, 297 insertions(+), 34 deletions(-) create mode 100644 samples/bluetooth/central_gatt_write/Kconfig create mode 100644 samples/bluetooth/central_gatt_write/Kconfig.gatt_write create mode 100644 samples/bluetooth/peripheral_gatt_write/Kconfig create mode 100644 tests/bsim/bluetooth/ll/throughput/Kconfig create mode 100644 tests/bsim/bluetooth/ll/throughput/overlay-no_phy_update.conf create mode 100755 tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write_no_phy_update.sh diff --git a/samples/bluetooth/central_gatt_write/Kconfig b/samples/bluetooth/central_gatt_write/Kconfig new file mode 100644 index 0000000000000..f4d630ef8a513 --- /dev/null +++ b/samples/bluetooth/central_gatt_write/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "samples/bluetooth/central_gatt_write/Kconfig.gatt_write" +source "Kconfig.zephyr" diff --git a/samples/bluetooth/central_gatt_write/Kconfig.gatt_write b/samples/bluetooth/central_gatt_write/Kconfig.gatt_write new file mode 100644 index 0000000000000..99201a36b2d4f --- /dev/null +++ b/samples/bluetooth/central_gatt_write/Kconfig.gatt_write @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config USE_VARIABLE_LENGTH_DATA + bool "Use variable length data in GATT Write without Response" + help + Use increasing and decreasing length data in GATT Write without + Response. diff --git a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c index 28071dbc05df0..ae23785b1421a 100644 --- a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c +++ b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c @@ -16,6 +16,7 @@ extern int mtu_exchange(struct bt_conn *conn); extern int write_cmd(struct bt_conn *conn); extern struct bt_conn *conn_connected; extern uint32_t last_write_rate; +extern uint32_t *write_countdown; extern void (*start_scan_func)(void); static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, @@ -94,6 +95,7 @@ uint32_t central_gatt_write(uint32_t count) conn_connected = NULL; last_write_rate = 0U; + write_countdown = &count; #if defined(CONFIG_BT_USER_PHY_UPDATE) err = bt_conn_le_set_default_phy(BT_GAP_LE_PHY_1M, BT_GAP_LE_PHY_1M); @@ -123,6 +125,10 @@ uint32_t central_gatt_write(uint32_t count) bt_conn_unref(conn); if (count) { + if ((count % 1000U) == 0U) { + printk("GATT Write countdown %u\n", count); + } + count--; if (!count) { break; diff --git a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c index 99d2e830aea90..a86c05410b6b2 100644 --- a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c +++ b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c @@ -12,11 +12,30 @@ #include #include +/* Count down number of write commands after all PHY and connection updates */ +#define COUNT_THROUGHPUT 1000U + /* Count down number of metrics intervals before performing a PHY update */ -#define PHY_UPDATE_COUNTDOWN 3U +#define PHY_UPDATE_COUNTDOWN 5U static uint32_t phy_update_countdown; static uint8_t phy_param_idx; +/* Count down number of metrics intervals before performing a param update */ +#define PARAM_UPDATE_COUNTDOWN PHY_UPDATE_COUNTDOWN +#if defined(CONFIG_TEST_PHY_UPDATE) +#define PARAM_UPDATE_ITERATION_MAX 1 +#else /* !CONFIG_TEST_PHY_UPDATE */ +#define PARAM_UPDATE_ITERATION_MAX 20 +#endif /* !CONFIG_TEST_PHY_UPDATE */ +static uint32_t param_update_countdown; +static uint32_t param_update_iteration; +static uint32_t param_update_count; +static uint8_t param_update_idx; + +#define CONN_TIMEOUT(_timeout) \ + BT_GAP_US_TO_CONN_TIMEOUT(DIV_ROUND_UP(MAX(100000U, (_timeout)), \ + 10U * USEC_PER_MSEC) * 10U * USEC_PER_MSEC) + static void phy_update_iterate(struct bt_conn *conn) { const struct bt_conn_le_phy_param phy_param[] = { @@ -95,11 +114,16 @@ static void phy_update_iterate(struct bt_conn *conn) phy_update_countdown = PHY_UPDATE_COUNTDOWN; - phy_param_idx++; if (phy_param_idx >= ARRAY_SIZE(phy_param)) { - /* No more PHY updates, stay at the last index */ - phy_param_idx = ARRAY_SIZE(phy_param); - return; + if (IS_ENABLED(CONFIG_TEST_PHY_UPDATE)) { + /* No more PHY updates, stay at the last index */ + return; + } + + /* Test PHY Update not enabled, lets continue with connection update iterations + * forever. + */ + phy_param_idx = 0U; } struct bt_conn_info conn_info; @@ -132,6 +156,8 @@ static void phy_update_iterate(struct bt_conn *conn) printk("Failed to update PHY (%d).\n", err); return; } + + phy_param_idx++; } /* Interval between storing the measured write rate */ @@ -145,6 +171,7 @@ static uint32_t write_rate; /* Globals, reused by central_gatt_write and peripheral_gatt_write samples */ struct bt_conn *conn_connected; uint32_t last_write_rate; +uint32_t *write_countdown; void (*start_scan_func)(void); static void write_cmd_cb(struct bt_conn *conn, void *user_data) @@ -178,6 +205,113 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) phy_update_iterate(conn); } + /* NOTE: Though minimum connection timeout permitted is 100 ms, to avoid supervision + * timeout when observer role is enabled in the sample, keep the timeout for + * smaller connection interval be large enough due to repeated overlaps by the + * scan window. + */ + const struct bt_le_conn_param update_params[] = {{ + + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(51250U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(51250U), + .latency = 0, + .timeout = CONN_TIMEOUT(51250U * 6U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .latency = 0, + .timeout = CONN_TIMEOUT(50000U * 6U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(8750U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(8750U), + .latency = 0, + .timeout = CONN_TIMEOUT(720000U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(7500U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(7500U), + .latency = 0, + .timeout = CONN_TIMEOUT(720000U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .latency = 0, + .timeout = CONN_TIMEOUT(50000U * 6U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(51250U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(51250U), + .latency = 0, + .timeout = CONN_TIMEOUT(51250U * 6U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(7500U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(7500U), + .latency = 0, + .timeout = CONN_TIMEOUT(720000U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(8750U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(8750U), + .latency = 0, + .timeout = CONN_TIMEOUT(720000U), + }, { + .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), + .latency = 0, + .timeout = CONN_TIMEOUT(50000U * 6U), + }, + }; + int err; + + if ((param_update_countdown--) != 0U) { + return; + } + + param_update_countdown = PARAM_UPDATE_COUNTDOWN; + + if (param_update_idx >= ARRAY_SIZE(update_params)) { + if (IS_ENABLED(CONFIG_TEST_CONN_UPDATE) && + (--param_update_iteration == 0U)) { + /* No more conn updates, stay at the last index */ + param_update_iteration = 1U; + + if (IS_ENABLED(CONFIG_BT_OBSERVER) && + !IS_ENABLED(CONFIG_TEST_PHY_UPDATE)) { + /* Stop scanning. We will keep calling on every complete + * countdown. This is ok, for implementation simplicity, + * i.e.not adding addition design. + */ + err = bt_le_scan_stop(); + if (err != 0) { + printk("Failed to stop scanning (%d).\n", err); + } + + printk("Scanning stopped.\n"); + + *write_countdown = COUNT_THROUGHPUT; + } + + return; + } + + /* Test Connection Update not enabled, lets continue with connection update + * iterations forever. + */ + param_update_idx = 0U; + } + + param_update_count++; + + printk("Parameter Update Count: %u. %u: 0x%x 0x%x %u %u\n", param_update_count, + param_update_idx, + update_params[param_update_idx].interval_min, + update_params[param_update_idx].interval_max, + update_params[param_update_idx].latency, + update_params[param_update_idx].timeout); + err = bt_conn_le_param_update(conn, &update_params[param_update_idx]); + if (err != 0) { + printk("Parameter update failed (err %d)\n", err); + } + + param_update_idx++; + } else { uint16_t len; @@ -226,7 +360,7 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (conn_err) { - printk("%s: Failed to connect to %s (%u)\n", __func__, addr, + printk("%s: Failed to connect to %s (0x%02x)\n", __func__, addr, conn_err); return; } @@ -256,6 +390,17 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) phy_update_countdown = PHY_UPDATE_COUNTDOWN; phy_param_idx = 0U; } + + /* Every 1 second the acknowledged total GATT Write without Response data size is used for + * the throughput calculation. + * PHY update is performed in reference to this calculation interval, and connection update + * is offset by 1 of this interval so that connection update is initiated one such interval + * after PHY update was requested. + */ + param_update_countdown = PARAM_UPDATE_COUNTDOWN + 1U; + param_update_iteration = PARAM_UPDATE_ITERATION_MAX; + param_update_count = 0U; + param_update_idx = 0U; } static void disconnected(struct bt_conn *conn, uint8_t reason) @@ -272,7 +417,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) return; } - printk("%s: %s role %u, reason %u %s\n", __func__, addr, conn_info.role, + printk("%s: %s role %u, reason 0x%02x %s\n", __func__, addr, conn_info.role, reason, bt_hci_err_to_str(reason)); conn_connected = NULL; @@ -366,28 +511,28 @@ int write_cmd(struct bt_conn *conn) data_len_max = BT_ATT_MAX_ATTRIBUTE_LEN; } -#if TEST_FRAGMENTATION_WITH_VARIABLE_LENGTH_DATA - /* Use incremental length data for every write command */ - /* TODO: Include test case in BabbleSim tests */ - static bool decrement; - - if (decrement) { - data_len--; - if (data_len <= 1) { - data_len = 1; - decrement = false; + if (IS_ENABLED(CONFIG_USE_VARIABLE_LENGTH_DATA)) { + /* Use incremental length data for every write command */ + /* TODO: Include test case in BabbleSim tests */ + static bool decrement; + + if (decrement) { + data_len--; + if (data_len <= 1) { + data_len = 1; + decrement = false; + } + } else { + data_len++; + if (data_len >= data_len_max) { + data_len = data_len_max; + decrement = true; + } } } else { - data_len++; - if (data_len >= data_len_max) { - data_len = data_len_max; - decrement = true; - } + /* Use fixed length data for every write command */ + data_len = data_len_max; } -#else - /* Use fixed length data for every write command */ - data_len = data_len_max; -#endif /* Pass the 16-bit data length value (instead of reference) in * user_data so that unique value is pass for each write callback. diff --git a/samples/bluetooth/peripheral_gatt_write/Kconfig b/samples/bluetooth/peripheral_gatt_write/Kconfig new file mode 100644 index 0000000000000..f4d630ef8a513 --- /dev/null +++ b/samples/bluetooth/peripheral_gatt_write/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "samples/bluetooth/central_gatt_write/Kconfig.gatt_write" +source "Kconfig.zephyr" diff --git a/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c b/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c index 0823d90b27741..ba2452c71c6cd 100644 --- a/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c +++ b/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c @@ -16,6 +16,7 @@ extern int mtu_exchange(struct bt_conn *conn); extern int write_cmd(struct bt_conn *conn); extern struct bt_conn *conn_connected; extern uint32_t last_write_rate; +extern uint32_t *write_countdown; static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), @@ -49,6 +50,23 @@ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = mtu_updated }; +#if defined(CONFIG_BT_OBSERVER) && !defined(CONFIG_TEST_PHY_UPDATE) +#define BT_LE_SCAN_PASSIVE_ALLOW_DUPILCATES \ + BT_LE_SCAN_PARAM(BT_LE_SCAN_TYPE_PASSIVE, \ + BT_LE_SCAN_OPT_NONE, \ + BT_GAP_SCAN_FAST_INTERVAL_MIN, \ + BT_GAP_SCAN_FAST_INTERVAL_MIN) + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, rssi); +} +#endif /* CONFIG_BT_OBSERVER && !CONFIG_TEST_PHY_UPDATE */ + uint32_t peripheral_gatt_write(uint32_t count) { int err; @@ -63,6 +81,17 @@ uint32_t peripheral_gatt_write(uint32_t count) bt_gatt_cb_register(&gatt_callbacks); +#if defined(CONFIG_BT_OBSERVER) && !defined(CONFIG_TEST_PHY_UPDATE) + printk("Start continuous passive scanning..."); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_ALLOW_DUPILCATES, + device_found); + if (err) { + printk("Scan start failed (%d).\n", err); + return err; + } + printk("success.\n"); +#endif /* CONFIG_BT_OBSERVER && !CONFIG_TEST_PHY_UPDATE */ + #if defined(CONFIG_BT_SMP) (void)bt_conn_auth_cb_register(&auth_callbacks); #endif /* CONFIG_BT_SMP */ @@ -85,6 +114,7 @@ uint32_t peripheral_gatt_write(uint32_t count) conn_connected = NULL; last_write_rate = 0U; + write_countdown = &count; while (true) { struct bt_conn *conn = NULL; @@ -103,6 +133,10 @@ uint32_t peripheral_gatt_write(uint32_t count) bt_conn_unref(conn); if (count) { + if ((count % 1000U) == 0U) { + printk("GATT Write countdown %u\n", count); + } + count--; if (!count) { break; diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh index 8943a9605ad37..86d560ed956c4 100755 --- a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh @@ -17,6 +17,7 @@ ${ZEPHYR_BASE}/tests/bsim/bluetooth/tester/compile.sh app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/throughput sysbuild=1 compile +app=tests/bsim/bluetooth/ll/throughput conf_overlay=overlay-no_phy_update.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/multiple_id sysbuild=1 compile app=tests/bsim/bluetooth/ll/bis conf_overlay=overlay-sequential.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/bis conf_overlay=overlay-interleaved.conf sysbuild=1 compile diff --git a/tests/bsim/bluetooth/compile.nrf54l15bsim_nrf54l15_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf54l15bsim_nrf54l15_cpuapp.sh index e0524dbbdeaa6..9db8bbcf8d25d 100755 --- a/tests/bsim/bluetooth/compile.nrf54l15bsim_nrf54l15_cpuapp.sh +++ b/tests/bsim/bluetooth/compile.nrf54l15bsim_nrf54l15_cpuapp.sh @@ -14,6 +14,7 @@ export BOARD="${BOARD:-nrf54l15bsim/nrf54l15/cpuapp}" source ${ZEPHYR_BASE}/tests/bsim/compile.source app=tests/bsim/bluetooth/ll/throughput compile +app=tests/bsim/bluetooth/ll/throughput conf_overlay=overlay-no_phy_update.conf compile app=tests/bsim/bluetooth/ll/multiple_id compile app=tests/bsim/bluetooth/ll/bis conf_overlay=overlay-sequential.conf compile app=tests/bsim/bluetooth/ll/bis conf_overlay=overlay-interleaved.conf compile diff --git a/tests/bsim/bluetooth/ll/compile.sh b/tests/bsim/bluetooth/ll/compile.sh index 87b1f3006addf..d5058386824d6 100755 --- a/tests/bsim/bluetooth/ll/compile.sh +++ b/tests/bsim/bluetooth/ll/compile.sh @@ -41,5 +41,6 @@ app=tests/bsim/bluetooth/ll/edtt/gatt_test_app \ app=tests/bsim/bluetooth/ll/multiple_id compile app=tests/bsim/bluetooth/ll/throughput compile +app=tests/bsim/bluetooth/ll/throughput conf_overlay=overlay-no_phy_update.conf compile wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/throughput/Kconfig b/tests/bsim/bluetooth/ll/throughput/Kconfig new file mode 100644 index 0000000000000..38907af4ad30d --- /dev/null +++ b/tests/bsim/bluetooth/ll/throughput/Kconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config TEST_CONN_UPDATE + bool "Test Connection Update" + default y + help + Test Connection Update for a single iteration. + +config TEST_PHY_UPDATE + bool "Test PHY Update" + depends on BT_USER_PHY_UPDATE + default y + help + Test PHY Update for a single iteration. + +menu "Zephyr Kernel" +source "Kconfig.zephyr" +endmenu diff --git a/tests/bsim/bluetooth/ll/throughput/overlay-no_phy_update.conf b/tests/bsim/bluetooth/ll/throughput/overlay-no_phy_update.conf new file mode 100644 index 0000000000000..5bbfc6422b603 --- /dev/null +++ b/tests/bsim/bluetooth/ll/throughput/overlay-no_phy_update.conf @@ -0,0 +1,2 @@ +# Disable user initiated PHY update support +CONFIG_BT_USER_PHY_UPDATE=n diff --git a/tests/bsim/bluetooth/ll/throughput/src/main.c b/tests/bsim/bluetooth/ll/throughput/src/main.c index a18801d40669b..64e818d4a4e5b 100644 --- a/tests/bsim/bluetooth/ll/throughput/src/main.c +++ b/tests/bsim/bluetooth/ll/throughput/src/main.c @@ -16,15 +16,26 @@ #include "time_machine.h" #include "bstests.h" -/* There are 13 iterations of PHY update every 3 seconds, and based on actual - * simulation 10000 iterations are sufficient to finish these iterations with +/* There are 13 iterations of PHY update every 5 seconds, and based on actual + * simulation COUNT iterations are sufficient to finish these iterations with * a stable 2M throughput value to be verified. If Central and Peripheral take * different duration to complete these iterations, the test will fail due to * the throughput calculated over one second duration will be low due to the * connection being disconnected before the other device could complete all the * iterations. + * If the PHY and connection update iterations complete before the below number + * of iterations, then a COUNT_THROUGHPUT number of write operations are + * performed and throughput calculated. Note, `count` value in the central and + * peripheral sample is referenced using a pointer and the pointer will be used + * to setup the throughput measurement countdown. */ -#define COUNT 10000 +#if defined(CONFIG_BT_USER_PHY_UPDATE) +#define COUNT_CENTRAL 17000U +#define COUNT_PERIPHERAL 17600U +#else /* !CONFIG_BT_USER_PHY_UPDATE */ +#define COUNT_CENTRAL 180000U +#define COUNT_PERIPHERAL 180000U +#endif /* !CONFIG_BT_USER_PHY_UPDATE */ /* Write Throughput calculation: * Measure interval = 1 s @@ -64,7 +75,7 @@ static void test_central_main(void) { uint32_t write_rate; - write_rate = central_gatt_write(COUNT); + write_rate = central_gatt_write(COUNT_CENTRAL); printk("%s: Write Rate = %u bps\n", __func__, write_rate); if (write_rate == WRITE_RATE) { @@ -83,7 +94,7 @@ static void test_peripheral_main(void) { uint32_t write_rate; - write_rate = peripheral_gatt_write(COUNT); + write_rate = peripheral_gatt_write(COUNT_PERIPHERAL); printk("%s: Write Rate = %u bps\n", __func__, write_rate); if (write_rate == WRITE_RATE) { @@ -95,7 +106,7 @@ static void test_peripheral_main(void) static void test_gatt_write_init(void) { - bst_ticker_set_next_tick_absolute(60e6); + bst_ticker_set_next_tick_absolute(1500e6); bst_result = In_progress; } diff --git a/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh index 61fd4bc8edcc4..32f4fed6a0597 100755 --- a/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh +++ b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor ASA # Copyright 2018 Oticon A/S # SPDX-License-Identifier: Apache-2.0 @@ -6,7 +7,7 @@ source ${ZEPHYR_BASE}/tests/bsim/sh_common.source simulation_id="ll-throughput" verbosity_level=2 -EXECUTE_TIMEOUT=240 +EXECUTE_TIMEOUT=180 cd ${BSIM_OUT_PATH}/bin @@ -19,6 +20,6 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_ll_throughput_prj_conf\ -testid=peripheral Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=60e6 $@ -argschannel -at=40 + -D=2 -sim_length=120e6 $@ -argschannel -at=40 wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write_no_phy_update.sh b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write_no_phy_update.sh new file mode 100755 index 0000000000000..abe3cf9df7b01 --- /dev/null +++ b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write_no_phy_update.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2018 Oticon A/S +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="ll-throughput-no-phy-update" +verbosity_level=2 +EXECUTE_TIMEOUT=2400 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_ll_throughput_prj_conf_overlay-no_phy_update_conf \ + -v=${verbosity_level} -s=${simulation_id} -RealEncryption=1 -d=0 \ + -testid=central + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_ll_throughput_prj_conf_overlay-no_phy_update_conf \ + -v=${verbosity_level} -s=${simulation_id} -RealEncryption=1 -d=1 \ + -testid=peripheral + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=1500e6 $@ -argschannel -at=40 + +wait_for_background_jobs From a905be5fb39d091e4b1c218606ac81e2ba4dea50 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Jul 2025 14:16:27 +0200 Subject: [PATCH 0201/1076] tests: bsim: Bluetooth: Fail throughput test with increased Tx count Make the throughput test to fail when increasing Tx buffers that will delay a LE Connection Ind PDU from being transmitted on air due to previously queued Data PDUs. Unlike legacy Zephyr Controller's double headed Tx queue linked list, the new split Zephyr Controller's new LLCP does not place a control PDU at the head of the queue causing control PDUs to be delayed on air. Signed-off-by: Vinayak Kariappa Chettimada --- tests/bsim/bluetooth/ll/throughput/prj.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bsim/bluetooth/ll/throughput/prj.conf b/tests/bsim/bluetooth/ll/throughput/prj.conf index e8848bbf25dbd..2306711e7141a 100644 --- a/tests/bsim/bluetooth/ll/throughput/prj.conf +++ b/tests/bsim/bluetooth/ll/throughput/prj.conf @@ -24,7 +24,7 @@ CONFIG_BT_BUF_CMD_TX_SIZE=255 # BT HCI Event Buffers # Greater than BT_BUF_ACL_TX_COUNT, to be able to receive Number of Completed Packets events -CONFIG_BT_BUF_EVT_RX_COUNT=4 +CONFIG_BT_BUF_EVT_RX_COUNT=7 CONFIG_BT_BUF_EVT_RX_SIZE=255 # BT HCI Discardable Event Buffers @@ -32,7 +32,7 @@ CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=3 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 # BT HCI ACL TX Data Buffers -CONFIG_BT_BUF_ACL_TX_COUNT=3 +CONFIG_BT_BUF_ACL_TX_COUNT=6 CONFIG_BT_BUF_ACL_TX_SIZE=251 # BT HCI ACL RX Data Buffers From 852422522c75c0e7bfab35de016e170bb0090caf Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sat, 5 Jul 2025 18:34:13 +0200 Subject: [PATCH 0202/1076] Bluetooth: Controller: Fix LLCP event_counter used during current event Fix LLCP to use event_counter in the current event to compare instant when trying to check instant passed on reception of PDU with instant. Fixes regression in commit e3e410aeed4e ("Bluetooth: Controller: Fix LLCP event_counter value used during prepare"). Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/ull_llcp_conn_upd.c | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c index 1f860ff49c545..e9d923355c4a2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c @@ -1219,11 +1219,9 @@ static void rp_cu_st_wait_tx_conn_update_ind(struct ll_conn *conn, struct proc_c } } -static void rp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, - void *param) +static void rp_cu_check_instant_by_counter(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, + uint16_t event_counter, void *param) { - uint16_t event_counter = ull_conn_event_counter_at_prepare(conn); - if (is_instant_reached_or_passed(ctx->data.cu.instant, event_counter)) { bool notify; @@ -1252,6 +1250,22 @@ static void rp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint } } +static void rp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, + void *param) +{ + uint16_t event_counter = ull_conn_event_counter_at_prepare(conn); + + rp_cu_check_instant_by_counter(conn, ctx, evt, event_counter, param); +} + +static void rp_cu_check_instant_rx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, + uint8_t evt, void *param) +{ + uint16_t event_counter = ull_conn_event_counter(conn); + + rp_cu_check_instant_by_counter(conn, ctx, evt, event_counter, param); +} + static void rp_cu_st_wait_rx_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -1267,15 +1281,17 @@ static void rp_cu_st_wait_rx_conn_update_ind(struct ll_conn *conn, struct proc_c /* Valid PDU */ if (cu_check_conn_ind_parameters(conn, ctx)) { - if (is_instant_not_passed(ctx->data.cu.instant, - ull_conn_event_counter(conn))) { + uint16_t event_counter = ull_conn_event_counter(conn); + + if (is_instant_not_passed(ctx->data.cu.instant, event_counter)) { /* Keep RX node to use for NTF */ llcp_rx_node_retain(ctx); ctx->state = RP_CU_STATE_WAIT_INSTANT; /* In case we only just received it in time */ - rp_cu_check_instant(conn, ctx, evt, param); + rp_cu_check_instant_rx_conn_update_ind(conn, ctx, evt, + param); break; } From 58091b181fd676695feef335d38d47dd28630c71 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Jul 2025 14:16:38 +0200 Subject: [PATCH 0203/1076] Bluetooth: Controller: Fix conn timeout due to delayed conn upd ind Unlike legacy Zephyr Controller's double headed Tx queue linked list, the new split Zephyr Controller's new LLCP does not place a control PDU at the head of the Tx queue causing control PDUs to be delayed on air. Pause the data enqueue until pending PDUs are transmitted across before enqueuing LE Connection Update Ind PDU, and thereafter resume other PDUs being enqueued again. There can still be connection timeout if enqueued PDUs are not being transmitted/acked during repeated retransmissions. Updated bap_unicast_audio_acl_disconnect test to not use random seed, to be similar to unicast_client test; to get it to pass without overlapping state/roles casing connection failed to be established after the changes in this PR. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 4 ++-- .../bluetooth/controller/ll_sw/ull_conn_internal.h | 2 +- .../bluetooth/controller/ll_sw/ull_llcp_conn_upd.c | 12 ++++++++++-- .../bluetooth/controller/ll_sw/ull_llcp_internal.h | 1 + subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c | 8 +++----- .../test_scripts/bap_unicast_audio_acl_disconnect.sh | 4 ++-- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index c25977526716a..e27b53d840235 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2975,7 +2975,7 @@ uint8_t ll_conn_set_path_loss_reporting(uint16_t handle, uint8_t enable) } #endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ -uint8_t ull_is_lll_tx_queue_empty(struct ll_conn *conn) +bool ull_conn_lll_tx_queue_is_empty(struct ll_conn *conn) { - return (memq_peek(conn->lll.memq_tx.head, conn->lll.memq_tx.tail, NULL) == NULL); + return memq_peek(conn->lll.memq_tx.head, conn->lll.memq_tx.tail, NULL) == NULL; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_internal.h b/subsys/bluetooth/controller/ll_sw/ull_conn_internal.h index 1c888fcf9e1e3..59b45579f0b01 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_internal.h @@ -138,7 +138,7 @@ void ull_conn_resume_rx_data(struct ll_conn *conn); /** * @brief Check if the lower link layer transmit queue is empty */ -uint8_t ull_is_lll_tx_queue_empty(struct ll_conn *conn); +bool ull_conn_lll_tx_queue_is_empty(struct ll_conn *conn); /** * @brief Set path loss parameters diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c index e9d923355c4a2..5fc5a261640f6 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c @@ -438,7 +438,9 @@ static void lp_cu_send_conn_update_ind_finalize(struct ll_conn *conn, struct pro static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { - if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) { + if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) || + (ull_tx_q_peek(&conn->tx_q) != NULL) || !ull_conn_lll_tx_queue_is_empty(conn)) { + llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); ctx->state = LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND; } else { /* ensure alloc of TX node, before possibly waiting for NTF node */ @@ -448,6 +450,7 @@ static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ct ctx->state = LP_CU_STATE_WAIT_NTF_AVAIL; } else { lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); + llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); } } } @@ -459,6 +462,7 @@ static void lp_cu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, case LP_CU_EVT_RUN: if (llcp_ntf_alloc_is_available()) { lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); + llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); } break; default: @@ -915,7 +919,9 @@ static void rp_cu_send_conn_update_ind_finalize(struct ll_conn *conn, struct pro static void rp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { - if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) { + if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) || + (ull_tx_q_peek(&conn->tx_q) != NULL) || !ull_conn_lll_tx_queue_is_empty(conn)) { + llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); ctx->state = RP_CU_STATE_WAIT_TX_CONN_UPDATE_IND; } else { /* ensure alloc of TX node, before possibly waiting for NTF node */ @@ -925,6 +931,7 @@ static void rp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ct ctx->state = RP_CU_STATE_WAIT_NTF_AVAIL; } else { rp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); + llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); } } } @@ -937,6 +944,7 @@ static void rp_cu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, if (llcp_ntf_alloc_is_available()) { /* If NTF node is now avail, so pick it up and continue */ rp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); + llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); } break; default: diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h index 446d78aeadb73..8c50558a08e1f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h @@ -47,6 +47,7 @@ enum llcp_tx_q_pause_data_mask { LLCP_TX_QUEUE_PAUSE_DATA_PHY_UPDATE = 0x02, LLCP_TX_QUEUE_PAUSE_DATA_DATA_LENGTH = 0x04, LLCP_TX_QUEUE_PAUSE_DATA_TERMINATE = 0x08, + LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD = 0x10, }; #if ((CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM <\ diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c index 38d3f85685e70..a9b48be2702f7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c @@ -542,12 +542,11 @@ static void lp_pu_send_phy_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8 static void lp_pu_send_phy_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { - if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) { + if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) || + (ull_tx_q_peek(&conn->tx_q) != NULL) || !ull_conn_lll_tx_queue_is_empty(conn)) { ctx->state = LP_PU_STATE_WAIT_TX_PHY_UPDATE_IND; } else { ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND; - - /* Allocate TX node */ ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); lp_pu_tx(conn, ctx, evt, param); } @@ -1011,14 +1010,13 @@ static void rp_pu_send_phy_update_ind(struct ll_conn *conn, struct proc_ctx *ctx { if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) || (llcp_rr_get_paused_cmd(conn) == PROC_PHY_UPDATE) || - !ull_is_lll_tx_queue_empty(conn)) { + (ull_tx_q_peek(&conn->tx_q) != NULL) || !ull_conn_lll_tx_queue_is_empty(conn)) { ctx->state = RP_PU_STATE_WAIT_TX_PHY_UPDATE_IND; } else { llcp_rr_set_paused_cmd(conn, PROC_CTE_REQ); ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND; ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); rp_pu_tx(conn, ctx, evt, param); - } } #endif /* CONFIG_BT_CENTRAL */ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh index d6ba945d80800..09c7d8217c557 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_unicast_audio_acl_disconnect.sh @@ -16,11 +16,11 @@ printf "\n\n======== Unicast Audio ACL Disconnect test =========\n\n" Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=unicast_client_acl_disconnect \ - -RealEncryption=1 -rs=23 -D=2 + -RealEncryption=1 -D=2 Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=unicast_server_acl_disconnect \ - -RealEncryption=1 -rs=28 -D=2 -start_offset=2e3 + -RealEncryption=1 -D=2 -start_offset=2e3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \ From c0fbfc3bb881df2e757b69de6748628b18f78311 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 25 Jul 2025 06:29:28 +0200 Subject: [PATCH 0204/1076] Bluetooth: Controller: Fix drift compensation on connection update Fix drift compensation applied late under high throughput at after the instant has passed for a connection update. Workaround test failures due to Zephyr Controller scheduling overlap causing Periodic Advertising Sync timeouts, ACL connection failed to be established or Controller assertion when having latency at the CIS setup instant. Workaround by using `-start_offset` to ensure that the ACL established does not overlap the sink being established. Relates to commit 5f852998d046 ("tests: bsim: Bluetooth: Workaround Zephyr Controller scheduling overlap"). Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/ll_sw/nordic/lll/lll_conn.c | 11 +++++++++++ .../audio/test_scripts/bap_bass_client_sync.sh | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index ea5028a00f104..5d18eb45431e7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -414,6 +414,17 @@ void lll_conn_isr_rx(void *param) cte_len = 0U; } +#if defined(CONFIG_BT_PERIPHERAL) + /* Lets close early so that drift compensation is calculated before this event overlaps + * with next interval. + * TODO: Optimize, to improve throughput, by removing this early close and using the drift + * compensation value in the overlapping next interval, if under high throughput + * scenarios. + */ + is_done = is_done || ((lll->role == BT_HCI_ROLE_PERIPHERAL) && + (lll->periph.window_size_event_us != 0U)); +#endif /* CONFIG_BT_PERIPHERAL */ + /* Decide on event continuation and hence Radio Shorts to use */ is_done = is_done || ((crc_ok) && (pdu_data_rx->md == 0) && diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh index 8e13d495d282f..6c3d71511d887 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh @@ -20,7 +20,8 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \ - -testid=bap_broadcast_assistant_client_sync -RealEncryption=1 -rs=46 -D=3 + -testid=bap_broadcast_assistant_client_sync -RealEncryption=1 -rs=46 -D=3 \ + -start_offset=2e3 Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster \ From 2b49185452007a6cc5ff7ff2ab01cac6cc4897d1 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 24 Jul 2025 21:17:28 +0200 Subject: [PATCH 0205/1076] Bluetooth: Controller: Fix window widening on connection update Fix window widening on connection update to current window widening periodic at the instant, and use new periodic window widening for subsequent new connection interval. Relates to commit 247037bd3e2a ("Bluetooth: Controller: Fix incorrect elapsed events value"). Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_conn.c | 11 ++--- .../ll_sw/nordic/lll/lll_peripheral.c | 25 +++++------- subsys/bluetooth/controller/ll_sw/ull_conn.c | 40 ++++++++++++------- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index 5d18eb45431e7..2d8ce316b9197 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -254,13 +254,10 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param) #if defined(CONFIG_BT_PERIPHERAL) if (lll->role == BT_HCI_ROLE_PERIPHERAL) { /* Accumulate window widening */ - lll->periph.window_widening_prepare_us += - lll->periph.window_widening_periodic_us * - (prepare_param->lazy + 1); - if (lll->periph.window_widening_prepare_us > - lll->periph.window_widening_max_us) { - lll->periph.window_widening_prepare_us = - lll->periph.window_widening_max_us; + lll->periph.window_widening_prepare_us += lll->periph.window_widening_periodic_us * + (prepare_param->lazy + 1); + if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { + lll->periph.window_widening_prepare_us = lll->periph.window_widening_max_us; } } #endif /* CONFIG_BT_PERIPHERAL */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c index 0ed7a63af8d8e..083a57fc412d7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c @@ -154,24 +154,21 @@ static int prepare_cb(struct lll_prepare_param *p) } /* Accumulate window widening */ - lll->periph.window_widening_prepare_us += - lll->periph.window_widening_periodic_us * (lll->lazy_prepare + 1U); - if (lll->periph.window_widening_prepare_us > - lll->periph.window_widening_max_us) { - lll->periph.window_widening_prepare_us = - lll->periph.window_widening_max_us; + lll->periph.window_widening_prepare_us += lll->periph.window_widening_periodic_us * + lll->lazy_prepare; + if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { + lll->periph.window_widening_prepare_us = lll->periph.window_widening_max_us; } - /* current window widening */ - lll->periph.window_widening_event_us += - lll->periph.window_widening_prepare_us; - lll->periph.window_widening_prepare_us = 0; - if (lll->periph.window_widening_event_us > - lll->periph.window_widening_max_us) { - lll->periph.window_widening_event_us = - lll->periph.window_widening_max_us; + /* Current window widening */ + lll->periph.window_widening_event_us += lll->periph.window_widening_prepare_us; + if (lll->periph.window_widening_event_us > lll->periph.window_widening_max_us) { + lll->periph.window_widening_event_us = lll->periph.window_widening_max_us; } + /* Pre-increment window widening */ + lll->periph.window_widening_prepare_us = lll->periph.window_widening_periodic_us; + /* current window size */ lll->periph.window_size_event_us += lll->periph.window_size_prepare_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index e27b53d840235..9b0b054fea81d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2400,43 +2400,52 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_ /* calculate the window widening and interval */ switch (lll->role) { + #if defined(CONFIG_BT_PERIPHERAL) case BT_HCI_ROLE_PERIPHERAL: /* Since LLL prepare doesn't get to run, accumulate window widening here */ lll->periph.window_widening_prepare_us += lll->periph.window_widening_periodic_us * - (conn->llcp.prep.lazy + 1); - if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { - lll->periph.window_widening_prepare_us = - lll->periph.window_widening_max_us; - } + conn->llcp.prep.lazy; - lll->periph.window_widening_prepare_us -= - lll->periph.window_widening_periodic_us * instant_latency; + /* Remove old window widening for the latency events */ + lll->periph.window_widening_prepare_us -= lll->periph.window_widening_periodic_us * + instant_latency; +#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) + conn->periph.ticks_to_offset = 0U; +#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ + + /* Calculate new window widening per connection event and permitted maximum value */ lll->periph.window_widening_periodic_us = DIV_ROUND_UP(((lll_clock_ppm_local_get() + lll_clock_ppm_get(conn->periph.sca)) * conn_interval_us), 1000000U); lll->periph.window_widening_max_us = (conn_interval_us >> 1U) - EVENT_IFS_US; - lll->periph.window_size_prepare_us = win_size * CONN_INT_UNIT_US; -#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) - conn->periph.ticks_to_offset = 0U; -#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ + /* Use requested window size for anchor point at instant, until successful sync */ + lll->periph.window_size_prepare_us = win_size * CONN_INT_UNIT_US; - lll->periph.window_widening_prepare_us += - lll->periph.window_widening_periodic_us * latency_upd; + /* Accumulated new window widening for latency events */ + lll->periph.window_widening_prepare_us += lll->periph.window_widening_periodic_us * + latency_upd; if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { lll->periph.window_widening_prepare_us = lll->periph.window_widening_max_us; } - ticks_at_expire -= HAL_TICKER_US_TO_TICKS(lll->periph.window_widening_periodic_us * - latency_upd); + /* Adjust for future window widening */ + ticks_at_expire -= HAL_TICKER_US_TO_TICKS_CEIL( + lll->periph.window_widening_periodic_us * latency_upd); + + /* Window Offset */ ticks_win_offset = HAL_TICKER_US_TO_TICKS((win_offset_us / CONN_INT_UNIT_US) * CONN_INT_UNIT_US); + + /* Periodic interval considering window widening */ periodic_us -= lll->periph.window_widening_periodic_us; + break; #endif /* CONFIG_BT_PERIPHERAL */ + #if defined(CONFIG_BT_CENTRAL) case BT_HCI_ROLE_CENTRAL: ticks_win_offset = HAL_TICKER_US_TO_TICKS(win_offset_us); @@ -2448,6 +2457,7 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_ ticks_win_offset += 1U; break; #endif /*CONFIG_BT_CENTRAL */ + default: LL_ASSERT(0); break; From 2d732e292aadc418e9d0f57143ca99878a40d5b6 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 6 Jul 2025 07:23:44 +0200 Subject: [PATCH 0206/1076] Bluetooth: Controller: Fix stuck forced continuation under throughput Fix stuck forced continuation of connection event under high throughput scenario. At near supervision timeout the force flag is set, but in the next connection event if full connection interval is used for data transmission and a subsequent request to abort happens it was not honoured causing the tx-rx chain to keep continuing until supervision timeout. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_conn.c | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index 2d8ce316b9197..4e825431334fc 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -165,15 +165,16 @@ int lll_conn_central_is_abort_cb(void *next, void *curr, { struct lll_conn *lll = curr; - /* Do not abort if near supervision timeout */ - if (lll->forced) { - return 0; - } + if (next != curr) { + /* Do not be aborted by a different event if near supervision timeout */ + if ((lll->forced == 1U) && (trx_cnt < 1U)) { + return 0; + } - /* Do not be aborted by same event if a single central trx has not been - * exchanged. - */ - if ((next == curr) && (trx_cnt < 1U)) { + } else if ((next == curr) && (trx_cnt < 1U)) { + /* Do not be aborted by same event if a single central's Rx has not completed. + * Cases where single trx duration can be greater than connection interval. + */ return -EBUSY; } @@ -187,15 +188,16 @@ int lll_conn_peripheral_is_abort_cb(void *next, void *curr, { struct lll_conn *lll = curr; - /* Do not abort if near supervision timeout */ - if (lll->forced) { - return 0; - } + if (next != curr) { + /* Do not be aborted by a different event if near supervision timeout */ + if ((lll->forced == 1U) && (tx_cnt < 1U)) { + return 0; + } - /* Do not be aborted by same event if a single peripheral trx has not - * been exchanged. - */ - if ((next == curr) && (tx_cnt < 1U)) { + } else if ((next == curr) && (tx_cnt < 1U)) { + /* Do not be aborted by same event if a single peripheral's Tx has not completed. + * Cases where single trx duration can be greater than connection interval. + */ return -EBUSY; } From 8ecb264fec14e55ac8015764978a64f7143fa959 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Jul 2025 12:27:43 +0200 Subject: [PATCH 0207/1076] Bluetooth: Controller: Disable connection event continuation on overlap Disable connection event continuation on overlap with same connection's next event. This implementation has bugs and needs to be fixed in subsequent commits. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_conn.c | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index 4e825431334fc..da33cbf369b3c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -69,6 +69,7 @@ static uint8_t crc_valid; static uint8_t is_aborted; static uint16_t tx_cnt; static uint16_t trx_cnt; +static uint8_t trx_busy_iteration; #if defined(CONFIG_BT_CTLR_LE_ENC) static uint8_t mic_state; @@ -153,6 +154,7 @@ void lll_conn_prepare_reset(void) crc_valid = 0U; crc_expire = 0U; is_aborted = 0U; + trx_busy_iteration = 0U; #if defined(CONFIG_BT_CTLR_LE_ENC) mic_state = LLL_CONN_MIC_NONE; @@ -160,6 +162,13 @@ void lll_conn_prepare_reset(void) } #if defined(CONFIG_BT_CENTRAL) +/* Number of times central event being aborted by same event instance be skipped */ +/* FIXME: Increasing this causes event pipeline overflow assertion, add LLL implementation to + * gracefully abort the deferred next event when -EBUSY is returned in this is_abort_cb + * interface. + */ +#define CENTRAL_TRX_BUSY_ITERATION_MAX 0 + int lll_conn_central_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb) { @@ -171,7 +180,10 @@ int lll_conn_central_is_abort_cb(void *next, void *curr, return 0; } - } else if ((next == curr) && (trx_cnt < 1U)) { + } else if ((next == curr) && (trx_cnt < 1U) && + (trx_busy_iteration < CENTRAL_TRX_BUSY_ITERATION_MAX)) { + trx_busy_iteration++; + /* Do not be aborted by same event if a single central's Rx has not completed. * Cases where single trx duration can be greater than connection interval. */ @@ -183,6 +195,13 @@ int lll_conn_central_is_abort_cb(void *next, void *curr, #endif /* CONFIG_BT_CENTRAL */ #if defined(CONFIG_BT_PERIPHERAL) +/* Number of times peripheral event being aborted by same event instance be skipped */ +/* FIXME: Increasing this causes event pipeline overflow assertion, add LLL implementation to + * gracefully abort the deferred next event when -EBUSY is returned in this is_abort_cb + * interface. + */ +#define PERIPHERAL_TRX_BUSY_ITERATION_MAX 0 + int lll_conn_peripheral_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb) { @@ -194,7 +213,10 @@ int lll_conn_peripheral_is_abort_cb(void *next, void *curr, return 0; } - } else if ((next == curr) && (tx_cnt < 1U)) { + } else if ((next == curr) && (tx_cnt < 1U) && + (trx_busy_iteration < PERIPHERAL_TRX_BUSY_ITERATION_MAX)) { + trx_busy_iteration++; + /* Do not be aborted by same event if a single peripheral's Tx has not completed. * Cases where single trx duration can be greater than connection interval. */ From c2eb901ea1d4ae00209c07166097073faac8108a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Jul 2025 16:12:59 +0200 Subject: [PATCH 0208/1076] Bluetooth: Controller: Introduce prepare deferred feature Introduce prepare being deferred due to previous events desire to continue. In such case the deferred prepare param will have the defer flag set. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/lll.h | 18 +++++- .../bluetooth/controller/ll_sw/lll_common.c | 2 + .../controller/ll_sw/nordic/lll/lll.c | 30 ++++++++-- .../controller/ll_sw/nordic/lll/lll_central.c | 13 ++++- .../controller/ll_sw/nordic/lll/lll_conn.c | 23 +++++--- .../ll_sw/nordic/lll/lll_peripheral.c | 13 ++++- subsys/bluetooth/controller/ll_sw/ull.c | 9 +-- subsys/bluetooth/controller/ll_sw/ull_adv.c | 3 +- .../bluetooth/controller/ll_sw/ull_central.c | 4 ++ subsys/bluetooth/controller/ll_sw/ull_conn.c | 7 ++- .../controller/ll_sw/ull_conn_types.h | 58 +++++++++++-------- .../controller/ll_sw/ull_peripheral.c | 3 + .../controller/common/src/helper_util.c | 6 +- 13 files changed, 135 insertions(+), 54 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/lll.h b/subsys/bluetooth/controller/ll_sw/lll.h index b5d8fffeac37f..f5d33c90d70cd 100644 --- a/subsys/bluetooth/controller/ll_sw/lll.h +++ b/subsys/bluetooth/controller/ll_sw/lll.h @@ -14,8 +14,6 @@ #define TICKER_USER_ID_ULL_LOW MAYFLY_CALL_ID_2 #define TICKER_USER_ID_THREAD MAYFLY_CALL_ID_PROGRAM -#define EVENT_PIPELINE_MAX 7 - #define ADV_INT_UNIT_US 625U #define SCAN_INT_UNIT_US 625U #define CONN_INT_UNIT_US 1250U @@ -194,6 +192,19 @@ enum { #define TICKER_ID_ULL_BASE ((TICKER_ID_LLL_PREEMPT) + 1) +/* Number of (connection interval) events that can occur per (connection) event length. + * These number of event's prepare will be deferred if overlapping a single Tx-Rx chain. + */ +#if defined(CONFIG_BT_CTLR_PHY_CODED) +/* Connection events per 251 byte PDU Coded PHY S8 event length */ +#define EVENT_DEFER_MAX 4U +#elif defined(CONFIG_BT_CTLR_PHY_2M) +/* Low latency connection interval events per 27 byte PDU 2M PHY event length */ +#define EVENT_DEFER_MAX 1U +#else /* !CONFIG_BT_CTLR_PHY_CODED && !CONFIG_BT_CTLR_PHY_2M */ +#define EVENT_DEFER_MAX 0U +#endif /* !CONFIG_BT_CTLR_PHY_CODED && !CONFIG_BT_CTLR_PHY_2M */ + enum done_result { DONE_COMPLETED, DONE_ABORTED, @@ -236,7 +247,8 @@ struct lll_prepare_param { #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) int8_t prio; #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ - uint8_t force; + uint8_t force:1; + uint8_t defer:1; void *param; }; diff --git a/subsys/bluetooth/controller/ll_sw/lll_common.c b/subsys/bluetooth/controller/ll_sw/lll_common.c index ed35b4ddd0837..c6c561dbb76dc 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_common.c +++ b/subsys/bluetooth/controller/ll_sw/lll_common.c @@ -62,6 +62,8 @@ int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, prepare_param->prio = prio; #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ + prepare_param->defer = 0U; + err = lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb, prepare_param, 0U, 0U); return err; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 495c72bbf8cb3..4e3a6d9b51625 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -901,7 +901,7 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, LL_ASSERT(next); #if !defined(CONFIG_BT_CTLR_LOW_LAT) - if (is_resume) { + if (is_resume || prepare_param->defer) { return -EINPROGRESS; } @@ -1020,7 +1020,8 @@ static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx) do { ready = ull_prepare_dequeue_iter(idx); - } while (ready && (ready->is_aborted || ready->is_resume)); + } while ((ready != NULL) && ((ready->is_aborted != 0U) || (ready->is_resume != 0U) || + (ready->prepare_param.defer != 0U))); return ready; } @@ -1320,10 +1321,27 @@ static void preempt(void *param) /* Check if current event want to continue */ err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); if (!err || (err == -EBUSY)) { - /* Returns -EBUSY when same curr and next state/role, do not - * abort same curr and next event. - */ - if (err != -EBUSY) { + if (err == -EBUSY) { + uint32_t ret; + + /* Returns -EBUSY when same curr and next ready state/role, do not abort + * same curr and next ready event. + */ + ready->prepare_param.defer = 1U; + + /* Find next prepare that is ready and not a resume */ + ready = prepare_dequeue_iter_ready_get(&idx); + if (ready == NULL) { + /* No ready prepare */ + return; + } + + /* Start the preempt timeout for next ready prepare */ + ret = preempt_ticker_start(ready, NULL, ready); + LL_ASSERT((ret == TICKER_STATUS_SUCCESS) || + (ret == TICKER_STATUS_BUSY)); + + } else { /* Let preemptor LLL know about the cancelled prepare */ ready->is_aborted = 1; ready->abort_cb(&ready->prepare_param, ready->prepare_param.param); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central.c index 0fd8a368047e1..4f082b4957a40 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central.c @@ -247,12 +247,21 @@ static int prepare_cb(struct lll_prepare_param *p) overhead = lll_preempt_calc(ull, (TICKER_ID_CONN_BASE + lll->handle), ticks_at_event); /* check if preempt to start has changed */ if (overhead) { - LL_ASSERT_OVERHEAD(overhead); + int err; + + if (p->defer == 1U) { + /* We accept the overlap as previous event elected to continue */ + err = 0; + } else { + LL_ASSERT_OVERHEAD(overhead); + + err = -ECANCELED; + } radio_isr_set(lll_isr_abort, lll); radio_disable(); - return -ECANCELED; + return err; } #endif /* !CONFIG_BT_CTLR_XTAL_ADVANCED */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index da33cbf369b3c..1527987c02d02 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -163,11 +163,10 @@ void lll_conn_prepare_reset(void) #if defined(CONFIG_BT_CENTRAL) /* Number of times central event being aborted by same event instance be skipped */ -/* FIXME: Increasing this causes event pipeline overflow assertion, add LLL implementation to - * gracefully abort the deferred next event when -EBUSY is returned in this is_abort_cb - * interface. +/* NOTE: Coded PHY S8 coding of 251 byte PDU at 7.5 ms connection interval need up to 4 events + * to be skipped due to large connection event length. */ -#define CENTRAL_TRX_BUSY_ITERATION_MAX 0 +#define CENTRAL_TRX_BUSY_ITERATION_MAX MIN(4U, (EVENT_DEFER_MAX)) int lll_conn_central_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb) @@ -190,17 +189,18 @@ int lll_conn_central_is_abort_cb(void *next, void *curr, return -EBUSY; } + LL_ASSERT(trx_busy_iteration < CENTRAL_TRX_BUSY_ITERATION_MAX); + return -ECANCELED; } #endif /* CONFIG_BT_CENTRAL */ #if defined(CONFIG_BT_PERIPHERAL) /* Number of times peripheral event being aborted by same event instance be skipped */ -/* FIXME: Increasing this causes event pipeline overflow assertion, add LLL implementation to - * gracefully abort the deferred next event when -EBUSY is returned in this is_abort_cb - * interface. +/* NOTE: Coded PHY S8 coding of 251 byte PDU at 7.5 ms connection interval need up to 4 events + * to be skipped due to large connection event length. */ -#define PERIPHERAL_TRX_BUSY_ITERATION_MAX 0 +#define PERIPHERAL_TRX_BUSY_ITERATION_MAX MIN(4U, (EVENT_DEFER_MAX)) int lll_conn_peripheral_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb) @@ -223,6 +223,8 @@ int lll_conn_peripheral_is_abort_cb(void *next, void *curr, return -EBUSY; } + LL_ASSERT(trx_busy_iteration < PERIPHERAL_TRX_BUSY_ITERATION_MAX); + return -ECANCELED; } #endif /* CONFIG_BT_PERIPHERAL */ @@ -451,6 +453,11 @@ void lll_conn_isr_rx(void *param) (pdu_data_rx->md == 0) && (pdu_data_tx->md == 0) && (pdu_data_tx->len == 0)); + /* Do not continue anymore if this event had continued despite an abort requested by same + * connection instance when overlapping due to connection event length being larger than + * the connection interval. + */ + is_done = is_done || (trx_busy_iteration != 0U); if (is_done) { radio_isr_set(isr_done, param); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c index 083a57fc412d7..8c3b83efd7215 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c @@ -336,12 +336,21 @@ static int prepare_cb(struct lll_prepare_param *p) overhead = lll_preempt_calc(ull, (TICKER_ID_CONN_BASE + lll->handle), ticks_at_event); /* check if preempt to start has changed */ if (overhead) { - LL_ASSERT_OVERHEAD(overhead); + int err; + + if (p->defer == 1U) { + /* We accept the overlap as previous event elected to continue */ + err = 0; + } else { + LL_ASSERT_OVERHEAD(overhead); + + err = -ECANCELED; + } radio_isr_set(lll_isr_abort, lll); radio_disable(); - return -ECANCELED; + return err; } #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index b5d3705cd3363..d62d858d112ca 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -335,8 +335,9 @@ static struct k_sem sem_ticker_api_cb; static struct k_sem *sem_recv; /* Declare prepare-event FIFO: mfifo_prep. - * Queue of struct node_rx_event_done */ +#define EVENT_PIPELINE_MAX (7U + (EVENT_DEFER_MAX)) + static MFIFO_DEFINE(prep, sizeof(struct lll_event), EVENT_PIPELINE_MAX); /* Declare done-event RXFIFO. This is a composite pool-backed MFIFO for rx_nodes. @@ -371,12 +372,12 @@ static MFIFO_DEFINE(prep, sizeof(struct lll_event), EVENT_PIPELINE_MAX); #if !defined(VENDOR_EVENT_DONE_MAX) #if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_OBSERVER) #if defined(CONFIG_BT_CTLR_PHY_CODED) -#define EVENT_DONE_MAX 6 +#define EVENT_DONE_MAX (6U + EVENT_DEFER_MAX) #else /* !CONFIG_BT_CTLR_PHY_CODED */ -#define EVENT_DONE_MAX 5 +#define EVENT_DONE_MAX (5U + EVENT_DEFER_MAX) #endif /* !CONFIG_BT_CTLR_PHY_CODED */ #else /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_OBSERVER */ -#define EVENT_DONE_MAX 4 +#define EVENT_DONE_MAX (4U + EVENT_DEFER_MAX) #endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_OBSERVER */ #else #define EVENT_DONE_MAX VENDOR_EVENT_DONE_MAX diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index 911a433f81de8..18f3f24b11db2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -1095,7 +1095,8 @@ uint8_t ll_adv_enable(uint8_t enable) conn_lll->df_tx_cfg.is_initialized = 0U; conn_lll->df_tx_cfg.cte_rsp_en = 0U; #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */ - conn->connect_expire = 6; + conn->event_counter = 0U; + conn->connect_expire = CONN_ESTAB_COUNTDOWN; conn->supervision_expire = 0; #if defined(CONFIG_BT_CTLR_LE_PING) diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 396560bd64663..5759908a15d10 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -268,6 +268,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window, conn_lll->df_tx_cfg.cte_rsp_en = 0U; #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */ + conn->event_counter = 0U; conn->connect_expire = CONN_ESTAB_COUNTDOWN; conn->supervision_expire = 0U; conn_interval_us = (uint32_t)interval * CONN_INT_UNIT_US; @@ -945,6 +946,9 @@ void ull_central_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, ref = ull_ref_inc(&conn->ull); LL_ASSERT(ref); + /* Increment event counter */ + conn->event_counter += (lazy + 1U); + /* De-mux 2 tx node from FIFO, sufficient to be able to set MD bit */ ull_conn_tx_demux(2); diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 9b0b054fea81d..b68eaea195897 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2188,7 +2188,7 @@ void ull_conn_resume_rx_data(struct ll_conn *conn) uint16_t ull_conn_event_counter_at_prepare(const struct ll_conn *conn) { - return conn->lll.event_counter + conn->lll.latency_prepare + conn->llcp.prep.lazy; + return conn->event_counter + conn->llcp.prep.lazy; } uint16_t ull_conn_event_counter(struct ll_conn *conn) @@ -2388,6 +2388,11 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_ conn_interval_old_us - conn_interval_new_us); } + /* Adjust ULL event counter */ + conn->event_counter += conn->llcp.prep.lazy; + conn->event_counter -= (instant_latency - latency_upd); + + /* Adjust LLL prepare latency */ lll->latency_prepare += conn->llcp.prep.lazy; lll->latency_prepare -= (instant_latency - latency_upd); diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index f901f2ad3cad0..3dce4b52b2a89 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -167,31 +167,6 @@ struct ll_conn { struct ull_hdr ull; struct lll_conn lll; -#if defined(CONFIG_BT_CTLR_SYNC_TRANSFER_RECEIVER) - struct past_params past; -#endif /* CONFIG_BT_CTLR_SYNC_TRANSFER_RECEIVER */ - - struct ull_tx_q tx_q; - struct llcp_struct llcp; - - struct { - uint8_t reason_final; - /* node rx type with dummy uint8_t to ensure room for terminate - * reason. - * HCI will reference the value using the pdu member of - * struct node_rx_pdu. - * - */ - struct { - struct node_rx_pdu rx; - uint8_t dummy_reason; - } node_rx; - } llcp_terminate; - -/* - * TODO: all the following comes from the legacy LL llcp structure - * and/or needs to be properly integrated in the control procedures - */ union { struct { #if defined(CONFIG_BT_CTLR_CONN_META) @@ -220,14 +195,42 @@ struct ll_conn { #endif /* CONFIG_BT_CENTRAL */ }; + struct ull_tx_q tx_q; + struct llcp_struct llcp; + + /* ULL tracked connection event counter. Under LLL Prepare deferred cases this member + * accumulates the connection event count, necessary for LLCP instant use in ULL. + */ + uint16_t event_counter; + /* Cancel the prepare in the instant a Connection Update takes place */ uint8_t cancel_prepare:1; + /* + * TODO: all the following comes from the legacy LL llcp structure + * and/or needs to be properly integrated in the control procedures + */ + #if defined(CONFIG_BT_CTLR_LE_ENC) /* Pause Rx data PDU's */ uint8_t pause_rx_data:1; #endif /* CONFIG_BT_CTLR_LE_ENC */ + /* Terminate Procedure reason and event memory per connection */ + struct { + uint8_t reason_final; + /* node rx type with dummy uint8_t to ensure room for terminate + * reason. + * HCI will reference the value using the pdu member of + * struct node_rx_pdu. + * + */ + struct { + struct node_rx_pdu rx; + uint8_t dummy_reason; + } node_rx; + } llcp_terminate; + #if defined(CONFIG_BT_CTLR_LE_PING) uint16_t appto_reload; uint16_t appto_expire; @@ -244,6 +247,7 @@ struct ll_conn { uint8_t phy_pref_tx:3; uint8_t phy_pref_rx:3; #endif /* CONFIG_BT_CTLR_PHY */ + #if defined(CONFIG_BT_CTLR_DATA_LENGTH) uint16_t default_tx_octets; @@ -252,6 +256,10 @@ struct ll_conn { #endif /* CONFIG_BT_CTLR_PHY */ #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ +#if defined(CONFIG_BT_CTLR_SYNC_TRANSFER_RECEIVER) + struct past_params past; +#endif /* CONFIG_BT_CTLR_SYNC_TRANSFER_RECEIVER */ + #if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN) uint8_t own_id_addr_type:1; uint8_t peer_id_addr_type:1; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index ccc711d00aaa8..8032b18e99502 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -580,6 +580,9 @@ void ull_periph_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, ref = ull_ref_inc(&conn->ull); LL_ASSERT(ref); + /* Increment event counter */ + conn->event_counter += (lazy + 1U); + /* Append timing parameters */ p.ticks_at_expire = ticks_at_expire; p.remainder = remainder; diff --git a/tests/bluetooth/controller/common/src/helper_util.c b/tests/bluetooth/controller/common/src/helper_util.c index 5aeca45c90c8f..cac779f9e4e42 100644 --- a/tests/bluetooth/controller/common/src/helper_util.c +++ b/tests/bluetooth/controller/common/src/helper_util.c @@ -314,7 +314,7 @@ void test_set_role(struct ll_conn *conn, uint8_t role) void event_prepare(struct ll_conn *conn) { - struct lll_conn *lll; + struct lll_conn *lll = &conn->lll; uint32_t *evt_active = &(event_active[find_idx(conn)]); /* Can only be called with no active event */ @@ -323,11 +323,13 @@ void event_prepare(struct ll_conn *conn) /*** ULL Prepare ***/ + /* Event counter */ + conn->event_counter = lll->event_counter + lll->latency_prepare; + /* Handle any LL Control Procedures */ ull_cp_run(conn); /*** LLL Prepare ***/ - lll = &conn->lll; /* Save the latency for use in event */ lll->latency_prepare += lll->latency; From 93b951d6fb31fc499a0594dd4433fb9136944c4c Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Sun, 27 Jul 2025 12:13:50 +0200 Subject: [PATCH 0209/1076] Bluetooth: Controller: Fix prepare pipeline overflow in observer role Fix long standing bug in processing resume events that cause prepare pipeline overflow due to incorrectly enqueueing up preemptor events as duplicate events in the pipeline where being aborted before currently active event. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll.c | 53 ++++++++++++++----- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 4e3a6d9b51625..b44847c05850a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -71,7 +71,9 @@ static inline void done_inc(void); #endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ static inline bool is_done_sync(void); static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx); -static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb); +static inline struct lll_event *resume_enqueue(lll_is_abort_cb_t is_abort_cb, + lll_abort_cb_t abort_cb, lll_prepare_cb_t resume_cb, + void *param); static void isr_race(void *param); #if !defined(CONFIG_BT_CTLR_LOW_LAT) @@ -942,7 +944,16 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, LL_ASSERT(err); if (err == -EAGAIN) { - next = resume_enqueue(resume_cb); + void *curr_param; + + /* Remove parameter assignment from currently active radio event so + * that done event is not generated. + */ + curr_param = event.curr.param; + event.curr.param = NULL; + + next = resume_enqueue(event.curr.is_abort_cb, event.curr.abort_cb, + resume_cb, curr_param); LL_ASSERT(next); } else { LL_ASSERT(err == -ECANCELED); @@ -1026,19 +1037,15 @@ static inline struct lll_event *prepare_dequeue_iter_ready_get(uint8_t *idx) return ready; } -static inline struct lll_event *resume_enqueue(lll_prepare_cb_t resume_cb) +static inline struct lll_event *resume_enqueue(lll_is_abort_cb_t is_abort_cb, + lll_abort_cb_t abort_cb, lll_prepare_cb_t resume_cb, + void *param) { struct lll_prepare_param prepare_param = {0}; - /* Enqueue into prepare pipeline as resume radio event, and remove - * parameter assignment from currently active radio event so that - * done event is not generated. - */ - prepare_param.param = event.curr.param; - event.curr.param = NULL; + prepare_param.param = param; - return ull_prepare_enqueue(event.curr.is_abort_cb, event.curr.abort_cb, - &prepare_param, resume_cb, 1); + return ull_prepare_enqueue(is_abort_cb, abort_cb, &prepare_param, resume_cb, 1U); } static void isr_race(void *param) @@ -1355,9 +1362,27 @@ static void preempt(void *param) /* Check if resume requested */ if (err == -EAGAIN) { - uint8_t is_resume_abort = 0U; + lll_is_abort_cb_t is_abort_cb; + lll_abort_cb_t abort_cb; + uint8_t is_resume_abort; struct lll_event *iter; uint8_t iter_idx; + void *curr_param; + + /* Remove parameter assignment from currently active radio event so that done event + * is not generated. + */ + curr_param = event.curr.param; + event.curr.param = NULL; + + /* backup is_abort_cb and abort_cb */ + is_abort_cb = event.curr.is_abort_cb; + abort_cb = event.curr.abort_cb; + + /* Iterate twice to ensure preempt timeout is setup after all duplicate resume + * events are aborted. + */ + is_resume_abort = 0U; preempt_abort_resume: /* Abort any duplicate non-resume, that they get dequeued */ @@ -1366,7 +1391,7 @@ static void preempt(void *param) while (iter) { if (!iter->is_aborted && (is_resume_abort || !iter->is_resume) && - event.curr.param == iter->prepare_param.param) { + (curr_param == iter->prepare_param.param)) { iter->is_aborted = 1; iter->abort_cb(&iter->prepare_param, iter->prepare_param.param); @@ -1390,7 +1415,7 @@ static void preempt(void *param) } /* Enqueue as resume event */ - iter = resume_enqueue(resume_cb); + iter = resume_enqueue(is_abort_cb, abort_cb, resume_cb, curr_param); LL_ASSERT(iter); } else { LL_ASSERT(err == -ECANCELED); From 0d1b4d2ba6b5f46e7b76b49500ddd3d8dde28f2d Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Jul 2025 16:12:59 +0200 Subject: [PATCH 0210/1076] Bluetooth: Controller: Fix prepare pipeline for overlapping events Fix prepare pipeline processing of overlapping events by including ticks_at_expire value to uniquely identify overlapping events. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index d62d858d112ca..bf15820ecd6db 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -2150,6 +2150,8 @@ void *ull_prepare_dequeue_iter(uint8_t *idx) void ull_prepare_dequeue(uint8_t caller_id) { + uint32_t param_normal_head_ticks = 0U; + uint32_t param_normal_next_ticks = 0U; void *param_normal_head = NULL; void *param_normal_next = NULL; void *param_resume_head = NULL; @@ -2186,6 +2188,7 @@ void ull_prepare_dequeue(uint8_t caller_id) next = ull_prepare_dequeue_get(); while (next) { + uint32_t ticks = next->prepare_param.ticks_at_expire; void *param = next->prepare_param.param; uint8_t is_aborted = next->is_aborted; uint8_t is_resume = next->is_resume; @@ -2233,8 +2236,10 @@ void ull_prepare_dequeue(uint8_t caller_id) if (!is_resume) { if (!param_normal_head) { param_normal_head = param; + param_normal_head_ticks = ticks; } else if (!param_normal_next) { param_normal_next = param; + param_normal_next_ticks = ticks; } } else { if (!param_resume_head) { @@ -2250,16 +2255,15 @@ void ull_prepare_dequeue(uint8_t caller_id) */ if (!next->is_aborted && ((!next->is_resume && - ((next->prepare_param.param == - param_normal_head) || - (next->prepare_param.param == - param_normal_next))) || - (next->is_resume && - !param_normal_next && - ((next->prepare_param.param == - param_resume_head) || - (next->prepare_param.param == - param_resume_next))))) { + (((next->prepare_param.param == param_normal_head) && + (next->prepare_param.ticks_at_expire == + param_normal_head_ticks)) || + ((next->prepare_param.param == param_normal_next) && + (next->prepare_param.ticks_at_expire == + param_normal_next_ticks)))) || + (next->is_resume && !param_normal_next && + ((next->prepare_param.param == param_resume_head) || + (next->prepare_param.param == param_resume_next))))) { break; } } From 4277e9ae8b43edb95de5a4ed9342d000eedcbab0 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 4 Jul 2025 14:16:23 +0200 Subject: [PATCH 0211/1076] tests: bsim: Bluetooth: Param update implementation review rework Updated the test with review rework, and added comments. Signed-off-by: Vinayak Kariappa Chettimada --- .../central_gatt_write/Kconfig.gatt_write | 11 +++ .../src/central_gatt_write.c | 9 +++ .../src/gatt_write_common.c | 72 ++++++++++++++----- .../src/peripheral_gatt_write.c | 32 ++++++--- .../bluetooth/controller/ll_sw/ull_central.c | 8 ++- tests/bsim/bluetooth/ll/throughput/Kconfig | 17 +---- tests/bsim/bluetooth/ll/throughput/prj.conf | 4 ++ 7 files changed, 108 insertions(+), 45 deletions(-) diff --git a/samples/bluetooth/central_gatt_write/Kconfig.gatt_write b/samples/bluetooth/central_gatt_write/Kconfig.gatt_write index 99201a36b2d4f..7e1d9db3e0cfd 100644 --- a/samples/bluetooth/central_gatt_write/Kconfig.gatt_write +++ b/samples/bluetooth/central_gatt_write/Kconfig.gatt_write @@ -6,3 +6,14 @@ config USE_VARIABLE_LENGTH_DATA help Use increasing and decreasing length data in GATT Write without Response. + +config USE_CONN_UPDATE_ITERATION_ONCE + bool "Test Connection Update" + help + Perform Connection Update for a single iteration. + +config USE_PHY_UPDATE_ITERATION_ONCE + bool "Test PHY Update" + depends on BT_USER_PHY_UPDATE + help + Perform PHY Update for a single iteration. diff --git a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c index ae23785b1421a..cf2d4df3814e5 100644 --- a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c +++ b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c @@ -97,6 +97,12 @@ uint32_t central_gatt_write(uint32_t count) last_write_rate = 0U; write_countdown = &count; + if (count != 0U) { + printk("GATT Write countdown %u on connection.\n", count); + } else { + printk("GATT Write forever on connection.\n"); + } + #if defined(CONFIG_BT_USER_PHY_UPDATE) err = bt_conn_le_set_default_phy(BT_GAP_LE_PHY_1M, BT_GAP_LE_PHY_1M); if (err) { @@ -124,6 +130,9 @@ uint32_t central_gatt_write(uint32_t count) (void)write_cmd(conn); bt_conn_unref(conn); + /* Passing `0` will not use GATT Write Cmd countdown. + * Below code block will be optimized out by the linker. + */ if (count) { if ((count % 1000U) == 0U) { printk("GATT Write countdown %u\n", count); diff --git a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c index a86c05410b6b2..3f5d3436053a9 100644 --- a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c +++ b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c @@ -18,24 +18,46 @@ /* Count down number of metrics intervals before performing a PHY update */ #define PHY_UPDATE_COUNTDOWN 5U static uint32_t phy_update_countdown; + +/* Current index of the parameters array to initiate PHY Update */ static uint8_t phy_param_idx; /* Count down number of metrics intervals before performing a param update */ #define PARAM_UPDATE_COUNTDOWN PHY_UPDATE_COUNTDOWN -#if defined(CONFIG_TEST_PHY_UPDATE) -#define PARAM_UPDATE_ITERATION_MAX 1 -#else /* !CONFIG_TEST_PHY_UPDATE */ -#define PARAM_UPDATE_ITERATION_MAX 20 -#endif /* !CONFIG_TEST_PHY_UPDATE */ static uint32_t param_update_countdown; + +/* Current index of the parameters array to initiate Connection Update */ +static uint8_t param_update_idx; + +/* If testing PHY Update then perform one iteration of Connection Updates otherwise when testing + * Connection Updates perform 20 iterations. + */ +#define PARAM_UPDATE_ITERATION_MAX COND_CODE_1(CONFIG_USE_PHY_UPDATE_ITERATION_ONCE, (1U), (20U)) static uint32_t param_update_iteration; + +/* Total number of Connection Updates performed + * + * Used for logging purposes only + */ static uint32_t param_update_count; -static uint8_t param_update_idx; +/* Calculate the Supervision Timeout to a Rounded up 10 ms unit + * + * Conform to required BT Specifiction defined minimum Supervision Timeout of 100 ms + */ #define CONN_TIMEOUT(_timeout) \ - BT_GAP_US_TO_CONN_TIMEOUT(DIV_ROUND_UP(MAX(100000U, (_timeout)), \ + BT_GAP_US_TO_CONN_TIMEOUT(DIV_ROUND_UP(MAX(100U * USEC_PER_MSEC, (_timeout)), \ 10U * USEC_PER_MSEC) * 10U * USEC_PER_MSEC) +/* Relaxed number of Connection Interval to set the Supervision Timeout. + * Shall be >= 2U. + * + * Refer to BT Spec v6.1, Vol 6, Part B, Section 4.5.2 Supervision timeout + * + * `(1 + connPeripheralLatency) × connSubrateFactor × connInterval × 2` + */ +#define CONN_INTERVAL_MULTIPLIER (6U) + static void phy_update_iterate(struct bt_conn *conn) { const struct bt_conn_le_phy_param phy_param[] = { @@ -115,7 +137,7 @@ static void phy_update_iterate(struct bt_conn *conn) phy_update_countdown = PHY_UPDATE_COUNTDOWN; if (phy_param_idx >= ARRAY_SIZE(phy_param)) { - if (IS_ENABLED(CONFIG_TEST_PHY_UPDATE)) { + if (IS_ENABLED(CONFIG_USE_PHY_UPDATE_ITERATION_ONCE)) { /* No more PHY updates, stay at the last index */ return; } @@ -169,9 +191,16 @@ static uint32_t write_len; static uint32_t write_rate; /* Globals, reused by central_gatt_write and peripheral_gatt_write samples */ +/* Connection context used by the Write Cmd calls */ struct bt_conn *conn_connected; +/* Stores the latest calculated write rate, bits per second */ uint32_t last_write_rate; +/* Number of Write Commands used to record the latest write rate. + * Has to be large enough to be transmitting packets for METRICS_INTERVAL duration. + * Assign 0 to continue calculating latest write rate, forever or until disconnection. + */ uint32_t *write_countdown; +/* Function pointer used to restart scanning on ACL disconnect */ void (*start_scan_func)(void); static void write_cmd_cb(struct bt_conn *conn, void *user_data) @@ -211,16 +240,15 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) * scan window. */ const struct bt_le_conn_param update_params[] = {{ - .interval_min = BT_GAP_US_TO_CONN_INTERVAL(51250U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(51250U), .latency = 0, - .timeout = CONN_TIMEOUT(51250U * 6U), + .timeout = CONN_TIMEOUT(51250U * CONN_INTERVAL_MULTIPLIER), }, { .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), .latency = 0, - .timeout = CONN_TIMEOUT(50000U * 6U), + .timeout = CONN_TIMEOUT(50000U * CONN_INTERVAL_MULTIPLIER), }, { .interval_min = BT_GAP_US_TO_CONN_INTERVAL(8750U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(8750U), @@ -235,12 +263,12 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), .latency = 0, - .timeout = CONN_TIMEOUT(50000U * 6U), + .timeout = CONN_TIMEOUT(50000U * CONN_INTERVAL_MULTIPLIER), }, { .interval_min = BT_GAP_US_TO_CONN_INTERVAL(51250U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(51250U), .latency = 0, - .timeout = CONN_TIMEOUT(51250U * 6U), + .timeout = CONN_TIMEOUT(51250U * CONN_INTERVAL_MULTIPLIER), }, { .interval_min = BT_GAP_US_TO_CONN_INTERVAL(7500U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(7500U), @@ -255,7 +283,7 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) .interval_min = BT_GAP_US_TO_CONN_INTERVAL(50000U), .interval_max = BT_GAP_US_TO_CONN_INTERVAL(50000U), .latency = 0, - .timeout = CONN_TIMEOUT(50000U * 6U), + .timeout = CONN_TIMEOUT(50000U * CONN_INTERVAL_MULTIPLIER), }, }; int err; @@ -267,16 +295,26 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) param_update_countdown = PARAM_UPDATE_COUNTDOWN; if (param_update_idx >= ARRAY_SIZE(update_params)) { - if (IS_ENABLED(CONFIG_TEST_CONN_UPDATE) && + if (IS_ENABLED(CONFIG_USE_CONN_UPDATE_ITERATION_ONCE) && (--param_update_iteration == 0U)) { /* No more conn updates, stay at the last index */ param_update_iteration = 1U; + /* As this function is re-used by the peripheral; on target, users + * can enable simultaneous (background) scanning but by default do + * not have the scanning enabled. + * If both Central plus Peripheral role is built together then + * Peripheral is scanning (on 1M and Coded PHY windows) while there + * is simultaneous Write Commands. + * + * We stop scanning if we are stopping after one iteration of + * Connection Updates. + */ if (IS_ENABLED(CONFIG_BT_OBSERVER) && - !IS_ENABLED(CONFIG_TEST_PHY_UPDATE)) { + !IS_ENABLED(CONFIG_USE_PHY_UPDATE_ITERATION_ONCE)) { /* Stop scanning. We will keep calling on every complete * countdown. This is ok, for implementation simplicity, - * i.e.not adding addition design. + * i.e. not adding addition design. */ err = bt_le_scan_stop(); if (err != 0) { diff --git a/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c b/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c index ba2452c71c6cd..8fb2f8392fafc 100644 --- a/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c +++ b/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c @@ -50,7 +50,6 @@ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = mtu_updated }; -#if defined(CONFIG_BT_OBSERVER) && !defined(CONFIG_TEST_PHY_UPDATE) #define BT_LE_SCAN_PASSIVE_ALLOW_DUPILCATES \ BT_LE_SCAN_PARAM(BT_LE_SCAN_TYPE_PASSIVE, \ BT_LE_SCAN_OPT_NONE, \ @@ -65,7 +64,6 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); printk("Device found: %s (RSSI %d)\n", addr_str, rssi); } -#endif /* CONFIG_BT_OBSERVER && !CONFIG_TEST_PHY_UPDATE */ uint32_t peripheral_gatt_write(uint32_t count) { @@ -81,16 +79,22 @@ uint32_t peripheral_gatt_write(uint32_t count) bt_gatt_cb_register(&gatt_callbacks); -#if defined(CONFIG_BT_OBSERVER) && !defined(CONFIG_TEST_PHY_UPDATE) - printk("Start continuous passive scanning..."); - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_ALLOW_DUPILCATES, - device_found); - if (err) { - printk("Scan start failed (%d).\n", err); - return err; + /* On target, users can enable simultaneous (background) scanning but by default do not have + * the scanning enabled. + * If both Central plus Peripheral role is built together then + * Peripheral is scanning (on 1M and Coded PHY windows) while there + * is simultaneous Write Commands. + */ + if (IS_ENABLED(CONFIG_BT_OBSERVER) && !IS_ENABLED(CONFIG_USE_PHY_UPDATE_ITERATION_ONCE)) { + printk("Start continuous passive scanning..."); + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_ALLOW_DUPILCATES, + device_found); + if (err != 0) { + printk("Scan start failed (%d).\n", err); + return err; + } + printk("success.\n"); } - printk("success.\n"); -#endif /* CONFIG_BT_OBSERVER && !CONFIG_TEST_PHY_UPDATE */ #if defined(CONFIG_BT_SMP) (void)bt_conn_auth_cb_register(&auth_callbacks); @@ -116,6 +120,12 @@ uint32_t peripheral_gatt_write(uint32_t count) last_write_rate = 0U; write_countdown = &count; + if (count != 0U) { + printk("GATT Write countdown %u on connection.\n", count); + } else { + printk("GATT Write forever on connection.\n"); + } + while (true) { struct bt_conn *conn = NULL; diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 5759908a15d10..1771cda124bda 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -946,7 +946,13 @@ void ull_central_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, ref = ull_ref_inc(&conn->ull); LL_ASSERT(ref); - /* Increment event counter */ + /* Increment event counter. + * + * Refer to BT Spec v6.0, Vol 6, Part B, Section 4.5.1 Connection events + * + * `the connEventCounter shall wrap from 0xFFFF to 0x0000. This counter is used to + * synchronize Link Layer control procedures.` + */ conn->event_counter += (lazy + 1U); /* De-mux 2 tx node from FIFO, sufficient to be able to set MD bit */ diff --git a/tests/bsim/bluetooth/ll/throughput/Kconfig b/tests/bsim/bluetooth/ll/throughput/Kconfig index 38907af4ad30d..3c4be151e4dc6 100644 --- a/tests/bsim/bluetooth/ll/throughput/Kconfig +++ b/tests/bsim/bluetooth/ll/throughput/Kconfig @@ -1,19 +1,4 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config TEST_CONN_UPDATE - bool "Test Connection Update" - default y - help - Test Connection Update for a single iteration. - -config TEST_PHY_UPDATE - bool "Test PHY Update" - depends on BT_USER_PHY_UPDATE - default y - help - Test PHY Update for a single iteration. - -menu "Zephyr Kernel" -source "Kconfig.zephyr" -endmenu +source "$(ZEPHYR_BASE)/samples/bluetooth/central_gatt_write/Kconfig" diff --git a/tests/bsim/bluetooth/ll/throughput/prj.conf b/tests/bsim/bluetooth/ll/throughput/prj.conf index 2306711e7141a..5b699d7e892f0 100644 --- a/tests/bsim/bluetooth/ll/throughput/prj.conf +++ b/tests/bsim/bluetooth/ll/throughput/prj.conf @@ -17,6 +17,10 @@ CONFIG_BT_AUTO_DATA_LEN_UPDATE=y # Enable user initiated Data Length update support CONFIG_BT_USER_DATA_LEN_UPDATE=y +# Perform one iteration of PHY and Connection Updates +CONFIG_USE_CONN_UPDATE_ITERATION_ONCE=y +CONFIG_USE_PHY_UPDATE_ITERATION_ONCE=y + # BT HCI Command Buffers # Greater than BT_BUF_ACL_TX_COUNT, to be able to Send Host Number of Completed Packets commands CONFIG_BT_BUF_CMD_TX_COUNT=4 From 6c75315c86132740091fe4353000bdac293bd8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Duda?= Date: Mon, 4 Aug 2025 10:21:37 +0200 Subject: [PATCH 0212/1076] openthread: Use OPENTHREAD instead of L2_OPENTHREAD in dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Kconfig dependencies in mbedTLS and logging backend to use OPENTHREAD instead of NET_L2_OPENTHREAD. Signed-off-by: Łukasz Duda --- modules/mbedtls/Kconfig.mbedtls | 2 +- subsys/logging/backends/Kconfig.spinel | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.mbedtls b/modules/mbedtls/Kconfig.mbedtls index 9a2576559f006..4a71ec4961421 100644 --- a/modules/mbedtls/Kconfig.mbedtls +++ b/modules/mbedtls/Kconfig.mbedtls @@ -453,7 +453,7 @@ config MBEDTLS_ENTROPY_POLL_ZEPHYR config MBEDTLS_OPENTHREAD_OPTIMIZATIONS_ENABLED bool "MbedTLS optimizations for OpenThread" - depends on NET_L2_OPENTHREAD + depends on OPENTHREAD default y if !NET_SOCKETS_SOCKOPT_TLS help Enable some OpenThread specific mbedTLS optimizations that allows to diff --git a/subsys/logging/backends/Kconfig.spinel b/subsys/logging/backends/Kconfig.spinel index d2d29370aa35d..94ed1f040a94a 100644 --- a/subsys/logging/backends/Kconfig.spinel +++ b/subsys/logging/backends/Kconfig.spinel @@ -4,7 +4,7 @@ config LOG_BACKEND_SPINEL bool "OpenThread dedicated Spinel protocol backend" depends on !LOG_BACKEND_UART - depends on NET_L2_OPENTHREAD + depends on OPENTHREAD help When enabled, backend will use OpenThread dedicated SPINEL protocol for logging. This protocol is byte oriented and wraps given messages into serial frames. From 302ab40380dac1bac4daef74589087e5df90addf Mon Sep 17 00:00:00 2001 From: Khaoula Bidani Date: Tue, 26 Aug 2025 14:35:57 +0200 Subject: [PATCH 0213/1076] drivers: clock_control: stm32: fix compilation issue Fix compilation issue in test overlay without pll like hse_8_bypass.overlay and hsi_8.overlay Signed-off-by: Khaoula Bidani --- drivers/clock_control/clock_stm32_ll_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index ce417e7ab2635..67cab58816b39 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -612,7 +612,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, #endif /* STM32_TIMER_PRESCALER && (RCC_DCKCFGR_TIMPRE || RCC_DCKCFGR1_TIMPRE) */ break; #endif /* STM32_SRC_TIMPCLK2 */ -#if defined(STM32_SRC_TIMPLLCLK) +#if defined(STM32_SRC_TIMPLLCLK) && DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll)) case STM32_SRC_TIMPLLCLK: *rate = get_pllout_frequency() * 2; if (*rate == 0) { From 166e1a3b81e35b82554d75ebd4a97021c3f83e8c Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sun, 20 Jul 2025 18:31:42 +0200 Subject: [PATCH 0214/1076] drivers: udc_rpi_pico: use reset API No need to toggle reset line manually, use the standard reset API. This improves code searchability and aids debugging. Requires f2f496df8491192da7ebbbed8d4c1dc798ec805b to make sure reset deassertion is waited for. Signed-off-by: Dmitrii Sharshakov --- drivers/usb/udc/udc_rpi_pico.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/udc/udc_rpi_pico.c b/drivers/usb/udc/udc_rpi_pico.c index 0aa3cc7e44a5f..b0fb2fcf44f10 100644 --- a/drivers/usb/udc/udc_rpi_pico.c +++ b/drivers/usb/udc/udc_rpi_pico.c @@ -12,13 +12,13 @@ #include #include -#include #include #include #include #include #include +#include #include LOG_MODULE_REGISTER(udc_rpi_pico, CONFIG_UDC_DRIVER_LOG_LEVEL); @@ -36,6 +36,7 @@ struct rpi_pico_config { const struct device *clk_dev; struct pinctrl_dev_config *const pcfg; clock_control_subsys_t clk_sys; + const struct reset_dt_spec reset; }; struct rpi_pico_ep_data { @@ -1025,10 +1026,13 @@ static int udc_rpi_pico_enable(const struct device *dev) const struct pinctrl_dev_config *const pcfg = config->pcfg; usb_device_dpram_t *dpram = config->dpram; usb_hw_t *base = config->base; + int ret; /* Reset USB controller */ - reset_block(RESETS_RESET_USBCTRL_BITS); - unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + ret = reset_line_toggle_dt(&config->reset); + if (ret) { + return ret; + } /* Clear registers and DPRAM */ memset(base, 0, sizeof(usb_hw_t)); @@ -1296,6 +1300,7 @@ static const struct udc_api udc_rpi_pico_api = { .pcfg = UDC_RPI_PICO_PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clk_sys = (void *)DT_INST_PHA_BY_IDX(n, clocks, 0, clk_id), \ + .reset = RESET_DT_SPEC_INST_GET(n), \ }; \ \ static struct rpi_pico_data udc_priv_##n = { \ From 1a47cd95d8c0eda47c8d1bf32e69c41b7d0d9b3a Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 7 Aug 2025 13:09:24 +0200 Subject: [PATCH 0215/1076] power_domain: nrfs_gdpwr: patch init sync The nrfs_gdpwr driver has a two stage init, which requires tracking an "expected" state of the power domain, to be applied once the ipc service needed to control the power domain is ready. This was tracked with the "off" member of struct domain_data. So, "off" was initialized to false, but, should actually be initialized to true, since by default, if nothing needs the power domain, it should be turned off when ipc service is ready. To fix this, rename "off" member to "on" and adjust logic. Additionally, define the correct struct domain_data in the DOMAIN_DEFINE() macro. Can save 2 bytes. This did not cause any issue since we typecast it anyway, and its size is large enough. Signed-off-by: Bjarki Arge Andreasen --- drivers/power_domain/power_domain_nrfs_gdpwr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/power_domain/power_domain_nrfs_gdpwr.c b/drivers/power_domain/power_domain_nrfs_gdpwr.c index 64e83f5774bc1..16343293be583 100644 --- a/drivers/power_domain/power_domain_nrfs_gdpwr.c +++ b/drivers/power_domain/power_domain_nrfs_gdpwr.c @@ -26,7 +26,7 @@ static const struct device *const domains[] = { }; struct domain_data { - bool off; + bool on; bool synced; }; @@ -104,7 +104,7 @@ static int manager_set_domain(const struct device *dev, bool on) * is ready. */ ret = 0; - dev_data->off = !on; + dev_data->on = on; } if (ret == 0) { @@ -134,9 +134,9 @@ static int manager_sync_domain_locked(const struct device *dev) /* * Power domains initialize ON so we only need to send a request - * if the expected state of the power domain is OFF. + * if the expected state of the power domain is not ON. */ - if (dev_data->off) { + if (!dev_data->on) { return manager_set_domain_locked(dev_config->domain, false); } @@ -261,7 +261,7 @@ static int domain_init(const struct device *dev) _CONCAT(GDPWR_GD_, DT_NODE_FULL_NAME_UPPER_TOKEN(node)) #define DOMAIN_DEFINE(node) \ - static struct domain_config DOMAIN_NODE_SYMNAME(node, data); \ + static struct domain_data DOMAIN_NODE_SYMNAME(node, data); \ static const struct domain_config DOMAIN_NODE_SYMNAME(node, config) = { \ .domain = DOMAIN_NODE_TO_GDPWR_ENUM(node), \ }; \ From 8a0716de24c9477001c442398d0d08b0055198df Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 2 Jul 2025 10:39:26 +0700 Subject: [PATCH 0216/1076] arch: rx: Add bindings for RX CPU core version Adding bindings for rx cpu core version and remove the redundant compatible in the qemu_rx and rsk_rx130 boards Signed-off-by: Duy Nguyen --- boards/qemu/rx/qemu_rx.dts | 2 +- boards/renesas/rsk_rx130/rsk_rx130.dts | 2 +- dts/bindings/cpu/renesas,rxv1.yaml | 8 ++++++++ dts/bindings/cpu/renesas,rxv2.yaml | 8 ++++++++ dts/bindings/cpu/renesas,rxv3.yaml | 8 ++++++++ 5 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 dts/bindings/cpu/renesas,rxv1.yaml create mode 100644 dts/bindings/cpu/renesas,rxv2.yaml create mode 100644 dts/bindings/cpu/renesas,rxv3.yaml diff --git a/boards/qemu/rx/qemu_rx.dts b/boards/qemu/rx/qemu_rx.dts index 4b2f7672769fd..c7855d739663a 100644 --- a/boards/qemu/rx/qemu_rx.dts +++ b/boards/qemu/rx/qemu_rx.dts @@ -11,7 +11,7 @@ / { model = "Renesas QEMU"; - compatible = "qemu,rx","renesas,rxv1"; + compatible = "qemu,rx"; chosen { zephyr,sram = &sram0; diff --git a/boards/renesas/rsk_rx130/rsk_rx130.dts b/boards/renesas/rsk_rx130/rsk_rx130.dts index 90be043f2c2c9..0c30d47cd257c 100644 --- a/boards/renesas/rsk_rx130/rsk_rx130.dts +++ b/boards/renesas/rsk_rx130/rsk_rx130.dts @@ -14,7 +14,7 @@ / { model = "Renesas RSK+RX130-512KB KIT"; - compatible = "renesas,rsk_rx130_512kb","renesas,rxv1"; + compatible = "renesas,rsk_rx130_512kb"; chosen { zephyr,sram = &sram0; diff --git a/dts/bindings/cpu/renesas,rxv1.yaml b/dts/bindings/cpu/renesas,rxv1.yaml new file mode 100644 index 0000000000000..f48b766d5c88d --- /dev/null +++ b/dts/bindings/cpu/renesas,rxv1.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RXv1 CPU + +compatible: "renesas,rxv1" + +include: renesas,rx.yaml diff --git a/dts/bindings/cpu/renesas,rxv2.yaml b/dts/bindings/cpu/renesas,rxv2.yaml new file mode 100644 index 0000000000000..1f68a16bf34f4 --- /dev/null +++ b/dts/bindings/cpu/renesas,rxv2.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RXv2 CPU + +compatible: "renesas,rxv2" + +include: renesas,rx.yaml diff --git a/dts/bindings/cpu/renesas,rxv3.yaml b/dts/bindings/cpu/renesas,rxv3.yaml new file mode 100644 index 0000000000000..6da63d8d3a77c --- /dev/null +++ b/dts/bindings/cpu/renesas,rxv3.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RXv3 CPU + +compatible: "renesas,rxv3" + +include: renesas,rx.yaml From 8b4581ba1dd4df8213222ff0fcac969a054f5d4b Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Mon, 4 Aug 2025 08:03:37 +0000 Subject: [PATCH 0217/1076] arch: rx: Get swint register address from devicetree Update irq_offload to get the swint register address from dts Signed-off-by: Quy Tran --- arch/rx/core/irq_offload.c | 9 +++++---- dts/bindings/rx/renesas,rx-swint.yaml | 15 +++++++++++++++ dts/rx/renesas/rx-qemu.dtsi | 12 +++++++++++- dts/rx/renesas/rx130-common.dtsi | 12 +++++++++++- dts/rx/renesas/rx261-common.dtsi | 14 ++++++++++++-- 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 dts/bindings/rx/renesas,rx-swint.yaml diff --git a/arch/rx/core/irq_offload.c b/arch/rx/core/irq_offload.c index 9845bb4da8717..1364c0fda10b6 100644 --- a/arch/rx/core/irq_offload.c +++ b/arch/rx/core/irq_offload.c @@ -17,11 +17,12 @@ #include #include -#define SWINT1_IRQ_LINE 27 -#define SWINT1_PRIO 14 +#define SWINT1_NODE DT_NODELABEL(swint1) +#define SWINT1_IRQ_LINE DT_IRQN(SWINT1_NODE) +#define SWINT1_PRIO DT_IRQ(SWINT1_NODE, priority) /* Address of the software interrupt trigger register for SWINT1 */ -#define SWINT_REGISTER_ADDRESS 0x872E0 -#define SWINTR_SWINT *(uint8_t *)(SWINT_REGISTER_ADDRESS) +#define SWINT_REGISTER_ADDRESS DT_REG_ADDR(SWINT1_NODE) +#define SWINTR_SWINT *(uint8_t *)(SWINT_REGISTER_ADDRESS) static irq_offload_routine_t _offload_routine; static const void *offload_param; diff --git a/dts/bindings/rx/renesas,rx-swint.yaml b/dts/bindings/rx/renesas,rx-swint.yaml new file mode 100644 index 0000000000000..e510f6a2b7bae --- /dev/null +++ b/dts/bindings/rx/renesas,rx-swint.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RX SWINT (Software Interrupt) + +compatible: "renesas,rx-swint" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/rx/renesas/rx-qemu.dtsi b/dts/rx/renesas/rx-qemu.dtsi index 1fb6442eb99d9..f29b2c082fa0f 100644 --- a/dts/rx/renesas/rx-qemu.dtsi +++ b/dts/rx/renesas/rx-qemu.dtsi @@ -31,6 +31,8 @@ icu: interrupt-controller@87000 { #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; compatible = "renesas,rx-icu"; interrupt-controller; reg = <0x0087000 0xff>, @@ -40,7 +42,15 @@ <0x0087500 0x0f>, <0x0087510 0x01>, <0x0087514 0x01>; - reg-names = "IR", "IER", "IPR", "FIR","IRQCR","IRQFLTE","IRQFLTC0"; + reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0"; + + swint1: swint1@872e0 { + compatible = "renesas,rx-swint"; + reg = <0x000872e0 0x01>; + interrupts = <27 14>; + interrupt-parent = <&icu>; + status = "okay"; + }; }; clocks: clocks { diff --git a/dts/rx/renesas/rx130-common.dtsi b/dts/rx/renesas/rx130-common.dtsi index b7dd10272de39..314bd9d61b386 100644 --- a/dts/rx/renesas/rx130-common.dtsi +++ b/dts/rx/renesas/rx130-common.dtsi @@ -31,6 +31,8 @@ icu: interrupt-controller@87000 { #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; compatible = "renesas,rx-icu"; interrupt-controller; reg = <0x0087000 0xff>, @@ -40,7 +42,15 @@ <0x0087500 0x0f>, <0x0087510 0x01>, <0x0087514 0x01>; - reg-names = "IR", "IER", "IPR", "FIR","IRQCR","IRQFLTE","IRQFLTC0"; + reg-names = "IR", "IER", "IPR", "FIR", "IRQCR","IRQFLTE","IRQFLTC0"; + + swint1: swint1@872e0 { + compatible = "renesas,rx-swint"; + reg = <0x000872e0 0x01>; + interrupts = <27 14>; + interrupt-parent = <&icu>; + status = "okay"; + }; }; soc { diff --git a/dts/rx/renesas/rx261-common.dtsi b/dts/rx/renesas/rx261-common.dtsi index 49308688966e7..f538002321738 100644 --- a/dts/rx/renesas/rx261-common.dtsi +++ b/dts/rx/renesas/rx261-common.dtsi @@ -29,6 +29,8 @@ icu: interrupt-controller@87000 { #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; compatible = "renesas,rx-icu"; interrupt-controller; reg = <0x0087000 0xff>, @@ -38,8 +40,16 @@ <0x0087500 0x0f>, <0x0087510 0x01>, <0x0087514 0x01>; - reg-names = "IR", "IER", "IPR", "FIR","IRQCR","IRQFLTE","IRQFLTC0"; - }; /* icu */ + reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0"; + + swint1: swint1@872e0 { + compatible = "renesas,rx-swint"; + reg = <0x000872e0 0x01>; + interrupts = <27 14>; + interrupt-parent = <&icu>; + status = "okay"; + }; + }; soc { #address-cells = <1>; From d29af6ff16559a43f1e615cc1c360bcf5243bb5b Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 18 Jul 2025 09:50:23 +0000 Subject: [PATCH 0218/1076] arch: rx: Update Exception Vector Table handling for RX The RXv2, RXv3 feature with a configuration to be able to relocate the exception vector table by setting the extb register in the CPU, this commit support to enable the config and code handling for it Signed-off-by: Duy Nguyen --- arch/rx/Kconfig | 12 ++++--- arch/rx/core/vects.c | 56 ++++++++++++++++++++++++++++++++ include/zephyr/arch/rx/linker.ld | 14 +++++++- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/arch/rx/Kconfig b/arch/rx/Kconfig index 9e34a16ea099f..c57500f8730cb 100644 --- a/arch/rx/Kconfig +++ b/arch/rx/Kconfig @@ -11,6 +11,11 @@ config ARCH string default "rx" +config HAS_EXCEPT_VECTOR_TABLE + bool + help + Set if the processor has the exception vector table. + config CPU_RXV1 bool help @@ -18,19 +23,16 @@ config CPU_RXV1 config CPU_RXV2 bool + select HAS_EXCEPT_VECTOR_TABLE help Set if the processor supports the Renesas RXv2 instruction set. config CPU_RXV3 bool + select HAS_EXCEPT_VECTOR_TABLE help Set if the processor supports the Renesas RXv3 instruction set. -config HAS_EXCEPT_VECTOR_TABLE - bool - help - Set if the processor has the exception vector table. - config XIP default y diff --git a/arch/rx/core/vects.c b/arch/rx/core/vects.c index 6835aeb868017..ff0154475fdcb 100644 --- a/arch/rx/core/vects.c +++ b/arch/rx/core/vects.c @@ -425,6 +425,8 @@ INT_DEMUX(253); INT_DEMUX(254); INT_DEMUX(255); +#if !CONFIG_HAS_EXCEPT_VECTOR_TABLE + const void *FixedVectors[] FVECT_SECT = { /* 0x00-0x4c: Reserved, must be 0xff (according to e2 studio example) */ /* Reserved for OFSM */ @@ -476,6 +478,60 @@ const void *FixedVectors[] FVECT_SECT = { _start, }; +#else + +/* The reset vector ALWAYS is at address 0xFFFFFFFC. Set it to point at + * the start routine (in reset.S) + */ +const FVECT_SECT void *resetVector = _start; + +/* Exception vector table + * (see rx-family-rxv2-instruction-set-architecture-users-manual-software) + */ +const void *ExceptVectors[] EXVECT_SECT = { + /* 0x00-0x4c: Reserved, must be 0xff (according to e2 studio example) */ + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + (fp)0xFFFFFFFF, + /* 0x50: Privileged instruction exception */ + INT_Excep_SuperVisorInst, + /* 0x54: Access exception */ + INT_Excep_AccessInst, + /* 0x58: Reserved */ + Dummy, + /* 0x5c: Undefined Instruction Exception */ + INT_Excep_UndefinedInst, + /* 0x60: Reserved */ + Dummy, + /* 0x64: Floating Point Exception */ + INT_Excep_FloatingPoint, + /* 0x68-0x74: Reserved */ + Dummy, + Dummy, + Dummy, + Dummy, + /* 0x78: Non-maskable interrupt */ + INT_NonMaskableInterrupt, +}; +#endif + const fp RelocatableVectors[] RVECT_SECT = { reserved_isr, switch_isr_wrapper, INT_RuntimeFatalInterrupt, reserved_isr, reserved_isr, reserved_isr, diff --git a/include/zephyr/arch/rx/linker.ld b/include/zephyr/arch/rx/linker.ld index 4f310c1558387..de445543069a9 100644 --- a/include/zephyr/arch/rx/linker.ld +++ b/include/zephyr/arch/rx/linker.ld @@ -61,10 +61,22 @@ SECTIONS . = ROM_START; /* for kernel logging */ PLACE_SYMBOL_HERE(__rodata_region_start); - .fvectors 0xFFFFFF80: AT(0xFFFFFF80) +#if CONFIG_HAS_EXCEPT_VECTOR_TABLE + .exvectors 0xFFFFFF80: AT(0xFFFFFF80) + { + KEEP(*(.exvectors)) + } GROUP_LINK_IN(ROMABLE_REGION) + + .fvectors 0xFFFFFFFC: AT(0xFFFFFFFC) + { + KEEP(*(.fvectors)) + } GROUP_LINK_IN(ROMABLE_REGION) +#else + .fvectors 0xFFFFFF80: AT(0xFFFFFF80) { KEEP(*(.fvectors)) } GROUP_LINK_IN(ROMABLE_REGION) +#endif SECTION_PROLOGUE(_TEXT_SECTION_NAME,ROM_START,) { From eb61b44ee96915a8efd32d3b43ff9b3fc0ddec2a Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Mon, 4 Aug 2025 08:58:14 +0000 Subject: [PATCH 0219/1076] drivers: cmt: Update cmt driver for Renesas RX - Update sys_clock_set_timeout function for Renesas RX using CMT - Remove some unused definitions Signed-off-by: Quy Tran --- drivers/timer/renesas_rx_cmt.c | 55 +++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/drivers/timer/renesas_rx_cmt.c b/drivers/timer/renesas_rx_cmt.c index ff44000edeb2d..b013e05a610e9 100644 --- a/drivers/timer/renesas_rx_cmt.c +++ b/drivers/timer/renesas_rx_cmt.c @@ -19,13 +19,12 @@ #define CMT0_NODE DT_NODELABEL(cmt0) #define CMT1_NODE DT_NODELABEL(cmt1) +#define CMT1_IRQN DT_IRQN(CMT1_NODE) + #define ICU_NODE DT_NODELABEL(icu) -#define ICU_IR_ADDR DT_REG_ADDR_BY_NAME(ICU_NODE, IR) -#define ICU_IER_ADDR DT_REG_ADDR_BY_NAME(ICU_NODE, IER) -#define ICU_IPR_ADDR DT_REG_ADDR_BY_NAME(ICU_NODE, IPR) -#define ICU_FIR_ADDR DT_REG_ADDR_BY_NAME(ICU_NODE, FIR) -#define ICU_IR ((volatile uint8_t *)ICU_IR_ADDR) +#define ICU_IR_ADDR DT_REG_ADDR_BY_NAME(ICU_NODE, IR) +#define ICU_IR ((volatile uint8_t *)ICU_IR_ADDR) #define CMT0_IRQ_NUM DT_IRQ_BY_NAME(CMT0_NODE, cmi, irq) #define CMT1_IRQ_NUM DT_IRQ_BY_NAME(CMT1_NODE, cmi, irq) @@ -35,10 +34,9 @@ #define CYCLES_PER_SEC (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) #define TICKS_PER_SEC (CONFIG_SYS_CLOCK_TICKS_PER_SEC) #define CYCLES_PER_TICK (CYCLES_PER_SEC / TICKS_PER_SEC) +#define MAX_TICKS ((k_ticks_t)(COUNTER_MAX / CYCLES_PER_TICK) - 1) #define CYCLES_CYCLE_TIMER (COUNTER_MAX + 1) -#define MSTPCR_ADDR ((volatile uint32_t *)0x00080010) /* MSTPCR register address */ -#define MSTP_CMT0_BIT (1 << 15) /* Bit 15 controls MSTPA15 (CMT0) */ static const struct clock_control_rx_subsys_cfg cmt_clk_cfg = { .mstp = DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(0), 0, mstp), @@ -86,13 +84,13 @@ const int32_t z_sys_timer_irq_for_test = CMT0_IRQ_NUM; static cycle_t cmt1_elapsed(void) { uint32_t val1 = (uint32_t)(*cycle_timer_cfg.cmcnt); - uint8_t cmt_ir = ICU_IR[29]; + uint8_t cmt_ir = ICU_IR[CMT1_IRQN]; uint32_t val2 = (uint32_t)(*cycle_timer_cfg.cmcnt); if ((1 == cmt_ir) || (val1 > val2)) { cycle_count += CYCLES_CYCLE_TIMER; - ICU_IR[29] = 0; + ICU_IR[CMT1_IRQN] = 0; } return (val2 + cycle_count); @@ -211,17 +209,40 @@ static int sys_clock_driver_init(void) void sys_clock_set_timeout(int32_t ticks, bool idle) { - if (IS_ENABLED(CONFIG_TICKLESS_KERNEL) && idle && ticks == K_TICKS_FOREVER) { - *tick_timer_cfg.cmstr = 0x0000; /* stop cmt0,1 */ + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return; + } + + if (ticks == K_TICKS_FOREVER || ticks == INT32_MAX) { return; } -#if defined(CONFIG_TICKLESS_KERNEL) - /* - * By default, it is implemented as a no operation. - * Implement the processing as needed. - */ -#endif /* CONFIG_TICKLESS_KERNEL */ + ticks = CLAMP(ticks - 1, 0, (int32_t)MAX_TICKS); + + k_spinlock_key_t key = k_spin_lock(&lock); + + cycle_t now = cmt1_elapsed(); + cycle_t elapsed; + + if (now < announced_cycle_count) { + /* cycle_count overflowed */ + elapsed = (cycle_t)(now + (CYCLE_COUNT_MAX - announced_cycle_count + 1)); + } else { + elapsed = (now - announced_cycle_count); + } + + cycle_t delay = (cycle_t)ticks * CYCLES_PER_TICK; + + delay += elapsed; + delay = DIV_ROUND_UP(delay, CYCLES_PER_TICK) * CYCLES_PER_TICK; + delay -= elapsed; + + uint16_t current = *tick_timer_cfg.cmcnt; + uint16_t new_cmcor = (uint16_t)(current + delay - 1U); + + *tick_timer_cfg.cmcor = new_cmcor; + + k_spin_unlock(&lock, key); } SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); From de3a78bb9a93e977757f620a67eaf3f827e86f2e Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 2 Jul 2025 10:42:15 +0700 Subject: [PATCH 0220/1076] include: arch: rx: Change the ROM value by using KCONFIG Change the ROM_START and ROM_SIZE to using KCONFIG option same as other architecture Signed-off-by: Duy Nguyen --- include/zephyr/arch/rx/linker.ld | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/include/zephyr/arch/rx/linker.ld b/include/zephyr/arch/rx/linker.ld index de445543069a9..f0cdc4b18c9a9 100644 --- a/include/zephyr/arch/rx/linker.ld +++ b/include/zephyr/arch/rx/linker.ld @@ -26,10 +26,24 @@ #endif #define RAMABLE_REGION RAM -/* single bank configuration with 2 MB of code flash */ -#define ROM_START (DT_REG_ADDR(DT_NODELABEL(code_flash))) +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif -#define ROM_SIZE (DT_REG_SIZE(DT_NODELABEL(code_flash))) +#if defined(CONFIG_FLASH_LOAD_OFFSET) +#define FLASH_LOAD_OFFSET CONFIG_FLASH_LOAD_OFFSET +#else +#define FLASH_LOAD_OFFSET 0 +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_flash), okay) +#define ROM_START (CONFIG_FLASH_BASE_ADDRESS + FLASH_LOAD_OFFSET) +#ifndef ROM_SIZE +#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - ROM_END_OFFSET) +#endif +#endif #define RAM_START (CONFIG_SRAM_BASE_ADDRESS) #define RAM_SIZE (KB(CONFIG_SRAM_SIZE)) From 84c2f87540a8558d85e4860ff3765d0652cbbf1c Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 2 Jul 2025 10:45:25 +0700 Subject: [PATCH 0221/1076] dts: renesas: rx: Change CPU compatible for RX dts Change the compatible of CPU core for qemu_rx, rx130 and rx261 target accroding to the change of dt-binding for rx cpu core Signed-off-by: Duy Nguyen --- dts/rx/renesas/rx-qemu.dtsi | 2 +- dts/rx/renesas/rx130-common.dtsi | 2 +- dts/rx/renesas/rx261-common.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dts/rx/renesas/rx-qemu.dtsi b/dts/rx/renesas/rx-qemu.dtsi index f29b2c082fa0f..1737456b4a550 100644 --- a/dts/rx/renesas/rx-qemu.dtsi +++ b/dts/rx/renesas/rx-qemu.dtsi @@ -22,7 +22,7 @@ #size-cells = <0>; cpu0: cpu@0 { - compatible = "renesas,rx"; + compatible = "renesas,rxv1"; device_type = "cpu"; reg = <0>; status = "okay"; diff --git a/dts/rx/renesas/rx130-common.dtsi b/dts/rx/renesas/rx130-common.dtsi index 314bd9d61b386..428de7456b386 100644 --- a/dts/rx/renesas/rx130-common.dtsi +++ b/dts/rx/renesas/rx130-common.dtsi @@ -22,7 +22,7 @@ #size-cells = <0>; cpu0: cpu@0 { - compatible = "renesas,rx"; + compatible = "renesas,rxv1"; device_type = "cpu"; reg = <0>; status = "okay"; diff --git a/dts/rx/renesas/rx261-common.dtsi b/dts/rx/renesas/rx261-common.dtsi index f538002321738..4764af0e72a84 100644 --- a/dts/rx/renesas/rx261-common.dtsi +++ b/dts/rx/renesas/rx261-common.dtsi @@ -20,7 +20,7 @@ #size-cells = <0>; cpu0: cpu@0 { - compatible = "renesas,rx"; + compatible = "renesas,rxv3"; device_type = "cpu"; reg = <0>; status = "okay"; From 7390004b06c06dfd10f29d6d41756ba2193d02ac Mon Sep 17 00:00:00 2001 From: Jaakko Korhonen Date: Tue, 19 Aug 2025 15:40:25 +0300 Subject: [PATCH 0222/1076] shell: modules: devmem: fix devmem load occasionally losing bytes Changed devmem load to process all characters from the *recv buffer. Signed-off-by: Jaakko Korhonen --- subsys/shell/modules/devmem_service.c | 42 ++++++++++++--------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/subsys/shell/modules/devmem_service.c b/subsys/shell/modules/devmem_service.c index 3663e0a2cfa16..559a946d6d677 100644 --- a/subsys/shell/modules/devmem_service.c +++ b/subsys/shell/modules/devmem_service.c @@ -175,14 +175,25 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len) static uint8_t tail; uint8_t byte; - if (tail == CHAR_CAN && recv[0] == CHAR_DC1) { - escape = true; - } else { - for (int i = 0; i < (len - 1); i++) { - if (recv[i] == CHAR_CAN && recv[i + 1] == CHAR_DC1) { - escape = true; - break; - } + for (size_t i = 0; i < len; i++) { + if (tail == CHAR_CAN && recv[i] == CHAR_DC1) { + escape = true; + tail = 0; + break; + } + tail = recv[i]; + + if (is_ascii(recv[i])) { + chunk[chunk_element] = recv[i]; + chunk_element++; + } + + if (chunk_element == 2) { + byte = (uint8_t)strtoul(chunk, NULL, 16); + *bytes = byte; + bytes++; + sum++; + chunk_element = 0; } } @@ -206,21 +217,6 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len) } return; } - - tail = recv[len - 1]; - - if (is_ascii(*recv)) { - chunk[chunk_element] = *recv; - chunk_element++; - } - - if (chunk_element == 2) { - byte = (uint8_t)strtoul(chunk, NULL, 16); - *bytes = byte; - bytes++; - sum++; - chunk_element = 0; - } } static int cmd_load(const struct shell *sh, size_t argc, char **argv) From 33fc4a8d2df940e96ec3f6f941cafc0b2936a0e6 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Fri, 16 May 2025 19:22:00 +0800 Subject: [PATCH 0223/1076] Bluetooth: tester: Support feature ISO sync receiver Add command `BTP_GAP_BIG_CREATE_SYNC` to create BIG sync establishment. Add event `BTP_GAP_EV_BIG_SYNC_ESTABLISHED` to notify the event that the BIG sync is established. Add event `BTP_GAP_EV_BIG_SYNC_LOST` to notify the event that the BIG sync is lost. Add event `BTP_GAP_EV_BIS_DATA_PATH_SETUP` to notify the event that the data path of the BIS is setup. Add event `BTP_GAP_EV_BIS_STREAM_RECEIVED` to notify the received BIS stream data. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp/btp_gap.h | 51 +++++ tests/bluetooth/tester/src/btp_gap.c | 253 +++++++++++++++++++++++ 2 files changed, 304 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index a4c902553f47c..e2320a843da8c 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -11,6 +11,7 @@ #include #include +#include /* GAP Service */ /* commands */ @@ -347,6 +348,21 @@ struct btp_gap_pair_v2_cmd { uint8_t flags; } __packed; +#define BTP_GAP_BIG_CREATE_SYNC_ENC_DISABLE 0x00 +#define BTP_GAP_BIG_CREATE_SYNC_ENC_ENABLE 0x01 + +#define BTP_GAP_BIG_CREATE_SYNC 0x2c +struct btp_gap_big_create_sync_cmd { + bt_addr_le_t address; + uint8_t sid; + uint8_t num_bis; + uint32_t bis_bitfield; + uint32_t mse; + uint16_t sync_timeout; + uint8_t encryption; + uint8_t broadcast_code[0]; +} __packed; + #define BTP_GAP_SET_RPA_TIMEOUT 0x30 struct btp_gap_set_rpa_timeout_cmd { uint16_t rpa_timeout; @@ -480,6 +496,41 @@ struct btp_gap_encryption_change_ev { uint8_t key_size; } __packed; +#define BTP_GAP_EV_BIG_SYNC_ESTABLISHED 0x93 +struct btp_gap_big_sync_established_ev { + bt_addr_le_t address; + uint32_t latency; + uint8_t nse; + uint8_t bn; + uint32_t pto; + uint8_t irc; + uint16_t max_pdu; + uint16_t iso_interval; +} __packed; + +#define BTP_GAP_EV_BIG_SYNC_LOST 0x94 +struct btp_gap_big_sync_lost_ev { + bt_addr_le_t address; + uint8_t reason; +} __packed; + +#define BTP_GAP_EV_BIS_DATA_PATH_SETUP 0x95 +struct btp_gap_bis_data_path_setup_ev { + bt_addr_le_t address; + uint8_t bis_id; +} __packed; + +#define BTP_GAP_EV_BIS_STREAM_RECEIVED 0x96 +struct btp_gap_bis_stream_received_ev { + bt_addr_le_t address; + uint8_t bis_id; + uint8_t flags; + uint32_t ts; + uint16_t seq_num; + uint8_t data_len; + uint8_t data[]; +} __packed; + #if defined(CONFIG_BT_EXT_ADV) struct bt_le_per_adv_param; struct bt_le_per_adv_sync_param; diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index ad22d1548ce34..d254178ccecf3 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -31,6 +31,7 @@ #include #include +#include #include "btp/btp.h" @@ -2364,6 +2365,247 @@ static uint8_t set_rpa_timeout(const void *cmd, uint16_t cmd_len, void *rsp, uin } #endif /* defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC) */ +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) +static struct bt_iso_big *iso_sync_receiver_big; + +static void iso_sync_receiver_big_started_cb(struct bt_iso_big *big) +{ + __maybe_unused struct btp_gap_big_sync_established_ev ev; + struct bt_iso_info info; + struct bt_iso_chan *bis; + bool found = false; + + if (big != iso_sync_receiver_big) { + return; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) { + int err = bt_iso_chan_get_info(bis, &info); + + if (err != 0) { + LOG_DBG("Failed to get ISO chan info: %d", err); + continue; + } + + if (info.type != BT_ISO_CHAN_TYPE_SYNC_RECEIVER) { + continue; + } + + found = true; + break; + } + + __ASSERT(found, "Failed to find the valid ISO info"); + + if (!found) { + LOG_ERR("Failed to find the valid ISO info"); + return; + } + + bt_addr_le_copy(&ev.address, &pa_sync->addr); + ev.latency = sys_cpu_to_le32(info.sync_receiver.latency); + ev.nse = info.max_subevent; + ev.bn = info.sync_receiver.bn; + ev.pto = sys_cpu_to_le32(info.sync_receiver.pto); + ev.irc = info.sync_receiver.irc; + ev.max_pdu = sys_cpu_to_le16(info.sync_receiver.max_pdu); + ev.iso_interval = sys_cpu_to_le16(info.iso_interval); + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIG_SYNC_ESTABLISHED, &ev, sizeof(ev)); +} + +static void iso_sync_receiver_big_stopped_cb(struct bt_iso_big *big, uint8_t reason) +{ + struct btp_gap_big_sync_lost_ev ev; + + if (big != iso_sync_receiver_big) { + return; + } + + bt_addr_le_copy(&ev.address, &pa_sync->addr); + ev.reason = reason; + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIG_SYNC_LOST, &ev, sizeof(ev)); + + iso_sync_receiver_big = NULL; +} + +static struct bt_iso_big_cb iso_sync_receiver_big_cb = { + .started = iso_sync_receiver_big_started_cb, + .stopped = iso_sync_receiver_big_stopped_cb, +}; + +#define BIS_STREAM_DATA_LEN (CONFIG_BT_ISO_RX_MTU + \ + sizeof(struct btp_gap_bis_stream_received_ev)) + +BUILD_ASSERT(BIS_STREAM_DATA_LEN < BTP_DATA_MAX_SIZE, "BIS stream data length exceeds BTP MTU"); + +static struct net_buf_simple *iso_sync_receiver_buf = NET_BUF_SIMPLE(BIS_STREAM_DATA_LEN); + +static int bt_iso_chan_get_index(struct bt_iso_chan *chan); + +static void iso_sync_receiver_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + struct btp_gap_bis_stream_received_ev *ev; + int err; + + if (pa_sync == NULL) { + return; + } + + err = bt_iso_chan_get_index(chan); + if (err < 0) { + LOG_ERR("Failed to get BIS channel index: %d", err); + return; + } + + /* cleanup */ + net_buf_simple_init(iso_sync_receiver_buf, 0); + + ev = net_buf_simple_add(iso_sync_receiver_buf, sizeof(*ev)); + + __ASSERT(buf->len <= net_buf_simple_tailroom(iso_sync_receiver_buf), "No more tailroom"); + + bt_addr_le_copy(&ev->address, &pa_sync->addr); + ev->bis_id = (uint8_t)err; + ev->data_len = buf->len; + ev->flags = info->flags; + ev->ts = sys_cpu_to_le32(info->ts); + ev->seq_num = sys_cpu_to_le16(info->seq_num); + net_buf_simple_add_mem(iso_sync_receiver_buf, buf->data, ev->data_len); + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIS_STREAM_RECEIVED, + iso_sync_receiver_buf->data, iso_sync_receiver_buf->len); +} + +static void iso_sync_receiver_connected(struct bt_iso_chan *chan) +{ + const struct bt_iso_chan_path hci_path = { + .pid = BT_ISO_DATA_PATH_HCI, + .format = BT_HCI_CODING_FORMAT_TRANSPARENT, + }; + int err; + struct btp_gap_bis_data_path_setup_ev ev; + + if (pa_sync == NULL) { + return; + } + + err = bt_iso_chan_get_index(chan); + if (err < 0) { + LOG_ERR("Failed to get BIS channel index: %d", err); + return; + } + ev.bis_id = (uint8_t)err; + + err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_CTLR_TO_HOST, &hci_path); + if (err != 0) { + LOG_ERR("Failed to setup ISO RX data path: %d", err); + return; + } + + bt_addr_le_copy(&ev.address, &pa_sync->addr); + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIS_DATA_PATH_SETUP, &ev, sizeof(ev)); +} + +static void iso_sync_receiver_disconnected(struct bt_iso_chan *chan, uint8_t reason) +{ + int err; + + err = bt_iso_remove_data_path(chan, BT_HCI_DATAPATH_DIR_CTLR_TO_HOST); + if (err != 0) { + LOG_ERR("Failed to remove ISO RX data path: %d", err); + } +} + +static struct bt_iso_chan_ops iso_sync_receiver_ops = { + .recv = iso_sync_receiver_recv, + .connected = iso_sync_receiver_connected, + .disconnected = iso_sync_receiver_disconnected, +}; + +static struct bt_iso_chan_qos bis_iso_qos; + +static struct bt_iso_chan bis_iso_chan = { + .qos = &bis_iso_qos, +}; + +#define DEFAULT_IO_QOS {.sdu = 40u, .phy = BT_GAP_LE_PHY_2M, .rtn = 2u,} + +static struct bt_iso_chan_io_qos iso_sync_receiver_qos = DEFAULT_IO_QOS; + +#define BIS_ISO_CHAN_COUNT 1 + +static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan }; + +static int bt_iso_chan_get_index(struct bt_iso_chan *chan) +{ + ARRAY_FOR_EACH(bis_channels, index) { + if (bis_channels[index] == chan) { + return (int)index; + } + } + return -EINVAL; +} + +static uint8_t big_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_gap_big_create_sync_cmd *cp = cmd; + struct bt_iso_big_sync_param param; + + if ((cmd_len < sizeof(*cp)) || + (cmd_len != (sizeof(*cp) + sizeof(param.bcode) * cp->encryption))) { + LOG_ERR("Invalid cmd len"); + return BTP_STATUS_FAILED; + } + + if (!(cp->encryption == BTP_GAP_BIG_CREATE_SYNC_ENC_DISABLE || + cp->encryption == BTP_GAP_BIG_CREATE_SYNC_ENC_ENABLE)) { + LOG_ERR("Invalid encryption %u", cp->encryption); + return BTP_STATUS_FAILED; + } + + if ((pa_sync == NULL) || !bt_addr_le_eq(&cp->address, &pa_sync->addr) || + (cp->sid != pa_sync->sid)) { + LOG_ERR("Invalid PA sync or SID"); + return BTP_STATUS_FAILED; + } + + if (cp->num_bis > ARRAY_SIZE(bis_channels)) { + LOG_ERR("BIS num exceeds %u > %u", cp->num_bis, ARRAY_SIZE(bis_channels)); + return BTP_STATUS_FAILED; + } + + bis_iso_qos.tx = NULL; + bis_iso_qos.rx = &iso_sync_receiver_qos; + + bis_iso_chan.ops = &iso_sync_receiver_ops; + + param.bis_channels = bis_channels; + param.num_bis = cp->num_bis; + param.bis_bitfield = sys_le32_to_cpu(cp->bis_bitfield); + param.mse = sys_le32_to_cpu(cp->mse); + param.sync_timeout = sys_le16_to_cpu(cp->sync_timeout); + param.encryption = cp->encryption == BTP_GAP_BIG_CREATE_SYNC_ENC_ENABLE; + if (param.encryption) { + memcpy(param.bcode, cp->broadcast_code, sizeof(param.bcode)); + } + + err = bt_iso_big_sync(pa_sync, ¶m, &iso_sync_receiver_big); + if (err != 0) { + LOG_ERR("Unable to sync to BIG (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("BIG syncing"); + + return BTP_STATUS_SUCCESS; +} +#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */ + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -2559,6 +2801,13 @@ static const struct btp_handler handlers[] = { .func = set_rpa_timeout, }, #endif /* defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC) */ +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) + { + .opcode = BTP_GAP_BIG_CREATE_SYNC, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = big_create_sync, + }, +#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */ }; uint8_t tester_init_gap(void) @@ -2594,6 +2843,10 @@ uint8_t tester_init_gap(void) bt_le_per_adv_sync_cb_register(&pa_sync_cb); } +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) + bt_iso_big_register_cb(&iso_sync_receiver_big_cb); +#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */ + tester_register_command_handlers(BTP_SERVICE_ID_GAP, handlers, ARRAY_SIZE(handlers)); From a7eeea1130e848f4eb7ca106c1fe53db4b87f34f Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 22 Jul 2025 18:17:00 +0800 Subject: [PATCH 0224/1076] Bluetooth: tester: Support feature ISO broadcaster Add command `BTP_GAP_CREATE_BIG` to create BIG. Add command `BTP_GAP_BIS_BROADCAST` to send broadcast data. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp/btp_gap.h | 24 +++ tests/bluetooth/tester/src/btp_gap.c | 205 ++++++++++++++++++++++- 2 files changed, 225 insertions(+), 4 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index e2320a843da8c..d0c5735aa3b92 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -363,6 +363,30 @@ struct btp_gap_big_create_sync_cmd { uint8_t broadcast_code[0]; } __packed; +#define BTP_GAP_CREATE_BIG_ENC_DISABLE 0x00 +#define BTP_GAP_CREATE_BIG_ENC_ENABLE 0x01 + +#define BTP_GAP_CREATE_BIG 0x2d +struct btp_gap_create_big_cmd { + uint8_t id; + uint8_t num_bis; + uint32_t interval; + uint16_t latency; + uint8_t rtn; + uint8_t phy; + uint8_t packing; + uint8_t framing; + uint8_t encryption; + uint8_t broadcast_code[0]; +} __packed; + +#define BTP_GAP_BIS_BROADCAST 0x2e +struct btp_gap_bis_broadcast_cmd { + uint8_t bis_id; + uint8_t data_len; + uint8_t data[]; +} __packed; + #define BTP_GAP_SET_RPA_TIMEOUT 0x30 struct btp_gap_set_rpa_timeout_cmd { uint16_t rpa_timeout; diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index d254178ccecf3..6635862b3c87c 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -2365,6 +2365,10 @@ static uint8_t set_rpa_timeout(const void *cmd, uint16_t cmd_len, void *rsp, uin } #endif /* defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC) */ +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) +static int bt_iso_chan_get_index(struct bt_iso_chan *chan); +#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) */ + #if defined(CONFIG_BT_ISO_SYNC_RECEIVER) static struct bt_iso_big *iso_sync_receiver_big; @@ -2442,8 +2446,6 @@ BUILD_ASSERT(BIS_STREAM_DATA_LEN < BTP_DATA_MAX_SIZE, "BIS stream data length ex static struct net_buf_simple *iso_sync_receiver_buf = NET_BUF_SIMPLE(BIS_STREAM_DATA_LEN); -static int bt_iso_chan_get_index(struct bt_iso_chan *chan); - static void iso_sync_receiver_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, struct net_buf *buf) { @@ -2525,7 +2527,57 @@ static struct bt_iso_chan_ops iso_sync_receiver_ops = { .connected = iso_sync_receiver_connected, .disconnected = iso_sync_receiver_disconnected, }; +#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */ + +#if defined(CONFIG_BT_ISO_BROADCASTER) +static uint32_t bis_sn_last; +static int64_t bis_sn_last_updated_ticks; +static uint32_t bis_sdu_interval_us; + +static void iso_broadcaster_connected(struct bt_iso_chan *chan) +{ + int err; + const struct bt_iso_chan_path hci_path = { + .pid = BT_ISO_DATA_PATH_HCI, + .format = BT_HCI_CODING_FORMAT_TRANSPARENT, + }; + struct btp_gap_bis_data_path_setup_ev ev; + struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0); + err = bt_iso_chan_get_index(chan); + if (err < 0) { + LOG_ERR("Failed to get BIS channel index: %d", err); + return; + } + ev.bis_id = (uint8_t)err; + + bis_sn_last = 0; + bis_sn_last_updated_ticks = k_uptime_ticks(); + + err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, &hci_path); + if (err != 0) { + LOG_ERR("Failed to setup ISO TX data path: %d", err); + return; + } + + bt_addr_le_copy(&ev.address, &ext_adv->random_addr); + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIS_DATA_PATH_SETUP, &ev, sizeof(ev)); +} + +static void iso_broadcaster_disconnected(struct bt_iso_chan *chan, uint8_t reason) +{ + ARG_UNUSED(chan); + ARG_UNUSED(reason); +} + +static struct bt_iso_chan_ops iso_broadcaster_ops = { + .connected = iso_broadcaster_connected, + .disconnected = iso_broadcaster_disconnected, +}; +#endif /* defined(CONFIG_BT_ISO_BROADCASTER) */ + +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) static struct bt_iso_chan_qos bis_iso_qos; static struct bt_iso_chan bis_iso_chan = { @@ -2534,8 +2586,6 @@ static struct bt_iso_chan bis_iso_chan = { #define DEFAULT_IO_QOS {.sdu = 40u, .phy = BT_GAP_LE_PHY_2M, .rtn = 2u,} -static struct bt_iso_chan_io_qos iso_sync_receiver_qos = DEFAULT_IO_QOS; - #define BIS_ISO_CHAN_COUNT 1 static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan }; @@ -2549,6 +2599,10 @@ static int bt_iso_chan_get_index(struct bt_iso_chan *chan) } return -EINVAL; } +#endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(CONFIG_BT_ISO_BROADCASTER) */ + +#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) +static struct bt_iso_chan_io_qos iso_sync_receiver_qos = DEFAULT_IO_QOS; static uint8_t big_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -2606,6 +2660,137 @@ static uint8_t big_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uin } #endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */ +#if defined(CONFIG_BT_ISO_BROADCASTER) +static struct bt_iso_chan_io_qos iso_broadcaster_qos = DEFAULT_IO_QOS; + +static struct bt_iso_big *iso_broadcaster_big; + +static uint8_t create_big(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_gap_create_big_cmd *cp = cmd; + struct bt_iso_big_create_param param = {0}; + struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0); + + if ((cmd_len < sizeof(*cp)) || + (cmd_len != (sizeof(*cp) + sizeof(param.bcode) * cp->encryption))) { + LOG_ERR("Invalid cmd len"); + return BTP_STATUS_FAILED; + } + + if (!(cp->encryption == BTP_GAP_CREATE_BIG_ENC_DISABLE || + cp->encryption == BTP_GAP_CREATE_BIG_ENC_ENABLE)) { + LOG_ERR("Invalid encryption %u", cp->encryption); + return BTP_STATUS_FAILED; + } + + if ((ext_adv == NULL) || (cp->id != ext_adv->id)) { + LOG_ERR("Invalid extended adv"); + return BTP_STATUS_FAILED; + } + + if (cp->num_bis > ARRAY_SIZE(bis_channels)) { + LOG_ERR("BIS num exceeds %u > %u", cp->num_bis, ARRAY_SIZE(bis_channels)); + return BTP_STATUS_FAILED; + } + + bis_iso_qos.rx = NULL; + bis_iso_qos.tx = &iso_broadcaster_qos; + bis_iso_qos.tx->phy = cp->phy; + bis_iso_qos.tx->rtn = cp->rtn; + bis_iso_qos.tx->sdu = CONFIG_BT_ISO_TX_MTU; + + bis_iso_chan.ops = &iso_broadcaster_ops; + + param.bis_channels = bis_channels; + param.num_bis = cp->num_bis; + param.interval = sys_le32_to_cpu(cp->interval); + param.packing = cp->packing; + param.framing = cp->framing; + param.latency = sys_le16_to_cpu(cp->latency); + + param.encryption = cp->encryption == BTP_GAP_CREATE_BIG_ENC_ENABLE; + if (param.encryption) { + memcpy(param.bcode, cp->broadcast_code, sizeof(param.bcode)); + } + + bis_sdu_interval_us = param.interval; + + err = bt_iso_big_create(ext_adv, ¶m, &iso_broadcaster_big); + if (err != 0) { + LOG_ERR("Unable to create BIG (err %d)", err); + return BTP_STATUS_FAILED; + } + + LOG_DBG("BIG created"); + + return BTP_STATUS_SUCCESS; +} + +NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, BIS_ISO_CHAN_COUNT, + BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + +static uint32_t get_next_sn(uint32_t last_sn, int64_t *last_ticks, + uint32_t interval_us) +{ + int64_t uptime_ticks, delta_ticks; + uint64_t delta_us; + uint64_t sn_incr; + uint64_t next_sn; + + /* Note: This does not handle wrapping of ticks when they go above + * 2^(62-1) + */ + uptime_ticks = k_uptime_ticks(); + delta_ticks = uptime_ticks - *last_ticks; + *last_ticks = uptime_ticks; + + delta_us = k_ticks_to_us_near64((uint64_t)delta_ticks); + sn_incr = delta_us / interval_us; + next_sn = (sn_incr + last_sn); + + return (uint32_t)next_sn; +} + +static uint8_t bis_broadcast(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_gap_bis_broadcast_cmd *cp = cmd; + struct net_buf *buf; + + buf = net_buf_alloc(&bis_tx_pool, K_NO_WAIT); + if (buf == NULL) { + LOG_ERR("Failed to allocate buffer"); + return BTP_STATUS_FAILED; + } + + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + + if (cp->data_len > net_buf_tailroom(buf)) { + net_buf_unref(buf); + LOG_ERR("Data length exceeds buffer tailroom"); + return BTP_STATUS_FAILED; + } + + bis_sn_last = get_next_sn(bis_sn_last, &bis_sn_last_updated_ticks, + bis_sdu_interval_us); + + net_buf_add_mem(buf, cp->data, cp->data_len); + + err = bt_iso_chan_send(&bis_iso_chan, buf, bis_sn_last); + if (err < 0) { + LOG_ERR("Unable to broadcast: %d", -err); + net_buf_unref(buf); + return BTP_STATUS_FAILED; + } + + LOG_DBG("ISO broadcasting..., sn %u len %u", bis_sn_last, cp->data_len); + + return BTP_STATUS_SUCCESS; +} +#endif /* defined(CONFIG_BT_ISO_BROADCASTER) */ + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -2808,6 +2993,18 @@ static const struct btp_handler handlers[] = { .func = big_create_sync, }, #endif /* defined(CONFIG_BT_ISO_SYNC_RECEIVER) */ +#if defined(CONFIG_BT_ISO_BROADCASTER) + { + .opcode = BTP_GAP_CREATE_BIG, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = create_big, + }, + { + .opcode = BTP_GAP_BIS_BROADCAST, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = bis_broadcast, + }, +#endif /* defined(CONFIG_BT_ISO_BROADCASTER) */ }; uint8_t tester_init_gap(void) From eaf1439ea9774f679d0a378441000a170406a779 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 30 Jun 2025 18:54:00 +0800 Subject: [PATCH 0225/1076] Bluetooth: tester: Add event of periodic BIGInfo advertising report Add event `BTP_GAP_EV_PERIODIC_BIGINFO` to notify the received periodic BIGInfo advertising report. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp/btp_gap.h | 22 +++++++++++++++++++ tests/bluetooth/tester/src/btp_gap.c | 28 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index d0c5735aa3b92..e410b56e460db 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -555,6 +555,28 @@ struct btp_gap_bis_stream_received_ev { uint8_t data[]; } __packed; +#define BTP_GAP_EV_PERIODIC_BIGINFO_ENC_DISABLE 0x00 +#define BTP_GAP_EV_PERIODIC_BIGINFO_ENC_ENABLE 0x01 + +#define BTP_GAP_EV_PERIODIC_BIGINFO 0x97 +struct btp_gap_periodic_biginfo_ev { + bt_addr_le_t address; + uint16_t sync_handle; + uint8_t sid; + uint8_t num_bis; + uint8_t nse; + uint16_t iso_interval; + uint8_t bn; + uint8_t pto; + uint8_t irc; + uint16_t max_pdu; + uint32_t sdu_interval; + uint16_t max_sdu; + uint8_t phy; + uint8_t framing; + uint8_t encryption; +} __packed; + #if defined(CONFIG_BT_EXT_ADV) struct bt_le_per_adv_param; struct bt_le_per_adv_sync_param; diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 6635862b3c87c..ed82a1ed3ad5b 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -1977,10 +1977,38 @@ static void pa_sync_recv_cb(struct bt_le_per_adv_sync *sync, ev, sizeof(*ev) + ev->data_len); } +static void pa_sync_biginfo_cb(struct bt_le_per_adv_sync *sync, + const struct bt_iso_biginfo *biginfo) +{ + struct btp_gap_periodic_biginfo_ev ev; + + LOG_DBG(""); + + bt_addr_le_copy(&ev.address, biginfo->addr); + ev.sync_handle = sys_cpu_to_le16(sync->handle); + ev.sid = biginfo->sid; + ev.num_bis = biginfo->num_bis; + ev.nse = biginfo->sub_evt_count; + ev.iso_interval = sys_cpu_to_le16(biginfo->iso_interval); + ev.bn = biginfo->burst_number; + ev.pto = biginfo->offset; + ev.irc = biginfo->rep_count; + ev.max_pdu = sys_cpu_to_le16(biginfo->max_pdu); + ev.sdu_interval = sys_cpu_to_le32(biginfo->sdu_interval); + ev.max_sdu = sys_cpu_to_le16(biginfo->max_sdu); + ev.phy = biginfo->phy; + ev.framing = biginfo->framing; + ev.encryption = biginfo->encryption ? BTP_GAP_EV_PERIODIC_BIGINFO_ENC_ENABLE : + BTP_GAP_EV_PERIODIC_BIGINFO_ENC_DISABLE; + + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_BIGINFO, &ev, sizeof(ev)); +} + static struct bt_le_per_adv_sync_cb pa_sync_cb = { .synced = pa_sync_synced_cb, .term = pa_sync_terminated_cb, .recv = pa_sync_recv_cb, + .biginfo = pa_sync_biginfo_cb, }; #if defined(CONFIG_BT_PER_ADV) From d973e4e3ced27092c69ad59d96b5912289c0d490 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 22 Jul 2025 16:17:13 +0800 Subject: [PATCH 0226/1076] tests: bsim: tester: Add BT tester GAP ISO smoke test Add test iso_broadcaster for GAP ISO broadcaster. Add test iso_sync_receiver for GAP ISO sync receiver. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/gap_iso.conf | 4 + tests/bluetooth/tester/testcase.yaml | 2 + tests/bsim/bluetooth/tester/CMakeLists.txt | 2 + tests/bsim/bluetooth/tester/src/bsim_btp.c | 25 ++ tests/bsim/bluetooth/tester/src/bsim_btp.h | 339 ++++++++++++++++++ .../tester/src/host/iso_broadcaster.c | 87 +++++ .../tester/src/host/iso_sync_receiver.c | 107 ++++++ tests/bsim/bluetooth/tester/src/test_main.c | 4 + .../bluetooth/tester/tests_scripts/gap_iso.sh | 43 +++ 9 files changed, 613 insertions(+) create mode 100644 tests/bluetooth/tester/gap_iso.conf create mode 100644 tests/bsim/bluetooth/tester/src/host/iso_broadcaster.c create mode 100644 tests/bsim/bluetooth/tester/src/host/iso_sync_receiver.c create mode 100755 tests/bsim/bluetooth/tester/tests_scripts/gap_iso.sh diff --git a/tests/bluetooth/tester/gap_iso.conf b/tests/bluetooth/tester/gap_iso.conf new file mode 100644 index 0000000000000..acc0aad80a4e2 --- /dev/null +++ b/tests/bluetooth/tester/gap_iso.conf @@ -0,0 +1,4 @@ +CONFIG_BT_ISO_BROADCASTER=y +CONFIG_BT_ISO_SYNC_RECEIVER=y +CONFIG_BT_ISO_CENTRAL=y +CONFIG_BT_ISO_PERIPHERAL=y diff --git a/tests/bluetooth/tester/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index 9d3f7f758ccf6..8f6cd0b98be70 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -45,6 +45,8 @@ tests: harness: bsim harness_config: bsim_exe_name: tests_bluetooth_tester_prj_conf + extra_args: + - EXTRA_CONF_FILE="gap_iso.conf" sysbuild: true bluetooth.general.tester_le_audio: build_only: true diff --git a/tests/bsim/bluetooth/tester/CMakeLists.txt b/tests/bsim/bluetooth/tester/CMakeLists.txt index b47f2b2fee1f2..2681d331a62e7 100644 --- a/tests/bsim/bluetooth/tester/CMakeLists.txt +++ b/tests/bsim/bluetooth/tester/CMakeLists.txt @@ -34,4 +34,6 @@ target_sources(app PRIVATE src/audio/vcp_peripheral.c src/host/gap_central.c src/host/gap_peripheral.c + src/host/iso_broadcaster.c + src/host/iso_sync_receiver.c ) diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.c b/tests/bsim/bluetooth/tester/src/bsim_btp.c index 30b8f4d198182..a5b2c7000dc88 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.c +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.c @@ -129,6 +129,8 @@ static bool is_valid_gap_packet_len(const struct btp_hdr *hdr, struct net_buf_si case BTP_GAP_SET_EXTENDED_ADVERTISING: return buf_simple->len == sizeof(struct btp_gap_set_extended_advertising_rp); case BTP_GAP_PADV_CONFIGURE: + return buf_simple->len == sizeof(struct btp_gap_padv_configure_rp); + case BTP_GAP_PADV_START: return buf_simple->len == sizeof(struct btp_gap_padv_start_rp); case BTP_GAP_PADV_STOP: return buf_simple->len == sizeof(struct btp_gap_padv_stop_rp); @@ -142,6 +144,12 @@ static bool is_valid_gap_packet_len(const struct btp_hdr *hdr, struct net_buf_si return buf_simple->len == 0U; case BTP_GAP_PADV_SYNC_TRANSFER_RECV: return buf_simple->len == 0U; + case BTP_GAP_BIG_CREATE_SYNC: + return buf_simple->len == 0U; + case BTP_GAP_CREATE_BIG: + return buf_simple->len == 0U; + case BTP_GAP_BIS_BROADCAST: + return buf_simple->len == 0U; /* events */ case BTP_GAP_EV_NEW_SETTINGS: @@ -194,6 +202,23 @@ static bool is_valid_gap_packet_len(const struct btp_hdr *hdr, struct net_buf_si return buf_simple->len == sizeof(struct btp_gap_ev_periodic_transfer_received_ev); case BTP_GAP_EV_ENCRYPTION_CHANGE: return buf_simple->len == sizeof(struct btp_gap_encryption_change_ev); + case BTP_GAP_EV_BIG_SYNC_ESTABLISHED: + return buf_simple->len == sizeof(struct btp_gap_big_sync_established_ev); + case BTP_GAP_EV_BIG_SYNC_LOST: + return buf_simple->len == sizeof(struct btp_gap_big_sync_lost_ev); + case BTP_GAP_EV_BIS_DATA_PATH_SETUP: + return buf_simple->len == sizeof(struct btp_gap_bis_data_path_setup_ev); + case BTP_GAP_EV_BIS_STREAM_RECEIVED: + if (hdr->len >= sizeof(struct btp_gap_bis_stream_received_ev)) { + const struct btp_gap_bis_stream_received_ev *ev = net_buf_simple_pull_mem( + buf_simple, sizeof(struct btp_gap_bis_stream_received_ev)); + + return ev->data_len == buf_simple->len; + } else { + return false; + } + case BTP_GAP_EV_PERIODIC_BIGINFO: + return buf_simple->len == sizeof(struct btp_gap_periodic_biginfo_ev); default: LOG_ERR("Unhandled opcode 0x%02X", hdr->opcode); return false; diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.h b/tests/bsim/bluetooth/tester/src/bsim_btp.h index 93b4ea678f856..a4088ec153944 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.h +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -109,6 +110,25 @@ static inline void bsim_btp_wait_for_lock(void) net_buf_unref(buf); } +static inline void bsim_btp_gap_set_connectable(bool enable) +{ + struct btp_gap_set_connectable_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_SET_CONNECTABLE; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->connectable = enable ? 1 : 0; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + static inline void bsim_btp_gap_set_discoverable(uint8_t discoverable) { struct btp_gap_set_discoverable_cmd *cmd; @@ -600,4 +620,323 @@ static inline void bsim_btp_wait_for_micp_state(bt_addr_le_t *address, uint8_t * net_buf_unref(buf); } + +static inline void bsim_btp_gap_set_extended_advertising(bool enable) +{ + struct btp_gap_set_extended_advertising_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_SET_EXTENDED_ADVERTISING; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->settings = enable ? BIT(0) : 0; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_gap_padv_configure(uint8_t flags, uint16_t interval_min, + uint16_t interval_max) +{ + struct btp_gap_padv_configure_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_PADV_CONFIGURE; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->flags = flags; + cmd->interval_min = sys_cpu_to_le16(interval_min); + cmd->interval_max = sys_cpu_to_le16(interval_max); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_gap_padv_start(void) +{ + struct btp_gap_padv_start_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_PADV_START; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->flags = 0; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_gap_padv_stop(void) +{ + struct btp_gap_padv_stop_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_PADV_STOP; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_gap_padv_create_sync(bt_addr_le_t *addr, uint8_t sid, uint16_t skip, + uint16_t sync_timeout, uint8_t flags) +{ + struct btp_gap_padv_create_sync_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_PADV_CREATE_SYNC; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, addr); + cmd->advertiser_sid = sid; + cmd->skip = sys_cpu_to_le16(skip); + cmd->sync_timeout = sys_cpu_to_le16(sync_timeout); + cmd->flags = flags; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_gap_periodic_sync_established(bt_addr_le_t *address, + uint16_t *sync_handle, + uint8_t *status) +{ + struct btp_gap_ev_periodic_sync_established_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_SYNC_ESTABLISHED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + if (sync_handle != NULL) { + *sync_handle = ev->sync_handle; + } + + if (status != NULL) { + *status = ev->status; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_gap_periodic_sync_lost(uint16_t *sync_handle, uint8_t *reason) +{ + struct btp_gap_ev_periodic_sync_lost_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_SYNC_LOST, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (sync_handle != NULL) { + *sync_handle = ev->sync_handle; + } + + if (reason != NULL) { + *reason = ev->reason; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_gap_periodic_biginfo(bt_addr_le_t *address, uint8_t *sid, + uint8_t *num_bis, uint8_t *encryption) +{ + struct btp_gap_periodic_biginfo_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PERIODIC_BIGINFO, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + if (sid != NULL) { + *sid = ev->sid; + } + + if (num_bis != NULL) { + *num_bis = ev->num_bis; + } + + if (encryption != NULL) { + *encryption = ev->encryption; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_gap_big_create_sync(bt_addr_le_t *address, uint8_t sid, uint8_t num_bis, + uint32_t bis_bitfield, uint32_t mse, + uint16_t sync_timeout, bool encryption, + uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]) +{ + struct btp_gap_big_create_sync_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_BIG_CREATE_SYNC; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->sid = sid; + cmd->num_bis = num_bis; + cmd->bis_bitfield = sys_cpu_to_le32(bis_bitfield); + cmd->mse = sys_cpu_to_le32(mse); + cmd->sync_timeout = sys_cpu_to_le16(sync_timeout); + cmd->encryption = encryption; + if (encryption) { + net_buf_simple_add(&cmd_buffer, BT_ISO_BROADCAST_CODE_SIZE); + memcpy(cmd->broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE); + } + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_gap_big_sync_established(bt_addr_le_t *address) +{ + struct btp_gap_big_sync_established_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIG_SYNC_ESTABLISHED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_gap_create_big(uint8_t num_bis, uint32_t interval, uint16_t latency, + bool encryption, + uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]) +{ + struct btp_gap_create_big_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_CREATE_BIG; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->id = 0; + cmd->num_bis = num_bis; + cmd->interval = sys_cpu_to_le32(interval); + cmd->latency = sys_cpu_to_le16(latency); + cmd->rtn = 2; + cmd->phy = BT_GAP_LE_PHY_2M; + cmd->packing = BT_ISO_PACKING_SEQUENTIAL; + cmd->framing = BT_ISO_FRAMING_UNFRAMED; + cmd->encryption = encryption; + if (encryption) { + net_buf_simple_add(&cmd_buffer, BT_ISO_BROADCAST_CODE_SIZE); + memcpy(cmd->broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE); + } + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_gap_bis_data_path_setup(bt_addr_le_t *address, uint8_t *bis_id) +{ + struct btp_gap_bis_data_path_setup_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIS_DATA_PATH_SETUP, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + if (bis_id != NULL) { + *bis_id = ev->bis_id; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_gap_bis_broadcast(uint8_t bis_id, struct net_buf_simple *buf) +{ + struct btp_gap_bis_broadcast_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_GAP; + cmd_hdr->opcode = BTP_GAP_BIS_BROADCAST; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + __ASSERT(buf->len <= net_buf_simple_tailroom(&cmd_buffer), "No more tail room"); + cmd->bis_id = bis_id; + cmd->data_len = buf->len; + net_buf_simple_add_mem(&cmd_buffer, buf->data, buf->len); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_gap_bis_stream_received(struct net_buf_simple *rx) +{ + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIS_STREAM_RECEIVED, &buf); + __ASSERT(buf->len <= net_buf_simple_tailroom(rx), "No more tail room"); + net_buf_simple_add_mem(rx, buf->data, buf->len); + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_gap_big_sync_lost(bt_addr_le_t *address, uint8_t *reason) +{ + struct btp_gap_big_sync_lost_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BIG_SYNC_LOST, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + if (reason != NULL) { + *reason = ev->reason; + } + + net_buf_unref(buf); +} + #endif /* BSIM_BTP_H_ */ diff --git a/tests/bsim/bluetooth/tester/src/host/iso_broadcaster.c b/tests/bsim/bluetooth/tester/src/host/iso_broadcaster.c new file mode 100644 index 0000000000000..4ba103da5a306 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/host/iso_broadcaster.c @@ -0,0 +1,87 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_iso_broadcaster, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10}; + +#define BIS_DATA_LEN 10 +#define BIG_INTERVAL 10000 /* 10ms */ + +static void test_iso_broadcaster(void) +{ + uint8_t bis_id; + uint32_t count = 100; /* 100 BIS data packets */ + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t ev_addr; + + NET_BUF_SIMPLE_DEFINE(data, BIS_DATA_LEN); + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + + bsim_btp_gap_set_connectable(false); + bsim_btp_gap_set_extended_advertising(true); + bsim_btp_gap_set_discoverable(BTP_GAP_GENERAL_DISCOVERABLE); + bsim_btp_gap_start_advertising(0U, 0U, NULL, BT_HCI_OWN_ADDR_PUBLIC); + bsim_btp_gap_padv_configure(BTP_GAP_PADV_INCLUDE_TX_POWER, 150, 200); + bsim_btp_gap_padv_start(); + bsim_btp_gap_create_big(1, BIG_INTERVAL, 20, true, broadcast_code); + + bsim_btp_wait_for_gap_bis_data_path_setup(&ev_addr, &bis_id); + bt_addr_le_to_str(&ev_addr, addr_str, sizeof(addr_str)); + LOG_INF("Device %s: Data path of BIS %u is setup", addr_str, bis_id); + while (count > 0) { + net_buf_simple_reset(&data); + while (net_buf_simple_tailroom(&data) > 0) { + net_buf_simple_add_u8(&data, (uint8_t)count); + } + bsim_btp_gap_bis_broadcast(bis_id, &data); + + k_sleep(K_USEC(BIG_INTERVAL)); + count--; + } + + k_sleep(K_SECONDS(1)); + bsim_btp_gap_padv_stop(); + k_sleep(K_SECONDS(1)); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "iso_broadcaster", + .test_descr = "Smoketest for the GAP ISO Broadcaster BT Tester behavior", + .test_main_f = test_iso_broadcaster, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_iso_broadcaster_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/host/iso_sync_receiver.c b/tests/bsim/bluetooth/tester/src/host/iso_sync_receiver.c new file mode 100644 index 0000000000000..6b0113effb8cb --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/host/iso_sync_receiver.c @@ -0,0 +1,107 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_iso_sync_receiver, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +extern uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]; +NET_BUF_SIMPLE_DEFINE_STATIC(bis_stream_rx, BTP_MTU); + +static void test_iso_sync_receiver(void) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + char ev_addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t remote_addr; + bt_addr_le_t ev_addr; + uint16_t sync_handle; + uint16_t lost_sync_handle; + uint8_t status; + uint8_t sid; + uint8_t num_bis; + uint8_t encryption; + uint8_t bis_id; + uint8_t reason; + struct btp_gap_bis_stream_received_ev *ev; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_gap_start_discovery(BTP_GAP_DISCOVERY_FLAG_LE); + bsim_btp_wait_for_gap_device_found(&remote_addr); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Found remote device %s", addr_str); + + bsim_btp_gap_padv_create_sync(&remote_addr, 0, 0, 0x200, 0); + bsim_btp_wait_for_gap_periodic_sync_established(&ev_addr, &sync_handle, &status); + bt_addr_le_to_str(&ev_addr, ev_addr_str, sizeof(ev_addr_str)); + TEST_ASSERT(bt_addr_le_eq(&remote_addr, &ev_addr), "%s != %s", addr_str, ev_addr_str); + TEST_ASSERT(status == 0, "Sync failed with status %u", status); + LOG_INF("Device %s: periodic synced %u status %u", addr_str, sync_handle, status); + + bsim_btp_wait_for_gap_periodic_biginfo(&ev_addr, &sid, &num_bis, &encryption); + bt_addr_le_to_str(&ev_addr, ev_addr_str, sizeof(ev_addr_str)); + TEST_ASSERT(bt_addr_le_eq(&remote_addr, &ev_addr), "%s != %s", addr_str, ev_addr_str); + LOG_INF("Device %s: BIGinfo sid %u num_bis %u enc %u", addr_str, sid, num_bis, encryption); + + bsim_btp_gap_big_create_sync(&remote_addr, sid, num_bis, BIT(0), 0x00, 0xFF, encryption, + broadcast_code); + + bsim_btp_wait_for_gap_bis_data_path_setup(&ev_addr, &bis_id); + bt_addr_le_to_str(&ev_addr, ev_addr_str, sizeof(ev_addr_str)); + TEST_ASSERT(bt_addr_le_eq(&remote_addr, &ev_addr), "%s != %s", addr_str, ev_addr_str); + LOG_INF("Device %s: Data path of BIS %u is setup", addr_str, bis_id); + + do { + net_buf_simple_reset(&bis_stream_rx); + bsim_btp_wait_for_gap_bis_stream_received(&bis_stream_rx); + TEST_ASSERT(bis_stream_rx.len >= sizeof(*ev)); + + ev = net_buf_simple_pull_mem(&bis_stream_rx, sizeof(*ev)); + bt_addr_le_to_str(&ev->address, ev_addr_str, sizeof(ev_addr_str)); + TEST_ASSERT(bt_addr_le_eq(&ev->address, &ev_addr)); + TEST_ASSERT(ev->bis_id == bis_id, "Invalid BIS %u != %u", ev->bis_id, bis_id); + LOG_INF("Device %s: BIS Stream RX BIS %u len %u flags %u TS %u seq_num %u", + addr_str, ev->bis_id, ev->data_len, ev->flags, ev->ts, ev->seq_num); + LOG_HEXDUMP_INF(bis_stream_rx.data, bis_stream_rx.len, "BIS Stream RX data: "); + } while (ev->data_len < 1); + + bsim_btp_wait_for_gap_periodic_sync_lost(&lost_sync_handle, &reason); + TEST_ASSERT(lost_sync_handle == sync_handle, "Sync lost handle mismatch %u != %u", + lost_sync_handle, sync_handle); + LOG_INF("Device %s: Periodic sync lost (reason %u)", addr_str, reason); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "iso_sync_receiver", + .test_descr = "Smoketest for the GAP ISO Sync receiver BT Tester behavior", + .test_main_f = test_iso_sync_receiver, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_iso_sync_receiver_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/test_main.c b/tests/bsim/bluetooth/tester/src/test_main.c index ab6e4565e4c7b..ac9c9e38cc5a2 100644 --- a/tests/bsim/bluetooth/tester/src/test_main.c +++ b/tests/bsim/bluetooth/tester/src/test_main.c @@ -17,6 +17,8 @@ extern struct bst_test_list *test_micp_central_install(struct bst_test_list *tes extern struct bst_test_list *test_micp_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_vcp_central_install(struct bst_test_list *tests); extern struct bst_test_list *test_vcp_peripheral_install(struct bst_test_list *tests); +extern struct bst_test_list *test_iso_broadcaster_install(struct bst_test_list *tests); +extern struct bst_test_list *test_iso_sync_receiver_install(struct bst_test_list *tests); bst_test_install_t test_installers[] = { test_csip_central_install, @@ -29,6 +31,8 @@ bst_test_install_t test_installers[] = { test_micp_peripheral_install, test_vcp_central_install, test_vcp_peripheral_install, + test_iso_broadcaster_install, + test_iso_sync_receiver_install, NULL, }; diff --git a/tests/bsim/bluetooth/tester/tests_scripts/gap_iso.sh b/tests/bsim/bluetooth/tester/tests_scripts/gap_iso.sh new file mode 100755 index 0000000000000..a2df2db1e7072 --- /dev/null +++ b/tests/bsim/bluetooth/tester/tests_scripts/gap_iso.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Copyright 2024-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +# Smoketest for GAP ISO BTP commands with the BT tester + +simulation_id="tester_gap_iso" +verbosity_level=2 +EXECUTE_TIMEOUT=100 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +UART_DIR=/tmp/bs_${USER}/${simulation_id}/ +UART_ISO_BROADCASTER=${UART_DIR}/broadcaster +UART_ISO_SYNC_RECEIVER=${UART_DIR}/sync_receiver + +# broadcaster BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=10 -d=0 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_ISO_BROADCASTER}.tx -uart0_fifob_txfile=${UART_ISO_BROADCASTER}.rx + +# broadcaster Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=21 -d=10 -RealEncryption=1 -testid=iso_broadcaster \ + -nosim -uart0_fifob_rxfile=${UART_ISO_BROADCASTER}.rx \ + -uart0_fifob_txfile=${UART_ISO_BROADCASTER}.tx + +# Sync receiver BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=32 -d=1 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_ISO_SYNC_RECEIVER}.tx -uart0_fifob_txfile=${UART_ISO_SYNC_RECEIVER}.rx + +# Sync receiver Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=43 -d=11 -RealEncryption=1 \ + -testid=iso_sync_receiver -nosim -uart0_fifob_rxfile=${UART_ISO_SYNC_RECEIVER}.rx \ + -uart0_fifob_txfile=${UART_ISO_SYNC_RECEIVER}.tx + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs # Wait for all programs in background and return != 0 if any fails From 8f251c1d83d276444dd8e084cb32a23c7f91a08d Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 23 Jul 2025 10:23:47 +0800 Subject: [PATCH 0227/1076] tests: bsim: tester: Fix payload length endian issue The payload length saved in command header should be changed from CPU endian to little-endian. Use `sys_cpu_to_le16()` to fix the issue. Signed-off-by: Lyle Zhu --- tests/bsim/bluetooth/tester/src/bsim_btp.h | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.h b/tests/bsim/bluetooth/tester/src/bsim_btp.h index a4088ec153944..1747d53cac15a 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.h +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.h @@ -37,7 +37,7 @@ static inline void bsim_btp_core_register(uint8_t id) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); cmd->id = id; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -143,7 +143,7 @@ static inline void bsim_btp_gap_set_discoverable(uint8_t discoverable) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); cmd->discoverable = discoverable; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -173,7 +173,7 @@ static inline void bsim_btp_gap_start_advertising(uint8_t adv_data_len, uint8_t net_buf_simple_add_le32(&cmd_buffer, 0xFFFF); /* unused in Zephyr */ net_buf_simple_add_u8(&cmd_buffer, own_addr_type); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -192,7 +192,7 @@ static inline void bsim_btp_gap_start_discovery(uint8_t flags) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); cmd->flags = flags; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -207,7 +207,7 @@ static inline void bsim_btp_gap_stop_discovery(void) cmd_hdr->service = BTP_SERVICE_ID_GAP; cmd_hdr->opcode = BTP_GAP_STOP_DISCOVERY; cmd_hdr->index = BTP_INDEX; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -241,7 +241,7 @@ static inline void bsim_btp_gap_connect(const bt_addr_le_t *address, uint8_t own bt_addr_le_copy(&cmd->address, address); cmd->own_addr_type = own_addr_type; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -274,7 +274,7 @@ static inline void bsim_btp_gap_disconnect(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -307,7 +307,7 @@ static inline void bsim_btp_gap_pair(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -400,7 +400,7 @@ static inline void bsim_btp_vcp_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -437,7 +437,7 @@ static inline void bsim_btp_vcp_ctlr_set_vol(const bt_addr_le_t *address, uint8_ bt_addr_le_copy(&cmd->address, address); cmd->volume = volume; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -478,7 +478,7 @@ static inline void bsim_btp_vocs_state_set(const bt_addr_le_t *address, int16_t bt_addr_le_copy(&cmd->address, address); cmd->offset = sys_cpu_to_le16(offset); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -519,7 +519,7 @@ static inline void bsim_btp_aics_set_gain(const bt_addr_le_t *address, int8_t ga bt_addr_le_copy(&cmd->address, address); cmd->gain = gain; - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -559,7 +559,7 @@ static inline void bsim_btp_micp_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -595,7 +595,7 @@ static inline void bsim_btp_micp_ctlr_mute(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } From e8bbf5c7323b3c108474f9c210e3608c7ead8570 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 23 Jul 2025 10:27:40 +0800 Subject: [PATCH 0228/1076] tests: tester: Add LOG_* to btp.c for debug purpose Add `LOG_ERR()` to log all reasons if status is `BTP_STATUS_FAILED`. Add `LOG_DBG()` to log the excution result of the BTP commander. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/bluetooth/tester/src/btp.c b/tests/bluetooth/tester/src/btp.c index da8a2826409a7..32165786b4fb8 100644 --- a/tests/bluetooth/tester/src/btp.c +++ b/tests/bluetooth/tester/src/btp.c @@ -111,13 +111,17 @@ static void cmd_handler(void *p1, void *p2, void *p3) if (len > BTP_DATA_MAX_SIZE) { status = BTP_STATUS_FAILED; + LOG_ERR("Data len exceeds BTP MTU %u > %u", len, BTP_DATA_MAX_SIZE); } else if (btp->index != hdr->index) { status = BTP_STATUS_FAILED; + LOG_ERR("Index mismatch %u != %u", btp->index, hdr->index); } else if ((btp->expect_len >= 0) && (btp->expect_len != len)) { status = BTP_STATUS_FAILED; + LOG_ERR("len mismatch %u != %u", btp->expect_len, len); } else { status = btp->func(hdr->data, len, cmd->rsp, &rsp_len); + LOG_DBG("Command returns status %u", status); } /* This means that caller likely overwrote rsp buffer */ From 7f12732dd61927c7b9d20a524181ecfcdef49068 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 23 Jul 2025 11:17:43 +0800 Subject: [PATCH 0229/1076] tests: tester: Add debug log Add debug log if the function `tester_gap_create_adv_instance()` is failed. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp_gap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index ed82a1ed3ad5b..b309589455f06 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -2028,6 +2028,7 @@ int tester_gap_padv_configure(struct bt_le_ext_adv *ext_adv, BTP_GAP_ADDR_TYPE_IDENTITY, ad, 1, NULL, 0, NULL, &ext_adv); if (err != 0) { + LOG_ERR("Failed to create adv instance (err %d)\n", err); return -EINVAL; } } @@ -2037,7 +2038,7 @@ int tester_gap_padv_configure(struct bt_le_ext_adv *ext_adv, */ err = bt_le_per_adv_set_param(ext_adv, param); if (err != 0) { - LOG_DBG("Failed to set periodic advertising parameters (err %d)\n", err); + LOG_ERR("Failed to set periodic advertising parameters (err %d)\n", err); } return err; From 77e6ff8ad4e038b2e37f1d01b498cba2dc637bf1 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 23 Jul 2025 13:18:27 +0800 Subject: [PATCH 0230/1076] tests: tester: Correct return value if ext adv create failed The error code instead of `BTP_STATUS_FAILED` of the function `bt_le_ext_adv_create()` should be returned. Returns the error code returned by `bt_le_ext_adv_create()`. Signed-off-by: Lyle Zhu --- tests/bluetooth/tester/src/btp_gap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index b309589455f06..07bd6a79df9a6 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -831,7 +831,8 @@ int tester_gap_create_adv_instance(struct bt_le_adv_param *param, err = bt_le_ext_adv_create(param, NULL, &ext_adv_sets[index]); if (err != 0) { - return BTP_STATUS_FAILED; + LOG_ERR("Failed to create ext adv(err %d)", err); + return err; } err = bt_le_ext_adv_set_data(ext_adv_sets[index], ad, ad_len, sd_len ? From fe356031db325f6de7698d86863a36f21e007cd0 Mon Sep 17 00:00:00 2001 From: Christian Rask Date: Wed, 11 Jun 2025 21:32:13 +0200 Subject: [PATCH 0231/1076] drivers: mipi_dbi: spi: add tearing effect support Add tearing effect support for better display synchronization. This allows users to configure an external interrupt on falling/rising edges of the gpio connected to the display controllers tearing effect pin. See dt-bindings/mipi_dbi/mipi_dbi.h for details of how this works for mipi_dbi display interfaces. Signed-off-by: Christian Rask --- drivers/mipi_dbi/mipi_dbi_spi.c | 166 ++++++++++++++++-- .../mipi-dbi/zephyr,mipi-dbi-spi.yaml | 6 + 2 files changed, 153 insertions(+), 19 deletions(-) diff --git a/drivers/mipi_dbi/mipi_dbi_spi.c b/drivers/mipi_dbi/mipi_dbi_spi.c index 85cba935dff3b..a62bb416c5f34 100644 --- a/drivers/mipi_dbi/mipi_dbi_spi.c +++ b/drivers/mipi_dbi/mipi_dbi_spi.c @@ -15,23 +15,6 @@ #include LOG_MODULE_REGISTER(mipi_dbi_spi, CONFIG_MIPI_DBI_LOG_LEVEL); -struct mipi_dbi_spi_config { - /* SPI hardware used to send data */ - const struct device *spi_dev; - /* Command/Data gpio */ - const struct gpio_dt_spec cmd_data; - /* Reset GPIO */ - const struct gpio_dt_spec reset; - /* Minimum transfer bits */ - const uint8_t xfr_min_bits; -}; - -struct mipi_dbi_spi_data { - struct k_mutex lock; - /* Used for 3 wire mode */ - uint16_t spi_byte; -}; - /* Expands to 1 if the node does not have the `write-only` property */ #define MIPI_DBI_SPI_WRITE_ONLY_ABSENT(n) (!DT_INST_PROP(n, write_only)) | @@ -42,6 +25,16 @@ struct mipi_dbi_spi_data { #define MIPI_DBI_SPI_READ_REQUIRED DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_SPI_WRITE_ONLY_ABSENT) 0 uint32_t var = MIPI_DBI_SPI_READ_REQUIRED; +/* Expands to 1 if the node configures a gpio in the `te-gpios` property */ +#define MIPI_DBI_SPI_TE_GPIOS_PRESENT(n) DT_INST_NODE_HAS_PROP(n, te_gpios) | + +/* This macro will evaluate to 1 if any of the nodes with zephyr,mipi-dbi-spi + * has a `te-gpios` property. The intention here is to allow the entire + * configure_te and mipi_dbi_spi_te_cb functions to be optimized out when it + * is not needed. + */ +#define MIPI_DBI_SPI_TE_REQUIRED DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_SPI_TE_GPIOS_PRESENT) 0 + /* Expands to 1 if the node does reflect the enum in `xfr-min-bits` property */ #define MIPI_DBI_SPI_XFR_8BITS(n) (DT_INST_STRING_UPPER_TOKEN(n, xfr_min_bits) \ == MIPI_DBI_SPI_XFR_8BIT) | @@ -64,6 +57,53 @@ uint32_t var = MIPI_DBI_SPI_READ_REQUIRED; */ #define MIPI_DBI_DC_BIT BIT(8) +struct mipi_dbi_spi_config { + /* SPI hardware used to send data */ + const struct device *spi_dev; + /* Command/Data gpio */ + const struct gpio_dt_spec cmd_data; + /* Tearing Effect GPIO */ + const struct gpio_dt_spec tearing_effect; + /* Reset GPIO */ + const struct gpio_dt_spec reset; + /* Minimum transfer bits */ + const uint8_t xfr_min_bits; +}; + +struct mipi_dbi_spi_data { + struct k_mutex lock; +#if MIPI_DBI_SPI_TE_REQUIRED + struct k_sem te_signal; + k_timeout_t te_delay; + atomic_t in_active_area; + struct gpio_callback te_cb_data; +#endif + /* Used for 3 wire mode */ + uint16_t spi_byte; +}; + +#if MIPI_DBI_SPI_TE_REQUIRED + +static void mipi_dbi_spi_te_cb(const struct device *dev, + struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct mipi_dbi_spi_data *data = CONTAINER_OF(cb, + struct mipi_dbi_spi_data, te_cb_data); + + /* Open frame window */ + if (!atomic_cas(&data->in_active_area, 0, 1)) { + return; + } + + k_sem_give(&data->te_signal); +} + +#endif /* MIPI_DBI_SPI_TE_REQUIRED */ + static inline int mipi_dbi_spi_write_helper_3wire(const struct device *dev, const struct mipi_dbi_config *dbi_config, @@ -323,8 +363,32 @@ static int mipi_dbi_spi_write_display(const struct device *dev, { ARG_UNUSED(pixfmt); - return mipi_dbi_spi_write_helper(dev, dbi_config, false, 0x0, - framebuf, desc->buf_size); + int ret = 0; + +#if MIPI_DBI_SPI_TE_REQUIRED + struct mipi_dbi_spi_data *data = dev->data; + + /* Wait for TE signal, otherwise transferring can begin */ + if (!atomic_get(&data->in_active_area)) { + ret = k_sem_take(&data->te_signal, K_FOREVER); + if (ret < 0) { + return ret; + } + k_sleep(data->te_delay); + } +#endif + + ret = mipi_dbi_spi_write_helper(dev, dbi_config, false, 0x0, + framebuf, desc->buf_size); + +#if MIPI_DBI_SPI_TE_REQUIRED + /* End of frame reset */ + if (!desc->frame_incomplete) { + atomic_set(&data->in_active_area, 0); + } +#endif + + return ret; } #if MIPI_DBI_SPI_READ_REQUIRED @@ -507,6 +571,66 @@ static int mipi_dbi_spi_release(const struct device *dev, return spi_release(config->spi_dev, &dbi_config->config); } +#if MIPI_DBI_SPI_TE_REQUIRED + +static int mipi_dbi_spi_configure_te(const struct device *dev, + uint8_t edge, + k_timeout_t delay_us) +{ + const struct mipi_dbi_spi_config *config = dev->config; + struct mipi_dbi_spi_data *data = dev->data; + int ret = 0; + + if (edge == MIPI_DBI_TE_NO_EDGE) { + /* No configuration */ + return 0; + } + + if (!mipi_dbi_has_pin(&config->tearing_effect)) { + return -ENOTSUP; + } + + if (!gpio_is_ready_dt(&config->tearing_effect)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->tearing_effect, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure Tearing Effect GPIO (%d)", ret); + return ret; + } + + if (edge == MIPI_DBI_TE_RISING_EDGE) { + ret = gpio_pin_interrupt_configure_dt(&config->tearing_effect, + GPIO_INT_EDGE_RISING); + } else if (edge == MIPI_DBI_TE_FALLING_EDGE) { + ret = gpio_pin_interrupt_configure_dt(&config->tearing_effect, + GPIO_INT_EDGE_FALLING); + } + if (ret < 0) { + LOG_ERR("Could not configure Tearing Effect GPIO EXT interrupt (%d)", ret); + return ret; + } + + gpio_init_callback(&data->te_cb_data, mipi_dbi_spi_te_cb, + BIT(config->tearing_effect.pin)); + + ret = gpio_add_callback(config->tearing_effect.port, + &data->te_cb_data); + if (ret < 0) { + LOG_ERR("Could not add Tearing Effect GPIO callback (%d)", ret); + return ret; + } + + data->te_delay = delay_us; + atomic_set(&data->in_active_area, 0); + k_sem_init(&data->te_signal, 0, 1); + + return ret; +} + +#endif /* MIPI_DBI_SPI_TE_REQUIRED */ + static int mipi_dbi_spi_init(const struct device *dev) { const struct mipi_dbi_spi_config *config = dev->config; @@ -553,6 +677,9 @@ static DEVICE_API(mipi_dbi, mipi_dbi_spi_driver_api) = { #if MIPI_DBI_SPI_READ_REQUIRED .command_read = mipi_dbi_spi_command_read, #endif +#if MIPI_DBI_SPI_TE_REQUIRED + .configure_te = mipi_dbi_spi_configure_te, +#endif }; #define MIPI_DBI_SPI_INIT(n) \ @@ -561,6 +688,7 @@ static DEVICE_API(mipi_dbi, mipi_dbi_spi_driver_api) = { .spi_dev = DEVICE_DT_GET( \ DT_INST_PHANDLE(n, spi_dev)), \ .cmd_data = GPIO_DT_SPEC_INST_GET_OR(n, dc_gpios, {}), \ + .tearing_effect = GPIO_DT_SPEC_INST_GET_OR(n, te_gpios, {}), \ .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {}), \ .xfr_min_bits = DT_INST_STRING_UPPER_TOKEN(n, xfr_min_bits) \ }; \ diff --git a/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml b/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml index e3e292fefa5b5..21793683482bb 100644 --- a/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml +++ b/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml @@ -22,6 +22,12 @@ properties: Data/command gpio pin. Required when using 4 wire SPI mode (Mode C1). Set to low when sending a command, or high when sending data. + te-gpios: + type: phandle-array + description: | + Tearing Effect GPIO pin. Set to high when the display is blanking + (i.e., not actively reading pixels from its RAM). + reset-gpios: type: phandle-array description: | From 23157c10e537cc123a5c7a41e340f94c0fa87fb1 Mon Sep 17 00:00:00 2001 From: Christian Rask Date: Wed, 11 Jun 2025 21:35:30 +0200 Subject: [PATCH 0232/1076] drivers: display: ili9xxx: add tearing effect support Add tearing effect support for better display synchronization. If tearing effect is configured in the mipi_dbi device, the display controller configures its tearing effect register. Display orientation configuration is updated to also rotated the direction of the display pixel vertical scanline, such that scan order matches the display orientation. Signed-off-by: Christian Rask --- drivers/display/display_ili9xxx.c | 20 +++++++++++++++++-- drivers/display/display_ili9xxx.h | 2 ++ .../display/ilitek,ili9xxx-common.yaml | 6 +++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index fbe4f06aa1a1e..ef258cfed8922 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -331,7 +331,7 @@ static int ili9xxx_set_orientation(const struct device *dev, } else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) { tx_data |= ILI9XXX_MADCTL_MV; } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) { - tx_data |= ILI9XXX_MADCTL_MY; + tx_data |= ILI9XXX_MADCTL_MY | ILI9XXX_MADCTL_ML; } else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) { tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MX | ILI9XXX_MADCTL_MY; @@ -342,7 +342,8 @@ static int ili9xxx_set_orientation(const struct device *dev, } else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) { tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MY; } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) { - tx_data |= ILI9XXX_MADCTL_MY | ILI9XXX_MADCTL_MX; + tx_data |= ILI9XXX_MADCTL_MY | ILI9XXX_MADCTL_MX | + ILI9XXX_MADCTL_ML; } else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) { tx_data |= ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MX; } @@ -425,6 +426,20 @@ static int ili9xxx_configure(const struct device *dev) } } + if (config->te_mode != MIPI_DBI_TE_NO_EDGE) { + /* Attempt to enable TE signal */ + r = mipi_dbi_configure_te(config->mipi_dev, config->te_mode, 0); + if (r == 0) { + /* TE was enabled, send TEON, and enable vblank only */ + const uint8_t tx_data = 0x0; /* Set M bit to 0 */ + + r = ili9xxx_transmit(dev, ILI9XXX_TEON, &tx_data, 1U); + if (r < 0) { + return r; + } + } + } + r = config->regs_init_fn(dev); if (r < 0) { return r; @@ -535,6 +550,7 @@ static const struct ili9xxx_quirks ili9488_quirks = { .x_resolution = ILI##t##_X_RES, \ .y_resolution = ILI##t##_Y_RES, \ .inversion = DT_PROP(INST_DT_ILI9XXX(n, t), display_inversion),\ + .te_mode = MIPI_DBI_TE_MODE_DT(INST_DT_ILI9XXX(n, t), te_mode),\ .regs = &ili##t##_regs_##n, \ .regs_init_fn = ili##t##_regs_init, \ }; \ diff --git a/drivers/display/display_ili9xxx.h b/drivers/display/display_ili9xxx.h index 861b26d436099..cb3774246c72a 100644 --- a/drivers/display/display_ili9xxx.h +++ b/drivers/display/display_ili9xxx.h @@ -24,6 +24,7 @@ #define ILI9XXX_RAMWR 0x2c #define ILI9XXX_RGBSET 0x2d #define ILI9XXX_RAMRD 0x2e +#define ILI9XXX_TEON 0x35 #define ILI9XXX_MADCTL 0x36 #define ILI9XXX_PIXSET 0x3A #define ILI9XXX_RAMRD_CONT 0x3e @@ -74,6 +75,7 @@ struct ili9xxx_config { uint16_t x_resolution; uint16_t y_resolution; bool inversion; + uint8_t te_mode; const void *regs; int (*regs_init_fn)(const struct device *dev); }; diff --git a/dts/bindings/display/ilitek,ili9xxx-common.yaml b/dts/bindings/display/ilitek,ili9xxx-common.yaml index a48dd8d34c704..7ce2f5eaa9c59 100644 --- a/dts/bindings/display/ilitek,ili9xxx-common.yaml +++ b/dts/bindings/display/ilitek,ili9xxx-common.yaml @@ -7,7 +7,11 @@ title: ILI9XXX display controllers common properties. description: | Ilitek ILI9XXX is a color TFT-LCD controller series. -include: [mipi-dbi-spi-device.yaml, display-controller.yaml] +include: + - display-controller.yaml + - name: mipi-dbi-spi-device.yaml + property-blocklist: + - te-delay properties: pixel-format: From c5c2e230f98d3eee0df2a47ce7c6dd6d5120c44c Mon Sep 17 00:00:00 2001 From: Christian Rask Date: Wed, 11 Jun 2025 21:35:37 +0200 Subject: [PATCH 0233/1076] boards: shields: x_nucleo_gfx01m2: add tearing effect gpio configuration Add tearing effect configuration of the spi display. The falling edge of the tearing signal is chosen because the spi bandwidth is lower than the display refresh rate at 60fps. Signed-off-by: Christian Rask --- boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay index 0f3d0261a71c6..fff1929494990 100644 --- a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay +++ b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay @@ -56,6 +56,7 @@ compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&st_morpho_lcd_spi>; dc-gpios = <&st_morpho_header ST_MORPHO_R_25 GPIO_ACTIVE_HIGH>; + te-gpios = <&st_morpho_header ST_MORPHO_L_28 GPIO_ACTIVE_HIGH>; reset-gpios = <&st_morpho_header ST_MORPHO_L_30 GPIO_ACTIVE_LOW>; #address-cells = <1>; #size-cells = <0>; @@ -65,6 +66,10 @@ compatible = "ilitek,ili9341"; mipi-max-frequency = ; mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + /* Transmit on falling edge to avoid tearing, since display + * reads pixels faster than we can transfer. + */ + te-mode = "MIPI_DBI_TE_FALLING_EDGE"; reg = <0>; width = <240>; height = <320>; From 8d826fd1eaf0683700bbd2754607a9a0db1901b9 Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Mon, 7 Jul 2025 13:28:52 +0200 Subject: [PATCH 0234/1076] samples: i2s_codec: Add mimxrt595_evk DTO lic. hdr. Add license header to the mimxrt595_evk/mimxrt595s/cm33 i2s_codec's DT overlay. Signed-off-by: Vit Stanicek --- .../i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.overlay | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.overlay b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.overlay index 022fff64aaab6..acee8d8110353 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.overlay +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.overlay @@ -1,3 +1,9 @@ +/* + * Copyright 2024, 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + / { aliases { i2s-codec-rx = &i2s0; From bddc1a4664ad34bd9e77a60ff16f5719d2cedd9e Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Fri, 27 Jun 2025 13:32:45 +0200 Subject: [PATCH 0235/1076] samples: i2s_codec: Parametrise peripheral and codec position Add Kconfig symbol USE_CODEC_CLOCK. Modify configuration for supported boards. This change enables to adjust the position of both the codec and I2S peripheral on the I2S bus. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/Kconfig | 8 ++++++++ .../boards/mimxrt595_evk_mimxrt595s_cm33.conf | 3 ++- .../boards/mimxrt685_evk_mimxrt685s_cm33.conf | 3 ++- samples/drivers/i2s/i2s_codec/src/main.c | 10 +++++++++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/samples/drivers/i2s/i2s_codec/Kconfig b/samples/drivers/i2s/i2s_codec/Kconfig index 08b66934a0290..aa4988b775166 100644 --- a/samples/drivers/i2s/i2s_codec/Kconfig +++ b/samples/drivers/i2s/i2s_codec/Kconfig @@ -17,6 +17,14 @@ config SAMPLE_FREQ help Sample frequency of the system. +config USE_CODEC_CLOCK + bool "I2S BCK is generated by a selected codec device" + help + If selected, the I2S selected peripheral will be configured to consume + (receive) the I2S BCK and WS signals and the codec will be configured + to generate those. If not selected, the I2S peripheral will generate + them and the codec will be expected to consume them. + config USE_DMIC bool "Use DMIC as an audio input" diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf index 7af9fce92a432..90b4b18eec47c 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024, 2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -14,3 +14,4 @@ CONFIG_AUDIO_CODEC_WM8904=y CONFIG_I2S_INIT_BUFFERS=4 CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=y +CONFIG_USE_CODEC_CLOCK=y diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf index 7af9fce92a432..90b4b18eec47c 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024, 2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -14,3 +14,4 @@ CONFIG_AUDIO_CODEC_WM8904=y CONFIG_I2S_INIT_BUFFERS=4 CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=y +CONFIG_USE_CODEC_CLOCK=y diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index 272ae92c009c1..2a69e7d8429cd 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -116,7 +116,11 @@ int main(void) audio_cfg.dai_cfg.i2s.word_size = SAMPLE_BIT_WIDTH; audio_cfg.dai_cfg.i2s.channels = 2; audio_cfg.dai_cfg.i2s.format = I2S_FMT_DATA_FORMAT_I2S; - audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_MASTER; +#ifdef CONFIG_USE_CODEC_CLOCK + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER; +#else + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_SLAVE | I2S_OPT_BIT_CLK_SLAVE; +#endif audio_cfg.dai_cfg.i2s.frame_clk_freq = SAMPLE_FREQUENCY; audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab; audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE; @@ -143,7 +147,11 @@ int main(void) config.word_size = SAMPLE_BIT_WIDTH; config.channels = NUMBER_OF_CHANNELS; config.format = I2S_FMT_DATA_FORMAT_I2S; +#ifdef CONFIG_USE_CODEC_CLOCK + config.options = I2S_OPT_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE; +#else config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER; +#endif config.frame_clk_freq = SAMPLE_FREQUENCY; config.mem_slab = &mem_slab; config.block_size = BLOCK_SIZE; From 36967affbd190bbe617109fec9eac90649eb685e Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Fri, 27 Jun 2025 13:27:24 +0200 Subject: [PATCH 0236/1076] samples: i2s_codec: Move audio slab to uncached Move mem_slab (audio queue) to an uncached region with __nocache. On platforms with data cache (such as platforms with the Cortex M7 core), it's desirable to have the audio data in an uncached region, so that all data is committed in the selected location before DMA transfers are triggered. Playback problems observed on mimxrt1170_evk/mimxrt1176/cm7 before this was done. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index 2a69e7d8429cd..0f1ae84ec4034 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -32,7 +32,8 @@ #define BLOCK_SIZE (BYTES_PER_SAMPLE * SAMPLES_PER_BLOCK) #define BLOCK_COUNT (INITIAL_BLOCKS + 32) -K_MEM_SLAB_DEFINE_STATIC(mem_slab, BLOCK_SIZE, BLOCK_COUNT, 4); + +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(mem_slab, __nocache, BLOCK_SIZE, BLOCK_COUNT, 4); static bool configure_tx_streams(const struct device *i2s_dev, struct i2s_config *config) { From a39483477d213a4809cec78848f7f4e7646c6067 Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Tue, 1 Jul 2025 15:15:33 +0200 Subject: [PATCH 0237/1076] samples: i2s_codec: Fix buffer size Use BLOCK_SIZE instead of the test 16 kHz sine wave length. Add a build check so that BLOCK_SIZE doesn't overflow the test sine wave buffer. This accounts for situations where the sample queue can't be big enough, mainly when it doesn't fit in the device's SRAM and the count of samples queued will be less. As the test sine wave vector contains ~42 periods, it can be truncated. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/src/main.c | 7 ++++++- samples/drivers/i2s/i2s_codec/src/sine.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index 0f1ae84ec4034..4298d6b2e6d8d 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #ifndef CONFIG_USE_DMIC @@ -189,8 +190,12 @@ int main(void) ret = i2s_write(i2s_dev_codec, mem_block, block_size); #else /* If not using DMIC, play a sine wave 440Hz */ + + BUILD_ASSERT( + BLOCK_SIZE <= __16kHz16bit_stereo_sine_pcm_len, + "BLOCK_SIZE is bigger than test sine wave buffer size." + ); mem_block = (void *)&__16kHz16bit_stereo_sine_pcm; - block_size = __16kHz16bit_stereo_sine_pcm_len; ret = i2s_buf_write(i2s_dev_codec, mem_block, block_size); #endif diff --git a/samples/drivers/i2s/i2s_codec/src/sine.h b/samples/drivers/i2s/i2s_codec/src/sine.h index 467b8177a4c16..99dfd1d0e90fe 100644 --- a/samples/drivers/i2s/i2s_codec/src/sine.h +++ b/samples/drivers/i2s/i2s_codec/src/sine.h @@ -444,6 +444,6 @@ unsigned char __16kHz16bit_stereo_sine_pcm[] = { 0xa3, 0xc0, 0xa3, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xfc, 0xc0, 0xfc, 0xc0, 0xfd, 0xc3, 0xfd, 0xc3, 0xc8, 0xc8, 0xc8, 0xc8, 0x38, 0xcf, 0x38, 0xcf, 0x1c, 0xd7, 0x1c, 0xd7, 0x37, 0xe0, 0x37, 0xe0, 0x45, 0xea, 0x45, 0xea, 0xf8, 0xf4, 0xf8, 0xf4}; -unsigned int __16kHz16bit_stereo_sine_pcm_len = 6400; +const unsigned int __16kHz16bit_stereo_sine_pcm_len = sizeof(__16kHz16bit_stereo_sine_pcm); #endif /* SINE_H_ */ From 4bdc70d0453ac2369bce6180023cee863ea9d3d8 Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Tue, 1 Jul 2025 15:12:17 +0200 Subject: [PATCH 0238/1076] samples: i2s_codec: Reorganise Kconfig fragments Reorganise Kconfig fragments (prj.conf, boards/*.conf). Rename mimxrt1170_evk@B/mimxrt1176/cm7 fragments to mimxrt1170_evk/mimxrt1176/cm7. Change Kconfig defaults for SAMPLE_RATE and I2S_INIT_BUFFER. This change is meant to reduce the length of target-specific configuration, as some of the settings are duplicated across targets. Also, with the inclusion of the sine wave vector, the default sample rate of this sample changed to 16 kHz. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/Kconfig | 4 ++-- .../boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf | 3 --- .../i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.conf | 3 --- ...m7_B.overlay => mimxrt1170_evk_mimxrt1176_cm7.overlay} | 0 .../i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf | 8 -------- .../i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf | 8 -------- .../boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf | 3 --- samples/drivers/i2s/i2s_codec/prj.conf | 1 + 8 files changed, 3 insertions(+), 27 deletions(-) rename samples/drivers/i2s/i2s_codec/boards/{mimxrt1170_evk_mimxrt1176_cm7_B.overlay => mimxrt1170_evk_mimxrt1176_cm7.overlay} (100%) diff --git a/samples/drivers/i2s/i2s_codec/Kconfig b/samples/drivers/i2s/i2s_codec/Kconfig index aa4988b775166..f5edd389f1bba 100644 --- a/samples/drivers/i2s/i2s_codec/Kconfig +++ b/samples/drivers/i2s/i2s_codec/Kconfig @@ -5,7 +5,7 @@ source "Kconfig.zephyr" config I2S_INIT_BUFFERS int "Initial count of audio data blocks" - default 2 + default 4 help Controls the initial count of audio data blocks, which are (optionally) filled by data from the DMIC peripheral and played back by the I2S @@ -13,7 +13,7 @@ config I2S_INIT_BUFFERS config SAMPLE_FREQ int "Sample rate" - default 48000 + default 16000 help Sample frequency of the system. diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf index 9e510b56da57a..53f0b7dc69cd4 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf @@ -4,8 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_HEAP_MEM_POOL_SIZE=81920 -CONFIG_AUDIO_CODEC=y CONFIG_DMA_TCD_QUEUE_SIZE=4 -CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=n diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.conf index 9e510b56da57a..53f0b7dc69cd4 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.conf @@ -4,8 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_HEAP_MEM_POOL_SIZE=81920 -CONFIG_AUDIO_CODEC=y CONFIG_DMA_TCD_QUEUE_SIZE=4 -CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=n diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay similarity index 100% rename from samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay rename to samples/drivers/i2s/i2s_codec/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf index 90b4b18eec47c..2dac479916bca 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -4,14 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_DMA=y -CONFIG_I2S_MCUX_FLEXCOMM=y CONFIG_I3C=y -CONFIG_HEAP_MEM_POOL_SIZE=81920 -CONFIG_AUDIO=y -CONFIG_AUDIO_CODEC=y -CONFIG_AUDIO_CODEC_WM8904=y -CONFIG_I2S_INIT_BUFFERS=4 -CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=y CONFIG_USE_CODEC_CLOCK=y diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf index 90b4b18eec47c..2dac479916bca 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt685_evk_mimxrt685s_cm33.conf @@ -4,14 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_DMA=y -CONFIG_I2S_MCUX_FLEXCOMM=y CONFIG_I3C=y -CONFIG_HEAP_MEM_POOL_SIZE=81920 -CONFIG_AUDIO=y -CONFIG_AUDIO_CODEC=y -CONFIG_AUDIO_CODEC_WM8904=y -CONFIG_I2S_INIT_BUFFERS=4 -CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=y CONFIG_USE_CODEC_CLOCK=y diff --git a/samples/drivers/i2s/i2s_codec/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf b/samples/drivers/i2s/i2s_codec/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf index 9e510b56da57a..53f0b7dc69cd4 100644 --- a/samples/drivers/i2s/i2s_codec/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf +++ b/samples/drivers/i2s/i2s_codec/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf @@ -4,8 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_HEAP_MEM_POOL_SIZE=81920 -CONFIG_AUDIO_CODEC=y CONFIG_DMA_TCD_QUEUE_SIZE=4 -CONFIG_SAMPLE_FREQ=16000 CONFIG_USE_DMIC=n diff --git a/samples/drivers/i2s/i2s_codec/prj.conf b/samples/drivers/i2s/i2s_codec/prj.conf index 683caf4f58709..3ae0329c89d22 100644 --- a/samples/drivers/i2s/i2s_codec/prj.conf +++ b/samples/drivers/i2s/i2s_codec/prj.conf @@ -1,3 +1,4 @@ CONFIG_I2S=y CONFIG_AUDIO=y CONFIG_AUDIO_DMIC=y +CONFIG_AUDIO_CODEC=y From d11474ce6463c89a8e43565142fae5914850c845 Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Tue, 12 Aug 2025 14:58:22 +0200 Subject: [PATCH 0239/1076] samples: i2s_codec: Modify DMIC channel mapping Modify DMIC channel mapping (req_chan_map_lo) to account for physical 1:1 mapping between logical channel numbers and physical channel space. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index 4298d6b2e6d8d..bf05cb7c8a0b3 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -132,7 +132,7 @@ int main(void) #if CONFIG_USE_DMIC cfg.channel.req_num_chan = 2; cfg.channel.req_chan_map_lo = dmic_build_channel_map(0, 0, PDM_CHAN_LEFT) | - dmic_build_channel_map(1, 0, PDM_CHAN_RIGHT); + dmic_build_channel_map(1, 1, PDM_CHAN_RIGHT); cfg.streams[0].pcm_rate = SAMPLE_FREQUENCY; cfg.streams[0].block_size = BLOCK_SIZE; From 51e0c52837aa19d7f7d870ce675a2fb88b1956e6 Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Tue, 26 Aug 2025 12:22:34 +0200 Subject: [PATCH 0240/1076] samples: i2s_codec: Factorise initial loop count Replace hard-wired constant "2" with CONFIG_I2S_INIT_BUFFERS in the loop where audio data is read and written. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index bf05cb7c8a0b3..edef0c9f07994 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -178,7 +178,7 @@ int main(void) uint32_t block_size = BLOCK_SIZE; int i; - for (i = 0; i < 2; i++) { + for (i = 0; i < CONFIG_I2S_INIT_BUFFERS; i++) { #if CONFIG_USE_DMIC /* If using DMIC, use a buffer (memory slab) from dmic_read */ ret = dmic_read(dmic_dev, 0, &mem_block, &block_size, TIMEOUT); From 2db38416e66448373ec5ff728f9de51721a9c483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ju=C5=99ena?= Date: Sun, 27 Jul 2025 10:59:23 +0200 Subject: [PATCH 0241/1076] boards: st: nucleo_l432kc: Add arduino connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds new node for arduino nano connector. Signed-off-by: Tomáš Juřena --- .../nucleo_l432kc/arduino_nano_connector.dtsi | 43 +++++++++++++++++++ boards/st/nucleo_l432kc/nucleo_l432kc.dts | 1 + 2 files changed, 44 insertions(+) create mode 100644 boards/st/nucleo_l432kc/arduino_nano_connector.dtsi diff --git a/boards/st/nucleo_l432kc/arduino_nano_connector.dtsi b/boards/st/nucleo_l432kc/arduino_nano_connector.dtsi new file mode 100644 index 0000000000000..efcf317f4522e --- /dev/null +++ b/boards/st/nucleo_l432kc/arduino_nano_connector.dtsi @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Joylab AG + * Copyright (c) 2025 Tomas Jurena + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + arduino_header: connector { + compatible = "arduino-nano-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , /* D0 */ + , /* D1 */ + , /* D2 */ + , /* D3 */ + , /* D4 */ + , /* D5 */ + , /* D6 */ + , /* D7 */ + , /* D8 */ + , /* D9 */ + , /* D10 */ + , /* D11 */ + , /* D12 */ + , /* D13 */ + , /* D14 / A0 */ + , /* D15 / A1 */ + , /* D16 / A2 */ + , /* D17 / A3 */ + , /* D18 / A4 */ + , /* D19 / A5 */ + , /* D20 / A6 */ + ; /* D21 / A7 */ + }; +}; + +arduino_spi: &spi1 {}; +arduino_serial: &usart1 {}; +arduino_i2c: &i2c1 {}; diff --git a/boards/st/nucleo_l432kc/nucleo_l432kc.dts b/boards/st/nucleo_l432kc/nucleo_l432kc.dts index 1d8b4647a4157..b94be61c1bf22 100644 --- a/boards/st/nucleo_l432kc/nucleo_l432kc.dts +++ b/boards/st/nucleo_l432kc/nucleo_l432kc.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include "arduino_nano_connector.dtsi" / { model = "STMicroelectronics STM32L432KC-NUCLEO board"; From 7cb48cce2661b629a9f3099a4e418fe1cf057981 Mon Sep 17 00:00:00 2001 From: James Roy Date: Sun, 20 Jul 2025 21:56:53 +0800 Subject: [PATCH 0242/1076] ztest: Fix the test_status variable to use the ztest_status enum global variable `test_status` should use the enum instead of equivalent integers (such as `1`). Signed-off-by: James Roy --- subsys/testsuite/ztest/src/ztest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index a5d6fc264ef32..080e172652845 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -538,7 +538,7 @@ static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test ret = get_final_test_result(test, ret); Z_TC_END_RESULT(ret, test->name); if (ret == TC_SKIP && current_test_failed_assumption) { - test_status = 1; + test_status = ZTEST_STATUS_HAS_FAILURE; } return ret; @@ -741,7 +741,7 @@ static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test ret = get_final_test_result(test, ret); Z_TC_END_RESULT(ret, test->name); if (ret == TC_SKIP && current_test_failed_assumption) { - test_status = 1; + test_status = ZTEST_STATUS_HAS_FAILURE; } return ret; @@ -1168,7 +1168,7 @@ void ztest_verify_all_test_suites_ran(void) if (test->stats->fail_count + test->stats->pass_count + test->stats->skip_count != test->stats->run_count) { PRINT_DATA("Bad stats for %s.%s\n", test->test_suite_name, test->name); - test_status = 1; + test_status = ZTEST_STATUS_HAS_FAILURE; } } } From 718f0e7272d0a6840feab5f8b6e222122538b591 Mon Sep 17 00:00:00 2001 From: MA Junyi Date: Tue, 19 Aug 2025 21:59:41 +0800 Subject: [PATCH 0243/1076] scripts: compliance: Add items to UNDEF_KCONFIG_ALLOWLIST `BOOT_ENCRYPT_ALG_AES_128` and `BOOT_ENCRYPT_ALG_AES_256` are used in `share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake` They were first introduced in commit 9a1fe30 Signed-off-by: MA Junyi --- scripts/ci/check_compliance.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 9993c7320d4dd..88bc870c598b1 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1200,6 +1200,8 @@ def check_no_undef_outside_kconfig(self, kconf): "BOOT_DIRECT_XIP", # Used in sysbuild for MCUboot configuration "BOOT_DIRECT_XIP_REVERT", # Used in sysbuild for MCUboot configuration "BOOT_ENCRYPTION_KEY_FILE", # Used in sysbuild + "BOOT_ENCRYPT_ALG_AES_128", # Used in sysbuild + "BOOT_ENCRYPT_ALG_AES_256", # Used in sysbuild "BOOT_ENCRYPT_IMAGE", # Used in sysbuild "BOOT_FIRMWARE_LOADER", # Used in sysbuild for MCUboot configuration "BOOT_FIRMWARE_LOADER_BOOT_MODE", # Used in sysbuild for MCUboot configuration From 101add04bbb56a1f1e36f7cec612463ea7a3e399 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Wed, 27 Aug 2025 18:07:34 +0800 Subject: [PATCH 0244/1076] bluetooth: avdtp: fix the checking of rsp_handler rsp_handler should be used instead of cmd_handler Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/avdtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index e217570bfa2f6..144adcd0028c6 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -1320,7 +1320,7 @@ int bt_avdtp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) } if (sigid != 0U && sigid <= BT_AVDTP_DELAYREPORT && - cmd_handler[sigid - 1U] != NULL) { + rsp_handler[sigid - 1U] != NULL) { rsp_handler[sigid - 1U](session, buf, msgtype); return 0; } From aad41f8d669caf93efb28745ef4a628fa884d92e Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 29 Jul 2025 13:56:30 -0500 Subject: [PATCH 0245/1076] phy: ksz8081: Minor refactor of init gpio code Minor refactor to remove the #ifdefs inline in init function. Signed-off-by: Declan Snyder --- drivers/ethernet/phy/phy_microchip_ksz8081.c | 52 +++++++++++++------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 71c799777bb10..1d0920ddf57b6 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -443,6 +443,37 @@ static void phy_mc_ksz8081_monitor_work_handler(struct k_work *work) k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); } +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) +static int ksz8081_init_int_gpios(const struct device *dev) +{ + const struct mc_ksz8081_config *config = dev->config; + + if (config->interrupt_gpio.port == NULL) { + return 0; + } + + /* Prevent NAND TREE mode */ + return gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_OUTPUT_ACTIVE); +} +#else +#define ksz8081_init_int_gpios(dev) 0 +#endif + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +static int ksz8081_init_reset_gpios(const struct device *dev) +{ + const struct mc_ksz8081_config *config = dev->config; + + if (config->reset_gpio.port == NULL) { + return 0; + } + + return gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); +} +#else +#define ksz8081_init_reset_gpios(dev) 0 +#endif + static int phy_mc_ksz8081_init(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; @@ -458,28 +489,15 @@ static int phy_mc_ksz8081_init(const struct device *dev) mdio_bus_enable(config->mdio_dev); -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) - if (!config->interrupt_gpio.port) { - goto skip_int_gpio; - } - - /* Prevent NAND TREE mode */ - ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_OUTPUT_ACTIVE); + ret = ksz8081_init_int_gpios(dev); if (ret) { return ret; } -skip_int_gpio: -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ - -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) - if (config->reset_gpio.port) { - ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); - if (ret) { - return ret; - } + ret = ksz8081_init_reset_gpios(dev); + if (ret) { + return ret; } -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ /* Reset PHY */ ret = phy_mc_ksz8081_reset(dev); From be8a0f3d1e4a9cab68252308cc2c2c4875049151 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 12 Aug 2025 14:59:30 -0500 Subject: [PATCH 0246/1076] drivers: phy_ksz8081: Improve logging Improve logging in the driver, using appropriate log levels. Signed-off-by: Declan Snyder --- drivers/ethernet/phy/phy_microchip_ksz8081.c | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 1d0920ddf57b6..0dfc4c8bba9fc 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -73,9 +73,12 @@ static int phy_mc_ksz8081_read(const struct device *dev, ret = mdio_read(config->mdio_dev, config->addr, reg_addr, (uint16_t *)data); if (ret) { + LOG_WRN("Failed to read from %s reg %d", dev->name, reg_addr); return ret; } + LOG_DBG("Read %x from phy %d reg %d", *data, config->addr, reg_addr); + return 0; } @@ -87,16 +90,19 @@ static int phy_mc_ksz8081_write(const struct device *dev, ret = mdio_write(config->mdio_dev, config->addr, reg_addr, (uint16_t)data); if (ret) { + LOG_WRN("Failed to write to %s reg %d", dev->name, reg_addr); return ret; } + LOG_DBG("Wrote %x to phy %d reg %d", data, config->addr, reg_addr); + return 0; } static int phy_mc_ksz8081_autonegotiate(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; - int ret; + int ret = 0, attempts = 0; uint32_t bmcr = 0; uint32_t bmsr = 0; uint16_t timeout = CONFIG_PHY_AUTONEG_TIMEOUT_MS / 100; @@ -122,7 +128,7 @@ static int phy_mc_ksz8081_autonegotiate(const struct device *dev) /* TODO change this to GPIO interrupt driven */ do { if (timeout-- == 0) { - LOG_DBG("PHY (%d) autonegotiation timed out", config->addr); + LOG_ERR("PHY (%d) autonegotiation timed out", config->addr); /* The value -ETIMEDOUT can be returned by PHY read/write functions, so * return -ENETDOWN instead to distinguish link timeout from PHY timeout. */ @@ -135,9 +141,11 @@ static int phy_mc_ksz8081_autonegotiate(const struct device *dev) LOG_ERR("Error reading phy (%d) basic status register", config->addr); return ret; } + + attempts++; } while (!(bmsr & MII_BMSR_AUTONEG_COMPLETE)); - LOG_DBG("PHY (%d) autonegotiation completed", config->addr); + LOG_DBG("PHY (%d) autonegotiation completed after %d checks", config->addr, attempts); return 0; } @@ -156,14 +164,13 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, /* Lock mutex */ ret = k_mutex_lock(&data->mutex, K_FOREVER); if (ret) { - LOG_ERR("PHY mutex lock error"); + LOG_ERR("PHY %d mutex lock error", config->addr); return ret; } /* Read link state */ ret = phy_mc_ksz8081_read(dev, MII_BMSR, &bmsr); if (ret) { - LOG_ERR("Error reading phy (%d) basic status register", config->addr); goto done; } state->is_up = bmsr & MII_BMSR_LINK_STATUS; @@ -175,14 +182,12 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, /* Read currently configured advertising options */ ret = phy_mc_ksz8081_read(dev, MII_ANAR, &anar); if (ret) { - LOG_ERR("Error reading phy (%d) advertising register", config->addr); goto done; } /* Read link partner capability */ ret = phy_mc_ksz8081_read(dev, MII_ANLPAR, &anlpar); if (ret) { - LOG_ERR("Error reading phy (%d) link partner register", config->addr); goto done; } @@ -211,6 +216,9 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, } done: + if (ret) { + LOG_ERR("Failed to get %s state", dev->name); + } k_mutex_unlock(&data->mutex); return ret; @@ -366,7 +374,6 @@ static int phy_mc_ksz8081_cfg_link(const struct device *dev, enum phy_link_speed ret = phy_mii_set_anar_reg(dev, speeds); if ((ret < 0) && (ret != -EALREADY)) { - LOG_ERR("Error setting ANAR register for phy (%d)", config->addr); goto done; } @@ -396,6 +403,9 @@ static int phy_mc_ksz8081_cfg_link(const struct device *dev, enum phy_link_speed } done: + if (ret) { + LOG_ERR("Failed to configure %s", dev->name); + } /* Unlock mutex */ k_mutex_unlock(&data->mutex); From 043ec3d9eeaf0b4d3d2b0963095d8e9668549f81 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 29 Jul 2025 14:28:26 -0500 Subject: [PATCH 0247/1076] drivers: phy_ksz8081: Fix boot and link up Two issues are being simultaneously address in this commit: Issue 1: Current issue is that zephyr boot / init is slow because it is blocked by the phy ksz8081 init doing autonegotiation which can take on the order of a few seconds. Fix by now doing autonegotiation in the monitor handler instead of in the cfg link call. The cfg link call will now only set the ANAR register and a software flag to let the monitor handler know whether or not to redo the autonegotiation sequence. Issue 2: The ksz8081 phy currently does not link up ever on cold boots on the NXP RT platforms due to regression on mainline. My understanding of why is not clear, but I found that re-setting the RMII override bit by the time the monitor work handler runs with the change to fix the first issue, makes the link come up. Signed-off-by: Declan Snyder --- drivers/ethernet/phy/phy_microchip_ksz8081.c | 154 ++++++++++++------- drivers/mdio/mdio_nxp_enet.c | 1 + 2 files changed, 100 insertions(+), 55 deletions(-) diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 0dfc4c8bba9fc..7083f1459876b 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -53,6 +53,10 @@ struct mc_ksz8081_config { #endif }; +/* arbitrarily defined internal driver flags */ +#define KSZ8081_DO_AUTONEG_FLAG 0x1 +#define KSZ8081_SILENCE_DEBUG_LOGS 0x2 + struct mc_ksz8081_data { const struct device *dev; struct phy_link_state state; @@ -60,12 +64,14 @@ struct mc_ksz8081_data { void *cb_data; struct k_mutex mutex; struct k_work_delayable phy_monitor_work; + uint8_t flags; }; static int phy_mc_ksz8081_read(const struct device *dev, uint16_t reg_addr, uint32_t *data) { const struct mc_ksz8081_config *config = dev->config; + struct mc_ksz8081_data *dev_data = dev->data; int ret; /* Make sure excessive bits 16-31 are reset */ @@ -73,11 +79,13 @@ static int phy_mc_ksz8081_read(const struct device *dev, ret = mdio_read(config->mdio_dev, config->addr, reg_addr, (uint16_t *)data); if (ret) { - LOG_WRN("Failed to read from %s reg %d", dev->name, reg_addr); + LOG_WRN("Failed to read from %s reg 0x%x", dev->name, reg_addr); return ret; } - LOG_DBG("Read %x from phy %d reg %d", *data, config->addr, reg_addr); + if (!(dev_data->flags & KSZ8081_SILENCE_DEBUG_LOGS)) { + LOG_DBG("Read 0x%x from phy %d reg 0x%x", *data, config->addr, reg_addr); + } return 0; } @@ -86,15 +94,18 @@ static int phy_mc_ksz8081_write(const struct device *dev, uint16_t reg_addr, uint32_t data) { const struct mc_ksz8081_config *config = dev->config; + struct mc_ksz8081_data *dev_data = dev->data; int ret; ret = mdio_write(config->mdio_dev, config->addr, reg_addr, (uint16_t)data); if (ret) { - LOG_WRN("Failed to write to %s reg %d", dev->name, reg_addr); + LOG_WRN("Failed to write to %s reg 0x%x", dev->name, reg_addr); return ret; } - LOG_DBG("Wrote %x to phy %d reg %d", data, config->addr, reg_addr); + if (!(dev_data->flags & KSZ8081_SILENCE_DEBUG_LOGS)) { + LOG_DBG("Wrote 0x%x to phy %d reg 0x%x", data, config->addr, reg_addr); + } return 0; } @@ -102,52 +113,72 @@ static int phy_mc_ksz8081_write(const struct device *dev, static int phy_mc_ksz8081_autonegotiate(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; + struct mc_ksz8081_data *data = dev->data; int ret = 0, attempts = 0; uint32_t bmcr = 0; - uint32_t bmsr = 0; + uint32_t bmsr = 0, last_bmsr = 0; uint16_t timeout = CONFIG_PHY_AUTONEG_TIMEOUT_MS / 100; + ret = k_mutex_lock(&data->mutex, K_FOREVER); + if (ret) { + LOG_ERR("PHY mutex lock error"); + goto done; + } + /* Read control register to write back with autonegotiation bit */ ret = phy_mc_ksz8081_read(dev, MII_BMCR, &bmcr); if (ret) { - LOG_ERR("Error reading phy (%d) basic control register", config->addr); - return ret; + goto done; } /* (re)start autonegotiation */ - LOG_DBG("PHY (%d) is entering autonegotiation sequence", config->addr); + LOG_INF("PHY (%d) is entering autonegotiation sequence", config->addr); bmcr |= MII_BMCR_AUTONEG_ENABLE | MII_BMCR_AUTONEG_RESTART; bmcr &= ~MII_BMCR_ISOLATE; ret = phy_mc_ksz8081_write(dev, MII_BMCR, bmcr); if (ret) { - LOG_ERR("Error writing phy (%d) basic control register", config->addr); - return ret; + goto done; } /* TODO change this to GPIO interrupt driven */ + data->flags |= KSZ8081_SILENCE_DEBUG_LOGS; do { if (timeout-- == 0) { LOG_ERR("PHY (%d) autonegotiation timed out", config->addr); /* The value -ETIMEDOUT can be returned by PHY read/write functions, so * return -ENETDOWN instead to distinguish link timeout from PHY timeout. */ - return -ENETDOWN; + ret = -ENETDOWN; + goto done; } k_msleep(100); ret = phy_mc_ksz8081_read(dev, MII_BMSR, &bmsr); if (ret) { - LOG_ERR("Error reading phy (%d) basic status register", config->addr); - return ret; + goto done; } + if (last_bmsr != bmsr) { + LOG_DBG("phy %d autoneg BMSR: %x", config->addr, bmsr); + } + + last_bmsr = bmsr; attempts++; } while (!(bmsr & MII_BMSR_AUTONEG_COMPLETE)); + data->flags &= ~KSZ8081_SILENCE_DEBUG_LOGS; LOG_DBG("PHY (%d) autonegotiation completed after %d checks", config->addr, attempts); - return 0; + data->flags &= ~KSZ8081_DO_AUTONEG_FLAG; + +done: + if (ret && ret != -ENETDOWN) { + LOG_ERR("Failed to configure %s for autonegotiation", dev->name); + } + /* Unlock mutex */ + k_mutex_unlock(&data->mutex); + return ret; } static int phy_mc_ksz8081_get_link(const struct device *dev, @@ -224,11 +255,6 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, return ret; } -/* - * Configuration set statically (DT) that should never change - * This function is needed in case the PHY is reset then the next call - * to configure the phy will ensure this configuration will be redone - */ static int phy_mc_ksz8081_static_cfg(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; @@ -275,7 +301,7 @@ static int phy_mc_ksz8081_static_cfg(const struct device *dev) } #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) -static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) +static int phy_mc_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) { int ret; @@ -301,7 +327,7 @@ static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) return ret; } #else -static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) +static int phy_mc_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) { ARG_UNUSED(config); @@ -322,7 +348,7 @@ static int phy_mc_ksz8081_reset(const struct device *dev) return ret; } - ret = phy_ksz8081_reset_gpio(config); + ret = phy_mc_ksz8081_reset_gpio(config); if (ret != -ENODEV) { /* On -ENODEV, attempt command-based reset */ goto done; } @@ -337,6 +363,11 @@ static int phy_mc_ksz8081_reset(const struct device *dev) */ k_busy_wait(500 * USEC_PER_MSEC); + /* After each reset we will apply the static cfg from DT */ + ret = phy_mc_ksz8081_static_cfg(dev); + if (ret) { + goto done; + } done: /* Unlock mutex */ k_mutex_unlock(&data->mutex); @@ -346,9 +377,7 @@ static int phy_mc_ksz8081_reset(const struct device *dev) static int phy_mc_ksz8081_cfg_link(const struct device *dev, enum phy_link_speed speeds, enum phy_cfg_link_flag flags) { - const struct mc_ksz8081_config *config = dev->config; struct mc_ksz8081_data *data = dev->data; - struct phy_link_state state = {}; int ret; if (flags & PHY_FLAG_AUTO_NEGOTIATION_DISABLED) { @@ -360,12 +389,9 @@ static int phy_mc_ksz8081_cfg_link(const struct device *dev, enum phy_link_speed ret = k_mutex_lock(&data->mutex, K_FOREVER); if (ret) { LOG_ERR("PHY mutex lock error"); - goto done; + return ret; } - /* We are going to reconfigure the phy, don't need to monitor until done */ - k_work_cancel_delayable(&data->phy_monitor_work); - /* DT configurations */ ret = phy_mc_ksz8081_static_cfg(dev); if (ret) { @@ -373,35 +399,14 @@ static int phy_mc_ksz8081_cfg_link(const struct device *dev, enum phy_link_speed } ret = phy_mii_set_anar_reg(dev, speeds); - if ((ret < 0) && (ret != -EALREADY)) { - goto done; + if (ret == -EALREADY) { + ret = 0; } - - /* (re)do autonegotiation */ - ret = phy_mc_ksz8081_autonegotiate(dev); - if (ret && (ret != -ENETDOWN)) { - LOG_ERR("Error in autonegotiation"); + if (ret < 0) { goto done; } - /* Get link status */ - ret = phy_mc_ksz8081_get_link(dev, &state); - - if (ret == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) { - memcpy(&data->state, &state, sizeof(struct phy_link_state)); - if (data->cb) { - data->cb(dev, &data->state, data->cb_data); - } - } - - /* Log the results of the configuration */ - LOG_INF("PHY %d is %s", config->addr, data->state.is_up ? "up" : "down"); - if (data->state.is_up) { - LOG_INF("PHY (%d) Link speed %s Mb, %s duplex\n", config->addr, - (PHY_LINK_IS_SPEED_100M(data->state.speed) ? "100" : "10"), - PHY_LINK_IS_FULL_DUPLEX(data->state.speed) ? "full" : "half"); - } - + data->flags |= KSZ8081_DO_AUTONEG_FLAG; done: if (ret) { LOG_ERR("Failed to configure %s", dev->name); @@ -437,16 +442,49 @@ static void phy_mc_ksz8081_monitor_work_handler(struct k_work *work) struct mc_ksz8081_data *data = CONTAINER_OF(dwork, struct mc_ksz8081_data, phy_monitor_work); const struct device *dev = data->dev; + const struct mc_ksz8081_config *config = dev->config; struct phy_link_state state = {}; - int rc; + bool turn_on_logs = false; + int rc = 0; - rc = phy_mc_ksz8081_get_link(dev, &state); + if (!data->state.is_up) { + /* some overrides might need set on cold reset way late for some reason */ + phy_mc_ksz8081_static_cfg(dev); + } + + /* (re)do autonegotiation if needed */ + if (data->flags & KSZ8081_DO_AUTONEG_FLAG) { + rc = phy_mc_ksz8081_autonegotiate(dev); + } + if (rc && (rc != -ENETDOWN)) { + LOG_ERR("Error in %s autonegotiation", dev->name); + data->flags &= ~KSZ8081_SILENCE_DEBUG_LOGS; /* get logs next time */ + turn_on_logs = true; + } + rc = phy_mc_ksz8081_get_link(dev, &state); + if (!turn_on_logs) { + turn_on_logs = (rc != 0); + } if (rc == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) { memcpy(&data->state, &state, sizeof(struct phy_link_state)); if (data->cb) { data->cb(dev, &data->state, data->cb_data); } + LOG_INF("PHY %d is %s", config->addr, data->state.is_up ? "up" : "down"); + if (data->state.is_up) { + LOG_INF("PHY (%d) Link speed %s Mb, %s duplex\n", config->addr, + (PHY_LINK_IS_SPEED_100M(data->state.speed) ? "100" : "10"), + PHY_LINK_IS_FULL_DUPLEX(data->state.speed) ? "full" : "half"); + } + } + + if (turn_on_logs) { + /* something wrong, if it happens again, we'll get logs next time */ + data->flags &= ~KSZ8081_SILENCE_DEBUG_LOGS; + } else { + /* everything is fine, don't need to spam annoying register logs */ + data->flags |= KSZ8081_SILENCE_DEBUG_LOGS; } /* TODO change this to GPIO interrupt driven */ @@ -492,12 +530,15 @@ static int phy_mc_ksz8081_init(const struct device *dev) data->dev = dev; + k_busy_wait(100000); + ret = k_mutex_init(&data->mutex); if (ret) { return ret; } mdio_bus_enable(config->mdio_dev); + k_busy_wait(100000); ret = ksz8081_init_int_gpios(dev); if (ret) { @@ -508,6 +549,7 @@ static int phy_mc_ksz8081_init(const struct device *dev) if (ret) { return ret; } + k_busy_wait(100000); /* Reset PHY */ ret = phy_mc_ksz8081_reset(dev); @@ -515,10 +557,12 @@ static int phy_mc_ksz8081_init(const struct device *dev) return ret; } + k_busy_wait(100000); k_work_init_delayable(&data->phy_monitor_work, phy_mc_ksz8081_monitor_work_handler); /* Advertise default speeds */ + k_busy_wait(100000); phy_mc_ksz8081_cfg_link(dev, config->default_speeds, 0); return 0; diff --git a/drivers/mdio/mdio_nxp_enet.c b/drivers/mdio/mdio_nxp_enet.c index d71e3640cd434..b79e3e1502b86 100644 --- a/drivers/mdio/mdio_nxp_enet.c +++ b/drivers/mdio/mdio_nxp_enet.c @@ -216,6 +216,7 @@ static int nxp_enet_mdio_init(const struct device *dev) data->base = (ENET_Type *)DEVICE_MMIO_GET(config->module_dev); + k_busy_wait(100000); ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); if (ret) { return ret; From 02b99470a3903c8ea34c65fb1410092374fa821b Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Wed, 27 Aug 2025 12:03:32 -0500 Subject: [PATCH 0248/1076] drivers: ethernet: ksz8081: Save link state for get Instead of using mdio bus for getting link state, only get it in the monitor and save it off for get rate api implementation to use Signed-off-by: Declan Snyder --- drivers/ethernet/phy/phy_microchip_ksz8081.c | 27 +++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 7083f1459876b..5c27b935f473b 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -56,6 +56,7 @@ struct mc_ksz8081_config { /* arbitrarily defined internal driver flags */ #define KSZ8081_DO_AUTONEG_FLAG 0x1 #define KSZ8081_SILENCE_DEBUG_LOGS 0x2 +#define KSZ8081_LINK_STATE_VALID 0x3 struct mc_ksz8081_data { const struct device *dev; @@ -181,11 +182,28 @@ static int phy_mc_ksz8081_autonegotiate(const struct device *dev) return ret; } + static int phy_mc_ksz8081_get_link(const struct device *dev, struct phy_link_state *state) +{ + struct mc_ksz8081_data *data = dev->data; + struct phy_link_state *link_state = &data->state; + + if ((data->flags & KSZ8081_LINK_STATE_VALID) != KSZ8081_LINK_STATE_VALID) { + return -EIO; + } + + state->speed = link_state->speed; + state->is_up = link_state->is_up; + + return 0; +} + +static int phy_mc_ksz8081_update_link(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; struct mc_ksz8081_data *data = dev->data; + struct phy_link_state *state = &data->state; int ret; uint32_t bmsr = 0; uint32_t anar = 0; @@ -443,7 +461,7 @@ static void phy_mc_ksz8081_monitor_work_handler(struct k_work *work) CONTAINER_OF(dwork, struct mc_ksz8081_data, phy_monitor_work); const struct device *dev = data->dev; const struct mc_ksz8081_config *config = dev->config; - struct phy_link_state state = {}; + struct phy_link_state state = data->state; bool turn_on_logs = false; int rc = 0; @@ -462,12 +480,15 @@ static void phy_mc_ksz8081_monitor_work_handler(struct k_work *work) turn_on_logs = true; } - rc = phy_mc_ksz8081_get_link(dev, &state); + data->flags &= ~KSZ8081_LINK_STATE_VALID; + rc = phy_mc_ksz8081_update_link(dev); + if (rc == 0) { + data->flags |= KSZ8081_LINK_STATE_VALID; + } if (!turn_on_logs) { turn_on_logs = (rc != 0); } if (rc == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) { - memcpy(&data->state, &state, sizeof(struct phy_link_state)); if (data->cb) { data->cb(dev, &data->state, data->cb_data); } From 26888c8fcc3110d5a5428ff1eb9049cb104f54d3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 21 Jul 2025 13:25:01 +0200 Subject: [PATCH 0249/1076] modem: modules: remove EXPERIMENTAL Remove the EXPERIMENTAL label from the MODEM_MODULES and update API version to 1.0.0. These modules are fully tested and widely used, and have been present for 2 years. Signed-off-by: Bjarki Arge Andreasen --- doc/_doxygen/groups.dox | 2 +- subsys/modem/Kconfig | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/_doxygen/groups.dox b/doc/_doxygen/groups.dox index 603791b3fd468..13eebaa9f25f3 100644 --- a/doc/_doxygen/groups.dox +++ b/doc/_doxygen/groups.dox @@ -85,7 +85,7 @@ @defgroup modem Modem APIs @ingroup connectivity @since 3.5 -@version 0.1.0 +@version 1.0.0 @{ @} diff --git a/subsys/modem/Kconfig b/subsys/modem/Kconfig index c4f4c0cd8982c..b7c3f7ba9014c 100644 --- a/subsys/modem/Kconfig +++ b/subsys/modem/Kconfig @@ -3,7 +3,6 @@ menuconfig MODEM_MODULES bool "Modem modules" - select EXPERIMENTAL if MODEM_MODULES From db8274a5f9a0c363060e730d12dd280fe4b54108 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 21 Jul 2025 14:33:02 +0200 Subject: [PATCH 0250/1076] modem: add versions to all headers Versions for specific modem modules don't include versions in their headers, and the chat module did not even define a group. This commits updates most modem modules to include versions in their headers. Specifically, the following modules have their versions set to 1.0.0, as these should no longer be marked experimental: - modem_chat - modem_cmux - modem_pipe - modem_pipelink - modem_ppp - modem_ubx Though the modem_ubx was recently refactored, it is tested in CI and is implemented by two drivers, and has been present since release 3.7, so it is not marked as experimental. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/chat.h | 13 +++++++++++++ include/zephyr/modem/cmux.h | 2 ++ include/zephyr/modem/pipe.h | 2 ++ include/zephyr/modem/pipelink.h | 2 ++ include/zephyr/modem/ppp.h | 2 ++ include/zephyr/modem/ubx.h | 2 ++ 6 files changed, 23 insertions(+) diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index 0836451d689d4..db7be17981f12 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -19,6 +19,15 @@ extern "C" { #endif +/** + * @brief Modem Chat + * @defgroup modem_chat Modem Chat + * @since 3.5 + * @version 1.0.0 + * @ingroup modem + * @{ + */ + struct modem_chat; /** @@ -520,6 +529,10 @@ void modem_chat_script_set_callback(struct modem_chat_script *script, */ void modem_chat_script_set_timeout(struct modem_chat_script *script, uint32_t timeout_s); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/modem/cmux.h b/include/zephyr/modem/cmux.h index f1fa0beec32a5..3332c40bd18eb 100644 --- a/include/zephyr/modem/cmux.h +++ b/include/zephyr/modem/cmux.h @@ -37,6 +37,8 @@ extern "C" { /** * @brief Modem CMUX * @defgroup modem_cmux Modem CMUX + * @since 3.5 + * @version 1.0.0 * @ingroup modem * @{ */ diff --git a/include/zephyr/modem/pipe.h b/include/zephyr/modem/pipe.h index b91dfb505a4cb..5e95d1f809f7f 100644 --- a/include/zephyr/modem/pipe.h +++ b/include/zephyr/modem/pipe.h @@ -17,6 +17,8 @@ extern "C" { /** * @brief Modem Pipe * @defgroup modem_pipe Modem Pipe + * @since 3.5 + * @version 1.0.0 * @ingroup modem * @{ */ diff --git a/include/zephyr/modem/pipelink.h b/include/zephyr/modem/pipelink.h index ca788aaeefb7c..5cacd362e8f71 100644 --- a/include/zephyr/modem/pipelink.h +++ b/include/zephyr/modem/pipelink.h @@ -18,6 +18,8 @@ extern "C" { /** * @brief Modem pipelink * @defgroup modem_pipelink Modem pipelink + * @since 3.7 + * @version 1.0.0 * @ingroup modem * @{ */ diff --git a/include/zephyr/modem/ppp.h b/include/zephyr/modem/ppp.h index 799aac60b0b13..2b91e51a35c99 100644 --- a/include/zephyr/modem/ppp.h +++ b/include/zephyr/modem/ppp.h @@ -24,6 +24,8 @@ extern "C" { /** * @brief Modem PPP * @defgroup modem_ppp Modem PPP + * @since 3.5 + * @version 1.0.0 * @ingroup modem * @{ */ diff --git a/include/zephyr/modem/ubx.h b/include/zephyr/modem/ubx.h index fd4b05cea7475..2ad047a47bfa4 100644 --- a/include/zephyr/modem/ubx.h +++ b/include/zephyr/modem/ubx.h @@ -23,6 +23,8 @@ extern "C" { /** * @brief Modem Ubx * @defgroup modem_ubx Modem Ubx + * @since 3.7 + * @version 1.0.0 * @ingroup modem * @{ */ From 806c3441460bc904e4bf96747c36422f230b0af6 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 5 Aug 2025 15:49:47 +0300 Subject: [PATCH 0251/1076] secure_storage: make UIDs 32-bit Make the storage UID type 32-bit long. This makes it more convenient to use those UIDs as storage entry IDs when storing the entries to NVM. The previous 64+ bits UIDs made it incovenient to use them as such. As Zephyr defines UID ranges to be used (see e.g. `zephyr/psa/key_ids.h`), this guarantees that all the UIDs will fit within the 30 bits reserved for them. The secure storage ITS implementation API is changed to take `psa_storage_uid_t` separately so the implementation can check that no forbidden bits are set before they are packed into `secure_storage_its_uid_t`. This change breaks backward compatibility because `secure_storage_its_uid_t`, which is used both as part of the additional data for authentication and for generating encryption keys, changes size from 12 to 4 bytes. For users wanting to preserve backward compatibility (for example when upgrading an existing installation to a newer Zephyr release) or that for some reason want to use a 64-bit `psa_storage_uid_t`, the Kconfig option CONFIG_SECURE_STORAGE_64_BIT_UID is added. When enabled, it makes the implementation behave the same as previously and compatibility with existing entries is preserved. This was tested manually. Fixes zephyrproject-rtos/zephyr#86177. Signed-off-by: Tomi Fontanilles --- subsys/secure_storage/Kconfig | 11 +++ subsys/secure_storage/Kconfig.its_store | 7 +- .../internal/zephyr/secure_storage/its.h | 17 ++-- .../zephyr/secure_storage/its/common.h | 23 ++++- .../include/psa/internal_trusted_storage.h | 10 +- .../include/psa/protected_storage.h | 12 +-- .../include/psa/storage_common.h | 4 + .../secure_storage/src/its/implementation.c | 94 ++++++++++++++----- subsys/secure_storage/src/its/store/zms.c | 30 ++---- 9 files changed, 139 insertions(+), 69 deletions(-) diff --git a/subsys/secure_storage/Kconfig b/subsys/secure_storage/Kconfig index 3fe8eb0f76a79..b0ac8c08a14c9 100644 --- a/subsys/secure_storage/Kconfig +++ b/subsys/secure_storage/Kconfig @@ -25,6 +25,17 @@ module = SECURE_STORAGE module-str = secure_storage source "subsys/logging/Kconfig.template.log_config" +config SECURE_STORAGE_64_BIT_UID + bool "Make psa_storage_uid_t 64-bit" + help + Zephyr, by default, uses a 30-bit psa_storage_uid_t, which allows using only 32 bits to + identify entries. + UID ranges are defined for the different users of the API which guarantees that all the + UIDs fit within 30 bits. See for example the zephyr/psa/key_ids.h header file. + Enable this for backward compatibility if you are updating an existing installation with + stored entries that was using Zephyr prior to 4.3 or if for some reason you need the full + 64-bit UID range. + choice SECURE_STORAGE_ITS_IMPLEMENTATION prompt "Internal Trusted Storage (ITS) API implementation" diff --git a/subsys/secure_storage/Kconfig.its_store b/subsys/secure_storage/Kconfig.its_store index ccd15b968a7ca..c924def563fa1 100644 --- a/subsys/secure_storage/Kconfig.its_store +++ b/subsys/secure_storage/Kconfig.its_store @@ -17,7 +17,7 @@ config SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_ZMS depends on ZMS help This implementation of the ITS store module makes direct use of ZMS for storage. - It needs a `secure_storage_its_partition` devicetree chosen property that points + It needs a secure_storage_its_partition devicetree chosen property that points to a fixed storage partition that will be dedicated to the ITS. It has lower overhead compared to the settings-based implementation, both in terms of runtime execution and storage space, and also ROM footprint if the settings subsystem is disabled. @@ -78,7 +78,8 @@ config SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX config SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_MAX_LEN int "Maximum setting name length" range 2 64 - default 22 if !SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_CUSTOM - default 0 + default 0 if SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_CUSTOM + default 22 if SECURE_STORAGE_64_BIT_UID + default 14 endif # SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_SETTINGS diff --git a/subsys/secure_storage/include/internal/zephyr/secure_storage/its.h b/subsys/secure_storage/include/internal/zephyr/secure_storage/its.h index 009bb5e061af7..c19dd7be7b63e 100644 --- a/subsys/secure_storage/include/internal/zephyr/secure_storage/its.h +++ b/subsys/secure_storage/include/internal/zephyr/secure_storage/its.h @@ -14,18 +14,21 @@ #include "its/common.h" /** @brief See `psa_its_set()`, to which this function is analogous. */ -psa_status_t secure_storage_its_set(secure_storage_its_uid_t uid, size_t data_length, - const void *p_data, psa_storage_create_flags_t create_flags); +psa_status_t secure_storage_its_set(secure_storage_its_caller_id_t caller_id, psa_storage_uid_t uid, + size_t data_length, const void *p_data, + psa_storage_create_flags_t create_flags); /** @brief See `psa_its_get()`, to which this function is analogous. */ -psa_status_t secure_storage_its_get(secure_storage_its_uid_t uid, size_t data_offset, - size_t data_size, void *p_data, size_t *p_data_length); +psa_status_t secure_storage_its_get(secure_storage_its_caller_id_t caller_id, psa_storage_uid_t uid, + size_t data_offset, size_t data_size, + void *p_data, size_t *p_data_length); /** @brief See `psa_its_get_info()`, to which this function is analogous. */ -psa_status_t secure_storage_its_get_info(secure_storage_its_uid_t uid, - struct psa_storage_info_t *p_info); +psa_status_t secure_storage_its_get_info(secure_storage_its_caller_id_t caller_id, + psa_storage_uid_t uid, struct psa_storage_info_t *p_info); /** @brief See `psa_its_remove()`, to which this function is analogous. */ -psa_status_t secure_storage_its_remove(secure_storage_its_uid_t uid); +psa_status_t secure_storage_its_remove(secure_storage_its_caller_id_t caller_id, + psa_storage_uid_t uid); #endif diff --git a/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h b/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h index cd953086950a0..f0576cba185f1 100644 --- a/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h +++ b/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h @@ -12,8 +12,7 @@ #include /** @brief The ID of the caller from which the ITS API call originates. - * This is used to prevent ID collisions between different callers that are not aware - * of each other and so might use the same numerical IDs, e.g. PSA Crypto and PSA ITS. + * This is used to namespace the different callers and possibly treat them differently. */ typedef enum { SECURE_STORAGE_ITS_CALLER_PSA_ITS, @@ -22,12 +21,32 @@ typedef enum { SECURE_STORAGE_ITS_CALLER_COUNT } secure_storage_its_caller_id_t; +#ifdef CONFIG_SECURE_STORAGE_64_BIT_UID + /** The UID (caller + entry IDs) of an ITS entry. */ typedef struct { psa_storage_uid_t uid; secure_storage_its_caller_id_t caller_id; } __packed secure_storage_its_uid_t; +#else + +#define SECURE_STORAGE_ITS_UID_BIT_SIZE 30 +#define SECURE_STORAGE_ITS_CALLER_ID_BIT_SIZE 2 + +/** @brief The UID (caller + entry IDs) of an ITS entry. + * This is a packed, 32-bit version of `psa_storage_uid_t` which allows storing + * smaller IDs compared to the 64-bit ones that PSA Secure Storage specifies. + * Zephyr defines ranges of IDs to be used by different users of the API (subsystems, application) + * which guarantees 1. no collisions and 2. that the IDs used fit within `uid`. + */ +typedef struct { + psa_storage_uid_t uid : SECURE_STORAGE_ITS_UID_BIT_SIZE; + secure_storage_its_caller_id_t caller_id : SECURE_STORAGE_ITS_CALLER_ID_BIT_SIZE; +} secure_storage_its_uid_t; + +#endif /* CONFIG_SECURE_STORAGE_64_BIT_UID */ + #ifdef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_MODULE /** The maximum size, in bytes, of an entry's data after it has been transformed for storage. */ diff --git a/subsys/secure_storage/include/psa/internal_trusted_storage.h b/subsys/secure_storage/include/psa/internal_trusted_storage.h index a8c3b77c601a0..06a09e34988b9 100644 --- a/subsys/secure_storage/include/psa/internal_trusted_storage.h +++ b/subsys/secure_storage/include/psa/internal_trusted_storage.h @@ -16,7 +16,6 @@ #else #define ITS_CALLER_ID SECURE_STORAGE_ITS_CALLER_PSA_ITS #endif -#define ITS_UID (secure_storage_its_uid_t){.uid = uid, .caller_id = ITS_CALLER_ID} /** @endcond */ #include @@ -50,7 +49,7 @@ static ALWAYS_INLINE psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags) { - return secure_storage_its_set(ITS_UID, data_length, p_data, create_flags); + return secure_storage_its_set(ITS_CALLER_ID, uid, data_length, p_data, create_flags); } /** @@ -76,7 +75,8 @@ static ALWAYS_INLINE psa_status_t psa_its_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size, void *p_data, size_t *p_data_length) { - return secure_storage_its_get(ITS_UID, data_offset, data_size, p_data, p_data_length); + return secure_storage_its_get(ITS_CALLER_ID, uid, data_offset, + data_size, p_data, p_data_length); } /** @@ -96,7 +96,7 @@ static ALWAYS_INLINE /** @endcond */ psa_status_t psa_its_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info) { - return secure_storage_its_get_info(ITS_UID, p_info); + return secure_storage_its_get_info(ITS_CALLER_ID, uid, p_info); } /** @@ -117,7 +117,7 @@ static ALWAYS_INLINE /** @endcond */ psa_status_t psa_its_remove(psa_storage_uid_t uid) { - return secure_storage_its_remove(ITS_UID); + return secure_storage_its_remove(ITS_CALLER_ID, uid); } #undef ITS_UID diff --git a/subsys/secure_storage/include/psa/protected_storage.h b/subsys/secure_storage/include/psa/protected_storage.h index 7c20d3097a2ad..40d731b042544 100644 --- a/subsys/secure_storage/include/psa/protected_storage.h +++ b/subsys/secure_storage/include/psa/protected_storage.h @@ -12,8 +12,7 @@ /** @cond INTERNAL_HIDDEN */ #ifdef CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_ITS #include "../internal/zephyr/secure_storage/its.h" -#define ITS_UID (secure_storage_its_uid_t){.uid = uid, \ - .caller_id = SECURE_STORAGE_ITS_CALLER_PSA_PS} +#define ITS_CALLER_ID SECURE_STORAGE_ITS_CALLER_PSA_PS #else #include "../internal/zephyr/secure_storage/ps.h" #endif @@ -50,7 +49,7 @@ psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags) { #ifdef CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_ITS - return secure_storage_its_set(ITS_UID, data_length, p_data, create_flags); + return secure_storage_its_set(ITS_CALLER_ID, uid, data_length, p_data, create_flags); #else return secure_storage_ps_set(uid, data_length, p_data, create_flags); #endif @@ -83,7 +82,8 @@ psa_status_t psa_ps_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size, void *p_data, size_t *p_data_length) { #ifdef CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_ITS - return secure_storage_its_get(ITS_UID, data_offset, data_size, p_data, p_data_length); + return secure_storage_its_get(ITS_CALLER_ID, uid, data_offset, + data_size, p_data, p_data_length); #else return secure_storage_ps_get(uid, data_offset, data_size, p_data, p_data_length); #endif @@ -110,7 +110,7 @@ static ALWAYS_INLINE psa_status_t psa_ps_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info) { #ifdef CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_ITS - return secure_storage_its_get_info(ITS_UID, p_info); + return secure_storage_its_get_info(ITS_CALLER_ID, uid, p_info); #else return secure_storage_ps_get_info(uid, p_info); #endif @@ -138,7 +138,7 @@ static ALWAYS_INLINE psa_status_t psa_ps_remove(psa_storage_uid_t uid) { #ifdef CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_ITS - return secure_storage_its_remove(ITS_UID); + return secure_storage_its_remove(ITS_CALLER_ID, uid); #else return secure_storage_ps_remove(uid); #endif diff --git a/subsys/secure_storage/include/psa/storage_common.h b/subsys/secure_storage/include/psa/storage_common.h index d5bed2a692e70..2bd0f7cce7327 100644 --- a/subsys/secure_storage/include/psa/storage_common.h +++ b/subsys/secure_storage/include/psa/storage_common.h @@ -20,7 +20,11 @@ #include /** UID type for identifying entries. */ +#ifdef CONFIG_SECURE_STORAGE_64_BIT_UID typedef uint64_t psa_storage_uid_t; +#else +typedef uint32_t psa_storage_uid_t; +#endif /** Flags used when creating an entry. */ typedef uint32_t psa_storage_create_flags_t; diff --git a/subsys/secure_storage/src/its/implementation.c b/subsys/secure_storage/src/its/implementation.c index 2ad937d45d27b..b39fbf90b002e 100644 --- a/subsys/secure_storage/src/its/implementation.c +++ b/subsys/secure_storage/src/its/implementation.c @@ -11,6 +11,33 @@ LOG_MODULE_DECLARE(secure_storage, CONFIG_SECURE_STORAGE_LOG_LEVEL); +#ifndef CONFIG_SECURE_STORAGE_64_BIT_UID +BUILD_ASSERT(sizeof(secure_storage_its_uid_t) == 4); /* ITS UIDs are 32-bit */ +BUILD_ASSERT(1 << SECURE_STORAGE_ITS_CALLER_ID_BIT_SIZE >= SECURE_STORAGE_ITS_CALLER_COUNT); +BUILD_ASSERT(SECURE_STORAGE_ITS_CALLER_ID_BIT_SIZE + SECURE_STORAGE_ITS_UID_BIT_SIZE == 32); +#endif + +static psa_status_t make_its_uid(secure_storage_its_caller_id_t caller_id, psa_storage_uid_t uid, + secure_storage_its_uid_t *its_uid) +{ + if (uid == 0) { + return PSA_ERROR_INVALID_ARGUMENT; + } + +#ifndef CONFIG_SECURE_STORAGE_64_BIT_UID + /* Check that the UID is not bigger than the maximum defined size. */ + if (uid & GENMASK64(63, SECURE_STORAGE_ITS_UID_BIT_SIZE)) { + LOG_DBG("UID %u/0x%llx cannot be used as it has bits set past " + "the first " STRINGIFY(SECURE_STORAGE_ITS_UID_BIT_SIZE) " ones.", + caller_id, (unsigned long long)uid); + return PSA_ERROR_INVALID_ARGUMENT; + } +#endif /* !CONFIG_SECURE_STORAGE_64_BIT_UID */ + + *its_uid = (secure_storage_its_uid_t){.caller_id = caller_id, .uid = uid}; + return PSA_SUCCESS; +} + static void log_failed_operation(const char *operation, const char *preposition, psa_status_t ret) { LOG_ERR("Failed to %s data %s storage. (%d)", operation, preposition, ret); @@ -117,12 +144,17 @@ static psa_status_t store_entry(secure_storage_its_uid_t uid, size_t data_length return ret; } -psa_status_t secure_storage_its_set(secure_storage_its_uid_t uid, size_t data_length, - const void *p_data, psa_storage_create_flags_t create_flags) +psa_status_t secure_storage_its_set(secure_storage_its_caller_id_t caller_id, psa_storage_uid_t uid, + size_t data_length, const void *p_data, + psa_storage_create_flags_t create_flags) { psa_status_t ret; + secure_storage_its_uid_t its_uid; - if (uid.uid == 0 || (p_data == NULL && data_length != 0)) { + if (make_its_uid(caller_id, uid, &its_uid) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (p_data == NULL && data_length != 0) { return PSA_ERROR_INVALID_ARGUMENT; } if (create_flags & ~SECURE_STORAGE_ALL_CREATE_FLAGS) { @@ -134,43 +166,49 @@ psa_status_t secure_storage_its_set(secure_storage_its_uid_t uid, size_t data_le return PSA_ERROR_INSUFFICIENT_STORAGE; } - if (keep_stored_entry(uid, data_length, p_data, create_flags, &ret)) { + if (keep_stored_entry(its_uid, data_length, p_data, create_flags, &ret)) { return ret; } - ret = store_entry(uid, data_length, p_data, create_flags); + ret = store_entry(its_uid, data_length, p_data, create_flags); return ret; } - -psa_status_t secure_storage_its_get(secure_storage_its_uid_t uid, size_t data_offset, - size_t data_size, void *p_data, size_t *p_data_length) +psa_status_t secure_storage_its_get(secure_storage_its_caller_id_t caller_id, psa_storage_uid_t uid, + size_t data_offset, size_t data_size, + void *p_data, size_t *p_data_length) { - if (uid.uid == 0 || (p_data == NULL && data_size != 0) || p_data_length == NULL) { + psa_status_t ret; + secure_storage_its_uid_t its_uid; + uint8_t stored_data[SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE]; + size_t stored_data_len; + psa_storage_create_flags_t create_flags; + + if (make_its_uid(caller_id, uid, &its_uid) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if ((p_data == NULL && data_size != 0) || p_data_length == NULL) { return PSA_ERROR_INVALID_ARGUMENT; } if (data_size == 0) { *p_data_length = 0; return PSA_SUCCESS; } - psa_status_t ret; - uint8_t stored_data[SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE]; - size_t stored_data_len; - psa_storage_create_flags_t create_flags; - ret = get_stored_data(uid, stored_data, &stored_data_len); + + ret = get_stored_data(its_uid, stored_data, &stored_data_len); if (ret != PSA_SUCCESS) { return ret; } if (data_offset == 0 && data_size >= SECURE_STORAGE_ITS_TRANSFORM_DATA_SIZE(stored_data_len)) { /* All the data fits directly in the provided buffer. */ - return transform_stored_data(uid, stored_data_len, stored_data, data_size, p_data, - p_data_length, &create_flags); + return transform_stored_data(its_uid, stored_data_len, stored_data, data_size, + p_data, p_data_length, &create_flags); } uint8_t data[CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE]; size_t data_len; - ret = transform_stored_data(uid, stored_data_len, stored_data, sizeof(data), data, + ret = transform_stored_data(its_uid, stored_data_len, stored_data, sizeof(data), data, &data_len, &create_flags); if (ret == PSA_SUCCESS) { if (data_offset > data_len) { @@ -184,41 +222,47 @@ psa_status_t secure_storage_its_get(secure_storage_its_uid_t uid, size_t data_of return ret; } -psa_status_t secure_storage_its_get_info(secure_storage_its_uid_t uid, - struct psa_storage_info_t *p_info) +psa_status_t secure_storage_its_get_info(secure_storage_its_caller_id_t caller_id, + psa_storage_uid_t uid, struct psa_storage_info_t *p_info) { psa_status_t ret; + secure_storage_its_uid_t its_uid; uint8_t data[CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE]; - if (uid.uid == 0 || p_info == NULL) { + if (make_its_uid(caller_id, uid, &its_uid) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (p_info == NULL) { return PSA_ERROR_INVALID_ARGUMENT; } - ret = get_entry(uid, sizeof(data), data, &p_info->size, &p_info->flags); + ret = get_entry(its_uid, sizeof(data), data, &p_info->size, &p_info->flags); if (ret == PSA_SUCCESS) { p_info->capacity = p_info->size; } return ret; } -psa_status_t secure_storage_its_remove(secure_storage_its_uid_t uid) +psa_status_t secure_storage_its_remove(secure_storage_its_caller_id_t caller_id, + psa_storage_uid_t uid) { psa_status_t ret; + secure_storage_its_uid_t its_uid; psa_storage_create_flags_t create_flags; uint8_t data[CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE]; size_t data_len; - if (uid.uid == 0) { + if (make_its_uid(caller_id, uid, &its_uid) != PSA_SUCCESS) { return PSA_ERROR_INVALID_ARGUMENT; } - ret = get_entry(uid, sizeof(data), data, &data_len, &create_flags); + ret = get_entry(its_uid, sizeof(data), data, &data_len, &create_flags); if (ret == PSA_SUCCESS && (create_flags & PSA_STORAGE_FLAG_WRITE_ONCE)) { return PSA_ERROR_NOT_PERMITTED; } /* Allow overwriting corrupted entries as well to not be stuck with them forever. */ if (ret == PSA_SUCCESS || ret == PSA_ERROR_STORAGE_FAILURE) { - ret = secure_storage_its_store_remove(uid); + ret = secure_storage_its_store_remove(its_uid); if (ret != PSA_SUCCESS) { log_failed_operation("remove", "from", ret); return PSA_ERROR_STORAGE_FAILURE; diff --git a/subsys/secure_storage/src/its/store/zms.c b/subsys/secure_storage/src/its/store/zms.c index ede296952ab5d..3a3bdd64c7623 100644 --- a/subsys/secure_storage/src/its/store/zms.c +++ b/subsys/secure_storage/src/its/store/zms.c @@ -33,26 +33,26 @@ static int init_zms(void) } SYS_INIT(init_zms, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); +#ifdef CONFIG_SECURE_STORAGE_64_BIT_UID + /* Bit position of the ITS caller ID in the ZMS entry ID. */ #define ITS_CALLER_ID_POS 30 /* Make sure that every ITS caller ID fits in ZMS entry IDs at the defined position. */ BUILD_ASSERT(1 << (32 - ITS_CALLER_ID_POS) >= SECURE_STORAGE_ITS_CALLER_COUNT); -static bool has_forbidden_bits_set(secure_storage_its_uid_t uid) +static uint32_t zms_id_from(secure_storage_its_uid_t uid) { - if (uid.uid & GENMASK64(63, ITS_CALLER_ID_POS)) { - LOG_DBG("UID %u/0x%llx cannot be used as it has bits set past " - "the first " STRINGIFY(ITS_CALLER_ID_POS) " ones.", - uid.caller_id, (unsigned long long)uid.uid); - return true; - } - return false; + __ASSERT_NO_MSG(!(uid.uid & GENMASK64(63, ITS_CALLER_ID_POS))); + return (uint32_t)uid.uid | (uid.caller_id << ITS_CALLER_ID_POS); } +#else static uint32_t zms_id_from(secure_storage_its_uid_t uid) { - return (uint32_t)uid.uid | (uid.caller_id << ITS_CALLER_ID_POS); + BUILD_ASSERT(sizeof(uid) == sizeof(uint32_t)); + return *(uint32_t *)&uid; } +#endif /* CONFIG_SECURE_STORAGE_64_BIT_UID */ psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid, size_t data_length, const void *data) @@ -61,10 +61,6 @@ psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid, ssize_t zms_ret; const uint32_t zms_id = zms_id_from(uid); - if (has_forbidden_bits_set(uid)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - zms_ret = zms_write(&s_zms, zms_id, data, data_length); if (zms_ret == data_length) { psa_ret = PSA_SUCCESS; @@ -85,10 +81,6 @@ psa_status_t secure_storage_its_store_get(secure_storage_its_uid_t uid, size_t d ssize_t zms_ret; const uint32_t zms_id = zms_id_from(uid); - if (has_forbidden_bits_set(uid)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - zms_ret = zms_read(&s_zms, zms_id, data, data_size); if (zms_ret > 0) { *data_length = zms_ret; @@ -108,10 +100,6 @@ psa_status_t secure_storage_its_store_remove(secure_storage_its_uid_t uid) int ret; const uint32_t zms_id = zms_id_from(uid); - if (has_forbidden_bits_set(uid)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - ret = zms_delete(&s_zms, zms_id); LOG_DBG("%s 0x%x. (%d)", ret ? "Failed to delete" : "Deleted", zms_id, ret); From 1a477748aafe8670af39c1307eaefc3fa01c0e09 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 5 Aug 2025 15:58:21 +0300 Subject: [PATCH 0252/1076] secure_storage: its: use %l printf length modifier Cast the UIDs to unsigned long when they are 32 bits. This allows to use a single %l length modifier instead of the double one for long long. Certain printf implementations only support the former and not the latter length modifier, so this has the advantage to work with them now that the UIDs are 32-bit by default. Signed-off-by: Tomi Fontanilles --- subsys/secure_storage/src/its/implementation.c | 11 +++++++++-- subsys/secure_storage/src/its/store/settings.c | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/subsys/secure_storage/src/its/implementation.c b/subsys/secure_storage/src/its/implementation.c index b39fbf90b002e..a2b7f97c3723b 100644 --- a/subsys/secure_storage/src/its/implementation.c +++ b/subsys/secure_storage/src/its/implementation.c @@ -115,8 +115,15 @@ static bool keep_stored_entry(secure_storage_its_uid_t uid, size_t data_length, if (existing_data_len == data_length && existing_create_flags == create_flags && !memcmp(existing_data, p_data, data_length)) { - LOG_DBG("Not writing entry %u/%llu to storage because its stored data" - " (of length %zu) is identical.", uid.caller_id, uid.uid, data_length); +#ifdef CONFIG_SECURE_STORAGE_64_BIT_UID + LOG_DBG("Not writing entry %u/%#llx to storage because its stored data" + " (of length %zu) is identical.", uid.caller_id, + (unsigned long long)uid.uid, data_length); +#else + LOG_DBG("Not writing entry %u/%#lx to storage because its stored data" + " (of length %zu) is identical.", uid.caller_id, + (unsigned long)uid.uid, data_length); +#endif *ret = PSA_SUCCESS; return true; } diff --git a/subsys/secure_storage/src/its/store/settings.c b/subsys/secure_storage/src/its/store/settings.c index 962fa516770a9..37973ffb02447 100644 --- a/subsys/secure_storage/src/its/store/settings.c +++ b/subsys/secure_storage/src/its/store/settings.c @@ -38,9 +38,15 @@ void secure_storage_its_store_settings_get_name( { int ret; +#ifdef CONFIG_SECURE_STORAGE_64_BIT_UID ret = snprintf(name, SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE, CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX "%x/%llx", uid.caller_id, (unsigned long long)uid.uid); +#else + ret = snprintf(name, SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE, + CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX "%x/%lx", + uid.caller_id, (unsigned long)uid.uid); +#endif __ASSERT_NO_MSG(ret > 0 && ret < SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE); } From 45ea4327fa58b38b378e214fd3ce62048b304fd1 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 5 Aug 2025 16:18:39 +0300 Subject: [PATCH 0253/1076] tests: secure_storage: psa: its: add test scenarios for 64-bit UIDs Add test scenarios for the newly-added CONFIG_SECURE_STORAGE_64_BIT_UID enabled with both the ZMS and Settings backends. They don't test backward compatibility but it makes sure that secure storage compiles and works fine with this configuration. Signed-off-by: Tomi Fontanilles --- .../secure_storage/psa/its/testcase.yaml | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/subsys/secure_storage/psa/its/testcase.yaml b/tests/subsys/secure_storage/psa/its/testcase.yaml index 05f1c1b9a6acf..e0cf75c589558 100644 --- a/tests/subsys/secure_storage/psa/its/testcase.yaml +++ b/tests/subsys/secure_storage/psa/its/testcase.yaml @@ -10,10 +10,9 @@ common: - psa.secure_storage tests: secure_storage.psa.its.secure_storage.store.zms: - filter: CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_ZMS # DT-based filtering is not possible for this test scenario. # Platforms with a storage_partition must be manually added here. - platform_allow: + platform_allow: &zms_platform_allow - native_sim - mps2/an385 - qemu_x86/atom @@ -25,14 +24,29 @@ tests: - nrf9160dk/nrf9160 - nrf9161dk/nrf9161 - ophelia4ev/nrf54l15/cpuapp - extra_args: + extra_args: &zms_extra_args - EXTRA_DTC_OVERLAY_FILE=zms.overlay - - EXTRA_CONF_FILE=overlay-secure_storage.conf;overlay-store_zms.conf;overlay-transform_default.conf + - EXTRA_CONF_FILE=\ + overlay-secure_storage.conf;overlay-store_zms.conf;overlay-transform_default.conf + + secure_storage.psa.its.secure_storage.store.zms.64-bit_uids: + platform_allow: *zms_platform_allow + extra_args: *zms_extra_args + extra_configs: + - CONFIG_SECURE_STORAGE_64_BIT_UID=y secure_storage.psa.its.secure_storage.store.settings: - filter: CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_SETTINGS - extra_args: "EXTRA_CONF_FILE=\ - overlay-secure_storage.conf;overlay-transform_default.conf;overlay-store_settings.conf" + filter: &settings_filter + CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_SETTINGS + extra_args: &settings_extra_args + "EXTRA_CONF_FILE=\ + overlay-secure_storage.conf;overlay-transform_default.conf;overlay-store_settings.conf" + + secure_storage.psa.its.secure_storage.store.settings.64-bit_uids: + filter: *settings_filter + extra_args: *settings_extra_args + extra_configs: + - CONFIG_SECURE_STORAGE_64_BIT_UID=y secure_storage.psa.its.secure_storage.custom.transform: filter: CONFIG_SECURE_STORAGE and not CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_NONE From 772db024da3299078a57fdfe77f9f9c8147dea3e Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 5 Aug 2025 16:22:46 +0300 Subject: [PATCH 0254/1076] tests: secure_storage: psa: its: fix ZMS test 77f19eb1b5ce10d8ec2e906b736d3789f15565c6 made ZMS depend on FLASH_MAP. Enable that Kconfig option in the ZMS Kconfig overlay file. Signed-off-by: Tomi Fontanilles --- tests/subsys/secure_storage/psa/its/overlay-store_zms.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/secure_storage/psa/its/overlay-store_zms.conf b/tests/subsys/secure_storage/psa/its/overlay-store_zms.conf index 7efe611bc0a4b..6c36dd4029728 100644 --- a/tests/subsys/secure_storage/psa/its/overlay-store_zms.conf +++ b/tests/subsys/secure_storage/psa/its/overlay-store_zms.conf @@ -1,3 +1,4 @@ CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_ZMS=y CONFIG_ZMS=y CONFIG_FLASH=y +CONFIG_FLASH_MAP=y From f399ae95ebfe2133faac338e23c1a4c2bace42ca Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Wed, 6 Aug 2025 14:35:23 +0300 Subject: [PATCH 0255/1076] doc: migration guide: document Secure storage UID size change to 32 bits Add a migration guide entry regarding the modification of the UID size as it is by default a breaking change. Signed-off-by: Tomi Fontanilles --- doc/releases/migration-guide-4.3.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index 9c20e47a5e7c7..866b21451a46d 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -154,6 +154,17 @@ Logging used. The new script supports the same functionality (and more), but requires different command line arguments when invoked. +Secure storage +============== + +* The size of :c:type:`psa_storage_uid_t`, used to identify storage entries, was changed from 64 to + 30 bits. + This change breaks backward compatibility with previously stored entries for which authentication + will start failing. + Enable :kconfig:option:`CONFIG_SECURE_STORAGE_64_BIT_UID` if you are updating an existing + installation from an earlier version of Zephyr and want to keep the pre-existing entries. + (:github:`94171`) + Shell ===== From 254a1daa070c824a54a3d13f5b23d9fd6758bb54 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Wed, 6 Aug 2025 15:00:10 +0300 Subject: [PATCH 0256/1076] tests: secure_storage: remove an integration platform nrf54l15dk/nrf54l15/cpuapp already covers the non-emulated case as part of the integration_platforms. Having ophelia4ev/nrf54l15/cpuapp does not bring any additional value and increases CI load, so remove it. Signed-off-by: Tomi Fontanilles --- tests/subsys/secure_storage/psa/crypto/testcase.yaml | 1 - tests/subsys/secure_storage/psa/its/testcase.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/subsys/secure_storage/psa/crypto/testcase.yaml b/tests/subsys/secure_storage/psa/crypto/testcase.yaml index 8755a5a193523..1482d23cb6c7e 100644 --- a/tests/subsys/secure_storage/psa/crypto/testcase.yaml +++ b/tests/subsys/secure_storage/psa/crypto/testcase.yaml @@ -8,7 +8,6 @@ tests: integration_platforms: - native_sim - nrf54l15dk/nrf54l15/cpuapp - - ophelia4ev/nrf54l15/cpuapp secure_storage.psa.crypto.tfm: filter: CONFIG_BUILD_WITH_TFM extra_args: EXTRA_CONF_FILE=overlay-tfm.conf diff --git a/tests/subsys/secure_storage/psa/its/testcase.yaml b/tests/subsys/secure_storage/psa/its/testcase.yaml index e0cf75c589558..75950a798143a 100644 --- a/tests/subsys/secure_storage/psa/its/testcase.yaml +++ b/tests/subsys/secure_storage/psa/its/testcase.yaml @@ -2,7 +2,6 @@ common: integration_platforms: - native_sim - nrf54l15dk/nrf54l15/cpuapp - - ophelia4ev/nrf54l15/cpuapp platform_exclude: - qemu_cortex_m0 # settings subsystem initialization fails timeout: 600 From 91029d7c0bd7ab345eaec859c10aafd7a3f3e7ff Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Wed, 6 Aug 2025 14:54:18 +0300 Subject: [PATCH 0257/1076] samples: psa: specify integration_platforms Explicitly specify native_sim as integration platform for better PR CI coverage. Signed-off-by: Tomi Fontanilles --- samples/psa/its/sample.yaml | 2 ++ samples/psa/persistent_key/sample.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/samples/psa/its/sample.yaml b/samples/psa/its/sample.yaml index 8d67cddd15731..d3e7b7e10c9b0 100644 --- a/samples/psa/its/sample.yaml +++ b/samples/psa/its/sample.yaml @@ -2,6 +2,8 @@ sample: name: PSA ITS API sample description: Demonstration of PSA Internal Trusted Storage (ITS) API usage. common: + integration_platforms: + - native_sim tags: - psa.secure_storage timeout: 10 diff --git a/samples/psa/persistent_key/sample.yaml b/samples/psa/persistent_key/sample.yaml index 490f2ea8f156d..7c5b9d8030043 100644 --- a/samples/psa/persistent_key/sample.yaml +++ b/samples/psa/persistent_key/sample.yaml @@ -2,6 +2,8 @@ sample: name: PSA Crypto persistent key sample description: Demonstration of persistent key usage in the PSA Crypto API. common: + integration_platforms: + - native_sim tags: - psa.secure_storage timeout: 10 From 1e78561cff8a9ba2c4f37bbc31addad53bb6e26e Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 5 Aug 2025 16:01:44 +0300 Subject: [PATCH 0258/1076] secure_storage: use %# flag character for hex printing Instead of literally having 0x in the format string, use the %# flag character so the printf implementation adds the 0x for us. Signed-off-by: Tomi Fontanilles --- subsys/secure_storage/src/its/implementation.c | 2 +- subsys/secure_storage/src/its/store/zms.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/secure_storage/src/its/implementation.c b/subsys/secure_storage/src/its/implementation.c index a2b7f97c3723b..6f33195a0628d 100644 --- a/subsys/secure_storage/src/its/implementation.c +++ b/subsys/secure_storage/src/its/implementation.c @@ -27,7 +27,7 @@ static psa_status_t make_its_uid(secure_storage_its_caller_id_t caller_id, psa_s #ifndef CONFIG_SECURE_STORAGE_64_BIT_UID /* Check that the UID is not bigger than the maximum defined size. */ if (uid & GENMASK64(63, SECURE_STORAGE_ITS_UID_BIT_SIZE)) { - LOG_DBG("UID %u/0x%llx cannot be used as it has bits set past " + LOG_DBG("UID %u/%#llx cannot be used as it has bits set past " "the first " STRINGIFY(SECURE_STORAGE_ITS_UID_BIT_SIZE) " ones.", caller_id, (unsigned long long)uid); return PSA_ERROR_INVALID_ARGUMENT; diff --git a/subsys/secure_storage/src/its/store/zms.c b/subsys/secure_storage/src/its/store/zms.c index 3a3bdd64c7623..4778e0365e917 100644 --- a/subsys/secure_storage/src/its/store/zms.c +++ b/subsys/secure_storage/src/its/store/zms.c @@ -69,7 +69,7 @@ psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid, } else { psa_ret = PSA_ERROR_STORAGE_FAILURE; } - LOG_DBG("%s 0x%x with %zu bytes. (%zd)", (psa_ret == PSA_SUCCESS) ? + LOG_DBG("%s %#x with %zu bytes. (%zd)", (psa_ret == PSA_SUCCESS) ? "Wrote" : "Failed to write", zms_id, data_length, zms_ret); return psa_ret; } @@ -90,7 +90,7 @@ psa_status_t secure_storage_its_store_get(secure_storage_its_uid_t uid, size_t d } else { psa_ret = PSA_ERROR_STORAGE_FAILURE; } - LOG_DBG("%s 0x%x for up to %zu bytes. (%zd)", (psa_ret != PSA_ERROR_STORAGE_FAILURE) ? + LOG_DBG("%s %#x for up to %zu bytes. (%zd)", (psa_ret != PSA_ERROR_STORAGE_FAILURE) ? "Read" : "Failed to read", zms_id, data_size, zms_ret); return psa_ret; } @@ -101,7 +101,7 @@ psa_status_t secure_storage_its_store_remove(secure_storage_its_uid_t uid) const uint32_t zms_id = zms_id_from(uid); ret = zms_delete(&s_zms, zms_id); - LOG_DBG("%s 0x%x. (%d)", ret ? "Failed to delete" : "Deleted", zms_id, ret); + LOG_DBG("%s %#x. (%d)", ret ? "Failed to delete" : "Deleted", zms_id, ret); return ret ? PSA_ERROR_STORAGE_FAILURE : PSA_SUCCESS; } From 90650158bbf6b54895d9e420d9421c4229906df1 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Wed, 6 Aug 2025 15:59:28 +0300 Subject: [PATCH 0259/1076] doc: secure_storage: document the 30-bit UID Add a bullet point for this new, relatively important deviation from the official specification. Also, advertise the Zephyr-specific zephyr/psa/* header files as they are related and probably need more attention from end users. Signed-off-by: Tomi Fontanilles --- doc/services/storage/secure_storage/index.rst | 11 ++++++++++- .../internal/zephyr/secure_storage/its/common.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/services/storage/secure_storage/index.rst b/doc/services/storage/secure_storage/index.rst index 57f7dc03b27ee..1829b435ea968 100644 --- a/doc/services/storage/secure_storage/index.rst +++ b/doc/services/storage/secure_storage/index.rst @@ -43,9 +43,18 @@ The secure storage subsystem's implementation of the PSA Secure Storage API: Instead, the PS API directly calls into the Internal Trusted Storage (ITS) API (unless a `custom implementation <#whole-api>`_ of the PS API is provided). -Below are some ways the implementation deviates from the specification +Below are some ways the implementation purposefully deviates from the specification and an explanation why. This is not an exhaustive list. +* The UID type is only 30 bits by default. (Against `2.5 UIDs `_.) + + | This is an optimization done to make it more convenient to directly use the UIDs as + storage entry IDs (e.g., with :ref:`ZMS ` when + :kconfig:option:`CONFIG_SECURE_STORAGE_ITS_STORE_IMPLEMENTATION_ZMS` is enabled). + | Zephyr defines numerical ranges to be used by different users of the API which guarantees that + there are no collisions and that they all fit within 30 bits. + See the header files in :zephyr_file:`include/zephyr/psa` for more information. + * The data stored in the ITS is by default encrypted and authenticated (Against ``1.`` in `3.2. Internal Trusted Storage requirements `_.) diff --git a/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h b/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h index f0576cba185f1..6ffc1bc78f57c 100644 --- a/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h +++ b/subsys/secure_storage/include/internal/zephyr/secure_storage/its/common.h @@ -39,6 +39,7 @@ typedef struct { * smaller IDs compared to the 64-bit ones that PSA Secure Storage specifies. * Zephyr defines ranges of IDs to be used by different users of the API (subsystems, application) * which guarantees 1. no collisions and 2. that the IDs used fit within `uid`. + * @see @ref zephyr/psa/key_ids.h and the other header files under `zephyr/psa`. */ typedef struct { psa_storage_uid_t uid : SECURE_STORAGE_ITS_UID_BIT_SIZE; From c2a2f99202cd977a5323cfcf5e13b7831bf39872 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 12 Aug 2025 12:31:06 +0200 Subject: [PATCH 0260/1076] soc: nxp: imxrt10xx: Configurable DCDC voltages Allow users to configure the DCDC target voltages for low power and normal mode. Signed-off-by: Pieter De Gendt --- soc/nxp/imxrt/imxrt10xx/Kconfig | 21 +++++++++++++++++++++ soc/nxp/imxrt/imxrt10xx/power.c | 8 ++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/soc/nxp/imxrt/imxrt10xx/Kconfig b/soc/nxp/imxrt/imxrt10xx/Kconfig index 87c370170af16..4019d75c2a2c0 100644 --- a/soc/nxp/imxrt/imxrt10xx/Kconfig +++ b/soc/nxp/imxrt/imxrt10xx/Kconfig @@ -84,4 +84,25 @@ config INIT_VIDEO_PLL depends on !SOC_MIMXRT1011 && !SOC_MIMXRT1015 && \ !SOC_MIMXRT1021 && !SOC_MIMXRT1024 +if PM + +config DCDC_TARGET_LOW_POWER_VOLTAGE + int "Target DCDC voltage in mV for low power mode" + default 1075 + range 800 1575 + help + When entering suspend-to-idle drops to this target SOC voltage. + If you are experiencing issues with low power mode stability, + try raising this voltage value. Increment or decrement in steps of 25 mV. + +config DCDC_TARGET_NORMAL_VOLTAGE + int "Target DCDC voltage in mV for normal mode" + default 1275 + range 800 1575 + help + When exiting suspend-to-idle raises to this SOC voltage. + Increment or decrement in steps of 25 mV. + +endif # PM + endif # SOC_SERIES_IMXRT10XX diff --git a/soc/nxp/imxrt/imxrt10xx/power.c b/soc/nxp/imxrt/imxrt10xx/power.c index 5936b70e02a91..237145d99cd3a 100644 --- a/soc/nxp/imxrt/imxrt10xx/power.c +++ b/soc/nxp/imxrt/imxrt10xx/power.c @@ -148,10 +148,10 @@ static void lpm_drop_voltage(void) CLOCK_SwitchOsc(kCLOCK_RcOsc); CLOCK_DeinitExternalClk(); /* - * Change to 1.075V SOC voltage. If you are experiencing issues with + * Change to low power SOC voltage. If you are experiencing issues with * low power mode stability, try raising this voltage value. */ - DCDC_AdjustRunTargetVoltage(DCDC, 0xB); + DCDC_AdjustRunTargetVoltage(DCDC, (CONFIG_DCDC_TARGET_LOW_POWER_VOLTAGE - 800) / 25); /* Enable 2.5 and 1.1V weak regulators */ PMU_2P5EnableWeakRegulator(PMU, true); PMU_1P1EnableWeakRegulator(PMU, true); @@ -173,8 +173,8 @@ static void lpm_raise_voltage(void) /* Disable weak LDOs */ PMU_2P5EnableWeakRegulator(PMU, false); PMU_1P1EnableWeakRegulator(PMU, false); - /* Change to 1.275V SOC voltage */ - DCDC_AdjustRunTargetVoltage(DCDC, 0x13); + /* Change to normal SOC voltage */ + DCDC_AdjustRunTargetVoltage(DCDC, (CONFIG_DCDC_TARGET_NORMAL_VOLTAGE - 800) / 25); /* Move to the external RC oscillator */ CLOCK_InitExternalClk(0); /* Switch clock source to external OSC. */ From 67126ab8aadf4cbde422fd927e35b8628597a21c Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 2 May 2025 15:00:54 +0200 Subject: [PATCH 0261/1076] Bluetooth: Controller: Fix building with Privacy without LE Encryption Fix building with Privacy feature without enabling LE Encryption support. This should allow being either Observer or Broadcaster role with Privacy features. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 2 +- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 5 +++- .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 24 ++++++++--------- .../nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 26 +++++++++---------- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 433b0fe8791d3..90a0945f5a19b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -2526,6 +2526,7 @@ void radio_ccm_disable(void) nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); nrf_ccm_disable(NRF_CCM); } +#endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */ #if defined(CONFIG_BT_CTLR_PRIVACY) static uint8_t MALIGN(4) _aar_scratch[3]; @@ -2656,7 +2657,6 @@ uint8_t radio_ar_resolve(const uint8_t *addr) } #endif /* CONFIG_BT_CTLR_PRIVACY */ -#endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */ #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST) /* @brief Function configures CTE inline register to start sampling of CTE diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 0afaa7d60bfb1..f01f9859db4bb 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -63,9 +63,12 @@ #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) #include -#include #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */ +#if defined(CONFIG_BT_CTLR_PRIVACY) +#include +#endif /* CONFIG_BT_CTLR_PRIVACY */ + /* Define to reset PPI registration. * This has to come before the ppi/dppi includes below. */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index ce0f8ac101475..11bb973994b4f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -175,18 +175,6 @@ static inline void hal_trigger_crypt_ppi_disable(void) nrf_ccm_subscribe_clear(NRF_CCM, NRF_CCM_TASK_START); } -#if defined(CONFIG_BT_CTLR_PRIVACY) -/******************************************************************************* - * Trigger automatic address resolution on Bit counter match: - * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. - */ -static inline void hal_trigger_aar_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH, HAL_TRIGGER_AAR_PPI); - nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI); -} -#endif /* CONFIG_BT_CTLR_PRIVACY */ - /* When hardware does not support Coded PHY we still allow the Controller * implementation to accept Coded PHY flags, but the Controller will use 1M * PHY on air. This is implementation specific feature. @@ -229,6 +217,18 @@ static inline void hal_trigger_crypt_by_bcmatch_ppi_config(void) #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */ +#if defined(CONFIG_BT_CTLR_PRIVACY) +/******************************************************************************* + * Trigger automatic address resolution on Bit counter match: + * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. + */ +static inline void hal_trigger_aar_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH, HAL_TRIGGER_AAR_PPI); + nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI); +} +#endif /* CONFIG_BT_CTLR_PRIVACY */ + /******************************************************************************/ #if !defined(CONFIG_BT_CTLR_TIFS_HW) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 21b615892a3bf..4b29bb4fe21d2 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -259,19 +259,6 @@ static inline void hal_trigger_crypt_by_bcmatch_ppi_config(void) } #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ -/******************************************************************************* - * Trigger automatic address resolution on Bit counter match: - * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. - * - * PPI channel 23 is pre-programmed with the following fixed settings: - * EEP: RADIO->EVENTS_BCMATCH - * TEP: AAR->TASKS_START - */ -static inline void hal_trigger_aar_ppi_config(void) -{ - /* No need to configure anything for the pre-programmed channel. */ -} - /******************************************************************************* * Trigger Radio Rate override upon Rateboost event. */ @@ -286,6 +273,19 @@ static inline void hal_trigger_rateoverride_ppi_config(void) } #endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ +/******************************************************************************* + * Trigger automatic address resolution on Bit counter match: + * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. + * + * PPI channel 23 is pre-programmed with the following fixed settings: + * EEP: RADIO->EVENTS_BCMATCH + * TEP: AAR->TASKS_START + */ +static inline void hal_trigger_aar_ppi_config(void) +{ + /* No need to configure anything for the pre-programmed channel. */ +} + /******************************************************************************/ #if !defined(CONFIG_BT_CTLR_TIFS_HW) /* PPI setup used for SW-based auto-switching during TIFS. */ From c4533d1b69f34ab9e5369e2a30dc46e826e30669 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Mon, 28 Jul 2025 10:46:28 -0400 Subject: [PATCH 0262/1076] posix: move limit definitions to common libc limits.h In order to reduce conflicts with limits defined in external C libraries, move Zephyr's POSIX limits from posix_features.h to limits.h in the common C library sources. In order to give the implementation better control over where POSIX limit definitions originate, use `#include_next ` to pull in the corresponding header of the C library, and provide a non-user configurable option `CONFIG_TC_PROVIDES_POSIX_LIMIT_DEFS` that may be set in order to ensure that the C library version of POSIX limits are used. Note: this may mean that runtime invariant values are inconsistent with parts that are actually in use within Zephyr, so applications are encouraged to use `sysconf()` with external C libraries that implement parts of the POSIX standard to query system configuration values at runtime. Signed-off-by: Chris Friedt --- include/zephyr/posix/posix_features.h | 134 ------------------------- include/zephyr/posix/sys/dirent.h | 2 - lib/libc/Kconfig | 1 + lib/libc/common/include/limits.h | 136 ++++++++++++++++++++++++++ lib/posix/options/Kconfig.toolchain | 3 + 5 files changed, 140 insertions(+), 136 deletions(-) create mode 100644 lib/libc/common/include/limits.h diff --git a/include/zephyr/posix/posix_features.h b/include/zephyr/posix/posix_features.h index ed4bffb1cf3e1..a78b4c2a8d941 100644 --- a/include/zephyr/posix/posix_features.h +++ b/include/zephyr/posix/posix_features.h @@ -245,138 +245,4 @@ /* #define _XOPEN_UNIX (-1L) */ /* #define _XOPEN_UUCP (-1L) */ -#if _POSIX_C_SOURCE >= 200809L && (__PICOLIBC__ > 1 || \ -(__PICOLIBC__ == 1 && (__PICOLIBC_MINOR__ > 8 || \ -__PICOLIBC_MINOR__ == 8 && __PICOLIBC_PATCHLEVEL__ >= 9))) -/* Use picolibc's limits.h when building POSIX code */ -#include -#else - -/* - * clang-format and checkpatch disagree on formatting here, so rely on checkpatch and disable - * clang-format since checkpatch cannot be selectively disabled. - */ - -/* clang-format off */ - -/* Maximum values */ -#define _POSIX_CLOCKRES_MIN (20000000L) - -/* Minimum values */ -#define _POSIX_AIO_LISTIO_MAX (2) -#define _POSIX_AIO_MAX (1) -#define _POSIX_ARG_MAX (4096) -#define _POSIX_CHILD_MAX (25) -#define _POSIX_DELAYTIMER_MAX (32) -#define _POSIX_HOST_NAME_MAX (255) -#define _POSIX_LINK_MAX (8) -#define _POSIX_LOGIN_NAME_MAX (9) -#define _POSIX_MAX_CANON (255) -#define _POSIX_MAX_INPUT (255) -#define _POSIX_MQ_OPEN_MAX (8) -#define _POSIX_MQ_PRIO_MAX (32) -#define _POSIX_NAME_MAX (14) -#define _POSIX_NGROUPS_MAX (8) -#define _POSIX_OPEN_MAX (20) -#define _POSIX_PATH_MAX (256) -#define _POSIX_PIPE_BUF (512) -#define _POSIX_RE_DUP_MAX (255) -#define _POSIX_RTSIG_MAX (8) -#define _POSIX_SEM_NSEMS_MAX (256) -#define _POSIX_SEM_VALUE_MAX (32767) -#define _POSIX_SIGQUEUE_MAX (32) -#define _POSIX_SSIZE_MAX (32767) -#define _POSIX_SS_REPL_MAX (4) -#define _POSIX_STREAM_MAX (8) -#define _POSIX_SYMLINK_MAX (255) -#define _POSIX_SYMLOOP_MAX (8) -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS (4) -#define _POSIX_THREAD_KEYS_MAX (128) -#define _POSIX_THREAD_THREADS_MAX (64) -#define _POSIX_TIMER_MAX (32) -#define _POSIX_TRACE_EVENT_NAME_MAX (30) -#define _POSIX_TRACE_NAME_MAX (8) -#define _POSIX_TRACE_SYS_MAX (8) -#define _POSIX_TRACE_USER_EVENT_MAX (32) -#define _POSIX_TTY_NAME_MAX (9) -#define _POSIX_TZNAME_MAX (6) -#define _POSIX2_BC_BASE_MAX (99) -#define _POSIX2_BC_DIM_MAX (2048) -#define _POSIX2_BC_SCALE_MAX (99) -#define _POSIX2_BC_STRING_MAX (1000) -#define _POSIX2_CHARCLASS_NAME_MAX (14) -#define _POSIX2_COLL_WEIGHTS_MAX (2) -#define _POSIX2_EXPR_NEST_MAX (32) -#define _POSIX2_LINE_MAX (2048) -#define _XOPEN_IOV_MAX (16) -#define _XOPEN_NAME_MAX (255) -#define _XOPEN_PATH_MAX (1024) - -#endif /* __PICOLIBC__ */ - -/* Other invariant values */ -#define NL_LANGMAX (14) -#define NL_MSGMAX (32767) -#define NL_SETMAX (255) -#define NL_TEXTMAX (_POSIX2_LINE_MAX) -#define NZERO (20) - -/* Runtime invariant values */ -#define AIO_LISTIO_MAX _POSIX_AIO_LISTIO_MAX -#define AIO_MAX _POSIX_AIO_MAX -#define AIO_PRIO_DELTA_MAX (0) -#ifndef ARG_MAX -#define ARG_MAX _POSIX_ARG_MAX -#endif -#ifndef ATEXIT_MAX -#define ATEXIT_MAX (32) -#endif -#define DELAYTIMER_MAX \ - COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_DELAYTIMER_MAX), (0)) -#define HOST_NAME_MAX \ - COND_CODE_1(CONFIG_POSIX_NETWORKING, (CONFIG_POSIX_HOST_NAME_MAX), (0)) -#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX -#define MQ_OPEN_MAX \ - COND_CODE_1(CONFIG_POSIX_MESSAGE_PASSING, (CONFIG_POSIX_MQ_OPEN_MAX), (0)) -#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX -#ifndef OPEN_MAX -#define OPEN_MAX CONFIG_POSIX_OPEN_MAX -#endif -#define PAGE_SIZE CONFIG_POSIX_PAGE_SIZE -#define PAGESIZE CONFIG_POSIX_PAGE_SIZE -#ifndef PATH_MAX -#define PATH_MAX _POSIX_PATH_MAX -#endif -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_KEYS_MAX \ - COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_KEYS_MAX), (0)) -#define PTHREAD_THREADS_MAX \ - COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_THREADS_MAX), (0)) -#define RTSIG_MAX \ - COND_CODE_1(CONFIG_POSIX_REALTIME_SIGNALS, (CONFIG_POSIX_RTSIG_MAX), (0)) -#define SEM_NSEMS_MAX \ - COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_NSEMS_MAX), (0)) -#define SEM_VALUE_MAX \ - COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_VALUE_MAX), (0)) -#define SIGQUEUE_MAX _POSIX_SIGQUEUE_MAX -#define STREAM_MAX _POSIX_STREAM_MAX -#define SYMLOOP_MAX _POSIX_SYMLOOP_MAX -#define TIMER_MAX \ - COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_TIMER_MAX), (0)) -#define TTY_NAME_MAX _POSIX_TTY_NAME_MAX -#ifndef TZNAME_MAX -#define TZNAME_MAX _POSIX_TZNAME_MAX -#endif - -/* Pathname variable values */ -#define FILESIZEBITS (32) -#define POSIX_ALLOC_SIZE_MIN (256) -#define POSIX_REC_INCR_XFER_SIZE (1024) -#define POSIX_REC_MAX_XFER_SIZE (32767) -#define POSIX_REC_MIN_XFER_SIZE (1) -#define POSIX_REC_XFER_ALIGN (4) -#define SYMLINK_MAX _POSIX_SYMLINK_MAX - -/* clang-format on */ - #endif /* INCLUDE_ZEPHYR_POSIX_POSIX_FEATURES_H_ */ diff --git a/include/zephyr/posix/sys/dirent.h b/include/zephyr/posix/sys/dirent.h index 63d02dc511edc..fde312136ebb2 100644 --- a/include/zephyr/posix/sys/dirent.h +++ b/include/zephyr/posix/sys/dirent.h @@ -9,8 +9,6 @@ #include -#include - #if !defined(NAME_MAX) && defined(_XOPEN_SOURCE) #define NAME_MAX _XOPEN_NAME_MAX #endif diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 62f5f33415137..b17220d2cdf4c 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -103,6 +103,7 @@ config PICOLIBC imply THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE select LIBC_ERRNO if THREAD_LOCAL_STORAGE select NEED_LIBC_MEM_PARTITION + select TC_PROVIDES_POSIX_LIMIT_DEFS select TC_PROVIDES_POSIX_C_LANG_SUPPORT_R imply COMMON_LIBC_MALLOC imply COMMON_LIBC_ABORT diff --git a/lib/libc/common/include/limits.h b/lib/libc/common/include/limits.h new file mode 100644 index 0000000000000..ed0735a8cbb27 --- /dev/null +++ b/lib/libc/common/include/limits.h @@ -0,0 +1,136 @@ +/* + * Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ +#define ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ + +#include_next + +#if !defined(CONFIG_TC_PROVIDES_POSIX_LIMIT_DEFS) + +#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) + +/* + * clang-format and checkpatch disagree on formatting here, so use rely and checkpatch and disable + * clang-format since the checkpatch cannot be selectively disabled. + */ + +/* clang-format off */ + +/* Maximum values */ +#define _POSIX_CLOCKRES_MIN (20000000L) + +/* Minimum values */ +#define _POSIX_AIO_LISTIO_MAX (2) +#define _POSIX_AIO_MAX (1) +#define _POSIX_ARG_MAX (4096) +#define _POSIX_CHILD_MAX (25) +#define _POSIX_DELAYTIMER_MAX (32) +#define _POSIX_HOST_NAME_MAX (255) +#define _POSIX_LINK_MAX (8) +#define _POSIX_LOGIN_NAME_MAX (9) +#define _POSIX_MAX_CANON (255) +#define _POSIX_MAX_INPUT (255) +#define _POSIX_MQ_OPEN_MAX (8) +#define _POSIX_MQ_PRIO_MAX (32) +#define _POSIX_NAME_MAX (14) +#define _POSIX_NGROUPS_MAX (8) +#define _POSIX_OPEN_MAX (20) +#define _POSIX_PATH_MAX (256) +#define _POSIX_PIPE_BUF (512) +#define _POSIX_RE_DUP_MAX (255) +#define _POSIX_RTSIG_MAX (8) +#define _POSIX_SEM_NSEMS_MAX (256) +#define _POSIX_SEM_VALUE_MAX (32767) +#define _POSIX_SIGQUEUE_MAX (32) +#define _POSIX_SSIZE_MAX (32767) +#define _POSIX_SS_REPL_MAX (4) +#define _POSIX_STREAM_MAX (8) +#define _POSIX_SYMLINK_MAX (255) +#define _POSIX_SYMLOOP_MAX (8) +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS (4) +#define _POSIX_THREAD_KEYS_MAX (128) +#define _POSIX_THREAD_THREADS_MAX (64) +#define _POSIX_TIMER_MAX (32) +#define _POSIX_TRACE_EVENT_NAME_MAX (30) +#define _POSIX_TRACE_NAME_MAX (8) +#define _POSIX_TRACE_SYS_MAX (8) +#define _POSIX_TRACE_USER_EVENT_MAX (32) +#define _POSIX_TTY_NAME_MAX (9) +#define _POSIX_TZNAME_MAX (6) +#define _POSIX2_BC_BASE_MAX (99) +#define _POSIX2_BC_DIM_MAX (2048) +#define _POSIX2_BC_SCALE_MAX (99) +#define _POSIX2_BC_STRING_MAX (1000) +#define _POSIX2_CHARCLASS_NAME_MAX (14) +#define _POSIX2_COLL_WEIGHTS_MAX (2) +#define _POSIX2_EXPR_NEST_MAX (32) +#define _POSIX2_LINE_MAX (2048) +#define _XOPEN_IOV_MAX (16) +#define _XOPEN_NAME_MAX (255) +#define _XOPEN_PATH_MAX (1024) + +/* Other invariant values */ +#define NL_LANGMAX (14) +#define NL_MSGMAX (32767) +#define NL_SETMAX (255) +#define NL_TEXTMAX (_POSIX2_LINE_MAX) +#define NZERO (20) + +/* Runtime invariant values */ +#define AIO_LISTIO_MAX _POSIX_AIO_LISTIO_MAX +#define AIO_MAX _POSIX_AIO_MAX +#define AIO_PRIO_DELTA_MAX (0) +#define ARG_MAX _POSIX_ARG_MAX +#define ATEXIT_MAX (32) +#define DELAYTIMER_MAX \ + COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_DELAYTIMER_MAX), (0)) +#define HOST_NAME_MAX \ + COND_CODE_1(CONFIG_POSIX_NETWORKING, (CONFIG_POSIX_HOST_NAME_MAX), (0)) +#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX +#define MQ_OPEN_MAX \ + COND_CODE_1(CONFIG_POSIX_MESSAGE_PASSING, (CONFIG_POSIX_MQ_OPEN_MAX), (0)) +#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX +#define OPEN_MAX CONFIG_POSIX_OPEN_MAX +#define PAGE_SIZE CONFIG_POSIX_PAGE_SIZE +#define PAGESIZE CONFIG_POSIX_PAGE_SIZE +#undef PATH_MAX +#define PATH_MAX _POSIX_PATH_MAX +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_KEYS_MAX \ + COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_KEYS_MAX), (0)) +#define PTHREAD_THREADS_MAX \ + COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_THREADS_MAX), (0)) +#define RTSIG_MAX \ + COND_CODE_1(CONFIG_POSIX_REALTIME_SIGNALS, (CONFIG_POSIX_RTSIG_MAX), (0)) +#define SEM_NSEMS_MAX \ + COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_NSEMS_MAX), (0)) +#define SEM_VALUE_MAX \ + COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_VALUE_MAX), (0)) +#define SIGQUEUE_MAX _POSIX_SIGQUEUE_MAX +#define STREAM_MAX _POSIX_STREAM_MAX +#define SYMLOOP_MAX _POSIX_SYMLOOP_MAX +#define TIMER_MAX \ + COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_TIMER_MAX), (0)) +#define TTY_NAME_MAX _POSIX_TTY_NAME_MAX +#define TZNAME_MAX _POSIX_TZNAME_MAX + +/* Pathname variable values */ +#define FILESIZEBITS (32) +#define POSIX_ALLOC_SIZE_MIN (256) +#define POSIX_REC_INCR_XFER_SIZE (1024) +#define POSIX_REC_MAX_XFER_SIZE (32767) +#define POSIX_REC_MIN_XFER_SIZE (1) +#define POSIX_REC_XFER_ALIGN (4) +#define SYMLINK_MAX _POSIX_SYMLINK_MAX + +/* clang-format on */ + +#endif /* defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) */ + +#endif /* !defined(CONFIG_TC_PROVIDES_POSIX_LIMIT_DEFS) */ + +#endif /* ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ */ diff --git a/lib/posix/options/Kconfig.toolchain b/lib/posix/options/Kconfig.toolchain index e328a03087944..16b77dd153922 100644 --- a/lib/posix/options/Kconfig.toolchain +++ b/lib/posix/options/Kconfig.toolchain @@ -13,6 +13,9 @@ # # https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html +config TC_PROVIDES_POSIX_LIMIT_DEFS + bool + config TC_PROVIDES_POSIX_ASYNCHRONOUS_IO bool From ab8b55ac992ea2d31ec0f7a66d7ff843affb47a2 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Mon, 18 Aug 2025 10:44:04 -0400 Subject: [PATCH 0263/1076] posix: move posix limit definitions to posix_limits.h Rather than keeping limits defined in a common way, controllable with one Kconfig, move posix definitions out of the standard common libc header `` into ``, not controlled with Kconfig. Additionally, include `` wherever an in-tree C library includes a custom ``. Note: the only reason any of the `` files exist, is to define the POSIX limit PATH_MAX without declaring `_POSIX_C_SOURCE`, which would be necessary according to the standard, and each of the custom `` files is nearly identical in this regard. Signed-off-by: Chris Friedt --- .../zephyr/posix/posix_limits.h | 21 +++++-------------- lib/libc/Kconfig | 1 - lib/libc/arcmwdt/include/limits.h | 10 ++++++++- lib/libc/armstdc/include/limits.h | 8 +++++++ lib/libc/iar/include/limits.h | 8 +++++++ lib/libc/minimal/include/limits.h | 8 +++++++ lib/posix/options/Kconfig.toolchain | 3 --- 7 files changed, 38 insertions(+), 21 deletions(-) rename lib/libc/common/include/limits.h => include/zephyr/posix/posix_limits.h (89%) diff --git a/lib/libc/common/include/limits.h b/include/zephyr/posix/posix_limits.h similarity index 89% rename from lib/libc/common/include/limits.h rename to include/zephyr/posix/posix_limits.h index ed0735a8cbb27..4441f9497cf35 100644 --- a/lib/libc/common/include/limits.h +++ b/include/zephyr/posix/posix_limits.h @@ -4,18 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ -#define ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ - -#include_next - -#if !defined(CONFIG_TC_PROVIDES_POSIX_LIMIT_DEFS) - -#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) +#ifndef ZEPHYR_INCLUDE_ZEPHYR_POSIX_POSIX_LIMITS_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_POSIX_POSIX_LIMITS_H_ /* - * clang-format and checkpatch disagree on formatting here, so use rely and checkpatch and disable - * clang-format since the checkpatch cannot be selectively disabled. + * clang-format and checkpatch disagree on formatting here, so rely on checkpatch and disable + * clang-format since checkpatch cannot be selectively disabled. */ /* clang-format off */ @@ -97,7 +91,6 @@ #define OPEN_MAX CONFIG_POSIX_OPEN_MAX #define PAGE_SIZE CONFIG_POSIX_PAGE_SIZE #define PAGESIZE CONFIG_POSIX_PAGE_SIZE -#undef PATH_MAX #define PATH_MAX _POSIX_PATH_MAX #define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS #define PTHREAD_KEYS_MAX \ @@ -129,8 +122,4 @@ /* clang-format on */ -#endif /* defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) */ - -#endif /* !defined(CONFIG_TC_PROVIDES_POSIX_LIMIT_DEFS) */ - -#endif /* ZEPHYR_LIB_LIBC_COMMON_INCLUDE_LIMITS_H_ */ +#endif /* ZEPHYR_INCLUDE_ZEPHYR_POSIX_POSIX_LIMITS_H_ */ diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index b17220d2cdf4c..62f5f33415137 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -103,7 +103,6 @@ config PICOLIBC imply THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE && TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE select LIBC_ERRNO if THREAD_LOCAL_STORAGE select NEED_LIBC_MEM_PARTITION - select TC_PROVIDES_POSIX_LIMIT_DEFS select TC_PROVIDES_POSIX_C_LANG_SUPPORT_R imply COMMON_LIBC_MALLOC imply COMMON_LIBC_ABORT diff --git a/lib/libc/arcmwdt/include/limits.h b/lib/libc/arcmwdt/include/limits.h index 822e66f24d283..96982ad6e4146 100644 --- a/lib/libc/arcmwdt/include/limits.h +++ b/lib/libc/arcmwdt/include/limits.h @@ -13,10 +13,18 @@ extern "C" { #endif +#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) + +#include + +#else + #define PATH_MAX 256 +#endif + #ifdef __cplusplus } #endif -#endif /* LIB_LIBC_ARCMWDT_INCLUDE_LIMITS_H_ */ +#endif /* ZEPHYR_LIB_LIBC_ARMSTDC_INCLUDE_LIMITS_H_ */ diff --git a/lib/libc/armstdc/include/limits.h b/lib/libc/armstdc/include/limits.h index 37aad4cf9bb8b..13206aa68b566 100644 --- a/lib/libc/armstdc/include/limits.h +++ b/lib/libc/armstdc/include/limits.h @@ -13,8 +13,16 @@ extern "C" { #endif +#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) + +#include + +#else + #define PATH_MAX 256 +#endif + #ifdef __cplusplus } #endif diff --git a/lib/libc/iar/include/limits.h b/lib/libc/iar/include/limits.h index 50decad13ad18..6db549c355e92 100644 --- a/lib/libc/iar/include/limits.h +++ b/lib/libc/iar/include/limits.h @@ -13,8 +13,16 @@ extern "C" { #endif +#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) + +#include + +#else + #define PATH_MAX 256 +#endif + #ifdef __cplusplus } #endif diff --git a/lib/libc/minimal/include/limits.h b/lib/libc/minimal/include/limits.h index 7b9a986465683..3a25ed16b1f83 100644 --- a/lib/libc/minimal/include/limits.h +++ b/lib/libc/minimal/include/limits.h @@ -80,8 +80,16 @@ extern "C" { #error "unexpected __SIZEOF_LONG_LONG__ value" #endif +#if defined(_POSIX_C_SOURCE) || defined(__DOXYGEN__) + +#include + +#else + #define PATH_MAX 256 +#endif + #ifdef __cplusplus } #endif diff --git a/lib/posix/options/Kconfig.toolchain b/lib/posix/options/Kconfig.toolchain index 16b77dd153922..e328a03087944 100644 --- a/lib/posix/options/Kconfig.toolchain +++ b/lib/posix/options/Kconfig.toolchain @@ -13,9 +13,6 @@ # # https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html -config TC_PROVIDES_POSIX_LIMIT_DEFS - bool - config TC_PROVIDES_POSIX_ASYNCHRONOUS_IO bool From bf4c8c2e2211c7d93ce668a7662d4536c24d1cc2 Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Thu, 21 Aug 2025 10:42:13 +0200 Subject: [PATCH 0264/1076] board: sensry: ganymed-bob - fix missing gpio/NET_L2 when compiling net-samples then the required gpio is disabled. the installed vsc8541 phy requires gpio for reset. additionally, we enable NET_L2 when network is enabled. Signed-off-by: Sven Ginka --- boards/sensry/ganymed_bob/Kconfig.defconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 boards/sensry/ganymed_bob/Kconfig.defconfig diff --git a/boards/sensry/ganymed_bob/Kconfig.defconfig b/boards/sensry/ganymed_bob/Kconfig.defconfig new file mode 100644 index 0000000000000..f0a5ec770cf7d --- /dev/null +++ b/boards/sensry/ganymed_bob/Kconfig.defconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +configdefault NET_L2_ETHERNET + default y From 0d794df481b9149e1f1a56450f1b3ff610e88477 Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Thu, 21 Aug 2025 10:42:34 +0200 Subject: [PATCH 0265/1076] board: sensry: ganymed-sk - fix missing gpio/NET_L2 when compiling net-samples then the required gpio is disabled. the installed vsc8541 phy requires gpio for reset. additionally, we enable NET_L2 when network is enabled. Signed-off-by: Sven Ginka --- boards/sensry/ganymed_sk/Kconfig.defconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 boards/sensry/ganymed_sk/Kconfig.defconfig diff --git a/boards/sensry/ganymed_sk/Kconfig.defconfig b/boards/sensry/ganymed_sk/Kconfig.defconfig new file mode 100644 index 0000000000000..f0a5ec770cf7d --- /dev/null +++ b/boards/sensry/ganymed_sk/Kconfig.defconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +configdefault NET_L2_ETHERNET + default y From e018a7e8ddd6003eafc535f2dc66acd32326a8ae Mon Sep 17 00:00:00 2001 From: Anisetti Avinash Krishna Date: Sun, 27 Apr 2025 23:15:01 +0530 Subject: [PATCH 0266/1076] drivers: pwm: Enable PWM support for PTL-h Enable PWM support on PTL-h and add 64bit address support for PWM driver. Signed-off-by: Anisetti Avinash Krishna --- boards/intel/ptl/intel_ptl_h_crb.dts | 4 ++++ boards/intel/ptl/intel_ptl_h_crb.yaml | 1 + drivers/pwm/pwm_intel_blinky.c | 8 +++++++- dts/bindings/pwm/intel,blinky-pwm.yaml | 8 ++++++++ dts/x86/intel/panther_lake_h.dtsi | 11 +++++++++++ .../pwm/pwm_api/boards/intel_ptl_h_crb.overlay | 9 +++++++++ 6 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/pwm/pwm_api/boards/intel_ptl_h_crb.overlay diff --git a/boards/intel/ptl/intel_ptl_h_crb.dts b/boards/intel/ptl/intel_ptl_h_crb.dts index 13a4906c6f940..09c83b2cccb91 100644 --- a/boards/intel/ptl/intel_ptl_h_crb.dts +++ b/boards/intel/ptl/intel_ptl_h_crb.dts @@ -43,3 +43,7 @@ &tco_wdt { status = "okay"; }; + +&pwm0 { + status = "okay"; +}; diff --git a/boards/intel/ptl/intel_ptl_h_crb.yaml b/boards/intel/ptl/intel_ptl_h_crb.yaml index 98e6763401d07..585596c382927 100644 --- a/boards/intel/ptl/intel_ptl_h_crb.yaml +++ b/boards/intel/ptl/intel_ptl_h_crb.yaml @@ -12,6 +12,7 @@ supported: - watchdog - uart - rtc + - pwm testing: ignore_tags: - net diff --git a/drivers/pwm/pwm_intel_blinky.c b/drivers/pwm/pwm_intel_blinky.c index 2396ae2246a6c..ef70b59f5179b 100644 --- a/drivers/pwm/pwm_intel_blinky.c +++ b/drivers/pwm/pwm_intel_blinky.c @@ -27,6 +27,7 @@ struct bk_intel_config { uint32_t reg_offset; uint32_t clock_freq; uint32_t max_pins; + uint32_t reg_upper_32; /* Stores higher 32 bits of 64 bit reg address */ }; struct bk_intel_runtime { @@ -103,9 +104,13 @@ static int bk_intel_init(const struct device *dev) { struct bk_intel_runtime *runtime = dev->data; const struct bk_intel_config *config = dev->config; + uintptr_t physical_addr; + + physical_addr = (config->reg_base.phys_addr & ~0xFFU) + | ((uintptr_t)config->reg_upper_32 << 32); device_map(&runtime->reg_base, - config->reg_base.phys_addr & ~0xFFU, + physical_addr, config->reg_base.size, K_MEM_CACHE_NONE); @@ -118,6 +123,7 @@ static int bk_intel_init(const struct device *dev) .reg_offset = DT_INST_PROP(n, reg_offset), \ .max_pins = DT_INST_PROP(n, max_pins), \ .clock_freq = DT_INST_PROP(n, clock_frequency), \ + .reg_upper_32 = DT_INST_PROP(n, reg_upper32), \ }; \ \ static struct bk_intel_runtime bk_rt_##n; \ diff --git a/dts/bindings/pwm/intel,blinky-pwm.yaml b/dts/bindings/pwm/intel,blinky-pwm.yaml index 10822317c09b1..97db3146e332c 100644 --- a/dts/bindings/pwm/intel,blinky-pwm.yaml +++ b/dts/bindings/pwm/intel,blinky-pwm.yaml @@ -27,6 +27,14 @@ properties: required: true description: Maximum number of pins supported by platform + reg-upper32: + type: int + default: 0 + description: | + Few platforms have 64 bit PWM register address, + this property will be used to share the higher + 32 bits(63-32). + "#pwm-cells": const: 2 diff --git a/dts/x86/intel/panther_lake_h.dtsi b/dts/x86/intel/panther_lake_h.dtsi index 8fd5ea216d100..02b216cd713fc 100644 --- a/dts/x86/intel/panther_lake_h.dtsi +++ b/dts/x86/intel/panther_lake_h.dtsi @@ -293,6 +293,17 @@ status = "disabled"; }; + pwm0: pwm@5d0000 { + compatible = "intel,blinky-pwm"; + reg = <0x5d0000 0x500>; + reg-upper32 = <0x40>; + reg-offset = <0x434>; + clock-frequency = <32768>; + max-pins = <1>; + #pwm-cells = <2>; + status = "disabled"; + }; + rtc: counter: rtc@70 { compatible = "motorola,mc146818"; reg = <0x70 0x0D 0x71 0x0D>; diff --git a/tests/drivers/pwm/pwm_api/boards/intel_ptl_h_crb.overlay b/tests/drivers/pwm/pwm_api/boards/intel_ptl_h_crb.overlay new file mode 100644 index 0000000000000..2d4f0bd802d67 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/intel_ptl_h_crb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwm0 { + status = "okay"; +}; From d28a755c028020521f5c81add8810dbe13513a41 Mon Sep 17 00:00:00 2001 From: Andrei Lalaev Date: Sun, 17 Aug 2025 13:30:15 +0200 Subject: [PATCH 0267/1076] boards: raspberrypi: rpi_pico2: include LED only for Pico 2 At the moment, "blinky" sample can be built for Pico 2 W, but it doesn't work as expected because the board has no LED connected to GPIO. rpi_pico2.dtsi is a common dtsi, used by Pico 2 and Pico 2 W, it shouldn't contain board specific stuff (like LEDs). So, include "rpi_pico-led.dtsi" directly in Pico 2 board dts. Signed-off-by: Andrei Lalaev --- boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi | 1 - boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi index 3b49981114797..51076a57dd73d 100644 --- a/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi @@ -10,7 +10,6 @@ #include #include "rpi_pico2-pinctrl.dtsi" -#include "../common/rpi_pico-led.dtsi" / { chosen { diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts index f96491f44e2e5..f7238b128cbfb 100644 --- a/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts @@ -20,3 +20,4 @@ * implemented) Hazard3 cores. */ #include "rpi_pico2.dtsi" +#include "../common/rpi_pico-led.dtsi" From 2310331e3e942baac73812f4df8e0fad467681df Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 2 Jun 2025 18:07:06 -0400 Subject: [PATCH 0268/1076] rpi_pico: make it work with picolibc The picolibc changes were merged upstream; switch to using that revision. Signed-off-by: Anas Nashif --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index cae08c1b47d8f..5290130c1a634 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_rpi_pico path: modules/hal/rpi_pico - revision: 5a981c7c29e3846646549a1902183684f0147e1d + revision: b547a36a722af7787e5f55b551fd6ce72dcba5a4 groups: - hal - name: hal_silabs From 3ed633b69b3a4c1d3c601e9d2636a09becb4f996 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 4 Jun 2025 12:24:54 -0700 Subject: [PATCH 0269/1076] modules/hal_rpi_pico: Switch boot_stage2 to picolibc Now that rpi_pico can use picolibc, let's switch to it. Signed-off-by: Keith Packard --- modules/hal_rpi_pico/bootloader/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/hal_rpi_pico/bootloader/CMakeLists.txt b/modules/hal_rpi_pico/bootloader/CMakeLists.txt index 7e8d39d8951fb..241ba3c23c305 100644 --- a/modules/hal_rpi_pico/bootloader/CMakeLists.txt +++ b/modules/hal_rpi_pico/bootloader/CMakeLists.txt @@ -45,8 +45,8 @@ target_include_directories(boot_stage2 PUBLIC target_link_options(boot_stage2 PRIVATE "-nostartfiles" - "--specs=nosys.specs" - "LINKER:--script=${boot_stage_dir}/boot_stage2.ld" + "--specs=picolibc.specs" + "-T${boot_stage_dir}/boot_stage2.ld" ) # The second stage bootloader is compiled without kconfig definitions. From ce97cd1d9cd17ffbcdb2122f2cfa86b63287fe9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 11:51:39 +0200 Subject: [PATCH 0270/1076] include: devicetree: show DT helpers in their respective device sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The various DT helpers benefit from being shown in their respective device sections as it's expected that some users will be looking there rather than generic Devicetree help pages. Signed-off-by: Benjamin Cabé --- include/zephyr/devicetree/can.h | 1 + include/zephyr/devicetree/clocks.h | 1 + include/zephyr/devicetree/display.h | 1 + include/zephyr/devicetree/dma.h | 1 + include/zephyr/devicetree/gpio.h | 1 + include/zephyr/devicetree/mbox.h | 1 + include/zephyr/devicetree/pinctrl.h | 1 + include/zephyr/devicetree/pwms.h | 1 + include/zephyr/devicetree/reset.h | 1 + include/zephyr/devicetree/spi.h | 1 + 10 files changed, 10 insertions(+) diff --git a/include/zephyr/devicetree/can.h b/include/zephyr/devicetree/can.h index a98a3ea7f0e0f..9097a9b3f53c1 100644 --- a/include/zephyr/devicetree/can.h +++ b/include/zephyr/devicetree/can.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-can Devicetree CAN API * @ingroup devicetree + * @ingroup can_interface * @{ */ diff --git a/include/zephyr/devicetree/clocks.h b/include/zephyr/devicetree/clocks.h index 1721de650ec90..8a345bfd12e46 100644 --- a/include/zephyr/devicetree/clocks.h +++ b/include/zephyr/devicetree/clocks.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-clocks Devicetree Clocks API * @ingroup devicetree + * @ingroup clock_control_interface * @{ */ diff --git a/include/zephyr/devicetree/display.h b/include/zephyr/devicetree/display.h index f73fdf5cd823c..833e06c9715ec 100644 --- a/include/zephyr/devicetree/display.h +++ b/include/zephyr/devicetree/display.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-display Devicetree Display API * @ingroup devicetree + * @ingroup display_interface * @{ */ diff --git a/include/zephyr/devicetree/dma.h b/include/zephyr/devicetree/dma.h index 3dff82928f6f5..3dc1eac4e2c7e 100644 --- a/include/zephyr/devicetree/dma.h +++ b/include/zephyr/devicetree/dma.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-dmas Devicetree DMA API * @ingroup devicetree + * @ingroup dma_interface * @{ */ diff --git a/include/zephyr/devicetree/gpio.h b/include/zephyr/devicetree/gpio.h index 93426796f8965..0576e5c5bd6bc 100644 --- a/include/zephyr/devicetree/gpio.h +++ b/include/zephyr/devicetree/gpio.h @@ -20,6 +20,7 @@ extern "C" { /** * @defgroup devicetree-gpio Devicetree GPIO API * @ingroup devicetree + * @ingroup gpio_interface * @{ */ diff --git a/include/zephyr/devicetree/mbox.h b/include/zephyr/devicetree/mbox.h index d1e990e247083..d3d47db7f4cb1 100644 --- a/include/zephyr/devicetree/mbox.h +++ b/include/zephyr/devicetree/mbox.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-mbox Devicetree MBOX API * @ingroup devicetree + * @ingroup mbox_interface * @{ */ diff --git a/include/zephyr/devicetree/pinctrl.h b/include/zephyr/devicetree/pinctrl.h index a5fde6a8fc162..0e86c389b184f 100644 --- a/include/zephyr/devicetree/pinctrl.h +++ b/include/zephyr/devicetree/pinctrl.h @@ -14,6 +14,7 @@ /** * @defgroup devicetree-pinctrl Pin control * @ingroup devicetree + * @ingroup pinctrl_interface * @{ */ diff --git a/include/zephyr/devicetree/pwms.h b/include/zephyr/devicetree/pwms.h index 4f5e8d41a9764..4b43abc412350 100644 --- a/include/zephyr/devicetree/pwms.h +++ b/include/zephyr/devicetree/pwms.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-pwms Devicetree PWMs API * @ingroup devicetree + * @ingroup pwm_interface * @{ */ diff --git a/include/zephyr/devicetree/reset.h b/include/zephyr/devicetree/reset.h index bb1f9bf888b47..9ce1d6d7e0f6a 100644 --- a/include/zephyr/devicetree/reset.h +++ b/include/zephyr/devicetree/reset.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-reset-controller Devicetree Reset Controller API * @ingroup devicetree + * @ingroup reset_controller_interface * @{ */ diff --git a/include/zephyr/devicetree/spi.h b/include/zephyr/devicetree/spi.h index db1b4996f6440..321bfc1cb1300 100644 --- a/include/zephyr/devicetree/spi.h +++ b/include/zephyr/devicetree/spi.h @@ -19,6 +19,7 @@ extern "C" { /** * @defgroup devicetree-spi Devicetree SPI API * @ingroup devicetree + * @ingroup spi_interface * @{ */ From 22d04f7f9336506d23d9c0b9dd33acfeb4f254d8 Mon Sep 17 00:00:00 2001 From: Julien Panis Date: Fri, 11 Oct 2024 14:53:08 +0200 Subject: [PATCH 0271/1076] drivers: crypto: cc23x0: Add power management Add PM support to cc23x0 AES module. Signed-off-by: Julien Panis --- drivers/crypto/crypto_cc23x0.c | 143 ++++++++++++++++++++++++++++++--- 1 file changed, 133 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/crypto_cc23x0.c b/drivers/crypto/crypto_cc23x0.c index 15c8bcb19b550..f6f2d5efbac69 100644 --- a/drivers/crypto/crypto_cc23x0.c +++ b/drivers/crypto/crypto_cc23x0.c @@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(crypto_cc23x0, CONFIG_CRYPTO_LOG_LEVEL); #include #include #include +#include +#include +#include #include #include @@ -80,6 +83,22 @@ struct crypto_cc23x0_data { #endif }; +static inline void crypto_cc23x0_pm_policy_state_lock_get(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif +} + +static inline void crypto_cc23x0_pm_policy_state_lock_put(void) +{ +#ifdef CONFIG_PM_DEVICE + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); +#endif +} + static void crypto_cc23x0_isr(const struct device *dev) { struct crypto_cc23x0_data *data = dev->data; @@ -102,17 +121,42 @@ static void crypto_cc23x0_isr(const struct device *dev) AESClearInterrupt(status); } -static void crypto_cc23x0_cleanup(const struct device *dev) -{ #ifdef CONFIG_CRYPTO_CC23X0_DMA + +static int crypto_cc23x0_dma_enable(const struct device *dev, bool *dma_enabled) +{ + const struct crypto_cc23x0_config *cfg = dev->config; + int ret; + + ret = pm_device_runtime_get(cfg->dma_dev); + if (ret) { + LOG_ERR("Failed to resume DMA"); + *dma_enabled = false; + } else { + *dma_enabled = true; + } + + return ret; +} + +static void crypto_cc23x0_dma_cleanup(const struct device *dev, bool dma_enabled) +{ const struct crypto_cc23x0_config *cfg = dev->config; dma_stop(cfg->dma_dev, cfg->dma_channel_b); dma_stop(cfg->dma_dev, cfg->dma_channel_a); + AESDisableDMA(); -#else - ARG_UNUSED(dev); -#endif + + if (dma_enabled) { + pm_device_runtime_put(cfg->dma_dev); + } +} + +#endif /* CONFIG_CRYPTO_CC23X0_DMA */ + +static void crypto_cc23x0_aes_cleanup(void) +{ AESClearAUTOCFGTrigger(); AESClearAUTOCFGBusHalt(); AESClearTXTAndBUF(); @@ -127,6 +171,7 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt * #ifdef CONFIG_CRYPTO_CC23X0_DMA uint32_t int_flags = AES_IMASK_CHBDONE; const struct crypto_cc23x0_config *cfg = dev->config; + bool dma_enabled = false; struct dma_block_config block_cfg_cha = { .source_address = (uint32_t)(pkt->in_buf), @@ -186,6 +231,8 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt * k_mutex_lock(&data->device_mutex, K_FOREVER); + crypto_cc23x0_pm_policy_state_lock_get(); + /* Enable interrupts */ AESSetIMASK(int_flags); @@ -198,6 +245,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt * AES_AUTOCFG_TRGAES_WRBUF3S); #ifdef CONFIG_CRYPTO_CC23X0_DMA + ret = crypto_cc23x0_dma_enable(dev, &dma_enabled); + if (ret) { + goto cleanup; + } + /* Setup the DMA for the AES engine */ AESSetupDMA(AES_DMA_ADRCHA_BUF0 | AES_DMA_TRGCHA_AESSTART | @@ -209,11 +261,13 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt * ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha); if (ret) { + LOG_ERR("Failed to configure DMA CHA"); goto cleanup; } ret = dma_config(cfg->dma_dev, cfg->dma_channel_b, &dma_cfg_chb); if (ret) { + LOG_ERR("Failed to configure DMA CHB"); goto cleanup; } @@ -265,7 +319,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt * #endif cleanup: - crypto_cc23x0_cleanup(dev); +#ifdef CONFIG_CRYPTO_CC23X0_DMA + crypto_cc23x0_dma_cleanup(dev, dma_enabled); +#endif + crypto_cc23x0_aes_cleanup(); + crypto_cc23x0_pm_policy_state_lock_put(); k_mutex_unlock(&data->device_mutex); pkt->out_len = out_bytes_processed; @@ -284,6 +342,7 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin #ifdef CONFIG_CRYPTO_CC23X0_DMA uint32_t int_flags = AES_IMASK_CHBDONE; const struct crypto_cc23x0_config *cfg = dev->config; + bool dma_enabled = false; struct dma_block_config block_cfg_cha = { .source_address = (uint32_t)(pkt->in_buf), @@ -345,6 +404,8 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin k_mutex_lock(&data->device_mutex, K_FOREVER); + crypto_cc23x0_pm_policy_state_lock_get(); + /* Enable interrupts */ AESSetIMASK(int_flags); @@ -359,6 +420,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin AES_AUTOCFG_CTRSIZE_CTR128); #ifdef CONFIG_CRYPTO_CC23X0_DMA + ret = crypto_cc23x0_dma_enable(dev, &dma_enabled); + if (ret) { + goto cleanup; + } + /* Setup the DMA for the AES engine */ AESSetupDMA(AES_DMA_ADRCHA_TXTX0 | AES_DMA_TRGCHA_AESDONE | @@ -367,11 +433,13 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha); if (ret) { + LOG_ERR("Failed to configure DMA CHA"); goto cleanup; } ret = dma_config(cfg->dma_dev, cfg->dma_channel_b, &dma_cfg_chb); if (ret) { + LOG_ERR("Failed to configure DMA CHB"); goto cleanup; } @@ -433,7 +501,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin #endif cleanup: - crypto_cc23x0_cleanup(dev); +#ifdef CONFIG_CRYPTO_CC23X0_DMA + crypto_cc23x0_dma_cleanup(dev, dma_enabled); +#endif + crypto_cc23x0_aes_cleanup(); + crypto_cc23x0_pm_policy_state_lock_put(); k_mutex_unlock(&data->device_mutex); pkt->out_len = bytes_processed; @@ -451,6 +523,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, #ifdef CONFIG_CRYPTO_CC23X0_DMA uint32_t int_flags = AES_IMASK_CHADONE; const struct crypto_cc23x0_config *cfg = dev->config; + bool dma_enabled = false; struct dma_block_config block_cfg_cha = { .source_address = (uint32_t)b0, @@ -492,6 +565,8 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, k_mutex_lock(&data->device_mutex, K_FOREVER); + crypto_cc23x0_pm_policy_state_lock_get(); + /* Enable interrupts */ AESSetIMASK(int_flags); @@ -506,6 +581,13 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, /* Write zero'd IV */ AESWriteIV32(iv); +#ifdef CONFIG_CRYPTO_CC23X0_DMA + ret = crypto_cc23x0_dma_enable(dev, &dma_enabled); + if (ret) { + goto out; + } +#endif + if (b0) { #ifdef CONFIG_CRYPTO_CC23X0_DMA /* Setup the DMA for the AES engine */ @@ -514,6 +596,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha); if (ret) { + LOG_ERR("Failed to configure DMA CHA"); goto out; } @@ -546,6 +629,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha); if (ret) { + LOG_ERR("Failed to configure DMA CHA"); goto out; } @@ -578,6 +662,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha); if (ret) { + LOG_ERR("Failed to configure DMA CHA"); goto out; } @@ -624,7 +709,11 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt, AESReadTag(pkt->out_buf); out: - crypto_cc23x0_cleanup(dev); +#ifdef CONFIG_CRYPTO_CC23X0_DMA + crypto_cc23x0_dma_cleanup(dev, dma_enabled); +#endif + crypto_cc23x0_aes_cleanup(); + crypto_cc23x0_pm_policy_state_lock_put(); k_mutex_unlock(&data->device_mutex); pkt->out_len = bytes_processed; @@ -979,6 +1068,7 @@ static int crypto_cc23x0_init(const struct device *dev) { #ifdef CONFIG_CRYPTO_CC23X0_DMA const struct crypto_cc23x0_config *cfg = dev->config; + int ret; #endif struct crypto_cc23x0_data *data = dev->data; @@ -1000,6 +1090,12 @@ static int crypto_cc23x0_init(const struct device *dev) if (!device_is_ready(cfg->dma_dev)) { return -ENODEV; } + + ret = pm_device_runtime_enable(cfg->dma_dev); + if (ret) { + LOG_ERR("Failed to enable DMA runtime PM"); + return ret; + } #else k_sem_init(&data->aes_done, 0, 1); #endif @@ -1015,6 +1111,33 @@ static DEVICE_API(crypto, crypto_enc_funcs) = { static struct crypto_cc23x0_data crypto_cc23x0_dev_data; +#ifdef CONFIG_PM_DEVICE + +static int crypto_cc23x0_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + CLKCTLDisable(CLKCTL_BASE, CLKCTL_LAES); + break; + case PM_DEVICE_ACTION_RESUME: + CLKCTLEnable(CLKCTL_BASE, CLKCTL_LAES); + break; + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_TURN_OFF: + break; + default: + ret = -ENOTSUP; + } + + return ret; +} + +#endif /* CONFIG_PM_DEVICE */ + +PM_DEVICE_DT_INST_DEFINE(0, crypto_cc23x0_pm_action); + #ifdef CONFIG_CRYPTO_CC23X0_DMA static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = { .dma_dev = DEVICE_DT_GET(TI_CC23X0_DT_INST_DMA_CTLR(0, cha)), @@ -1026,7 +1149,7 @@ static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = { DEVICE_DT_INST_DEFINE(0, crypto_cc23x0_init, - NULL, + PM_DEVICE_DT_INST_GET(0), &crypto_cc23x0_dev_data, &crypto_cc23x0_dev_config, POST_KERNEL, @@ -1035,7 +1158,7 @@ DEVICE_DT_INST_DEFINE(0, #else DEVICE_DT_INST_DEFINE(0, crypto_cc23x0_init, - NULL, + PM_DEVICE_DT_INST_GET(0), &crypto_cc23x0_dev_data, NULL, POST_KERNEL, From 40e91b42422fc9e9889a2172a470b187b4e680be Mon Sep 17 00:00:00 2001 From: Clay Wynn Date: Mon, 9 Jun 2025 16:10:39 -0700 Subject: [PATCH 0272/1076] os: add __weak to to assert_print to allow customization System designers may want to change the behavior of assert_print, such as storing the message off into retained RAM and instantly rebooting. Adding __weak allows customatization Signed-off-by: Clay Wynn --- lib/os/assert.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/os/assert.c b/lib/os/assert.c index 1fee487bff64e..4f37f62d031b7 100644 --- a/lib/os/assert.c +++ b/lib/os/assert.c @@ -44,7 +44,17 @@ __weak void assert_post_action(const char *file, unsigned int line) } EXPORT_SYMBOL(assert_post_action); -void assert_print(const char *fmt, ...) +/** + * @brief Assert Print Handler + * + * This routine implements printing the assertion message. + * + * System designers may wish to substitute this implementation to store the + * assertion, or otherwise change the behavior of the assertion print + * + * @param N/A + */ +__weak void assert_print(const char *fmt, ...) { va_list ap; From bf4565246519823cace9bd7340f5cbd7f3b6b867 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 7 Apr 2025 16:08:24 +0200 Subject: [PATCH 0273/1076] tests: Bluetooth: Tester: TMAP BSIM test Adds BSIM testing of the TMAP features of the BT Tester. Signed-off-by: Emil Gydesen --- tests/bsim/bluetooth/tester/CMakeLists.txt | 2 + .../bluetooth/tester/src/audio/tmap_central.c | 70 +++++++++++++++++++ .../tester/src/audio/tmap_peripheral.c | 58 +++++++++++++++ tests/bsim/bluetooth/tester/src/bsim_btp.h | 32 +++++++++ tests/bsim/bluetooth/tester/src/test_main.c | 4 ++ .../bluetooth/tester/tests_scripts/tmap.sh | 41 +++++++++++ 6 files changed, 207 insertions(+) create mode 100644 tests/bsim/bluetooth/tester/src/audio/tmap_central.c create mode 100644 tests/bsim/bluetooth/tester/src/audio/tmap_peripheral.c create mode 100755 tests/bsim/bluetooth/tester/tests_scripts/tmap.sh diff --git a/tests/bsim/bluetooth/tester/CMakeLists.txt b/tests/bsim/bluetooth/tester/CMakeLists.txt index 2681d331a62e7..7a3244ec457d7 100644 --- a/tests/bsim/bluetooth/tester/CMakeLists.txt +++ b/tests/bsim/bluetooth/tester/CMakeLists.txt @@ -30,6 +30,8 @@ target_sources(app PRIVATE src/audio/hap_peripheral.c src/audio/micp_central.c src/audio/micp_peripheral.c + src/audio/tmap_central.c + src/audio/tmap_peripheral.c src/audio/vcp_central.c src/audio/vcp_peripheral.c src/host/gap_central.c diff --git a/tests/bsim/bluetooth/tester/src/audio/tmap_central.c b/tests/bsim/bluetooth/tester/src/audio/tmap_central.c new file mode 100644 index 0000000000000..7dc32249522b4 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/tmap_central.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_tmap_central, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_tmap_central(void) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t remote_addr; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_TMAP); + + bsim_btp_gap_start_discovery(BTP_GAP_DISCOVERY_FLAG_LE); + bsim_btp_wait_for_gap_device_found(&remote_addr); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Found remote device %s", addr_str); + + bsim_btp_gap_stop_discovery(); + bsim_btp_gap_connect(&remote_addr, BTP_GAP_ADDR_TYPE_IDENTITY); + bsim_btp_wait_for_gap_device_connected(NULL); + LOG_INF("Device %s connected", addr_str); + + bsim_btp_gap_pair(&remote_addr); + bsim_btp_wait_for_gap_sec_level_changed(NULL, NULL); + + bsim_btp_tmap_discover(&remote_addr); + bsim_btp_wait_for_tmap_discovery_complete(); + + bsim_btp_gap_disconnect(&remote_addr); + bsim_btp_wait_for_gap_device_disconnected(NULL); + LOG_INF("Device %s disconnected", addr_str); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "tmap_central", + .test_descr = "Smoketest for the TMAP central BT Tester behavior", + .test_main_f = test_tmap_central, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_tmap_central_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/audio/tmap_peripheral.c b/tests/bsim/bluetooth/tester/src/audio/tmap_peripheral.c new file mode 100644 index 0000000000000..0a0ebf33cdb58 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/tmap_peripheral.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_tmap_peripheral, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_tmap_peripheral(void) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t remote_addr; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_TMAP); + + bsim_btp_gap_set_discoverable(BTP_GAP_GENERAL_DISCOVERABLE); + bsim_btp_gap_start_advertising(0U, 0U, NULL, BT_HCI_OWN_ADDR_PUBLIC); + bsim_btp_wait_for_gap_device_connected(&remote_addr); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Device %s connected", addr_str); + bsim_btp_wait_for_gap_device_disconnected(NULL); + LOG_INF("Device %s disconnected", addr_str); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "tmap_peripheral", + .test_descr = "Smoketest for the TMAP peripheral BT Tester behavior", + .test_main_f = test_tmap_peripheral, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_tmap_peripheral_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.h b/tests/bsim/bluetooth/tester/src/bsim_btp.h index 1747d53cac15a..4103dcbd5a4e1 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.h +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.h @@ -386,6 +386,38 @@ static inline void bsim_btp_wait_for_hauc_discovery_complete(bt_addr_le_t *addre net_buf_unref(buf); } +static inline void bsim_btp_tmap_discover(const bt_addr_le_t *address) +{ + struct btp_tmap_discover_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_TMAP; + cmd_hdr->opcode = BTP_TMAP_DISCOVER; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_tmap_discovery_complete(void) +{ + struct btp_tmap_discovery_complete_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_TMAP, BT_TMAP_EV_DISCOVERY_COMPLETE, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS); + + net_buf_unref(buf); +} + static inline void bsim_btp_vcp_discover(const bt_addr_le_t *address) { struct btp_vcp_discover_cmd *cmd; diff --git a/tests/bsim/bluetooth/tester/src/test_main.c b/tests/bsim/bluetooth/tester/src/test_main.c index ac9c9e38cc5a2..5c6e1e5231e62 100644 --- a/tests/bsim/bluetooth/tester/src/test_main.c +++ b/tests/bsim/bluetooth/tester/src/test_main.c @@ -15,6 +15,8 @@ extern struct bst_test_list *test_hap_central_install(struct bst_test_list *test extern struct bst_test_list *test_hap_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_micp_central_install(struct bst_test_list *tests); extern struct bst_test_list *test_micp_peripheral_install(struct bst_test_list *tests); +extern struct bst_test_list *test_tmap_central_install(struct bst_test_list *tests); +extern struct bst_test_list *test_tmap_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_vcp_central_install(struct bst_test_list *tests); extern struct bst_test_list *test_vcp_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_iso_broadcaster_install(struct bst_test_list *tests); @@ -29,6 +31,8 @@ bst_test_install_t test_installers[] = { test_hap_peripheral_install, test_micp_central_install, test_micp_peripheral_install, + test_tmap_central_install, + test_tmap_peripheral_install, test_vcp_central_install, test_vcp_peripheral_install, test_iso_broadcaster_install, diff --git a/tests/bsim/bluetooth/tester/tests_scripts/tmap.sh b/tests/bsim/bluetooth/tester/tests_scripts/tmap.sh new file mode 100755 index 0000000000000..d20719d53dfa8 --- /dev/null +++ b/tests/bsim/bluetooth/tester/tests_scripts/tmap.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Smoketest for TMAP BTP commands with the BT tester + +simulation_id="tester_tmap" +verbosity_level=2 +EXECUTE_TIMEOUT=100 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +UART_DIR=/tmp/bs_${USER}/${simulation_id}/ +UART_PER=${UART_DIR}/peripheral +UART_CEN=${UART_DIR}/central + +# Central BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=10 -d=0 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_CEN}.tx -uart0_fifob_txfile=${UART_CEN}.rx + +# Central Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=21 -d=10 -RealEncryption=1 -testid=tmap_central \ + -nosim -uart0_fifob_rxfile=${UART_CEN}.rx -uart0_fifob_txfile=${UART_CEN}.tx + +# Peripheral BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=32 -d=1 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_PER}.tx -uart0_fifob_txfile=${UART_PER}.rx + +# Peripheral Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=43 -d=11 -RealEncryption=1 -testid=tmap_peripheral \ + -nosim -uart0_fifob_rxfile=${UART_PER}.rx -uart0_fifob_txfile=${UART_PER}.tx + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs # Wait for all programs in background and return != 0 if any fails From 862faccb27d058dfb97965226a14f8df3581c574 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 19 Jun 2025 13:11:23 +0200 Subject: [PATCH 0274/1076] samples: drivers: i2c: rtio_loopback: fix CONFIG_I2C_TARGET_BUFFER _MODE=n Allow to disable CONFIG_I2C_TARGET_BUFFER_MODE in rtio_loopback I2C driver sample. Signed-off-by: Etienne Carriere --- samples/drivers/i2c/rtio_loopback/src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/drivers/i2c/rtio_loopback/src/main.c b/samples/drivers/i2c/rtio_loopback/src/main.c index ef2a17dd47aed..f68a47ce8579e 100644 --- a/samples/drivers/i2c/rtio_loopback/src/main.c +++ b/samples/drivers/i2c/rtio_loopback/src/main.c @@ -94,6 +94,7 @@ static int sample_target_read_processed(struct i2c_target_config *target_config, return 0; } +#ifdef CONFIG_I2C_TARGET_BUFFER_MODE static void sample_target_buf_write_received(struct i2c_target_config *target_config, uint8_t *data, uint32_t size) @@ -110,6 +111,7 @@ static int sample_target_buf_read_requested(struct i2c_target_config *target_con *size = sizeof(sample_read_data); return 0; } +#endif /* CONFIG_I2C_TARGET_BUFFER_MODE */ static int sample_target_stop(struct i2c_target_config *config) { @@ -122,8 +124,10 @@ static const struct i2c_target_callbacks sample_target_callbacks = { .read_requested = sample_target_read_requested, .write_received = sample_target_write_received, .read_processed = sample_target_read_processed, +#ifdef CONFIG_I2C_TARGET_BUFFER_MODE .buf_write_received = sample_target_buf_write_received, .buf_read_requested = sample_target_buf_read_requested, +#endif .stop = sample_target_stop, }; From 2560dca75df69cd636f385c476fe6c062c9155ec Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 20 Jun 2025 13:31:07 +0200 Subject: [PATCH 0275/1076] samples: drivers: i2c: rtio_loopback: configure transfer byte size Add configuration options CONFIG_I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE and CONFIG_I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE to set the number of bytes exchanged during I2C transfers in I2C driver rtio_loopback sample. Add also a bit of verbosity when exchanged data are corrupted. Signed-off-by: Etienne Carriere --- samples/drivers/i2c/rtio_loopback/Kconfig | 14 ++++++++++ samples/drivers/i2c/rtio_loopback/README.rst | 7 +++++ samples/drivers/i2c/rtio_loopback/src/main.c | 28 +++++++++++++++++--- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 samples/drivers/i2c/rtio_loopback/Kconfig diff --git a/samples/drivers/i2c/rtio_loopback/Kconfig b/samples/drivers/i2c/rtio_loopback/Kconfig new file mode 100644 index 0000000000000..079f4a735f3a1 --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/Kconfig @@ -0,0 +1,14 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "I2C RTIO Loopback Test" + +config I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE + int "Max data size used for testing I2C read transfers" + default 2 + +config I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE + int "Max data size used for testing I2C write transfers" + default 6 + +source "Kconfig.zephyr" diff --git a/samples/drivers/i2c/rtio_loopback/README.rst b/samples/drivers/i2c/rtio_loopback/README.rst index 29599173d73ea..787f2a959419c 100644 --- a/samples/drivers/i2c/rtio_loopback/README.rst +++ b/samples/drivers/i2c/rtio_loopback/README.rst @@ -48,3 +48,10 @@ If necessary, add any board specific configs to the board specific overlay: .. code-block:: cfg CONFIG_I2C_TARGET_BUFFER_MODE=y + +Transferred data sizes +********************** + +One can tune the number of data bytes echanged during the tests using +configuration options ``CONFIG_I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE`` +and ``CONFIG_I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE``. diff --git a/samples/drivers/i2c/rtio_loopback/src/main.c b/samples/drivers/i2c/rtio_loopback/src/main.c index f68a47ce8579e..27ea4c3f0a786 100644 --- a/samples/drivers/i2c/rtio_loopback/src/main.c +++ b/samples/drivers/i2c/rtio_loopback/src/main.c @@ -22,12 +22,12 @@ static const struct device *sample_i2c_controller = I2C_CONTROLLER_DEVICE_GET; static const struct device *sample_i2c_controller_target = I2C_CONTROLLER_TARGET_DEVICE_GET; /* Data to write and buffer to store write in */ -static uint8_t sample_write_data[] = {0x0A, 0x0B}; +static uint8_t sample_write_data[CONFIG_I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE]; static uint8_t sample_write_buf[sizeof(sample_write_data)]; static uint32_t sample_write_buf_pos; /* Data to read and buffer to store read in */ -static uint8_t sample_read_data[] = {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5}; +static uint8_t sample_read_data[CONFIG_I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE]; static uint32_t sample_read_data_pos; static uint8_t sample_read_buf[sizeof(sample_read_data)]; @@ -176,16 +176,30 @@ static int sample_validate_write_read(void) int ret; if (sample_write_buf_pos != sizeof(sample_write_data)) { + printk("Posittion error: %zu != %zu\n", + sample_write_buf_pos, sizeof(sample_write_data)); return -EIO; } ret = memcmp(sample_write_buf, sample_write_data, sizeof(sample_write_data)); if (ret) { + for (int n = 0; n < sizeof(sample_write_data); n++) { + if (sample_write_buf[n] != sample_write_data[n]) { + printk("Write at offset %u: %02x != %02x\n", + n, sample_write_buf[n], sample_write_data[n]); + } + } return -EIO; } ret = memcmp(sample_read_buf, sample_read_data, sizeof(sample_read_data)); if (ret) { + for (int n = 0; n < sizeof(sample_read_data); n++) { + if (sample_read_buf[n] != sample_read_data[n]) { + printk("Read at offset %u: %02x != %02x\n", + n, sample_read_buf[n], sample_read_data[n]); + } + } return -EIO; } @@ -360,7 +374,15 @@ static int sample_rtio_write_read_async(void) int main(void) { - int ret; + int ret, n; + + for (n = 0; n < sizeof(sample_write_data); n++) { + sample_write_data[n] = (0xFF - n) % 0xFF; + } + + for (n = 0; n < sizeof(sample_read_data); n++) { + sample_read_data[n] = n % 0xFF; + } printk("%s %s\n", "init_i2c_target", "running"); ret = sample_init_i2c_target(); From 81b76e0a4ef154f21261d6dca7ab9beeb7a5103e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 19 Jun 2025 12:50:07 +0200 Subject: [PATCH 0276/1076] tests: drivers: i2c: i2c_target_api: configure transfer byte size Add CONFIG_I2C_TEST_DATA_MAX_SIZE to I2C driver i2c_target_api tests to set the max data size of tested I2C transfer. The effective I2C transfer data size depends on that value and the size of the EEPROM defined in the board DTS file. Signed-off-by: Etienne Carriere --- tests/drivers/i2c/i2c_target_api/README.txt | 6 ++++ .../drivers/i2c/i2c_target_api/common/Kconfig | 4 +++ tests/drivers/i2c/i2c_target_api/src/main.c | 35 +++++++++++++++---- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/tests/drivers/i2c/i2c_target_api/README.txt b/tests/drivers/i2c/i2c_target_api/README.txt index 4624da97c5ec7..1204cf8c935b1 100644 --- a/tests/drivers/i2c/i2c_target_api/README.txt +++ b/tests/drivers/i2c/i2c_target_api/README.txt @@ -39,3 +39,9 @@ Presence of this required hardware configuration is identified by the `i2c_bus_short` fixture. If the buses are not connected as required, or the controller driver has bugs, the test will fail one or more I2C transactions. + +Transfer data size +****************** + +One can tune the number of data bytes echanged during the tests using +configuration option ``CONFIG_I2C_TEST_DATA_MAX_SIZE``. diff --git a/tests/drivers/i2c/i2c_target_api/common/Kconfig b/tests/drivers/i2c/i2c_target_api/common/Kconfig index b516534a8e145..b42bbdba07cfc 100644 --- a/tests/drivers/i2c/i2c_target_api/common/Kconfig +++ b/tests/drivers/i2c/i2c_target_api/common/Kconfig @@ -17,3 +17,7 @@ config I2C_VIRTUAL_NAME config APP_DUAL_ROLE_I2C bool "Test with combined controller/target behavior" + +config I2C_TEST_DATA_MAX_SIZE + int "Max tested data size for the I2C transfers" + default 20 diff --git a/tests/drivers/i2c/i2c_target_api/src/main.c b/tests/drivers/i2c/i2c_target_api/src/main.c index b249daae90bd4..143248d187e4f 100644 --- a/tests/drivers/i2c/i2c_target_api/src/main.c +++ b/tests/drivers/i2c/i2c_target_api/src/main.c @@ -23,9 +23,11 @@ #define NODE_EP0 DT_NODELABEL(eeprom0) #define NODE_EP1 DT_NODELABEL(eeprom1) -#define TEST_DATA_SIZE 20 -static const uint8_t eeprom_0_data[TEST_DATA_SIZE] = "0123456789abcdefghij"; -static const uint8_t eeprom_1_data[TEST_DATA_SIZE] = "jihgfedcba9876543210"; +#define TEST_DATA_SIZE MIN(CONFIG_I2C_TEST_DATA_MAX_SIZE, \ + MIN(DT_PROP(NODE_EP0, size), DT_PROP(NODE_EP1, size))) + +static uint8_t eeprom_0_data[TEST_DATA_SIZE]; +static uint8_t eeprom_1_data[TEST_DATA_SIZE]; static uint8_t i2c_buffer[TEST_DATA_SIZE]; /* @@ -35,6 +37,23 @@ static uint8_t i2c_buffer[TEST_DATA_SIZE]; uint8_t buffer_print_eeprom[TEST_DATA_SIZE * 5 + 1]; uint8_t buffer_print_i2c[TEST_DATA_SIZE * 5 + 1]; +static void init_eeprom_test_data(void) +{ + size_t n; + + /* + * Initialize EEPROM data with printable ASCII value (range [32 126]). + * Make sure content differs between eeprom_0_data[] and eeprom_1_data[]. + */ + for (n = 0; n < sizeof(eeprom_0_data); n++) { + eeprom_0_data[n] = 32 + (n % (126 - 32)); + } + + for (n = 0; n < sizeof(eeprom_1_data); n++) { + eeprom_1_data[n] = 32 + (((n + 10) * 3) % (126 - 32)); + } +} + static void to_display_format(const uint8_t *src, size_t size, char *dst) { size_t i; @@ -123,7 +142,7 @@ static int run_program_read(const struct device *i2c, uint8_t addr, i2c->name, addr, offset); for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { - i2c_buffer[i] = i; + i2c_buffer[i] = i & 0xFF; } switch (addr_width) { @@ -155,11 +174,11 @@ static int run_program_read(const struct device *i2c, uint8_t addr, zassert_equal(ret, 0, "Failed to read EEPROM"); for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { - if (i2c_buffer[i] != i) { + if (i2c_buffer[i] != (i & 0xFF)) { to_display_format(i2c_buffer, TEST_DATA_SIZE-offset, buffer_print_i2c); - TC_PRINT("Error: Unexpected buffer content: %s\n", - buffer_print_i2c); + TC_PRINT("Error: Unexpected %u (%02x) buffer content: %s\n", + i, i2c_buffer[i], buffer_print_i2c); return -EIO; } } @@ -235,6 +254,8 @@ ZTEST(i2c_eeprom_target, test_eeprom_target) uint8_t addr_1_width = DT_PROP_OR(NODE_EP1, address_width, 8); int ret, offset; + init_eeprom_test_data(); + zassert_not_null(i2c_0, "EEPROM 0 - I2C bus not found"); zassert_not_null(eeprom_0, "EEPROM 0 device not found"); From 39e73fe2ed09a8ebee96b19cf87eb2bc265149d5 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 20 Jun 2025 13:46:08 +0200 Subject: [PATCH 0277/1076] tests: drivers: i2c: i2c_target_api: add nucleo_h503rb board Add ST nucleo_h503rb board to I2C driver i2c_target_api test. The board configuration make it testing transfer of 300 bytes data to ensure the ReloadMode of the SoC I2C controller nicely handles exchanges of more than 256 byte. Signed-off-by: Etienne Carriere --- .../i2c_target_api/boards/nucleo_h503rb.conf | 3 ++ .../boards/nucleo_h503rb.overlay | 42 +++++++++++++++++++ .../drivers/i2c/i2c_target_api/testcase.yaml | 1 + 3 files changed, 46 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.conf create mode 100644 tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.conf b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.conf new file mode 100644 index 0000000000000..ef46de38d35cb --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.conf @@ -0,0 +1,3 @@ +CONFIG_I2C_STM32_INTERRUPT=y +CONFIG_I2C_TEST_DATA_MAX_SIZE=300 +CONFIG_I2C_VIRTUAL=n diff --git a/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.overlay b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.overlay new file mode 100644 index 0000000000000..37b87dce643bb --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/nucleo_h503rb.overlay @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/* I2C bus pins are exposed on the ST morpho header. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB7 CN5:9 PB6 CN5:10/CN10:3 + * i2c2 PB4 CN9:6/CN10:27 PB5 CN9:5/CN10:29 + * + * Short Pin PB7 to PB4, and PB6 to PB5, for the test to pass. + */ + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; + + eeprom1: eeprom@10 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x10>; + address-width = <16>; + size = <1024>; + }; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb5 &i2c2_sda_pb4>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; + + eeprom0: eeprom@18 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x18>; + address-width = <16>; + size = <1024>; + }; +}; diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index 0a84b703f8b92..13ef2bb16c4c2 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -24,6 +24,7 @@ tests: - nucleo_f207zg - nucleo_f401re - nucleo_f429zi + - nucleo_h503rb - nucleo_wl55jc - nucleo_l073rz - nucleo_l152re From 71a5f29150fc36fd7585ec2e36174b97f031e4c5 Mon Sep 17 00:00:00 2001 From: Lukasz Fundakowski Date: Sat, 9 Aug 2025 14:49:42 +0200 Subject: [PATCH 0278/1076] twister: Add configuration reader to pytest-twister-harness Added a class that helps to read Kconfigs from a configuration file. Signed-off-by: Lukasz Fundakowski --- .../src/twister_harness/fixtures.py | 27 ++++- .../twister_harness/helpers/config_reader.py | 103 ++++++++++++++++++ .../tests/helpers/test_config_reader.py | 81 ++++++++++++++ 3 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/config_reader.py create mode 100644 scripts/pylib/pytest-twister-harness/tests/helpers/test_config_reader.py diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py index d53d74b1be1d9..621b0defd71a1 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py @@ -4,7 +4,7 @@ import logging from pathlib import Path -from typing import Generator, Type +from typing import Generator, Type, Callable import pytest import time @@ -15,6 +15,7 @@ from twister_harness.helpers.shell import Shell from twister_harness.helpers.mcumgr import MCUmgr, MCUmgrBle from twister_harness.helpers.utils import find_in_config +from twister_harness.helpers.config_reader import ConfigReader logger = logging.getLogger(__name__) @@ -117,3 +118,27 @@ def mcumgr_ble(device_object: DeviceAdapter) -> Generator[MCUmgrBle, None, None] ) or 'Zephyr' yield MCUmgrBle.create_for_ble(hci_index, peer_name) + + +@pytest.fixture +def config_reader() -> Callable[[str | Path], ConfigReader]: + """ + Pytest fixture that provides a ConfigReader instance for reading configuration files. + + This fixture allows tests to easily create a ConfigReader object by passing + the path to a configuration file. The ConfigReader reads the file and + provides a method to access the configuration data. + + Returns: + Callable[[str, Path], ConfigReader]: A function that takes a file path + (as a string or Path object) and returns an instance of ConfigReader. + + Example: + def test_config_value(config_reader): + config = config_reader("build_dir/zephyr/.config") + assert config.read("some_key") == "expected_value" + """ + def inner(file): + return ConfigReader(file) + + return inner diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/config_reader.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/config_reader.py new file mode 100644 index 0000000000000..701a83982f0d1 --- /dev/null +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/config_reader.py @@ -0,0 +1,103 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +"""Implementation for a configuration file reader.""" + +import logging +import os +import re +from pathlib import Path +from typing import Any + +__tracebackhide__ = True + +logger = logging.getLogger(__name__) + + +class ConfigReader: + """Reads configuration from a config file.""" + + def __init__(self, config_file: Path | str) -> None: + """Initialize. + + :param config_file: path to a configuration file + """ + assert os.path.exists(config_file), f"Path does not exist: {config_file}" + assert os.path.isfile(config_file), f"It is not a file: {config_file}" + self.config_file = config_file + self.config: dict[str, str] = {} + self.parse() + + def parse(self) -> dict[str, str]: + """Parse a config file.""" + pattern = re.compile(r"^(?P.+)=(?P.+)$") + with open(self.config_file) as file: + for line in file: + if match := pattern.match(line): + key, value = match.group("key"), match.group("value") + self.config[key] = value.strip("\"'") + return self.config + + def read(self, config_key: str, default: Any = None, *, silent=False) -> str | None: + """Find key in config file. + + :param config_key: key to read + :param default: default value to return if key not found + :param silent: do not raise an exception when key not found + :raises ValueError: if key not found + """ + try: + value = self.config[config_key] + except KeyError: + if default is not None: + return default + logger.debug("Not found key: %s", config_key) + if silent: + return None + raise ValueError(f"Could not find key: {config_key}") from None + logger.debug("Found matching key: %s=%s", config_key, value) + return value + + def read_int(self, config_key: str, default: int | None = None) -> int: + """Find key in config file and return int. + + :param config_key: key to read + :param default: default value to return if key not found + """ + if default is not None and not isinstance(default, int): + raise TypeError(f"default value must be type of int, but was {type(default)}") + if default is not None: + default = hex(default) # type: ignore + if value := self.read(config_key, default): + try: + return int(value) + except ValueError: + return int(value, 16) + raise Exception("Non reachable code") # pragma: no cover + + def read_bool(self, config_key: str, default: bool | None = None) -> bool: + """Find key in config file and return bool. + + :param config_key: key to read + :param default: default value to return if key not found + """ + value = self.read(config_key, default) + if isinstance(value, str): + if value.lower() == "y": + return True + if value.lower() == "n": + return False + return bool(value) + + def read_hex(self, config_key: str, default: int | None = None) -> str: + """Find key in config file and return hex. + + :param config_key: key to read + :param default: default value to return if key not found + :return: hex value as string + """ + if default is not None and not isinstance(default, int): + raise TypeError(f"default value must be type of int, but was {type(default)}") + value = self.read_int(config_key, default) + return hex(value) diff --git a/scripts/pylib/pytest-twister-harness/tests/helpers/test_config_reader.py b/scripts/pylib/pytest-twister-harness/tests/helpers/test_config_reader.py new file mode 100644 index 0000000000000..81046b77b5702 --- /dev/null +++ b/scripts/pylib/pytest-twister-harness/tests/helpers/test_config_reader.py @@ -0,0 +1,81 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import textwrap + +import pytest +from twister_harness.helpers.config_reader import ConfigReader + +CONFIG: str = textwrap.dedent(""" + # comment + X_PM_MCUBOOT_OFFSET=0x0 + X_PM_MCUBOOT_END_ADDRESS=0xd800 + + X_PM_MCUBOOT_NAME=mcuboot + X_PM_MCUBOOT_ID=0 + X_CONFIG_BOOL_TRUE=y + X_CONFIG_BOOL_FALSE=n +""") + + +@pytest.fixture +def config_reader(tmp_path) -> ConfigReader: + config_file = tmp_path / "config" + config_file.write_text(CONFIG) + reader = ConfigReader(config_file) + return reader + + +def test_if_raises_exception_path_is_directory(tmp_path): + build_dir = tmp_path / "build" + build_dir.mkdir() + with pytest.raises(AssertionError, match=f"It is not a file: {build_dir}"): + ConfigReader(build_dir) + + +def test_if_raises_exception_when_path_does_not_exist(tmp_path): + build_dir = tmp_path / "build" + build_dir.mkdir() + config_file = build_dir / "file_does_not_exist" + with pytest.raises(AssertionError, match=f"Path does not exist: {config_file}"): + ConfigReader(config_file) + + +def test_if_can_read_values_from_config_file(config_reader): + assert config_reader.config, "Config is empty" + assert config_reader.read("X_PM_MCUBOOT_NAME") == "mcuboot" + assert config_reader.read("X_CONFIG_BOOL_TRUE") == "y" + assert config_reader.read_bool("X_CONFIG_BOOL_TRUE") is True + assert config_reader.read_bool("X_CONFIG_BOOL_FALSE") is False + assert config_reader.read_hex("X_PM_MCUBOOT_END_ADDRESS") == "0xd800" + assert config_reader.read_int("X_PM_MCUBOOT_END_ADDRESS") == 0xD800 + + +def test_if_raises_value_error_when_key_does_not_exist(config_reader): + with pytest.raises(ValueError, match="Could not find key: DO_NOT_EXIST"): + config_reader.read("DO_NOT_EXIST") + + with pytest.raises(ValueError, match="Could not find key: DO_NOT_EXIST"): + config_reader.read_int("DO_NOT_EXIST") + + +def test_if_raises_value_error_when_default_value_is_not_proper(config_reader): + with pytest.raises(TypeError, match="default value must be type of int, but was .*"): + config_reader.read_hex("X_PM_MCUBOOT_OFFSET", "0x10") + with pytest.raises(TypeError, match="default value must be type of int, but was .*"): + config_reader.read_int("X_PM_MCUBOOT_OFFSET", "0x10") + + +def test_if_returns_default_value_when_key_does_not_exist(config_reader): + assert config_reader.read("DO_NOT_EXIST", "default") == "default" + assert config_reader.read_int("DO_NOT_EXIST", 10) == 10 + assert config_reader.read_hex("DO_NOT_EXIST", 0x20) == "0x20" + assert config_reader.read_bool("DO_NOT_EXIST", True) is True + assert config_reader.read_bool("DO_NOT_EXIST", False) is False + assert config_reader.read_bool("DO_NOT_EXIST", 1) is True + assert config_reader.read_bool("DO_NOT_EXIST", "1") is True + + +def test_if_does_not_raise_exception_in_silent_mode_for_key_not_found(config_reader): + assert config_reader.read("DO_NOT_EXIST", silent=True) is None From f6f79f0c5b949ba18cacd1ef5c0f7e8247779636 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 22 Aug 2025 14:48:47 +0200 Subject: [PATCH 0279/1076] Bluetooth: Audio: Shell: Reduce memory usage of the shell Modify values in audio.conf to reduce memory usage. Most notably disabling logs reduced the FLASH requirements. Ideally the shell works as expected without debug logs, but there are far too many profiles and services to verify them all. All the log options are left in audio.conf so they can easily be re-enabled when needed. Memory before this change: Memory region Used Size Region Size %age Used FLASH: 1018512 B 1 MB 97.13% RAM: 423146 B 448 KB 92.24% IDT_LIST: 0 GB 32 KB 0.00% Memory after this change: Memory region Used Size Region Size %age Used FLASH: 791308 B 1 MB 75.47% RAM: 369090 B 448 KB 80.46% IDT_LIST: 0 GB 32 KB 0.00% Signed-off-by: Emil Gydesen --- tests/bluetooth/shell/audio.conf | 102 ++++++++++++++----------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index 4208bd7a56c99..bae871f97cb2c 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -65,7 +65,7 @@ CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y # Support an ISO channel per ASE CONFIG_BT_ISO_BROADCASTER=y CONFIG_BT_ISO_PERIPHERAL=y -CONFIG_BT_ISO_MAX_CHAN=4 +CONFIG_BT_ISO_MAX_CHAN=2 CONFIG_BT_ISO_TEST_PARAMS=y CONFIG_BT_ISO_TX_BUF_COUNT=10 CONFIG_BT_ISO_RX_BUF_COUNT=20 @@ -76,7 +76,7 @@ CONFIG_BT_AUDIO=y CONFIG_BT_BAP_UNICAST_SERVER=y CONFIG_BT_BAP_UNICAST_CLIENT=y -CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4 +CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2 @@ -89,12 +89,12 @@ CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 CONFIG_BT_PAC_SRC=y CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=2 CONFIG_BT_BAP_BROADCAST_SOURCE=y -CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=4 -CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=4 +CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=1 +CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2 CONFIG_BT_BAP_BROADCAST_SINK=y -CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 -CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=4 +CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=1 +CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 CONFIG_BT_VOCS_MAX_INSTANCE_COUNT=1 CONFIG_BT_VOCS_CLIENT_MAX_INSTANCE_COUNT=1 @@ -131,11 +131,6 @@ CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS=y CONFIG_BT_MPL=y CONFIG_BT_MPL_OBJECTS=y -# TODO Check which value is sensible in the line below -# Must be larger than any of the object sizes - icon, track, group, segments, ... -CONFIG_BT_MPL_MAX_OBJ_SIZE=600 -CONFIG_BT_MPL_ICON_BITMAP_SIZE=321 -CONFIG_BT_MPL_TRACK_MAX_SIZE=50 # Call Control CONFIG_BT_CCP_CALL_CONTROL_SERVER=y @@ -151,20 +146,17 @@ CONFIG_BT_TBS_CLIENT_GTBS=y CONFIG_BT_MCS=y CONFIG_BT_MCC=y CONFIG_BT_MCC_OTS=y -CONFIG_BT_MCC_TOTAL_OBJ_CONTENT_MEM=4096 CONFIG_UTF8=y # Object Transfer CONFIG_BT_OTS=y CONFIG_BT_OTS_SECONDARY_SVC=y -CONFIG_BT_OTS_MAX_OBJ_CNT=0x30 CONFIG_BT_OTS_CLIENT=y CONFIG_BT_BAP_SCAN_DELEGATOR=y -CONFIG_BT_BAP_BASS_MAX_SUBGROUPS=2 -CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=255 +CONFIG_BT_BAP_BASS_MAX_SUBGROUPS=1 CONFIG_BT_BAP_BROADCAST_ASSISTANT=y -CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT=4 +CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT=2 # IAS CONFIG_BT_IAS=y @@ -172,7 +164,7 @@ CONFIG_BT_IAS_CLIENT=y CONFIG_BT_HAS=y CONFIG_BT_HAS_PRESET_NAME_DYNAMIC=y -CONFIG_BT_HAS_PRESET_COUNT=4 +CONFIG_BT_HAS_PRESET_COUNT=2 CONFIG_BT_HAS_CLIENT=y CONFIG_BT_HAS_FEATURES_NOTIFIABLE=y @@ -202,44 +194,44 @@ CONFIG_BT_GMAP=y # DEBUGGING CONFIG_LOG=y -CONFIG_BT_AUDIO_LOG_LEVEL_DBG=y -CONFIG_BT_MPL_LOG_LEVEL_DBG=y -CONFIG_BT_MCS_LOG_LEVEL_DBG=y -CONFIG_BT_MCC_LOG_LEVEL_DBG=y -CONFIG_BT_OTS_LOG_LEVEL_DBG=y -CONFIG_BT_OTS_CLIENT_LOG_LEVEL_DBG=y -CONFIG_MCTL_LOG_LEVEL_DBG=y -CONFIG_BT_ASCS_LOG_LEVEL_DBG=y -CONFIG_BT_PACS_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_UNICAST_SERVER_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_UNICAST_CLIENT_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_BROADCAST_SOURCE_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_BROADCAST_SINK_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_BROADCAST_ASSISTANT_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL_DBG=y -CONFIG_BT_HAS_LOG_LEVEL_DBG=y -CONFIG_BT_HAS_CLIENT_LOG_LEVEL_DBG=y -CONFIG_BT_TBS_LOG_LEVEL_DBG=y -CONFIG_BT_TBS_CLIENT_LOG_LEVEL_DBG=y -CONFIG_BT_VCP_VOL_CTLR_LOG_LEVEL_DBG=y -CONFIG_BT_VCP_VOL_REND_LOG_LEVEL_DBG=y -CONFIG_BT_MICP_MIC_CTLR_LOG_LEVEL_DBG=y -CONFIG_BT_MICP_MIC_DEV_LOG_LEVEL_DBG=y -CONFIG_BT_AICS_CLIENT_LOG_LEVEL_DBG=y -CONFIG_BT_VOCS_CLIENT_LOG_LEVEL_DBG=y -CONFIG_BT_AICS_LOG_LEVEL_DBG=y -CONFIG_BT_VOCS_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_STREAM_LOG_LEVEL_DBG=y -CONFIG_BT_BAP_ISO_LOG_LEVEL_DBG=y -CONFIG_BT_AUDIO_CODEC_LOG_LEVEL_DBG=y -CONFIG_BT_CSIP_SET_COORDINATOR_LOG_LEVEL_DBG=y -CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL_DBG=y -CONFIG_BT_CAP_ACCEPTOR_LOG_LEVEL_DBG=y -CONFIG_BT_CAP_INITIATOR_LOG_LEVEL_DBG=y -CONFIG_BT_CAP_COMMANDER_LOG_LEVEL_DBG=y -CONFIG_BT_CAP_COMMON_LOG_LEVEL_DBG=y -CONFIG_BT_TMAP_LOG_LEVEL_DBG=y -CONFIG_BT_GMAP_LOG_LEVEL_DBG=y +# CONFIG_BT_AUDIO_LOG_LEVEL_DBG=y +# CONFIG_BT_AUDIO_CODEC_LOG_LEVEL_DBG=y +# CONFIG_BT_AICS_LOG_LEVEL_DBG=y +# CONFIG_BT_AICS_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_ASCS_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_BROADCAST_SOURCE_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_BROADCAST_SINK_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_BROADCAST_ASSISTANT_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_ISO_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_STREAM_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_UNICAST_SERVER_LOG_LEVEL_DBG=y +# CONFIG_BT_BAP_UNICAST_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_CAP_ACCEPTOR_LOG_LEVEL_DBG=y +# CONFIG_BT_CAP_COMMANDER_LOG_LEVEL_DBG=y +# CONFIG_BT_CAP_COMMON_LOG_LEVEL_DBG=y +# CONFIG_BT_CAP_INITIATOR_LOG_LEVEL_DBG=y +# CONFIG_BT_CSIP_SET_COORDINATOR_LOG_LEVEL_DBG=y +# CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL_DBG=y +# CONFIG_BT_GMAP_LOG_LEVEL_DBG=y +# CONFIG_BT_HAS_LOG_LEVEL_DBG=y +# CONFIG_BT_HAS_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_MCS_LOG_LEVEL_DBG=y +# CONFIG_BT_MCC_LOG_LEVEL_DBG=y +# CONFIG_BT_MICP_MIC_CTLR_LOG_LEVEL_DBG=y +# CONFIG_BT_MICP_MIC_DEV_LOG_LEVEL_DBG=y +# CONFIG_BT_MPL_LOG_LEVEL_DBG=y +# CONFIG_BT_OTS_LOG_LEVEL_DBG=y +# CONFIG_BT_OTS_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_PACS_LOG_LEVEL_DBG=y +# CONFIG_BT_TBS_LOG_LEVEL_DBG=y +# CONFIG_BT_TBS_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_TMAP_LOG_LEVEL_DBG=y +# CONFIG_BT_VCP_VOL_CTLR_LOG_LEVEL_DBG=y +# CONFIG_BT_VCP_VOL_REND_LOG_LEVEL_DBG=y +# CONFIG_BT_VOCS_CLIENT_LOG_LEVEL_DBG=y +# CONFIG_BT_VOCS_LOG_LEVEL_DBG=y +# CONFIG_MCTL_LOG_LEVEL_DBG=y # Controller settings CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 From 506e95325d0cdd353f84d505f69c1509e3c2f6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 23:02:35 +0200 Subject: [PATCH 0280/1076] include: can: re-organize doxygen groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit group controller and transceiver API under a common umbrella Signed-off-by: Benjamin Cabé --- doc/hardware/peripherals/can/controller.rst | 2 +- include/zephyr/drivers/can.h | 14 ++++++++++---- include/zephyr/drivers/can/transceiver.h | 10 ++++++++-- samples/drivers/can/babbling/README.rst | 2 +- samples/drivers/can/counter/README.rst | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/hardware/peripherals/can/controller.rst b/doc/hardware/peripherals/can/controller.rst index 99cda14a36196..4eba0e1a73460 100644 --- a/doc/hardware/peripherals/can/controller.rst +++ b/doc/hardware/peripherals/can/controller.rst @@ -317,4 +317,4 @@ We have two ready-to-build samples demonstrating use of the Zephyr CAN API: CAN Controller API Reference **************************** -.. doxygengroup:: can_interface +.. doxygengroup:: can_controller diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index edebeed3fff41..e4109cc63685f 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -8,7 +8,8 @@ /** * @file - * @brief Controller Area Network (CAN) driver API. + * @brief Main header file for Controller Area Network (CAN) driver API. + * @ingroup can_controller */ #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_H_ @@ -28,11 +29,16 @@ extern "C" { #endif /** - * @brief CAN Interface - * @defgroup can_interface CAN Interface + * @brief Interfaces for Controller Area Network (CAN) controllers and transceivers + * @defgroup can_interface CAN + * @ingroup io_interfaces + * + * @defgroup can_controller CAN Controller + * @brief Interfaces for CAN controllers + * @ingroup can_interface * @since 1.12 * @version 1.1.0 - * @ingroup io_interfaces + * * @{ */ diff --git a/include/zephyr/drivers/can/transceiver.h b/include/zephyr/drivers/can/transceiver.h index 9dcf2cafb6c67..67542701101e5 100644 --- a/include/zephyr/drivers/can/transceiver.h +++ b/include/zephyr/drivers/can/transceiver.h @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @ingroup can_transceiver + * @brief Header file for CAN transceiver driver API + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_TRANSCEIVER_H_ #define ZEPHYR_INCLUDE_DRIVERS_CAN_TRANSCEIVER_H_ @@ -15,11 +21,11 @@ extern "C" { #endif /** - * @brief CAN Transceiver Driver APIs + * @brief Interfaces for CAN transceivers * @defgroup can_transceiver CAN Transceiver * @since 3.1 * @version 0.1.0 - * @ingroup io_interfaces + * @ingroup can_interface * @{ */ diff --git a/samples/drivers/can/babbling/README.rst b/samples/drivers/can/babbling/README.rst index 8a0f6e55ac7e1..68e55227b397f 100644 --- a/samples/drivers/can/babbling/README.rst +++ b/samples/drivers/can/babbling/README.rst @@ -1,6 +1,6 @@ .. zephyr:code-sample:: can-babbling :name: Controller Area Network (CAN) babbling node - :relevant-api: can_interface + :relevant-api: can_controller Simulate a babbling CAN node. diff --git a/samples/drivers/can/counter/README.rst b/samples/drivers/can/counter/README.rst index 3b66661a714e3..db07d554e2877 100644 --- a/samples/drivers/can/counter/README.rst +++ b/samples/drivers/can/counter/README.rst @@ -1,6 +1,6 @@ .. zephyr:code-sample:: can-counter :name: Controller Area Network (CAN) counter - :relevant-api: can_interface + :relevant-api: can_controller Send and receive CAN messages. From aa7d79488be4836aafa443c4574ba364688321f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 21 Aug 2025 17:24:26 +0200 Subject: [PATCH 0281/1076] include: drivers: comparator: add doxygen doc to comparator_callback_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While reasonably straightforward, ensure the signature of the comparator_callback_t is properly documented. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/comparator.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/comparator.h b/include/zephyr/drivers/comparator.h index 1a6609cafa5b1..083609153e692 100644 --- a/include/zephyr/drivers/comparator.h +++ b/include/zephyr/drivers/comparator.h @@ -35,7 +35,12 @@ enum comparator_trigger { COMPARATOR_TRIGGER_BOTH_EDGES }; -/** Comparator callback template */ +/** + * @brief Comparator callback template + * + * @param dev Comparator device + * @param user_data Pointer to the user data that was provided when the trigger callback was set + */ typedef void (*comparator_callback_t)(const struct device *dev, void *user_data); /** @cond INTERNAL_HIDDEN */ From 5ca4ff8bb511912375d0666657a7f739bca4ca85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 23 Jul 2025 15:00:21 +0200 Subject: [PATCH 0282/1076] include: drivers: fpga: add doxygen group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add doxygen group for FPGA driver API Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/fpga.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/zephyr/drivers/fpga.h b/include/zephyr/drivers/fpga.h index 61e9c1cf0dda4..7e4c5ecf233e9 100644 --- a/include/zephyr/drivers/fpga.h +++ b/include/zephyr/drivers/fpga.h @@ -17,6 +17,14 @@ extern "C" { #endif +/** + * @defgroup fpga_interface FPGA Interface. + * @since 2.7 + * @version 0.1.0 + * @ingroup io_interfaces + * @{ + */ + enum FPGA_status { /* Inactive is when the FPGA cannot accept the bitstream * and will not be programmed correctly @@ -172,6 +180,8 @@ static inline int fpga_off(const struct device *dev) return api->off(dev); } +/** @} */ + #ifdef __cplusplus } #endif From b50c314b07ecf89d054a62aa32359445912300c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 16:37:38 +0200 Subject: [PATCH 0283/1076] include: drivers: sensor: enhance Doxygen documentation for PAT9136 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the Doxygen documentation for this sensor driver, put in sensor_interface_ext group. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/sensor/pat9136.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/sensor/pat9136.h b/include/zephyr/drivers/sensor/pat9136.h index a88de369d76de..41b1cd37157ca 100644 --- a/include/zephyr/drivers/sensor/pat9136.h +++ b/include/zephyr/drivers/sensor/pat9136.h @@ -5,16 +5,32 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended sensor API of PAT9136 sensor + * @ingroup pat9136_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_PAT9136_H_ #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_PAT9136_H_ +/** + * @brief Pixart PAT9136 optical flow sensor + * @defgroup pat9136_interface PAT9136 + * @ingroup sensor_interface_ext + * @{ + */ + #include #ifdef __cplusplus extern "C" { #endif -/** This sensor does have the ability to provide DXY in meaningful units, and +/** + * Custom sensor channels for PAT9136 + * + * This sensor does have the ability to provide DXY in meaningful units, and * since the standard channels' unit is in points (SENSOR_CHAN_POS_DX, * SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DXYZ), we've captured the following * channels to provide an alternative for this sensor. @@ -35,4 +51,8 @@ enum sensor_channel_pat9136 { } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_PAT9136_H_ */ From 2ed0d0d44dd2e8a81096951d5197a2d5f1b370b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 16:37:48 +0200 Subject: [PATCH 0284/1076] include: drivers: sensor: enhance Doxygen documentation for FDC2X1X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the Doxygen documentation for this sensor driver, put in sensor_interface_ext group. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/sensor/fdc2x1x.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/include/zephyr/drivers/sensor/fdc2x1x.h b/include/zephyr/drivers/sensor/fdc2x1x.h index 0dc33b118dea0..ebb37e1c3f68b 100644 --- a/include/zephyr/drivers/sensor/fdc2x1x.h +++ b/include/zephyr/drivers/sensor/fdc2x1x.h @@ -6,26 +6,37 @@ /** * @file - * @brief Extended public API for the Texas Instruments FDC2X1X + * @brief Header file for extended sensor API of FDC2X1X sensor + * @ingroup fdc2x1x_interface */ #ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_H_ #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_H_ +/** + * @brief Texas Instruments FDC2X1X capacitive sensor + * @defgroup fdc2x1x_interface FDC2X1X + * @ingroup sensor_interface_ext + * @{ + */ + #ifdef __cplusplus extern "C" { #endif #include +/** + * Custom sensor channels for FDC2X1X + */ enum sensor_channel_fdc2x1x { - /** CH0 Capacitance, in Picofarad **/ + /** CH0 Capacitance, in picofarad **/ SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH0 = SENSOR_CHAN_PRIV_START, - /** CH1 Capacitance, in Picofarad **/ + /** CH1 Capacitance, in picofarad **/ SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH1, - /** CH2 Capacitance, in Picofarad **/ + /** CH2 Capacitance, in picofarad **/ SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH2, - /** CH3 Capacitance, in Picofarad **/ + /** CH3 Capacitance, in picofarad **/ SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH3, /** CH0 Frequency, in MHz **/ @@ -42,4 +53,8 @@ enum sensor_channel_fdc2x1x { } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_ */ From f5cc5d857c4fd5c9ad8a7d16cf4919283c5f284b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Aug 2025 16:47:36 +0200 Subject: [PATCH 0285/1076] include: drivers: sensor: add missing doxygen for sensor_channel_afbr_s50 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure enum has a doxygen documentation Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/sensor/afbr_s50.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/zephyr/drivers/sensor/afbr_s50.h b/include/zephyr/drivers/sensor/afbr_s50.h index 39a8a428df059..5682bf08486cc 100644 --- a/include/zephyr/drivers/sensor/afbr_s50.h +++ b/include/zephyr/drivers/sensor/afbr_s50.h @@ -30,6 +30,9 @@ extern "C" { /** Disregard pixel reading if contains this value */ #define AFBR_PIXEL_INVALID_VALUE 0x80000000 +/** + * Custom sensor channels for AFBR-S50 + */ enum sensor_channel_afbr_s50 { /** * Obtain matrix of pixels, with readings in meters. From 1c5cfc3ad4d344108f246e23abd1a6c2fcce2723 Mon Sep 17 00:00:00 2001 From: Lukasz Fundakowski Date: Wed, 27 Aug 2025 11:25:47 +0200 Subject: [PATCH 0286/1076] ci: fix github actions for twister blackbox tests Twister blackbox tests are not executed on CI. This change fixes the problem. Signed-off-by: Lukasz Fundakowski --- .github/workflows/twister_tests_blackbox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 5590016e922ec..798135fd84c1f 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -51,7 +51,7 @@ jobs: toolchains: all - name: Run Pytest For Twister Black Box Tests - if: ${{ startsWith(runner.os, 'ubuntu') }} + if: ${{ runner.os == 'Linux' }} working-directory: zephyr shell: bash env: From d0675936dad3e19a7e6c63500814e2d1dc1c89ca Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 30 Aug 2025 06:36:09 -0400 Subject: [PATCH 0287/1076] twister: tests: fix failing blackbox tests Few tests failing and were not caught due to CI not running. Signed-off-by: Anas Nashif --- .../tests/seed_native_sim/dummy/prj.conf | 1 + scripts/tests/twister_blackbox/test_device.py | 2 +- scripts/tests/twister_blackbox/test_error.py | 4 ++-- .../tests/twister_blackbox/test_outfile.py | 4 ++-- .../tests/twister_blackbox/test_quarantine.py | 21 +++++++------------ scripts/tests/twister_blackbox/test_runner.py | 2 +- .../tests/twister_blackbox/test_testplan.py | 3 ++- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/scripts/tests/twister_blackbox/test_data/tests/seed_native_sim/dummy/prj.conf b/scripts/tests/twister_blackbox/test_data/tests/seed_native_sim/dummy/prj.conf index 9467c2926896d..d25c9c7d100a2 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/seed_native_sim/dummy/prj.conf +++ b/scripts/tests/twister_blackbox/test_data/tests/seed_native_sim/dummy/prj.conf @@ -1 +1,2 @@ CONFIG_ZTEST=y +CONFIG_ENTROPY_GENERATOR=y diff --git a/scripts/tests/twister_blackbox/test_device.py b/scripts/tests/twister_blackbox/test_device.py index c35daa337e49a..9dfdb963478b4 100644 --- a/scripts/tests/twister_blackbox/test_device.py +++ b/scripts/tests/twister_blackbox/test_device.py @@ -56,7 +56,7 @@ def teardown_class(cls): def test_seed(self, capfd, out_path, seed): test_platforms = ['native_sim'] path = os.path.join(TEST_DATA, 'tests', 'seed_native_sim') - args = ['--outdir', out_path, '-i', '-T', path, '-vv',] + \ + args = ['--detailed-test-id', '--outdir', out_path, '-i', '-T', path, '-vv',] + \ ['--seed', f'{seed[0]}'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms diff --git a/scripts/tests/twister_blackbox/test_error.py b/scripts/tests/twister_blackbox/test_error.py index 93d589fefdfce..7235276cd336b 100644 --- a/scripts/tests/twister_blackbox/test_error.py +++ b/scripts/tests/twister_blackbox/test_error.py @@ -72,7 +72,7 @@ def test_test(self, out_path, testroot, test, expected_exception): args = [] if testroot: args = ['-T', testroot] - args += ['-i', '--outdir', out_path, '--test', test, '-y'] + \ + args += ['--detailed-test-id', '-i', '--outdir', out_path, '--test', test, '-y'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms ) for val in pair] @@ -98,7 +98,7 @@ def test_test(self, out_path, testroot, test, expected_exception): def test_overflow_as_errors(self, capfd, out_path, switch, expected): path = os.path.join(TEST_DATA, 'tests', 'qemu_overflow') test_platforms = ['qemu_x86'] - args = ['--outdir', out_path, '-T', path, '-vv'] + \ + args = ['--detailed-test-id', '--outdir', out_path, '-T', path, '-vv'] + \ ['--build-only'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms diff --git a/scripts/tests/twister_blackbox/test_outfile.py b/scripts/tests/twister_blackbox/test_outfile.py index bdaa5d3291d85..79e970fbe587e 100644 --- a/scripts/tests/twister_blackbox/test_outfile.py +++ b/scripts/tests/twister_blackbox/test_outfile.py @@ -207,7 +207,7 @@ def test_package_artifacts(self, out_path): path = os.path.join(TEST_DATA, 'samples', 'hello_world') package_name = 'PACKAGE' package_path = os.path.join(out_path, package_name) - args = ['-i', '--outdir', out_path, '-T', path] + \ + args = ['--detailed-test-id','-i', '--outdir', out_path, '-T', path] + \ ['--package-artifacts', package_path] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms @@ -242,7 +242,7 @@ def test_package_artifacts(self, out_path): for file_name in file_names: shutil.move(os.path.join(out_path, os.path.basename(out_path), file_name), out_path) - args = ['-i', '--outdir', out_path, '-T', path] + \ + args = ['--detailed-test-id', '-i', '--outdir', out_path, '-T', path] + \ ['--test-only'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms diff --git a/scripts/tests/twister_blackbox/test_quarantine.py b/scripts/tests/twister_blackbox/test_quarantine.py index c2b6a183266c6..4c3cc492cb6f7 100644 --- a/scripts/tests/twister_blackbox/test_quarantine.py +++ b/scripts/tests/twister_blackbox/test_quarantine.py @@ -80,7 +80,7 @@ def test_quarantine_verify(self, out_path): ) @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) def test_quarantine_list(self, capfd, out_path, test_path, test_platforms, quarantine_directory): - args = ['--outdir', out_path, '-T', test_path] +\ + args = ['--detailed-test-id', '--outdir', out_path, '-T', test_path] +\ ['--quarantine-list', quarantine_directory] + \ ['-vv', '-ll', 'DEBUG'] + \ [val for pair in zip( @@ -95,27 +95,22 @@ def test_quarantine_list(self, capfd, out_path, test_path, test_platforms, quara sys.stdout.write(out) sys.stderr.write(err) - board1_match1 = re.search('agnostic/group2/dummy.agnostic.group2 SKIPPED: Quarantine: test ' - 'intel_adl_crb', err) + board1_match1 = re.search('agnostic/group2/dummy.agnostic.group2 SKIPPED: Quarantined', + err) board1_match2 = re.search( - 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantine: test ' - 'intel_adl_crb', + 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantined', err) qemu_64_match = re.search( - 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantine: test ' - 'qemu_x86_64', + 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantined', err) all_platforms_match = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' - 'all platforms', + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantined', err) all_platforms_match2 = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' - 'all platforms', + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantined', err) all_platforms_match3 = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' - 'all platforms', + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantined', err) assert board1_match1 and board1_match2, 'platform quarantine not working properly' diff --git a/scripts/tests/twister_blackbox/test_runner.py b/scripts/tests/twister_blackbox/test_runner.py index 09286663475be..b15d9f3231285 100644 --- a/scripts/tests/twister_blackbox/test_runner.py +++ b/scripts/tests/twister_blackbox/test_runner.py @@ -573,7 +573,7 @@ def test_timeout_multiplier(self, capfd, out_path, test_path, test_platforms, ti ], ) def test_tag(self, capfd, out_path, test_path, test_platforms, tags, expected): - args = ['--outdir', out_path, '-T', test_path, '-vv', '-ll', 'DEBUG'] + \ + args = ['--detailed-test-id', '--outdir', out_path, '-T', test_path, '-vv', '-ll', 'DEBUG'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms ) for val in pair] + \ diff --git a/scripts/tests/twister_blackbox/test_testplan.py b/scripts/tests/twister_blackbox/test_testplan.py index 701acf94ddf21..898fbcd53a057 100644 --- a/scripts/tests/twister_blackbox/test_testplan.py +++ b/scripts/tests/twister_blackbox/test_testplan.py @@ -59,7 +59,8 @@ def teardown_class(cls): def test_subtest(self, out_path, test, expected_exception, expected_subtest_count): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') - args = ['-i', '--outdir', out_path, '-T', path, '--sub-test', test, '-y'] + \ + args = ['--detailed-test-id', + '-i', '--outdir', out_path, '-T', path, '--sub-test', test, '-y'] + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms ) for val in pair] From d175b5005d2f2348c85b2161e028537511ce345e Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 30 Aug 2025 08:09:57 -0400 Subject: [PATCH 0288/1076] twister: tests: resolve warning about function being uncallable Get rid of warnings about uncallable functions due to variable names having test prefix. Signed-off-by: Anas Nashif --- doc/develop/test/twister/sample_blackbox_test.py | 4 ++-- doc/develop/test/twister/twister_blackbox.rst | 2 +- scripts/tests/twister_blackbox/conftest.py | 2 +- scripts/tests/twister_blackbox/test_addon.py | 16 ++++++++-------- scripts/tests/twister_blackbox/test_config.py | 6 +++--- scripts/tests/twister_blackbox/test_coverage.py | 4 ++-- scripts/tests/twister_blackbox/test_device.py | 4 ++-- scripts/tests/twister_blackbox/test_disable.py | 4 ++-- scripts/tests/twister_blackbox/test_error.py | 6 +++--- scripts/tests/twister_blackbox/test_filter.py | 14 +++++++------- scripts/tests/twister_blackbox/test_footprint.py | 4 ++-- .../tests/twister_blackbox/test_hardwaremap.py | 4 ++-- scripts/tests/twister_blackbox/test_outfile.py | 4 ++-- scripts/tests/twister_blackbox/test_output.py | 4 ++-- scripts/tests/twister_blackbox/test_platform.py | 4 ++-- scripts/tests/twister_blackbox/test_printouts.py | 4 ++-- .../tests/twister_blackbox/test_quarantine.py | 6 +++--- scripts/tests/twister_blackbox/test_report.py | 4 ++-- scripts/tests/twister_blackbox/test_runner.py | 4 ++-- scripts/tests/twister_blackbox/test_shuffle.py | 4 ++-- scripts/tests/twister_blackbox/test_testlist.py | 4 ++-- scripts/tests/twister_blackbox/test_testplan.py | 8 ++++---- scripts/tests/twister_blackbox/test_tooling.py | 6 +++--- 23 files changed, 61 insertions(+), 61 deletions(-) diff --git a/doc/develop/test/twister/sample_blackbox_test.py b/doc/develop/test/twister/sample_blackbox_test.py index c391669f88928..346ba34d000ef 100644 --- a/doc/develop/test/twister/sample_blackbox_test.py +++ b/doc/develop/test/twister/sample_blackbox_test.py @@ -10,7 +10,7 @@ from unittest import mock import pytest -from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock +from conftest import TEST_DATA, ZEPHYR_BASE, suite_filename_mock from twisterlib.testplan import TestPlan @@ -34,7 +34,7 @@ def teardown_class(cls): @pytest.mark.parametrize( "level, expected_tests", TESTDATA_X, ids=["smoke", "acceptance"] ) - @mock.patch.object(TestPlan, "TESTSUITE_FILENAME", testsuite_filename_mock) + @mock.patch.object(TestPlan, "TESTSUITE_FILENAME", suite_filename_mock) def test_level(self, capfd, out_path, level, expected_tests): # Select platforms used for the tests test_platforms = ["qemu_x86", "frdm_k64f"] diff --git a/doc/develop/test/twister/twister_blackbox.rst b/doc/develop/test/twister/twister_blackbox.rst index fc6231fb90dd5..f40cd40a7e9b0 100644 --- a/doc/develop/test/twister/twister_blackbox.rst +++ b/doc/develop/test/twister/twister_blackbox.rst @@ -63,7 +63,7 @@ Decorators - this is an example of ``pytest`` 's test parametrization. Read up on it `here `__. TESTDATAs are most often declared as class fields. -* ``@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock)`` +* ``@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock)`` - this decorator allows us to use only tests defined in the ``test_data`` and ignore the Zephyr testcases in the ``tests`` directory. **Note that all ``test_data`` tests use** ``test_data.yaml`` **as a filename, not** ``testcase.yaml`` **!** diff --git a/scripts/tests/twister_blackbox/conftest.py b/scripts/tests/twister_blackbox/conftest.py index 615e2f986b773..82897c4fa1cf3 100644 --- a/scripts/tests/twister_blackbox/conftest.py +++ b/scripts/tests/twister_blackbox/conftest.py @@ -24,7 +24,7 @@ sample_filename_mock = mock.PropertyMock(return_value='test_sample.yaml') -testsuite_filename_mock = mock.PropertyMock(return_value='test_data.yaml') +suite_filename_mock = mock.PropertyMock(return_value='test_data.yaml') sample_filename_mock = mock.PropertyMock(return_value='test_sample.yaml') def pytest_configure(config): diff --git a/scripts/tests/twister_blackbox/test_addon.py b/scripts/tests/twister_blackbox/test_addon.py index bb7fe84b6b88e..2ac6ea947b46f 100644 --- a/scripts/tests/twister_blackbox/test_addon.py +++ b/scripts/tests/twister_blackbox/test_addon.py @@ -17,7 +17,7 @@ import sys # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, suite_filename_mock from twisterlib.testplan import TestPlan @@ -43,7 +43,7 @@ def teardown_class(cls): ], ids=['no sanitiser', 'ubsan'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_ubsan(self, out_path, ubsan_flags, expected_exit_value): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'san', 'ubsan') @@ -70,7 +70,7 @@ def test_enable_ubsan(self, out_path, ubsan_flags, expected_exit_value): ], ids=['no sanitiser', 'lsan'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_lsan(self, out_path, lsan_flags, expected_exit_value): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'san', 'lsan') @@ -103,7 +103,7 @@ def test_enable_lsan(self, out_path, lsan_flags, expected_exit_value): 'asan' ] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_asan(self, capfd, out_path, asan_flags, expected_exit_value, expect_asan): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'san', 'asan') @@ -127,7 +127,7 @@ def test_enable_asan(self, capfd, out_path, asan_flags, expected_exit_value, exp asan_template = r'^==\d+==ERROR:\s+AddressSanitizer:' assert expect_asan == bool(re.search(asan_template, err, re.MULTILINE)) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_extra_test_args(self, capfd, out_path): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'params', 'dummy') @@ -158,7 +158,7 @@ def test_extra_test_args(self, capfd, out_path): ] assert all([testname in err for testname in expected_test_names]) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_extra_args(self, caplog, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic', 'group2') @@ -293,7 +293,7 @@ def refresh_plugin_installed_variable(): assert all([log in caplog.text for log in expected_logs]) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_pytest_args(self, out_path): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'pytest') @@ -322,7 +322,7 @@ def test_pytest_args(self, out_path): ], ids=['no valgrind', 'valgrind'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_valgrind(self, capfd, out_path, valgrind_flags, expected_exit_value): test_platforms = ['native_sim'] test_path = os.path.join(TEST_DATA, 'tests', 'san', 'val') diff --git a/scripts/tests/twister_blackbox/test_config.py b/scripts/tests/twister_blackbox/test_config.py index 1b34e637ff47b..e392788275e56 100644 --- a/scripts/tests/twister_blackbox/test_config.py +++ b/scripts/tests/twister_blackbox/test_config.py @@ -14,7 +14,7 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan @@ -30,7 +30,7 @@ def setup_class(cls): def teardown_class(cls): pass - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_alt_config_root(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') @@ -66,7 +66,7 @@ def test_alt_config_root(self, out_path): ], ids=['smoke', 'acceptance'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_level(self, out_path, level, expected_tests): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') diff --git a/scripts/tests/twister_blackbox/test_coverage.py b/scripts/tests/twister_blackbox/test_coverage.py index c1f85c05057bb..54c96d8a22dcd 100644 --- a/scripts/tests/twister_blackbox/test_coverage.py +++ b/scripts/tests/twister_blackbox/test_coverage.py @@ -14,11 +14,11 @@ import json # pylint: disable=duplicate-code, disable=no-name-in-module -from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock, clear_log_in_test +from conftest import TEST_DATA, ZEPHYR_BASE, suite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestCoverage: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_device.py b/scripts/tests/twister_blackbox/test_device.py index 9dfdb963478b4..2e117981c0eef 100644 --- a/scripts/tests/twister_blackbox/test_device.py +++ b/scripts/tests/twister_blackbox/test_device.py @@ -14,7 +14,7 @@ import re # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan @@ -52,7 +52,7 @@ def teardown_class(cls): ], ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_seed(self, capfd, out_path, seed): test_platforms = ['native_sim'] path = os.path.join(TEST_DATA, 'tests', 'seed_native_sim') diff --git a/scripts/tests/twister_blackbox/test_disable.py b/scripts/tests/twister_blackbox/test_disable.py index 3cbc7d314289f..f3689ab0cb23e 100644 --- a/scripts/tests/twister_blackbox/test_disable.py +++ b/scripts/tests/twister_blackbox/test_disable.py @@ -14,11 +14,11 @@ import re # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestDisable: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_error.py b/scripts/tests/twister_blackbox/test_error.py index 7235276cd336b..a15b3b5129cf9 100644 --- a/scripts/tests/twister_blackbox/test_error.py +++ b/scripts/tests/twister_blackbox/test_error.py @@ -14,7 +14,7 @@ import re # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan from twisterlib.error import TwisterRuntimeError @@ -66,7 +66,7 @@ def teardown_class(cls): TESTDATA_1, ids=['valid', 'invalid', 'valid'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_test(self, out_path, testroot, test, expected_exception): test_platforms = ['qemu_x86', 'intel_adl_crb'] args = [] @@ -94,7 +94,7 @@ def test_test(self, out_path, testroot, test, expected_exception): ], ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_overflow_as_errors(self, capfd, out_path, switch, expected): path = os.path.join(TEST_DATA, 'tests', 'qemu_overflow') test_platforms = ['qemu_x86'] diff --git a/scripts/tests/twister_blackbox/test_filter.py b/scripts/tests/twister_blackbox/test_filter.py index c65dda1604c32..acc3910547783 100644 --- a/scripts/tests/twister_blackbox/test_filter.py +++ b/scripts/tests/twister_blackbox/test_filter.py @@ -15,7 +15,7 @@ import re # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan @@ -95,7 +95,7 @@ def teardown_class(cls): ], ids=['no device, no cpp', 'no agnostic'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_exclude_tag(self, out_path, tags, expected_test_count): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') @@ -123,7 +123,7 @@ def test_exclude_tag(self, out_path, tags, expected_test_count): assert str(sys_exit.value) == '0' - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_slow(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic') @@ -151,7 +151,7 @@ def test_enable_slow(self, out_path): assert len(filtered_j) == 6 - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_enable_slow_only(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic') @@ -189,7 +189,7 @@ def test_enable_slow_only(self, out_path): ], ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_arch(self, capfd, out_path, arch, expected): path = os.path.join(TEST_DATA, 'tests', 'no_filter') test_platforms = ['qemu_x86', 'hsdk', 'intel_adl_crb', 'it8xxx2_evb'] @@ -223,7 +223,7 @@ def test_arch(self, capfd, out_path, arch, expected): ], ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_vendor(self, capfd, out_path, vendor, expected): path = os.path.join(TEST_DATA, 'tests', 'no_filter') test_platforms = ['qemu_x86', 'hsdk', 'intel_adl_crb', 'it8xxx2_evb'] @@ -254,7 +254,7 @@ def test_vendor(self, capfd, out_path, vendor, expected): ], ids=['ignore_platform_key', 'without ignore_platform_key'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_ignore_platform_key(self, out_path, flag, expected_test_count): test_platforms = ['qemu_x86', 'qemu_x86_64'] path = os.path.join(TEST_DATA, 'tests', 'platform_key') diff --git a/scripts/tests/twister_blackbox/test_footprint.py b/scripts/tests/twister_blackbox/test_footprint.py index b9e072a266617..863a139770352 100644 --- a/scripts/tests/twister_blackbox/test_footprint.py +++ b/scripts/tests/twister_blackbox/test_footprint.py @@ -15,12 +15,12 @@ import re # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock, clear_log_in_test +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock, clear_log_in_test from twisterlib.statuses import TwisterStatus from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestFootprint: # Log printed when entering delta calculations FOOTPRINT_LOG = 'running footprint_reports' diff --git a/scripts/tests/twister_blackbox/test_hardwaremap.py b/scripts/tests/twister_blackbox/test_hardwaremap.py index ce3493415a9dc..01bab62313e01 100644 --- a/scripts/tests/twister_blackbox/test_hardwaremap.py +++ b/scripts/tests/twister_blackbox/test_hardwaremap.py @@ -12,12 +12,12 @@ import sys # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, testsuite_filename_mock, clear_log_in_test +from conftest import ZEPHYR_BASE, suite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister/twisterlib")) -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestHardwaremap: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_outfile.py b/scripts/tests/twister_blackbox/test_outfile.py index 79e970fbe587e..8046db3b755e3 100644 --- a/scripts/tests/twister_blackbox/test_outfile.py +++ b/scripts/tests/twister_blackbox/test_outfile.py @@ -16,11 +16,11 @@ import tarfile # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, suite_filename_mock from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) @mock.patch.object(TestPlan, 'SAMPLE_FILENAME', sample_filename_mock) class TestOutfile: @classmethod diff --git a/scripts/tests/twister_blackbox/test_output.py b/scripts/tests/twister_blackbox/test_output.py index c6a77020638ba..6535a342d749e 100644 --- a/scripts/tests/twister_blackbox/test_output.py +++ b/scripts/tests/twister_blackbox/test_output.py @@ -15,11 +15,11 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock, clear_log_in_test +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestOutput: TESTDATA_1 = [ ([]), diff --git a/scripts/tests/twister_blackbox/test_platform.py b/scripts/tests/twister_blackbox/test_platform.py index 33239d5fcc02e..d06598b6aacd8 100644 --- a/scripts/tests/twister_blackbox/test_platform.py +++ b/scripts/tests/twister_blackbox/test_platform.py @@ -15,11 +15,11 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestPlatform: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_printouts.py b/scripts/tests/twister_blackbox/test_printouts.py index f383fe09744c2..cf35c4683bdf9 100644 --- a/scripts/tests/twister_blackbox/test_printouts.py +++ b/scripts/tests/twister_blackbox/test_printouts.py @@ -19,12 +19,12 @@ ZEPHYR_BASE, clear_log_in_test, sample_filename_mock, - testsuite_filename_mock + suite_filename_mock ) from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestPrintOuts: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_quarantine.py b/scripts/tests/twister_blackbox/test_quarantine.py index 4c3cc492cb6f7..b01688baeaa83 100644 --- a/scripts/tests/twister_blackbox/test_quarantine.py +++ b/scripts/tests/twister_blackbox/test_quarantine.py @@ -16,7 +16,7 @@ # pylint: disable=duplicate-code # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan @@ -32,7 +32,7 @@ def setup_class(cls): def teardown_class(cls): pass - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_quarantine_verify(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') @@ -78,7 +78,7 @@ def test_quarantine_verify(self, out_path): 'quarantine', ], ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_quarantine_list(self, capfd, out_path, test_path, test_platforms, quarantine_directory): args = ['--detailed-test-id', '--outdir', out_path, '-T', test_path] +\ ['--quarantine-list', quarantine_directory] + \ diff --git a/scripts/tests/twister_blackbox/test_report.py b/scripts/tests/twister_blackbox/test_report.py index 95f14d9b5ca26..c1e5d406a27f4 100644 --- a/scripts/tests/twister_blackbox/test_report.py +++ b/scripts/tests/twister_blackbox/test_report.py @@ -17,12 +17,12 @@ import xml.etree.ElementTree as etree # pylint: disable=no-name-in-module -from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock, clear_log_in_test +from conftest import TEST_DATA, ZEPHYR_BASE, suite_filename_mock, clear_log_in_test from twisterlib.statuses import TwisterStatus from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestReport: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_runner.py b/scripts/tests/twister_blackbox/test_runner.py index b15d9f3231285..1d4dafee29d8c 100644 --- a/scripts/tests/twister_blackbox/test_runner.py +++ b/scripts/tests/twister_blackbox/test_runner.py @@ -16,11 +16,11 @@ import time # pylint: disable=no-name-in-module -from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock, clear_log_in_test +from conftest import TEST_DATA, ZEPHYR_BASE, suite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan -@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) +@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) class TestRunner: TESTDATA_1 = [ ( diff --git a/scripts/tests/twister_blackbox/test_shuffle.py b/scripts/tests/twister_blackbox/test_shuffle.py index ba19faf64b6e4..53454d41ef5fd 100644 --- a/scripts/tests/twister_blackbox/test_shuffle.py +++ b/scripts/tests/twister_blackbox/test_shuffle.py @@ -14,7 +14,7 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan @@ -49,7 +49,7 @@ def teardown_class(cls): 'first third, 321', 'middle third, 321', 'last third, 321' ] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_shuffle_tests(self, out_path, seed, ratio, expected_order): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') diff --git a/scripts/tests/twister_blackbox/test_testlist.py b/scripts/tests/twister_blackbox/test_testlist.py index 410c417e14cda..d86b9cf883dc3 100644 --- a/scripts/tests/twister_blackbox/test_testlist.py +++ b/scripts/tests/twister_blackbox/test_testlist.py @@ -14,7 +14,7 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock, clear_log_in_test +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan @@ -30,7 +30,7 @@ def setup_class(cls): def teardown_class(cls): pass - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_save_tests(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic') diff --git a/scripts/tests/twister_blackbox/test_testplan.py b/scripts/tests/twister_blackbox/test_testplan.py index 898fbcd53a057..b416b3b43263f 100644 --- a/scripts/tests/twister_blackbox/test_testplan.py +++ b/scripts/tests/twister_blackbox/test_testplan.py @@ -14,7 +14,7 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, suite_filename_mock from twisterlib.testplan import TestPlan from twisterlib.error import TwisterRuntimeError @@ -55,7 +55,7 @@ def teardown_class(cls): TESTDATA_1, ids=['valid', 'not found'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_subtest(self, out_path, test, expected_exception, expected_subtest_count): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') @@ -89,7 +89,7 @@ def test_subtest(self, out_path, test, expected_exception, expected_subtest_coun TESTDATA_2, ids=['buildable', 'runnable'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_filter(self, out_path, filter, expected_count): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy') @@ -121,7 +121,7 @@ def test_filter(self, out_path, filter, expected_count): TESTDATA_3, ids=['integration', 'no integration'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) @mock.patch.object(TestPlan, 'SAMPLE_FILENAME', '') def test_integration(self, out_path, integration, expected_count): test_platforms = ['qemu_x86', 'intel_adl_crb'] diff --git a/scripts/tests/twister_blackbox/test_tooling.py b/scripts/tests/twister_blackbox/test_tooling.py index d844ec824de0b..45d5ca400ac29 100644 --- a/scripts/tests/twister_blackbox/test_tooling.py +++ b/scripts/tests/twister_blackbox/test_tooling.py @@ -15,7 +15,7 @@ import json # pylint: disable=no-name-in-module -from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, testsuite_filename_mock +from conftest import ZEPHYR_BASE, TEST_DATA, sample_filename_mock, suite_filename_mock from twisterlib.statuses import TwisterStatus from twisterlib.testplan import TestPlan @@ -37,7 +37,7 @@ def teardown_class(cls): ['1', '2'], ids=['single job', 'two jobs'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_jobs(self, out_path, jobs): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic', 'group2') @@ -103,7 +103,7 @@ def test_force_toolchain(self, out_path): 'flag', ['--ninja', '-N'] ) - @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) + @mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', suite_filename_mock) def test_ninja(self, capfd, out_path, test_path, test_platforms, flag): args = ['--outdir', out_path, '-T', test_path, flag] + \ [val for pair in zip( From de8914ddc0c5a9bf6728bf2d96ede020ad890b72 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 30 Aug 2025 08:42:39 -0400 Subject: [PATCH 0289/1076] twister: coverage: --gcov-object-directory works with >= gcovr 7.0 This command line option is not available in older versions of gcovr. Signed-off-by: Anas Nashif --- scripts/pylib/twister/twisterlib/coverage.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/coverage.py b/scripts/pylib/twister/twisterlib/coverage.py index 272aa3c7c1be4..9354d0519c5d2 100644 --- a/scripts/pylib/twister/twisterlib/coverage.py +++ b/scripts/pylib/twister/twisterlib/coverage.py @@ -414,8 +414,9 @@ def collect_coverage(self, outdir, coverage_file, ztest_file, coveragelog): cmd = ["gcovr", "-r", self.base_dir, "--gcov-ignore-parse-errors=negative_hits.warn_once_per_file", "--gcov-executable", self.gcov_tool, - "--gcov-object-directory", outdir, "-e", "tests/*"] + if self.version >= "7.0": + cmd += ["--gcov-object-directory", outdir] cmd += excludes + self.options + ["--json", "-o", coverage_file, outdir] cmd_str = " ".join(cmd) logger.debug(f"Running: {cmd_str}") @@ -428,9 +429,11 @@ def collect_coverage(self, outdir, coverage_file, ztest_file, coveragelog): cmd = ["gcovr", "-r", self.base_dir] + self.options cmd += ["--gcov-executable", self.gcov_tool, - "--gcov-object-directory", outdir, "-f", "tests/ztest", "-e", "tests/ztest/test/*", "--json", "-o", ztest_file, outdir] + if self.version >= "7.0": + cmd += ["--gcov-object-directory", outdir] + cmd_str = " ".join(cmd) logger.debug(f"Running: {cmd_str}") coveragelog.write(f"Running: {cmd_str}\n") From db8e7ab65a38dd193ca264ef5c20a28fb15b7695 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 30 Aug 2025 10:37:13 -0400 Subject: [PATCH 0290/1076] workflows: twister: install lcov Install lcov needed for some tests. Signed-off-by: Anas Nashif --- .github/workflows/twister_tests_blackbox.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 798135fd84c1f..b45e4d51b4102 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -59,6 +59,7 @@ jobs: ZEPHYR_TOOLCHAIN_VARIANT: zephyr run: | export ZEPHYR_SDK_INSTALL_DIR=${{ github.workspace }}/zephyr-sdk + sudo apt-get install -y lcov echo "Run twister tests" source zephyr-env.sh PYTHONPATH="./scripts/tests" pytest ./scripts/tests/twister_blackbox/ From 375d51452e80ed9fd2427492c41eb1163b0b8e49 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Sun, 3 Aug 2025 08:09:15 +0200 Subject: [PATCH 0291/1076] scripts: twister: Fix --flash-before with serial-pty script Honor the --flash-before option when using a serial-pty script with --device-serial-pty