I have been experimenting with changing clock modes using SDK demo applications that I have adapted to the KBOOT flash resident bootloader (Version 2.0.0). In it's simplest form, I used the K22FN512xxx12_application_0xA000.icf linker file, startup.c, startup.h, crt0.s, from the led_demo project of the KBOOT .zip in order to adapt the gpio_led_output project from SDK 2.3.1. In my current application changes to the bootloader are not possible, any workaround must be in the application code.
With no other modifications to the code I am able to successfully bootload the application most of the time. Frequently enough to be a problem, the application doesn't boot. And using blhost the FRDM board is not communicable, i.e. not in KBOOT. I can reconnect with KBOOT after a reset. The application will also launch after the default 5 second timeout after 1 to Many resets. When the application fails to boot correctly I use the debugger and IAR's "Attach to Running Target" to see what state the uC is in. I am seeing the clock initialization of the application fail and spin here:
while((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt)))
{
}
By looking at the MCG registers I can confirm that the IREFST bit in MCG_S is not changing as expected. And I can confirm that I have not seen a hang elsewhere.
I have a couple observations that I made based on some information gleaned from the discussion here and here.
My comments on the aforementioned is as follows:
I have also tried replacing the while loop with and if statement and returns kStatus_Fail in order for me to retry, setting the clocks, this just causes a hang at the external loop.
Interestingly, using the pee_blpi demo from the SDK without adapting, I can make the transition from FEI to FBE just fine, and have not seen the issue recreated, even when attempting to re-create the issue. Further to this, taking the application I did adapt for bootloading and solely running that on the eval board without KBOOT I have also yet to see it fail. However as soon as I start playing with the clocks before the BOARD_BootClockHSRUN call I can cause it to fail, but only in the adapted application.
Is there a workaround to this?
After reviewing Kevin Luty's solution and e7993 I believe that when these hangups occur the system clock frequency is exceeded when KBOOT transitions from FEE to FEI even if the processor continues to run and jump to application. Since the clock frequency is not predictable unless it is handled properly (I had assumed that it was fixed as per Bryan Cole's post, it still isn't in KBOOT 2.0.0), it would be very possible to not exceed the system clock frequency and thus not have any problem, however it is also possible to exceed it and have problems.
Taking this idea, I tried to re-put the clock into FEI mode (i.e. a FEI -> FEI transition) within the application using just some standard values, let it run overnight and when I checked on it in the morning, it had spent all night rebooting and running the application correctly. It would seem to me that if the system clock frequency is exceeded this puts the MCG into a state where it can not transition between external and internal reference. This seems to be a solution that can be implemented inside the bootloaded application in the instance you can not change the bootloader code.
Testing in a more complex application shows me this not to work 100%. Bummer.
Hi Terry
Baring potential erratas, the MCG operation is quite logical (it is simpler to view it as simply switch paths rather than the PEE, PBE, etc. states since they are in fact just common-sense settings that can be moved between without losing the clock). See http://www.utasker.com/kinetis/MCG.html for a practical overview.
Also check that the output clock values are always within specification to avoid momentary transitions that are out-of-spec. and could cause randomness.
Basically remember that when a transition is not taking place (stuck) it is because the requirements for the transiting are not met (eg. the HW won't set switches if the sources are not available), therefore look at the 'requirements' for the move/switch and investigate what could lead to that causing the dead-lock.
Regards
Mark
uTasker developer and supporter (+5'000 hours experience on +60 Kinetis derivatives in +80 product developments)
Kinetis: http://www.utasker.com/kinetis.html