diff --git a/boards/posix/nrf52_bsim/Kconfig.board b/boards/posix/nrf52_bsim/Kconfig.board index c29cf83ec90..1c298a2ed7a 100644 --- a/boards/posix/nrf52_bsim/Kconfig.board +++ b/boards/posix/nrf52_bsim/Kconfig.board @@ -14,6 +14,11 @@ config BOARD_NRF52_BSIM # of it), so that the corresponding driver becomes available (see # dependencies of the ENTROPY_NRF5_RNG option). select HAS_HW_NRF_RNG + # Do the same for the CLOCK and POWER peripherals, so that the nrfx + # drivers for them can be used. + select HAS_HW_NRF_CLOCK + select HAS_HW_NRF_POWER + select HAS_NRFX help Will produce a console Linux process which can be executed natively. It needs the BabbleSim simulator both in compile time and to execute diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index 3a9361e08b1..23670ccd5dd 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -14,6 +14,8 @@ menuconfig CLOCK_CONTROL_NRF bool "NRF Clock controller support" depends on SOC_COMPATIBLE_NRF depends on !CLOCK_CONTROL_NRF_FORCE_ALT + select NRFX_CLOCK + select NRFX_POWER default y help Enable support for the Nordic Semiconductor nRFxx series SoC clock diff --git a/drivers/clock_control/nrf_clock_calibration.c b/drivers/clock_control/nrf_clock_calibration.c index 8ca2304fcaf..cc42aa2a186 100644 --- a/drivers/clock_control/nrf_clock_calibration.c +++ b/drivers/clock_control/nrf_clock_calibration.c @@ -7,7 +7,7 @@ #include #include "nrf_clock_calibration.h" #include -#include +#include #include #include @@ -109,7 +109,7 @@ static void start_hw_cal(void) *(volatile uint32_t *)0x40000C34 = 0x00000002; } - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_CAL); + nrfx_clock_calibration_start(); calib_skip_cnt = CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP; } @@ -166,19 +166,6 @@ static void cal_hf_callback(struct onoff_manager *mgr, } } -static void on_hw_cal_done(void) -{ - /* Workaround for Errata 192 */ - if (IS_ENABLED(CONFIG_SOC_SERIES_NRF52X)) { - *(volatile uint32_t *)0x40000C34 = 0x00000000; - } - - total_cnt++; - LOG_DBG("Calibration done."); - - start_cycle(); -} - /* Convert sensor value to 0.25'C units. */ static inline int16_t sensor_value_to_temp_unit(struct sensor_value *val) { @@ -249,12 +236,6 @@ static inline struct device *temp_device(void) void z_nrf_clock_calibration_init(struct onoff_manager *onoff_mgrs) { - /* Anomaly 36: After watchdog timeout reset, CPU lockup reset, soft - * reset, or pin reset EVENTS_DONE and EVENTS_CTTO are not reset. - */ - nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_DONE); - nrf_clock_int_enable(NRF_CLOCK, NRF_CLOCK_INT_DONE_MASK); - mgrs = onoff_mgrs; total_cnt = 0; total_skips_cnt = 0; @@ -298,12 +279,12 @@ void z_nrf_clock_calibration_lfclk_stopped(void) LOG_DBG("Calibration stopped"); } -void z_nrf_clock_calibration_isr(void) +void z_nrf_clock_calibration_done_handler(void) { - if (nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_DONE)) { - nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_DONE); - on_hw_cal_done(); - } + total_cnt++; + LOG_DBG("Calibration done."); + + start_cycle(); } int z_nrf_clock_calibration_count(void) diff --git a/drivers/clock_control/nrf_clock_calibration.h b/drivers/clock_control/nrf_clock_calibration.h index 92fa222d9f1..8071192b90b 100644 --- a/drivers/clock_control/nrf_clock_calibration.h +++ b/drivers/clock_control/nrf_clock_calibration.h @@ -20,11 +20,11 @@ extern "C" { void z_nrf_clock_calibration_init(struct onoff_manager *mgrs); /** - * @brief Calibration interrupts handler + * @brief Calibration done handler * - * Must be called from clock interrupt context. + * Must be called from clock event handler. */ -void z_nrf_clock_calibration_isr(void); +void z_nrf_clock_calibration_done_handler(void); /** * @brief Notify calibration module about LF clock start diff --git a/drivers/clock_control/nrf_power_clock.c b/drivers/clock_control/nrf_power_clock.c index 25140a18cd8..67f92123e77 100644 --- a/drivers/clock_control/nrf_power_clock.c +++ b/drivers/clock_control/nrf_power_clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 Nordic Semiconductor ASA + * Copyright (c) 2016-2020 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 @@ -10,8 +10,9 @@ #include #include #include "nrf_clock_calibration.h" +#include +#include #include -#include #include LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -79,33 +80,6 @@ static atomic_t hfclk_users; static uint64_t hf_start_tstamp; static uint64_t hf_stop_tstamp; -/* Return true if given event has enabled interrupt and is triggered. Event - * is cleared. - */ -static bool clock_event_check_and_clean(nrf_clock_event_t evt, uint32_t intmask) -{ - bool ret = nrf_clock_event_check(NRF_CLOCK, evt) && - nrf_clock_int_enable_check(NRF_CLOCK, intmask); - - if (ret) { - nrf_clock_event_clear(NRF_CLOCK, evt); - } - - return ret; -} - -static void clock_irqs_enable(void) -{ - nrf_clock_int_enable(NRF_CLOCK, - (NRF_CLOCK_INT_HF_STARTED_MASK | - NRF_CLOCK_INT_LF_STARTED_MASK | - COND_CODE_1(CONFIG_USB_NRFX, - (NRF_POWER_INT_USBDETECTED_MASK | - NRF_POWER_INT_USBREMOVED_MASK | - NRF_POWER_INT_USBPWRRDY_MASK), - (0)))); -} - static struct nrf_clock_control_sub_data *get_sub_data(struct device *dev, enum clock_control_nrf_type type) { @@ -229,7 +203,7 @@ static void lfclk_start(void) anomaly_132_workaround(); } - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART); + nrfx_clock_lfclk_start(); } static void lfclk_stop(void) @@ -238,8 +212,7 @@ static void lfclk_stop(void) z_nrf_clock_calibration_lfclk_stopped(); } - nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_LFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP); + nrfx_clock_lfclk_stop(); } static void hfclk_start(void) @@ -248,7 +221,7 @@ static void hfclk_start(void) hf_start_tstamp = k_uptime_get(); } - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); + nrfx_clock_hfclk_start(); } static void hfclk_stop(void) @@ -257,8 +230,7 @@ static void hfclk_stop(void) hf_stop_tstamp = k_uptime_get(); } - nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); + nrfx_clock_hfclk_stop(); } static uint32_t *get_hf_flags(void) @@ -276,8 +248,7 @@ static void generic_hfclk_start(void) hfclk_users |= HF_USER_GENERIC; if (hfclk_users & HF_USER_BT) { - (void)nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, - &type); + (void)nrfx_clock_is_running(NRF_CLOCK_DOMAIN_HFCLK, &type); if (type == NRF_CLOCK_HFCLK_HIGH_ACCURACY) { already_started = true; /* Set on state in case clock interrupt comes and we @@ -458,8 +429,7 @@ static void lfclk_spinwait(nrf_clock_lfclk_t t) nrf_clock_domain_t d = NRF_CLOCK_DOMAIN_LFCLK; nrf_clock_lfclk_t type; - while (!(nrf_clock_is_running(NRF_CLOCK, d, (void *)&type) - && (type == t))) { + while (!(nrfx_clock_is_running(d, (void *)&type) && (type == t))) { /* empty */ } } @@ -497,18 +467,69 @@ void z_nrf_clock_control_lf_on(enum nrf_lfclk_start_mode start_mode) } } -/* Note: this function has public linkage, and MUST have this - * particular name. The platform architecture itself doesn't care, - * but there is a test (tests/kernel/arm_irq_vector_table) that needs - * to find it to it can set it in a custom vector table. Should - * probably better abstract that at some point (e.g. query and reset - * it by pointer at runtime, maybe?) so we don't have this leaky - * symbol. - */ -void nrf_power_clock_isr(void *arg); +static void clock_event_handler(nrfx_clock_evt_type_t event) +{ + struct device *dev = DEVICE_GET(clock_nrf); + + switch (event) { + case NRFX_CLOCK_EVT_HFCLK_STARTED: + { + struct nrf_clock_control_sub_data *data = + get_sub_data(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK); + + /* Check needed due to anomaly 201: + * HFCLKSTARTED may be generated twice. + */ + if (GET_STATUS(data->flags) == CLOCK_CONTROL_STATUS_STARTING) { + clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK); + } + + break; + } + case NRFX_CLOCK_EVT_LFCLK_STARTED: + if (IS_ENABLED( + CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) { + z_nrf_clock_calibration_lfclk_started(); + } + clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_LFCLK); + break; + case NRFX_CLOCK_EVT_CAL_DONE: + if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) { + z_nrf_clock_calibration_done_handler(); + } + break; + default: + __ASSERT_NO_MSG(0); + break; + } +} + +#if defined(CONFIG_USB_NRFX) + +static void usb_event_handler(nrfx_power_usb_evt_t event) +{ + extern void usb_dc_nrfx_power_event_callback(nrf_power_event_t evt); + + switch (event) { + case NRFX_POWER_USB_EVT_DETECTED: + usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBDETECTED); + break; + case NRFX_POWER_USB_EVT_REMOVED: + usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBREMOVED); + break; + case NRFX_POWER_USB_EVT_READY: + usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBPWRRDY); + break; + default: + __ASSERT_NO_MSG(0); + break; + } +} +#endif static int clk_init(struct device *dev) { + nrfx_err_t nrfx_err; int err; static const struct onoff_transitions transitions = { .start = onoff_start, @@ -516,11 +537,22 @@ static int clk_init(struct device *dev) }; IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), - nrf_power_clock_isr, 0, 0); - + nrfx_isr, nrfx_power_clock_irq_handler, 0); irq_enable(DT_INST_IRQN(0)); - nrf_clock_lf_src_set(NRF_CLOCK, CLOCK_CONTROL_NRF_K32SRC); +#if defined(CONFIG_USB_NRFX) && defined(CONFIG_SOC_SERIES_NRF53X) + /* Use CLOCK/POWER priority for compatibility with other series where + * USB events are handled by CLOCK interrupt handler. + */ + IRQ_CONNECT(USBREGULATOR_IRQn, DT_INST_IRQ(0, priority), + nrfx_usbreg_irq_handler, 0, 0); + irq_enable(USBREGULATOR_IRQn); +#endif + + nrfx_err = nrfx_clock_init(clock_event_handler); + if (nrfx_err != NRFX_SUCCESS) { + return -EIO; + } if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) { struct nrf_clock_control_data *data = dev->data; @@ -528,7 +560,13 @@ static int clk_init(struct device *dev) z_nrf_clock_calibration_init(data->mgr); } - clock_irqs_enable(); + nrfx_clock_enable(); + + static const nrfx_power_usbevt_config_t config = { + .handler = usb_event_handler + }; + + nrfx_power_usbevt_init(&config); for (enum clock_control_nrf_type i = 0; i < CLOCK_CONTROL_NRF_TYPE_COUNT; i++) { @@ -546,6 +584,7 @@ static int clk_init(struct device *dev) return 0; } + static const struct clock_control_driver_api clock_control_api = { .on = api_blocking_start, .off = api_stop, @@ -575,94 +614,13 @@ DEVICE_AND_API_INIT(clock_nrf, DT_INST_LABEL(0), CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &clock_control_api); -#if defined(CONFIG_USB_NRFX) -static bool power_event_check_and_clean(nrf_power_event_t evt, uint32_t intmask) -{ - bool ret = nrf_power_event_check(NRF_POWER, evt) && - nrf_power_int_enable_check(NRF_POWER, intmask); - - if (ret) { - nrf_power_event_clear(NRF_POWER, evt); - } - - return ret; -} -#endif - -static void usb_power_isr(void) -{ -#if defined(CONFIG_USB_NRFX) - extern void usb_dc_nrfx_power_event_callback(nrf_power_event_t event); - - if (power_event_check_and_clean(NRF_POWER_EVENT_USBDETECTED, - NRF_POWER_INT_USBDETECTED_MASK)) { - usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBDETECTED); - } - - if (power_event_check_and_clean(NRF_POWER_EVENT_USBPWRRDY, - NRF_POWER_INT_USBPWRRDY_MASK)) { - usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBPWRRDY); - } - - if (power_event_check_and_clean(NRF_POWER_EVENT_USBREMOVED, - NRF_POWER_INT_USBREMOVED_MASK)) { - usb_dc_nrfx_power_event_callback(NRF_POWER_EVENT_USBREMOVED); - } -#endif -} - -void nrf_power_clock_isr(void *arg) -{ - ARG_UNUSED(arg); - struct device *dev = DEVICE_GET(clock_nrf); - - if (clock_event_check_and_clean(NRF_CLOCK_EVENT_HFCLKSTARTED, - NRF_CLOCK_INT_HF_STARTED_MASK)) { - struct nrf_clock_control_sub_data *data = - get_sub_data(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK); - - /* Check needed due to anomaly 201: - * HFCLKSTARTED may be generated twice. - * - * Also software should be notified about clock being on only - * if generic request occured. - */ - if ((GET_STATUS(data->flags) == CLOCK_CONTROL_STATUS_STARTING) - && (hfclk_users & HF_USER_GENERIC)) { - clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_HFCLK); - } - } - - if (clock_event_check_and_clean(NRF_CLOCK_EVENT_LFCLKSTARTED, - NRF_CLOCK_INT_LF_STARTED_MASK)) { - if (IS_ENABLED( - CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) { - z_nrf_clock_calibration_lfclk_started(); - } - clkstarted_handle(dev, CLOCK_CONTROL_NRF_TYPE_LFCLK); - } - - usb_power_isr(); - - if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) { - z_nrf_clock_calibration_isr(); - } -} - #ifdef CONFIG_USB_NRFX void nrf5_power_usb_power_int_enable(bool enable) { - uint32_t mask; - - mask = NRF_POWER_INT_USBDETECTED_MASK | - NRF_POWER_INT_USBREMOVED_MASK | - NRF_POWER_INT_USBPWRRDY_MASK; - if (enable) { - nrf_power_int_enable(NRF_POWER, mask); - irq_enable(DT_INST_IRQN(0)); + nrfx_power_usbevt_enable(); } else { - nrf_power_int_disable(NRF_POWER, mask); + nrfx_power_usbevt_disable(); } } #endif @@ -671,8 +629,7 @@ static int cmd_status(const struct shell *shell, size_t argc, char **argv) { nrf_clock_hfclk_t hfclk_src; bool hf_status; - bool lf_status = - nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, NULL); + bool lf_status = nrfx_clock_is_running(NRF_CLOCK_DOMAIN_LFCLK, NULL); struct onoff_manager *hf_mgr = get_onoff_manager(DEVICE_GET(clock_nrf), CLOCK_CONTROL_NRF_TYPE_HFCLK); @@ -683,8 +640,7 @@ static int cmd_status(const struct shell *shell, size_t argc, char **argv) int key = irq_lock(); uint64_t now = k_uptime_get(); - (void)nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, - (void *)&hfclk_src); + (void)nrfx_clock_is_running(NRF_CLOCK_DOMAIN_HFCLK, (void *)&hfclk_src); hf_status = (hfclk_src == NRF_CLOCK_HFCLK_HIGH_ACCURACY); abs_start = hf_start_tstamp; diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index 81c50905099..d3749c47f05 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -186,16 +186,16 @@ typedef void (*vth)(void); /* Vector Table Handler */ * Note: qemu_cortex_m0 uses TIMER0 to implement system timer. */ void rtc_nrf_isr(void); -void nrf_power_clock_isr(void); +void nrfx_clock_irq_handler(void); #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) #if defined(CONFIG_BOARD_QEMU_CORTEX_M0) void timer0_nrf_isr(void); vth __irq_vector_table _irq_vector_table[] = { - nrf_power_clock_isr, 0, 0, 0, 0, 0, 0, 0, timer0_nrf_isr, isr0, isr1, isr2 + nrfx_clock_irq_handler, 0, 0, 0, 0, 0, 0, 0, timer0_nrf_isr, isr0, isr1, isr2 }; #else vth __irq_vector_table _irq_vector_table[] = { - nrf_power_clock_isr, + nrfx_clock_irq_handler, isr0, isr1, isr2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, rtc_nrf_isr @@ -204,14 +204,14 @@ vth __irq_vector_table _irq_vector_table[] = { #elif defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF91X) #ifndef CONFIG_SOC_NRF5340_CPUNET vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrf_power_clock_isr, 0, 0, + 0, 0, 0, 0, 0, nrfx_clock_irq_handler, 0, 0, isr0, isr1, isr2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, rtc_nrf_isr }; #else vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrf_power_clock_isr, 0, 0, + 0, 0, 0, 0, 0, nrfx_clock_irq_handler, 0, 0, isr0, isr1, isr2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, rtc_nrf_isr diff --git a/west.yml b/west.yml index 76fb64170b0..2a41083fbed 100644 --- a/west.yml +++ b/west.yml @@ -56,7 +56,7 @@ manifest: revision: f1fa8241f8786198ba41155413243de36ed878a5 path: modules/hal/infineon - name: hal_nordic - revision: 4be2a1eadc99511e0271b6de6e0be459a4cf0cef + revision: f32e904fb9ea0309f7319cf121dd22ad16233df0 path: modules/hal/nordic - name: hal_openisa revision: 40d049f69c50b58ea20473bee14cf93f518bf262 @@ -126,7 +126,7 @@ manifest: revision: 957d46bc3ce0d5f628f0d525196bb4db207672ee - name: nrf_hw_models path: modules/bsim_hw_models/nrf_hw_models - revision: 9e594dace1af29252903938064b8ecb1b8b77678 + revision: f86079a7333968f0ba71fe1266e241295a4e9943 - name: hal_xtensa revision: e7a57d0c252f9c5f3cab9d5ceadda8753cacee5b path: modules/hal/xtensa