MK10DN128VFT5 halts in clock setup

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MK10DN128VFT5 halts in clock setup

1,499 Views
korneliuszosmen
Contributor III

I have a problem with setting up clocks.

I'm trying to use FEE mode from RTC oscillator

Code which I use:

 

	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->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;

	MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(0); // divide clock for FLL by 1

	MCG->C2 &= ~MCG_C2_LP_MASK; // switch off low power for FLL

	// select FLL factor
	MCG->C2 &= ~MCG_C2_RANGE_MASK;

	MCG->C4 |= MCG_C4_DMX32_MASK;
	MCG->C4 |= (MCG->C4 & ~MCG_C4_DRST_DRS_MASK) | MCG_C4_DRST_DRS(0);

	// select external clock for FLL
	MCG->C1 &= ~MCG_C1_IREFS_MASK;
	while((MCG->S & MCG_S_IREFST_MASK));

	// select FLL, not PLL and wait for switching
	MCG->C6 &= ~MCG_C6_PLLS_MASK;
	while((MCG->S & MCG_S_PLLST_MASK));

	// select FLL/PLL as clock source and wait for it
	MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(0); // set PLL/FLL output
	while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(0));

 

It halts on while((MCG->S & MCG_S_IREFST_MASK));

Any ideas how to fix this problem?

Labels (1)
0 Kudos
12 Replies

1,458 Views
mjbcswitzerland
Specialist V

Hi

Here's commented code to set up the FLL to 95.97747MHz from external 32kHz crystal taken from the uTasker project:

#define _FLL_VALUE (MCG_C4_HIGH_RANGE | MCG_C4_DMX32)

POWER_UP_ATOMIC(6, RTC); // enable access to the RTC
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK
RTC_CR = (RTC_CR_OSCE); // enable RTC oscillator and output the 32.768kHz output clock so that it can be used by the MCG (the first time that it starts it can have a startup/stabilisation time but this is not critical for the FLL usage)
MCG_C1 = ((MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_RANGE0_1) & ~MCG_C1_IREFS); // switch the FLL input to the undivided external clock source (RTC)
SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides ready for the final operating frequency
_WAIT_REGISTER_TRUE(MCG_S, MCG_S_IREFST); // wait until the switch to the external RTC source has completed
MCG_C4 = ((MCG_C4 & ~(MCG_C4_DMX32 | MCG_C4_HIGH_RANGE)) | (_FLL_VALUE)); // adjust FLL factor to obtain the required operating frequency

 

Beware however that this works on Revision 2 devices only.
If you happen to have an old Revision 1 part (or generally can be used for compatibility)

SIM_SOPT2 |= SIM_SOPT2_MCGCLKSEL; // attempt to select external source (revision 1 parts)
if ((SIM_SOPT2 & SIM_SOPT2_MCGCLKSEL) == 0) { // rev 2 parts won't set this bit so we can tell that the setting must be performed in the MCG module instead
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK
}

can be used in place of the second line
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK

 

If your code is hanging waiting for the RTC output to be selected as input to the FLL it will usually mean that the RTC clock isn't operating. See also https://www.utasker.com/kinetis/MCG.html for a practical discussion of the MCG.

 

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 or product development requirements

mjbcswitzerland_0-1600344318021.png

 

0 Kudos

1,445 Views
mjbcswitzerland
Specialist V

Hi

Here's commented code to set up the FLL to 95.97747MHz from external 32kHz crystal taken from the uTasker project:

 

#define _FLL_VALUE     (MCG_C4_HIGH_RANGE | MCG_C4_DMX32)

POWER_UP_ATOMIC(6, RTC);                                             // enable access to the RTC
MCG_C7 = MCG_C7_OSCSEL_32K;                                          // select the RTC clock as external clock input to the FLL or MCGOUTCLK
RTC_CR = (RTC_CR_OSCE);                                              // enable RTC oscillator and output the 32.768kHz output clock so that it can be used by the MCG (the first time that it starts it can have a startup/stabilisation time but this is not critical for the FLL usage)
MCG_C1 = ((MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_RANGE0_1) & ~MCG_C1_IREFS); // switch the FLL input to the undivided external clock source (RTC)
SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides ready for the final operating frequency
_WAIT_REGISTER_TRUE(MCG_S, MCG_S_IREFST);                             // wait until the switch to the external RTC source has completed
MCG_C4 = ((MCG_C4 & ~(MCG_C4_DMX32 | MCG_C4_HIGH_RANGE)) | (_FLL_VALUE)); // adjust FLL factor to obtain the required operating frequency

 

 Beware however that this works on Revision 2 devices only.
