Skip to content

Commit de51972

Browse files
0xc0170theotherjimmy
authored andcommitted
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.
1 parent ba019fd commit de51972

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
8585

8686
n = GetSecNum(address); // Get Sector Number
8787

88+
core_util_critical_section_enter();
8889
IAP.cmd = 50;// Prepare Sector for Erase
8990
IAP.par[0] = n;// Start Sector
9091
IAP.par[1] = n;// End Sector
@@ -98,6 +99,7 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
9899
IAP.par[1] = n;// End Sector
99100
IAP.par[2] = CCLK;// CCLK in kHz
100101
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
102+
core_util_critical_section_exit();
101103
if (IAP.stat) {
102104
return (1); // Command Failed
103105
}
@@ -114,10 +116,12 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
114116
const uint8_t *data, uint32_t size)
115117
{
116118
unsigned long n;
117-
uint8_t *alignedData = 0;
119+
// always malloc outside critical section
120+
uint8_t *alignedData = malloc(size);
118121

119122
n = GetSecNum(address); // Get Sector Number
120123

124+
core_util_critical_section_enter();
121125
IAP.cmd = 50;// Prepare Sector for Write
122126
IAP.par[0] = n;// Start Sector
123127
IAP.par[1] = n;// End Sector
@@ -132,14 +136,14 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
132136
if ((unsigned long)data%4==0) { // Word boundary
133137
IAP.par[1] = (unsigned long)data;// Source RAM Address
134138
} else {
135-
alignedData = malloc(size);
136139
memcpy(alignedData,data,size);
137140
IAP.par[1] = (unsigned long)alignedData; // Source RAM Address
138141
}
139142

140143
IAP.par[2] = 1024; // Fixed Page Size
141144
IAP.par[3] = CCLK;// CCLK in kHz
142145
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
146+
core_util_critical_section_exit();
143147

144148
if(alignedData !=0) { // We allocated our own memory
145149
free(alignedData);

0 commit comments

Comments
 (0)