diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 04a226f23d24..bacf3cf4db26 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -581,7 +581,7 @@ - "tests/subsys/suit/**/*" "CI-test-low-level": - - "applications/sw_io_devices/**/*" + - "applications/sdp/**/*" - "drivers/gpio/**/*" - "dts/bindings/gpio/**/*" - "include/drivers/gpio/**/*" diff --git a/CODEOWNERS b/CODEOWNERS index a841ea278a70..522573196d6d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -34,9 +34,9 @@ /applications/matter_weather_station/ @nrfconnect/ncs-matter /applications/nrf5340_audio/ @nrfconnect/ncs-audio /applications/nrf_desktop/ @nrfconnect/ncs-si-bluebagel +/applications/sdp/ @masz-nordic /applications/serial_lte_modem/ @nrfconnect/ncs-co-networking @nrfconnect/ncs-iot-oulu /applications/serial_lte_modem/src/lwm2m_carrier/ @nrfconnect/ncs-carrier -/applications/sw_io_devices/ @masz-nordic /applications/zigbee_weather_station/ @milewr /applications/**/*.rst @nrfconnect/ncs-doc-owners diff --git a/applications/sw_io_devices/gpio/CMakeLists.txt b/applications/sdp/gpio/CMakeLists.txt similarity index 60% rename from applications/sw_io_devices/gpio/CMakeLists.txt rename to applications/sdp/gpio/CMakeLists.txt index 61a0cf2816ea..5a428c69b31e 100644 --- a/applications/sw_io_devices/gpio/CMakeLists.txt +++ b/applications/sdp/gpio/CMakeLists.txt @@ -9,4 +9,6 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(emulated_gpio) +target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG app PRIVATE src/nrfe_icmsg.c) +target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX app PRIVATE src/nrfe_mbox.c) target_sources(app PRIVATE src/main.c) diff --git a/applications/sw_io_devices/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.conf b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.conf similarity index 100% rename from applications/sw_io_devices/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.conf rename to applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.conf diff --git a/applications/sw_io_devices/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay similarity index 76% rename from applications/sw_io_devices/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay rename to applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay index 527705970859..80ecba58376d 100644 --- a/applications/sw_io_devices/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay +++ b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay @@ -19,17 +19,6 @@ }; }; }; - - ipc { - ipc0: ipc0 { - compatible = "zephyr,ipc-icmsg"; - tx-region = <&sram_tx>; - rx-region = <&sram_rx>; - mboxes = <&cpuflpr_vevif_rx 16>, <&cpuflpr_vevif_tx 15>; - mbox-names = "rx", "tx"; - status = "okay"; - }; - }; }; &cpuflpr_vevif_rx { diff --git a/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_icmsg.overlay b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_icmsg.overlay new file mode 100644 index 000000000000..002cf9b3aded --- /dev/null +++ b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_icmsg.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icmsg"; + tx-region = <&sram_tx>; + rx-region = <&sram_rx>; + mboxes = <&cpuflpr_vevif_rx 21>, <&cpuflpr_vevif_tx 20>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + }; +}; diff --git a/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_mbox.overlay b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_mbox.overlay new file mode 100644 index 000000000000..57534433d353 --- /dev/null +++ b/applications/sdp/gpio/boards/nrf54l15dk_nrf54l15_cpuflpr_mbox.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + mbox_consumer: mbox_consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&cpuflpr_vevif_rx 21>, <&cpuflpr_vevif_tx 20>; + mbox-names = "rx", "tx"; + }; +}; diff --git a/applications/sdp/gpio/include/main.h b/applications/sdp/gpio/include/main.h new file mode 100644 index 000000000000..e0a0e0cf0c35 --- /dev/null +++ b/applications/sdp/gpio/include/main.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef MAIN_H__ +#define MAIN_H__ + +#include +#include + +#if !defined(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG) && !defined(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX) +#error "Define communication backend type" +#endif + +void process_packet(nrfe_gpio_data_packet_t *packet); +int backend_init(void); + +#endif /* MAIN_H__ */ diff --git a/applications/sdp/gpio/prj.conf b/applications/sdp/gpio/prj.conf new file mode 100644 index 000000000000..79f89305ca0d --- /dev/null +++ b/applications/sdp/gpio/prj.conf @@ -0,0 +1 @@ +CONFIG_MBOX=y diff --git a/applications/sdp/gpio/sample.yaml b/applications/sdp/gpio/sample.yaml new file mode 100644 index 000000000000..05eaef699158 --- /dev/null +++ b/applications/sdp/gpio/sample.yaml @@ -0,0 +1,28 @@ +sample: + name: eGPIO application + description: SW-defined GPIO application +common: + integration_platforms: + - nrf54l15dk/nrf54l15/cpuflpr +tests: + applications.sdp.egpio_mbox: + build_only: true + sysbuild: true + platform_allow: nrf54l15dk/nrf54l15/cpuflpr + tags: ci_build sysbuild gpio + extra_args: + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuflpr_mbox.overlay" + extra_configs: + - CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX=y + + applications.sdp.egpio_icmsg: + build_only: true + sysbuild: true + platform_allow: nrf54l15dk/nrf54l15/cpuflpr + tags: ci_build sysbuild gpio + extra_args: + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuflpr_icmsg.overlay" + extra_configs: + - CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG=y + - CONFIG_IPC_SERVICE=y + - CONFIG_IPC_SERVICE_BACKEND_ICMSG=y diff --git a/applications/sw_io_devices/gpio/src/main.c b/applications/sdp/gpio/src/main.c similarity index 78% rename from applications/sw_io_devices/gpio/src/main.c rename to applications/sdp/gpio/src/main.c index 0ab0b7d83268..fc31686ae2df 100644 --- a/applications/sw_io_devices/gpio/src/main.c +++ b/applications/sdp/gpio/src/main.c @@ -4,25 +4,14 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ +#include "../include/main.h" + #include #include -#include - -#include - #include #include #include -static struct ipc_ept ep; - -volatile uint32_t bound_sem = 1; - -static void ep_bound(void *priv) -{ - bound_sem = 0; -} - static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) { if (flags & GPIO_PULL_UP) { @@ -122,10 +111,8 @@ static void gpio_nrfe_port_toggle_bits(uint16_t toggle_mask) nrf_vpr_csr_vio_out_toggle_set(toggle_mask); } -static void ep_recv(const void *data, size_t len, void *priv) +void process_packet(nrfe_gpio_data_packet_t *packet) { - nrfe_gpio_data_packet_t *packet = (nrfe_gpio_data_packet_t *)data; - if (packet->port != 2) { return; } @@ -153,42 +140,15 @@ static void ep_recv(const void *data, size_t len, void *priv) } } -static struct ipc_ept_cfg ep_cfg = { - .cb = { - .bound = ep_bound, - .received = ep_recv, - }, -}; - int main(void) { - int ret; - const struct device *ipc0_instance; - volatile uint32_t delay = 0; - -#if !defined(CONFIG_SYS_CLOCK_EXISTS) - /* Wait a little bit for IPC service to be ready on APP side */ - while (delay < 1000) { - delay++; - } -#endif - - ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0)); + int ret = 0; - ret = ipc_service_open_instance(ipc0_instance); - if ((ret < 0) && (ret != -EALREADY)) { - return ret; - } - - ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); + ret = backend_init(); if (ret < 0) { - return ret; + return 0; } - /* Wait for endpoint to be bound */ - while (bound_sem != 0) { - }; - if (!nrf_vpr_csr_rtperiph_enable_check()) { nrf_vpr_csr_rtperiph_enable_set(true); } diff --git a/applications/sdp/gpio/src/nrfe_icmsg.c b/applications/sdp/gpio/src/nrfe_icmsg.c new file mode 100644 index 000000000000..64d7478bd99f --- /dev/null +++ b/applications/sdp/gpio/src/nrfe_icmsg.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "../include/main.h" +#include + +static struct ipc_ept ep; + +volatile uint32_t bound_sem = 1; + +static void ep_bound(void *priv) +{ + bound_sem = 0; +} + +static void ep_recv(const void *data, size_t len, void *priv) +{ + (void)len; + (void)priv; + + process_packet((nrfe_gpio_data_packet_t *)data); +} + +static struct ipc_ept_cfg ep_cfg = { + .cb = { + .bound = ep_bound, + .received = ep_recv, + }, +}; + +int backend_init(void) +{ + int ret = 0; + const struct device *ipc0_instance; + volatile uint32_t delay = 0; + +#if !defined(CONFIG_SYS_CLOCK_EXISTS) + /* Wait a little bit for IPC service to be ready on APP side */ + while (delay < 1000) { + delay++; + } +#endif + + ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0)); + + ret = ipc_service_open_instance(ipc0_instance); + if ((ret < 0) && (ret != -EALREADY)) { + return ret; + } + + ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); + if (ret < 0) { + return ret; + } + + /* Wait for endpoint to be bound */ + while (bound_sem != 0) { + }; + + return 0; +} diff --git a/applications/sdp/gpio/src/nrfe_mbox.c b/applications/sdp/gpio/src/nrfe_mbox.c new file mode 100644 index 000000000000..c0573b47a855 --- /dev/null +++ b/applications/sdp/gpio/src/nrfe_mbox.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "../include/main.h" +#include + +static const struct mbox_dt_spec rx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), rx); + +/** + * @brief Callback function for when a message is received from the mailbox + * @param instance Pointer to the mailbox device instance + * @param channel Unused, but required by the mailbox API + * @param user_data Pointer to the received message + * @param msg_data Unused, but required by the mailbox API + * + * This function is called when a message is received from the mailbox. + * It is responsible for handling the received data and logging any errors. + */ +static void mbox_callback(const struct device *instance, uint32_t channel, void *user_data, + struct mbox_msg *msg_data) +{ + /* Unused parameters */ + (void)msg_data; + + /* Check for invalid arguments */ + if (user_data == NULL) { + return; + } + + nrfe_gpio_mbox_data_t *rx_data = (nrfe_gpio_mbox_data_t *)user_data; + + /* Try and get lock for the shared data structure */ + if (atomic_flag_test_and_set(&rx_data->lock.locked)) { + /* Return in case lock is not acquired (used by other core)*/ + return; + } + + nrfe_gpio_data_packet_t *packet = (nrfe_gpio_data_packet_t *)&rx_data->data; + + process_packet(packet); + + /* Clear shared_data.buffer_size (there is no more data available) + * This is necessary so that the other core knows that the data has been read + */ + rx_data->lock.data_size = 0; + + /* We are finished with the shared data structure, so we can release the lock */ + atomic_flag_clear(&rx_data->lock.locked); +} + +/** + * @brief Initialize the mailbox driver. + * + * This function sets up the mailbox receive channel with the callback + * function specified in the DT node. + * + * @return 0 on success, negative error code on failure. + */ +static int mbox_init(void *shared_data) +{ + int ret; + + /* Register the callback function for the mailbox receive channel */ + ret = mbox_register_callback_dt(&rx_channel, mbox_callback, shared_data); + if (ret < 0) { + return ret; + } + + /* Enable the mailbox receive channel */ + return mbox_set_enabled_dt(&rx_channel, true); +} + +int backend_init(void) +{ + int ret = 0; + + static nrfe_gpio_mbox_data_t *rx_data = + (nrfe_gpio_mbox_data_t *)((uint8_t *)(DT_REG_ADDR(DT_NODELABEL(sram_rx)))); + + ret = mbox_init((void *)rx_data); + if (ret < 0) { + return ret; + } + + /* clear the buffer locks and their size holders */ + atomic_flag_clear(&rx_data->lock.locked); + rx_data->lock.data_size = 0; + + return 0; +} diff --git a/applications/sw_io_devices/gpio/sysbuild.conf b/applications/sdp/gpio/sysbuild.conf similarity index 100% rename from applications/sw_io_devices/gpio/sysbuild.conf rename to applications/sdp/gpio/sysbuild.conf diff --git a/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.conf b/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.conf deleted file mode 100644 index 4d4345cb7004..000000000000 --- a/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.conf +++ /dev/null @@ -1,44 +0,0 @@ -# Single-threaded -CONFIG_MULTITHREADING=n -CONFIG_KERNEL_MEM_POOL=n -CONFIG_LOG=n - -# Drivers and peripherals -CONFIG_I2C=n -CONFIG_WATCHDOG=n -CONFIG_GPIO=n -CONFIG_PINCTRL=n -CONFIG_SPI=n -CONFIG_SERIAL=n -CONFIG_FLASH=n - -# Power management -CONFIG_PM=n - -# Interrupts -CONFIG_DYNAMIC_INTERRUPTS=n -CONFIG_IRQ_OFFLOAD=n - -# Memory protection -CONFIG_THREAD_STACK_INFO=n -CONFIG_THREAD_CUSTOM_DATA=n -CONFIG_FPU=n - -# Boot -CONFIG_BOOT_BANNER=n - -# Console -CONFIG_CONSOLE=n -CONFIG_UART_CONSOLE=n -CONFIG_STDOUT_CONSOLE=n -CONFIG_PRINTK=n -CONFIG_EARLY_CONSOLE=n - -# Build -CONFIG_SIZE_OPTIMIZATIONS=y - -# No timer support in the kernel -CONFIG_SYS_CLOCK_EXISTS=n - -CONFIG_OUTPUT_DISASSEMBLY=y -CONFIG_COMMON_LIBC_MALLOC=n diff --git a/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.overlay b/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.overlay deleted file mode 100644 index 527705970859..000000000000 --- a/applications/sw_io_devices/gpio/boards/nrf54l15pdk_nrf54l15_cpuflpr.overlay +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -/ { - soc { - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - - sram_tx: memory@20018000 { - reg = <0x20018000 0x0800>; - }; - - sram_rx: memory@20020000 { - reg = <0x20020000 0x0800>; - }; - }; - }; - - ipc { - ipc0: ipc0 { - compatible = "zephyr,ipc-icmsg"; - tx-region = <&sram_tx>; - rx-region = <&sram_rx>; - mboxes = <&cpuflpr_vevif_rx 16>, <&cpuflpr_vevif_tx 15>; - mbox-names = "rx", "tx"; - status = "okay"; - }; - }; -}; - -&cpuflpr_vevif_rx { - status = "okay"; -}; - -&cpuflpr_vevif_tx { - status = "okay"; -}; - -&gpio0 { - status = "disabled"; -}; - -&gpio1 { - status = "disabled"; -}; - -&gpio2 { - status = "disabled"; -}; - -&gpiote20 { - status = "disabled"; -}; - -&gpiote30 { - status = "disabled"; -}; - -&grtc { - status = "disabled"; -}; - -&uart20 { - status = "disabled"; -}; - -&uart30 { - status = "disabled"; -}; - -&pwm20 { - status = "disabled"; -}; diff --git a/applications/sw_io_devices/gpio/prj.conf b/applications/sw_io_devices/gpio/prj.conf deleted file mode 100644 index 530e6ab86604..000000000000 --- a/applications/sw_io_devices/gpio/prj.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IPC_SERVICE=y -CONFIG_IPC_SERVICE_BACKEND_ICMSG=y -CONFIG_MBOX=y diff --git a/applications/sw_io_devices/gpio/sample.yaml b/applications/sw_io_devices/gpio/sample.yaml deleted file mode 100644 index e4a8a7cd00e1..000000000000 --- a/applications/sw_io_devices/gpio/sample.yaml +++ /dev/null @@ -1,13 +0,0 @@ -sample: - name: eGPIO application - description: SW-defined GPIO application -common: - integration_platforms: - - nrf54l15dk/nrf54l15/cpuflpr - - nrf54l15pdk/nrf54l15/cpuflpr -tests: - applications.sw_io_devices.egpio: - sysbuild: true - build_only: true - platform_allow: nrf54l15dk/nrf54l15/cpuflpr nrf54l15pdk/nrf54l15/cpuflpr - tags: ci_build sysbuild diff --git a/cmake/sysbuild/sdp.cmake b/cmake/sysbuild/sdp.cmake new file mode 100644 index 000000000000..d935a3887051 --- /dev/null +++ b/cmake/sysbuild/sdp.cmake @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + +# Update eGPIO images KConfig based on SDP configuration. +# +# Usage: +# egpio_update_kconfig() +# +function(egpio_update_kconfig) + if(SB_CONFIG_EGPIO_BACKEND_MBOX) + foreach(image ${PRE_CMAKE_IMAGES}) + set_config_bool(${image} CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX y) + endforeach() + if(DEFINED SB_CONFIG_SOC_NRF54L15) + sysbuild_cache_set(VAR flpr_egpio_EXTRA_DTC_OVERLAY_FILE APPEND REMOVE_DUPLICATES "./boards/nrf54l15dk_nrf54l15_cpuflpr_mbox.overlay") + endif() + sysbuild_cache_set(VAR ${DEFAULT_IMAGE}_SNIPPET APPEND REMOVE_DUPLICATES "emulated-gpio-mbox") + message(STATUS "eGPIO: Using MBOX backend") + elseif(SB_CONFIG_EGPIO_BACKEND_ICMSG) + foreach(image ${PRE_CMAKE_IMAGES}) + set_config_bool(${image} CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG y) + endforeach() + set_config_bool(flpr_egpio CONFIG_IPC_SERVICE y) + set_config_bool(flpr_egpio CONFIG_IPC_SERVICE_BACKEND_ICMSG y) + if(DEFINED SB_CONFIG_SOC_NRF54L15) + sysbuild_cache_set(VAR flpr_egpio_EXTRA_DTC_OVERLAY_FILE APPEND REMOVE_DUPLICATES "./boards/nrf54l15dk_nrf54l15_cpuflpr_icmsg.overlay") + endif() + sysbuild_cache_set(VAR ${DEFAULT_IMAGE}_SNIPPET APPEND REMOVE_DUPLICATES "emulated-gpio-icmsg") + message(STATUS "eGPIO: Using ICMSG backend") + endif() +endfunction() + +# If eGPIO FLPR application is enabled, update Kconfigs +if(SB_CONFIG_EGPIO_FLPR_APPLICATION) + egpio_update_kconfig() +endif() diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 8a288bc46522..3f234f723fc8 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -5,4 +5,13 @@ # zephyr_library_amend() -zephyr_library_sources_ifdef(CONFIG_GPIO_NRFE gpio_nrfe.c) + +if(CONFIG_GPIO_NRFE) + if(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG) + zephyr_library_sources(gpio_nrfe_icmsg.c) + elseif(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX) + zephyr_library_sources(gpio_nrfe_mbox.c) + endif() + + zephyr_library_sources(gpio_nrfe.c) +endif() diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 52aee39fa231..8c2452d9e5c4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -18,3 +18,23 @@ config GPIO_NRFE_INIT_PRIORITY eGPIO driver device initialization priority. eGPIO initialization depends on IPC initialization which is done at the same init level and has init priority equal to 46. + +choice GPIO_NRFE_EGPIO_BACKEND + prompt "eGPIO driver backend type" + default GPIO_NRFE_EGPIO_BACKEND_ICMSG + help + Select the backend type for the eGPIO driver and application. + +config GPIO_NRFE_EGPIO_BACKEND_MBOX + bool "MBOX" + help + Use MBOX backend driver for eGPIO. + The MBOX version is more resource-efficient than the ICMSG backend, + but needs to have a shared structure defined as a communication channel. + +config GPIO_NRFE_EGPIO_BACKEND_ICMSG + bool "ICMSG" + help + Use ICMSG backend driver for eGPIO. + +endchoice diff --git a/drivers/gpio/gpio_nrfe.c b/drivers/gpio/gpio_nrfe.c index 0453264a42a4..fd443b5ca7d0 100644 --- a/drivers/gpio/gpio_nrfe.c +++ b/drivers/gpio/gpio_nrfe.c @@ -6,29 +6,10 @@ #define DT_DRV_COMPAT nordic_nrf_egpio -#include #include #include -#include - -#include - -K_SEM_DEFINE(bound_sem, 0, 1); - -static void ep_bound(void *priv) -{ - k_sem_give(&bound_sem); -} - -static struct ipc_ept_cfg ep_cfg = { - .cb = { - .bound = ep_bound, - .received = NULL, - }, -}; - -static struct ipc_ept ep; +#include "gpio_nrfe.h" struct gpio_nrfe_data { /* gpio_driver_data needs to be first */ @@ -46,16 +27,6 @@ static inline const struct gpio_nrfe_cfg *get_port_cfg(const struct device *port return port->config; } -static int gpio_send(nrfe_gpio_data_packet_t *msg) -{ - if (ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)) - == sizeof(nrfe_gpio_data_packet_t)) { - return 0; - } else { - return -EIO; - } -} - static int gpio_nrfe_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { nrfe_gpio_data_packet_t msg = {.opcode = NRFE_GPIO_PIN_CONFIGURE, @@ -112,25 +83,6 @@ static int gpio_nrfe_port_toggle_bits(const struct device *port, gpio_port_pins_ return gpio_send(&msg); } -static int gpio_nrfe_init(const struct device *port) -{ - const struct device *ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0)); - int ret = ipc_service_open_instance(ipc0_instance); - - if ((ret < 0) && (ret != -EALREADY)) { - return ret; - } - - ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); - if (ret < 0) { - return ret; - } - - k_sem_take(&bound_sem, K_FOREVER); - - return 0; -} - static const struct gpio_driver_api gpio_nrfe_drv_api_funcs = { .pin_configure = gpio_nrfe_pin_configure, .port_set_masked_raw = gpio_nrfe_port_set_masked_raw, diff --git a/drivers/gpio/gpio_nrfe.h b/drivers/gpio/gpio_nrfe.h new file mode 100644 index 000000000000..0a797e429559 --- /dev/null +++ b/drivers/gpio/gpio_nrfe.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef GPIO_NRFE_H__ +#define GPIO_NRFE_H__ + +#include +#include + +#if !defined(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG) && !defined(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX) +#error "Configure communication backend type" +#endif + +int gpio_send(nrfe_gpio_data_packet_t *msg); +int gpio_nrfe_init(const struct device *port); + +#endif /* GPIO_NRFE_H__ */ diff --git a/drivers/gpio/gpio_nrfe_icmsg.c b/drivers/gpio/gpio_nrfe_icmsg.c new file mode 100644 index 000000000000..b3e2577e7ff1 --- /dev/null +++ b/drivers/gpio/gpio_nrfe_icmsg.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include + +#include "gpio_nrfe.h" + +#if defined(CONFIG_MULTITHREADING) +K_SEM_DEFINE(bound_sem, 0, 1); +#else +static volatile uint32_t bound_sem = 1; +#endif + +static void ep_bound(void *priv) +{ +#if defined(CONFIG_MULTITHREADING) + k_sem_give(&bound_sem); +#else + bound_sem = 0; +#endif +} + +static struct ipc_ept_cfg ep_cfg = { + .cb = { + .bound = ep_bound, + .received = NULL, + }, +}; + +static struct ipc_ept ep; + +int gpio_send(nrfe_gpio_data_packet_t *msg) +{ + if (ipc_service_send(&ep, (void *)msg, sizeof(nrfe_gpio_data_packet_t)) == + sizeof(nrfe_gpio_data_packet_t)) { + return 0; + } else { + return -EIO; + } +} + +int gpio_nrfe_init(const struct device *port) +{ + const struct device *ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0)); + int ret = ipc_service_open_instance(ipc0_instance); + + if ((ret < 0) && (ret != -EALREADY)) { + return ret; + } + + ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); + if (ret < 0) { + return ret; + } + +#if defined(CONFIG_MULTITHREADING) + k_sem_take(&bound_sem, K_FOREVER); +#else + while (bound_sem != 0) { + } +#endif + + return 0; +} diff --git a/drivers/gpio/gpio_nrfe_mbox.c b/drivers/gpio/gpio_nrfe_mbox.c new file mode 100644 index 000000000000..88394c990c6d --- /dev/null +++ b/drivers/gpio/gpio_nrfe_mbox.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include + +#include "gpio_nrfe.h" + +static const struct mbox_dt_spec tx_channel = MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), tx); +static nrfe_gpio_mbox_data_t *tx_data = + (nrfe_gpio_mbox_data_t *)((uint8_t *)(DT_REG_ADDR(DT_NODELABEL(sram_tx)))); +#define MAX_MSG_SIZE (DT_REG_SIZE(DT_NODELABEL(sram_tx))) + +int gpio_send(nrfe_gpio_data_packet_t *msg) +{ + printk("Sending opcode: %d, pin %d, port %d, flag: %d\n", msg->opcode, msg->pin, msg->port, + msg->flags); + /* Try and get lock */ + if (atomic_flag_test_and_set(&tx_data->lock.locked)) { + /* Return -1 in case lock is not acquired (used by other core)*/ + return -1; + } + + memcpy((void *)&tx_data->data, (void *)msg, sizeof(nrfe_gpio_data_packet_t)); + tx_data->lock.data_size = sizeof(nrfe_gpio_data_packet_t); + + /* Release lock */ + atomic_flag_clear(&tx_data->lock.locked); + + return mbox_send_dt(&tx_channel, NULL); +} + +int gpio_nrfe_init(const struct device *port) +{ + return 0; +} diff --git a/include/drivers/gpio/nrfe_gpio.h b/include/drivers/gpio/nrfe_gpio.h index 18c3b2a0bef9..0aa91c8887cc 100644 --- a/include/drivers/gpio/nrfe_gpio.h +++ b/include/drivers/gpio/nrfe_gpio.h @@ -8,6 +8,7 @@ #define NRFE_GPIO_H #include +#include #ifdef __cplusplus extern "C" { @@ -32,6 +33,11 @@ typedef struct __packed { */ } nrfe_gpio_data_packet_t; +typedef struct __packed { + nrfe_shared_data_lock_t lock; + nrfe_gpio_data_packet_t data; +} nrfe_gpio_mbox_data_t; + #ifdef __cplusplus } #endif diff --git a/include/sdp/nrfe_common.h b/include/sdp/nrfe_common.h new file mode 100644 index 000000000000..558ca7f6c166 --- /dev/null +++ b/include/sdp/nrfe_common.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NRFE_COMMON_H__ +#define NRFE_COMMON_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct __packed { + atomic_bool locked; + uint32_t data_size; +} nrfe_shared_data_lock_t; + +#ifdef __cplusplus +} +#endif + +#endif /* NRFE_COMMON_H__ */ diff --git a/scripts/twister/alt/zephyr/samples/basic/blinky/sample.yaml b/scripts/twister/alt/zephyr/samples/basic/blinky/sample.yaml new file mode 100644 index 000000000000..69273d82887f --- /dev/null +++ b/scripts/twister/alt/zephyr/samples/basic/blinky/sample.yaml @@ -0,0 +1,51 @@ +sample: + name: Blinky Sample +common: + tags: + - LED + - gpio + depends_on: gpio +tests: + sample.basic.blinky: + filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds") + harness: led + integration_platforms: + - frdm_k64f + + sample.basic.blinky.egpio_icmsg: + sysbuild: true + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + extra_args: SB_CONFIG_SDP=y + SB_CONFIG_EGPIO_FLPR_APPLICATION=y + SB_CONFIG_EGPIO_BACKEND_ICMSG=y + SB_CONFIG_PARTITION_MANAGER=n + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay" + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "LED state: ON" + - "LED state: OFF" + + sample.basic.blinky.egpio_mbox: + sysbuild: true + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + extra_args: SB_CONFIG_SDP=y + SB_CONFIG_EGPIO_FLPR_APPLICATION=y + SB_CONFIG_EGPIO_BACKEND_MBOX=y + SB_CONFIG_PARTITION_MANAGER=n + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay" + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "LED state: ON" + - "LED state: OFF" diff --git a/snippets/emulated-gpio/emulated-gpio.overlay b/snippets/emulated-gpio/emulated-gpio.overlay deleted file mode 100644 index ebcb50a19fae..000000000000 --- a/snippets/emulated-gpio/emulated-gpio.overlay +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -&cpuflpr_vpr { - status = "okay"; - - egpio: gpio { - compatible = "nordic,nrf-egpio"; - gpio-controller; - #gpio-cells = <0x2>; - ngpios = <0x10>; - status = "disabled"; - port = <0x2>; - }; -}; diff --git a/snippets/emulated-gpio/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/snippets/emulated-gpio/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp.overlay similarity index 91% rename from snippets/emulated-gpio/boards/nrf54l15dk_nrf54l15_cpuapp.overlay rename to snippets/emulated-gpio/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index 62f8e924a9be..e598942eee45 100644 --- a/snippets/emulated-gpio/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/snippets/emulated-gpio/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -39,7 +39,7 @@ compatible = "zephyr,ipc-icmsg"; tx-region = <&sram_tx>; rx-region = <&sram_rx>; - mboxes = <&cpuapp_vevif_rx 15>, <&cpuapp_vevif_tx 16>; + mboxes = <&cpuapp_vevif_rx 20>, <&cpuapp_vevif_tx 21>; mbox-names = "rx", "tx"; status = "okay"; }; @@ -68,10 +68,6 @@ status = "okay"; }; -&led0 { - gpios = <&egpio 7 GPIO_ACTIVE_HIGH>; -}; - &egpio { status = "okay"; }; diff --git a/snippets/emulated-gpio/icmsg/emulated-gpio.overlay b/snippets/emulated-gpio/icmsg/emulated-gpio.overlay new file mode 100644 index 000000000000..59e7421ed232 --- /dev/null +++ b/snippets/emulated-gpio/icmsg/emulated-gpio.overlay @@ -0,0 +1,17 @@ +/* Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +&cpuflpr_vpr { + status = "okay"; + + egpio: gpio { + compatible = "nordic,nrf-egpio"; + gpio-controller; + #gpio-cells = <0x2>; + ngpios = <0x10>; + status = "disabled"; + port = <0x2>; + }; +}; diff --git a/snippets/emulated-gpio/snippet.yml b/snippets/emulated-gpio/icmsg/snippet.yml similarity index 67% rename from snippets/emulated-gpio/snippet.yml rename to snippets/emulated-gpio/icmsg/snippet.yml index 58a32d671c5a..8a8051c2f7f1 100644 --- a/snippets/emulated-gpio/snippet.yml +++ b/snippets/emulated-gpio/icmsg/snippet.yml @@ -4,14 +4,11 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -name: emulated-gpio +name: emulated-gpio-icmsg append: EXTRA_DTC_OVERLAY_FILE: emulated-gpio.overlay boards: - nrf54l15pdk/nrf54l15/cpuapp: - append: - EXTRA_DTC_OVERLAY_FILE: boards/nrf54l15pdk_nrf54l15_cpuapp.overlay nrf54l15dk/nrf54l15/cpuapp: append: EXTRA_DTC_OVERLAY_FILE: boards/nrf54l15dk_nrf54l15_cpuapp.overlay diff --git a/snippets/emulated-gpio/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/snippets/emulated-gpio/mbox/boards/nrf54l15dk_nrf54l15_cpuapp.overlay similarity index 78% rename from snippets/emulated-gpio/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay rename to snippets/emulated-gpio/mbox/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index 62f8e924a9be..887bc419206c 100644 --- a/snippets/emulated-gpio/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay +++ b/snippets/emulated-gpio/mbox/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -34,15 +34,10 @@ }; }; - ipc { - ipc0: ipc0 { - compatible = "zephyr,ipc-icmsg"; - tx-region = <&sram_tx>; - rx-region = <&sram_rx>; - mboxes = <&cpuapp_vevif_rx 15>, <&cpuapp_vevif_tx 16>; - mbox-names = "rx", "tx"; - status = "okay"; - }; + mbox_consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&cpuapp_vevif_rx 20>, <&cpuapp_vevif_tx 21>; + mbox-names = "rx", "tx"; }; }; @@ -68,10 +63,6 @@ status = "okay"; }; -&led0 { - gpios = <&egpio 7 GPIO_ACTIVE_HIGH>; -}; - &egpio { status = "okay"; }; diff --git a/snippets/emulated-gpio/mbox/emulated-gpio.overlay b/snippets/emulated-gpio/mbox/emulated-gpio.overlay new file mode 100644 index 000000000000..59e7421ed232 --- /dev/null +++ b/snippets/emulated-gpio/mbox/emulated-gpio.overlay @@ -0,0 +1,17 @@ +/* Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +&cpuflpr_vpr { + status = "okay"; + + egpio: gpio { + compatible = "nordic,nrf-egpio"; + gpio-controller; + #gpio-cells = <0x2>; + ngpios = <0x10>; + status = "disabled"; + port = <0x2>; + }; +}; diff --git a/snippets/emulated-gpio/mbox/snippet.yml b/snippets/emulated-gpio/mbox/snippet.yml new file mode 100644 index 000000000000..9d5c418a9432 --- /dev/null +++ b/snippets/emulated-gpio/mbox/snippet.yml @@ -0,0 +1,14 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +name: emulated-gpio-mbox +append: + EXTRA_DTC_OVERLAY_FILE: emulated-gpio.overlay + +boards: + nrf54l15dk/nrf54l15/cpuapp: + append: + EXTRA_DTC_OVERLAY_FILE: boards/nrf54l15dk_nrf54l15_cpuapp.overlay diff --git a/sysbuild/CMakeLists.txt b/sysbuild/CMakeLists.txt index dcbf74ca446f..884ab20674b1 100644 --- a/sysbuild/CMakeLists.txt +++ b/sysbuild/CMakeLists.txt @@ -64,6 +64,10 @@ function(include_packaging) include(${ZEPHYR_NRF_MODULE_DIR}/subsys/bootloader/cmake/packaging.cmake) endfunction() +function(include_sdp) + include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/sdp.cmake) +endfunction() + function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) cmake_parse_arguments(PRE_CMAKE "" "" "IMAGES" ${ARGN}) restore_ncs_vars() @@ -463,6 +467,10 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) set_config_bool(${DEFAULT_IMAGE} CONFIG_SUIT_MPI_APP_RECOVERY y) set_config_bool(${DEFAULT_IMAGE} CONFIG_SUIT_MPI_RAD_RECOVERY y) endif() + + if(SB_CONFIG_SDP) + include_sdp() + endif() endfunction(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) # Sysbuild function hooks used by nRF Connect SDK @@ -608,5 +616,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/netcore.cmake) include(${CMAKE_CURRENT_LIST_DIR}/secureboot.cmake) include(${CMAKE_CURRENT_LIST_DIR}/mcuboot.cmake) include(${CMAKE_CURRENT_LIST_DIR}/suit.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/sdp.cmake) store_ncs_vars() diff --git a/sysbuild/Kconfig.sdp b/sysbuild/Kconfig.sdp new file mode 100644 index 000000000000..d963e18d2a08 --- /dev/null +++ b/sysbuild/Kconfig.sdp @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + +menu "SW defined peripherals" + +menuconfig SDP + bool "Software defined peripherals" + +if SDP + +config EGPIO_FLPR_APPLICATION + bool "Nordic eGPIO FLPR application" + help + Include FLPR side eGPIO application in build. + FLPR eGPIO application is an eGPIO driver built for an FLPR core that receives commands + from the app core and controls the pin states based on them. + +choice EGPIO_BACKEND + prompt "eGPIO driver backend type" + depends on EGPIO_FLPR_APPLICATION + default EGPIO_BACKEND_ICMSG + help + Select the backend type for the eGPIO driver and application. + +config EGPIO_BACKEND_MBOX + bool "MBOX backend for eGPIO" + help + Use MBOX backend driver for eGPIO. + The MBOX version is more resource-efficient than the ICMSG backend, + but needs to have a shared structure defined as a communication channel. + +config EGPIO_BACKEND_ICMSG + bool "ICMSG backend for eGPIO" + help + Use ICMSG backend driver for eGPIO. + +endchoice + +endif # SDP + +endmenu diff --git a/sysbuild/Kconfig.sysbuild b/sysbuild/Kconfig.sysbuild index d724d17a3ab7..2da4c5f113b7 100644 --- a/sysbuild/Kconfig.sysbuild +++ b/sysbuild/Kconfig.sysbuild @@ -79,3 +79,4 @@ rsource "Kconfig.zip" rsource "Kconfig.matter" rsource "Kconfig.wifi" rsource "Kconfig.suit" +rsource "Kconfig.sdp" diff --git a/sysbuild/sdp.cmake b/sysbuild/sdp.cmake new file mode 100644 index 000000000000..d6098a2e5438 --- /dev/null +++ b/sysbuild/sdp.cmake @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + +# If it is enabled, include the eGPIO FLPR application in the build +if(SB_CONFIG_EGPIO_FLPR_APPLICATION) + # Extract SoC name from related variables + string(REPLACE "/" ";" split_board_qualifiers "${BOARD_QUALIFIERS}") + list(GET split_board_qualifiers 1 target_soc) + set(board_target_flpr "${BOARD}/${target_soc}/cpuflpr") + set(target_soc) + + ExternalZephyrProject_Add( + APPLICATION flpr_egpio + SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/applications/sdp/gpio + BOARD ${board_target_flpr} + BOARD_REVISION ${BOARD_REVISION} + ) +endif() diff --git a/west.yml b/west.yml index e7f01f29cbdb..13d9de288c88 100644 --- a/west.yml +++ b/west.yml @@ -72,7 +72,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: 5d10d27a0a978816153764e8f7024cbbc3fae197 + revision: 8005d4e87b9bcba25f441a51f4f5d29b541022b9 import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above