void lp_ticker_init() { core_util_critical_section_enter(); if (!rtc_inited) { CMU_ClockEnable(cmuClock_RTC, true); /* Initialize RTC */ RTC_Init_TypeDef init = RTC_INIT_DEFAULT; init.enable = 1; /* Don't use compare register 0 as top value */ init.comp0Top = 0; /* Initialize */ RTC_Init(&init); RTC_CounterSet(20); /* Enable Interrupt from RTC */ RTC_IntDisable(RTC_IF_COMP0); RTC_IntClear(RTC_IF_COMP0); NVIC_SetVector(RTC_IRQn, (uint32_t)RTC_IRQHandler); NVIC_EnableIRQ(RTC_IRQn); rtc_inited = true; } else { /* Cancel current interrupt by virtue of calling init again */ RTC_IntDisable(RTC_IF_COMP0); RTC_IntClear(RTC_IF_COMP0); } core_util_critical_section_exit(); }
void rtt_clear_overflow_cb(void) { rtt_state.overflow_cb = NULL; rtt_state.overflow_arg = NULL; RTC_IntDisable(RTC_IEN_OF); }
/***************************************************************************//** * @brief * Enables LFACLK and selects LFXO as clock source for RTC * * @param osc * Oscillator ******************************************************************************/ void RTC_Setup(CMU_Select_TypeDef osc) { RTC_Init_TypeDef init; rtcInitialized = 1; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, osc); /* Use a 32 division prescaler to reduce power consumption. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32); rtcFreq = CMU_ClockFreqGet(cmuClock_RTC); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = false; /* Count to max before wrapping */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); }
/***************************************************************************//** * @brief Enables LFACLK and selects LFRCO as clock source for RTC ******************************************************************************/ static void RTC_Setup(void) { RTC_Init_TypeDef init; rtcInitialized = 1; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable LFRCO as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = false; /* Count to max before wrapping */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); }
/** * Initialize RTC Based on Crystal Oscillator */ void rtc_crystal_init(void) { RTC_Init_TypeDef init; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Use the prescaler to reduce power consumption. */ CMU_ClockDivSet(cmuClock_RTC, RTC_PRESCALE); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; /* Start disabled to reset counter */ init.debugRun = false; init.comp0Top = false; /* Count to max before wrapping */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); /* Start RTC counter */ RTC_Enable(true); }
/*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) { RTC_Init_TypeDef init = RTC_INIT_DEFAULT; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Don't use prescaler to have highest precision */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_1); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; /* Start disabled to reset counter */ init.debugRun = false; init.comp0Top = false; /* Don't Reset Count on comp0 */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); /* Start RTC counter */ RTC_Enable(true); }
/***************************************************************************//** * @brief Enables LFACLK and selects osc as clock source for RTC ******************************************************************************/ void RTC_Setup(CMU_Select_TypeDef osc) { RTC_Init_TypeDef init; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, osc); /* No division prescaler to increase accuracy. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_1); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = true; /* Count only to top before wrapping */ RTC_Init(&init); RTC_CompareSet(0, ((LFRCOFREQ * WAKEUP_US) / 1000000)); /* Disable interrupt generation from RTC0, is enabled before each sample-run. */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts in NVIC */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); }
void RTC_IRQHandler(void) { // Check to see which counter has triggered if (RTC->IF & RTC_IF_COMP0) { // Within 10 seconds allows us to speed up the clock for testing if ((RTC->CNT - time_keeper.timer_start_seconds) < 10) { run_sprinkler(); RTC_CompareSet(0, time_keeper.timer_stop_seconds); } else { RTC_IntDisable(0); stop_sprinkler(); } RTC_IntClear(RTC_IFC_COMP0); } else // A minute update has occurred { if (RTC->CNT >= END_OF_DAY) { RTC->CNT = 0; } RTC_CompareSet(1, RTC->CNT + 60); RTC_IntClear(RTC_IFC_COMP1); display_hours = get_time(HOURS); display_minutes = get_time(MINUTES); display_time(display_hours, display_minutes); } }
void os_idle_demon(void) { RTC_Init_TypeDef init; unsigned int sleep; /* The idle demon is a system thread, running when no other thread is */ /* ready to run. */ /* Enable system clock for RTC */ /* LFXO setup */ /* Use 70% boost */ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Use a 32 division prescaler to reduce power consumption. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = false; /* Count to max value before wrapping */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); for (;;) { /* os_suspend stops scheduler and returns time to next event in OS_TICK units */ sleep = os_suspend(); if (sleep) { RTC_CompareSet(0, sleep - 1); RTC_IntClear(RTC_IFC_COMP0); RTC_IntEnable(RTC_IF_COMP0); RTC_CounterReset(); /* Enter EM2 low power mode - could be replaced with EM1 if required */ EMU_EnterEM2(true); /* get information how long we were in sleep */ sleep = RTC_CounterGet(); RTC_Enable(false); }; /* resume scheduler providing information how long MCU was sleeping */ os_resume(sleep); } }
void rtt_clear_alarm(void) { rtt_state.alarm_cb = NULL; rtt_state.alarm_arg = NULL; /* disable the interrupt */ RTC_IntDisable(RTC_IEN_COMP0); }
void lp_ticker_set_interrupt(timestamp_t timestamp) { RTC_IntDisable(RTC_IF_COMP0); RTC_IntClear(RTC_IF_COMP0); RTC_FreezeEnable(true); RTC_CompareSet(0, (uint32_t) (timestamp & RTC_MAX_VALUE)); RTC_FreezeEnable(false); RTC_IntEnable(RTC_IF_COMP0); }
/**************************************************************************//** * @brief vPortSetupTimerInterrupt * Override the default definition of vPortSetupTimerInterrupt() that is weakly * defined in the FreeRTOS Cortex-M3, which set source of system tick interrupt *****************************************************************************/ void vPortSetupTimerInterrupt(void) { /* Set our data about timer used as system ticks*/ ulTimerReloadValueForOneTick = SYSTICK_LOAD_VALUE ; #if (configUSE_TICKLESS_IDLE == 1) xMaximumPossibleSuppressedTicks = TIMER_CAPACITY / (SYSTICK_LOAD_VALUE); ulStoppedTimerCompensation = TIMER_COMPENSATION / (configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ); #endif /* (configUSE_TICKLESS_IDLE == 1) */ /* Configure RTC as system tick source */ /* Structure of RTC init */ RTC_Init_TypeDef init; #if (configCRYSTAL_IN_EM2 == 1) /* LFXO setup */ /* For cut D, use 70% boost */ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT; #if defined( EMU_AUXCTRL_REDLFXOBOOST ) EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST; #endif #else /* RC oscillator */ CMU_OscillatorEnable(cmuOsc_LFRCO, true, true); #endif /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); #if (configCRYSTAL_IN_EM2 == 1) /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); #else /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO); #endif /* Set 2 times divider to reduce energy*/ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_2); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = false; /* Count to max value before wrapping */ /* Initialization of RTC */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(RTC_IFC_COMP0); /* Tick interrupt MUST execute at the lowest interrupt priority. */ NVIC_SetPriority(RTC_IRQn, 255); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); RTC_CompareSet(0, SYSTICK_LOAD_VALUE); RTC_IntClear(RTC_IFC_COMP0); RTC_IntEnable(RTC_IF_COMP0); RTC_Enable(true); //RTC_CounterReset(); }
error_t hw_timer_cancel(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP1); RTC_IntClear(RTC_IEN_COMP1); end_atomic(); }
/**************************************************************************//** * @brief Delay function, does not depend on interrupts. *****************************************************************************/ static void Delay( uint32_t msec ) { /* RTC frequency is LFXO divided by 32 (prescaler) */ #define RTC_FREQ (32768 / 32) RTC_IntDisable( RTC_IF_COMP0 ); RTC_IntClear( RTC_IF_COMP0 ); RTC_CompareSet( 0, (RTC_FREQ * msec ) / 1000 ); /* Calculate trigger value */ RTC_Enable( true ); while ( !( RTC_IntGet() & RTC_IF_COMP0 ) ); /* Wait for trigger */ RTC_Enable( false ); }
error_t hw_timer_schedule(hwtimer_id_t timer_id, hwtimer_tick_t tick ) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP1); RTC_CompareSet( 1, tick ); RTC_IntClear(RTC_IEN_COMP1); RTC_IntEnable(RTC_IEN_COMP1); end_atomic(); }
void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg) { rtt_state.alarm_cb = cb; rtt_state.alarm_arg = arg; /* disable interrupt so it doesn't accidentally trigger */ RTC_IntDisable(RTC_IEN_COMP0); /* set compare register */ RTC_CompareSet(0, alarm & RTT_MAX_VALUE); /* enable the interrupt */ RTC_IntClear(RTC_IFC_COMP0); RTC_IntEnable(RTC_IEN_COMP0); }
error_t hw_timer_counter_reset(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP0 | RTC_IEN_COMP1); RTC_IntClear(RTC_IEN_COMP0 | RTC_IEN_COMP1); RTC_CounterReset(); RTC_IntEnable(RTC_IEN_COMP0); end_atomic(); }
/***************************************************************************//** * @brief RTC Interrupt Handler, invoke callback if defined. * The interrupt table is in assembly startup file startup_efm32.s ******************************************************************************/ void RTC_IRQHandler(void) { /* Disable RTC */ RTC_Enable(false); /* Clear interrupt source */ RTC_IntClear(RTC_IF_COMP0); /* Disable interrupt */ RTC_IntDisable(RTC_IF_COMP0); /* Trigger callback if defined */ if (rtcCb) { rtcCb(); } }
/****************************************************************************** * @brief * Stops RTC. Turns off clocks and interrupts *****************************************************************************/ void stopRTCTick(void) { RTC_Enable(false); RTC->CNT = 0; /* Turn off clock for RTC */ CMU_ClockEnable(cmuClock_RTC, false); /* Disable clock to LF peripherals */ CMU_ClockEnable(cmuClock_CORELE, false); /* Disable RTC interrupts */ NVIC_DisableIRQ(RTC_IRQn); RTC_IntDisable(RTC_IF_COMP0); }
/***************************************************************************//** * @brief RTC Interrupt Handler. ******************************************************************************/ void RTC_IRQHandler(void) { /* Start ADC conversion as soon as we wake up. */ ADC_Start(ADC0, adcStartSingle); /* Clear the interrupt flag */ RTC_IntClear(RTC_IF_COMP0); /* Wait while conversion is active */ while (ADC0->STATUS & ADC_STATUS_SINGLEACT); /* Get ADC result */ sampleBuffer[sampleCount++] = ADC_DataSingleGet(ADC0); if(sampleCount >= N_SAMPLES){ adcFinished = 1; RTC_Enable(false); RTC_IntDisable(_RTC_IF_MASK); } }
/**************************************************************************//** * @brief Enables LFACLK and selects LFXO as clock source for RTC. * Sets up the RTC to count at 1024 Hz. * The counter should not be cleared on a compare match and keep running. * Interrupts should be cleared and enabled. * The counter should run. *****************************************************************************/ error_t hw_timer_init(hwtimer_id_t timer_id, uint8_t frequency, timer_callback_t compare_callback, timer_callback_t overflow_callback) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(timer_inited) return EALREADY; if(frequency != HWTIMER_FREQ_1MS && frequency != HWTIMER_FREQ_32K) return EINVAL; start_atomic(); compare_f = compare_callback; overflow_f = overflow_callback; timer_inited = true; /* Configuring clocks in the Clock Management Unit (CMU) */ startLfxoForRtc(frequency); RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT; rtcInit.enable = false; /* Don't enable RTC after init has run */ rtcInit.comp0Top = true; /* Clear counter on compare 0 match: cmp 0 is used to limit the value of the rtc to 0xffff */ rtcInit.debugRun = false; /* Counter shall not keep running during debug halt. */ /* Initialize the RTC */ RTC_Init(&rtcInit); //disable all rtc interrupts while we're still configuring RTC_IntDisable(RTC_IEN_OF | RTC_IEN_COMP0 | RTC_IEN_COMP1); RTC_IntClear(RTC_IFC_OF | RTC_IFC_COMP0 | RTC_IFC_COMP1); //Set maximum value for the RTC RTC_CompareSet( 0, 0x0000FFFF ); RTC_CounterReset(); RTC_IntEnable(RTC_IEN_COMP0); NVIC_EnableIRQ(RTC_IRQn); RTC_Enable(true); end_atomic(); return SUCCESS; }
void RTC_IRQHandler(void) { ENERGEST_ON(ENERGEST_TYPE_IRQ); // Find reason of IRQ if(RTC_IntGet() & RTC_IF_COMP0) { watchdog_start(); rtimer_run_next(); watchdog_stop(); // disable interrupt RTC_IntDisable(RTC_IF_COMP0); } else { PRINTF("%s: unknown reason for RTC interrupt\r\n",__func__); } // Clear interrupts RTC_IntClear(_RTC_IF_MASK); ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
inline void lp_ticker_disable_interrupt() { RTC_IntDisable(RTC_IF_COMP0); lp_ticker_free(); }
void lp_ticker_disable_interrupt() { RTC_IntDisable(RTC_IF_COMP0); }
// Use buttons to set time, start, stop // Stores those values to memory void program_timer() { static bool initial_programming = true; // Disable RTC interrupts while in here... RTC_IntDisable(0); RTC_IntDisable(1); delay(BUTTON_DELAY); for (int i=0; i < 3; i++) { if (i == 0) { SegmentLCD_Write("Clock"); } else if (i == 1) { SegmentLCD_Write("Start"); if (initial_programming) { start_hours = display_hours; start_minutes = display_minutes; } display_hours = start_hours; display_minutes = start_minutes; } else if (i == 2) { SegmentLCD_Write("Stop"); if (initial_programming) { stop_hours = start_hours; stop_minutes = start_minutes; } display_hours = stop_hours; display_minutes = stop_minutes; } display_time(display_hours, display_minutes); blink(HOURS); delay(BUTTON_DELAY); // Set the hours while (!set_button.short_press) { if (adjust_button.short_press) { display_hours++; if (display_hours > 23) { display_hours = 1; } display_time(display_hours, display_minutes); // Delay so that we don't get double presses delay(BUTTON_DELAY); } } display_time(display_hours, display_minutes); blink(MINUTES); delay(BUTTON_DELAY); // Set the minutes while (!set_button.short_press) { if (adjust_button.short_press) { display_minutes++; if (display_minutes > 59) { display_minutes = 0; } display_time(display_hours, display_minutes); // Delay so that we don't get double presses delay(FASTER_BUTTON_DELAY); } } // Commit the clock hours and minutes to memory for the given index set_clock_time(i, display_hours, display_minutes); } display_hours = get_time(HOURS); display_minutes = get_time(MINUTES); blink(NONE); display_time(display_hours, display_minutes); // Delay so that we don't get double presses delay(BUTTON_DELAY); initial_programming = false; // Trigger interrupt every 60 seconds to update the time RTC_CompareSet(1, RTC->CNT + 60); // Now that programming is done, clear and enable interrupts RTC_IntClear(RTC_IFC_COMP0); RTC_IntClear(RTC_IFC_COMP1); RTC_IntEnable(RTC_IFC_COMP0); RTC_IntEnable(RTC_IFC_COMP1); }
const hwtimer_info_t* hw_timer_get_info(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return NULL; static const hwtimer_info_t timer_info = { .min_delay_ticks = 0, }; return &timer_info; } hwtimer_tick_t hw_timer_getvalue(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM || (!timer_inited)) return 0; else { uint32_t value =(uint16_t)(RTC->CNT & 0xFFFF); return value; } } error_t hw_timer_schedule(hwtimer_id_t timer_id, hwtimer_tick_t tick ) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP1); RTC_CompareSet( 1, tick ); RTC_IntClear(RTC_IEN_COMP1); RTC_IntEnable(RTC_IEN_COMP1); end_atomic(); } error_t hw_timer_cancel(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP1); RTC_IntClear(RTC_IEN_COMP1); end_atomic(); } error_t hw_timer_counter_reset(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return ESIZE; if(!timer_inited) return EOFF; start_atomic(); RTC_IntDisable(RTC_IEN_COMP0 | RTC_IEN_COMP1); RTC_IntClear(RTC_IEN_COMP0 | RTC_IEN_COMP1); RTC_CounterReset(); RTC_IntEnable(RTC_IEN_COMP0); end_atomic(); } bool hw_timer_is_overflow_pending(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return false; start_atomic(); //COMP0 is used to limit thc RTC to 16 bits -> use this one to check bool is_pending = !!((RTC_IntGet() & RTC->IEN) & RTC_IFS_COMP0); end_atomic(); return is_pending; } bool hw_timer_is_interrupt_pending(hwtimer_id_t timer_id) { if(timer_id >= HWTIMER_NUM) return false; start_atomic(); bool is_pending = !!((RTC_IntGet() & RTC->IEN) & RTC_IFS_COMP1); end_atomic(); return is_pending; } INT_HANDLER(RTC_IRQHandler) { //retrieve flags. We 'OR' this with the enabled interrupts //since the COMP1 flag may be set if it wasn't used before (compare register == 0 -> ifs flag set regardless of whether interrupt is enabled) //by AND ing with the IEN we make sure we only consider the flags of the ENABLED interrupts uint32_t flags = (RTC_IntGet() & RTC->IEN); RTC_IntClear(RTC_IFC_OF | RTC_IFC_COMP0 | RTC_IFC_COMP1); //evaluate flags to see which one(s) fired: if((flags & RTC_IFS_COMP0) && (overflow_f != 0x0)) overflow_f(); if((flags & RTC_IFS_COMP1)) { RTC_IntDisable(RTC_IEN_COMP1); if(compare_f != 0x0) compare_f(); } }