diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 72a20f47fc9f015..6d1973ca0aae9c2 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -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); } diff --git a/drivers/display/display_nrf_led_matrix.c b/drivers/display/display_nrf_led_matrix.c index 5468347551da6da..403ca87ea8dd585 100644 --- a/drivers/display/display_nrf_led_matrix.c +++ b/drivers/display/display_nrf_led_matrix.c @@ -20,13 +20,14 @@ #include LOG_MODULE_REGISTER(nrf_led_matrix, CONFIG_DISPLAY_LOG_LEVEL); -#define MATRIX_NODE DT_INST(0, nordic_nrf_led_matrix) -#define TIMER_NODE DT_PHANDLE(MATRIX_NODE, timer) -#define USE_PWM DT_NODE_HAS_PROP(MATRIX_NODE, pwm) -#define PWM_NODE DT_PHANDLE(MATRIX_NODE, pwm) -#define ROW_COUNT DT_PROP_LEN(MATRIX_NODE, row_gpios) -#define COL_COUNT DT_PROP_LEN(MATRIX_NODE, col_gpios) -#define GROUP_SIZE DT_PROP(MATRIX_NODE, pixel_group_size) +#define DT_DRV_COMPAT nordic_nrf_led_matrix +#define MATRIX_NODE DT_INST(0, nordic_nrf_led_matrix) +#define TIMER_NODE DT_PHANDLE(MATRIX_NODE, timer) +#define USE_PWM DT_NODE_HAS_PROP(MATRIX_NODE, pwm) +#define PWM_NODE DT_PHANDLE(MATRIX_NODE, pwm) +#define ROW_COUNT DT_PROP_LEN(MATRIX_NODE, row_gpios) +#define COL_COUNT DT_PROP_LEN(MATRIX_NODE, col_gpios) +#define GROUP_SIZE DT_PROP(MATRIX_NODE, pixel_group_size) #if (GROUP_SIZE > DT_PROP(TIMER_NODE, cc_num) - 1) || \ (USE_PWM && GROUP_SIZE > PWM0_CH_NUM) #error "Invalid pixel-group-size configured." @@ -85,6 +86,19 @@ DT_FOREACH_PROP_ELEM(MATRIX_NODE, pixel_mapping, CHECK_PIXEL) #define ITERATION_COUNT PIXEL_COUNT #endif +#if !USE_PWM +#define GPIO_NODE(pin) DT_GPIO_CTLR_BY_IDX(DT_DRV_INST(0), col_gpios, pin) +#define GPIOTE_PHANDLE(pin) DT_PHANDLE(GPIO_NODE(pin), gpiote_instance) +#define GPIOTE_IDX(pin) DT_PROP(GPIOTE_PHANDLE(pin), instance) + +#define GPIOTE_INSTANCE(_node_id, _prop, _idx) \ + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(_idx)), + +static const nrfx_gpiote_t gpiote[COL_COUNT] = { + DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, GPIOTE_INSTANCE) +}; +#endif + struct display_drv_config { NRF_TIMER_Type *timer; #if USE_PWM @@ -324,7 +338,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; + gpiote[channel_idx].p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; #endif /* USE_PWM */ } @@ -354,7 +368,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; + gpiote[i].p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0; } #endif @@ -450,7 +464,7 @@ static int instance_init(const struct device *dev) return -ENOMEM; } - err = nrfx_gpiote_channel_alloc(gpiote_ch); + err = nrfx_gpiote_channel_alloc(&gpiote[i], gpiote_ch); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate GPIOTE channel."); /* Do not bother with freeing resources allocated @@ -463,7 +477,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(gpiote[i].p_reg, nrf_gpiote_out_task_get(*gpiote_ch))); nrf_ppi_channel_enable(NRF_PPI, ppi_ch); } diff --git a/drivers/gpio/Kconfig.nrfx b/drivers/gpio/Kconfig.nrfx index 356c43cb5fa1fc3..760a45204fdff48 100644 --- a/drivers/gpio/Kconfig.nrfx +++ b/drivers/gpio/Kconfig.nrfx @@ -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. diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 0aa282dda37dc31..96c3290676f431e 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define DT_DRV_COMPAT nordic_nrf_gpio #include @@ -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,131 +39,139 @@ 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) +{ + return cfg->gpiote.p_reg != NULL; +} + +static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) +{ + if (flags & GPIO_PULL_UP) { + return NRF_GPIO_PIN_PULLUP; + } else if (flags & GPIO_PULL_DOWN) { + return NRF_GPIO_PIN_PULLDOWN; + } + + return NRF_GPIO_PIN_NOPULL; +} + +static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, + gpio_flags_t flags) { + nrfx_err_t err = NRFX_SUCCESS; + uint8_t ch; + 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; + drive = NRF_GPIO_PIN_S0S1; break; case NRF_GPIO_DRIVE_S0H1: - *drive = NRF_GPIO_PIN_S0H1; + drive = NRF_GPIO_PIN_S0H1; break; case NRF_GPIO_DRIVE_H0S1: - *drive = NRF_GPIO_PIN_H0S1; + drive = NRF_GPIO_PIN_H0S1; break; case NRF_GPIO_DRIVE_H0H1: - *drive = NRF_GPIO_PIN_H0H1; + drive = NRF_GPIO_PIN_H0H1; break; case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_S0D1; + drive = NRF_GPIO_PIN_S0D1; break; case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_H0D1; + drive = NRF_GPIO_PIN_H0D1; break; case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0S1; + drive = NRF_GPIO_PIN_D0S1; break; case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0H1; + drive = NRF_GPIO_PIN_D0H1; break; default: return -EINVAL; } - return 0; -} - -static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) -{ - if (flags & GPIO_PULL_UP) { - return NRF_GPIO_PIN_PULLUP; - } else if (flags & GPIO_PULL_DOWN) { - return NRF_GPIO_PIN_PULLDOWN; + 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)); } - return NRF_GPIO_PIN_NOPULL; -} + 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; -static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, - gpio_flags_t flags) -{ - nrfx_err_t err = NRFX_SUCCESS; - uint8_t ch; - 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_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); - - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + (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, + }; + + err = nrfx_gpiote_input_configure(&cfg->gpiote, + abs_pin, &input_pin_config); + if (err != NRFX_SUCCESS) { + return -EINVAL; + } } - return 0; - } - - if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - nrfx_gpiote_trigger_config_t trigger_config = { - .trigger = NRFX_GPIOTE_TRIGGER_NONE - }; + 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, + }; + + 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; + } + + if (nrfx_gpiote_init_check(&cfg->gpiote)) { return 0; } - err = nrfx_gpiote_init(0/*not used*/); + 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_IDX(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_IDX(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; \ diff --git a/drivers/pwm/pwm_nrf_sw.c b/drivers/pwm/pwm_nrf_sw.c index f367bb59899f39a..2b9a22a38f081a0 100644 --- a/drivers/pwm/pwm_nrf_sw.c +++ b/drivers/pwm/pwm_nrf_sw.c @@ -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) }, diff --git a/drivers/spi/spi_nrfx_common.c b/drivers/spi/spi_nrfx_common.c index 1ef233cfab3819f..04a11c2367a92f9 100644 --- a/drivers/spi/spi_nrfx_common.c +++ b/drivers/spi/spi_nrfx_common.c @@ -6,40 +6,39 @@ #include "spi_nrfx_common.h" #include -#include -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; diff --git a/drivers/spi/spi_nrfx_common.h b/drivers/spi/spi_nrfx_common.h index 515ed5c6f1f2758..0cf17e2a0356de3 100644 --- a/drivers/spi/spi_nrfx_common.h +++ b/drivers/spi/spi_nrfx_common.h @@ -8,10 +8,17 @@ #define ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ #include +#include #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_ */ diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index fd1dc5d933c49a6..d5966e15367c9d0 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -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), \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 1338bd0a4dc6fec..95b737d6cf5b5f3 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -9,7 +9,6 @@ #include #include #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 -#include #include #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),\ diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 363a1174e916c43..8967d1e162be561 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -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; \ } \ diff --git a/dts/bindings/gpio/nordic,nrf-gpio.yaml b/dts/bindings/gpio/nordic,nrf-gpio.yaml index 550acd1a865cfe8..097a99d8fa94b0f 100644 --- a/dts/bindings/gpio/nordic,nrf-gpio.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpio.yaml @@ -11,6 +11,11 @@ properties: reg: required: true + gpiote-instance: + type: phandle + description: | + GPIOTE instance that can be used with this GPIO port. + "#gpio-cells": const: 2 diff --git a/dts/bindings/gpio/nordic,nrf-gpiote.yaml b/dts/bindings/gpio/nordic,nrf-gpiote.yaml index 49ddba3595ba42f..cefc3385afef8b2 100644 --- a/dts/bindings/gpio/nordic,nrf-gpiote.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpiote.yaml @@ -13,3 +13,15 @@ properties: interrupts: required: true + + instance: + type: int + required: true + description: | + The GPIOTE instance number. GPIOTE instance GPIOTE0 has: + + instance = <0>; + + And GPIOTE1 has: + + instance = <1>; diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 72617325684d73a..57417644c321ba7 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -9,12 +9,6 @@ #include -/* - * 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. diff --git a/modules/hal_nordic/nrfx/nrfx_config_common.h b/modules/hal_nordic/nrfx/nrfx_config_common.h index 8c0a58713a05ba5..28a3a15b0deff7b 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_common.h +++ b/modules/hal_nordic/nrfx/nrfx_config_common.h @@ -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. */ diff --git a/samples/boards/nrf/nrfx/Kconfig b/samples/boards/nrf/nrfx/Kconfig index 0d54067202a2276..a46af347ba932e3 100644 --- a/samples/boards/nrf/nrfx/Kconfig +++ b/samples/boards/nrf/nrfx/Kconfig @@ -2,9 +2,19 @@ # SPDX-License-Identifier: Apache-2.0 config NRFX_DPPI - default HAS_HW_NRF_DPPIC + default $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_DPPIC)) config NRFX_PPI - default HAS_HW_NRF_PPI + default $(dt_has_compat,$(DT_COMPAT_NORDIC_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" diff --git a/samples/boards/nrf/nrfx/prj.conf b/samples/boards/nrf/nrfx/prj.conf index 32cbfc3279cccd1..d4f0c29699f8806 100644 --- a/samples/boards/nrf/nrfx/prj.conf +++ b/samples/boards/nrf/nrfx/prj.conf @@ -1,4 +1,3 @@ CONFIG_GPIO=n -CONFIG_NRFX_GPIOTE=y CONFIG_LOG=y CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 diff --git a/samples/boards/nrf/nrfx/src/main.c b/samples/boards/nrf/nrfx/src/main.c index 615b800545e4863..721cbe033c09322 100644 --- a/samples/boards/nrf/nrfx/src/main.c +++ b/samples/boards/nrf/nrfx/src/main.c @@ -18,8 +18,17 @@ #include 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 INPUT_PIN NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios) +#define OUTPUT_PIN NRF_DT_GPIOS_TO_PSEL(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(GPIOTE_INST == NRF_DT_GPIOTE_INST(DT_ALIAS(led0), gpios), + "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, @@ -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)); diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 621ec3cb3a8bdc6..58cc4ac5c8d3a64 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -558,6 +558,25 @@ def dt_node_array_prop(kconf, name, path, prop, index, unit=None): if name == "dt_node_array_prop_hex": return hex(_node_array_prop(node, prop, index, unit)) +def dt_node_phandle_prop(kconf, _, path, prop): + if doc_mode or edt is None: + return "" + + try: + node = edt.get_node(path) + except edtlib.EDTError: + return "" + + if not node: + return "" + + if prop not in node.props: + return "" + + if node.props[prop].type != "phandle": + return "" + + return str(node.props[prop].val.path) def dt_node_str_prop_equals(kconf, _, path, prop, val): """ @@ -743,6 +762,25 @@ def dt_gpio_hogs_enabled(kconf, _): return "n" +def dt_gpio_ctrl(kconf, _, path, index): + if doc_mode or edt is None: + return "" + + try: + node = edt.get_node(path) + except edtlib.EDTError: + return "" + + if node is None: + return "" + + if node.props["gpios"].type != "phandle-array": + return "" + if int(index) >= len(node.props["gpios"].val): + return "" + return str(node.props["gpios"].val[int(index)].controller.path) + + def shields_list_contains(kconf, _, shield): """ Return "n" if cmake environment variable 'SHIELD_AS_LIST' doesn't exist. @@ -799,6 +837,7 @@ def shields_list_contains(kconf, _, shield): "dt_node_int_prop_hex": (dt_node_int_prop, 2, 3), "dt_node_array_prop_int": (dt_node_array_prop, 3, 4), "dt_node_array_prop_hex": (dt_node_array_prop, 3, 4), + "dt_node_phandle_prop": (dt_node_phandle_prop, 2, 2), "dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3), "dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2), "dt_node_has_compat": (dt_node_has_compat, 2, 2), @@ -806,5 +845,6 @@ def shields_list_contains(kconf, _, shield): "dt_node_parent": (dt_node_parent, 1, 1), "dt_nodelabel_array_prop_has_val": (dt_nodelabel_array_prop_has_val, 3, 3), "dt_gpio_hogs_enabled": (dt_gpio_hogs_enabled, 0, 0), + "dt_gpio_ctrl": (dt_gpio_ctrl, 2, 2), "shields_list_contains": (shields_list_contains, 1, 1), } diff --git a/soc/arm/nordic_nrf/common/soc_nrf_common.h b/soc/arm/nordic_nrf/common/soc_nrf_common.h index 4c00d7c0237cb83..a555d536486d55e 100644 --- a/soc/arm/nordic_nrf/common/soc_nrf_common.h +++ b/soc/arm/nordic_nrf/common/soc_nrf_common.h @@ -149,6 +149,14 @@ (NRF_DT_GPIOS_TO_PSEL(node_id, prop)), \ (default_value)) +#define NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) \ + DT_PROP(DT_PHANDLE(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx), \ + gpiote_instance), \ + instance) + +#define NRF_DT_GPIOTE_INST(node_id, prop) \ + NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0) + /** * Error out the build if 'prop' is set on node 'node_id' and * DT_GPIO_CTLR(node_id, prop) is not an SoC GPIO controller, diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 90d756504398f57..069e9fa34b959b3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "util/mem.h" @@ -55,6 +56,10 @@ GPIOTE_CONFIG_OUTINIT_High : \ GPIOTE_CONFIG_OUTINIT_Low) +#define GPIO_NODE(node, pin, idx) DT_GPIO_CTLR_BY_IDX(node, pin, idx) +#define GPIOTE_PHANDLE(node, pin, idx) DT_PHANDLE(GPIO_NODE(node, pin, idx), gpiote_instance) +#define GPIOTE_IDX(node, pin, idx) DT_PROP(GPIOTE_PHANDLE(node, pin, idx), instance) + #if defined(FEM_NODE) BUILD_ASSERT(!HAL_RADIO_GPIO_PA_OFFSET_MISSING, "fem node " DT_NODE_PATH(FEM_NODE) " has property " @@ -1547,7 +1552,10 @@ uint32_t radio_tmr_sample_get(void) #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) void radio_gpio_pa_setup(void) { - NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = + nrfx_gpiote_t gpiote = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, 0)); + + gpiote.p_reg->CONFIG[HAL_PALNA_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (NRF_GPIO_PA_PSEL << @@ -1568,7 +1576,10 @@ void radio_gpio_pa_setup(void) #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) void radio_gpio_lna_setup(void) { - NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = + nrfx_gpiote_t gpiote = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP, 0)); + + gpiote.p_reg->CONFIG[HAL_PALNA_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (NRF_GPIO_LNA_PSEL << @@ -1589,7 +1600,9 @@ void radio_gpio_pdn_setup(void) { /* Note: the pdn-gpios property is optional. */ #if defined(NRF_GPIO_PDN) - NRF_GPIOTE->CONFIG[HAL_PDN_GPIOTE_CHAN] = + nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, pdn_gpios, 0)); + + gpiote.p_reg->CONFIG[HAL_PDN_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (NRF_GPIO_PDN_PSEL << @@ -1605,7 +1618,10 @@ void radio_gpio_csn_setup(void) { /* Note: the spi-if property is optional. */ #if defined(NRF_GPIO_CSN_PIN) - NRF_GPIOTE->CONFIG[HAL_CSN_GPIOTE_CHAN] = + nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE( + GPIOTE_IDX(DT_BUS(FEM_SPI_DEV_NODE), cs_gpios, DT_REG_ADDR(FEM_SPI_DEV_NODE))); + + gpiote.p_reg->CONFIG[HAL_CSN_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (NRF_GPIO_CSN_PSEL << @@ -1653,18 +1669,28 @@ void radio_gpio_pa_lna_enable(uint32_t trx_us) void radio_gpio_pa_lna_disable(void) { + nrfx_gpiote_t gpiote_pa = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, 0)); #if defined(HAL_RADIO_FEM_IS_NRF21540) + nrfx_gpiote_t gpiote_pdn = NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, pdn_gpios, 0)); +#if defined(NRF_GPIO_CSN_PIN) + nrfx_gpiote_t gpiote_cs = NRFX_GPIOTE_INSTANCE( + GPIOTE_IDX(DT_BUS(FEM_SPI_DEV_NODE), cs_gpios, DT_REG_ADDR(FEM_SPI_DEV_NODE))); +#endif + hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) | BIT(HAL_DISABLE_PALNA_PPI) | BIT(HAL_ENABLE_FEM_PPI) | BIT(HAL_DISABLE_FEM_PPI)); - NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0; - NRF_GPIOTE->CONFIG[HAL_PDN_GPIOTE_CHAN] = 0; - NRF_GPIOTE->CONFIG[HAL_CSN_GPIOTE_CHAN] = 0; + gpiote_pa.p_reg->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0; + gpiote_pdn.p_reg->CONFIG[HAL_PDN_GPIOTE_CHAN] = 0; +#if defined(NRF_GPIO_CSN_PIN) + gpiote_cs.p_reg->CONFIG[HAL_CSN_GPIOTE_CHAN] = 0; +#endif #else hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) | BIT(HAL_DISABLE_PALNA_PPI)); - NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0; + gpiote_pa.p_reg->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0; #endif } #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 1fdf7d90d30cb27..50b9e9030e5ebd9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -180,6 +180,13 @@ static inline void hal_trigger_rateoverride_ppi_config(void) nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_RATEOVERRIDE, HAL_TRIGGER_RATEOVERRIDE_PPI); } +#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) || \ + defined(HAL_RADIO_FEM_IS_NRF21540) +#define GPIO_NODE(node, pin, idx) DT_GPIO_CTLR_BY_IDX(node, pin, idx) +#define GPIOTE_PHANDLE(node, pin, idx) DT_PHANDLE(GPIO_NODE(node, pin, idx), gpiote_instance) +#define GPIOTE_IDX(node, pin, idx) DT_PROP(GPIOTE_PHANDLE(node, pin, idx), instance) +#endif + /******************************************************************************/ #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) static inline void hal_palna_ppi_setup(void) @@ -191,9 +198,11 @@ static inline void hal_palna_ppi_setup(void) #if !defined(HAL_RADIO_FEM_IS_NRF21540) nrf_gpiote_task_t task; + nrfx_gpiote_t gpiote = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, 0)); task = nrf_gpiote_out_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_DISABLE_PALNA_PPI); #endif } #endif /* defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) */ @@ -204,40 +213,47 @@ static inline void hal_palna_ppi_setup(void) static inline void hal_pa_ppi_setup(void) { nrf_gpiote_task_t task; + nrfx_gpiote_t gpiote = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, 0)); #if defined(HAL_RADIO_GPIO_PA_POL_INV) task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_ENABLE_PALNA_PPI); task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_DISABLE_PALNA_PPI); #else /* !HAL_RADIO_GPIO_PA_POL_INV */ task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_ENABLE_PALNA_PPI); task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_DISABLE_PALNA_PPI); #endif /* !HAL_RADIO_GPIO_PA_POL_INV */ } static inline void hal_lna_ppi_setup(void) { nrf_gpiote_task_t task; + nrfx_gpiote_t gpiote = + NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, 0)); #if defined(HAL_RADIO_GPIO_LNA_POL_INV) task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_ENABLE_PALNA_PPI); task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_DISABLE_PALNA_PPI); #else /* !HAL_RADIO_GPIO_LNA_POL_INV */ task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_ENABLE_PALNA_PPI); task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI); + nrf_gpiote_subscribe_set(gpiote.p_reg, task, HAL_DISABLE_PALNA_PPI); #endif /* !HAL_RADIO_GPIO_LNA_POL_INV */ } static inline void hal_fem_ppi_setup(void) { nrf_gpiote_task_t task; + nrfx_gpiote_t gpiote_pdn = NRFX_GPIOTE_INSTANCE(GPIOTE_IDX(FEM_NODE, pdn_gpios, 0)); + nrfx_gpiote_t gpiote_cs = NRFX_GPIOTE_INSTANCE( + GPIOTE_IDX(DT_BUS(FEM_SPI_DEV_NODE), cs_gpios, DT_REG_ADDR(FEM_SPI_DEV_NODE))); nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE3, HAL_ENABLE_FEM_PPI); @@ -246,26 +262,26 @@ static inline void hal_fem_ppi_setup(void) #if defined(HAL_RADIO_GPIO_NRF21540_PDN_POL_INV) task = nrf_gpiote_clr_task_get(HAL_PDN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_pdn.p_reg, task, HAL_ENABLE_FEM_PPI); task = nrf_gpiote_set_task_get(HAL_PDN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_pdn.p_reg, task, HAL_DISABLE_FEM_PPI); #else /* !HAL_RADIO_GPIO_NRF21540_PDN_POL_INV */ task = nrf_gpiote_set_task_get(HAL_PDN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_pdn.p_reg, task, HAL_ENABLE_FEM_PPI); task = nrf_gpiote_clr_task_get(HAL_PDN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_pdn.p_reg, task, HAL_DISABLE_FEM_PPI); #endif /* !HAL_RADIO_GPIO_NRF21540_PDN_POL_INV */ #if defined(HAL_RADIO_GPIO_NRF21540_CSN_POL_INV) task = nrf_gpiote_clr_task_get(HAL_CSN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_cs.p_reg, task, HAL_ENABLE_FEM_PPI); task = nrf_gpiote_set_task_get(HAL_CSN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_cs.p_reg, task, HAL_DISABLE_FEM_PPI); #else /* !HAL_RADIO_GPIO_NRF21540_CSN_POL_INV */ task = nrf_gpiote_set_task_get(HAL_CSN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_cs.p_reg, task, HAL_ENABLE_FEM_PPI); task = nrf_gpiote_clr_task_get(HAL_CSN_GPIOTE_CHAN); - nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI); + nrf_gpiote_subscribe_set(gpiote_cs.p_reg, task, HAL_DISABLE_FEM_PPI); #endif /* !HAL_RADIO_GPIO_NRF21540_CSN_POL_INV */ }