Hi Pauli
Probably the firmware is expecting the 50MHz oscillator input from the PHY and so will wait forever for the input signal to "become valid". The code doing this will be running from the default clock.
You can use the HIRC (internal 48MHz oscillator) as PLL reference to generate the same 120MHz core frequency instead.
If your environment is not flexible you can use the following code (taken from the uTasker project for FRDM-K64F, which supports all possible configurations). You will need to be aware of a chip errata in older K64s that require the USB controller to be enabled too in order for the HIRC to work (workaround also shown below).
MCG_C7 = MCG_C7_OSCSEL_IRC48MCLK; // route the IRC48M clock to the external reference clock input (this enables IRC48M)
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
MCG_C1 = (MCG_C1_IREFS | MCG_C1_CLKS_EXTERN_CLK); // switch IRC48M reference to MCGOUTCLK
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTERN_CLK) { // wait until the new source is valid (move to FBI using IRC48M external source is complete)
// Older K64 devices require the IRC48M to be switched on by the USB module
if (++iIRC48M_USB_control >= IRC48M_TIMEOUT) { // if the switch-over is taking too long it means that the clock needs to be enabled in the USB controller
POWER_UP_ATOMIC(4, USBOTG); // power up the USB controller module
USB_CLK_RECOVER_IRC_EN = (USB_CLK_RECOVER_IRC_EN_REG_EN | USB_CLK_RECOVER_IRC_EN_IRC_EN); // the IRC48M is only usable when enabled via the USB module
}
}
// We are presently running directly from the IRC48MCLK and have also determined whether a K64 is an older or newer device (with IRC48M independent from the USB module)
MCG_C1 = (MCG_C1_CLKS_EXTERN_CLK | MCG_C1_FRDIV_1280); // switch the external clock source also to the FLL to satisfy the PBE state requirement
MCG_C5 = ((CLOCK_DIV - 1) | MCG_C5_PLLSTEN0); // PLL remains enabled in normal stop modes
MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS); // complete PLL configuration and move to PBE
while ((MCG_S & MCG_S_PLLST) == 0) {} // loop until the PLLS clock source becomes valid
while ((MCG_S & MCG_S_LOCK) == 0) {} // loop until PLL locks
MCG_C1 = (MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_1024); // finally move from PBE to PEE mode - switch to PLL clock
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) {} // loop until the PLL clock is selected
The actual register values (if the defines are not understandable) to run at 120MHz core, 60MHz bus and 24MHz flash clock (see uTasker FRDM_K64F simulation below) are:
MCG_C7 = 0x02;
SIM_CLKDIV1 = 0x01240000;
MCG_C1 = 0x84;
// wait until the new source is valid (move to FBI using IRC48M external source is complete)
MCG_C1 = 0xb0;
MCG_C5 = 0x33;
MCG_C6 = 0x5a;
// loop until the PLLS clock source becomes valid
// loop until PLL locks
MCG_C1 = 0x28;
// loop until the PLL clock is selected
I have also attached a FRDM-K64F binary that you can load to the board in case you need to reverse engineer on the board. It has a command line interface on the VCOM UART and on the K64's USB (USB-CDC) and there are low power menus in the "administrator" menu in case you would like to check the power consumption possible in the various modes based on this clock configuration.
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
Kinetis K64:
- http://www.utasker.com/kinetis/FRDM-K64F.html
- http://www.utasker.com/kinetis/TWR-K64F120M.html
- http://www.utasker.com/kinetis/TEENSY_3.5.html
- http://www.utasker.com/kinetis/Hexiwear-K64F.html
MCG module: http://www.utasker.com/kinetis/MCG.html
Low Leakage Modes: http://www.utasker.com/kinetis/LLWU.html
Free Open Source solution: https://github.com/uTasker/uTasker-Kinetis
Working project in 15 minutes video: https://youtu.be/K8ScSgpgQ6M
Professional Kinetis support, one-on-one training and complete fast-track project solutions: http://www.utasker.com/support.html
