CANNOT erase flash for MPC5748G

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

CANNOT erase flash for MPC5748G

3,651 Views
happy_larry
Contributor II

Dear All,

 

When I use the below test code to erase flash, write flash, then erase flash again, something wrong may occurs.

I could write the data well.

However I CANNOT to erase the flash.

Could someone help me?

 

void bl_flash_test(void)

{

        //unlock mid block 0x00FB_8000 - 0x00FB_FFFF

        C55FMC.LOCK0.R &= 0xFFFFFDFF;

   

        //erase the mid block

        C55FMC.MCR.B.ERS = 1;

        C55FMC.SEL0.R = 0x00000200; //select the mid block

        *(unsigned int*)0x00FB8000 = 0xFFFFFFFF;    //interlock write

        C55FMC.MCR.B.EHV = 1;

        while(C55FMC.MCR.B.DONE == 0);

        C55FMC.MCR.B.EHV = 0;

        C55FMC.MCR.B.ERS = 0;

   

        //program one page in the mid block  This part can work well. Data is wrote to flash.

        C55FMC.MCR.B.PGM = 1;

        *(unsigned int*)0x00FB8000 = 0x11111111;    //interlock write

        *(unsigned int*)0x00FB8004 = 0x22222222;   

        *(unsigned int*)0x00FB8008 = 0x33333333;

        *(unsigned int*)0x00FB800C = 0x44444444;

        *(unsigned int*)0x00FB8010 = 0x55555555;

        *(unsigned int*)0x00FB8014 = 0x66666666;

        *(unsigned int*)0x00FB8018 = 0x77777777;

        *(unsigned int*)0x00FB801C = 0x88888888;              

        C55FMC.MCR.B.EHV = 1;

        while(C55FMC.MCR.B.DONE == 0);

        C55FMC.MCR.B.EHV = 0;

        C55FMC.MCR.B.PGM = 0;

 

 

        //erase the mid block     This part CANNOT work wll. The data after 0x00FB8004 is still store in flash.

        C55FMC.MCR.B.ERS = 1;

        C55FMC.SEL0.R = 0x00000200; //select the mid block

        *(unsigned int*)0x00FB8000 = 0xFFFFFFFF;    //interlock write

        C55FMC.MCR.B.EHV = 1;

        while(C55FMC.MCR.B.DONE == 0);

        C55FMC.MCR.B.EHV = 0;

        C55FMC.MCR.B.ERS = 0;

}

Labels (1)
11 Replies

2,069 Views
happy_larry
Contributor II

Dear Lukas,

We have solve the problem with your help!

Thanks very much!

2,069 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

it looks like it is caused by cache. Try to disable the cache in this way to see if it works:

void DCACHE_Disable(void)

{

    asm("mfspr r3,L1CSR0");

    asm("e_lis r4,0xFFFF");

    asm("e_add16i r4,r4,0xFFFE");

    asm("se_and r3,r4");

    asm("mtspr L1CSR0,r3");

    asm("se_isync");

}

If it is really the root cause, there are following solutions:

- disable the cache as shown above

- invalidate whole cache after erase/program operation

- invalidate just the affected area line by line

- configure required area as non-cacheable using SMPU module

Regards,

Lukas

0 Kudos

2,069 Views
happy_larry
Contributor II

Dear Lukas,

We found another phenomenon. After we read a flash memory, we cannot erase it at all.

Is it the same reason as your described?

And do you have the read sample code for MPC5748G?

The read code is attached below.

bl_ret_t bl_flash_read(bl_uint32_t address, bl_uint16_t length, bl_uint8_t * buffer)

{

    bl_uint32_t data_count;

    bl_uint8_t * p_read = (bl_uint8_t *)address;

    for(data_count = 0u; data_count < length; data_count++)

    {

        buffer[data_count] = p_read[data_count];

    }

    return BL_ERR_OK;

}

0 Kudos

2,069 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

S32DS uses different syntax (I used Green Hills MULTI IDE), so let's try:

void DCACHE_Disable(void)

