Skip to content

Commit cd07a81

Browse files
toyowataadbridge
authored andcommitted
LPC176X: Fix flash program size
This patch fix flash write issue when program size is more than page size (= 1024 bytes). See detail - #6165 Source data always use aligned data in heap memory.
1 parent 7360771 commit cd07a81

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -112,42 +112,56 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
112112
const uint8_t *data, uint32_t size)
113113
{
114114
unsigned long n;
115+
const uint32_t copySize = 1024; // should be 256|512|1024|4096
116+
uint8_t *alignedData, *source;
117+
115118
// always malloc outside critical section
116-
uint8_t *alignedData = malloc(size);
119+
alignedData = malloc(size);
120+
if (alignedData == 0) {
121+
return (1);
122+
}
117123

118124
n = GetSecNum(address); // Get Sector Number
119125

120-
core_util_critical_section_enter();
121-
IAP.cmd = 50;// Prepare Sector for Write
122-
IAP.par[0] = n;// Start Sector
123-
IAP.par[1] = n;// End Sector
124-
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
125-
if (IAP.stat) {
126-
return (1); // Command Failed
127-
}
126+
memcpy(alignedData, data, size);
127+
source = alignedData;
128128

129-
IAP.cmd = 51; // Copy RAM to Flash
130-
IAP.par[0] = address;// Destination Flash Address
129+
core_util_critical_section_enter();
131130

132-
if ((unsigned long)data%4==0) { // Word boundary
133-
IAP.par[1] = (unsigned long)data;// Source RAM Address
134-
} else {
135-
memcpy(alignedData,data,size);
136-
IAP.par[1] = (unsigned long)alignedData; // Source RAM Address
131+
while (size) {
132+
/*
133+
Prepare_Sector_for_Write command must be exected before
134+
Copy_RAM_to_Flash command.
135+
*/
136+
IAP.cmd = 50; // Prepare Sector for Write
137+
IAP.par[0] = n; // Start Sector
138+
IAP.par[1] = n; // End Sector
139+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
140+
if (IAP.stat) {
141+
return (1); // Command Failed
142+
}
143+
144+
IAP.cmd = 51; // Copy RAM to Flash
145+
IAP.par[0] = address; // Destination Flash Address
146+
IAP.par[1] = (unsigned long)source; // Source RAM Address
147+
IAP.par[2] = copySize; // number of bytes to be written
148+
IAP.par[3] = CCLK; // CCLK in kHz
149+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
150+
if (IAP.stat) {
151+
return (1); // Command Failed
152+
}
153+
154+
source += copySize;
155+
size -= copySize;
156+
address += copySize;
137157
}
138158

139-
IAP.par[2] = 1024; // Fixed Page Size
140-
IAP.par[3] = CCLK;// CCLK in kHz
141-
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
142159
core_util_critical_section_exit();
143160

144-
if(alignedData !=0) { // We allocated our own memory
161+
if(alignedData != 0) { // We allocated our own memory
145162
free(alignedData);
146163
}
147164

148-
if (IAP.stat) {
149-
return (1); // Command Failed
150-
}
151165
return (0); // Finished without Errors
152166
}
153167

0 commit comments

Comments
 (0)