If you happen to have an old Revision 1 part (or generally can be used for compatibility)

 

SIM_SOPT2 |= SIM_SOPT2_MCGCLKSEL;                                    // attempt to select external source (revision 1 parts)
if ((SIM_SOPT2 & SIM_SOPT2_MCGCLKSEL) == 0) {                        // rev 2 parts won't set this bit so we can tell that the setting must be performed in the MCG module instead
    MCG_C7 = MCG_C7_OSCSEL_32K;                                      // select the RTC clock as external clock input to the FLL or MCGOUTCLK
}

 

 

can be used in place of the second line
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK


If your code is hanging waiting for the RTC output to be selected as input to the FLL it will usually mean that the RTC clock isn't operating. See also https://www.utasker.com/kinetis/MCG.html for a practical discussion of the MCG.

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 or product development requirements

mjbcswitzerland_0-1600336475124.png

 

 

0 Kudos

1,441 Views
mjbcswitzerland
Specialist V

Hi

Here's commented code to set up the FLL to 95.97747MHz from external 32kHz crystal taken from the uTasker project:

#define _FLL_VALUE     (MCG_C4_HIGH_RANGE | MCG_C4_DMX32)

POWER_UP_ATOMIC(6, RTC);                                             // enable access to the RTC
MCG_C7 = MCG_C7_OSCSEL_32K;                                          // select the RTC clock as external clock input to the FLL or MCGOUTCLK
RTC_CR = (RTC_CR_OSCE);                                              // enable RTC oscillator and output the 32.768kHz output clock so that it can be used by the MCG (the first time that it starts it can have a startup/stabilisation time but this is not critical for the FLL usage)
MCG_C1 = ((MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_RANGE0_1) & ~MCG_C1_IREFS); // switch the FLL input to the undivided external clock source (RTC)
SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides ready for the final operating frequency
_WAIT_REGISTER_TRUE(MCG_S, MCG_S_IREFST);                             // wait until the switch to the external RTC source has completed
MCG_C4 = ((MCG_C4 & ~(MCG_C4_DMX32 | MCG_C4_HIGH_RANGE)) | (_FLL_VALUE)); // adjust FLL factor to obtain the required operating frequency

 Beware however that this works on Revision 2 devices only.
If you happen to have an old Revision 1 part (or generally can be used for compatibility)

SIM_SOPT2 |= SIM_SOPT2_MCGCLKSEL;                                    // attempt to select external source (revision 1 parts)
if ((SIM_SOPT2 & SIM_SOPT2_MCGCLKSEL) == 0) {                        // rev 2 parts won't set this bit so we can tell that the setting must be performed in the MCG module instead
    MCG_C7 = MCG_C7_OSCSEL_32K;                                      // select the RTC clock as external clock input to the FLL or MCGOUTCLK
}

 

can be used in place of the second line
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK


If your code is hanging waiting for the RTC output to be selected as input to the FLL it will usually mean that the RTC clock isn't operating. See also https://www.utasker.com/kinetis/MCG.html for a practical discussion of the MCG.

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 or product development requirements

mjbcswitzerland_0-1600336475124.png

 

 

0 Kudos

1,441 Views
mjbcswitzerland
Specialist V

Hi

Here's commented code to set up the FLL to 95.97747MHz from external 32kHz crystal taken from the uTasker project:

 

 

 

#define _FLL_VALUE (MCG_C4_HIGH_RANGE | MCG_C4_DMX32)