{

    asm("mfspr %r3,1010"); //L1CSR0

    asm("e_lis %r4,0xFFFF");

    asm("e_or2i %r4,0xFFFE");

    asm("se_and %r3,%r4");

    asm("mtspr 1010,%r3"); //L1CSR0

    asm("se_isync");

}

L1CSR0 is described in core reference manual:

http://www.nxp.com/files/32bit/doc/ref_manual/e200z4RM.pdf

S32DS does not know symbolic L1CSR0, so it is necessary to use SPR number which is 1010 in this case.

I have shared two examples here:

Example MPC5748G Flash RW

Example MPC5748G Flash RW SSD

I think that example for read operation is not really necessary. Just read the memory via pointer as usual. There' s nothing special.

I guess that all these troubles are caused by cache. Please give this a try and let me know.

Lukas

2,069 Views
casian
Contributor II

Hello. I must mention that the following code is for S32 MPC5744P

For me, only the following worked, I am not sure why though.

void CACHE_Disable(void) {
   // # Instruction cache (I-CACHE)
   asm("e_lis %r5,0x2"); // Start instruction cache invalidation and disable
   asm("mtspr 1010,%r5"); // Set L1CSR1.ICINV & ICE bits

   // # Data cache (D-CACHE)
   asm("e_li %r5, 0x3"); // Start data cache invalidation and disable
   asm("mtspr 1010, %r5"); // Set L1CSR0.DCINV & DCE bits
}

With this, I am able to erase, program, and reprogram the flash memory.

The following is my flash erase and program function:

void blahblah(void){

       // 0x010C0000--0x010FFFFF - partition 6 - LOCK2/SEL0 bit 28

       C55FMC.LOCK2.R &= 0b11111111111111111111111111110111;

       // Erase the large block
        C55FMC.MCR.B.ERS = 1;
        C55FMC.SEL0.R = 0b11111111111111111111111111110111; // Select the large block
       *(unsigned int*)(0x010C0000) = 0xFFFFFFFF; // Interlock write

       C55FMC.MCR.B.EHV = 1;
       while(C55FMC.MCR.B.DONE == 0);
       C55FMC.MCR.B.EHV = 0;
       C55FMC.MCR.B.ERS = 0;

       // Program one page in the large block
       C55FMC.MCR.B.PGM = 1;
       *(unsigned int*)(0x010C0000) = 0x11111111; // Interlock write
       *(unsigned int*)(0x010C0000+4) = 0x22222222; // Up to 8 words (one 256bit page) can be programmed at once
       C55FMC.MCR.B.EHV = 1;
       while(C55FMC.MCR.B.DONE == 0);
       C55FMC.MCR.B.EHV = 0;
       C55FMC.MCR.B.PGM = 0;

}

This https://www.nxp.com/docs/en/application-note/AN4939.pdf helped me a lot. The "3.6 Enable caches" section.

This may be useful too:

