LPC1788 - IAP erase sector always returns BUSY

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

LPC1788 - IAP erase sector always returns BUSY

963 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Mon Feb 06 14:10:27 MST 2012
Hello,

I'm trying to erase some sectors of the internal flash using IAP but for a reason I can not figure out it is not working.

I'm preparing the sectors and this IAP command suceeds but when I try and erase the sectors I am returned BUSY (11).

I'm disabling interrupts.

Does anybody know why the IAP call would return BUSY?  Any suggestions of things I could try?

Thank you.

Regards,

M
Labels (1)
0 Kudos
10 Replies

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Jul 23 16:40:44 MST 2014
I wrote the code in August 2012, so memory is a little fuzzy.
I seem to remember that it always lied, but didn't try to pin it down.
Anyway, I 'fixed' it by blank check and moved on.
The OP remarks about internal EEPROM seem relevant, I have initialised EEPROM
by the time I call the Flash functions.

Regards, Mike
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Wed Jul 23 16:21:24 MST 2014
Hi Mike,

Just curious... with your code, is there ever a time when the erase_sector ISN'T lying?

No matter what I do, I always get r[0] = 11

And since I always have to "prepare" before I do something, I'm guessing the preparing is leaving the flags set in the status register...

the code is pretty simple:

#define IAP_ADDRESS           0x1FFF1FF1

void (*IAP_function)( uint32_t [],uint32_t [] ) = (void (*)(uint32_t[], uint32_t[]))(IAP_ADDRESS);

uint32_t PrepareSector( uint32_t StartSector, uint32_t EndSector )
   {
   uint32_t ParamTable  [ TABLE_SIZE ];
   uint32_t ResultTable [ TABLE_SIZE ];
   __disable_irq();                          // turn off interrupts...                             
   ParamTable[0] = PREPARE_FOR_WRITE_OR_ERASE;  // set command...                                  
   ParamTable[1] = StartSector;              // set start sector number (0-29)                     
   ParamTable[2] = EndSector;                // set end sector number (0-29)                       
   ParamTable[3] = SystemCoreClock / 1000;   // set clock frequency in kHz                         
   IAP_function( ParamTable, ResultTable );  // execute IAP function                               
   __enable_irq();                           // turn back on interrupts...                         

   return( ResultTable[ 0 ] );               // return result of operation...                      
   }

uint32_t EraseFlashSector( uint32_t StartSector, uint32_t EndSector )
   {
   uint32_t ParamTable  [ TABLE_SIZE ];
   uint32_t ResultTable [ TABLE_SIZE ];
   
   LPC_EEPROM->INT_CLR_STATUS = (1<<26) | (1<<28); // without this, erase reports it's busy...
   
   __disable_irq();                          // turn off interrupts...                             
   ParamTable[0] = ERASE_SECTOR;             // set command...                                     
   ParamTable[1] = StartSector;              // set start sector number (0-29)                     
   ParamTable[2] = EndSector;                // set end sector number (0-29)                       
   ParamTable[3] = SystemCoreClock / 1000;   // set clock frequency in kHz                         
   IAP_function( ParamTable, ResultTable );  // execute IAP function                               
   __enable_irq();                           // turn back on interrupts...                         
   
   return( ResultTable[ 0 ] );               // return result of operation...                      
   }


Anyway, thanks for the recommendation on verifying the flash is blank before moving forward...

-Dave
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Jul 23 16:08:23 MST 2014
I too have run into this is nusy issue.

So when I check for the erase status, I exclude 'busy' and continue to blank check.
You DO check that the erased sector(s) is(are) blank don't you!

Incomplete sample (for 1778) follows, but you will get the idea.

ldrr0, [r7, 5*4]; get status code
cmpr0, 11; is it lying about being 'busy'?
bne9f; nope

;---------------------------------------;
movsr0, 53; yup -- is it actually blank?
strr0, [r7];
movsr0, r7; 'in'  parameters
addsr1, r7,  5*4; 'out' parameters
blGoIAP;
ldrr0, [r7, 5*4]; get status code
;cbnzr0, 9f; OOPS -- IAP failed

;---------------------------------------;
9:pop{r7,pc}; return (zero == success)

