Hallo community,
is it possible to change the core clock when I have already initialized it?
I have a MK10DX128 VLH7 that runs on 48 Mhz. Now I try to change the core clock by changing MCG_C4_DRST_DRS and MCG_C4_DMX32_MASK but it just change the DMX32. When I set DRS to 2 the mcu crashs.
Here is the source code I use:
static void clockSystem_init(void)
{
uint32_t i;
// Configure RTC
SIM_SCGC6 |= SIM_SCGC6_RTC_MASK; // Activate clock for RTC
RTC_CR = RTC_CR_SWR_MASK; // Reset RTC registers
RTC_CR = 0u; // No additional load capacitors, RTC is output to other peripherals
RTC_CR |= RTC_CR_OSCE_MASK; // Enable RTC oscillator
// Wait for oscillator is stabilized --> TBD: Check and set correct value for this process
for(i = 0u; i < 1000000ul; i++)
{
asm volatile ("nop");
}
// Configure clock distribution and FLL
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(1); // core/sys clock DIV = 1, bus clock DIV = 1, FlexBus clock DIV = 2, flash clock DIV = 2
MCG_C1 = 0x00u; // FLL is output for MCGOUTCLK, external ref. is clock for FLL, set FLL input divider to 1
MCG_C2 = 0x00u; // Set RANGE0 to 0 --> low frequency range crystal oscillator
MCG_C7 |= MCG_C7_OSCSEL_MASK; // Select RTC as external clock reference for MCG
SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(2); // Select RTC as clock clock source for ERCLK32K --> LPTMR
while(MCG_S & MCG_S_IREFST_MASK); // Wait for reference clock to switch to external reference
while( ((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0u ); // Wait for clock status bit to update
MCG_C4 |= MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(1); // Configure FLL for 48 MHz output
}
void changeSystemClock( uint8_t clockRate )
{
bool_t dmx32 = 0;
uint8_t drs = 0;
switch(clockRate)
{
case 20:
dmx32 = 0;
drs = 0;
break;
case 24:
dmx32 = 1;
drs = 0;
break;
case 40:
dmx32 = 0;
drs = 1;
break;
case 48:
dmx32 = 1;
drs = 1;
break;
case 60:
dmx32 = 0;
drs = 2;
break;
case 72:
dmx32 = 1;
drs = 2;
break;
}
// Configure new core clock
if( dmx32 == 1 )
{
MCG_C4 |= MCG_C4_DMX32_MASK;
}
else
{
MCG_C4 &= ~(MCG_C4_DMX32_MASK);
}
MCG_C4 |= MCG_C4_DRST_DRS(drs); // Configure FLL
}
It would be nice when you can help me.
sincerelly yours
Eric
Solved! Go to Solution.
Hi Mark,
I solved the problem by setting the drs first to zero and then change to the new value. I dont know why it not worked only with changing the value but now it dont reset and run with the clock rate I change to.
I used the follow code:
void changeSystemClock( uint8_t clockRate )
{
bool_t dmx32 = 0;
uint8_t drs = 0;
switch(clockRate)
{
case 20:
dmx32 = 0;
drs = 0;
break;
case 24:
ADC0_CFG1 |= ADC_CFG1_ADIV(0);
dmx32 = 1;
drs = 0;
break;
case 40:
dmx32 = 0;
drs = 1;
break;
case 48:
dmx32 = 1;
drs = 1;
break;
case 60:
dmx32 = 0;
drs = 2;
break;
case 72:
dmx32 = 1;
drs = 2;
break;
}
// Configure new core clock
if( dmx32 == 1 )
{
MCG_C4 |= MCG_C4_DMX32_MASK;
}
else
{
MCG_C4 &= ~(MCG_C4_DMX32_MASK);
}
MCG_C4 &= (uint8_t)(~(1<<6));
MCG_C4 &= (uint8_t)(~(1<<5));
MCG_C4 |= MCG_C4_DRST_DRS(drs); // Configure FLL
}
Thanks for your help Mark.
Regards
Eric
Hi Mark,
I solved the problem by setting the drs first to zero and then change to the new value. I dont know why it not worked only with changing the value but now it dont reset and run with the clock rate I change to.
I used the follow code:
void changeSystemClock( uint8_t clockRate )
{
bool_t dmx32 = 0;
uint8_t drs = 0;
switch(clockRate)
{
case 20:
dmx32 = 0;
drs = 0;
break;
case 24:
ADC0_CFG1 |= ADC_CFG1_ADIV(0);
dmx32 = 1;
drs = 0;
break;
case 40:
dmx32 = 0;
drs = 1;
break;
case 48:
dmx32 = 1;
drs = 1;
break;
case 60:
dmx32 = 0;
drs = 2;
break;
case 72:
dmx32 = 1;
drs = 2;
break;
}
// Configure new core clock
if( dmx32 == 1 )
{
MCG_C4 |= MCG_C4_DMX32_MASK;
}
else
{
MCG_C4 &= ~(MCG_C4_DMX32_MASK);
}
MCG_C4 &= (uint8_t)(~(1<<6));
MCG_C4 &= (uint8_t)(~(1<<5));
MCG_C4 |= MCG_C4_DRST_DRS(drs); // Configure FLL
}
Thanks for your help Mark.
Regards
Eric
Hello Eric
You may find some additional information at µTasker MCG Configuration Support
Have you ensured that the flash clock is still vaid when you change frequencies? If a change will cause it to be too high the processor will crash - you need to first set a new value for SIM_CLKDIV1 before changing the MCGOUTCLK frequency in such a case.
Regards
Mark
Kinetis: µTasker Kinetis support
K60: µTasker Kinetis TWR-K60N512 support / µTasker Kinetis TWR-K60D100M support / µTasker Kinetis TWR-K60F120M support
For the complete "out-of-the-box" Kinetis experience and faster time to market
Ok, now I know that the crash is a reset. I looked in the "Reset Control Modul" and found "Reset caused by core LOCKUP event". Why can that happen?
Eric
A lock-up occurs when there is a processor fault but the fault handler also fails.
Eg. you did something that causes a hard faut to occur but you have no fault interrupt to handle it. Or you did something that doesn't allow the processor to operate within specifications.
Normall changing the FLL output frequency in FEE just involves changing its multiplication factors.
You could try moving back to FEI and then changing back to FEE with the new frequency.
Regards
Mark
Kinetis: µTasker Kinetis support
K60: µTasker Kinetis TWR-K60N512 support / µTasker Kinetis TWR-K60D100M support / µTasker Kinetis TWR-K60F120M support
For the complete "out-of-the-box" Kinetis experience and faster time to market
Hallo Mark,
thanks for your response. I can config six clock rates in the initialization ( 20 - 72 Mhz ). All that rates works without problems. There is only a problem when I have initialized a clock rate and than try to change it. When all that rates works when I config it in the beginning, there cant be a problem with flash clock, is it so? Is there anything I have to deactivate in the beginning before I switch rds? I cant find any example for that. The description says I can switch rds on any time when the lp bit is not set. It isnt set and the clock is only change by toggle dmx.
Regards
Eric