LPC1768: flash erase/write require a critical section

From RM:

32.3.2.6 Interrupts during IAP
The on-chip flash memory is not accessible during erase/write operations. When the user
application code starts executing the interrupt vectors from the user flash area are active.
The user should either disable interrupts, or ensure that user interrupt vectors are active in
RAM and that the interrupt handlers reside in RAM, before making a flash erase/write IAP
call. The IAP code does not use or disable interrupts.
pull/5189/head
Martin Kojtal 2017-09-25 14:18:47 +01:00
parent c623e889c0
commit 6a6561028e
1 changed files with 6 additions and 2 deletions

View File

@ -85,6 +85,7 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
n = GetSecNum(address); // Get Sector Number
core_util_critical_section_enter();
IAP.cmd = 50;// Prepare Sector for Erase
IAP.par[0] = n;// Start Sector
IAP.par[1] = n;// End Sector
@ -98,6 +99,7 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
IAP.par[1] = n;// End Sector
IAP.par[2] = CCLK;// CCLK in kHz
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
core_util_critical_section_exit();
if (IAP.stat) {
return (1); // Command Failed
}
@ -114,10 +116,12 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
const uint8_t *data, uint32_t size)
{
unsigned long n;
uint8_t *alignedData = 0;
// always malloc outside critical section
uint8_t *alignedData = malloc(size);
n = GetSecNum(address); // Get Sector Number
core_util_critical_section_enter();
IAP.cmd = 50;// Prepare Sector for Write
IAP.par[0] = n;// Start Sector
IAP.par[1] = n;// End Sector
@ -132,7 +136,6 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
if ((unsigned long)data%4==0) { // Word boundary
IAP.par[1] = (unsigned long)data;// Source RAM Address
} else {
alignedData = malloc(size);
memcpy(alignedData,data,size);
IAP.par[1] = (unsigned long)alignedData; // Source RAM Address
}
@ -140,6 +143,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
IAP.par[2] = 1024; // Fixed Page Size
IAP.par[3] = CCLK;// CCLK in kHz
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
core_util_critical_section_exit();
if(alignedData !=0) { // We allocated our own memory
free(alignedData);