Hope this help. Mike
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Wed Jul 23 15:58:15 MST 2014
Hey Marc,

Good find here - I just ran into this issue, and you solved it 2 years ago...

Thanks again!

btw, hope your project is going good!

-Dave
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Lien.Nguyen on Wed Feb 15 20:45:11 MST 2012
Hi Marc,
Thanks for your reponse. Maybe, IAP interface thinks that the eeprom operation hasnt finished yet.
I found that there is an error in the EEPROM_Read. When the last byte is read, if it is also the last byte of a EEPROM page, erasing flash will be failed with Busy.
The fix is:
   Replace the line:
       if(page_offset >= EEPROM_PAGE_SIZE)
   with
       if((page_offset >= EEPROM_PAGE_SIZE) && (i < count - 1))

Best Regards,
Lien
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Wed Feb 15 13:50:30 MST 2012
After some trial and error the following solved my problem:

<code>
    BOOT_PRINT("Checking EEPROM boot code: ");
    EEPROM_Read(BOOT_CODE_PAGE_OFFSET, BOOT_CODE_PAGE_ADDRESS, (void*)&boot_code, MODE_8_BIT, sizeof(uint32_t));

    //CLEAR THE INT FLAGS
    LPC_EEPROM->INT_CLR_STATUS = (BIT26|BIT28);

    BOOT_PRINT("0x%X\r\n", boot_code);
  
    BOOT_PRINT("TEST 1 Erasing user flash...\r\n");
    erase_user_flash();
    BOOT_PRINT("END TEST 1\r\n");

</code>

Marc

0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Wed Feb 15 12:28:52 MST 2012
Hi Lien,

I apologize for not being thorough enough but right now it is fairly difficult to isolate my code.

It seems that it's not the LCD as you mention above but rather if I read from the EEPROM directly before the erase user flash:

example.

This works:
<code>
    BOOT_PRINT("Checking EEPROM boot code: ");
    //EEPROM_Read(BOOT_CODE_PAGE_OFFSET, BOOT_CODE_PAGE_ADDRESS, (void*)&boot_code, MODE_8_BIT, sizeof(uint32_t));
    BOOT_PRINT("0x%X\r\n", boot_code);
   
    BOOT_PRINT("TEST 1 Erasing user flash...\r\n");
    erase_user_flash();
    BOOT_PRINT("END TEST 1\r\n");
</code>



This fails with BUSY:
<code>
    BOOT_PRINT("Checking EEPROM boot code: ");
    EEPROM_Read(BOOT_CODE_PAGE_OFFSET, BOOT_CODE_PAGE_ADDRESS, (void*)&boot_code, MODE_8_BIT, sizeof(uint32_t));
    BOOT_PRINT("0x%X\r\n", boot_code);
   
    BOOT_PRINT("TEST 1 Erasing user flash...\r\n");
    erase_user_flash();
    BOOT_PRINT("END TEST 1\r\n");
</code>

Any thoughts?  What is the actual meaning of the BUSY return value?  It's not very clear in the user manual.

Thanks.

Marc
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Lien.Nguyen on Mon Feb 13 21:21:15 MST 2012
Hi Marc,
I added the iap test code to the LCD example. It still runs ok.
I think that you should check more on the sectors you erase. Maybe erasing corrupts the IAP code.
Please try to erase last sectors of flash memory first.

Best Regards,
Lien
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Fri Feb 10 07:11:58 MST 2012
Hi Lien,

Thank you for the example.  This is the example I started from.  When I have no LCD and UART0 running I can get the IAP to work as expected.  Once I add the LCD and UART0 functionality to my application I get the BUSY flag every time I try and erase the flash.

What could cause the BUSY flag? Interrupts are disabled and I'm not trying to erase a section of flash I'm running from or currently using in ay other way.

Thank you.

M

EDIT:  I just did a second test and it seems it's only the LCD being enabled that causes the BUSY flag not the UART0 functionality.
0 Kudos

721 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Lien.Nguyen on Tue Feb 07 22:01:16 MST 2012
Hi Marc,
There is an example for IAP and it works ok.
I attached it for you. You can test on your board. if ok, compare it with your code to get the reason.

Best Regards,
Lien
0 Kudos