From 6f65c644d8242bc8a345ca4eb9f0cb2aef84fce2 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Thu, 16 Jul 2026 16:12:49 +0200 Subject: [PATCH 1/7] samples: sid_end_device: add nRF70 Wi-Fi location PAL Add a Sidewalk Wi-Fi PAL (sid_pal_wifi_ifc.h) backed by an asynchronous Zephyr net_mgmt Wi-Fi scan on the nRF70, enabling Wi-Fi-based location alongside (or instead of) the LR1110 GNSS/Wi-Fi PAL. - subsys/nrf70_location: new nrf70_wifi_scan (net_mgmt scan wrapper) and sid_pal_wifi_nrf70_impl (Wi-Fi PAL) backend, enabled via the new CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 Kconfig option (with scan band/type/timeout sub-options), and select NET_MGMT/NET_MGMT_EVENT/ NET_MGMT_EVENT_INFO so struct net_mgmt_event_callback::info is actually available to the scan callback. - subsys/semtech: skip the sx126x_location NOSUPPORT stub and the LR1110's own Wi-Fi PAL entry points when the nRF70 PAL is active, so it takes priority while LR1110 keeps providing GNSS. - Kconfig: tie the whole nRF70 Wi-Fi stack (WIFI, NETWORKING, WIFI_NRF70, NRF70_SCAN_ONLY, FW patch storage, and the scan band/type defaults) to the presence of the nrf7002eb2 shield via `if SHIELD_NRF7002EB2`, so `--shield nrf7002eb2` alone is enough - no -DFILE_SUFFIX or sysbuild SB_CONFIG_WIFI_NRF70* flags needed. - samples/sid_end_device: no per-board wifi variant file needed either - the DUT/CLI shell variant (needed to drive `location scan`) is already the existing, board-agnostic overlay-dut.conf, applied the usual way (-DOVERLAY_CONFIG="overlay-dut.conf"). sysbuild_wifi.conf and the nRF54LM20 wifi board conf are both removed as redundant. Also a board overlay fix for the LED pin the shield repurposes as its SPI-CS line. - west.yml / .gitignore: pull in the nrf_wifi module and ignore local provisioning artifacts. Verified building and linking end to end (west build) for: nrf54lm20dk/nrf54lm20a/cpuapp --shield nrf7002eb2 nrf54l15dk/nrf54l15/cpuapp (default, unaffected by this change) Co-authored-by: Cursor Signed-off-by: Bartosz Ludwin --- Kconfig | 133 ++++++++ .../boards/nrf54l15dk_nrf54l15_cpuapp.overlay | 2 +- .../nrf54l15dk_nrf54l15_cpuapp_ns.overlay | 2 +- samples/sid_end_device/src/sidewalk_events.c | 2 +- subsys/CMakeLists.txt | 4 + subsys/nrf70_location/CMakeLists.txt | 12 + subsys/nrf70_location/nrf70_wifi_scan.c | 197 ++++++++++++ subsys/nrf70_location/nrf70_wifi_scan.h | 86 ++++++ .../nrf70_location/sid_pal_wifi_nrf70_impl.c | 286 ++++++++++++++++++ subsys/sal/sid_pal/include/bt_app_callbacks.h | 2 +- subsys/semtech/CMakeLists.txt | 9 +- .../lr1110_location/sid_pal_gnss_wifi_impl.c | 9 + west.yml | 1 + 13 files changed, 740 insertions(+), 5 deletions(-) create mode 100644 subsys/nrf70_location/CMakeLists.txt create mode 100644 subsys/nrf70_location/nrf70_wifi_scan.c create mode 100644 subsys/nrf70_location/nrf70_wifi_scan.h create mode 100644 subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c diff --git a/Kconfig b/Kconfig index 5674ecb313..8568f5b4f4 100644 --- a/Kconfig +++ b/Kconfig @@ -233,6 +233,139 @@ config SIDEWALK_USE_PREBUILT_LIBRARIES Building from sources requires additional dependencies, not released with nRF Connect SDK. +if SHIELD_NRF7002EB2 + +config WIFI + default y + +config NETWORKING + default y + +config NET_L2_ETHERNET + default y + +config NET_OFFLOAD + default y + +config WIFI_NRF70 + default y + +# NRF70_SCAN_ONLY and NRF_WIFI_PATCHES_EXT_FLASH_DISABLED are choice members +# (NRF70_OPER_MODES / NRF_WIFI_PATCHES_EXT_FLASH_SUPPORT), so the default has +# to be set on the choice itself, not on the member config. +choice NRF70_OPER_MODES + default NRF70_SCAN_ONLY +endchoice + +choice NRF_WIFI_PATCHES_EXT_FLASH_SUPPORT + default NRF_WIFI_PATCHES_EXT_FLASH_DISABLED +endchoice + +endif # SHIELD_NRF7002EB2 + +config SIDEWALK_WIFI_LOCATION_NRF70 + bool "nRF70 Wi-Fi location PAL" + depends on WIFI + default y + # NETWORKING is already forced on via `if SHIELD_NRF7002EB2` above; + # selecting it again here would create a WIFI -> NETWORKING -> WIFI + # Kconfig dependency loop (NETWORKING's select is conditioned on WIFI). + select NET_MGMT + select NET_MGMT_EVENT + select NET_MGMT_EVENT_INFO + help + Provide the Sidewalk Wi-Fi PAL (sid_pal_wifi_ifc.h) backed by an + asynchronous Zephyr net_mgmt Wi-Fi scan on the nRF70. This lets the + Sidewalk location library drive the Wi-Fi scan by itself + (init/schedule_scan/get_scan_payload). + + When SIDEWALK_SUBGHZ_RADIO_SX126X is also selected this PAL replaces + the sx126x_location NOSUPPORT stub, so the (lora_fsk) Sidewalk library + actually invokes the Wi-Fi PAL. + + This PAL can also coexist with SIDEWALK_SUBGHZ_RADIO_LR1110 (for + example the nRF Sidewalk EB together with an nRF7002 EB): whenever WIFI + is enabled the nRF70 provides the Wi-Fi PAL (taking priority), while the + LR1110 keeps providing the GNSS PAL and the sub-GHz radio. When WIFI is + disabled the LR1110 provides the Wi-Fi PAL itself. + +if SIDEWALK_WIFI_LOCATION_NRF70 + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TIMEOUT_MS + int "nRF70 Wi-Fi scan timeout (ms)" + default 20000 + range 1000 60000 + help + Backstop timeout for a single nRF70 Wi-Fi scan. If the net_mgmt + scan-done event does not arrive within this window the scan is + abandoned and reported as timed out, so the Wi-Fi PAL cannot get + stuck busy. Increase it for slow passive or multi-band scans. + +choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_FILTER + prompt "nRF70 Wi-Fi location scan band filter" + # nrf7002eb2 is only verified/tuned for 2.4 GHz so far; other Wi-Fi + # hardware defaults to scanning both bands. + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ if SHIELD_NRF7002EB2 + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ + help + Select which Wi-Fi frequency bands the nRF70 location scan covers. + Band filtering is applied via wifi_scan_params.bands. See the nRF + Connect SDK "Optimizing scan operation" guide for scan time/energy + trade-offs per profile. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ + bool "2.4 GHz only" + help + Scan only the 2.4 GHz band. Matches the "2.4 GHz Active" profile + in the nRF Connect SDK scan optimization guide. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ + bool "2.4 and 5 GHz" + help + Scan both the 2.4 GHz and 5 GHz bands. This is the typical profile + for Wi-Fi location when dual-band AP visibility is needed. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_ALL + bool "All regulatory bands (2.4/5/6 GHz)" + help + Do not restrict wifi_scan_params.bands; scan every band the + regulatory domain allows. + +endchoice + +choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TYPE + prompt "nRF70 Wi-Fi location scan type" + # nrf7002eb2 is only verified/tuned for passive scanning so far; other + # Wi-Fi hardware defaults to active scanning. + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE if SHIELD_NRF7002EB2 + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE + help + Sets the scan_type hint passed to the driver. It's only a hint - + the chip or the regulatory domain can still fall back to passive + scanning on channels where active probing isn't allowed (e.g. + 2.4 GHz channels 12-14). Also make sure + CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN stays disabled (its default), + since it overrides this hint and forces passive scanning on every + channel regardless of what you pick here. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE + bool "Active" + help + Sends probe requests (WIFI_SCAN_TYPE_ACTIVE). Faster than passive, + but draws more instantaneous transmit power. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE + bool "Passive" + help + Only listens for beacons, no probe requests + (WIFI_SCAN_TYPE_PASSIVE). Slower than active, but uses less + instantaneous transmit power and works on channels where active + probing is restricted. + +endchoice + +endif # SIDEWALK_WIFI_LOCATION_NRF70 + rsource "Kconfig.dependencies" rsource "utils/Kconfig" rsource "boards/shields/*/Kconfig.shield" diff --git a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index a35eebbd54..51340c43fd 100644 --- a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -7,7 +7,7 @@ /{ aliases { state-notifier-connected = &led0; - state-notifier-time-sync = &led1; + /* led1 is repurposed as SPI-CS by the nrf7002eb2 Wi-Fi shield */ state-notifier-registered = &led2; state-notifier-working = &led3; }; diff --git a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay index a649cf85b5..d697eb3e7e 100644 --- a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay +++ b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay @@ -7,7 +7,7 @@ /{ aliases { state-notifier-connected = &led0; - state-notifier-time-sync = &led1; + /* led1 is repurposed as SPI-CS by the nrf7002eb2 Wi-Fi shield */ state-notifier-registered = &led2; state-notifier-working = &led3; }; diff --git a/samples/sid_end_device/src/sidewalk_events.c b/samples/sid_end_device/src/sidewalk_events.c index 976ef23010..8434b9b4fb 100644 --- a/samples/sid_end_device/src/sidewalk_events.c +++ b/samples/sid_end_device/src/sidewalk_events.c @@ -107,7 +107,7 @@ void sidewalk_event_platform_init(sidewalk_ctx_t *sid, void *ctx) void sidewalk_event_autostart(sidewalk_ctx_t *sid, void *ctx) { if (sid->handle != NULL) { - LOG_INF("Sidewlak is already running"); + LOG_INF("Sidewalk is already running"); return; } if (app_mfg_cfg_is_empty()) { diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index 14204d282f..2a06eb9d10 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(sal) + if (CONFIG_SIDEWALK_USE_PREBUILT_LIBRARIES) add_subdirectory(app_utils) add_subdirectory(semtech) @@ -15,4 +16,7 @@ if (CONFIG_SIDEWALK_USE_PREBUILT_LIBRARIES) endif() endif() +add_subdirectory_ifdef(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 nrf70_location) + + add_subdirectory_ifdef(CONFIG_SIDEWALK_DEMO_PARSER demo) diff --git a/subsys/nrf70_location/CMakeLists.txt b/subsys/nrf70_location/CMakeLists.txt new file mode 100644 index 0000000000..1d61aa90ad --- /dev/null +++ b/subsys/nrf70_location/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +zephyr_include_directories(.) + +zephyr_library_sources( + nrf70_wifi_scan.c + sid_pal_wifi_nrf70_impl.c +) diff --git a/subsys/nrf70_location/nrf70_wifi_scan.c b/subsys/nrf70_location/nrf70_wifi_scan.c new file mode 100644 index 0000000000..5b29232039 --- /dev/null +++ b/subsys/nrf70_location/nrf70_wifi_scan.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "nrf70_wifi_scan.h" + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nrf70_wifi_scan, CONFIG_SIDEWALK_LOG_LEVEL); + +#define WIFI_SCAN_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE) + +static struct net_mgmt_event_callback scan_cb; +static bool cb_registered; +static nrf70_wifi_scan_done_cb_t scan_done_cb; + +static struct { + struct nrf70_wifi_scan_ap *results; + size_t max_results; + size_t stored; + size_t total; + int status; +} scan_ctx; + +static atomic_t scan_done = ATOMIC_INIT(0); + +static struct net_if *wifi_iface(void) +{ + struct net_if *iface = net_if_get_first_wifi(); + + return iface ? iface : net_if_get_default(); +} + +/* Insert an AP into the results array, keeping it sorted by descending RSSI and + * capped at max_results (weakest dropped). */ +static void scan_result_insert(int8_t rssi, const uint8_t *mac, uint8_t mac_len) +{ + struct nrf70_wifi_scan_ap *r = scan_ctx.results; + size_t max = scan_ctx.max_results; + size_t pos; + + if (!r || max == 0) { + return; + } + + if (scan_ctx.stored < max) { + pos = scan_ctx.stored++; + } else if (rssi > r[max - 1].rssi) { + pos = max - 1; + } else { + return; + } + + for (; pos > 0 && r[pos - 1].rssi < rssi; pos--) { + r[pos] = r[pos - 1]; + } + + memset(&r[pos], 0, sizeof(r[pos])); + r[pos].rssi = rssi; + r[pos].mac_len = MIN(mac_len, (uint8_t)WIFI_MAC_ADDR_LEN); + memcpy(r[pos].mac, mac, r[pos].mac_len); +} + +static void scan_result_handle(struct net_mgmt_event_callback *cb) +{ + const struct wifi_scan_result *entry = (const struct wifi_scan_result *)cb->info; + + scan_ctx.total++; + scan_result_insert(entry->rssi, entry->mac, entry->mac_length); +} + +static void scan_done_handle(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = (const struct wifi_status *)cb->info; + + scan_ctx.status = status->status; + atomic_set(&scan_done, 1); + + if (scan_done_cb) { + scan_done_cb(); + } +} + +static void scan_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface) +{ + ARG_UNUSED(iface); + + switch (mgmt_event) { + case NET_EVENT_WIFI_SCAN_RESULT: + scan_result_handle(cb); + break; + case NET_EVENT_WIFI_SCAN_DONE: + scan_done_handle(cb); + break; + default: + break; + } +} + +int nrf70_wifi_scan_start(struct nrf70_wifi_scan_ap *results, size_t max_results, + nrf70_wifi_scan_done_cb_t on_done) +{ + struct net_if *iface = wifi_iface(); + int ret; + + if (!results || max_results == 0) { + return -EINVAL; + } + if (!iface) { + return -ENODEV; + } + if (!net_if_is_admin_up(iface)) { + return -ENETDOWN; + } + + scan_ctx.results = results; + scan_ctx.max_results = max_results; + scan_ctx.stored = 0; + scan_ctx.total = 0; + scan_ctx.status = 0; + scan_done_cb = on_done; + atomic_set(&scan_done, 0); + + net_mgmt_init_event_callback(&scan_cb, scan_mgmt_event_handler, WIFI_SCAN_EVENTS); + net_mgmt_add_event_callback(&scan_cb); + cb_registered = true; + + struct wifi_scan_params params = { +#if defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE) + .scan_type = WIFI_SCAN_TYPE_ACTIVE, +#elif defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE) + .scan_type = WIFI_SCAN_TYPE_PASSIVE, +#endif +#if defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ) + .bands = BIT(WIFI_FREQ_BAND_2_4_GHZ), +#elif defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ) + .bands = BIT(WIFI_FREQ_BAND_2_4_GHZ) | BIT(WIFI_FREQ_BAND_5_GHZ), +#endif + }; + + ret = net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params)); + if (ret) { + nrf70_wifi_scan_abort(); + return ret; + } + + return 0; +} + +int nrf70_wifi_scan_get_result(size_t *stored, size_t *total, int *status) +{ + if (!cb_registered) { + return -EINVAL; + } + if (!atomic_get(&scan_done)) { + return 0; + } + + net_mgmt_del_event_callback(&scan_cb); + cb_registered = false; + + if (stored) { + *stored = scan_ctx.stored; + } + if (total) { + *total = scan_ctx.total; + } + if (status) { + *status = scan_ctx.status; + } + + return 1; +} + +void nrf70_wifi_scan_abort(void) +{ + /* Zephyr's Wi-Fi mgmt API has no scan-cancel request, so a scan already + * running in the driver cannot be stopped; it will run to completion in + * the background. All we can do is stop listening for its results and + * release the collection context. */ + if (cb_registered) { + net_mgmt_del_event_callback(&scan_cb); + cb_registered = false; + } + scan_ctx.results = NULL; + scan_ctx.max_results = 0; + atomic_set(&scan_done, 0); +} diff --git a/subsys/nrf70_location/nrf70_wifi_scan.h b/subsys/nrf70_location/nrf70_wifi_scan.h new file mode 100644 index 0000000000..a4494afcd8 --- /dev/null +++ b/subsys/nrf70_location/nrf70_wifi_scan.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NRF70_WIFI_SCAN_H +#define NRF70_WIFI_SCAN_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A single access point discovered by a net_mgmt Wi-Fi scan. + * + * Only the fields the Sidewalk Wi-Fi PAL payload actually carries (BSSID and + * signal strength) are kept; SSID/channel/security are intentionally dropped to + * keep the collection buffer small. + */ +struct nrf70_wifi_scan_ap { + int8_t rssi; + uint8_t mac[WIFI_MAC_ADDR_LEN]; + uint8_t mac_len; +}; + +/** + * Completion callback, invoked once from the net_mgmt event thread when the + * scan finishes. It must be lightweight (e.g. post an event); the actual + * results are read later with nrf70_wifi_scan_get_result(). + */ +typedef void (*nrf70_wifi_scan_done_cb_t)(void); + +/** + * Start an asynchronous net_mgmt Wi-Fi scan. + * + * Returns immediately after handing the request to the driver. Results stream + * in on the net_mgmt event thread and are kept as the @p max_results strongest + * access points (descending RSSI) in @p results. When the scan finishes, + * @p on_done is called (from the net_mgmt thread) so the caller can wake up and + * collect the results with nrf70_wifi_scan_get_result(). + * + * Only one scan may be in flight at a time. @p results must stay valid until + * the scan completes or nrf70_wifi_scan_abort() is called. + * + * @param[out] results Array to keep the strongest APs (must be non-NULL). + * @param[in] max_results Capacity of @p results. + * @param[in] on_done Completion callback (may be NULL). + * + * @return 0 on success, negative errno on failure. + */ +int nrf70_wifi_scan_start(struct nrf70_wifi_scan_ap *results, size_t max_results, + nrf70_wifi_scan_done_cb_t on_done); + +/** + * Collect the results of a scan started by nrf70_wifi_scan_start(). + * + * Intended to be called after the completion callback has fired. + * + * @param[out] stored Number of APs kept in the results array. May be NULL. + * @param[out] total Total number of APs reported by the driver. May be NULL. + * @param[out] status Driver scan status (0 = success). Valid when done. May be NULL. + * + * @return 1 if the scan has completed, 0 if still running, negative errno on error. + */ +int nrf70_wifi_scan_get_result(size_t *stored, size_t *total, int *status); + +/** + * Stop tracking an in-flight scan and release the net_mgmt callback. + * + * NOTE: Zephyr's Wi-Fi mgmt API has no scan-cancel request, so a scan already + * issued to the driver cannot be stopped in hardware - it keeps running to + * completion in the background. This only detaches the results listener and + * frees the collection context, so the caller may reuse its results buffer. + */ +void nrf70_wifi_scan_abort(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NRF70_WIFI_SCAN_H */ diff --git a/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c b/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c new file mode 100644 index 0000000000..9a6f5bb5d2 --- /dev/null +++ b/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "nrf70_wifi_scan.h" + +LOG_MODULE_REGISTER(sid_pal_wifi_nrf70, CONFIG_SIDEWALK_LOG_LEVEL); + +#define WIFI_SCAN_TIMEOUT_MS CONFIG_SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TIMEOUT_MS + +static struct sid_pal_wifi_config wifi_config; + +/* Access points kept for the last/ongoing scan, capped at the payload size. */ +static struct nrf70_wifi_scan_ap scan_aps[SID_WIFI_MAX_RESULTS]; + +/* Results of the last completed scan, consumed by get_scan_payload(). */ +static struct sid_pal_wifi_payload last_payload; + +static bool scan_busy; /* a scan request is in progress (delayed or running) */ +static bool scan_started; /* the net_mgmt scan has actually been issued */ +static int64_t scan_deadline; + +/* Ask the library to call sid_pal_wifi_process_event() after delay_ms. + * Safe to call from any thread: on_wifi_event posts to the Sidewalk event + * queue. */ +static void request_process_event(uint32_t delay_ms) +{ + if (wifi_config.on_wifi_event) { + wifi_config.on_wifi_event(wifi_config.ctx, SID_PAL_WIFI_INTERNAL, delay_ms); + } +} + +/* Scanner completion callback - runs on the net_mgmt event thread. */ +static void scan_done_wake(void) +{ + request_process_event(0); +} + +/* Issue the net_mgmt scan and arm the backstop timeout. Runs on the library + * thread (schedule_scan or, for a delayed scan, process_event). */ +static sid_error_t start_scan_now(void) +{ + int ret = nrf70_wifi_scan_start(scan_aps, ARRAY_SIZE(scan_aps), scan_done_wake); + + if (ret) { + LOG_ERR("nRF70 Wi-Fi PAL: failed to start scan (%d)", ret); + return SID_ERROR_IO_ERROR; + } + + scan_started = true; + scan_deadline = k_uptime_get() + WIFI_SCAN_TIMEOUT_MS; + + /* Backstop only: real completion is signalled by scan_done_wake(). */ + request_process_event(WIFI_SCAN_TIMEOUT_MS); + return SID_ERROR_NONE; +} + +static void finish_scan(size_t stored, int status) +{ + memset(&last_payload, 0, sizeof(last_payload)); + + if (status != 0) { + LOG_ERR("nRF70 Wi-Fi scan failed (status %d)", status); + } else if (stored == 0) { + LOG_WRN("nRF70 Wi-Fi scan found no access points"); + } else { + /* scan_aps is already sorted by descending RSSI and capped at + * SID_WIFI_MAX_RESULTS by the scanner. */ + uint8_t n = (uint8_t)MIN(stored, (size_t)SID_WIFI_MAX_RESULTS); + + for (uint8_t i = 0; i < n; i++) { + /* PAL contract stores RSSI as unsigned. */ + last_payload.results[i].rssi = (uint8_t)scan_aps[i].rssi; + memcpy(last_payload.results[i].mac, scan_aps[i].mac, + SID_WIFI_MAC_ADDRESS_LENGTH); + } + last_payload.nbr_results = n; + LOG_INF("nRF70 Wi-Fi PAL: collected %u AP(s)", n); + } + + scan_busy = false; + scan_started = false; + + if (wifi_config.on_wifi_event) { + wifi_config.on_wifi_event(wifi_config.ctx, SID_PAL_WIFI_SCAN_COMPLETE, 0); + } +} + +/* --------------------------------------------------------------------------- + * Wi-Fi PAL + * ------------------------------------------------------------------------- */ + +sid_error_t sid_pal_wifi_init(struct sid_pal_wifi_config *config) +{ + if (!config) { + return SID_ERROR_NULL_POINTER; + } + + wifi_config = *config; + + LOG_INF("nRF70 Wi-Fi PAL initialized"); + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_deinit(void) +{ + nrf70_wifi_scan_abort(); + scan_busy = false; + scan_started = false; + memset(&wifi_config, 0, sizeof(wifi_config)); + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_process_event(uint8_t event_id) +{ + ARG_UNUSED(event_id); + + if (!scan_busy) { + return SID_ERROR_NONE; + } + + if (!scan_started) { + /* The requested scan delay has elapsed; start the scan now. */ + if (start_scan_now() != SID_ERROR_NONE) { + finish_scan(0, -EIO); + } + return SID_ERROR_NONE; + } + + size_t stored = 0; + size_t total = 0; + int status = 0; + + int ret = nrf70_wifi_scan_get_result(&stored, &total, &status); + + if (ret == 0) { + /* Woken but scan not done yet: only act if the backstop timeout + * has elapsed, otherwise wait for the real completion wake. */ + if (k_uptime_get() >= scan_deadline) { + LOG_ERR("nRF70 Wi-Fi scan timed out"); + nrf70_wifi_scan_abort(); + finish_scan(0, -ETIMEDOUT); + } + return SID_ERROR_NONE; + } + + if (ret < 0) { + finish_scan(0, ret); + return SID_ERROR_NONE; + } + + LOG_INF("nRF70 Wi-Fi PAL: scan complete (%u of %u AP(s))", + (unsigned)stored, (unsigned)total); + finish_scan(stored, status); + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_schedule_scan(uint32_t scan_delay_s) +{ + if (!wifi_config.on_wifi_event) { + return SID_ERROR_UNINITIALIZED; + } + + if (scan_busy) { + LOG_WRN("nRF70 Wi-Fi PAL: scan already in progress"); + return SID_ERROR_BUSY; + } + + scan_busy = true; + scan_started = false; + + if (scan_delay_s == 0) { + sid_error_t err = start_scan_now(); + + if (err != SID_ERROR_NONE) { + scan_busy = false; + return err; + } + LOG_INF("nRF70 Wi-Fi PAL: scan scheduled"); + } else { + /* Defer the scan: ask the library to call process_event() after + * the requested delay, where start_scan_now() will run. */ + LOG_INF("nRF70 Wi-Fi PAL: scan scheduled in %u s", scan_delay_s); + request_process_event(scan_delay_s * 1000U); + } + + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_cancel_scan(void) +{ + /* Best-effort cancel. A scan that has not started yet (a deferred scan + * still waiting for its delay to elapse) is cancelled cleanly. A scan + * already running in the driver cannot be stopped in hardware (Zephyr + * has no scan-cancel request); we just detach the listener so its + * eventual completion is ignored and the PAL is freed for a new scan. */ + if (scan_busy) { + nrf70_wifi_scan_abort(); + scan_busy = false; + scan_started = false; + } + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_get_scan_payload(struct sid_pal_wifi_payload *wifi_scan_result) +{ + if (!wifi_scan_result) { + return SID_ERROR_NULL_POINTER; + } + + if (last_payload.nbr_results == 0) { + return SID_ERROR_INSUFFICIENT_RESULTS; + } + + *wifi_scan_result = last_payload; + + LOG_INF("nRF70 Wi-Fi PAL: reporting %u AP(s) to Sidewalk", + wifi_scan_result->nbr_results); + return SID_ERROR_NONE; +} + +/* --------------------------------------------------------------------------- + * GNSS PAL - not available on this platform. + * + * These stubs are required because, when this PAL replaces the + * sx126x_location stub, the Sidewalk library still references the full GNSS + * PAL surface. All functions report NOSUPPORT so the GNSS method degrades + * gracefully. + * + * When SIDEWALK_SUBGHZ_RADIO_LR1110 is selected the LR1110 provides the real + * GNSS PAL, so these stubs are compiled out to avoid duplicate sid_pal_gnss_* + * symbols (the nRF70 keeps providing the Wi-Fi PAL alongside it). + * ------------------------------------------------------------------------- */ +#if !defined(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110) + +sid_error_t sid_pal_gnss_init(struct sid_pal_gnss_config *config) +{ + ARG_UNUSED(config); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_process_event(uint8_t event_id) +{ + ARG_UNUSED(event_id); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_schedule_scan(uint32_t scan_delay_s) +{ + ARG_UNUSED(scan_delay_s); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_cancel_scan(void) +{ + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_get_scan_payload(struct sid_pal_gnss_payload *gnss_scan_group) +{ + ARG_UNUSED(gnss_scan_group); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_alm_demod_start(void) +{ + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_deinit(void) +{ + return SID_ERROR_NOSUPPORT; +} + +#endif /* !CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110 */ diff --git a/subsys/sal/sid_pal/include/bt_app_callbacks.h b/subsys/sal/sid_pal/include/bt_app_callbacks.h index 13d4812ca5..2d7f4aa51d 100644 --- a/subsys/sal/sid_pal/include/bt_app_callbacks.h +++ b/subsys/sal/sid_pal/include/bt_app_callbacks.h @@ -25,7 +25,7 @@ extern "C" { bool sid_ble_bt_attr_is_SMP(const struct bt_gatt_attr *attr); /** - * @brief check if attr is for one of Sidewlak services + * @brief check if attr is for one of Sidewalk services * * @param attr * @return true if attr is diff --git a/subsys/semtech/CMakeLists.txt b/subsys/semtech/CMakeLists.txt index 56b9675e5e..270ca3654d 100644 --- a/subsys/semtech/CMakeLists.txt +++ b/subsys/semtech/CMakeLists.txt @@ -67,7 +67,14 @@ target_compile_definitions(smtc_lbm INTERFACE ) add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X sx126x) -add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X sx126x_location) + +# When the nRF70 Wi-Fi PAL is active it provides the GNSS/Wi-Fi PAL symbols +# instead of the sx126x_location NOSUPPORT stub, so skip the stub to avoid +# duplicate symbol definitions. +if(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X AND NOT CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) + add_subdirectory(sx126x_location) +endif() + add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110 lr11xx) add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110 lr1110) add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110 lr1110_location) diff --git a/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c b/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c index 7aaa69dd5c..f7c2d61c08 100644 --- a/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c +++ b/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c @@ -230,10 +230,12 @@ sid_error_t sid_pal_gnss_process_event(uint8_t event_id) return sid_pal_common_process_event(); } +#if !defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) sid_error_t sid_pal_wifi_process_event(uint8_t event_id) { return sid_pal_common_process_event(); } +#endif /* !CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 */ sid_error_t sid_pal_gnss_alm_demod_start() { smtc_modem_almanac_demodulation_start(LBM_STACK_ID); @@ -318,6 +320,11 @@ sid_error_t sid_pal_gnss_get_scan_payload(struct sid_pal_gnss_payload *gnss_scan // END OF GNSS SPECIFIC PAL IMPLEMENTATION // WIFI SPECIFIC PAL IMPLEMENTATION +// +// When SIDEWALK_WIFI_LOCATION_NRF70 is enabled the nRF70 provides the Wi-Fi PAL +// (it takes priority), so the LR1110 Wi-Fi entry points are compiled out here to +// avoid duplicate sid_pal_wifi_* symbols. The LR1110 still provides GNSS. +#if !defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) sid_error_t sid_pal_wifi_init(struct sid_pal_wifi_config *config) { location_state.wifi_cfg = *config; @@ -364,4 +371,6 @@ sid_error_t sid_pal_wifi_get_scan_payload(struct sid_pal_wifi_payload *wifi_scan wifi_scan_payload->nbr_results = location_state.wifi_scan_done_data.nbr_results; return SID_ERROR_NONE; } + +#endif /* !CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 */ // END OF WIFI PAL IMPLEMENTATION diff --git a/west.yml b/west.yml index 1060a56833..564a360146 100644 --- a/west.yml +++ b/west.yml @@ -21,6 +21,7 @@ manifest: - hal_nordic - mbedtls - mcuboot + - nrf_wifi - nrfxlib - oberon-psa-crypto - qcbor From f716194d4036a63750cd5a32609e2ab39af9b3b3 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 13:43:44 +0200 Subject: [PATCH 2/7] boards: add nrf7002eb2 Sidewalk shield overlays Move nRF7002-specific devicetree handling out of board overlays. Apply shield overlays via EXTRA_DTC when nrf7002eb2 is selected, and restore state-notifier-time-sync on LED1 when the shield is not used. Co-authored-by: Cursor --- CMakeLists.txt | 28 +++++++++++++++++++ .../boards/nrf54l15dk_nrf54l15_cpuapp.overlay | 7 +++++ .../nrf54l15dk_nrf54l15_cpuapp_ns.overlay | 7 +++++ boards/shields/nrf7002eb2/nrf54l15.overlay | 11 ++++++++ .../nrf54l15_state_notifier_time_sync.overlay | 11 ++++++++ .../boards/nrf54l15dk_nrf54l15_cpuapp.overlay | 2 -- .../nrf54l15dk_nrf54l15_cpuapp_ns.overlay | 1 - 7 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp.overlay create mode 100644 boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay create mode 100644 boards/shields/nrf7002eb2/nrf54l15.overlay create mode 100644 boards/shields/nrf7002eb2/nrf54l15_state_notifier_time_sync.overlay diff --git a/CMakeLists.txt b/CMakeLists.txt index d2e0d438d7..f392ed44ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,34 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +# Sidewalk-specific nrf7002eb2 overlays live under boards/shields/nrf7002eb2/. +# Do not map state-notifier-time-sync to &led1 in board overlays; add it here only +# when the nrf7002eb2 shield is not used, and drop the alias from the shield overlay +# when it is. +if(DEFINED BOARD AND BOARD MATCHES "^nrf54l15dk_nrf54l15_cpuapp(_ns)?$") + set(nrf7002eb2_shield_dir ${CMAKE_CURRENT_LIST_DIR}/boards/shields/nrf7002eb2) + set(nrf7002eb2_shield_selected FALSE) + + if(DEFINED SHIELD) + string(REPLACE " " ";" shield_list "${SHIELD}") + foreach(shield_name IN LISTS shield_list) + if(shield_name MATCHES "^nrf7002eb2") + set(nrf7002eb2_shield_selected TRUE) + set(shield_overlay ${nrf7002eb2_shield_dir}/boards/${BOARD}.overlay) + if(EXISTS "${shield_overlay}") + list(APPEND EXTRA_DTC_OVERLAY_FILE "${shield_overlay}") + endif() + break() + endif() + endforeach() + endif() + + if(NOT nrf7002eb2_shield_selected) + list(APPEND EXTRA_DTC_OVERLAY_FILE + "${nrf7002eb2_shield_dir}/nrf54l15_state_notifier_time_sync.overlay") + endif() +endif() + if(CONFIG_SIDEWALK_BUILD) if (CONFIG_SIDEWALK_USE_PREBUILT_LIBRARIES) add_subdirectory(lib) diff --git a/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 0000000000..23bf0ef60f --- /dev/null +++ b/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "../nrf54l15.overlay" diff --git a/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay b/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 0000000000..23bf0ef60f --- /dev/null +++ b/boards/shields/nrf7002eb2/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "../nrf54l15.overlay" diff --git a/boards/shields/nrf7002eb2/nrf54l15.overlay b/boards/shields/nrf7002eb2/nrf54l15.overlay new file mode 100644 index 0000000000..a00b1409c1 --- /dev/null +++ b/boards/shields/nrf7002eb2/nrf54l15.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + /delete-property/ state-notifier-time-sync; + }; +}; diff --git a/boards/shields/nrf7002eb2/nrf54l15_state_notifier_time_sync.overlay b/boards/shields/nrf7002eb2/nrf54l15_state_notifier_time_sync.overlay new file mode 100644 index 0000000000..ffbd13c4d1 --- /dev/null +++ b/boards/shields/nrf7002eb2/nrf54l15_state_notifier_time_sync.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + state-notifier-time-sync = &led1; + }; +}; diff --git a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index 51340c43fd..9c0c63c0a3 100644 --- a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -7,11 +7,9 @@ /{ aliases { state-notifier-connected = &led0; - /* led1 is repurposed as SPI-CS by the nrf7002eb2 Wi-Fi shield */ state-notifier-registered = &led2; state-notifier-working = &led3; }; - }; &cpuapp_rram { diff --git a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay index d697eb3e7e..175b3fc461 100644 --- a/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay +++ b/samples/sid_end_device/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay @@ -7,7 +7,6 @@ /{ aliases { state-notifier-connected = &led0; - /* led1 is repurposed as SPI-CS by the nrf7002eb2 Wi-Fi shield */ state-notifier-registered = &led2; state-notifier-working = &led3; }; From 3b3252e7c25ca286979824fef7d3b6a846ef2075 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 13:43:53 +0200 Subject: [PATCH 3/7] location: split LR1110 and nRF70 Wi-Fi PAL implementations Extract LR1110 Wi-Fi PAL into a dedicated file and link it only when nRF70 Wi-Fi location is disabled. Add a separate GNSS stub for nRF70-only builds and skip sx126x location stubs when the nRF70 PAL is active. Co-authored-by: Cursor --- subsys/nrf70_location/CMakeLists.txt | 25 +++++- subsys/nrf70_location/sid_pal_gnss_stub.c | 48 +++++++++++ .../nrf70_location/sid_pal_wifi_nrf70_impl.c | 56 ------------- subsys/semtech/CMakeLists.txt | 9 +- subsys/semtech/lr1110_location/CMakeLists.txt | 6 ++ .../lr1110_location/lr1110_location_priv.h | 33 ++++++++ .../lr1110_location/sid_pal_gnss_wifi_impl.c | 84 ++----------------- .../sid_pal_wifi_lr1110_impl.c | 76 +++++++++++++++++ 8 files changed, 194 insertions(+), 143 deletions(-) create mode 100644 subsys/nrf70_location/sid_pal_gnss_stub.c create mode 100644 subsys/semtech/lr1110_location/lr1110_location_priv.h create mode 100644 subsys/semtech/lr1110_location/sid_pal_wifi_lr1110_impl.c diff --git a/subsys/nrf70_location/CMakeLists.txt b/subsys/nrf70_location/CMakeLists.txt index 1d61aa90ad..87ec74b01c 100644 --- a/subsys/nrf70_location/CMakeLists.txt +++ b/subsys/nrf70_location/CMakeLists.txt @@ -4,9 +4,26 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -zephyr_include_directories(.) +zephyr_library_named(sid_pal_wifi_nrf70_impl) -zephyr_library_sources( - nrf70_wifi_scan.c - sid_pal_wifi_nrf70_impl.c +target_sources(sid_pal_wifi_nrf70_impl PRIVATE + nrf70_wifi_scan.c + sid_pal_wifi_nrf70_impl.c +) + +if(NOT CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110) + target_sources(sid_pal_wifi_nrf70_impl PRIVATE + sid_pal_gnss_stub.c + ) + target_link_libraries(sid_pal_wifi_nrf70_impl PRIVATE + sid_pal_gnss_ifc + ) +endif() + +target_include_directories(sid_pal_wifi_nrf70_impl PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(sid_pal_wifi_nrf70_impl PRIVATE + sid_pal_wifi_ifc ) diff --git a/subsys/nrf70_location/sid_pal_gnss_stub.c b/subsys/nrf70_location/sid_pal_gnss_stub.c new file mode 100644 index 0000000000..5660bf89bc --- /dev/null +++ b/subsys/nrf70_location/sid_pal_gnss_stub.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include + +sid_error_t sid_pal_gnss_init(struct sid_pal_gnss_config *config) +{ + ARG_UNUSED(config); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_process_event(uint8_t event_id) +{ + ARG_UNUSED(event_id); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_schedule_scan(uint32_t scan_delay_s) +{ + ARG_UNUSED(scan_delay_s); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_cancel_scan(void) +{ + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_get_scan_payload(struct sid_pal_gnss_payload *gnss_scan_group) +{ + ARG_UNUSED(gnss_scan_group); + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_alm_demod_start(void) +{ + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_gnss_deinit(void) +{ + return SID_ERROR_NOSUPPORT; +} diff --git a/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c b/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c index 9a6f5bb5d2..64869298ff 100644 --- a/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c +++ b/subsys/nrf70_location/sid_pal_wifi_nrf70_impl.c @@ -5,7 +5,6 @@ */ #include -#include #include #include @@ -229,58 +228,3 @@ sid_error_t sid_pal_wifi_get_scan_payload(struct sid_pal_wifi_payload *wifi_scan wifi_scan_result->nbr_results); return SID_ERROR_NONE; } - -/* --------------------------------------------------------------------------- - * GNSS PAL - not available on this platform. - * - * These stubs are required because, when this PAL replaces the - * sx126x_location stub, the Sidewalk library still references the full GNSS - * PAL surface. All functions report NOSUPPORT so the GNSS method degrades - * gracefully. - * - * When SIDEWALK_SUBGHZ_RADIO_LR1110 is selected the LR1110 provides the real - * GNSS PAL, so these stubs are compiled out to avoid duplicate sid_pal_gnss_* - * symbols (the nRF70 keeps providing the Wi-Fi PAL alongside it). - * ------------------------------------------------------------------------- */ -#if !defined(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110) - -sid_error_t sid_pal_gnss_init(struct sid_pal_gnss_config *config) -{ - ARG_UNUSED(config); - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_process_event(uint8_t event_id) -{ - ARG_UNUSED(event_id); - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_schedule_scan(uint32_t scan_delay_s) -{ - ARG_UNUSED(scan_delay_s); - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_cancel_scan(void) -{ - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_get_scan_payload(struct sid_pal_gnss_payload *gnss_scan_group) -{ - ARG_UNUSED(gnss_scan_group); - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_alm_demod_start(void) -{ - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_gnss_deinit(void) -{ - return SID_ERROR_NOSUPPORT; -} - -#endif /* !CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110 */ diff --git a/subsys/semtech/CMakeLists.txt b/subsys/semtech/CMakeLists.txt index 270ca3654d..2c9e923e3f 100644 --- a/subsys/semtech/CMakeLists.txt +++ b/subsys/semtech/CMakeLists.txt @@ -68,9 +68,6 @@ target_compile_definitions(smtc_lbm INTERFACE add_subdirectory_ifdef(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X sx126x) -# When the nRF70 Wi-Fi PAL is active it provides the GNSS/Wi-Fi PAL symbols -# instead of the sx126x_location NOSUPPORT stub, so skip the stub to avoid -# duplicate symbol definitions. if(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X AND NOT CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) add_subdirectory(sx126x_location) endif() @@ -85,9 +82,13 @@ if(CONFIG_SIDEWALK_SUBGHZ_RADIO_SX126X) target_link_libraries(sidewalk_radio INTERFACE "-Wl,--start-group" sid_pal_radio_sx126x_impl - sid_pal_radio_sx126x_location_impl "-Wl,--end-group" ) + if(NOT CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) + target_link_libraries(sidewalk_radio INTERFACE + sid_pal_radio_sx126x_location_impl + ) + endif() endif() if(CONFIG_SIDEWALK_SUBGHZ_RADIO_LR1110) diff --git a/subsys/semtech/lr1110_location/CMakeLists.txt b/subsys/semtech/lr1110_location/CMakeLists.txt index 9dea1e0662..35d385f5dc 100644 --- a/subsys/semtech/lr1110_location/CMakeLists.txt +++ b/subsys/semtech/lr1110_location/CMakeLists.txt @@ -9,6 +9,12 @@ add_library(sid_pal_radio_lr11xx_location_impl STATIC smtc_modem_impl.c ) +if(NOT CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) + target_sources(sid_pal_radio_lr11xx_location_impl PRIVATE + sid_pal_wifi_lr1110_impl.c + ) +endif() + target_include_directories(sid_pal_radio_lr11xx_location_impl PRIVATE ${SEMTECH_COMMON_INCLUDES} ${LR11XX_COMMON_INCLUDES} diff --git a/subsys/semtech/lr1110_location/lr1110_location_priv.h b/subsys/semtech/lr1110_location/lr1110_location_priv.h new file mode 100644 index 0000000000..96e2dbea5f --- /dev/null +++ b/subsys/semtech/lr1110_location/lr1110_location_priv.h @@ -0,0 +1,33 @@ +/* + * Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved. + * + * AMAZON PROPRIETARY/CONFIDENTIAL + */ + +#ifndef LR1110_LOCATION_PRIV_H +#define LR1110_LOCATION_PRIV_H + +#include +#include +#include +#include +#include + +struct lr11xx_location_configuration { + struct sid_pal_gnss_config gnss_cfg; + struct sid_pal_wifi_config wifi_cfg; + bool is_init; + bool is_busy; + lr11xx_gnss_wifi_config_t *init_config; + smtc_modem_gnss_event_data_scan_done_t gnss_scan_done_data; + smtc_modem_wifi_event_data_scan_done_t wifi_scan_done_data; + bool radio_init_on_loc; +}; + +extern struct lr11xx_location_configuration location_state; + +sid_error_t sid_pal_common_location_init(void); +sid_error_t sid_pal_common_location_deinit(void); +sid_error_t sid_pal_common_process_event(void); + +#endif /* LR1110_LOCATION_PRIV_H */ diff --git a/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c b/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c index f7c2d61c08..8e53995674 100644 --- a/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c +++ b/subsys/semtech/lr1110_location/sid_pal_gnss_wifi_impl.c @@ -30,26 +30,17 @@ #include #include +#include "lr1110_location_priv.h" + #define LBM_STACK_ID 0 #define NAV3_TLV_HEADER_SIZE 3 #define SEMTECH_GNSS_NG_TAG 0x53 enum LOCATION_EVENT_TYPE { - EVENT_TYPE_LBM, -}; - -struct lr11xx_location_configuration { - struct sid_pal_gnss_config gnss_cfg; - struct sid_pal_wifi_config wifi_cfg; - bool is_init; - bool is_busy; - lr11xx_gnss_wifi_config_t *init_config; - smtc_modem_gnss_event_data_scan_done_t gnss_scan_done_data; - smtc_modem_wifi_event_data_scan_done_t wifi_scan_done_data; - bool radio_init_on_loc; + EVENT_TYPE_LBM, }; -static struct lr11xx_location_configuration location_state = {0}; +struct lr11xx_location_configuration location_state; static uint8_t grp_token = 0; void rotate_scan_grp_token() { @@ -227,15 +218,8 @@ sid_error_t sid_pal_gnss_init(struct sid_pal_gnss_config *config) { sid_error_t sid_pal_gnss_process_event(uint8_t event_id) { - return sid_pal_common_process_event(); -} - -#if !defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) -sid_error_t sid_pal_wifi_process_event(uint8_t event_id) -{ - return sid_pal_common_process_event(); + return sid_pal_common_process_event(); } -#endif /* !CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 */ sid_error_t sid_pal_gnss_alm_demod_start() { smtc_modem_almanac_demodulation_start(LBM_STACK_ID); @@ -316,61 +300,3 @@ sid_error_t sid_pal_gnss_get_scan_payload(struct sid_pal_gnss_payload *gnss_scan return SID_ERROR_NONE; } - -// END OF GNSS SPECIFIC PAL IMPLEMENTATION - -// WIFI SPECIFIC PAL IMPLEMENTATION -// -// When SIDEWALK_WIFI_LOCATION_NRF70 is enabled the nRF70 provides the Wi-Fi PAL -// (it takes priority), so the LR1110 Wi-Fi entry points are compiled out here to -// avoid duplicate sid_pal_wifi_* symbols. The LR1110 still provides GNSS. -#if !defined(CONFIG_SIDEWALK_WIFI_LOCATION_NRF70) - -sid_error_t sid_pal_wifi_init(struct sid_pal_wifi_config *config) { - location_state.wifi_cfg = *config; - return sid_pal_common_location_init(); -} - -sid_error_t sid_pal_wifi_deinit(){ - sid_pal_common_location_deinit(); - return SID_ERROR_NONE; -} - -sid_error_t sid_pal_wifi_schedule_scan(uint32_t scan_delay_s) { - if(location_state.is_busy) { - SID_PAL_LOG_INFO("Location modem is busy, cannot schedule scan"); - return SID_ERROR_BUSY; - } - - if(!location_state.is_init) { - SID_PAL_LOG_INFO("PAL is uninitialized"); - return SID_ERROR_UNINITIALIZED; - } - - location_state.is_busy = true; - smtc_modem_wifi_scan(LBM_STACK_ID, scan_delay_s); - sid_pal_common_process_event(); - - return SID_ERROR_NONE; -} - -sid_error_t sid_pal_wifi_cancel_scan() { - return SID_ERROR_NOSUPPORT; -} - -sid_error_t sid_pal_wifi_get_scan_payload(struct sid_pal_wifi_payload *wifi_scan_payload) { - uint8_t ap_idx = location_state.wifi_scan_done_data.nbr_results; - if(ap_idx < 1) { - return SID_ERROR_INSUFFICIENT_RESULTS; - } - for(uint8_t i = 0; i < location_state.wifi_scan_done_data.nbr_results; i++) { - wifi_scan_payload->results[i].rssi = location_state.wifi_scan_done_data.results[i].rssi; - memcpy(&(wifi_scan_payload->results[i].mac), location_state.wifi_scan_done_data.results[i].mac_address, SID_WIFI_MAC_ADDRESS_LENGTH); - } - - wifi_scan_payload->nbr_results = location_state.wifi_scan_done_data.nbr_results; - return SID_ERROR_NONE; -} - -#endif /* !CONFIG_SIDEWALK_WIFI_LOCATION_NRF70 */ -// END OF WIFI PAL IMPLEMENTATION diff --git a/subsys/semtech/lr1110_location/sid_pal_wifi_lr1110_impl.c b/subsys/semtech/lr1110_location/sid_pal_wifi_lr1110_impl.c new file mode 100644 index 0000000000..66e8ff880f --- /dev/null +++ b/subsys/semtech/lr1110_location/sid_pal_wifi_lr1110_impl.c @@ -0,0 +1,76 @@ +/* + * Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved. + * + * AMAZON PROPRIETARY/CONFIDENTIAL + */ + +#include +#include +#include +#include +#include + +#include "lr1110_location_priv.h" + +#define LBM_STACK_ID 0 + +sid_error_t sid_pal_wifi_init(struct sid_pal_wifi_config *config) +{ + location_state.wifi_cfg = *config; + return sid_pal_common_location_init(); +} + +sid_error_t sid_pal_wifi_process_event(uint8_t event_id) +{ + return sid_pal_common_process_event(); +} + +sid_error_t sid_pal_wifi_deinit(void) +{ + sid_pal_common_location_deinit(); + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_schedule_scan(uint32_t scan_delay_s) +{ + if (location_state.is_busy) { + SID_PAL_LOG_INFO("Location modem is busy, cannot schedule scan"); + return SID_ERROR_BUSY; + } + + if (!location_state.is_init) { + SID_PAL_LOG_INFO("PAL is uninitialized"); + return SID_ERROR_UNINITIALIZED; + } + + location_state.is_busy = true; + smtc_modem_wifi_scan(LBM_STACK_ID, scan_delay_s); + sid_pal_common_process_event(); + + return SID_ERROR_NONE; +} + +sid_error_t sid_pal_wifi_cancel_scan(void) +{ + return SID_ERROR_NOSUPPORT; +} + +sid_error_t sid_pal_wifi_get_scan_payload(struct sid_pal_wifi_payload *wifi_scan_payload) +{ + uint8_t ap_idx = location_state.wifi_scan_done_data.nbr_results; + + if (ap_idx < 1) { + return SID_ERROR_INSUFFICIENT_RESULTS; + } + + for (uint8_t i = 0; i < location_state.wifi_scan_done_data.nbr_results; i++) { + wifi_scan_payload->results[i].rssi = + location_state.wifi_scan_done_data.results[i].rssi; + memcpy(&(wifi_scan_payload->results[i].mac), + location_state.wifi_scan_done_data.results[i].mac_address, + SID_WIFI_MAC_ADDRESS_LENGTH); + } + + wifi_scan_payload->nbr_results = location_state.wifi_scan_done_data.nbr_results; + return SID_ERROR_NONE; +} From 1efe9daea3c5134e01e964a53495301741e3a9d6 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 13:44:03 +0200 Subject: [PATCH 4/7] kconfig: move nRF70 Wi-Fi location options to subsys Relocate nRF70 location Kconfig under subsys/nrf70_location and imply the Wi-Fi stack from SIDEWALK_WIFI_LOCATION_NRF70 instead of tying it directly to the shield. Co-authored-by: Cursor --- Kconfig | 133 +--------------------------------- subsys/nrf70_location/Kconfig | 65 +++++++++++++++++ 2 files changed, 66 insertions(+), 132 deletions(-) create mode 100644 subsys/nrf70_location/Kconfig diff --git a/Kconfig b/Kconfig index 8568f5b4f4..16f78e4e6a 100644 --- a/Kconfig +++ b/Kconfig @@ -233,138 +233,7 @@ config SIDEWALK_USE_PREBUILT_LIBRARIES Building from sources requires additional dependencies, not released with nRF Connect SDK. -if SHIELD_NRF7002EB2 - -config WIFI - default y - -config NETWORKING - default y - -config NET_L2_ETHERNET - default y - -config NET_OFFLOAD - default y - -config WIFI_NRF70 - default y - -# NRF70_SCAN_ONLY and NRF_WIFI_PATCHES_EXT_FLASH_DISABLED are choice members -# (NRF70_OPER_MODES / NRF_WIFI_PATCHES_EXT_FLASH_SUPPORT), so the default has -# to be set on the choice itself, not on the member config. -choice NRF70_OPER_MODES - default NRF70_SCAN_ONLY -endchoice - -choice NRF_WIFI_PATCHES_EXT_FLASH_SUPPORT - default NRF_WIFI_PATCHES_EXT_FLASH_DISABLED -endchoice - -endif # SHIELD_NRF7002EB2 - -config SIDEWALK_WIFI_LOCATION_NRF70 - bool "nRF70 Wi-Fi location PAL" - depends on WIFI - default y - # NETWORKING is already forced on via `if SHIELD_NRF7002EB2` above; - # selecting it again here would create a WIFI -> NETWORKING -> WIFI - # Kconfig dependency loop (NETWORKING's select is conditioned on WIFI). - select NET_MGMT - select NET_MGMT_EVENT - select NET_MGMT_EVENT_INFO - help - Provide the Sidewalk Wi-Fi PAL (sid_pal_wifi_ifc.h) backed by an - asynchronous Zephyr net_mgmt Wi-Fi scan on the nRF70. This lets the - Sidewalk location library drive the Wi-Fi scan by itself - (init/schedule_scan/get_scan_payload). - - When SIDEWALK_SUBGHZ_RADIO_SX126X is also selected this PAL replaces - the sx126x_location NOSUPPORT stub, so the (lora_fsk) Sidewalk library - actually invokes the Wi-Fi PAL. - - This PAL can also coexist with SIDEWALK_SUBGHZ_RADIO_LR1110 (for - example the nRF Sidewalk EB together with an nRF7002 EB): whenever WIFI - is enabled the nRF70 provides the Wi-Fi PAL (taking priority), while the - LR1110 keeps providing the GNSS PAL and the sub-GHz radio. When WIFI is - disabled the LR1110 provides the Wi-Fi PAL itself. - -if SIDEWALK_WIFI_LOCATION_NRF70 - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TIMEOUT_MS - int "nRF70 Wi-Fi scan timeout (ms)" - default 20000 - range 1000 60000 - help - Backstop timeout for a single nRF70 Wi-Fi scan. If the net_mgmt - scan-done event does not arrive within this window the scan is - abandoned and reported as timed out, so the Wi-Fi PAL cannot get - stuck busy. Increase it for slow passive or multi-band scans. - -choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_FILTER - prompt "nRF70 Wi-Fi location scan band filter" - # nrf7002eb2 is only verified/tuned for 2.4 GHz so far; other Wi-Fi - # hardware defaults to scanning both bands. - default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ if SHIELD_NRF7002EB2 - default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ - help - Select which Wi-Fi frequency bands the nRF70 location scan covers. - Band filtering is applied via wifi_scan_params.bands. See the nRF - Connect SDK "Optimizing scan operation" guide for scan time/energy - trade-offs per profile. - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ - bool "2.4 GHz only" - help - Scan only the 2.4 GHz band. Matches the "2.4 GHz Active" profile - in the nRF Connect SDK scan optimization guide. - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ - bool "2.4 and 5 GHz" - help - Scan both the 2.4 GHz and 5 GHz bands. This is the typical profile - for Wi-Fi location when dual-band AP visibility is needed. - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_ALL - bool "All regulatory bands (2.4/5/6 GHz)" - help - Do not restrict wifi_scan_params.bands; scan every band the - regulatory domain allows. - -endchoice - -choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TYPE - prompt "nRF70 Wi-Fi location scan type" - # nrf7002eb2 is only verified/tuned for passive scanning so far; other - # Wi-Fi hardware defaults to active scanning. - default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE if SHIELD_NRF7002EB2 - default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE - help - Sets the scan_type hint passed to the driver. It's only a hint - - the chip or the regulatory domain can still fall back to passive - scanning on channels where active probing isn't allowed (e.g. - 2.4 GHz channels 12-14). Also make sure - CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN stays disabled (its default), - since it overrides this hint and forces passive scanning on every - channel regardless of what you pick here. - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE - bool "Active" - help - Sends probe requests (WIFI_SCAN_TYPE_ACTIVE). Faster than passive, - but draws more instantaneous transmit power. - -config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE - bool "Passive" - help - Only listens for beacons, no probe requests - (WIFI_SCAN_TYPE_PASSIVE). Slower than active, but uses less - instantaneous transmit power and works on channels where active - probing is restricted. - -endchoice - -endif # SIDEWALK_WIFI_LOCATION_NRF70 +rsource "subsys/nrf70_location/Kconfig" rsource "Kconfig.dependencies" rsource "utils/Kconfig" diff --git a/subsys/nrf70_location/Kconfig b/subsys/nrf70_location/Kconfig new file mode 100644 index 0000000000..e5ff97e425 --- /dev/null +++ b/subsys/nrf70_location/Kconfig @@ -0,0 +1,65 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config SIDEWALK_WIFI_LOCATION_NRF70 + bool "nRF70 Wi-Fi location PAL" + default y if SHIELD_NRF7002EB2 + select NET_MGMT + select NET_MGMT_EVENT + select NET_MGMT_EVENT_INFO + select WIFI + select NETWORKING + select WIFI_NRF70 + help + Wi-Fi PAL for Sidewalk location using nRF70 net_mgmt scan. + +if SIDEWALK_WIFI_LOCATION_NRF70 + +choice NRF70_OPER_MODES + default NRF70_SCAN_ONLY +endchoice + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TIMEOUT_MS + int "nRF70 Wi-Fi scan timeout (ms)" + default 20000 + range 1000 60000 + help + Backstop timeout for a single nRF70 Wi-Fi scan. + +choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_FILTER + prompt "nRF70 Wi-Fi location scan band filter" + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ if SHIELD_NRF7002EB2 + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ + help + Select which Wi-Fi frequency bands the nRF70 location scan covers. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4GHZ + bool "2.4 GHz only" + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_2_4_AND_5_GHZ + bool "2.4 and 5 GHz" + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_BAND_ALL + bool "All regulatory bands (2.4/5/6 GHz)" + +endchoice + +choice SIDEWALK_WIFI_LOCATION_NRF70_SCAN_TYPE + prompt "nRF70 Wi-Fi location scan type" + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE if SHIELD_NRF7002EB2 + default SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE + help + Scan type hint passed to the nRF70 driver. + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_ACTIVE + bool "Active" + +config SIDEWALK_WIFI_LOCATION_NRF70_SCAN_PASSIVE + bool "Passive" + +endchoice + +endif # SIDEWALK_WIFI_LOCATION_NRF70 From 28b54aea5e90637b35b263e920b825675c08f39e Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 13:44:03 +0200 Subject: [PATCH 5/7] utils: report nRF7002 shield in startup banner Show nRF7002 EB-II in the Sidewalk startup banner when the nRF70 Wi-Fi shield is present, and fix the SX1262 shield name preprocessor check. Co-authored-by: Cursor --- utils/include/sidewalk_version.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/include/sidewalk_version.h b/utils/include/sidewalk_version.h index 5b574d2d81..d041a4e248 100644 --- a/utils/include/sidewalk_version.h +++ b/utils/include/sidewalk_version.h @@ -11,9 +11,12 @@ #ifdef CONFIG_DT_HAS_SEMTECH_LR1110_ENABLED #define SHIELD_NAME "Semtech lr1110" -#elif defined(CONFIG_DT_HAS_SEMTECH_SX1262_ENABLED) | \ +#elif defined(CONFIG_DT_HAS_SEMTECH_SX1262_ENABLED) || \ defined(CONFIG_DT_HAS_SEMTECH_SX1262_NEW_ENABLED) #define SHIELD_NAME "Semtech sx1262" +#elif defined(CONFIG_DT_HAS_NORDIC_NRF7002_SPI_ENABLED) || \ + defined(CONFIG_DT_HAS_NORDIC_NRF7002_QSPI_ENABLED) +#define SHIELD_NAME "nRF7002 EB-II" #endif #ifndef SHIELD_NAME From 510ab2ebe46d9f3a0832beabe6c7f9d019094465 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 13:44:03 +0200 Subject: [PATCH 6/7] gitignore: ignore local provision certificate file Co-authored-by: Cursor --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5cdbea3bfc..8b4520baf0 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ compliance.xml tools/provision/*.hex tools/provision/*.bin +tools/provision/certificate.json From 2b3ac8ec774bb5dabf310889c6bc71bcdaa00604 Mon Sep 17 00:00:00 2001 From: Bartosz Ludwin Date: Tue, 21 Jul 2026 15:20:11 +0200 Subject: [PATCH 7/7] samples: sid_end_device: add nrf7002eb2 Twister build Add a build-only DUT sample entry so CI compiles the nRF70 Wi-Fi location PAL configuration with the nrf7002eb2 shield. Co-authored-by: Cursor --- samples/sid_end_device/sample.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/samples/sid_end_device/sample.yaml b/samples/sid_end_device/sample.yaml index e3bdcb6679..fa40ce6d95 100644 --- a/samples/sid_end_device/sample.yaml +++ b/samples/sid_end_device/sample.yaml @@ -157,6 +157,18 @@ tests: - cli - lr1110 + sample.sidewalk.dut.nrf7002eb2: + platform_exclude: + - nrf54l15dk/nrf54l15/cpuapp/ns + extra_args: + - OVERLAY_CONFIG="overlay-dut.conf" + - SHIELD=nrf7002eb2 + extra_configs: + - CONFIG_SIDEWALK_APPLICATION_NAME="dut.nrf7002" + tags: + - cli + - nrf70 + sample.sidewalk.dut.nrf_sidewalk_eb: platform_exclude: - nrf54l15dk/nrf54l15/cpuapp/ns