I'm doing this way clock initialization:(copied from mxuxpresso ide)
SIM->CLKDIV1 = 0x01240000U;
MCG->SC=0x00;
MCG->SC|=MCG_SC_FCRDIV(0x01);
MCG->C2=0x03;
while(!(MCG->C2 & 0x01));
MCG->C1|=MCG_C1_IRCLKEN_MASK | MCG_C1_IREFS_MASK;
//while(!(MCG->C1 & MCG_C1_IREFS_MASK)){};
while(!(MCG->S & MCG_S_IREFST_MASK));
MCG->C1=(MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(1);
//while(!((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(1))) ; //wait until CLKS become 0x01
while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(1));
//now running 2MHz from IRC
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
if(!(RTC->CR & RTC_CR_OSCE_MASK))
RTC->CR = RTC_CR_OSCE_MASK | RTC_CR_SC8P_MASK;
//RTC->CR &= ~RTC_CR_CLKO_MASK;
// select external crystal for fll
MCG->C7 |= MCG_C7_OSCSEL_MASK;
/* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */
uint32_t i = 1500U;
while (i--)
{
__NOP();
}
uint8_t mcg_c4 = MCG->C4;
uint8_t change_drs = FALSE;
/*
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((MCG->S & MCG_S_IREFST_MASK))
{
change_drs = TRUE;
/* Change the LSB of DRST_DRS. */
MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT);
}
MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) |
(MCG_C1_CLKS(0) /* CLKS = 0 */
| MCG_C1_FRDIV(0) /* FRDIV */
| (0<< MCG_C1_IREFS_SHIFT))); /* IREFS = 0 */
while((MCG->S & MCG_S_IREFST_MASK));
/* Errata: ERR007993 */
if (change_drs)
{
MCG->C4 = mcg_c4;
}
/* Set DRS and DMX32. */
mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | ((1<< MCG_C4_DMX32_SHIFT) | MCG_C4_DRST_DRS(0)));
MCG->C4 = mcg_c4;
/* Wait for DRST_DRS update. */
while (MCG->C4 != mcg_c4){};
/* Check MCG_S[CLKST] */
while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(0)){};
i = 30000U;
while (i--)
{
__NOP();
}
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1);
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | (0<< SIM_SOPT2_PLLFLLSEL_SHIFT));
SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(0));
on second call it Hardfaults in busy loop on nop instruction.
How to correct this behaviour?
This error was caused bu unhandled ISR7 in code.
Asked another question: https://community.nxp.com/t5/Kinetis-Microcontrollers/MK10DN128VFT5-fires-ISR7/m-p/1189719#M58950
Hi
A hard fault in normally inconspicuous code points to a clock (usually the flash clock) being run out of specification.
Therefore if you recall this code it would be a good idea to first set things like clock dividers back to their default values so that there is not the risk of setting up a clock that is directly connected to something that will be overclocked.
Consider the clock speeds at each point in the code that are really being applied to buses and identify whether they may not be connected yet in the program flow if all registers start with their defaults, but are if registers retain the settings after the first operation.
See also this for an overview of the operation, whereby the rules are simply to wait for clocks settings to become stable at each change and avoid any 'connected' clocks being out of specification: https://www.utasker.com/kinetis/MCG.html
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements
Hello @korneliuszosmen,
One of the big differences between the supported MCUs in the SDK and the ones that aren't is the MCG so this initialization would not be useful. If you want a reference for configuring the MCG I will suggest using the Processor Expert tool included in the CodeWarrior IDE (link).
Best Regards,
Alexis Andalon