status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) { CLOCK_SetExternalRefClkConfig(oscsel); /* Set to FBE mode. */ MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ /* If use external crystal as clock source, wait for it stable. */ { if (MCG->C2 & MCG_C2_EREFS_MASK) { while (!(MCG->S & MCG_S_OSCINIT0_MASK)) { } } } /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) { } /* In FBE now, start to enter BLPE. */ MCG->C2 |= MCG_C2_LP_MASK; return kStatus_Success; }
status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) { uint8_t mcg_c4; bool change_drs = false; #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) mcg_mode_t mode = CLOCK_GetMode(); if (!((kMCG_ModeFEI == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEE == mode))) { return kStatus_MCG_ModeUnreachable; } #endif mcg_c4 = MCG->C4; /* Errata: ERR007993 Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before reference clock source changes, then reset to previous value after reference clock changes. */ if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) { change_drs = true; /* Change the LSB of DRST_DRS. */ MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); } /* Set CLKS and IREFS. */ MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK))) | (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcInternal)); /* IREFS = 1 */ /* Wait and check status. */ while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) { } /* Errata: ERR007993 */ if (change_drs) { MCG->C4 = mcg_c4; } /* In FEI mode, the MCG_C4[DMX32] is set to 0U. */ MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); /* Check MCG_S[CLKST] */ while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) { } /* Wait for FLL stable time. */ if (fllStableDelay) { fllStableDelay(); } return kStatus_Success; }
status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) { uint8_t mcg_c4; bool change_drs = false; #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) mcg_mode_t mode = CLOCK_GetMode(); if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode) || (kMCG_ModePBE == mode) || (kMCG_ModeBLPE == mode))) { return kStatus_MCG_ModeUnreachable; } #endif /* Change to FLL mode. */ MCG->C6 &= ~MCG_C6_PLLS_MASK; while (MCG->S & MCG_S_PLLST_MASK) { } /* Set LP bit to enable the FLL */ MCG->C2 &= ~MCG_C2_LP_MASK; mcg_c4 = MCG->C4; /* Errata: ERR007993 Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before reference clock source changes, then reset to previous value after reference clock changes. */ if (kMCG_FllSrcInternal == MCG_S_IREFST_VAL) { change_drs = true; /* Change the LSB of DRST_DRS. */ MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); } /* Set CLKS and IREFS. */ MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ /* Wait for Reference clock Status bit to clear */ while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) { } /* Errata: ERR007993 */ if (change_drs) { MCG->C4 = mcg_c4; } /* Set DRST_DRS and DMX32. */ mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs))); /* Wait for clock status bits to show clock source is ext ref clk */ while (kMCG_ClkOutStatExt != MCG_S_CLKST_VAL) { } /* Wait for fll stable time. */ if (fllStableDelay) { fllStableDelay(); } return kStatus_Success; }