LPC824 Page Erase (actually a sector erase???)

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

LPC824 Page Erase (actually a sector erase???)

3,057 Views
volkeroth
Contributor II

I'm toying with the idea to design/implement some kind of EEPROM simulation for the LPC824 and therefore trying to understand the concept of page erases - especially regarding flash wear.

Since the according command only exists in the IAP API and the concept of erasing pages inside a sector seems to contradict the idea of flash, I wonder if the page erase command just performs a sector erase internally but reads/restores all other pages with some embedded 1kB buffer. If this should be the case, consecutive page erasing wouldn't help to reduce the flash wear and I'd go for a 2 sector approach.

So is my assumption true or does the page erase command really only affect the page (and not the whole sector)?

Tags (3)
0 Kudos
10 Replies

2,063 Views
caibai
Contributor III

thank you for reply,but where does function  Chip_IAP_PreSectorForReadWrite  and  Chip_IAP_CopyRamToFlash define.

0 Kudos

2,063 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi cai bai,

  Please download the lpc824 lpcopen code:

LPCOpen Software for LPC8XX|NXP 

The Chip_IAP_PreSectorForReadWrite  and  Chip_IAP_CopyRamToFlash is in the chip lib.


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,063 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Volker Oth,

 1.  We need know the page, sector and write size:

Page size is:64Bytes.
Sector size is : 1KB.
sector size = 16 Page size.
each write is 4Bytes.
each page can have 16 times writes, it is 16*4=64Bytes.

2. Page erase is not sector erase

  1 page erase is just 64 Bytes, 1 sector erase is 1K Bytes.

  Please note, the User manual for LPC824 have bugs, before you do the page erase,  you need to call Prepare sector(s) for write operation command, this command is also used to page erase.

  In the same sector, if you just want to erase small part address, you can use the page erase, the other part in the sector won't be erased, I think it will minimize the flash wear.

Wish it helps you!

If you still have question, please let me know!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,063 Views
caibai
Contributor III

hi,i'm stuck in when erase a page by iapCall, code as follow

pastedImage_1.png



i just call
    writePage(0x7C00,buf,4);
and in writePage  call prepareSector return success,but call erasePage will be stuck in,
how to fix it,does IRC must enable?
0 Kudos

2,063 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Cai bai,

   This is my code for your reference:

void jjtest(void)
{
     uint32_t flash_start_sector, flash_end_sector, i;
     uint8_t ret;
     
     flash_start_sector = (FLASH_ADDR_TEST - LPC_FLASH_BASE)/FLASH_SECTOR_SIZE;
     flash_end_sector = flash_start_sector + 1;

     for(i = 0;i < 512; i++) 
     {
              ram_buffer[i] = i;
     }
     
     ret = Chip_IAP_PreSectorForReadWrite(flash_start_sector, flash_end_sector);
     if(ret == IAP_CMD_SUCCESS) 
     {
          ret = Chip_IAP_EraseSector(flash_start_sector, flash_end_sector);
          if (ret == IAP_CMD_SUCCESS) 
          {
               ret = Chip_IAP_PreSectorForReadWrite(flash_start_sector, flash_end_sector);               
               ret = Chip_IAP_CopyRamToFlash(0x6000, ram_buffer, 512); //write 2 page data
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "write OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }
               
               
               ret = Chip_IAP_PreSectorForReadWrite(flash_start_sector, flash_end_sector);
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "page1 erase prepare\r\n");
                    Board_UARTPutSTR(debug_output);                         
               }     
               // erase page one: 0x6000+0x00  0x180 page
               ret= Chip_IAP_ErasePage(0x180, 0x180);//0x181
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "page180 erase OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }               
               //erase page two : 0x6000+0x40  0x181
               ret = Chip_IAP_PreSectorForReadWrite(flash_start_sector, flash_end_sector);
               ret= Chip_IAP_ErasePage(0x181, 0x181);
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "page181 erase OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }                    
               //write page one : 0x6000+0x00
               ret = Chip_IAP_CopyRamToFlash(0x6000, ram_buffer, 64); //write 2 page data
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "write OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }               
               //write page two : 0x6000+0x40
               ret = Chip_IAP_CopyRamToFlash(0x6040, ram_buffer, 64); //write 2 page data
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "write OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }                         
               // erase page one: 0x6000+0x00
               ret= Chip_IAP_ErasePage(0x180, 0x181);
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "page1 erase OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }                         
          }
     }
          
}     ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You need to use the Chip_IAP_CopyRamToFlash function to write the page data, the following code also for your reference:

               for(i=0;i<16;i++)
               {
                 ram_buffer[i]=i;
               //write page one : 0x6000+0x00
               ret = Chip_IAP_PreSectorForReadWrite(flash_start_sector, flash_end_sector);
               ret = Chip_IAP_CopyRamToFlash(0x6000, ram_buffer, 64); //write 2 page data
               if(ret == IAP_CMD_SUCCESS) 
               {
                    sprintf(debug_output, "write OK\r\n");
                    Board_UARTPutSTR(debug_output);                    
               }                         
               
               }‍‍‍‍‍‍‍‍‍‍‍‍‍

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,063 Views
caibai
Contributor III

