Section programming (PGMSEC) on K66 fails

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

Section programming (PGMSEC) on K66 fails

675 Views
ajuc
Contributor I

Hello,

I am attempting to write data in the P-flash of my K66FX (MK66FX1M0VMD18) controller. However it sometimes fails with an ACCERR without apparent reason...

My code is running in the first block of the P-flash and I am attempting to write to the second block. The commands to erase the sector where the data will be written (ERSSRC) and to make the FlexRAM available as RAM (SETRAM) both complete successfully. All the P-flash is currently unprotected.
Here is some sample code to make it easier to understand:

const uint32_t address = 0xA0000UL;
// Fill up data to be written
uint8_t data[0x800U];
for(uint16_t i = 0U; i < sizeof(data); ++i) {
    data[i] = (uint8_t)(i & 0xFFU);
}

// Erase
FTFE->FCCOB0 = 0x09U; // ERSSCR
FTFE->FCCOB1 = (uint8_t)((address >> 16U) & 0xFFU);
FTFE->FCCOB2 = (uint8_t)((address >> 8U) & 0xFFU);
FTFE->FCCOB3 = (uint8_t)(address & 0xFFU);
FTFE->FSTAT = 0x80U;
while((FTFE->FSTAT & 0x80U) == 0U) {
    // Wait for the command to complete
}

// Set the FlexRAM function
FTFE->FCCOB0 = 0x81U; // SETRAM
FTFE->FCCOB1 = 0xFFU;
FTFE->FSTAT = 0x80U;
while((FTFE->FSTAT & 0x80U) == 0U) {
    // Wait for the command to complete
}

// Copy the data to be written into FlexRAM
volatile uint8_t *flexram_address = (volatile uint8_t *)0x14000000UL;
for(uint16_t i = 0U; i < sizeof(data); ++i) {
    flexram_address[i] = data[i];
}
// Write
FTFE->FCCOB0 = 0x0BU; // PGMSEC
FTFE->FCCOB1 = (uint8_t)((address >> 16U) & 0xFFU);
FTFE->FCCOB2 = (uint8_t)((address >> 8U) & 0xFFU);
FTFE->FCCOB3 = (uint8_t)(address & 0xFFU);
FTFE->FCCOB4 = (uint8_t)(((sizeof(data) / 8U) >> 8U) & 0xFFU);
FTFE->FCCOB5 = (uint8_t)((sizeof(data) / 8U) & 0xFFU);
FTFE->FSTAT = 0x80U;
while((FTFE->FSTAT & 0x80U) == 0U) {
    // Wait for the command to complete
    // It will complete with ACCERR
}

Reducing the size of the data to write to 512 bytes will make the command succeed. However, according to the manual, it should be possible to write up to 1kB. Also, attempting to write 512 bytes at another location, for example 0xA0C40, fails as well. Even though this address is aligned to 128-bits and the sector boundary is not exceeded...

 

Am I missing something or have you already experienced a similar problem?

Labels (1)
Tags (1)
0 Kudos
2 Replies

649 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

Hello ajuc

 

If the swap system is enabled, the swap indicator address in each program flash block is implicitly protected from sector erase unless the swap system is in the UPDATE or UPDATE-ERASED state and the program flash sector containing the swap indicator address being erased is in the non-active block.

 

Also, applying voltages to the I/O when the processor is not powered can lead to corruption of flash contents, corruption of flash control logic, or corruption of device configuration and trim values which in turn can lead the processor reporting as secured or failure the processor to respond to and complete flash commands.

 

Let me know if this is helpful, if you have more questions do not hesitate to ask me.

Best Regards,

Omar

0 Kudos

618 Views
ajuc
Contributor I

Hello Omar,

Thank you for your reply.

From what I understand, the swap features are not available on this processor...

 

Meanwhile I've found the solution to my problem. I was using sizes in phrases instead of double-phrase... When preparing the PGMSEC command, the assignments to FCCOB4 and FCCOB5 should be:

 

FTFE->FCCOB4 = (uint8_t)(((sizeof(data) / 16U) >> 8U) & 0xFFU);
FTFE->FCCOB5 = (uint8_t)((sizeof(data) / 16U) & 0xFFU);

 

 

Also, as a side-note, the two P-flash blocks do not seem to be fully decoupled. I've imroved my code to remove the active wait for the CCIR bit. This resulted in sometimes running in read collision errors (RDCOLERR) when attempting to read data too early (even though the CCIR bit was set when starting the command). Also when performing several write operations successively, some write operations were being skipped. I could fix this by running my entire software from RAM.

0 Kudos