POWER_UP_ATOMIC(6, RTC); // enable access to the RTC
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK
RTC_CR = (RTC_CR_OSCE); // enable RTC oscillator and output the 32.768kHz output clock so that it can be used by the MCG (the first time that it starts it can have a startup/stabilisation time but this is not critical for the FLL usage)
MCG_C1 = ((MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_RANGE0_1) & ~MCG_C1_IREFS); // switch the FLL input to the undivided external clock source (RTC)
SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides ready for the final operating frequency
_WAIT_REGISTER_TRUE(MCG_S, MCG_S_IREFST); // wait until the switch to the external RTC source has completed
MCG_C4 = ((MCG_C4 & ~(MCG_C4_DMX32 | MCG_C4_HIGH_RANGE)) | (_FLL_VALUE)); // adjust FLL factor to obtain the required operating frequency

 

 

 

 

Beware however that this works on Revision 2 devices only.
If you happen to have an old Revision 1 part (or generally can be used for compatibility)

SIM_SOPT2 |= SIM_SOPT2_MCGCLKSEL; // attempt to select external source (revision 1 parts)
if ((SIM_SOPT2 & SIM_SOPT2_MCGCLKSEL) == 0) { // rev 2 parts won't set this bit so we can tell that the setting must be performed in the MCG module instead
MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK
}

can be used in place of the second line


MCG_C7 = MCG_C7_OSCSEL_32K; // select the RTC clock as external clock input to the FLL or MCGOUTCLK

 

If your code is hanging waiting for the RTC output to be selected as input to the FLL it will usually mean that the RTC clock isn't operating. See also https://www.utasker.com/kinetis/MCG.html for a practical discussion of the MCG.

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 or product development requirements

mjbcswitzerland_0-1600336174472.png

 

0 Kudos

1,408 Views
korneliuszosmen
Contributor III

Hi,

It looks like this solution is for K60.

My problem is for K10 which doesn't have SIM_SOPT2_MCGCLKSEL flag in register.

Regards

Korneliusz

0 Kudos

1,402 Views
mjbcswitzerland
Specialist V

Hi Korneliusz

The K10 and K60 are compatible with respect to the clock module (the K10 is effectively a K60 without Ethernet and USB).

Rev. 1 versions of the chips have SIM_SOPT2_MCGCLKSEL
but Rev. 2 versions don't -> the control was moved to a different register.

If your part is not a rev.1 part (doesn't have Z in its name) you can ignore that detail.

Regards

Mark


0 Kudos

1,482 Views
nxf58904
NXP Employee
NXP Employee

Hi,

I am debugging your code .I still need time to do it. I will update immediately as soon as solved. Before this, you can have a try to use mcuxpresso to configure the FEE with rtc osc.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,446 Views
myke_predko
Senior Contributor III

Hi @korneliuszosmen 

The problem you're experiencing is that the clock is not stabilizing (the loop you're in is the clocking hardware waiting for stabilization to happen).  I typically see this when I've specified the wrong crystal caps or I have not configured the clocking module properly.  

I would reiterate @nxf58904 's suggestion - try to set up in the MCUXpresso IDE Clocking Wizard.   It's a bit finicky to work with (ie don't be afraid of clicking on things repeatedly for them to take) but it does provide a good model of the clock circuitry in Kinetis and will flag configuration errors either as not allowing you to set your desired configuration or flag.  In the paths view, make sure that all the paths are Black or Blue (not Red).  

If you can't get it to set up the way you want it to or if there are errors (look at the "Problems" window in the bottom right corner of the screen).  

Once you have that, compare the code it generates to yours or, better still, just use it.  

Good luck!

myke

0 Kudos

1,437 Views
mjbcswitzerland
Specialist V

Hi

 

Yes, it is important to measure that the RTC clock is actually oscillating since if it isn't it will never be able to pass the check that it is hanging on.
For example, if the crystal were broken or not correctly soldered and the oscillator were not to start there is no need to search solutions in the code and this must be fixed first.

In fact in designs based on the RTC crystal as source it may also be useful to allow the code to fall back to using an internal clock source so that it can report HW errors, or maybe be able to 'limp-on' using the internal 32kHz RC to guarantee some basic operation.

Regards

Mark

 

1,435 Views
myke_predko
Senior Contributor III

@mjbcswitzerland ,

Interesting suggestions - thank you.  

myke

0 Kudos

1,395 Views
korneliuszosmen
Contributor III
    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));

Changed to flow which is used in mcuxpresso sample but it randomly hardfalults on second call (common code in crt between bootloader and main code)

0 Kudos

1,216 Views
korneliuszosmen
Contributor III

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

0 Kudos