Hello everyone,
I am facing an issue when I want to erase or program a flash sector when core frequency is 120MHz on a K22FN512 device, present on a FRDM_K22F board.
I am using KDS_3.0.0, KSDK_1.2.0, C90TFS flash driver and a FRDM_K22F board.
If the core clock is set to 60MHz (flash clock = 24MHz) everything works fine.
But if core clock is set to 120MHz (flash clock = 20MHz), the FlashCommandSequence() function returns with an error code = 0x20 (FTFx_SSD_FSTAT_ACCERR).
I suspect a timing issue but I didn't found anything in the K22F errata document.
I have tried to fing a workaround without success (modifying CCIF loop test).
I even tried to lower core clock during runtime using CLOCK_SYS_UpdateConfiguration() without any success on that flash programming issue.
Of course, I need to have the K22F running at 120MHz due to performance constraints...
Please find attached a little demo program in order to demonstrate this issue.
Is anybody can help ?
Thank you
Original Attachment has been moved to: flash_Test.zip
Solved! Go to Solution.
Maurice
I think that I have just realised what your problem is:
If your code is using the High Speed Run mode it is not possible to work with the Flash.
Although "out-of-specification" for this device it is still possible to run at 120MHz and work with Flash, but probably not recommended for end-products......
Regards
Mark
Hi
I know of no issues with the clock settings and flash programming on the K22 so perhaps the speeds are not as you expect them to be (is the Flash clock set a little too high for example?)
You can also set the Flash clock for 24MHz when the code is operating at 120MHz, in case that helps in some way.
Try a FRDM-K22F object from the links below for comparison - these operate at 120MHz (60MHz bus and 24MHz Flash) and you can program and delete sections of internal flash using commands on the command line - "I/O" menu). The simulation also shows the clock speed that are set by the code in order to avoid uncertainty. In an emergency you can also take its Flash programming interface which work for all K, KL, KE, KEA, KV, KM devices without any porting needs.
Regard
Mark
Kinetis: http://www.utasker.com/kinetis.html
K22: http://www.utasker.com/kinetis/FRDM-K22F.html / http://www.utasker.com/kinetis/TWR-K22F120M.html
For the complete "out-of-the-box" Kinetis experience and faster time to market
:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)
Maurice
I tried with your code and can confirm that it can't erase the Flash due to the stated error.
Your project is running core, bus and flash clocks at all 24MHz (in the code that you attached) and I don't think that it is clock related - I tried adjusting and didn't find any behavioral differences (it always failed).
Then I stepped the Flash erase code, which is OK (there is one "error" in trying to clear the read-only MGSTAT0 flag, but this probably won't actually hurt but instead just be redundant).
I can however tell you how to find the cause, which is probably somewhere in the initialistion (I am thinking about the flash not being accessible by a certain processor mode or similar but I didn't hunt where it was).
1. If you reset the board (stop in the debugger after the reset vector) and do the following you can see that the flash sector can be erased:
- Using the debugger write 0x09 to FTFA_FFCOB0, followed by
- write 0x04 to FTFA_FFCOB0
- write 0x80 to FTFA_FSTATE
Watch the FSTAT value remains at 0x80 (successful operation) [these three commands are actually all that is needed to delete your test sector]
2. Run to the point where your routine would start to do it and repeat. Now you see that it fails with 0xa0 (FSTAT), as the routine also fails.
3. Now repeat the simple test at various points during the initialisation (step through the code and decide when to check). Each time it is successful you can move on until you find where it starts failing. Then home in on the part of the initialisation which causes it until you see exactly what was modified to cause it to subsequently fail.
Once you know the cause you can then decide how best to work around it.
Note however that the code being used operates in Flash and can thus only work (on this processor) with addresses in the second half of the Flash (>= 0x40000). If you need to write/erase in areas lower than this you will need to either use a different module or execute the code in SRAM with interrupts disabled.
Regards
Mark
Maurice
I think that I have just realised what your problem is:
If your code is using the High Speed Run mode it is not possible to work with the Flash.
Although "out-of-specification" for this device it is still possible to run at 120MHz and work with Flash, but probably not recommended for end-products......
Regards
Mark
Hello Mark,
Thank you very much for these explanations and for your time.
It is perfectly clear.
As you can see in the code that I sent, I tried to find a solution using a second clock configuration with Fcore=60MHz and Fflash=20MHz at runtime, before calling flash erase.
Define (USE_CLOCK_SYS_METHOD) at line 49 in os_task.c
I used the CLOCK_SYS_UpdateConfiguration() feature to do that.
But It doesn't work... I've got the same issue on the flash erase.
Do you have any idea about that ? Having Fcore=60MHz, High Speed run should not be enabled...
Best regards,
Maurice
Maurice
I enabled the define but didn't understand the routines being used (they are a bit too complicated for me to follow) but the result looks to be that you still have the PLL (core frequency) set to 120MHz but have the system frequency divided to 60Mhz and bus, flex and flash at 20MHz. Since the core is still 120MHz, high speed run mode would still theoretically be the one to use.
If you check in the SMC_PMCTL register just before you try to work with the flash you can also see that the RUNM is set to 0x3, which is indeed high speed run mode (HSRM). Then an attempt to delete a sector will fail.
If you however add the following line just before trying to write/erase flash it works:
SMC_PMCTRL = 0; // set normal RUN mode
which proves that it is the HSRM that is restricting flash operations.
As noted before, the K22 will operate at 120MHz in RUN mode but it is not specified to do so, meaning that you will either need to temporarily reduce clock speeds and switch to RUN mode when programming or else generally limit the operation to RUN mode (80MHz core, system clock - 40MHz bus clock, 20MHz FlexClock and 26.67MHz flash clock) [Note that the Flash clock is in fact faster than in HSRM].
Regards
Mark
P.S. Note that the default mode is RUN mode after a reset so code is setting it to another state.
After a bit of searching I find the following in system_MK22F51212.c
/* High speed run mode enable */ #if (((SYSTEM_SMC_PMCTRL_VALUE) & SMC_PMCTRL_RUNM_MASK) == (0x03U << SMC_PMCTRL_RUNM_SHIFT)) SMC->PMCTRL = (uint8_t)((SYSTEM_SMC_PMCTRL_VALUE) & (SMC_PMCTRL_RUNM_MASK)); /* Enable HSRUN mode */ while(SMC->PMSTAT != 0x80U) { /* Wait until the system is in HSRUN mode */ } #endif
so it looks to be controlled by SYSTEM_SMC_PMCTRL_VALUE in some way.
Hello Mark,
Yes, you are absolutely right !
I tried to run the core @120MHz in normal RUN MODE and it works fine for flash erase/write (flash frequency = 20MHz)
However, to be sure to stay in the K22F specifications, I apply the following procedure :
- The default running mode is @120MHz HIGH SPEED mode
- I define 2 clock configuration, using PE. One with Fcore=120MHz Fflash=24MHz and the other one with Fcore=60MHz Fflash=20MHz
- Before entering into flash erase/program I do the following :
/* Normal RUN Mode with Fcore=60MHz Fbus=Fflash=20MHz */
SMC_PMCTRL = 0; // set NORMAL running mode
CLOCK_SYS_UpdateConfiguration( 1, kClockManagerPolicyAgreement);
- After erasing and programming the flash
/* HIGH SPEED Mode Fcore=120MHz Fbus=Fflash=24MHz */
SMC_PMCTRL = 0x60; // set HIGH SPEED running mode
CLOCK_SYS_UpdateConfiguration( 0, kClockManagerPolicyAgreement);
So, the clock speed and running mode are only changed during the flash erase/program and the rest of the time, the K22F operates @120MHz in high speed mode.
Thank you very much Mark for helping me to solve that problem.
Best regards,
Maurice
Maurice
To be absolutely correct I think that you should set the RUN mode "after" reducing the speed and not before.
When moving back to the HSRM it is also recommended to wait for the mode to be confiirmed (checking PMSTAT) before continuing with code.
Since the change of the clock speed will also involve some jumps in the operating frequency (in order to change the PLL), as well as a short PLL lock delay each time, you may need to consider when Flash programming/erasure should take place in order to not disrupt other operations (eg. loss of peripheral data due to in accurate clocks).
Regards
Mark
I have seen a new data sheet release (13.10.2015) where the Flash speed in RUN mode shows 26.67MHz so this speed is OK:
Here's an interesting point:
From the K22F120's user's manual as typical option for faster speeds in RUN mode -
From the same devices' data sheet:
Therefore I wouldn't use the recommendation from the user's manual but instead use maxium 20MHz flash clock!
Regards
Mark