void rtc_init(void) { /* enable clocks */ CMU_ClockEnable(cmuClock_CORELE, true); CMU_ClockEnable(cmuClock_RTCC, true); /* reset and initialize peripheral */ EFM32_CREATE_INIT(init, RTCC_Init_TypeDef, RTCC_INIT_DEFAULT, .conf.enable = false, .conf.presc = rtccCntPresc_32768, .conf.cntMode = rtccCntModeCalendar ); RTCC_Reset(); RTCC_Init(&init.conf); /* initialize alarm channel */ RTCC_CCChConf_TypeDef init_channel = RTCC_CH_INIT_COMPARE_DEFAULT; RTCC_ChannelInit(0, &init_channel); /* enable interrupt */ NVIC_ClearPendingIRQ(RTCC_IRQn); NVIC_EnableIRQ(RTCC_IRQn); /* enable peripheral */ RTCC_Enable(true); }
/**************************************************************************//** * @brief Enables LFECLK and selects clock source for RTCC * Sets up the RTCC to generate an interrupt every second. *****************************************************************************/ static void rtccSetup(unsigned int frequency) { RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT; rtccInit.presc = rtccCntPresc_1; palClockSetup(cmuClock_LFE); /* Enable RTCC clock */ CMU_ClockEnable(cmuClock_RTCC, true); /* Initialize RTC */ rtccInit.enable = false; /* Do not start RTC after initialization is complete. */ rtccInit.debugRun = false; /* Halt RTC when debugging. */ rtccInit.cntWrapOnCCV1 = true; /* Wrap around on CCV1 match. */ RTCC_Init(&rtccInit); /* Interrupt at given frequency. */ RTCC_CCChConf_TypeDef ccchConf = RTCC_CH_INIT_COMPARE_DEFAULT; ccchConf.compMatchOutAction = rtccCompMatchOutActionToggle; RTCC_ChannelInit(1, &ccchConf); RTCC_ChannelCCVSet(1, (CMU_ClockFreqGet(cmuClock_RTCC) / frequency) - 1); #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY /* Enable interrupt */ NVIC_EnableIRQ(RTCC_IRQn); RTCC_IntEnable(RTCC_IEN_CC1); #endif RTCC->CNT = _RTCC_CNT_RESETVALUE; /* Start Counter */ RTCC_Enable(true); }
//================================================================================ // RTCC_enter_DefaultMode_from_RESET //================================================================================ extern void RTCC_enter_DefaultMode_from_RESET(void) { // $[Compare/Capture Channel 0 init] // [Compare/Capture Channel 0 init]$ // $[Compare/Capture Channel 1 init] // [Compare/Capture Channel 1 init]$ // $[Compare/Capture Channel 2 init] // [Compare/Capture Channel 2 init]$ // $[RTCC init] RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT; rtccInit.enable = true; rtccInit.debugRun = false; rtccInit.precntWrapOnCCV0 = false; rtccInit.cntWrapOnCCV1 = false; rtccInit.prescMode = rtccCntTickPresc; rtccInit.presc = rtccCntPresc_32; rtccInit.enaOSCFailDetect = false; rtccInit.cntMode = rtccCntModeNormal; RTCC_Init(&rtccInit); // [RTCC init]$ }
void vPortSetupTimerInterrupt( void ) { /* Configure the RTCC to generate the RTOS tick interrupt. */ /* The maximum number of ticks that can be suppressed depends on the clock frequency. */ xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick; /* Ensure LE modules are accessible. */ CMU_ClockEnable( cmuClock_CORELE, true ); /* Use LFXO. */ CMU_ClockSelectSet( cmuClock_LFE, cmuSelect_LFXO ); /* Enable clock to the RTC module. */ CMU_ClockEnable( cmuClock_RTCC, true ); /* Use channel 1 to generate the RTOS tick interrupt. */ RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValueForOneTick ); RTCC_Init( &xRTCInitStruct ); RTCC_ChannelInit( lpRTCC_CHANNEL, &xRTCCChannel1InitStruct ); RTCC_EM4WakeupEnable( true ); /* Disable RTCC interrupt. */ RTCC_IntDisable( _RTCC_IF_MASK ); RTCC_IntClear( _RTCC_IF_MASK ); RTCC->CNT = _RTCC_CNT_RESETVALUE; /* The tick interrupt must be set to the lowest priority possible. */ NVIC_SetPriority( RTCC_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY ); NVIC_ClearPendingIRQ( RTCC_IRQn ); NVIC_EnableIRQ( RTCC_IRQn ); RTCC_IntEnable( RTCC_IEN_CC1 ); RTCC_Enable( true ); #if( lpUSE_TEST_TIMER == 1 ) { void prvSetupTestTimer( void ); /* A second timer is used to test the path where the MCU is brought out of a low power state by a timer other than the tick timer. */ prvSetupTestTimer(); } #endif }
/***************************************************************************//** * @brief * Initialize RTCDRV driver. * * @details * Will enable all necessary clocks. Initializes internal datastructures * and configures the underlying hardware timer. * * @return * @ref ECODE_EMDRV_RTCDRV_OK. ******************************************************************************/ Ecode_t RTCDRV_Init( void ) { if ( rtcdrvIsInitialized == true ) { return ECODE_EMDRV_RTCDRV_OK; } rtcdrvIsInitialized = true; // Ensure LE modules are clocked. CMU_ClockEnable( cmuClock_CORELE, true ); #if defined( CMU_LFECLKEN0_RTCC ) // Enable LFECLK in CMU (will also enable oscillator if not enabled). CMU_ClockSelectSet( cmuClock_LFE, RTCDRV_OSC ); #else // Enable LFACLK in CMU (will also enable oscillator if not enabled). CMU_ClockSelectSet( cmuClock_LFA, RTCDRV_OSC ); #endif #if defined( RTCDRV_USE_RTC ) // Set clock divider. CMU_ClockDivSet( cmuClock_RTC, RTC_DIVIDER ); // Enable RTC module clock. CMU_ClockEnable( cmuClock_RTC, true ); // Initialize RTC. RTC_Init( &initRTC ); #elif defined( RTCDRV_USE_RTCC ) // Set clock divider. initRTCC.presc = (RTCC_CntPresc_TypeDef)CMU_DivToLog2( RTC_DIVIDER ); // Enable RTCC module clock. CMU_ClockEnable( cmuClock_RTCC, true ); // Initialize RTCC. RTCC_Init( &initRTCC ); // Set up Compare channel. RTCC_ChannelInit( 1, &initRTCCCompareChannel ); #endif // Disable RTC/RTCC interrupt generation. RTC_INTDISABLE( RTC_ALL_INTS ); RTC_INTCLEAR( RTC_ALL_INTS ); RTC_COUNTERRESET(); // Clear and then enable RTC interrupts in NVIC. NVIC_CLEARPENDINGIRQ(); NVIC_ENABLEIRQ(); #if defined( EMDRV_RTCDRV_WALLCLOCK_CONFIG ) // Enable overflow interrupt for wallclock. RTC_INTENABLE( RTC_OF_INT ); #endif // Reset RTCDRV internal data structures/variables. memset( timer, 0, sizeof( timer ) ); inTimerIRQ = false; rtcRunning = false; startTimerNestingLevel = 0; #if defined( EMODE_DYNAMIC ) sleepBlocked = false; #endif #if defined( EMDRV_RTCDRV_WALLCLOCK_CONFIG ) wallClockOverflowCnt = 0; wallClockTimeBase = 0; #if defined( EMODE_NEVER_ALLOW_EM3EM4 ) // Always block EM3 and EM4 if wallclock is running. SLEEP_SleepBlockBegin( sleepEM3 ); #endif #endif return ECODE_EMDRV_RTCDRV_OK; }