/** * @brief Initialize RTT module * * The RTT is running at 32768 Hz by default, i.e. @ XOSC32K frequency without * divider. There are 2 cascaded dividers in the clock path: * * - GCLK_GENDIV_DIV(n): between 1 and 31 * - RTC_MODE0_CTRL_PRESCALER_DIVn: between 1 and 1024, see defines in `component_rtc.h` * * However the division scheme of GCLK_GENDIV_DIV can be changed by setting * GCLK_GENCTRL_DIVSEL: * * - GCLK_GENCTRL_DIVSEL = 0: Clock divided by GENDIV.DIV (default) * - GCLK_GENCTRL_DIVSEL = 1: Clock divided by 2^( GENDIV.DIV + 1 ) */ void rtt_init(void) { RtcMode0 *rtcMode0 = &(RTT_DEV); /* Turn on power manager for RTC */ PM->APBAMASK.reg |= PM_APBAMASK_RTC; /* RTC uses External 32,768KHz Oscillator because OSC32K isn't accurate * enough (p1075/1138). Also keep running in standby. */ SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | SYSCTRL_XOSC32K_EN32K | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_STARTUP(6) | #if RTT_RUNSTDBY SYSCTRL_XOSC32K_RUNSTDBY | #endif SYSCTRL_XOSC32K_ENABLE; /* Setup clock GCLK2 with divider 1 */ GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); while (GCLK->STATUS.bit.SYNCBUSY) {} /* Enable GCLK2 with XOSC32K as source. Use divider without modification * and keep running in standby. */ GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN | #if RTT_RUNSTDBY GCLK_GENCTRL_RUNSTDBY | #endif GCLK_GENCTRL_SRC_XOSC32K; while (GCLK->STATUS.bit.SYNCBUSY) {} /* Connect GCLK2 to RTC */ GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(RTC_GCLK_ID); while (GCLK->STATUS.bit.SYNCBUSY) {} /* Disable RTC */ rtt_poweroff(); /* Reset RTC */ rtcMode0->CTRL.bit.SWRST = 1; while (rtcMode0->STATUS.bit.SYNCBUSY || rtcMode0->CTRL.bit.SWRST) {} /* Configure as 32bit counter with no prescaler and no clear on match compare */ rtcMode0->CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32 | RTT_PRESCALER; while (rtcMode0->STATUS.bit.SYNCBUSY) {} /* Setup interrupt */ NVIC_EnableIRQ(RTT_IRQ); /* Enable RTC */ rtt_poweron(); }
void rtc_poweroff(void) { rtt_poweroff(); }