/******************************************************************************/
/* Flash blocks on MPC5748G, compatible with MPC5744P too:   
; Low address space

0x00404000--0x00407FFF /INFO "BAF (read only)"
0x00610000--0x0061FFFF /INFO "HSM code"
0x00620000--0x0062FFFF /INFO "HSM code"

0x00F8C000--0x00F8FFFF - partition 0 - LOCK0/SEL0 bit 15
0x00FC0000--0x00FC7FFF - partition 0 - LOCK0/SEL0 bit 13
0x00FC8000--0x00FCFFFF - partition 0 - LOCK0/SEL0 bit 12
0x00FD0000--0x00FD7FFF - partition 1 - LOCK0/SEL0 bit 11
0x00FD8000--0x00FDFFFF - partition 1 - LOCK0/SEL0 bit 10
0x00FE0000--0x00FEFFFF - partition 0 - LOCK0/SEL0 bit 09
0x00FF0000--0x00FFFFFF - partition 1 - LOCK0/SEL0 bit 07

; Mid address space

0x00F90000--0x00F93FFF - partition 2 - LOCK0/SEL0 bit 31
0x00F94000--0x00F97FFF - partition 2 - LOCK0/SEL0 bit 30
0x00F98000--0x00F9BFFF - partition 2 - LOCK0/SEL0 bit 29
0x00F9C000--0x00F9FFFF - partition 2 - LOCK0/SEL0 bit 28
0x00FA0000--0x00FA3FFF - partition 3 - LOCK0/SEL0 bit 27
0x00FA4000--0x00FA7FFF - partition 3 - LOCK0/SEL0 bit 26
0x00FA8000--0x00FABFFF - partition 3 - LOCK0/SEL0 bit 25
0x00FAC000--0x00FAFFFF - partition 3 - LOCK0/SEL0 bit 24
0x00FB0000--0x00FB7FFF - partition 2 - LOCK0/SEL0 bit 23
0x00FB8000--0x00FBFFFF - partition 3 - LOCK0/SEL0 bit 22

; High address space

0x00F80000--0x00F83FFF /INFO "HSM data"
0x00F84000--0x00F87FFF /INFO "HSM data"

; Large (256k) address space
0x01000000--0x0103FFFF - partition 6 - LOCK2/SEL0 bit 31
0x01040000--0x0107FFFF - partition 6 - LOCK2/SEL0 bit 30
0x01080000--0x010BFFFF - partition 6 - LOCK2/SEL0 bit 29
0x010C0000--0x010FFFFF - partition 6 - LOCK2/SEL0 bit 28
0x01100000--0x0113FFFF - partition 6 - LOCK2/SEL0 bit 27
0x01140000--0x0117FFFF - partition 6 - LOCK2/SEL0 bit 26
0x01180000--0x011BFFFF - partition 6 - LOCK2/SEL0 bit 25
0x011C0000--0x011FFFFF - partition 6 - LOCK2/SEL0 bit 24
0x01200000--0x0123FFFF - partition 7 - LOCK2/SEL0 bit 23
0x01240000--0x0127FFFF - partition 7 - LOCK2/SEL0 bit 22
0x01280000--0x012BFFFF - partition 7 - LOCK2/SEL0 bit 21
0x012C0000--0x012FFFFF - partition 7 - LOCK2/SEL0 bit 20
0x01300000--0x0133FFFF - partition 7 - LOCK2/SEL0 bit 19
0x01340000--0x0137FFFF - partition 7 - LOCK2/SEL0 bit 18
0x01380000--0x013BFFFF - partition 7 - LOCK2/SEL0 bit 17
0x013C0000--0x013FFFFF - partition 7 - LOCK2/SEL0 bit 16
0x01400000--0x0143FFFF - partition 8 - LOCK2/SEL0 bit 15
0x01440000--0x0147FFFF - partition 8 - LOCK2/SEL0 bit 14
0x01480000--0x014BFFFF - partition 8 - LOCK2/SEL0 bit 13
0x014C0000--0x014FFFFF - partition 9 - LOCK2/SEL0 bit 12
0x01500000--0x0153FFFF - partition 9 - LOCK2/SEL0 bit 11
0x01540000--0x0157FFFF - partition 9 - LOCK2/SEL0 bit 10
*/

Thank you for the useful information. I really appreciate it.

0 Kudos

2,069 Views
casian
Contributor II

I have encountered a problem though.

I am trying to erase an entire block of memory, from 0x00FC0000 to 0x00FC7FFF, but some addresses will not erase. They will be set with the value 0x00000000 (should be 0xFFFFFFFF), and if I try to program that address, it will fail, throwing an IVOR1(). Why is it doing that?

this is my erase function:

uint32_t* address = (uint32_t*)0x00FC0000;
for (address = (uint32_t*)0x00FC0000; address < (uint32_t*)0x00FC7FFF; address += 2) {
         if (*address != 0xFFFFFFFF && *(address + 1) != 0xFFFFFFFF) {
                  C55FMC.MCR.B.ERS = 1; //erase
                  *(address) = 0xFFFFFFFF; // Interlock write
                  *(address + 1) = 0xFFFFFFFF; // Interlock write
                  C55FMC.MCR.B.EHV = 1;
                  while (C55FMC.MCR.B.DONE == 0);
                  C55FMC.MCR.B.EHV = 0;
                  C55FMC.MCR.B.ERS = 0;
}

0 Kudos

2,069 Views
casian
Contributor II

This is my new code that works:

void erase_flash_firmware(void) {

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//erase block 0x00FB0000-0x00FBFFFF
      //0x00FB0000--0x00FBFFFF 64 KB high flash memory block 1 (boot location 3) RWW partition 4 LOCK1 bit30 SEL1 bit30


      volatile uint32_t* address = (uint32_t*) 0x00FB0000;

      while (C55FMC.MCR.B.ERS == 1);
      C55FMC.MCR.B.ERS = 1; //erase

      C55FMC.LOCK0.R = 0b11111111111111111111111111111111;
      C55FMC.LOCK1.R = 0b11111111111111111111111111111101;
      C55FMC.LOCK2.R = 0b11111111111111111111111111111111;
      C55FMC.LOCK3.R = 0b11111111111111111111111111111111;

      C55FMC.SEL0.R = 0b00000000000000000000000000000000;
      C55FMC.SEL1.R = 0b00000000000000000000000000000010;
      C55FMC.SEL2.R = 0b00000000000000000000000000000000;
      C55FMC.SEL3.R = 0b00000000000000000000000000000000;

      for (address = (uint32_t*) 0x00FB0000; address < (uint32_t*) (0x00FBFFFF);address += 2) {
            *(address) = 0xFFFFFFFF; // Interlock write
            *(address + 1) = 0xFFFFFFFF; // Interlock write
      }


      C55FMC.MCR.B.EHV = 1;
      while (C55FMC.MCR.B.DONE == 0);
      while (C55FMC.MCR.B.PEG != 1); //Confirm MCR[PEG] = 1
      C55FMC.MCR.B.EHV = 0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//erase block 0x01080000-0x010BFFFF 

      //0x01080000--0x010BFFFF 256 KB flash memory block 2 (boot location 6) RWW partition 6 LOCK2 bit29 SEL2 bit29
      C55FMC.LOCK0.R = 0b11111111111111111111111111111111;
      C55FMC.LOCK1.R = 0b11111111111111111111111111111111;
      C55FMC.LOCK2.R = 0b11111111111111111111111111111011;
      C55FMC.LOCK3.R = 0b11111111111111111111111111111111;

      C55FMC.SEL0.R = 0b00000000000000000000000000000000;
      C55FMC.SEL1.R = 0b00000000000000000000000000000000;
      C55FMC.SEL2.R = 0b00000000000000000000000000000100;
      C55FMC.SEL3.R = 0b00000000000000000000000000000000;

      address = (uint32_t*) 0x01100000;

      for (address = (uint32_t*) 0x01100000; address < (uint32_t*) (0x010BFFFF);address += 2) {
            *(address) = 0xFFFFFFFF; // Interlock write
            *(address + 1) = 0xFFFFFFFF; // Interlock write
      }
      C55FMC.MCR.B.EHV = 1;
      while (C55FMC.MCR.B.DONE == 0);
      while (C55FMC.MCR.B.PEG != 1); //Confirm MCR[PEG] = 1
      C55FMC.MCR.B.EHV = 0;
      C55FMC.MCR.B.ERS = 0; //erase

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

It didn't work because the LOCKn and SELn were wrong in the previous code. And also maybe the memory blocks on MPC5748G are not compatible with MPC5744P, I have'nt checked the MPC5748G ref. manual.

0 Kudos

2,069 Views
dennisyuan
Contributor III

Hi Lukas,

I have the same problem on MPC5634M project ,I use the flash driver is xPC56xx_C90LC Driver\cw\vle\c-array_driver ,CodeWarrior for MCU Version: 10.6.

The fail case is : the return value of the Erase  function is C90FL_OK ,but actually the block which I want to erase  is not erased . that means the last value still in the block . the all value didn't change to 0xFF .

Do you have any good idea to solve this problem ?

Thanks very much!

Dennis

0 Kudos

2,069 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport
0 Kudos

2,069 Views
dennisyuan
Contributor III

Hi Lukas,

Thank you very much! I will try it .

0 Kudos

2,069 Views
happy_larry
Contributor II

Dear Lukas,

     Thanks for your help. However, put your code in the S32, it can't be complied well.

     The error is like below. And I could find the register of L1CSR0 in the datasheet.

pastedImage_0.png

     Do you have some idea about it?

0 Kudos