Wiriting other half of flash from code

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

Wiriting other half of flash from code

1,026 Views
comsosysarch
Contributor III

K60 chips with part number PK60N512VLQ100

 

I had some code running on three different chips batch marked 0M33Z. Has worked for several motnshs with no changes.

Now we have some chips batch marked 2N30Q.

Same code no longer works on any of the three new devices with that batch marking.

 

Code with the issue happens to be related to writing to upper half of flash while running from lower half of flash.

These are all flash-only devices (ie no flex).

I am disabling flash caching due to the issue with that on the 0M33Z devices. Then I erase the sector containing the flash table, then writing the new table data to the accelerator block in RAM, then commanding the flash controller to write to flash. This gets repeated as often as needed to fill a table.

 

It -seems- to (perhaps) work one time, but never after that. The IAR debugger leaves much to be desired for this sort of thing but that would be a whole other story.

 

Any ideas based on what changed in the device between those chip batches?

 

0 Kudos
4 Replies

427 Views
comsosysarch
Contributor III

It looks like I am getting a read collision error on the new chips.

 

FTFL Read Collision Error Flag
The RDCOLERR error bit indicates that the MCU attempted a read from an FTFL resource that was being
manipulated by an FTFL command (CCIF=0). Any simultaneous access is detected as a collision error by
the block arbitration logic. The read data in this case cannot be guaranteed. The RDCOLERR bit is
cleared by writing a 1 to it. Writing a 0 to RDCOLERR has no effect.
0 No collision error detected
1 Collision error detected

 

Not sure how. Here is the code that is executing when the error occurs. It is directly out of the FRM flowchart.

bool ftflErsScr(UInt32 flAddr){ if(flAddr & 0xff000007)  return false; if(flAddr < 0x00040000 || flAddr > 0x0007ffff)  return false; 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 = 0x09; // erase sector 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->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}bool ftflPgmSec(UInt32 flAddr, UInt16 num64s){ if(flAddr & 0xff000007)  return false; if(num64s == 0)  return false; if(flAddr < 0x00040000 || flAddr > 0x0007ffff)  return false; 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}

The erase sector command works fine every time. But the program section generates the read collision while in the last loop waiting for the CCIF bit to be set indicating the completion of the operation.

 

The routine is around flash address 0x15ac2 (lower half). The flash table being programmed is at 0x40000 or 0x50000 (upper half).

 

0 Kudos

427 Views
comsosysarch
Contributor III

The following is in the 2N30D errata. Maybe a new problem in something that used to work on 0M33Z?

 

e2596: EzPort and FTFL: The 64-bit flash programming command PGMSEC is not fully
implemented.
Errata type: Errata
Description: The 64-bit flash programming command PGMSEC is not fully implemented. The command can
be used by flash programming algorithms and is used by the EzPort serial flash programming
interface.
Workaround: Use the 32-bit flash programming command PGM4 in flash programming algorithms until the
PGMSEC command is fully supported. Do not use the EzPort module until PGMSEC is fully
supported.

 

If so, do I just need to use PGM4 instead?

 

0 Kudos

427 Views
comsosysarch
Contributor III

Apparently, yes. Thanks. Disregard thread unless someone else runs into this problem.

Aggravating though that something which used to work on older silicon is now busted.

 

0 Kudos

427 Views
egoodii
Senior Contributor III

Refer also to my thread:

https://community.freescale.com/message/94076#94076

Flash bank/swap operations were significantly changed over the silicon revs.

 

--ERGII

0 Kudos