FLASH1_LDD unexpected behavior

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

FLASH1_LDD unexpected behavior

997 Views
tallxcrunner
Contributor II

I have noticed a few strange things happen when trying to modify flash with Flash_LDD functions. I tried using the interrupt enabled, then polling, and got the same results.

Write:

It appears as though I can only write to each address one time. Attempting another write to the same location twice will cause "DataWrittenFlg" to never clear, and the processor gets stuck in an infinite loop.

Erase:

I have an instruction to clear 0x1FE28 (size 0x1C bytes). I have found that this wipes out data that I've written to 0x1FE14 - 0x1FE27. This is strange because I have another command that seems to work elsewhere, that erases 0x1FE00 - 0x1FEA0.

I wrote "write" and "erase" functions that use a self written macro called "wait_for_flash()". These are pasted below. The only way I could get write and erase to work was to disable the watchdog because it couldn't be fed long enough to get through the erase step.

LDD_TError flash_write(LDD_TDeviceData *DeviceDataPtr, LDD_TData *FromPtr, LDD_FLASH_TAddress ToAddress, LDD_FLASH_TDataSize Size) {
DataWrittenFlg = FALSE;
WDog1_Disable(MyWDog1Ptr);
Error = FLASH1_Write(DeviceDataPtr, FromPtr, ToAddress, Size);
if(Error == ERR_OK) {
wait_for_flash();
}
WDog1_Enable(MyWDog1Ptr);
return Error;
}

LDD_TError flash_erase(LDD_TDeviceData *DeviceDataPtr, LDD_FLASH_TAddress FromAddress, LDD_FLASH_TDataSize Size) {
WDog1_Disable(MyWDog1Ptr);
DataWrittenFlg = FALSE;
Error = FLASH1_Erase(DeviceDataPtr, FromAddress, Size);
if(Error == ERR_OK) {
wait_for_flash();
}
WDog1_Enable(MyWDog1Ptr);
return Error;

void wait_for_flash(void) {
while(!DataWrittenFlg) {
FLASH1_Main(MyFLASH_Ptr);
}
flashOpStatus = FLASH1_GetOperationStatus(MyFLASH_Ptr);
if ((flashOpStatus == LDD_FLASH_FAILED)) {
Error = ERR_FAILED;
error_code_6205 = 0x6205;
}
}

Using KDS 3.2 (although condition persists in other versions.) for a KEA128 processor.

Labels (1)
0 Kudos
4 Replies

655 Views
mjbcswitzerland
Specialist V


Hi David

The KEA Flash needs to be written as long words and you can't write again to a long word that has already been programmed without first erasing the sector that it is in. Doing so can also damage the Flash due to over-programing. Beware also that you have set up the programming time correctly to suit the bus clock rate used.

The smallest entity when erasing is a sector, which is 512 bytes in size in the KE parts.

A sector erase takes about 5ms but can increase with device age to 15x that. If your watchdog fires it may be that the watchog timeout is set too short. Beware that there is typically an error in the KE and KEA user's manuals about setting the watchog value since it shows the timeout register as little-endian whereby it is in in fact big-endian so the bytes may be swapped to give unexpected short timeouts.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html
Kinetis KEA128:
- http://www.utasker.com/kinetis/TRK-KEA128.html
- http://www.utasker.com/kinetis/FRDM-KEAZ128Q80.html
S32 Design Studio: http://www.utasker.com/kinetis/compilers.html#S32

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

0 Kudos

655 Views
tallxcrunner
Contributor II

Ok, I suspected that I might need to erase a full sector, but I wanted to make sure.

My procedure will then be:

1.) flash read sector into an array

2.) erase sector (which I would write in as 0x1FE00, size 0x200, even though I only need to erase 0x1FE28, size 0x1C)

3.) edit array with new data at desired addresses

4.) flash write full sector from modified array.

As far as programming time, is that something I can set using the FLASH1_LDD component options or do I need to do it manually in the code?

Thanks for the information about the sector timing. That would have been likely to cause a headache later. I'll increase the watchdog timeout since I technically would rather not disable it during flash operations.

I will let you know if these issues are resolved tomorrow.

0 Kudos

655 Views
mjbcswitzerland
Specialist V

David

I don't know the FLASH1_LDD method and what it supports. I use the methods in the uTasker project that include a fail safe parameter system that is compatible with all Kinetis Flash types: http://www.utasker.com/docs/uTasker/uTaskerFileSystem_3.PDF

Its flash driver (for all Kinetis Flash types, parameter system and external SPI Flash) is attached as reference.

In the uTasker project the flash is simulated so complete projects can be tested in Visual Studio and the simulator would inform of any incorrect usage so that HW issues are not encountered later on the real HW.

Regards

Mark

P.S. Your technique for modifying data is correct but has the risk that a reset/power loss during the process will lose or corrupt the data.

0 Kudos

655 Views
tallxcrunner
Contributor II

Hi Mark,

I will look into using uTasker in the future. For now, it's a long story, but I finally got everything working. If I get time later, I'll post my functions for read/write/erase because I feel that it is not well explained how to use FLASH_LDD. Here are the key points:

1.) The solution I figured out only seemed to work when FLASH_LDD was running with interrupts enabled, indicating that the flash operation was finished. It crashed when using polling, although it's possible that I wasn't using it correctly.

2.) To overwrite existing flash data, you have to read the full sector (0x200) into a RAM variable, erase the full sector (0x200), modify the RAM variable with the updated data, then write to the full sector (0x200).

Thanks for your help Mark!

-Dave

0 Kudos