Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

samples: basic: blinky: eGPIO PoC #1

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/gpio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/gpio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
10 changes: 10 additions & 0 deletions drivers/gpio/Kconfig.nrfe
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

config GPIO_NRFE
bool "nRF eGPIO driver"
default y
depends on DT_HAS_NORDIC_NRF_EGPIO_ENABLED
select NRFE_GPIO2 if HAS_HW_NRF_EGPIO2
help
Enable eGPIO driver for nRF line of MCUs.
208 changes: 208 additions & 0 deletions drivers/gpio/gpio_nrfe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
* Copyright (c) 2024, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT nordic_nrf_egpio

#include <zephyr/drivers/gpio.h>
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>

#include <zephyr/ipc/ipc_service.h>

#include <nrfe_gpio.h>

#ifdef CONFIG_MULTITHREADING
K_SEM_DEFINE(bound_sem, 0, 1);
#else
volatile uint32_t bound_sem = 1;
#endif

static void ep_bound(void *priv)
{
#ifdef CONFIG_MULTITHREADING
k_sem_give(&bound_sem);
#else
bound_sem = 0;
#endif
}

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_nrfx_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};

int ret = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

return 0;
}

static int gpio_nrfx_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 = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

msg.opcode = NRFE_GPIO_PIN_CLEAR;
msg.pin = clear_mask;

ret = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

return ret;
}

static int gpio_nrfx_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};

int ret = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

return ret;
}

static int gpio_nrfx_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};

int ret = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

return ret;
}

static int gpio_nrfx_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};

int ret = ipc_service_send(&ep, (void *)(&msg), sizeof(nrfe_gpio_data_packet_t));

if (ret < 0) {
return ret;
}

return ret;
}

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;
}

/* Wait for endpoint to be bound */
#ifdef CONFIG_MULTITHREADING
k_sem_take(&bound_sem, K_FOREVER);
#else
while (bound_sem != 0) {
};
#endif

return 0;
}

static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
.pin_configure = gpio_nrfx_pin_configure,
.port_set_masked_raw = gpio_nrfx_port_set_masked_raw,
.port_set_bits_raw = gpio_nrfx_port_set_bits_raw,
.port_clear_bits_raw = gpio_nrfx_port_clear_bits_raw,
.port_toggle_bits = gpio_nrfx_port_toggle_bits,
};

/* needs to be done after MBOX driver init, which is at
* POST_KERNEL:KERNEL_INIT_PRIORITY_DEFAULT.
*/
#define CONFIG_EGPIO_INIT_PRIORITY CONFIG_KERNEL_INIT_PRIORITY_DEVICE

/* Device instantiation is done with node labels because 'port_num' is
* the peripheral number by SoC numbering. We therefore cannot use
* DT_INST APIs here without wider changes.
*/
#define EGPIO_NRF_DEVICE(id) \
static const struct gpio_nrfe_cfg gpio_nrfx_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_nrfx_p##id##_data; \
\
DEVICE_DT_INST_DEFINE(id, gpio_nrfe_init, NULL, &gpio_nrfx_p##id##_data, \
&gpio_nrfx_p##id##_cfg, POST_KERNEL, CONFIG_EGPIO_INIT_PRIORITY, \
&gpio_nrfx_drv_api_funcs);

DT_INST_FOREACH_STATUS_OKAY(EGPIO_NRF_DEVICE)
60 changes: 60 additions & 0 deletions dts/bindings/gpio/nordic,nrf-egpio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

description: NRF eGPIO node

compatible: "nordic,nrf-egpio"

include: [base.yaml]

properties:
ngpios:
type: int
default: 32
description: |
This property indicates the number of in-use slots of available slots
for GPIOs. The typical example is something like this: the hardware
register is 32 bits wide, but only 18 of the bits have a physical
counterpart. The driver is generally written so that all 32 bits can
be used, but the IP block is reused in a lot of designs, some using
all 32 bits, some using 18 and some using 12. In this case, setting
"ngpios = <18>;" informs the driver that only the first 18 GPIOs, at
local offset 0 .. 17, are in use. For cases in which there might be
holes in the slot range, this value should be the max slot number+1.
gpio-reserved-ranges:
type: array
description: |
If not all the GPIOs at offsets 0...N-1 are usable for ngpios = <N>, then
this property contains an additional set of tuples which specify which GPIOs
are unusable. This property indicates the start and size of the GPIOs
that can't be used.

For example, setting "gpio-reserved-ranges = <3 2>, <10 1>;" means that
GPIO offsets 3, 4, and 10 are not usable, even if ngpios = <18>.

"#gpio-cells":
type: int
required: true
description: Number of items to expect in a GPIO specifier
const: 2

sense-edge-mask:
type: int
description: |
Mask of pins that use the GPIO sense mechanism for edge detection.

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
2 changes: 2 additions & 0 deletions include/zephyr/ipc/icmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ struct icmsg_data_t {

/* General */
const struct icmsg_config_t *cfg;
#ifdef CONFIG_MULTITHREADING
struct k_work_delayable notify_work;
struct k_work mbox_work;
#endif
atomic_t state;
};

Expand Down
1 change: 1 addition & 0 deletions modules/hal_nordic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions modules/hal_nordic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,5 @@ endmenu # HAS_NORDIC_DRIVERS

rsource "nrfs/Kconfig"
rsource "nrfx/Kconfig"
rsource "nrfe/Kconfig"
rsource "Kconfig.nrf_regtool"
15 changes: 15 additions & 0 deletions modules/hal_nordic/nrfe/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

# The nrfe source directory can be override through the definition of the NRFE_DIR symbol
# during the invocation of the build system
if(NOT DEFINED NRFE_DIR)
set(NRFE_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/nrfe CACHE PATH "nrfe Directory")
endif()

set(INC_DIR ${NRFE_DIR}/include)

zephyr_include_directories(${NRFE_DIR})
zephyr_include_directories(${INC_DIR})
18 changes: 18 additions & 0 deletions modules/hal_nordic/nrfe/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2016 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

config HAS_NRFE
bool

menu "nrfe drivers"
depends on HAS_NRFE

config NRFE_GPIO
bool

config NRFE_GPIO2
bool "eGPIO2 driver instance"
depends on $(dt_nodelabel_has_compat,egpio2,$(DT_COMPAT_NORDIC_NRF_EGPIO))
select NRFE_GPIO

endmenu # "nrfe drivers"
7 changes: 7 additions & 0 deletions samples/basic/blinky/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

if(NOT CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUAPP)
message(FATAL_ERROR "${BOARD} is not supported for this sample")
endif()

project(blinky)

target_sources(app PRIVATE src/main.c)

include(ExternalProject)
9 changes: 9 additions & 0 deletions samples/basic/blinky/Kconfig.sysbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0

source "share/sysbuild/Kconfig"

config REMOTE_BOARD
string
default "nrf54l15pdk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15pdk"
Loading
Loading