forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Magdalena Pastula <[email protected]>
- Loading branch information
1 parent
17c3770
commit f79b54b
Showing
4 changed files
with
212 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Copyright (c) 2024, Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#define DT_DRV_COMPAT nordic_nrf_gpio | ||
|
||
#include <nrfx_gpiote.h> | ||
#include <string.h> | ||
#include <zephyr/drivers/gpio.h> | ||
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h> | ||
#include <zephyr/irq.h> | ||
|
||
#include <zephyr/drivers/gpio/gpio_utils.h> | ||
|
||
#include <zephyr/kernel.h> | ||
#include <zephyr/device.h> | ||
|
||
#include <zephyr/ipc/ipc_service.h> | ||
|
||
#include <app/nrfe_gpio.h> | ||
|
||
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_nrfx_data { | ||
/* gpio_driver_data needs to be first */ | ||
struct gpio_driver_data common; | ||
}; | ||
|
||
struct gpio_nrfx_cfg { | ||
/* gpio_driver_config needs to be first */ | ||
struct gpio_driver_config common; | ||
uint8_t port_num; | ||
}; | ||
|
||
static inline const struct gpio_nrfx_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) | ||
{ | ||
struct nrfe_gpio_data_packet 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(struct nrfe_gpio_data_packet)); | ||
} | ||
|
||
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; | ||
|
||
struct nrfe_gpio_data_packet 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(struct nrfe_gpio_data_packet)); | ||
|
||
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(struct nrfe_gpio_data_packet)); | ||
} | ||
|
||
static int gpio_nrfx_port_set_bits_raw(const struct device *port, | ||
gpio_port_pins_t mask) | ||
{ | ||
struct nrfe_gpio_data_packet msg = {.opcode = NRFE_GPIO_PIN_SET, | ||
.pin = mask, | ||
.port = get_port_cfg(port)->port_num}; | ||
|
||
return ipc_service_send(&ep, (void*)(&msg), sizeof(struct nrfe_gpio_data_packet)); | ||
} | ||
|
||
static int gpio_nrfx_port_clear_bits_raw(const struct device *port, | ||
gpio_port_pins_t mask) | ||
{ | ||
struct nrfe_gpio_data_packet msg = {.opcode = NRFE_GPIO_PIN_CLEAR, | ||
.pin = mask, | ||
.port = get_port_cfg(port)->port_num}; | ||
|
||
return ipc_service_send(&ep, (void*)(&msg), sizeof(struct nrfe_gpio_data_packet)); | ||
} | ||
|
||
static int gpio_nrfx_port_toggle_bits(const struct device *port, | ||
gpio_port_pins_t mask) | ||
{ | ||
struct nrfe_gpio_data_packet msg = {.opcode = NRFE_GPIO_PIN_TOGGLE, | ||
.pin = mask, | ||
.port = get_port_cfg(port)->port_num}; | ||
|
||
return ipc_service_send(&ep, (void*)(&msg), sizeof(struct nrfe_gpio_data_packet)); | ||
} | ||
|
||
static int gpio_nrfx_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)) { | ||
// LOG_ERR("ipc_service_open_instance() failure"); | ||
return ret; | ||
} | ||
|
||
ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); | ||
if (ret < 0) { | ||
// LOG_ERR("ipc_service_register_endpoint() failure"); | ||
return ret; | ||
} | ||
|
||
k_sem_take(&bound_sem, K_FOREVER); | ||
|
||
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, | ||
}; | ||
|
||
#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance) | ||
#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance) | ||
|
||
#define GPIOTE_INSTANCE(id) \ | ||
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ | ||
(NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \ | ||
({ .p_reg = NULL })) | ||
|
||
/* 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 GPIOTE_CHECK(id) \ | ||
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ | ||
(BUILD_ASSERT(DT_NODE_HAS_STATUS(GPIOTE_PHANDLE(id), okay), \ | ||
"Please enable GPIOTE instance for used GPIO port!")), \ | ||
()) | ||
|
||
#define GPIO_NRF_DEVICE(id) \ | ||
GPIOTE_CHECK(id); \ | ||
static const struct gpio_nrfx_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_nrfx_data gpio_nrfx_p##id##_data; \ | ||
\ | ||
DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \ | ||
NULL, \ | ||
&gpio_nrfx_p##id##_data, \ | ||
&gpio_nrfx_p##id##_cfg, \ | ||
PRE_KERNEL_1, \ | ||
CONFIG_GPIO_INIT_PRIORITY, \ | ||
&gpio_nrfx_drv_api_funcs); | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(GPIO_NRF_DEVICE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters