Skip to content

Commit f895392

Browse files
authored
Merge pull request #6413 from toyowata/lpc1768_flash_fix
LPC176X: Fix flash program size
2 parents 4797b53 + 3acdc81 commit f895392

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -112,42 +112,64 @@ 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-
// always malloc outside critical section
116-
uint8_t *alignedData = malloc(size);
115+
const uint32_t copySize = 1024; // should be 256|512|1024|4096
116+
uint8_t *alignedData, *source;
117+
118+
alignedData = 0;
119+
source = (uint8_t *)data;
120+
121+
// check word boundary
122+
if (((uint32_t)data % 4) != 0) {
123+
// always malloc outside critical section
124+
alignedData = malloc(copySize);
125+
if (alignedData == 0) {
126+
return (1);
127+
}
128+
}
117129

118130
n = GetSecNum(address); // Get Sector Number
119131

120132
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-
}
128133

129-
IAP.cmd = 51; // Copy RAM to Flash
130-
IAP.par[0] = address;// Destination Flash Address
131-
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
134+
while (size) {
135+
if (((uint32_t)data % 4) != 0) {
136+
memcpy(alignedData, source, copySize);
137+
source = alignedData;
138+
}
139+
140+
/*
141+
Prepare_Sector_for_Write command must be exected before
142+
Copy_RAM_to_Flash command.
143+
*/
144+
IAP.cmd = 50; // Prepare Sector for Write
145+
IAP.par[0] = n; // Start Sector
146+
IAP.par[1] = n; // End Sector
147+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
148+
if (IAP.stat) {
149+
return (1); // Command Failed
150+
}
151+
152+
IAP.cmd = 51; // Copy RAM to Flash
153+
IAP.par[0] = address; // Destination Flash Address
154+
IAP.par[1] = (unsigned long)source; // Source RAM Address
155+
IAP.par[2] = copySize; // number of bytes to be written
156+
IAP.par[3] = CCLK; // CCLK in kHz
157+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
158+
if (IAP.stat) {
159+
return (1); // Command Failed
160+
}
161+
162+
source += copySize;
163+
size -= copySize;
164+
address += copySize;
137165
}
138166

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
142167
core_util_critical_section_exit();
143168

144-
if(alignedData !=0) { // We allocated our own memory
169+
if(alignedData != 0) { // We allocated our own memory
145170
free(alignedData);
146171
}
147172

148-
if (IAP.stat) {
149-
return (1); // Command Failed
150-
}
151173
return (0); // Finished without Errors
152174
}
153175

0 commit comments

Comments
 (0)