//----------------------------------------------------------------------------- static void sys_init(void) { OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_XTALEN | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_RUNSTDBY | OSC32KCTRL_XOSC32K_STARTUP(7); while (0 == OSC32KCTRL->STATUS.bit.XOSC32KRDY); #define LDR (((unsigned long)F_CPU * 32) / 32768) GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_XOSC32K) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; while (0 == (GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg & GCLK_PCHCTRL_CHEN)); GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL032K].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; while (0 == (GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL032K].reg & GCLK_PCHCTRL_CHEN)); OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR % 32) | OSCCTRL_DPLLRATIO_LDR((LDR / 32) - 1); OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32 | OSCCTRL_DPLLCTRLB_DIV(1) | OSCCTRL_DPLLCTRLB_WUF | OSCCTRL_DPLLCTRLB_LBYPASS; OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY; while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY || 0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK); GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL0) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; }
void RtcInit() { // SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ENABLE | SYSCTRL_XOSC32K_EN32K; // //wait for crystal to warm up // while((SYSCTRL->PCLKSR.reg & (SYSCTRL_PCLKSR_XOSC32KRDY)) == 0); GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(8); GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_SRC(GCLK_SOURCE_OSC8M) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Configure RTC GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(2); RTC->MODE1.CTRL.reg = RTC_MODE1_CTRL_MODE_COUNT16; while (RTC->MODE1.STATUS.bit.SYNCBUSY); // Prescaler needs to be enabled separately from the mode for some reason RTC->MODE1.CTRL.reg |= RTC_MODE1_CTRL_PRESCALER_DIV1; while (RTC->MODE1.STATUS.bit.SYNCBUSY); RTC->MODE1.PER.reg = 998; while (RTC->MODE1.STATUS.bit.SYNCBUSY); RTC->MODE1.READREQ.reg |= RTC_READREQ_RCONT | RTC_READREQ_ADDR(0x10); RTC->MODE1.INTENSET.reg = RTC_MODE1_INTENSET_OVF; RTC->MODE1.CTRL.bit.ENABLE = 1; while (RTC->MODE1.STATUS.bit.SYNCBUSY); NVIC_EnableIRQ(RTC_IRQn); }