/**************************************************************************//** * @brief LESENSE_IRQHandler * Interrupt Service Routine for LESENSE Interrupt Line *****************************************************************************/ void LESENSE_IRQHandler(void) { /* Read interrupts flags */ uint32_t intFlags = LESENSE_IntGet(); /* Clear interrupts */ LESENSE_IntClear(LESENSE_IFC_DEC | LESENSE_IFC_DECERR); /* Enable clock for LCD. */ CMU_ClockEnable(cmuClock_LCD, true); /* Wait until SYNCBUSY_CTRL flag is cleared. */ LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL); /* Enable LCD. */ LCD_Enable(true); /* If there is a decoder error stop trap execution in this loop */ if (intFlags & LESENSE_IF_DECERR) { /* DECODER ERROR */ SegmentLCD_Write(LCSENSE_ERROR_STRING); while (1) ; } /* Write PCNT counter number the LCD */ SegmentLCD_Number(PCNT_CounterGet(PCNT0)); /* Disable RTC first to reset counter */ RTC_Enable(false); /* Set compare value */ RTC_CompareSet(0, RTC_COMP_VALUE); /* Enable RTC */ RTC_Enable(true); }
/***************************************************************************//** * @brief RTC trigger enable * @param msec Enable trigger in msec * @param cb Callback invoked when @p msec elapsed ******************************************************************************/ void RTC_Trigger(uint32_t msec, void (*cb)(void)) { /* Disable RTC - this will also reset the counter. */ RTC_Enable(false); /* Auto init upon first use */ if (!rtcInitialized) { RTC_Setup(); } /* Register callback */ rtcCb = cb; /* Clear interrupt source */ RTC_IntClear(RTC_IF_COMP0); /* Calculate trigger value in ticks based on 32768Hz clock */ RTC_CompareSet(0, (RTC_FREQ * msec) / 1000); /* Enable RTC */ RTC_Enable(true); /* Enable interrupt on COMP0 */ RTC_IntEnable(RTC_IF_COMP0); }
/***************************************************************************//** * @brief RTC trigger enable * @param msec Enable trigger in msec * @param cb Callback invoked when @p msec elapsed ******************************************************************************/ void RTCDRV_Trigger(uint32_t msec, void (*cb)(void)) { /* Disable RTC - this will also reset the counter. */ RTC_Enable(false); /* Auto init if not configured already */ if (!rtcInitialized) { /* Default to LFRCO as clock source and prescale by 32. */ RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32); } /* Register callback */ rtcCb = cb; /* Clear interrupt source */ RTC_IntClear(RTC_IF_COMP0); /* Calculate trigger value in ticks based on 32768Hz clock */ RTC_CompareSet(0, (rtcFreq * msec) / 1000); /* Enable RTC */ RTC_Enable(true); /* Enable interrupt on COMP0 */ RTC_IntEnable(RTC_IF_COMP0); }
/**************************************************************************//** * @brief Button Handler * Shared by GPIO Even and GPIO Odd interrupt handlers *****************************************************************************/ void button_handler() { uint32_t interrupt_source = GPIO_IntGet(); /* Both buttons were pushed - toggle the timer */ if (pb1_is_pushed && pb0_is_pushed) { toggleTimer = true; } if (toggleTimer) { /* Wait for both buttons to be released */ if (!pb1_is_pushed && !pb0_is_pushed) { if (enableTimer) { SegmentLCD_Write("STOP"); time = old_time; SegmentLCD_Number(time); /* Disable RTC */ RTC_Enable(false); } else { SegmentLCD_Write("START"); old_time = time; /* Enable RTC */ RTC_Enable(true); } enableTimer = !enableTimer; toggleTimer = false; return; } } else { /* If only Push Button 0 was pressed - decrease the time */ if (!pb0_is_pushed && interrupt_source & 1 << PB0_PIN) { if (time > 0) time--; SegmentLCD_Number(time); } /* If only Push Button 1 was pressed - increase the time */ else if (!pb1_is_pushed && interrupt_source & 1 << PB1_PIN) { if (time < 9999) time++; SegmentLCD_Number(time); } } }
/**************************************************************************//** * @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 ); }
/** * 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); }
void rtcSetup(){ RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT; /* Enabling clock to LE configuration register */ CMU_ClockEnable(cmuClock_CORELE, true); /* Selecting crystal oscillator to drive LF clock */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* 32 clock division to save energy */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32768); /* Providing clock to RTC */ CMU_ClockEnable(cmuClock_RTC, true); /* Initialize RTC */ rtcInit.enable = false; /* Do not start RTC after initialization is complete. */ rtcInit.debugRun = false; /* Halt RTC when debugging. */ rtcInit.comp0Top = true; /* Wrap around on COMP0 match. */ RTC_Init(&rtcInit); /* Interrupt every minute */ RTC_CompareSet(0, ((RTC_FREQ / CLOCK_DIVISION) * 10 ) - 1 ); /* Enable interrupt */ NVIC_EnableIRQ(RTC_IRQn); RTC_IntEnable(RTC_IEN_COMP0); /* Start Counter */ RTC_Enable(true); }
/***************************************************************************//** * @brief * Deinitialize RTCDRV driver. * * @details * Will disable interrupts and turn off the clock to the underlying hardware * timer. * If integration with SLEEP module is enabled it will remove any * restriction that are set on energy mode usage. * * @return * @ref ECODE_EMDRV_RTCDRV_OK. ******************************************************************************/ Ecode_t RTCDRV_DeInit( void ) { // Disable and clear all interrupt sources. NVIC_DISABLEIRQ(); RTC_INTDISABLE( RTC_ALL_INTS ); RTC_INTCLEAR( RTC_ALL_INTS ); NVIC_CLEARPENDINGIRQ(); // Disable RTC module and its clock. #if defined( RTCDRV_USE_RTC ) RTC_Enable( false ); CMU_ClockEnable( cmuClock_RTC, false ); #elif defined( RTCDRV_USE_RTCC ) RTCC_Enable( false ); CMU_ClockEnable( cmuClock_RTCC, false ); #endif #if defined( EMODE_NEVER_ALLOW_EM3EM4 ) // End EM3 and EM4 blocking. SLEEP_SleepBlockEnd( sleepEM3 ); #endif #if defined( EMODE_DYNAMIC ) // End EM3 and EM4 blocking if a block start has been set. if ( sleepBlocked ) { SLEEP_SleepBlockEnd( sleepEM3 ); } #endif // Mark the driver as uninitialized. rtcdrvIsInitialized = false; return ECODE_EMDRV_RTCDRV_OK; }
/**************************************************************************//** * @brief Enables LFACLK and selects LFXO as clock source for RTC * Sets up the RTC to generate an interrupt every minute. *****************************************************************************/ void rtcSetup(void) { RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT; /* Enable LE domain registers */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable LFXO as LFACLK in CMU. This will also start LFXO */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Set a clock divisor of 32 to reduce power conumption. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32); /* Enable RTC clock */ CMU_ClockEnable(cmuClock_RTC, true); /* Initialize RTC */ rtcInit.enable = false; /* Do not start RTC after initialization is complete. */ rtcInit.debugRun = false; /* Halt RTC when debugging. */ rtcInit.comp0Top = true; /* Wrap around on COMP0 match. */ RTC_Init(&rtcInit); /* Interrupt every minute */ RTC_CompareSet(0, ((RTC_FREQ / 32) * 60 ) - 1 ); /* Enable interrupt */ NVIC_EnableIRQ(RTC_IRQn); RTC_IntEnable(RTC_IEN_COMP0); /* Start Counter */ RTC_Enable(true); }
/**************************************************************************//** * @brief Enables LFACLK and selects LFXO as clock source for RTC * Sets up the RTC to generate an interrupt every second. *****************************************************************************/ static void rtcSetup(unsigned int frequency) { RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT; palClockSetup(cmuClock_LFA); /* Set the prescaler. */ CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_2 ); /* Enable RTC clock */ CMU_ClockEnable(cmuClock_RTC, true); /* Initialize RTC */ rtcInit.enable = false; /* Do not start RTC after initialization is complete. */ rtcInit.debugRun = false; /* Halt RTC when debugging. */ rtcInit.comp0Top = true; /* Wrap around on COMP0 match. */ RTC_Init(&rtcInit); /* Interrupt at given frequency. */ RTC_CompareSet(0, ((CMU_ClockFreqGet(cmuClock_RTC) / frequency) - 1) & _RTC_COMP0_MASK ); #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY /* Enable interrupt */ NVIC_EnableIRQ(RTC_IRQn); RTC_IntEnable(RTC_IEN_COMP0); #endif RTC_CounterReset(); /* Start Counter */ RTC_Enable(true); }
/**************************************************************************//** * @brief RTC_IRQHandler * Interrupt Service Routine for RTC which is used as system tick counter in EM2 *****************************************************************************/ void RTC_IRQHandler(void) { /* If using preemption, also force a context switch. */ #if (configUSE_PREEMPTION == 1) port_NVIC_INT_CTRL_REG = port_NVIC_PENDSVSET_BIT; #endif /* (configUSE_PREEMPTION == 1) */ /* Set RTC interrupt to one system tick period*/ RTC_Enable(false); RTC_CompareSet(0, ulTimerReloadValueForOneTick); /* Restart the counter */ #if (configUSE_TICKLESS_IDLE == 1) /* Set flag that interrupt was made*/ intTickFlag = true; #endif /* (configUSE_TICKLESS_IDLE == 1) */ /* Critical section which protect incrementing the tick*/ ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); { xTaskIncrementTick(); } portCLEAR_INTERRUPT_MASK_FROM_ISR(0); /* Clear interrupt */ RTC_IntClear(_RTC_IFC_MASK); RTC_CounterReset(); }
void rtt_init(void) { /* prescaler of 32768 = 1 s of resolution and overflow each 194 days */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32768); /* enable clocks */ CMU_ClockEnable(cmuClock_CORELE, true); CMU_ClockEnable(cmuClock_RTC, true); /* reset and initialize peripheral */ EFM32_CREATE_INIT(init, RTC_Init_TypeDef, RTC_INIT_DEFAULT, .conf.enable = false, .conf.comp0Top = false ); RTC_Reset(); RTC_Init(&init.conf); /* enable interrupts */ RTC_IntEnable(RTC_IEN_OF); NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); /* enable peripheral */ RTC_Enable(true); }
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); } }
/************************************************************************* * Function Name: RTC_Init * Parameters: void * * Return: 0: sucess * 1: fail * * Description: Initialize RTC, configure prescaler, CIIR and AMR register * *************************************************************************/ int rtc_init(unsigned char BackComp) { LPC_Rtc_DateTime_t datetime; LPC_Rtc_Date_t date; /* check if RTC is enabled already -> battery buffered */ if (RTC_CCR & CCR_CLKEN) { /* make sure it is set to external watch quartz, no matter if enabled or not */ RTC_CCR |= CCR_CLKSRC; /* get current date from RTC */ RTC_GetDate(&date); } else { /* disable and reset RTC */ RTC_CCR = CCR_CTCRST; RTC_CCR = 0x00; RTC_CCR |= CCR_CLKSRC; /* 32kHz watch quarz */ /* init all necessary RTC registers */ RTC_ILR = ILR_COUNT_INC_FLAG | ILR_ALARM_FLAG | ILR_SUB_SEC_FLAG; /* clear all interrupt flags of RTC */ RTC_CIIR = CIIR_SEC; /* enable second interrupt */ RTC_AMR = AMR_SEC; /* mask second interrupts */ RTC_CISS = CISS_DISABLE; /* no sub second interrupts */ /* set default time */ memcpy((unsigned char *)&datetime, (unsigned char *)&RTC_InitDateTime, sizeof(LPC_Rtc_DateTime_t)); /* initialize Date and Time */ RTC_SetDateTime(&datetime); } /* check if the date is valid, set default if not */ if(!IsValidDay(date.year, date.month, date.day)) { memcpy((char *)&datetime, (char *)&RTC_InitDateTime, sizeof(LPC_Rtc_DateTime_t)); /* initialize Date and Time */ if (RTC_SetDateTime(&datetime)) return 1; } /* convert current time to unix time */ RTC_datetime_to_unix(&unix_time, &datetime); /* set interrupt vector entry for RTC 1s interrupt */ set_isr_handler( RTC_IRQ,(void *)RTC_ISR,RTC_IRQ_PRIO); #ifndef LPC1768 /* Enable the interrupts */ VICIntEnable |= (1<<13); #endif RTC_Enable(); return 0; }
/**************************************************************************//** * @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(); }
/**************************************************************************//** * @brief Initialize Real Time Counter *****************************************************************************/ void initRTC() { /* Starting LFXO and waiting until it is stable */ CMU_OscillatorEnable(cmuOsc_LFXO, true, true); /* Routing the LFXO clock to the RTC */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); CMU_ClockEnable(cmuClock_RTC, true); /* Enabling clock to the interface of the low energy modules */ CMU_ClockEnable(cmuClock_CORELE, true); const RTC_Init_TypeDef rtcInit = { .enable = true, .debugRun = false, .comp0Top = true, }; RTC_Init(&rtcInit); /* Set comapre value for compare register 0 */ RTC_CompareSet(0, RTC_COUNT_BETWEEN_WAKEUP); /* Enable interrupt for compare register 0 */ RTC_IntEnable(RTC_IFC_COMP0); /* Enabling Interrupt from RTC */ NVIC_EnableIRQ(RTC_IRQn); RTC_Enable(false); } /**************************************************************************//** * @brief Initialize General Purpuse Input/Output *****************************************************************************/ void initGPIO() { /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure pin PB9/PD8 (Push Button 1) and PB10/PB11 (Push Button 2) as an input, * so that we can read their values. */ GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInput, 1); GPIO_PinModeSet(PB1_PORT, PB1_PIN, gpioModeInput, 1); /* Enable GPIO_ODD and GPIO_EVEN interrupts in NVIC */ NVIC_EnableIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_EVEN_IRQn); /* Configure interrupts on falling edge for pins B9/D8 (Push Button 1), * B10/B11 (Push Button 2) and D3 */ GPIO_IntConfig(PB0_PORT, PB0_PIN, true, true, true); GPIO_IntConfig(PB1_PORT, PB1_PIN, true, true, true); }
/**************************************************************************//** * @brief A separate function for taking all the samples is preferred since * the whole idea is to stay in EM2 between samples. If other code is added, * it might be more energy efficient to configure the ADC to use DMA while * the cpu can other work. *****************************************************************************/ void startAdcSampling(void) { sampleCount = 0; adcFinished = false; /* Enable RTC, it can be enabled all the time as well if needed. */ RTC_Enable(true); /* Enable interrupt on COMP0 */ RTC_IntEnable(RTC_IF_COMP0); }
/**************************************************************************//** * @brief Enables LFACLK and selects LFXO as clock source for RTC * Sets up the RTC to generate an interrupt every second. *****************************************************************************/ static void rtcSetup(unsigned int frequency) { RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT; /* Enable LE domain registers */ if ( !( CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE) ) { CMU_ClockEnable(cmuClock_CORELE, true); } #ifdef PAL_RTC_CLOCK_LFXO /* LFA with LFXO setup is relatively time consuming. Therefore, check if it already enabled before calling. */ if ( !(CMU->STATUS & CMU_STATUS_LFXOENS) ) { CMU_OscillatorEnable(cmuOsc_LFXO, true, true); } if ( cmuSelect_LFXO != CMU_ClockSelectGet(cmuClock_LFA) ) { CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); } #elif defined PAL_RTC_CLOCK_LFRCO /* Enable LFACLK in CMU (will also enable LFRCO oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO); #elif defined PAL_RTC_CLOCK_ULFRCO /* Enable LFACLK in CMU (will also enable ULFRCO oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_ULFRCO); #else #error No clock source for RTC defined. #endif /* Set the prescaler. */ CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_1 ); /* Enable RTC clock */ CMU_ClockEnable(cmuClock_RTC, true); /* Initialize RTC */ rtcInit.enable = false; /* Do not start RTC after initialization is complete. */ rtcInit.debugRun = false; /* Halt RTC when debugging. */ rtcInit.comp0Top = true; /* Wrap around on COMP0 match. */ RTC_Init(&rtcInit); /* Interrupt at given frequency. */ RTC_CompareSet(0, (CMU_ClockFreqGet(cmuClock_RTC) / frequency) - 1 ); /* Enable interrupt */ NVIC_EnableIRQ(RTC_IRQn); RTC_IntEnable(RTC_IEN_COMP0); /* Start Counter */ RTC_Enable(true); }
/**************************************************************************//** * @brief PCNT0_IRQHandler * Interrupt Service Routine for PCNT0 Interrupt Line *****************************************************************************/ void PCNT0_IRQHandler(void) { PCNT_IntGet(PCNT0); PCNT_IntClear(PCNT0, PCNT_IEN_DIRCNG); /* Enable clock for LCD. */ CMU_ClockEnable(cmuClock_LCD, true); /* Wait until SYNCBUSY_CTRL flag is cleared. */ LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL); /* Enable LCD. */ LCD_Enable(true); /* Write PCNT counter number the LCD */ SegmentLCD_Write(PCNT_DIRCHANGE_STRING); /* Disable RTC first to reset counter */ RTC_Enable(false); /* Set compare value */ RTC_CompareSet(0, RTC_COMP_VALUE); /* Enable RTC */ RTC_Enable(true); }
/******************************************************************//** * @brief * Configure RTC device * * @details * * @note * * @param[in] dev * Pointer to device descriptor * * @param[in] cmd * RTC control command * * @param[in] args * Arguments * * @return * Error code *********************************************************************/ static rt_err_t rt_rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args) { RT_ASSERT(dev != RT_NULL); switch (cmd) { case RT_DEVICE_CTRL_RTC_GET_TIME: *(rt_uint32_t *)args = rtc_time + RTC_CounterGet(); break; case RT_DEVICE_CTRL_RTC_SET_TIME: { rtc_time = *(rt_uint32_t *)args; /* Reset counter */ RTC_Enable(false); RTC_Enable(true); } break; } return RT_EOK; }
/**************************************************************************//** * @brief RTC_IRQHandler * Interrupt Service Routine for RTC Interrupt Line *****************************************************************************/ void RTC_IRQHandler(void) { /* Clear interrupt flag */ RTC_IntClear(RTC_IFS_COMP0); /* Disable RTC */ RTC_Enable(false); /* Turn off all segments */ SegmentLCD_AllOff(); /* Disable LCD to avoid excessive current consumption */ LCD_Enable(false); /* Wait until SYNCBUSY_CTRL flag is cleared. */ LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL); /* Disable clock for LCD. */ CMU_ClockEnable(cmuClock_LCD, false); }
/****************************************************************************** * @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, 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 Real Time Counter Interrupt Handler *****************************************************************************/ void RTC_IRQHandler(void) { /* Clear interrupt source */ RTC_IntClear(RTC_IFC_COMP0); time--; SegmentLCD_Number(time); if (time == 0) { SegmentLCD_Write("DONE"); time = old_time; /* Disable RTC */ RTC_Enable(false); enableTimer = false; } SegmentLCD_Number(time); }
void initClocks() { /* Starting LFXO and waiting until it is stable */ CMU_OscillatorEnable(cmuOsc_LFXO, true, true); // starting HFXO, wait till stable CMU_OscillatorEnable(cmuOsc_HFXO, true, true); // route HFXO to CPU CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); /* Routing the LFXO clock to the RTC */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO); // disabling the RCs CMU_ClockEnable(cmuSelect_HFRCO, false); CMU_ClockEnable(cmuSelect_LFRCO, false); /* Enabling clock to the interface of the low energy modules */ CMU_ClockEnable(cmuClock_CORE, true); CMU_ClockEnable(cmuClock_CORELE, true); // enable clock to hf perfs CMU_ClockEnable(cmuClock_HFPER, true); // enable clock to GPIO CMU_ClockEnable(cmuClock_GPIO, true); // enable clock to RTC CMU_ClockEnable(cmuClock_RTC, true); RTC_Enable(true); // enable radio usart CMU_ClockEnable(cmuClock_USART0, true); // enable timers CMU_ClockEnable(cmuClock_TIMER0, true); CMU_ClockEnable(cmuClock_TIMER1, true); }
/***************************************************************************//** * @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 Configure RTC * *****************************************************************************/ void rtcSetup(void) { RTC_Init_TypeDef rtcInit; /* Select LFXO as clock source for the RTC */ CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO); CMU_ClockEnable(cmuClock_RTC, true); /* Set RTC pre-scaler */ CMU_ClockDivSet(cmuClock_RTC,cmuClkDiv_1); /* Enable clock to low energy modules */ CMU_ClockEnable(cmuClock_CORELE, true); /* RTC configuration struct */ rtcInit.debugRun = false; rtcInit.comp0Top = false; rtcInit.enable = false; /* Initialize RTC */ RTC_Init(&rtcInit); /* Set RTC compare value for first display update */ RTC_CompareSet(0, RTC_COUNTS_BETWEEN_DISPLAY ); /* Set RTC compare value for first temperature compensation */ RTC_CompareSet(1, RTC_COUNTS_BETWEEN_TC ); /* Enable COMP0 interrupt to trigger display update, */ /* COMP1 interrupt to trigger temperature compensation, and */ /* OF interrupt to keep track of counter overflows */ RTC_IntEnable(RTC_IEN_COMP0 | RTC_IEN_COMP1 | RTC_IEN_OF ); /* Enable RTC interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); /* Enable RTC */ RTC_Enable(true); }
/**************************************************************************//** * @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 rtcSetDelay(int menuItem){ int delay; switch (menuItem) { case 0: delay = 10; break; case 1: delay = 3600 * 12; break; case 2: delay = 3600 * 24; break; case 3: delay = 3600 * 48; break; } /* Interrupt every minute */ RTC_CompareSet(0, ((RTC_FREQ / CLOCK_DIVISION) * delay ) - 1 ); /* Start Counter */ RTC_Enable(true); }