status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv) { uint32_t mcgOutClkState = MCG_S_CLKST_VAL; mcg_irc_mode_t curIrcs = (mcg_irc_mode_t)MCG_S_IRCST_VAL; uint8_t curFcrdiv = MCG_SC_FCRDIV_VAL; #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) /* If MCGIRCLK is used as system clock source. */ if (kMCG_ClkOutStatInt == mcgOutClkState) { /* If need to change MCGIRCLK source or driver, return error. */ if (((kMCG_IrcFast == curIrcs) && (fcrdiv != curFcrdiv)) || (ircs != curIrcs)) { return kStatus_MCG_SourceUsed; } } #endif /* If need to update the FCRDIV. */ if (fcrdiv != curFcrdiv) { /* If fast IRC is in use currently, change to slow IRC. */ if ((kMCG_IrcFast == curIrcs) && ((mcgOutClkState == kMCG_ClkOutStatInt) || (MCG->C1 & MCG_C1_IRCLKEN_MASK))) { MCG->C2 = ((MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(kMCG_IrcSlow))); while (MCG_S_IRCST_VAL != kMCG_IrcSlow) { } } /* Update FCRDIV. */ MCG->SC = (MCG->SC & ~(MCG_SC_FCRDIV_MASK | MCG_SC_ATMF_MASK | MCG_SC_LOCS0_MASK)) | MCG_SC_FCRDIV(fcrdiv); } /* Set internal reference clock selection. */ MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(ircs)); MCG->C1 = (MCG->C1 & ~(MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK)) | (uint8_t)enableMode; /* If MCGIRCLK is used, need to wait for MCG_S_IRCST. */ if ((mcgOutClkState == kMCG_ClkOutStatInt) || (enableMode & kMCG_IrclkEnable)) { while (MCG_S_IRCST_VAL != ircs) { } } return kStatus_Success; }
status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig) { assert(targetConfig); /* * If switch between LIRC8M and LIRC2M, need to switch to HIRC mode first, * because could not switch directly. */ if ((kMCGLITE_ClkSrcLirc == MCG_S_CLKST_VAL) && (kMCGLITE_ClkSrcLirc == targetConfig->outSrc) && (MCG_C2_IRCS_VAL != targetConfig->ircs)) { MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCGLITE_ClkSrcHirc); while (kMCGLITE_ClkSrcHirc != MCG_S_CLKST_VAL) { } } /* Set configuration now. */ MCG->SC = MCG_SC_FCRDIV(targetConfig->fcrdiv); MCG->MC = MCG_MC_HIRCEN(targetConfig->hircEnableInNotHircMode) | MCG_MC_LIRC_DIV2(targetConfig->lircDiv2); MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | MCG_C2_IRCS(targetConfig->ircs); MCG->C1 = MCG_C1_CLKS(targetConfig->outSrc) | targetConfig->irclkEnableMode; /* * If external oscillator used and MCG_Lite is set to EXT mode, need to * wait for the OSC stable. */ if ((MCG->C2 & MCG_C2_EREFS0_MASK) && (kMCGLITE_ClkSrcExt == targetConfig->outSrc)) { while (!(MCG->S & MCG_S_OSCINIT0_MASK)) { } } /* Wait for clock source change completed. */ while (targetConfig->outSrc != MCG_S_CLKST_VAL) { } return kStatus_Success; }