AnsweredAssumed Answered

MK60DN512VLQ10 4N30D flash program section command still not working?

Question asked by comsosysarch on May 7, 2012
Latest reply on Sep 27, 2013 by Klayton Jones

Freescale indicates the issue with the MK60DN512VLQ10 flash program section (PGMSEC, 0x0b) command (it would actually be rejected on 2N30D v1.2 silicon) has been fixed on 4N30D v1.4 silicon.

 

On the v1.4 devices I am working with I am still having trouble with this command. Mind you I had no problems with the same code on v1.0. The problem now is not that the command is rejected, but rather the command never completes and the processor remain stuck in an endless loop waiting for the FTFL FSTAT register CCIF bit. This has been on multiple devices and I have not seen any actually work yet.

 

I guess what I am asking is if anyone else has had this issue or do I just have a code bug or maybe a bad batch of chips?

 

To that end, here is my flash writing code (always called after a successful erase)...

 

bool ftflPgmSec(UInt32 flAddr, UInt16 num64s)
{
    if(flAddr & 0xff000007)
        return false;
    if(num64s == 0)
        return false;
    if(flAddr < 0x00040000 || flAddr > 0x0007ffff)
        return false;
#ifdef SI_2N30D_PGMSEC_PROBLEM {  UInt32 subWrAddr, subRdAddr;  for(subWrAddr = flAddr, subRdAddr = 0x14000000; subWrAddr < flAddr + 8 * num64s; subWrAddr += 4, subRdAddr += 4)  {   while(!(FTFL_BASE_PTR->FSTAT & FTFL_FSTAT_CCIF_MASK)); // wait for any previous command to complete (required to proceed)   if(FTFL_BASE_PTR->FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK)) // check for previous command error flags    FTFL_BASE_PTR->FSTAT = (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK); // write 1 to clear error flags (required to proceed)   FTFL_BASE_PTR->FCCOB0 = 0x06; // program longword command   FTFL_BASE_PTR->FCCOB1 = (UInt08)((subWrAddr & 0x00ff0000) >> 16);   FTFL_BASE_PTR->FCCOB2 = (UInt08)((subWrAddr & 0x0000ff00) >> 8);   FTFL_BASE_PTR->FCCOB3 = (UInt08)(subWrAddr & 0x000000fc);   FTFL_BASE_PTR->FCCOB4 = *((UInt08 *)subRdAddr + 3);   FTFL_BASE_PTR->FCCOB5 = *((UInt08 *)subRdAddr + 2);   FTFL_BASE_PTR->FCCOB6 = *((UInt08 *)subRdAddr + 1);   FTFL_BASE_PTR->FCCOB7 = *((UInt08 *)subRdAddr + 0);   FTFL_BASE_PTR->FSTAT = FTFL_FSTAT_CCIF_MASK; // write 1 to clear flag (executes command)   while(!(FTFL_BASE_PTR->FSTAT & FTFL_FSTAT_CCIF_MASK)); // wait for command to complete   if(FTFL_BASE_PTR->FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_MGSTAT0_MASK)) return false; // return command error flag status  }  return true; }#else while(!(FTFL_BASE_PTR->FSTAT & FTFL_FSTAT_CCIF_MASK)); // wait for any previous command to complete (required to proceed) if(FTFL_BASE_PTR->FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK)) // check for previous command error flags  FTFL_BASE_PTR->FSTAT = (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK); // write 1 to clear error flags (required to proceed) FTFL_BASE_PTR->FCCOB0 = 0x0b; // program section command FTFL_BASE_PTR->FCCOB1 = (UInt08)((flAddr & 0x00ff0000) >> 16); FTFL_BASE_PTR->FCCOB2 = (UInt08)((flAddr & 0x0000ff00) >> 8); FTFL_BASE_PTR->FCCOB3 = (UInt08)(flAddr & 0x000000f8); FTFL_BASE_PTR->FCCOB4 = (UInt08)(num64s >> 8); FTFL_BASE_PTR->FCCOB5 = (UInt08)(num64s & 0x00ff); FTFL_BASE_PTR->FSTAT = FTFL_FSTAT_CCIF_MASK; // write 1 to clear flag (executes command) while(!(FTFL_BASE_PTR->FSTAT & FTFL_FSTAT_CCIF_MASK)); // wait for command to complete return((FTFL_BASE_PTR->FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_MGSTAT0_MASK)) == 0); // return command error flag status#endif
}

 

Outcomes