thank you for reply,but where does function  Chip_IAP_PreSectorForReadWrite  and  Chip_IAP_CopyRamToFlash define.

0 Kudos

2,063 Views
kerryzhou
NXP TechSupport
NXP TechSupport

I find you are not this post author,  actually, if you have the detail question, you can create your own question post, then we will help you in your own question post directly.

Next time, please create your own question post, thank you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,063 Views
volkeroth
Contributor II

Thanks for the quick reply.

Re #1 I'm not sure what exactly you need/want to know. The page size etc. is stated in the manual and the write size of the "copy ram to flash" command is limited to (power of two) multiples of 64 bytes, so there's not much design choices that could affect my question about page erase.

About the 16 consecutive writes: I intend to write data records of 64 bytes to a page and would only attempt multiple writes in a page used to manage the data pages (i.e. write a marker which is the last valid page).

Still I wonder how consecutive writes or write of only 4 bytes are even possible if the "copy ram to flash" commands only supports sizes of (2^n) multiples of 64 bytes. 

I assume the user has to take care that 32bit data other than the current flash content is only written to flash that still has the fill pattern in it (as even writing a single bit from 1 to 0 would most probably create an ECC error).

Or is it also allowed to perform a normal 32bit (aligned) write operation after preparing the sector? If so: how is the flash reprogramming ended in this case (as the manual says the "copy ram ..." command would do this automatically)?

Regarding the page erase: is it really 100% sure that there is no sector erase performed in the background?

There are two things that seem strange:

1) The page erase command only exists for the IAP commands, not for the ISP commands. This made me wonder if some buffer needed for ISP mode is used in IAP to store/restore the unchanged pages.

2) There is a remark in the ISP chapter that says:

         To avoid write disturbance (a mechanism intrinsic to flash memories), an erase should
         be performed after following 16 consecutive writes inside the same page. Note that
         the erase operation then erases the entire sector.

So if there is a physical page erase, why would erasing the whole sector be necessary if the limit of 16 write operation is exceeded within a page? Shouldn't it be sufficient to erase the page?

I'm still pretty far from actually implementing anything, but I would be tempted to measure the time needed for a page erase vs. a sector erase. If the page erase is faster than the sector erase, I guess this would prove that no sector erase is done in the background.

0 Kudos

2,063 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Volker Oth,

   I am sorry for my later reply, because I didn't find the updated information.

  1) page erase is just exist in the IAP mode, ISP don't have it. If you want to erase the flash in ISP mode, you need to erase the sector.

  2) About the remark in the ISP chapter, it is still caused by the ISP mode don't have the page erase function, so it need to erase the entire sector, not the page, ISP don't have the page erase command.

  If you want to use the page erase, I suggest you use the IAP function.Please just follow the user manual.

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,163 Views
jvahue
Contributor I

