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 * 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 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); }
void RTCC_init(void) { RTCC_SOSCenable(); RTCC_Enable(); RTCC_SetWriteDisable(); RTCC_AlarmDisable(); RTCC_OutputDisable(); IntClearFlag(INT_REAL_TIME_CLOCK); }
void RTCC_SetAlarmEnable(int enable) { while (RTCALRM & 0x1000); // wait ALRMSYNC to be off RTCC_Disable(); if (enable) RTCALRMbits.ALRMEN = 1; // Alarm is enabled else RTCALRMbits.ALRMEN = 0; // Alarm is disabled RTCC_Enable(); }
rtccRes RTCC_Open(unsigned long tm, unsigned long dt, int drift) { RTCC_SOSCenable(); RTCC_SetTime(tm); RTCC_SetDate(dt); RTCC_SetCalibration(drift); RTCC_Enable(); RTCC_AlarmDisable(); RTCC_OutputDisable(); RTCC_SetWriteDisable(); IntClearFlag(INT_REAL_TIME_CLOCK); }
void RTCC_SetAlarmInitialPulse(int enable) { while (RTCALRM & 0x1000); // wait ALRMSYNC to be off RTCC_Disable(); // RTCC_SetAlarmEnable(False);// Alarm is disabled, PIV is writable if (enable) RTCALRMbits.PIV = 1; // the initial value of the Alarm Pulse is high else RTCALRMbits.PIV = 0; // the initial value of the Alarm Pulse is low RTCC_SetAlarmEnable(True); // Alarm is enabled RTCC_Enable(); // }
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 }
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCountAfterSleep; eSleepModeStatus eSleepAction; TickType_t xModifiableIdleTime; /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */ /* Make sure the RTC reload value does not overflow the counter. */ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) { xExpectedIdleTime = xMaximumPossibleSuppressedTicks; } /* Calculate the reload value required to wait xExpectedIdleTime tick periods. */ ulReloadValue = ulReloadValueForOneTick * xExpectedIdleTime; if( ulReloadValue > ulStoppedTimerCompensation ) { /* Compensate for the fact that the RTC is going to be stopped momentarily. */ ulReloadValue -= ulStoppedTimerCompensation; } /* Stop the RTC momentarily. The time the RTC is stopped for is accounted for as best it can be, but using the tickless mode will inevitably result in some tiny drift of the time maintained by the kernel with respect to calendar time. */ RTCC_Enable( false ); /* Enter a critical section but don't use the taskENTER_CRITICAL() method as that will mask interrupts that should exit sleep mode. */ INT_Disable(); __asm volatile( "dsb" ); __asm volatile( "isb" ); /* The tick flag is set to false before sleeping. If it is true when sleep mode is exited then sleep mode was probably exited because the tick was suppressed for the entire xExpectedIdleTime period. */ ulTickFlag = pdFALSE; /* If a context switch is pending then abandon the low power entry as the context switch might have been pended by an external interrupt that requires processing. */ eSleepAction = eTaskConfirmSleepModeStatus(); if( eSleepAction == eAbortSleep ) { /* Restart tick and continue counting to complete the current time slice. */ RTCC_Enable( true ); /* Re-enable interrupts - see comments above the RTCC_Enable() call above. */ INT_Enable(); } else { RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValue ); /* Restart the RTC. */ RTCC_Enable( true ); /* Allow the application to define some pre-sleep processing. */ xModifiableIdleTime = xExpectedIdleTime; configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); /* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING() means the application defined code has already executed the WAIT instruction. */ if( xModifiableIdleTime > 0 ) { __asm volatile( "dsb" ); SLEEP_Sleep(); __asm volatile( "isb" ); } /* Allow the application to define some post sleep processing. */ configPOST_SLEEP_PROCESSING( xModifiableIdleTime ); /* Stop RTC. Again, the time the SysTick is stopped for is accounted for as best it can be, but using the tickless mode will inevitably result in some tiny drift of the time maintained by the kernel with respect to calendar time. */ RTCC_Enable( false ); ulCountAfterSleep = RTCC_CounterGet(); /* Re-enable interrupts - see comments above the INT_Enable() call above. */ INT_Enable(); __asm volatile( "dsb" ); __asm volatile( "isb" ); if( ulTickFlag != pdFALSE ) { /* The tick interrupt has already executed, although because this function is called with the scheduler suspended the actual tick processing will not occur until after this function has exited. The tick interrupt handler will already have pended the tick processing in the kernel. As the pending tick will be processed as soon as this function exits, the tick value maintained by the tick is stepped forward by one less than the time spent sleeping. The actual stepping of the tick appears later in this function. */ ulCompleteTickPeriods = xExpectedIdleTime - 1UL; /* The interrupt should have reset the CCV value. */ configASSERT( RTCC_ChannelCCVGet( lpRTCC_CHANNEL ) == ulReloadValueForOneTick ); } else { /* Something other than the tick interrupt ended the sleep. How many complete tick periods passed while the processor was sleeping? */ ulCompleteTickPeriods = ulCountAfterSleep / ulReloadValueForOneTick; /* The next interrupt is configured to occur at whatever fraction of the current tick period remains by setting the reload value back to that required for one tick, and truncating the count to remove the counts that are greater than the reload value. */ RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValueForOneTick ); ulCountAfterSleep %= ulReloadValueForOneTick; RTCC_CounterSet( ulCountAfterSleep ); } /* Restart the RTC so it runs up to the alarm value. The alarm value will get set to the value required to generate exactly one tick period the next time the RTC interrupt executes. */ RTCC_Enable( true ); /* Wind the tick forward by the number of tick periods that the CPU remained in a low power state. */ vTaskStepTick( ulCompleteTickPeriods ); }