modules: hal_nordic: nrfx: update API version to 3.2.0
Updated API version enables multi-instance GPIOTE driver. Additionally obsolete symbol that was used to specify API version in the past was removed. Affected drivers have been adjusted and appropriate changes in affected files have been made. Signed-off-by: Jakub Zymelka <jakub.zymelka@nordicsemi.no>
This commit is contained in:
parent
c546c8b96b
commit
ade49f081d
|
@ -170,7 +170,7 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx,
|
|||
if (!repeat) {
|
||||
nrf_saadc_buffer_pointer_set(
|
||||
NRF_SAADC,
|
||||
nrf_saadc_buffer_pointer_get(NRF_SAADC) +
|
||||
(uint16_t *)nrf_saadc_buffer_pointer_get(NRF_SAADC) +
|
||||
nrf_saadc_amount_get(NRF_SAADC));
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ static int check_buffer_size(const struct adc_sequence *sequence,
|
|||
{
|
||||
size_t needed_buffer_size;
|
||||
|
||||
needed_buffer_size = active_channels * sizeof(nrf_saadc_value_t);
|
||||
needed_buffer_size = active_channels * sizeof(uint16_t);
|
||||
if (sequence->options) {
|
||||
needed_buffer_size *= (1 + sequence->options->extra_samplings);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <zephyr/drivers/display.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
#include <soc.h>
|
||||
#include <hal/nrf_timer.h>
|
||||
#ifdef PWM_PRESENT
|
||||
#include <hal/nrf_pwm.h>
|
||||
|
@ -89,6 +90,8 @@ struct display_drv_config {
|
|||
NRF_TIMER_Type *timer;
|
||||
#if USE_PWM
|
||||
NRF_PWM_Type *pwm;
|
||||
#else
|
||||
nrfx_gpiote_t gpiote;
|
||||
#endif
|
||||
uint8_t rows[ROW_COUNT];
|
||||
uint8_t cols[COL_COUNT];
|
||||
|
@ -324,7 +327,7 @@ static void prepare_pixel_pulse(const struct device *dev,
|
|||
|
||||
/* First timer channel is used for timing the period of pulses. */
|
||||
nrf_timer_cc_set(dev_config->timer, 1 + channel_idx, pulse);
|
||||
NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg;
|
||||
dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg;
|
||||
#endif /* USE_PWM */
|
||||
}
|
||||
|
||||
|
@ -354,7 +357,7 @@ static void timer_irq_handler(void *arg)
|
|||
}
|
||||
#else
|
||||
for (int i = 0; i < GROUP_SIZE; ++i) {
|
||||
NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[i]] = 0;
|
||||
dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -450,7 +453,7 @@ static int instance_init(const struct device *dev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_channel_alloc(gpiote_ch);
|
||||
err = nrfx_gpiote_channel_alloc(&dev_config->gpiote, gpiote_ch);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
LOG_ERR("Failed to allocate GPIOTE channel.");
|
||||
/* Do not bother with freeing resources allocated
|
||||
|
@ -463,7 +466,7 @@ static int instance_init(const struct device *dev)
|
|||
nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch,
|
||||
nrf_timer_event_address_get(dev_config->timer,
|
||||
nrf_timer_compare_event_get(1 + i)),
|
||||
nrf_gpiote_event_address_get(NRF_GPIOTE,
|
||||
nrf_gpiote_event_address_get(dev_config->gpiote.p_reg,
|
||||
nrf_gpiote_out_task_get(*gpiote_ch)));
|
||||
nrf_ppi_channel_enable(NRF_PPI, ppi_ch);
|
||||
}
|
||||
|
@ -514,6 +517,14 @@ static struct display_drv_data instance_data = {
|
|||
.blanking = true,
|
||||
};
|
||||
|
||||
#if !USE_PWM
|
||||
#define CHECK_GPIOTE_INST(node_id, prop, idx) \
|
||||
BUILD_ASSERT(NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) == \
|
||||
NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0), \
|
||||
"All column GPIOs must use the same GPIOTE instance");
|
||||
DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, CHECK_GPIOTE_INST)
|
||||
#endif
|
||||
|
||||
#define GET_PIN_INFO(node_id, pha, idx) \
|
||||
(DT_GPIO_PIN_BY_IDX(node_id, pha, idx) | \
|
||||
(DT_PROP_BY_PHANDLE_IDX(node_id, pha, idx, port) << 5) | \
|
||||
|
@ -530,6 +541,9 @@ static const struct display_drv_config instance_config = {
|
|||
.timer = (NRF_TIMER_Type *)DT_REG_ADDR(TIMER_NODE),
|
||||
#if USE_PWM
|
||||
.pwm = (NRF_PWM_Type *)DT_REG_ADDR(PWM_NODE),
|
||||
#else
|
||||
.gpiote = NRFX_GPIOTE_INSTANCE(
|
||||
NRF_DT_GPIOTE_INST_BY_IDX(MATRIX_NODE, col_gpios, 0)),
|
||||
#endif
|
||||
.rows = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, row_gpios, GET_PIN_INFO) },
|
||||
.cols = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, GET_PIN_INFO) },
|
||||
|
|
|
@ -5,7 +5,12 @@ menuconfig GPIO_NRFX
|
|||
bool "nRF GPIO driver"
|
||||
default y
|
||||
depends on DT_HAS_NORDIC_NRF_GPIO_ENABLED
|
||||
select NRFX_GPIOTE
|
||||
select NRFX_GPIOTE0 if HAS_HW_NRF_GPIOTE0
|
||||
select NRFX_GPIOTE1 if HAS_HW_NRF_GPIOTE1
|
||||
select NRFX_GPIOTE20 if HAS_HW_NRF_GPIOTE20
|
||||
select NRFX_GPIOTE30 if HAS_HW_NRF_GPIOTE30
|
||||
select NRFX_GPIOTE130 if HAS_HW_NRF_GPIOTE130
|
||||
select NRFX_GPIOTE131 if HAS_HW_NRF_GPIOTE131
|
||||
help
|
||||
Enable GPIO driver for nRF line of MCUs.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT nordic_nrf_gpio
|
||||
|
||||
#include <nrfx_gpiote.h>
|
||||
|
@ -25,6 +26,7 @@ struct gpio_nrfx_cfg {
|
|||
NRF_GPIO_Type *port;
|
||||
uint32_t edge_sense;
|
||||
uint8_t port_num;
|
||||
nrfx_gpiote_t gpiote;
|
||||
};
|
||||
|
||||
static inline struct gpio_nrfx_data *get_port_data(const struct device *port)
|
||||
|
@ -37,38 +39,9 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port
|
|||
return port->config;
|
||||
}
|
||||
|
||||
static int get_drive(gpio_flags_t flags, nrf_gpio_pin_drive_t *drive)
|
||||
static bool has_gpiote(const struct gpio_nrfx_cfg *cfg)
|
||||
{
|
||||
switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) {
|
||||
case NRF_GPIO_DRIVE_S0S1:
|
||||
*drive = NRF_GPIO_PIN_S0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S0H1:
|
||||
*drive = NRF_GPIO_PIN_S0H1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0S1:
|
||||
*drive = NRF_GPIO_PIN_H0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0H1:
|
||||
*drive = NRF_GPIO_PIN_H0H1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN:
|
||||
*drive = NRF_GPIO_PIN_S0D1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN:
|
||||
*drive = NRF_GPIO_PIN_H0D1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE:
|
||||
*drive = NRF_GPIO_PIN_D0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE:
|
||||
*drive = NRF_GPIO_PIN_D0H1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cfg->gpiote.p_reg != NULL;
|
||||
}
|
||||
|
||||
static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
|
||||
|
@ -90,78 +63,115 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
|
|||
bool free_ch = false;
|
||||
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
|
||||
nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
|
||||
nrf_gpio_pin_pull_t pull = get_pull(flags);
|
||||
nrf_gpio_pin_drive_t drive;
|
||||
|
||||
switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) {
|
||||
case NRF_GPIO_DRIVE_S0S1:
|
||||
drive = NRF_GPIO_PIN_S0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S0H1:
|
||||
drive = NRF_GPIO_PIN_S0H1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0S1:
|
||||
drive = NRF_GPIO_PIN_H0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0H1:
|
||||
drive = NRF_GPIO_PIN_H0H1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN:
|
||||
drive = NRF_GPIO_PIN_S0D1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN:
|
||||
drive = NRF_GPIO_PIN_H0D1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE:
|
||||
drive = NRF_GPIO_PIN_D0S1;
|
||||
break;
|
||||
case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE:
|
||||
drive = NRF_GPIO_PIN_D0H1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
nrf_gpio_port_out_set(cfg->port, BIT(pin));
|
||||
} else if (flags & GPIO_OUTPUT_INIT_LOW) {
|
||||
nrf_gpio_port_out_clear(cfg->port, BIT(pin));
|
||||
}
|
||||
|
||||
if (!has_gpiote(cfg)) {
|
||||
nrf_gpio_pin_dir_t dir = (flags & GPIO_OUTPUT)
|
||||
? NRF_GPIO_PIN_DIR_OUTPUT
|
||||
: NRF_GPIO_PIN_DIR_INPUT;
|
||||
nrf_gpio_pin_input_t input = (flags & GPIO_INPUT)
|
||||
? NRF_GPIO_PIN_INPUT_CONNECT
|
||||
: NRF_GPIO_PIN_INPUT_DISCONNECT;
|
||||
|
||||
nrf_gpio_reconfigure(abs_pin, &dir, &input, &pull, &drive, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the GPIOTE channel associated with this pin, if any. It needs
|
||||
* to be freed when the pin is reconfigured or disconnected.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
|
||||
err = nrfx_gpiote_channel_get(abs_pin, &ch);
|
||||
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
|
||||
free_ch = (err == NRFX_SUCCESS);
|
||||
}
|
||||
|
||||
if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
|
||||
/* Ignore the error code. The pin may not have been used. */
|
||||
(void)nrfx_gpiote_pin_uninit(abs_pin);
|
||||
(void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin);
|
||||
} else {
|
||||
/* Remove previously configured trigger when pin is reconfigured. */
|
||||
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
|
||||
nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
.trigger = NRFX_GPIOTE_TRIGGER_NONE,
|
||||
};
|
||||
nrfx_gpiote_input_pin_config_t input_pin_config = {
|
||||
.p_trigger_config = &trigger_config,
|
||||
};
|
||||
|
||||
if (free_ch) {
|
||||
err = nrfx_gpiote_channel_free(ch);
|
||||
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
|
||||
err = nrfx_gpiote_input_configure(&cfg->gpiote,
|
||||
abs_pin, &input_pin_config);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (flags & GPIO_OUTPUT) {
|
||||
nrfx_gpiote_output_config_t output_config = {
|
||||
.drive = drive,
|
||||
.input_connect = (flags & GPIO_INPUT)
|
||||
? NRF_GPIO_PIN_INPUT_CONNECT
|
||||
: NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
.pull = pull,
|
||||
};
|
||||
|
||||
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
|
||||
nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
.trigger = NRFX_GPIOTE_TRIGGER_NONE
|
||||
};
|
||||
err = nrfx_gpiote_output_configure(&cfg->gpiote,
|
||||
abs_pin, &output_config, NULL);
|
||||
} else {
|
||||
nrfx_gpiote_input_pin_config_t input_pin_config = {
|
||||
.p_pull_config = &pull,
|
||||
};
|
||||
|
||||
err = nrfx_gpiote_input_configure(&cfg->gpiote,
|
||||
abs_pin, &input_pin_config);
|
||||
}
|
||||
|
||||
/* Remove previously configured trigger when pin is reconfigured. */
|
||||
err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (free_ch) {
|
||||
err = nrfx_gpiote_channel_free(ch);
|
||||
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & GPIO_OUTPUT) {
|
||||
nrf_gpio_pin_drive_t drive;
|
||||
int rv = get_drive(flags, &drive);
|
||||
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nrfx_gpiote_output_config_t output_config = {
|
||||
.drive = drive,
|
||||
.input_connect = (flags & GPIO_INPUT) ?
|
||||
NRF_GPIO_PIN_INPUT_CONNECT :
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
.pull = get_pull(flags)
|
||||
};
|
||||
|
||||
|
||||
if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
nrf_gpio_port_out_set(cfg->port, BIT(pin));
|
||||
} else if (flags & GPIO_OUTPUT_INIT_LOW) {
|
||||
nrf_gpio_port_out_clear(cfg->port, BIT(pin));
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_output_configure(abs_pin, &output_config, NULL);
|
||||
return (err != NRFX_SUCCESS) ? -EINVAL : 0;
|
||||
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT) && free_ch) {
|
||||
err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
|
||||
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
|
||||
}
|
||||
|
||||
nrfx_gpiote_input_config_t input_config = {
|
||||
.pull = get_pull(flags)
|
||||
};
|
||||
|
||||
err = nrfx_gpiote_input_configure(abs_pin, &input_config, NULL, NULL);
|
||||
|
||||
return (err != NRFX_SUCCESS) ? -EINVAL : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_nrfx_port_get_raw(const struct device *port,
|
||||
|
@ -242,12 +252,17 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
|
|||
enum gpio_int_mode mode,
|
||||
enum gpio_int_trig trig)
|
||||
{
|
||||
uint32_t abs_pin = NRF_GPIO_PIN_MAP(get_port_cfg(port)->port_num, pin);
|
||||
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
|
||||
uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
|
||||
nrfx_err_t err;
|
||||
uint8_t ch;
|
||||
|
||||
if (!has_gpiote(cfg)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (mode == GPIO_INT_MODE_DISABLED) {
|
||||
nrfx_gpiote_trigger_disable(abs_pin);
|
||||
nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -255,16 +270,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
|
|||
nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
.trigger = get_trigger(mode, trig),
|
||||
};
|
||||
nrfx_gpiote_input_pin_config_t input_pin_config = {
|
||||
.p_trigger_config = &trigger_config,
|
||||
};
|
||||
|
||||
/* If edge mode is to be used and pin is not configured to use sense for
|
||||
* edge use IN event.
|
||||
*/
|
||||
if (!(BIT(pin) & get_port_cfg(port)->edge_sense) &&
|
||||
if (!(BIT(pin) & cfg->edge_sense) &&
|
||||
(mode == GPIO_INT_MODE_EDGE) &&
|
||||
(nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) {
|
||||
err = nrfx_gpiote_channel_get(abs_pin, &ch);
|
||||
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
|
||||
if (err == NRFX_ERROR_INVALID_PARAM) {
|
||||
err = nrfx_gpiote_channel_alloc(&ch);
|
||||
err = nrfx_gpiote_channel_alloc(&cfg->gpiote, &ch);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -273,12 +291,12 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
|
|||
trigger_config.p_in_channel = &ch;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL);
|
||||
err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nrfx_gpiote_trigger_enable(abs_pin, true);
|
||||
nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -367,26 +385,31 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
|
|||
}
|
||||
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
|
||||
|
||||
#define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote)
|
||||
#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \
|
||||
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
|
||||
NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
|
||||
|
||||
static int gpio_nrfx_init(const struct device *port)
|
||||
{
|
||||
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
|
||||
nrfx_err_t err;
|
||||
|
||||
if (nrfx_gpiote_is_init()) {
|
||||
if (!has_gpiote(cfg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_init(0/*not used*/);
|
||||
if (nrfx_gpiote_init_check(&cfg->gpiote)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIO_NRFX_INTERRUPT
|
||||
nrfx_gpiote_global_callback_set(nrfx_gpio_handler, NULL);
|
||||
|
||||
IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority),
|
||||
nrfx_isr, nrfx_gpiote_irq_handler, 0);
|
||||
nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL);
|
||||
DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT);
|
||||
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
|
||||
|
||||
return 0;
|
||||
|
@ -408,12 +431,27 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
|
|||
#endif
|
||||
};
|
||||
|
||||
#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 = \
|
||||
|
@ -421,7 +459,8 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
|
|||
}, \
|
||||
.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
|
||||
.port_num = DT_INST_PROP(id, port), \
|
||||
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0) \
|
||||
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
|
||||
.gpiote = GPIOTE_INSTANCE(id), \
|
||||
}; \
|
||||
\
|
||||
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
|
||||
|
|
|
@ -62,6 +62,7 @@ struct pwm_config {
|
|||
NRF_RTC_Type *rtc;
|
||||
NRF_TIMER_Type *timer;
|
||||
};
|
||||
nrfx_gpiote_t gpiote[PWM_0_MAP_SIZE];
|
||||
uint8_t psel_ch[PWM_0_MAP_SIZE];
|
||||
uint8_t initially_inverted;
|
||||
uint8_t map_size;
|
||||
|
@ -123,6 +124,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel,
|
|||
const struct pwm_config *config = dev->config;
|
||||
NRF_TIMER_Type *timer = pwm_config_timer(config);
|
||||
NRF_RTC_Type *rtc = pwm_config_rtc(config);
|
||||
NRF_GPIOTE_Type *gpiote;
|
||||
struct pwm_data *data = dev->data;
|
||||
uint32_t ppi_mask;
|
||||
uint8_t active_level;
|
||||
|
@ -161,6 +163,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel,
|
|||
}
|
||||
}
|
||||
|
||||
gpiote = config->gpiote[channel].p_reg;
|
||||
psel_ch = config->psel_ch[channel];
|
||||
gpiote_ch = data->gpiote_ch[channel];
|
||||
ppi_chs = data->ppi_ch[channel];
|
||||
|
@ -186,7 +189,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel,
|
|||
: active_level);
|
||||
|
||||
/* clear GPIOTE config */
|
||||
nrf_gpiote_te_default(NRF_GPIOTE, gpiote_ch);
|
||||
nrf_gpiote_te_default(gpiote, gpiote_ch);
|
||||
|
||||
/* No PWM generation for this channel. */
|
||||
data->pulse_cycles[channel] = 0U;
|
||||
|
@ -235,7 +238,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel,
|
|||
}
|
||||
|
||||
/* Configure GPIOTE - toggle task with proper initial output value. */
|
||||
NRF_GPIOTE->CONFIG[gpiote_ch] =
|
||||
gpiote->CONFIG[gpiote_ch] =
|
||||
(GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
|
||||
((uint32_t)psel_ch << 8) |
|
||||
(GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
|
||||
|
@ -256,9 +259,9 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel,
|
|||
pulse_end_task = period_end_task = nrf_gpiote_out_task_get(gpiote_ch);
|
||||
#endif
|
||||
uint32_t pulse_end_task_address =
|
||||
nrf_gpiote_task_address_get(NRF_GPIOTE, pulse_end_task);
|
||||
nrf_gpiote_task_address_get(gpiote, pulse_end_task);
|
||||
uint32_t period_end_task_address =
|
||||
nrf_gpiote_task_address_get(NRF_GPIOTE, period_end_task);
|
||||
nrf_gpiote_task_address_get(gpiote, period_end_task);
|
||||
|
||||
if (USE_RTC) {
|
||||
uint32_t clear_task_address =
|
||||
|
@ -359,7 +362,8 @@ static int pwm_nrf_sw_init(const struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_channel_alloc(&data->gpiote_ch[i]);
|
||||
err = nrfx_gpiote_channel_alloc(&config->gpiote[i],
|
||||
&data->gpiote_ch[i]);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
/* Do not free allocated resource. It is a fatal condition,
|
||||
* system requires reconfiguration.
|
||||
|
@ -402,8 +406,14 @@ static int pwm_nrf_sw_init(const struct device *dev)
|
|||
((DT_GPIO_FLAGS_BY_IDX(_node_id, _prop, _idx) & GPIO_ACTIVE_LOW) \
|
||||
? BIT(_idx) : 0) |
|
||||
|
||||
#define GPIOTE_AND_COMMA(_node_id, _prop, _idx) \
|
||||
NRFX_GPIOTE_INSTANCE(NRF_DT_GPIOTE_INST_BY_IDX(_node_id, _prop, _idx)),
|
||||
|
||||
static const struct pwm_config pwm_nrf_sw_0_config = {
|
||||
COND_CODE_1(USE_RTC, (.rtc), (.timer)) = GENERATOR_ADDR,
|
||||
.gpiote = {
|
||||
DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, GPIOTE_AND_COMMA)
|
||||
},
|
||||
.psel_ch = {
|
||||
DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, PSEL_AND_COMMA)
|
||||
},
|
||||
|
|
|
@ -6,40 +6,39 @@
|
|||
|
||||
#include "spi_nrfx_common.h"
|
||||
#include <zephyr/kernel.h>
|
||||
#include <nrfx_gpiote.h>
|
||||
|
||||
int spi_nrfx_wake_init(uint32_t wake_pin)
|
||||
int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin)
|
||||
{
|
||||
nrfx_gpiote_input_config_t input_config = {
|
||||
.pull = NRF_GPIO_PIN_PULLDOWN,
|
||||
};
|
||||
nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN;
|
||||
uint8_t ch;
|
||||
nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
.trigger = NRFX_GPIOTE_TRIGGER_HITOLO,
|
||||
.p_in_channel = &ch,
|
||||
};
|
||||
nrfx_gpiote_input_pin_config_t input_config = {
|
||||
.p_pull_config = &pull_config,
|
||||
.p_trigger_config = &trigger_config,
|
||||
.p_handler_config = NULL,
|
||||
};
|
||||
nrfx_err_t res;
|
||||
|
||||
res = nrfx_gpiote_channel_alloc(&ch);
|
||||
res = nrfx_gpiote_channel_alloc(gpiote, &ch);
|
||||
if (res != NRFX_SUCCESS) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res = nrfx_gpiote_input_configure(wake_pin,
|
||||
&input_config,
|
||||
&trigger_config,
|
||||
NULL);
|
||||
res = nrfx_gpiote_input_configure(gpiote, wake_pin, &input_config);
|
||||
if (res != NRFX_SUCCESS) {
|
||||
nrfx_gpiote_channel_free(ch);
|
||||
nrfx_gpiote_channel_free(gpiote, ch);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_nrfx_wake_request(uint32_t wake_pin)
|
||||
int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin)
|
||||
{
|
||||
nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(wake_pin);
|
||||
nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(gpiote, wake_pin);
|
||||
uint32_t start_cycles;
|
||||
uint32_t max_wait_cycles =
|
||||
DIV_ROUND_UP(CONFIG_SPI_NRFX_WAKE_TIMEOUT_US *
|
||||
|
@ -51,7 +50,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin)
|
|||
* The expected time to wait is quite short so it is not worth paying
|
||||
* the overhead of context switching to handle the interrupt.
|
||||
*/
|
||||
nrfx_gpiote_trigger_enable(wake_pin, false);
|
||||
nrfx_gpiote_trigger_enable(gpiote, wake_pin, false);
|
||||
/* Enable pull-up on the WAKE line. After the slave device sees the
|
||||
* WAKE line going high, it will force the line to go low. This will
|
||||
* be caught by the enabled trigger and the loop below waits for that.
|
||||
|
@ -59,7 +58,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin)
|
|||
nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLUP);
|
||||
|
||||
start_cycles = k_cycle_get_32();
|
||||
while (!nrf_gpiote_event_check(NRF_GPIOTE, trigger_event)) {
|
||||
while (!nrf_gpiote_event_check(gpiote->p_reg, trigger_event)) {
|
||||
uint32_t elapsed_cycles = k_cycle_get_32() - start_cycles;
|
||||
|
||||
if (elapsed_cycles >= max_wait_cycles) {
|
||||
|
@ -68,7 +67,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin)
|
|||
}
|
||||
}
|
||||
|
||||
nrfx_gpiote_trigger_disable(wake_pin);
|
||||
nrfx_gpiote_trigger_disable(gpiote, wake_pin);
|
||||
nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLDOWN);
|
||||
|
||||
return err;
|
||||
|
|
|
@ -8,10 +8,17 @@
|
|||
#define ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <nrfx_gpiote.h>
|
||||
|
||||
#define WAKE_PIN_NOT_USED UINT32_MAX
|
||||
|
||||
int spi_nrfx_wake_init(uint32_t wake_pin);
|
||||
int spi_nrfx_wake_request(uint32_t wake_pin);
|
||||
#define WAKE_GPIOTE_INSTANCE(node_id) \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(node_id, wake_gpios), \
|
||||
(NRFX_GPIOTE_INSTANCE( \
|
||||
NRF_DT_GPIOTE_INST(node_id, wake_gpios))), \
|
||||
({0}))
|
||||
|
||||
int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin);
|
||||
int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ */
|
||||
|
|
|
@ -31,6 +31,7 @@ struct spi_nrfx_config {
|
|||
void (*irq_connect)(void);
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
uint32_t wake_pin;
|
||||
nrfx_gpiote_t wake_gpiote;
|
||||
};
|
||||
|
||||
static void event_handler(const nrfx_spi_evt_t *p_event, void *p_context);
|
||||
|
@ -237,7 +238,8 @@ static int transceive(const struct device *dev,
|
|||
dev_data->busy = true;
|
||||
|
||||
if (dev_config->wake_pin != WAKE_PIN_NOT_USED) {
|
||||
error = spi_nrfx_wake_request(dev_config->wake_pin);
|
||||
error = spi_nrfx_wake_request(&dev_config->wake_gpiote,
|
||||
dev_config->wake_pin);
|
||||
if (error == -ETIMEDOUT) {
|
||||
LOG_WRN("Waiting for WAKE acknowledgment timed out");
|
||||
/* If timeout occurs, try to perform the transfer
|
||||
|
@ -381,7 +383,7 @@ static int spi_nrfx_init(const struct device *dev)
|
|||
}
|
||||
|
||||
if (dev_config->wake_pin != WAKE_PIN_NOT_USED) {
|
||||
err = spi_nrfx_wake_init(dev_config->wake_pin);
|
||||
err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin);
|
||||
if (err == -ENODEV) {
|
||||
LOG_ERR("Failed to allocate GPIOTE channel for WAKE");
|
||||
return err;
|
||||
|
@ -444,6 +446,7 @@ static int spi_nrfx_init(const struct device *dev)
|
|||
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPI(idx)), \
|
||||
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPI(idx), wake_gpios, \
|
||||
WAKE_PIN_NOT_USED), \
|
||||
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPI(idx)), \
|
||||
}; \
|
||||
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPI(idx), wake_gpios) || \
|
||||
!(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <soc.h>
|
||||
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
|
||||
#include <nrfx_gpiote.h>
|
||||
#include <nrfx_ppi.h>
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_NRF5340_CPUAPP
|
||||
|
@ -64,6 +63,7 @@ struct spi_nrfx_config {
|
|||
bool anomaly_58_workaround;
|
||||
#endif
|
||||
uint32_t wake_pin;
|
||||
nrfx_gpiote_t wake_gpiote;
|
||||
};
|
||||
|
||||
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
|
||||
|
@ -207,6 +207,8 @@ static int configure(const struct device *dev,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
|
||||
static const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(0);
|
||||
|
||||
/*
|
||||
* Brief Workaround for transmitting 1 byte with SPIM.
|
||||
*
|
||||
|
@ -226,15 +228,15 @@ static void anomaly_58_workaround_setup(const struct device *dev)
|
|||
NRF_SPIM_Type *spim = dev_config->spim.p_reg;
|
||||
uint32_t ppi_ch = dev_data->ppi_ch;
|
||||
uint32_t gpiote_ch = dev_data->gpiote_ch;
|
||||
uint32_t eep = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_ch];
|
||||
uint32_t eep = (uint32_t)&gpiote.p_reg->EVENTS_IN[gpiote_ch];
|
||||
uint32_t tep = (uint32_t)&spim->TASKS_STOP;
|
||||
|
||||
dev_data->anomaly_58_workaround_active = true;
|
||||
|
||||
/* Create an event when SCK toggles */
|
||||
nrf_gpiote_event_configure(NRF_GPIOTE, gpiote_ch, spim->PSEL.SCK,
|
||||
nrf_gpiote_event_configure(gpiote.p_reg, gpiote_ch, spim->PSEL.SCK,
|
||||
GPIOTE_CONFIG_POLARITY_Toggle);
|
||||
nrf_gpiote_event_enable(NRF_GPIOTE, gpiote_ch);
|
||||
nrf_gpiote_event_enable(gpiote.p_reg, gpiote_ch);
|
||||
|
||||
/* Stop the spim instance when SCK toggles */
|
||||
nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, eep, tep);
|
||||
|
@ -253,7 +255,7 @@ static void anomaly_58_workaround_clear(struct spi_nrfx_data *dev_data)
|
|||
|
||||
if (dev_data->anomaly_58_workaround_active) {
|
||||
nrf_ppi_channel_disable(NRF_PPI, ppi_ch);
|
||||
nrf_gpiote_task_disable(NRF_GPIOTE, gpiote_ch);
|
||||
nrf_gpiote_task_disable(gpiote.p_reg, gpiote_ch);
|
||||
|
||||
dev_data->anomaly_58_workaround_active = false;
|
||||
}
|
||||
|
@ -274,7 +276,7 @@ static int anomaly_58_workaround_init(const struct device *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
err_code = nrfx_gpiote_channel_alloc(&dev_data->gpiote_ch);
|
||||
err_code = nrfx_gpiote_channel_alloc(&gpiote, &dev_data->gpiote_ch);
|
||||
if (err_code != NRFX_SUCCESS) {
|
||||
LOG_ERR("Failed to allocate GPIOTE channel");
|
||||
return -ENODEV;
|
||||
|
@ -426,7 +428,8 @@ static int transceive(const struct device *dev,
|
|||
dev_data->busy = true;
|
||||
|
||||
if (dev_config->wake_pin != WAKE_PIN_NOT_USED) {
|
||||
error = spi_nrfx_wake_request(dev_config->wake_pin);
|
||||
error = spi_nrfx_wake_request(&dev_config->wake_gpiote,
|
||||
dev_config->wake_pin);
|
||||
if (error == -ETIMEDOUT) {
|
||||
LOG_WRN("Waiting for WAKE acknowledgment timed out");
|
||||
/* If timeout occurs, try to perform the transfer
|
||||
|
@ -574,7 +577,7 @@ static int spi_nrfx_init(const struct device *dev)
|
|||
}
|
||||
|
||||
if (dev_config->wake_pin != WAKE_PIN_NOT_USED) {
|
||||
err = spi_nrfx_wake_init(dev_config->wake_pin);
|
||||
err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin);
|
||||
if (err == -ENODEV) {
|
||||
LOG_ERR("Failed to allocate GPIOTE channel for WAKE");
|
||||
return err;
|
||||
|
@ -665,6 +668,7 @@ static int spi_nrfx_init(const struct device *dev)
|
|||
()) \
|
||||
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
|
||||
WAKE_PIN_NOT_USED), \
|
||||
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
|
||||
}; \
|
||||
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
|
||||
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
|
||||
|
|
|
@ -145,8 +145,12 @@ static const struct wdt_driver_api wdt_nrfx_driver_api = {
|
|||
.feed = wdt_nrf_feed,
|
||||
};
|
||||
|
||||
static void wdt_event_handler(const struct device *dev, uint32_t requests)
|
||||
static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type,
|
||||
uint32_t requests, void *p_context)
|
||||
{
|
||||
(void)event_type;
|
||||
(void)p_context;
|
||||
|
||||
struct wdt_nrfx_data *data = dev->data;
|
||||
|
||||
while (requests) {
|
||||
|
@ -162,9 +166,12 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests)
|
|||
#define WDT(idx) DT_NODELABEL(wdt##idx)
|
||||
|
||||
#define WDT_NRFX_WDT_DEVICE(idx) \
|
||||
static void wdt_##idx##_event_handler(uint32_t requests) \
|
||||
static void wdt_##idx##_event_handler(nrf_wdt_event_t event_type, \
|
||||
uint32_t requests, \
|
||||
void *p_context) \
|
||||
{ \
|
||||
wdt_event_handler(DEVICE_DT_GET(WDT(idx)), requests); \
|
||||
wdt_event_handler(DEVICE_DT_GET(WDT(idx)), event_type, \
|
||||
requests, p_context); \
|
||||
} \
|
||||
static int wdt_##idx##_init(const struct device *dev) \
|
||||
{ \
|
||||
|
@ -174,7 +181,8 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests)
|
|||
nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0); \
|
||||
err_code = nrfx_wdt_init(&config->wdt, \
|
||||
NULL, \
|
||||
wdt_##idx##_event_handler); \
|
||||
wdt_##idx##_event_handler, \
|
||||
NULL); \
|
||||
if (err_code != NRFX_SUCCESS) { \
|
||||
return -EBUSY; \
|
||||
} \
|
||||
|
|
|
@ -9,12 +9,6 @@
|
|||
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
/*
|
||||
* NRFX API version 2.10 flag.
|
||||
* When the flag is set NRFX API is compatible with the newest NRFX release.
|
||||
*/
|
||||
#define NRFX_CONFIG_API_VER_2_10 1
|
||||
|
||||
/*
|
||||
* These are mappings of Kconfig options enabling nrfx drivers and particular
|
||||
* peripheral instances to the corresponding symbols used inside of nrfx.
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
/** @brief Symbol specifying minor version of the nrfx API to be used. */
|
||||
#ifndef NRFX_CONFIG_API_VER_MINOR
|
||||
#define NRFX_CONFIG_API_VER_MINOR 0
|
||||
#define NRFX_CONFIG_API_VER_MINOR 2
|
||||
#endif
|
||||
|
||||
/** @brief Symbol specifying micro version of the nrfx API to be used. */
|
||||
|
|
|
@ -7,4 +7,14 @@ config NRFX_DPPI
|
|||
config NRFX_PPI
|
||||
default HAS_HW_NRF_PPI
|
||||
|
||||
config NRFX_GPIOTE0
|
||||
default y if SOC_SERIES_NRF51X || \
|
||||
SOC_SERIES_NRF52X || \
|
||||
(SOC_SERIES_NRF53X && !TRUSTED_EXECUTION_NONSECURE) || \
|
||||
(SOC_SERIES_NRF91X && !TRUSTED_EXECUTION_NONSECURE)
|
||||
|
||||
config NRFX_GPIOTE1
|
||||
default y if (SOC_SERIES_NRF53X && TRUSTED_EXECUTION_NONSECURE) || \
|
||||
(SOC_SERIES_NRF91X && TRUSTED_EXECUTION_NONSECURE)
|
||||
|
||||
source "Kconfig.zephyr"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
CONFIG_GPIO=n
|
||||
CONFIG_NRFX_GPIOTE=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100
|
||||
|
|
|
@ -21,6 +21,15 @@ LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF);
|
|||
#define INPUT_PIN DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
|
||||
#define OUTPUT_PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios)
|
||||
|
||||
#define GPIOTE_INST NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios)
|
||||
#define GPIOTE_NODE DT_NODELABEL(_CONCAT(gpiote, GPIOTE_INST))
|
||||
|
||||
BUILD_ASSERT(NRF_DT_GPIOTE_INST(DT_ALIAS(led0), gpios) == GPIOTE_INST,
|
||||
"Both sw0 and led0 GPIOs must use the same GPIOTE instance");
|
||||
BUILD_ASSERT(IS_ENABLED(_CONCAT(CONFIG_, _CONCAT(NRFX_GPIOTE, GPIOTE_INST))),
|
||||
"NRFX_GPIOTE" STRINGIFY(GPIOTE_INST) " must be enabled in Kconfig");
|
||||
|
||||
|
||||
static void button_handler(nrfx_gpiote_pin_t pin,
|
||||
nrfx_gpiote_trigger_t trigger,
|
||||
void *context)
|
||||
|
@ -35,28 +44,28 @@ int main(void)
|
|||
nrfx_err_t err;
|
||||
uint8_t in_channel, out_channel;
|
||||
uint8_t ppi_channel;
|
||||
const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(GPIOTE_INST);
|
||||
|
||||
/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
|
||||
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
|
||||
DT_IRQ(DT_NODELABEL(gpiote), priority),
|
||||
nrfx_isr, nrfx_gpiote_irq_handler, 0);
|
||||
/* Connect GPIOTE instance IRQ to irq handler */
|
||||
IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), nrfx_isr,
|
||||
NRFX_CONCAT(nrfx_gpiote_, GPIOTE_INST, _irq_handler), 0);
|
||||
|
||||
/* Initialize GPIOTE (the interrupt priority passed as the parameter
|
||||
* here is ignored, see nrfx_glue.h).
|
||||
*/
|
||||
err = nrfx_gpiote_init(0);
|
||||
err = nrfx_gpiote_init(&gpiote, 0);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
LOG_ERR("nrfx_gpiote_init error: 0x%08X", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_channel_alloc(&in_channel);
|
||||
err = nrfx_gpiote_channel_alloc(&gpiote, &in_channel);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
LOG_ERR("Failed to allocate in_channel, error: 0x%08X", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = nrfx_gpiote_channel_alloc(&out_channel);
|
||||
err = nrfx_gpiote_channel_alloc(&gpiote, &out_channel);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
LOG_ERR("Failed to allocate out_channel, error: 0x%08X", err);
|
||||
return 0;
|
||||
|
@ -65,20 +74,22 @@ int main(void)
|
|||
/* Initialize input pin to generate event on high to low transition
|
||||
* (falling edge) and call button_handler()
|
||||
*/
|
||||
static const nrfx_gpiote_input_config_t input_config = {
|
||||
.pull = NRF_GPIO_PIN_PULLUP,
|
||||
};
|
||||
const nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
static const nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLUP;
|
||||
nrfx_gpiote_trigger_config_t trigger_config = {
|
||||
.trigger = NRFX_GPIOTE_TRIGGER_HITOLO,
|
||||
.p_in_channel = &in_channel,
|
||||
};
|
||||
static const nrfx_gpiote_handler_config_t handler_config = {
|
||||
.handler = button_handler,
|
||||
};
|
||||
err = nrfx_gpiote_input_configure(INPUT_PIN,
|
||||
&input_config,
|
||||
&trigger_config,
|
||||
&handler_config);
|
||||
nrfx_gpiote_input_pin_config_t input_config = {
|
||||
.p_pull_config = &pull_config,
|
||||
.p_trigger_config = &trigger_config,
|
||||
.p_handler_config = &handler_config
|
||||
};
|
||||
|
||||
err = nrfx_gpiote_input_configure(&gpiote, INPUT_PIN, &input_config);
|
||||
|
||||
if (err != NRFX_SUCCESS) {
|
||||
LOG_ERR("nrfx_gpiote_input_configure error: 0x%08X", err);
|
||||
return 0;
|
||||
|
@ -97,7 +108,7 @@ int main(void)
|
|||
.polarity = NRF_GPIOTE_POLARITY_TOGGLE,
|
||||
.init_val = 1,
|
||||
};
|
||||
err = nrfx_gpiote_output_configure(OUTPUT_PIN,
|
||||
err = nrfx_gpiote_output_configure(&gpiote, OUTPUT_PIN,
|
||||
&output_config,
|
||||
&task_config);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
|
@ -105,8 +116,8 @@ int main(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
nrfx_gpiote_trigger_enable(INPUT_PIN, true);
|
||||
nrfx_gpiote_out_task_enable(OUTPUT_PIN);
|
||||
nrfx_gpiote_trigger_enable(&gpiote, INPUT_PIN, true);
|
||||
nrfx_gpiote_out_task_enable(&gpiote, OUTPUT_PIN);
|
||||
|
||||
LOG_INF("nrfx_gpiote initialized");
|
||||
|
||||
|
@ -122,8 +133,8 @@ int main(void)
|
|||
* the button is pressed, the LED pin will be toggled.
|
||||
*/
|
||||
nrfx_gppi_channel_endpoints_setup(ppi_channel,
|
||||
nrfx_gpiote_in_event_address_get(INPUT_PIN),
|
||||
nrfx_gpiote_out_task_address_get(OUTPUT_PIN));
|
||||
nrfx_gpiote_in_event_address_get(&gpiote, INPUT_PIN),
|
||||
nrfx_gpiote_out_task_address_get(&gpiote, OUTPUT_PIN));
|
||||
|
||||
/* Enable the channel. */
|
||||
nrfx_gppi_channels_enable(BIT(ppi_channel));
|
||||
|
|
Loading…
Reference in a new issue