So I tried using the page erase IAP command and it did not seem to work for me.  I have two small persistent data sets that must be in their own page in FLASH as one is written when the system is shutting down while latched to a battery (if battery has power), and the other if application configuration info that we do not want to corrupt if the shutdown log is corrupted due to a bad/missing battery.

I use a single function to write the two pages shown below but when I read the data sets back they are all zero.  Sorry I modified this function back to what is was when trying to do page erase - the return type was UINT32 to see the status from each IAP operation and I didn't uncomment the first result byte -  the result always came back 0.

static void WritePersistPage(UINT08* data, UINT32 page, UINT32 pageAddr)
{
    UINT32 result = 0;
    iap_entry = (IAP)IAP_LOCATION;

    // disable interrupts while we save the Cfg data to FLASH
    __disable_irq(); // Disable Interrupts

    // 1. Prepare Persist FLASH Sector
    iapCmds[0] = 50;
    iapCmds[1] = PERSIST_SECTOR;  //Start sector 31
    iapCmds[2] = PERSIST_SECTOR;  //End sector 31
    iap_entry(iapCmds, iapResults);
    //result = (iapResults[0] & 0xff) << 0;

    // 2. Erase Page
    iapCmds[0] = 59;
    iapCmds[1] = page;  //Start page 499
    iapCmds[2] = page;  //End page 499
    iap_entry(iapCmds, iapResults);
    result = (iapResults[0] & 0xff) << 8;

    // 3. prepare Persist FLASH Sector
    iapCmds[0] = 50;
    iapCmds[1] = PERSIST_SECTOR;  //Start sector 31
    iapCmds[2] = PERSIST_SECTOR;  //End sector 31
    iap_entry(iapCmds, iapResults);
    result = (iapResults[0] & 0xff) << 16;

    // 4. Copy RAM to Persist FLASH page
    iapCmds[0] = 51;
    iapCmds[1] = pageAddr;            // Destination address
    iapCmds[2] = (UINT32)data;        // Source data address
    iapCmds[3] = PERSIST_WRITE_SIZE;  // Size in bytes (64)
    iap_entry(iapCmds, iapResults);
    result = (iapResults[0] & 0xff) << 24;

    // enable the interrupts after saving data to FLASH.
    __enable_irq();  // Enable Interrupts

    return result;
}

If I give up (as I did) and put each data set in its own 1k sector (what a waste) everything is fine (see below).

static void WritePersistPage(UINT08* data, UINT32 sector, UINT32 dstAddr)
{
    //UINT32 result = 0;
    iap_entry = (IAP)IAP_LOCATION;

    // disable interrupts while we save the Cfg data to FLASH
    __disable_irq(); // Disable Interrupts

    // 1. Prepare Persist FLASH Sector
    iapCmds[0] = 50;
    iapCmds[1] = sector;  //Start sector
    iapCmds[2] = sector;  //End sector
    iap_entry(iapCmds, iapResults);
    //result = (iapResults[0] & 0xff) << 0;

    // 2. Erase Sector
    iapCmds[0] = 52;
    iapCmds[1] = sector;  //Start page
    iapCmds[2] = sector;  //End page
    iap_entry(iapCmds, iapResults);
    //result = (iapResults[0] & 0xff) << 8;

    // 3. prepare Persist FLASH Sector
    iapCmds[0] = 50;
    iapCmds[1] = sector;  //Start sector
    iapCmds[2] = sector;  //End sector
    iap_entry(iapCmds, iapResults);
    //result = (iapResults[0] & 0xff) << 16;

    // 4. Copy RAM to Persist FLASH page
    iapCmds[0] = 51;
    iapCmds[1] = dstAddr;             // Destination address
    iapCmds[2] = (UINT32)data;        // Source data address
    iapCmds[3] = PERSIST_WRITE_SIZE;  // Size in bytes
    iap_entry(iapCmds, iapResults);
    //result = (iapResults[0] & 0xff) << 24;

    // enable the interrupts after saving data to FLASH.
    __enable_irq();  // Enable Interrupts

    //return result;
}

 

0 Kudos