int z_clock_driver_init(struct device *device) { struct device *clock; ARG_UNUSED(device); clock = device_get_binding(CONFIG_CLOCK_CONTROL_NRF_K32SRC_DRV_NAME); if (!clock) { return -1; } clock_control_on(clock, (void *)CLOCK_CONTROL_NRF_K32SRC); /* TODO: replace with counter driver to access RTC */ nrf_rtc_prescaler_set(RTC, 0); nrf_rtc_cc_set(RTC, 0, CYC_PER_TICK); nrf_rtc_event_enable(RTC, RTC_EVTENSET_COMPARE0_Msk); nrf_rtc_int_enable(RTC, RTC_INTENSET_COMPARE0_Msk); /* Clear the event flag and possible pending interrupt */ nrf_rtc_event_clear(RTC, NRF_RTC_EVENT_COMPARE_0); NVIC_ClearPendingIRQ(RTC1_IRQn); IRQ_CONNECT(RTC1_IRQn, 1, rtc1_nrf_isr, 0, 0); irq_enable(RTC1_IRQn); nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR); nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START); if (!IS_ENABLED(TICKLESS_KERNEL)) { set_comparator(counter() + CYC_PER_TICK); } return 0; }
/* * Setup the RTC time to generate the tick interrupts at the required * frequency. */ void vPortSetupTimerInterrupt( void ) { /* Request LF clock */ nrf_drv_clock_lfclk_request(); /* Configure SysTick to interrupt at the requested rate. */ nrf_rtc_prescaler_set(portNRF_RTC_REG, portNRF_RTC_PRESCALER); nrf_rtc_int_enable (portNRF_RTC_REG, RTC_INTENSET_TICK_Msk); nrf_rtc_task_trigger (portNRF_RTC_REG, NRF_RTC_TASK_CLEAR); nrf_rtc_task_trigger (portNRF_RTC_REG, NRF_RTC_TASK_START); NVIC_SetPriority(portNRF_RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY); NVIC_EnableIRQ(portNRF_RTC_IRQn); }
void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance) { ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; }
void nrf5AlarmInit(void) { sTimeOffset = 0; memset(sTimerData, 0, sizeof(sTimerData)); // Setup low frequency clock. nrf_drv_clock_lfclk_request(NULL); while (!nrf_drv_clock_lfclk_is_running()) {} // Setup RTC timer. NVIC_SetPriority(RTC_IRQN, RTC_IRQ_PRIORITY); NVIC_ClearPendingIRQ(RTC_IRQN); NVIC_EnableIRQ(RTC_IRQN); nrf_rtc_prescaler_set(RTC_INSTANCE, 0); nrf_rtc_event_clear(RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); nrf_rtc_event_enable(RTC_INSTANCE, RTC_EVTEN_OVRFLW_Msk); nrf_rtc_int_enable(RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); for (uint32_t i = 0; i < kNumTimers; i++) { nrf_rtc_event_clear(RTC_INSTANCE, sChannelData[i].mCompareEvent); nrf_rtc_event_disable(RTC_INSTANCE, sChannelData[i].mCompareEventMask); nrf_rtc_int_disable(RTC_INSTANCE, sChannelData[i].mCompareInt); } nrf_rtc_task_trigger(RTC_INSTANCE, NRF_RTC_TASK_START); }
void nrfx_rtc_disable(nrfx_rtc_t const * const p_instance) { NRFX_ASSERT(m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_INITIALIZED; NRFX_LOG_INFO("Disabled."); }
void nrfx_rtc_enable(nrfx_rtc_t const * const p_instance) { NRFX_ASSERT(m_cb[p_instance->instance_id].state == NRFX_DRV_STATE_INITIALIZED); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START); m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_POWERED_ON; NRFX_LOG_INFO("Enabled."); }
/** * * @brief Stop announcing sys ticks into the kernel * * This routine disables the RTC1 so that timer interrupts are no * longer delivered. * * @return N/A */ void sys_clock_disable(void) { unsigned int key; key = irq_lock(); irq_disable(NRF5_IRQ_RTC1_IRQn); nrf_rtc_event_disable(SYS_CLOCK_RTC, RTC_EVTENCLR_COMPARE0_Msk); nrf_rtc_int_disable(SYS_CLOCK_RTC, RTC_INTENCLR_COMPARE0_Msk); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_STOP); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_CLEAR); irq_unlock(key); /* TODO: turn off (release) 32 KHz clock source. * Turning off of 32 KHz clock source is not implemented in clock * driver. */ }
int _sys_clock_driver_init(struct device *device) { struct device *clock; ARG_UNUSED(device); clock = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_K32SRC_DRV_NAME); if (!clock) { return -1; } clock_control_on(clock, (void *)CLOCK_CONTROL_NRF5_K32SRC); rtc_past = 0; #ifdef CONFIG_TICKLESS_IDLE expected_sys_ticks = 1; #endif /* CONFIG_TICKLESS_IDLE */ /* TODO: replace with counter driver to access RTC */ SYS_CLOCK_RTC->PRESCALER = 0; nrf_rtc_cc_set(SYS_CLOCK_RTC, RTC_CC_IDX, sys_clock_hw_cycles_per_tick); nrf_rtc_event_enable(SYS_CLOCK_RTC, RTC_EVTENSET_COMPARE0_Msk); nrf_rtc_int_enable(SYS_CLOCK_RTC, RTC_INTENSET_COMPARE0_Msk); /* Clear the event flag and possible pending interrupt */ RTC_CC_EVENT = 0; NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn); IRQ_CONNECT(NRF5_IRQ_RTC1_IRQn, 1, rtc1_nrf5_isr, 0, 0); irq_enable(NRF5_IRQ_RTC1_IRQn); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_CLEAR); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_START); return 0; }
void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance) { uint32_t mask = NRF_RTC_INT_TICK_MASK | NRF_RTC_INT_OVERFLOW_MASK | NRF_RTC_INT_COMPARE0_MASK | NRF_RTC_INT_COMPARE1_MASK | NRF_RTC_INT_COMPARE2_MASK | NRF_RTC_INT_COMPARE3_MASK; ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); nrf_drv_common_irq_disable(p_instance->irq); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); nrf_rtc_event_disable(p_instance->p_reg, mask); nrf_rtc_int_disable(p_instance->p_reg, mask); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; }
void nrfx_rtc_uninit(nrfx_rtc_t const * const p_instance) { uint32_t mask = NRF_RTC_INT_TICK_MASK | NRF_RTC_INT_OVERFLOW_MASK | NRF_RTC_INT_COMPARE0_MASK | NRF_RTC_INT_COMPARE1_MASK | NRF_RTC_INT_COMPARE2_MASK | NRF_RTC_INT_COMPARE3_MASK; NRFX_ASSERT(m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED); NRFX_IRQ_DISABLE(p_instance->irq); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); nrf_rtc_event_disable(p_instance->p_reg, mask); nrf_rtc_int_disable(p_instance->p_reg, mask); m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_UNINITIALIZED; NRFX_LOG_INFO("Uninitialized."); }
void nrf5AlarmDeinit(void) { nrf_rtc_task_trigger(RTC_INSTANCE, NRF_RTC_TASK_STOP); for (uint32_t i = 0; i < kNumTimers; i++) { nrf_rtc_event_clear(RTC_INSTANCE, sChannelData[i].mCompareEvent); nrf_rtc_event_disable(RTC_INSTANCE, sChannelData[i].mCompareEventMask); nrf_rtc_int_disable(RTC_INSTANCE, sChannelData[i].mCompareInt); } nrf_rtc_int_disable(RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); nrf_rtc_event_disable(RTC_INSTANCE, RTC_EVTEN_OVRFLW_Msk); nrf_rtc_event_clear(RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); NVIC_DisableIRQ(RTC_IRQN); NVIC_ClearPendingIRQ(RTC_IRQN); NVIC_SetPriority(RTC_IRQN, 0); nrf_drv_clock_lfclk_release(); }
void common_rtc_init(void) { if (m_common_rtc_enabled) { return; } errata_20(); NVIC_SetVector(RTC1_IRQn, (uint32_t)RTC1_IRQHandler); // RTC is driven by the low frequency (32.768 kHz) clock, a proper request // must be made to have it running. // Currently this clock is started in 'SystemInit' (see "system_nrf51.c" // or "system_nrf52.c", respectively). nrf_rtc_prescaler_set(COMMON_RTC_INSTANCE, 0); nrf_rtc_event_clear(COMMON_RTC_INSTANCE, US_TICKER_EVENT); #if defined(TARGET_MCU_NRF51822) nrf_rtc_event_clear(COMMON_RTC_INSTANCE, OS_TICK_EVENT); #endif #if DEVICE_LOWPOWERTIMER nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT); #endif nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); // Interrupts on all related events are enabled permanently. Particular // events will be enabled or disabled as needed (such approach is more // energy efficient). nrf_rtc_int_enable(COMMON_RTC_INSTANCE, #if DEVICE_LOWPOWERTIMER LP_TICKER_INT_MASK | #endif US_TICKER_INT_MASK | NRF_RTC_INT_OVERFLOW_MASK); // This event is enabled permanently, since overflow indications are needed // continuously. nrf_rtc_event_enable(COMMON_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); // All other relevant events are initially disabled. nrf_rtc_event_disable(COMMON_RTC_INSTANCE, #if defined(TARGET_MCU_NRF51822) OS_TICK_INT_MASK | #endif #if DEVICE_LOWPOWERTIMER LP_TICKER_INT_MASK | #endif US_TICKER_INT_MASK); nrf_drv_common_irq_enable(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE), #ifdef NRF51 APP_IRQ_PRIORITY_LOW #elif defined(NRF52) || defined(NRF52840_XXAA) APP_IRQ_PRIORITY_LOWEST #endif ); nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_START); m_common_rtc_enabled = true; }