void Clock_init(void){ /*Configure SAM4L to run at 48MHz*/ // - Switch Main clock to RCSYS for reconfiguration PM->PM_MCCTRL = PM_MCCTRL_MCSEL(0); // - Set CPU clock = Main clock PM->PM_CPUSEL = ((0<<PM_CPUSEL_CPUDIV_Pos)|(0<<PM_CPUSEL_CPUSEL_Pos)); // - Set Flash wait state to 1 HFLASHC->FLASHCALW_FCR |= (0x1 << FLASHCALW_FCR_FWS_Pos); // - Enable OSC0 SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)|SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_OSCCTRL0 - (uint32_t)SCIF); SCIF->SCIF_OSCCTRL0 |= SCIF_OSCCTRL0_STARTUP(2)|SCIF_OSCCTRL0_GAIN(3)|SCIF_OSCCTRL0_MODE| SCIF_OSCCTRL0_OSCEN; while (!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_OSC0RDY)); // - Configure and enable PLL to generate 48MHz from OSC0 SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)|SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_PLL[0] - (uint32_t)SCIF); SCIF->SCIF_PLL[0].SCIF_PLL|= SCIF_PLL_PLLOSC(0)|SCIF_PLL_PLLDIV(0)|SCIF_PLL_PLLMUL(3)|SCIF_PLL_PLLOPT(2); SCIF->SCIF_PLL[0].SCIF_PLL|= SCIF_PLL_PLLEN; //while (!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_PLL0LOCK));//wait while the PLL is not locked (not used refer to Datasheet errata rev B)... // - Select PLL0 as main clock source PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_MCCTRL); PM->PM_MCCTRL = PM_MCCTRL_MCSEL_PLL0; /* Enable required peripheral clocks */ PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBAMASK); PM->PM_PBAMASK |= PM_PBAMASK_USART0 ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK); PM->PM_PBCMASK |= PM_PBCMASK_GPIO ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_HSBMASK); PM->PM_HSBMASK |= PM_HSBMASK_PDCA ; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu)|BPM_UNLOCK_ADDR((uint32_t)&PM->PM_PBBMASK); PM->PM_PBBMASK |= PM_PBBMASK_PDCA ; }
static inline void sam_enablerc80m(void) { uint32_t regval; /* Configure and enable RC80M */ regval = getreg32(SAM_SCIF_RC80MCR); putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RC80MCR_OFFSET), SAM_SCIF_UNLOCK); putreg32(regval | SCIF_RC80MCR_EN, SAM_SCIF_RC80MCR); /* Wait for OSC32 to be ready */ while (getreg32(SAM_SCIF_RC80MCR) & SCIF_RC80MCR_EN) == 0); }
static inline void sam_enableosc0(void) { uint32_t regval; /* Enable and configure OSC0 */ regval = SAM_OSC0_STARTUP_VALUE | SAM_OSC0_GAIN_VALUE | SAM_OSC0_MODE_VALUE | SCIF_OSCCTRL0_OSCEN; putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_OSCCTRL0_OFFSET), SAM_SCIF_UNLOCK); putreg32(regval, SAM_SCIF_OSCCTRL0); /* Wait for OSC0 to be ready */ while (getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_OSC0RDY) == 0); }
void osc_priv_enable_osc0(void) { irqflags_t flags; flags = cpu_irq_save(); SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu) | SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_OSCCTRL0 - (uint32_t)SCIF); SCIF->SCIF_OSCCTRL0 = OSC0_STARTUP_VALUE # if BOARD_OSC0_IS_XTAL == true | OSC0_GAIN_VALUE #endif | OSC0_MODE_VALUE | SCIF_OSCCTRL0_OSCEN; cpu_irq_restore(flags); }
void osc_priv_disable_rcfast(void) { irqflags_t flags; uint32_t temp; flags = cpu_irq_save(); // Let FCD and calibration value by default temp = SCIF->SCIF_RCFASTCFG; // Clear previous FRANGE value temp &= ~SCIF_RCFASTCFG_FRANGE_Msk; // Disalbe RCFAST temp &= ~SCIF_RCFASTCFG_EN; SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu) | SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_RCFASTCFG - (uint32_t)SCIF); SCIF->SCIF_RCFASTCFG = temp; cpu_irq_restore(flags); }
void dfll_enable_open_loop(const struct dfll_config *cfg, uint32_t dfll_id) { irqflags_t flags; UNUSED(dfll_id); /* First, enable the DFLL, then configure it */ flags = cpu_irq_save(); SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAUL) | SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_DFLL0CONF - (uint32_t)SCIF); SCIF->SCIF_DFLL0CONF = SCIF_DFLL0CONF_EN; cpu_irq_restore(flags); dfll_write_reg(DFLL0CONF, cfg->conf | SCIF_DFLL0CONF_EN); dfll_write_reg(DFLL0MUL, cfg->mul); dfll_write_reg(DFLL0VAL, cfg->val); dfll_write_reg(DFLL0SSG, cfg->ssg); }
static inline void sam_enablercfast(void) { uint32_t regval; /* Configure and enable RCFAST */ regval = getreg32(SAM_SCIF_RCFASTCFG); regval &= ~SCIF_RCFASTCFG_FRANGE_MASK; regval |= (SAM_RCFAST_RANGE | SCIF_RCFASTCFG_EN); putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RCFASTCFG_OFFSET), SAM_SCIF_UNLOCK); putreg32(regval, SAM_SCIF_RCFASTCFG); /* Wait for RCFAST to be ready */ while (getreg32(SAM_SCIF_RCFASTCFG) & SCIF_RCFASTCFG_EN) == 0); }
static inline void sam_enabledfll0(void) { uint32_t regval; uint32_t conf; /* Set up generic clock source with specified reference clock * and divider. */ putreg32(0, SAM_SCIF_GCCTRL0); /* Set the generic clock 0 source */ regval = getreg32(SAM_SCIF_GCCTRL0); regval &= ~SCIF_GCCTRL_OSCSEL_MASK; regval |= SAM_DFLLO_REFCLK; putreg32(regval, SAM_SCIF_GCCTRL0); /* Get the generic clock 0 divider */ regval = getreg32(SAM_SCIF_GCCTRL0); regval &= ~(SCIF_GCCTRL_DIVEN | SCIF_GCCTRL_DIV_MASK); #if BOARD_DFLL0_DIV > 1 regval |= SCIF_GCCTRL_DIVEN; regval |= SCIF_GCCTRL_DIV(((BOARD_DFLL0_DIV + 1) / 2) - 1); #endif putreg32(regval, SAM_SCIF_GCCTRL0); /* Sync before reading a dfll conf register */ putreg32(SCIF_DFLL0SYNC_SYNC, SAM_SCIF_DFLL0SYNC); while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_DFLL0RDY) == 0); /* Select Closed Loop Mode */ conf = getreg32(SAM_SCIF_DFLL0CONF); conf &= ~SCIF_DFLL0CONF_RANGE_MASK; conf |= SCIF_DFLL0CONF_MODE; /* Select the DFLL0 Frequency Range */ #if BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE3 conf |= SCIF_DFLL0CONF_RANGE3; #elif BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE2 conf |= SCIF_DFLL0CONF_RANGE2; #elif BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE1 conf |= SCIF_DFLL0CONF_RANGE1; #else conf |= SCIF_DFLL0CONF_RANGE0; #endif /* Enable the reference generic clock 0 */ regval = getreg32(SAM_SCIF_GCCTRL0); regval |= SCIF_GCCTRL_CEN; putreg32(regval, SAM_SCIF_GCCTRL0); /* Enable DFLL0. Here we assume DFLL0RDY because the DFLL was disabled * before this function was called. */ putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_DFLL0CONF_OFFSET), SAM_SCIF_UNLOCK); putreg32(SCIF_DFLL0CONF_EN, SAM_SCIF_DFLL0CONF); /* Configure DFLL0. Note that now we do have to wait for DFLL0RDY before * every write. * * Set the initial coarse and fine step lengths to 4. If this is set * too high, DFLL0 may fail to lock. */ sam_dfll0_putreg32(SCIF_DFLL0STEP_CSTEP(4) | SCIF_DFLL0STEP_FSTEP(4), SAM_SCIF_DFLL0STEP, SAM_SCIF_DFLL0STEP_OFFSET); /* Set the DFLL0 multipler register */ sam_dfll0_putreg32(BOARD_DFLL0_MUL, SAM_SCIF_DFLL0MUL, SAM_SCIF_DFLL0MUL_OFFSET); /* Set the multipler and spread spectrum generator control registers */ sam_dfll0_putreg32(0, SAM_SCIF_DFLL0SSG, SAM_SCIF_DFLL0SSG_OFFSET); /* Finally, set the DFLL0 configuration */ sam_dfll0_putreg32(conf | SCIF_DFLL0CONF_EN, SAM_SCIF_DFLL0CONF, SAM_SCIF_DFLL0CONF_OFFSET); /* Wait until we are locked on the fine value */ while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_DFLL0LOCKF) == 0); }