FreeCalypso > hg > freecalypso-tools
comparison loadtools/romload.c @ 636:3172e3111ab7
loadtools/romload.c: implemented grouping of S-records into bigger blocks
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 01 Mar 2020 05:40:29 +0000 |
parents | 4dca8542f569 |
children | 46d7ed4ee634 |
comparison
equal
deleted
inserted
replaced
635:d9b01a171baf | 636:3172e3111ab7 |
---|---|
45 0x00, 0x01, 0xD4, 0xC0 /* UART timeout */ | 45 0x00, 0x01, 0xD4, 0xC0 /* UART timeout */ |
46 /* I've chosen the same value as what the */ | 46 /* I've chosen the same value as what the */ |
47 /* boot ROM runs with before getting this cmd */ | 47 /* boot ROM runs with before getting this cmd */ |
48 }; | 48 }; |
49 | 49 |
50 static u_char write_cmd[10] = {'<', 'w', 0x01, 0x01, 0x00}; | 50 static u_char write_cmd[1024] = {'<', 'w', 0x01, 0x01}; |
51 static u_char cksum_cmd[3] = {'<', 'c'}; | 51 static u_char cksum_cmd[3] = {'<', 'c'}; |
52 static u_char branch_cmd[6] = {'<', 'b'}; | 52 static u_char branch_cmd[6] = {'<', 'b'}; |
53 | |
54 static uint32_t write_cmd_endaddr; | |
55 static unsigned write_cmd_datalen; | |
56 static unsigned write_block_count; | |
57 static uint16_t image_cksum; | |
58 | |
59 #define MAX_WRITE_LEN 0x3F6 | |
53 | 60 |
54 #define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */ | 61 #define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */ |
55 #define SERIAL_FLUSH_DELAY 200 /* also in ms */ | 62 #define SERIAL_FLUSH_DELAY 200 /* also in ms */ |
56 | 63 |
57 /* | 64 /* |
186 compute_block_cksum() | 193 compute_block_cksum() |
187 { | 194 { |
188 uint32_t sum; | 195 uint32_t sum; |
189 int i, llen; | 196 int i, llen; |
190 | 197 |
191 sum = iramimage.datalen + 5; | 198 sum = write_cmd_datalen + 5; |
192 llen = iramimage.datalen + 4; | 199 llen = write_cmd_datalen + 4; |
193 for (i = 0; i < llen; i++) | 200 for (i = 0; i < llen; i++) |
194 sum += iramimage.record[i+1]; | 201 sum += write_cmd[i+6]; |
195 return sum; | 202 return sum; |
196 } | 203 } |
197 | 204 |
205 static void | |
206 send_write_cmd() | |
207 { | |
208 int resp; | |
209 | |
210 write_cmd[4] = write_cmd_datalen >> 8; | |
211 write_cmd[5] = write_cmd_datalen & 0xFF; | |
212 write(target_fd, write_cmd, write_cmd_datalen + 10); | |
213 /* update our checksum accumulator */ | |
214 image_cksum += ~compute_block_cksum() & 0xFF; | |
215 /* collect response */ | |
216 resp = expect_response(INTERMEDIATE_TIMEOUT); | |
217 if (resp != 'w') { | |
218 fprintf(stderr, "Block #%lu: ", write_block_count); | |
219 if (resp < 0) | |
220 fprintf(stderr, "No response to <w command\n"); | |
221 else if (isprint(resp)) | |
222 fprintf(stderr, | |
223 "Got >%c in response to <w command; expected >w\n", | |
224 resp); | |
225 else | |
226 fprintf(stderr, | |
227 "Got > %02X in response to <w command; expected >w\n", | |
228 resp); | |
229 exit(1); | |
230 } | |
231 putchar('.'); | |
232 fflush(stdout); | |
233 write_block_count++; | |
234 } | |
235 | |
198 perform_romload() | 236 perform_romload() |
199 { | 237 { |
200 int resp; | 238 int resp; |
201 uint16_t image_cksum; | |
202 unsigned long rec_count; | 239 unsigned long rec_count; |
203 u_char addresp[2]; | 240 u_char addresp[2]; |
204 static int zero = 0; | 241 static int zero = 0; |
205 | 242 |
206 if (open_srec_file(&iramimage) < 0) | 243 if (open_srec_file(&iramimage) < 0) |
238 romload_baud_rate->name); | 275 romload_baud_rate->name); |
239 set_serial_baudrate(romload_baud_rate); | 276 set_serial_baudrate(romload_baud_rate); |
240 usleep(SERIAL_FLUSH_DELAY * 1000); | 277 usleep(SERIAL_FLUSH_DELAY * 1000); |
241 tcflush(target_fd, TCIFLUSH); | 278 tcflush(target_fd, TCIFLUSH); |
242 | 279 |
280 write_cmd_datalen = 0; | |
281 write_block_count = 0; | |
243 image_cksum = 0; | 282 image_cksum = 0; |
244 for (rec_count = 0; ; ) { | 283 for (rec_count = 0; ; ) { |
245 if (read_s_record(&iramimage) < 0) | 284 if (read_s_record(&iramimage) < 0) |
246 exit(1); | 285 exit(1); |
247 switch (iramimage.record_type) { | 286 switch (iramimage.record_type) { |
271 fprintf(stderr, | 310 fprintf(stderr, |
272 "%s line %d: S3 record has zero data length\n", | 311 "%s line %d: S3 record has zero data length\n", |
273 iramimage.filename, iramimage.lineno); | 312 iramimage.filename, iramimage.lineno); |
274 exit(1); | 313 exit(1); |
275 } | 314 } |
276 /* form <w command */ | 315 /* get to work */ |
277 if (!rec_count) | 316 if (!rec_count) |
278 printf("Sending image payload\n"); | 317 printf("Sending image payload\n"); |
279 write_cmd[5] = iramimage.datalen; | 318 if (write_cmd_datalen && |
280 bcopy(iramimage.record + 1, write_cmd + 6, 4); | 319 (iramimage.addr != write_cmd_endaddr || |
281 write(target_fd, write_cmd, sizeof write_cmd); | 320 write_cmd_datalen + iramimage.datalen > MAX_WRITE_LEN)) { |
282 write(target_fd, iramimage.record + 5, iramimage.datalen); | 321 send_write_cmd(); |
283 /* update our checksum accumulator */ | 322 write_cmd_datalen = 0; |
284 image_cksum += ~compute_block_cksum() & 0xFF; | 323 } |
285 /* collect response */ | 324 if (!write_cmd_datalen) { |
286 resp = expect_response(INTERMEDIATE_TIMEOUT); | 325 bcopy(iramimage.record + 1, write_cmd + 6, 4); |
287 if (resp != 'w') { | 326 write_cmd_endaddr = iramimage.addr; |
288 fprintf(stderr, "Block #%lu: ", rec_count); | 327 } |
289 if (resp < 0) | 328 bcopy(iramimage.record + 5, write_cmd + 10 + write_cmd_datalen, |
290 fprintf(stderr, "No response to <w command\n"); | 329 iramimage.datalen); |
291 else if (isprint(resp)) | 330 write_cmd_endaddr += iramimage.datalen; |
292 fprintf(stderr, | 331 write_cmd_datalen += iramimage.datalen; |
293 "Got >%c in response to <w command; expected >w\n", | |
294 resp); | |
295 else | |
296 fprintf(stderr, | |
297 "Got > %02X in response to <w command; expected >w\n", | |
298 resp); | |
299 exit(1); | |
300 } | |
301 putchar('.'); | |
302 fflush(stdout); | |
303 rec_count++; | 332 rec_count++; |
304 } | 333 } |
305 /* got S7 */ | 334 /* got S7 */ |
306 fclose(iramimage.openfile); | 335 fclose(iramimage.openfile); |
307 if (!rec_count) { | 336 if (!rec_count) { |
308 fprintf(stderr, | 337 fprintf(stderr, |
309 "%s line %d: S7 without any preceding S3 data records\n", | 338 "%s line %d: S7 without any preceding S3 data records\n", |
310 iramimage.filename, iramimage.lineno); | 339 iramimage.filename, iramimage.lineno); |
311 exit(1); | 340 exit(1); |
312 } | 341 } |
342 send_write_cmd(); /* last block */ | |
343 putchar('\n'); /* end line of dots */ | |
313 | 344 |
314 /* send <c */ | 345 /* send <c */ |
315 printf("Sending checksum\n"); | 346 printf("Sending checksum\n"); |
316 cksum_cmd[2] = ~image_cksum & 0xFF; | 347 cksum_cmd[2] = ~image_cksum & 0xFF; |
317 write(target_fd, cksum_cmd, sizeof cksum_cmd); | 348 write(target_fd, cksum_cmd, sizeof cksum_cmd); |