//Function running from flashvoid upgrade_flash(*flash_array, length){//Wait for flash to be readywhile (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}//Erase the flashFTFE_FCCOB0 = 0x44;FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}address = 0;while(length > 0) {//Read 8 bytes from flash_array at a time, run command to write the bytes to flashFCCOB0 = 0x7//Load address (64 bit alligned) onto FCCOB1, FCCOB2, FCCOB3;//Load 8 bytes of data onto FCCOB4 to FCCOBBFTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}length -=8address += 8flash_array += 8}REBOOT device.}
void upgrade_flash(*flash_array, length){//Wait for flash to be readywhile (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);//Erase the flashwhile(1) {FTFE_FCCOB0 = 0x44;FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);if (!(FTFE_FSTAT & FTFE_FSTAT_MGSTAT0_MASK))break;}address = 0;while(length > 0) {while (1) {//Read 8 bytes from flash_array at a time, run command to write the bytes to flashFCCOB0 = 0x7Load address (64 bit alligned) onto FCCOB1, FCCOB2, FCCOB3;Load 8 bytes of data onto FCCOB4 to FCCOBBFTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);if (!(FTFE_FSTAT & FTFE_FSTAT_MGSTAT0_MASK))break;}length -=8address += 8flash_array += 8}REBOOT device.}
My main concern is, what is the correct way to handle runtime errors reported by MGSTAT0 bit? My new approach is just attempting to re run the command if it occurs. But, the documentation says that we cannot reprogram the same addresses without erase. But there is no command to erase just 8 bytes. Does that mean that we need to erase the complete block and start over again? Also, does checking the 3 error flags guarantee that the data was programmed correctly? Or should I read 1's and 0's using the block read commands at the end or programming the complete flash.
My goal is to make a failure proof procedure. Execution time is not that big a concern. A few minutes of program time is expected. Accuracy is more important, so that device can be upgraded without fear of corruption.
To my knowledge, based on past NXP comments, full or block erase are the only option, byte/word level is not.
"But there is no command to erase just 8 bytes. Does that mean that we need to erase the complete block and start over again?"
Yes. I've been warned about just erasing a few bytes in the past. It seems to have to do with wear leveling.
"Or should I read 1's and 0's using the block read commands at the end or programming the complete flash."
Yes, however, reading back flash right after it is written, not just these devices, is no guarantee of long term viability. Flash works with floating gate charges. A fresh write recharges the gate. It tells nothing about the viability or degradation of the gate over time. It may hold its charge for minutes or decades.
Something that reads fine at room temperature may fail to read at a higher temperature etc.
If you part has CRC ability in hardware that may be a faster option. That does not solve the gate charge issue.
Rereading does solve your immediate problem of did the product get programmed successfully.
If this issue is happening often, I'd look for things like questionable power supplies or reset circuits.