diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index e150c8c8ea3b1b..9d284c1cc78c62 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -57,6 +57,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_NEORV32 gpio_neorv32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NPCX gpio_npcx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NPM1300 gpio_npm1300.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NPM6001 gpio_npm6001.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_NRFE gpio_nrfe.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NRFX gpio_nrfx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMICRO gpio_numicro.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e6aac9e04ceb5f..ddfd0d8a7abf87 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -144,6 +144,7 @@ source "drivers/gpio/Kconfig.neorv32" source "drivers/gpio/Kconfig.npcx" source "drivers/gpio/Kconfig.npm1300" source "drivers/gpio/Kconfig.npm6001" +source "drivers/gpio/Kconfig.nrfe" source "drivers/gpio/Kconfig.nrfx" source "drivers/gpio/Kconfig.numaker" source "drivers/gpio/Kconfig.numicro" diff --git a/drivers/gpio/Kconfig.nrfe b/drivers/gpio/Kconfig.nrfe new file mode 100644 index 00000000000000..9217670aae308f --- /dev/null +++ b/drivers/gpio/Kconfig.nrfe @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_NRFE + bool "Emulated GPIO" + default y + depends on DT_HAS_NORDIC_NRF_EGPIO_ENABLED + select NRFE_GPIO if HAS_HW_NRF_EGPIO + select IPC_SERVICE + select IPC_SERVICE_BACKEND_ICMSG + select MBOX + help + Use emulated GPIO driver. + +# eGPIO initialization depends on IPC initialization which is done at the same init level and +# has init priority equal to 46. +config EGPIO_INIT_PRIORITY + int "eGPIO init priority" + depends on GPIO_NRFE + default 48 + help + eGPIO driver device initialization priority. diff --git a/drivers/gpio/gpio_nrfe.c b/drivers/gpio/gpio_nrfe.c new file mode 100644 index 00000000000000..0100b8e70256f2 --- /dev/null +++ b/drivers/gpio/gpio_nrfe.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#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 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, + }, +}; + +struct ipc_ept ep; + +struct gpio_nrfe_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; +}; + +struct gpio_nrfe_cfg { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + uint8_t port_num; +}; + +static inline const struct gpio_nrfe_cfg *get_port_cfg(const struct device *port) +{ + return port->config; +} + +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, + .pin = pin, + .port = get_port_cfg(port)->port_num, + .flags = flags}; + + return ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); +} + +static int gpio_nrfe_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + + const uint32_t set_mask = value & mask; + const uint32_t clear_mask = (~set_mask) & mask; + + nrfe_gpio_data_packet_t msg = { + .opcode = NRFE_GPIO_PIN_SET, .pin = set_mask, .port = get_port_cfg(port)->port_num}; + + int ret_val = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); + + if (ret_val < 0) { + return ret_val; + } + + msg.opcode = NRFE_GPIO_PIN_CLEAR; + msg.pin = clear_mask; + + return ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); +} + +static int gpio_nrfe_port_set_bits_raw(const struct device *port, gpio_port_pins_t mask) +{ + nrfe_gpio_data_packet_t msg = { + .opcode = NRFE_GPIO_PIN_SET, .pin = mask, .port = get_port_cfg(port)->port_num}; + + return ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); +} + +static int gpio_nrfe_port_clear_bits_raw(const struct device *port, gpio_port_pins_t mask) +{ + nrfe_gpio_data_packet_t msg = { + .opcode = NRFE_GPIO_PIN_CLEAR, .pin = mask, .port = get_port_cfg(port)->port_num}; + + return ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); +} + +static int gpio_nrfe_port_toggle_bits(const struct device *port, gpio_port_pins_t mask) +{ + nrfe_gpio_data_packet_t msg = { + .opcode = NRFE_GPIO_PIN_TOGGLE, .pin = mask, .port = get_port_cfg(port)->port_num}; + + return ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t)); +} + +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, + .port_set_bits_raw = gpio_nrfe_port_set_bits_raw, + .port_clear_bits_raw = gpio_nrfe_port_clear_bits_raw, + .port_toggle_bits = gpio_nrfe_port_toggle_bits, +}; + +#define GPIO_NRFE_DEVICE(id) \ + static const struct gpio_nrfe_cfg gpio_nrfe_p##id##_cfg = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \ + }, \ + .port_num = DT_INST_PROP(id, port), \ + }; \ + \ + static struct gpio_nrfe_data gpio_nrfe_p##id##_data; \ + \ + DEVICE_DT_INST_DEFINE(id, gpio_nrfe_init, NULL, &gpio_nrfe_p##id##_data, \ + &gpio_nrfe_p##id##_cfg, POST_KERNEL, CONFIG_EGPIO_INIT_PRIORITY, \ + &gpio_nrfe_drv_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_NRFE_DEVICE) diff --git a/dts/arm/nordic/nrf54l15_cpuapp.dtsi b/dts/arm/nordic/nrf54l15_cpuapp.dtsi index 9cf1f6eea54c1d..58f10691d9ce4b 100644 --- a/dts/arm/nordic/nrf54l15_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54l15_cpuapp.dtsi @@ -55,6 +55,15 @@ nvic: &cpuapp_nvic {}; nordic,tasks-mask = <0x0003f800>; status = "disabled"; }; + + egpio: gpio { + compatible = "nordic,nrf-egpio"; + gpio-controller; + #gpio-cells = < 0x2 >; + ngpios = < 0x10 >; + status = "disabled"; + port = < 0x2 >; + }; }; &cpuapp_ppb { diff --git a/dts/bindings/gpio/nordic,nrf-egpio.yaml b/dts/bindings/gpio/nordic,nrf-egpio.yaml new file mode 100644 index 00000000000000..09c8c98bdea071 --- /dev/null +++ b/dts/bindings/gpio/nordic,nrf-egpio.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2018, marc-cpdesign +# SPDX-License-Identifier: Apache-2.0 + +description: Emulated GPIO node + +compatible: "nordic,nrf-egpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + + "#gpio-cells": + const: 2 + + port: + type: int + required: true + description: | + The GPIO port number. GPIO port P0 has: + + port = <0>; + + And P1 has: + + port = <1>; + +gpio-cells: + - pin + - flags diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt index ac9b3f8ce4c6c9..6512fc44264a74 100644 --- a/modules/hal_nordic/CMakeLists.txt +++ b/modules/hal_nordic/CMakeLists.txt @@ -7,6 +7,7 @@ endif (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) add_subdirectory_ifdef(CONFIG_HAS_NRFX nrfx) add_subdirectory_ifdef(CONFIG_HAS_NRFS nrfs) +add_subdirectory_ifdef(CONFIG_HAS_NRFE nrfe) if(CONFIG_NRF_REGTOOL_GENERATE_UICR) list(APPEND nrf_regtool_components GENERATE:UICR) diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index 13ab8d9cd2f9c5..0d4148ccc8cf85 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -237,4 +237,5 @@ endmenu # HAS_NORDIC_DRIVERS rsource "nrfs/Kconfig" rsource "nrfx/Kconfig" +rsource "nrfe/Kconfig" rsource "Kconfig.nrf_regtool" diff --git a/modules/hal_nordic/nrfe/CMakeLists.txt b/modules/hal_nordic/nrfe/CMakeLists.txt new file mode 100644 index 00000000000000..666182b2ae638c --- /dev/null +++ b/modules/hal_nordic/nrfe/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_include_directories(${ZEPHYR_CURRENT_MODULE_DIR}/nrfe) diff --git a/modules/hal_nordic/nrfe/Kconfig b/modules/hal_nordic/nrfe/Kconfig new file mode 100644 index 00000000000000..dab034a7378baf --- /dev/null +++ b/modules/hal_nordic/nrfe/Kconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config HAS_NRFE + bool + +menu "nRF Emulated Peripherals" + depends on HAS_NRFE + +config NRFE_GPIO + bool "eGPIO driver instance" + depends on $(dt_nodelabel_has_compat,egpio,$(DT_COMPAT_NORDIC_NRF_EGPIO)) + +endmenu diff --git a/samples/basic/blinky/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/basic/blinky/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000000..8d98be1bbb5c77 --- /dev/null +++ b/samples/basic/blinky/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + sram_rx: memory@20018000 { + reg = <0x20018000 0x0800>; + }; + + sram_tx: memory@20020000 { + reg = <0x20020000 0x0800>; + }; + }; + }; + + 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"; + }; + }; +}; + +&gpio2 { + status = "disabled"; +}; + +&egpio { + status = "okay"; +}; + +&cpuapp_vevif_rx { + status = "okay"; +}; + +&cpuapp_vevif_tx { + status = "okay"; +}; + +&led0 { + gpios = <&egpio 9 GPIO_ACTIVE_HIGH>; +}; diff --git a/soc/nordic/common/Kconfig.peripherals b/soc/nordic/common/Kconfig.peripherals index a6d730804b824d..db79c64c2c4005 100644 --- a/soc/nordic/common/Kconfig.peripherals +++ b/soc/nordic/common/Kconfig.peripherals @@ -66,6 +66,9 @@ config HAS_HW_NRF_EGU5 config HAS_HW_NRF_EGU020 def_bool $(dt_nodelabel_enabled_with_compat,egu020,$(DT_COMPAT_NORDIC_NRF_EGU)) +config HAS_HW_NRF_EGPIO + def_bool $(dt_nodelabel_enabled_with_compat,egpio,$(DT_COMPAT_NORDIC_NRF_EGPIO)) + config HAS_HW_NRF_GPIO0 def_bool $(dt_nodelabel_enabled_with_compat,gpio0,$(DT_COMPAT_NORDIC_NRF_GPIO)) diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index 18e315078e9daa..3a07ca007c8714 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -19,6 +19,7 @@ config SOC_NRF54L15_ENGA_CPUAPP select CPU_HAS_FPU select HAS_HW_NRF_RADIO_IEEE802154 select HAS_POWEROFF + select HAS_NRFE config SOC_NRF54L15_ENGA_CPUFLPR depends on RISCV_CORE_NORDIC_VPR diff --git a/west.yml b/west.yml index 0a2c096a975cce..497a687d3b5dc4 100644 --- a/west.yml +++ b/west.yml @@ -23,6 +23,8 @@ manifest: url-base: https://github.com/zephyrproject-rtos - name: babblesim url-base: https://github.com/BabbleSim + - name: magp + url-base: https://github.com/magp-nordic group-filter: [-babblesim, -optional] @@ -188,7 +190,8 @@ manifest: groups: - hal - name: hal_nordic - revision: ab5cb2e2faeb1edfad7a25286dcb513929ae55da + remote: magp + revision: pull/1/head path: modules/hal/nordic groups: - hal