ARM: only use one set of dummy FPA registers
[openocd.git] / src / flash / lpc2000.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
6 * didele.deze@gmail.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "lpc2000.h"
29 #include "armv7m.h"
30 #include "binarybuffer.h"
31 #include "algorithm.h"
32
33
34 /* flash programming support for NXP LPC17xx and LPC2xxx devices
35 * currently supported devices:
36 * variant 1 (lpc2000_v1):
37 * - 2104 | 5 | 6
38 * - 2114 | 9
39 * - 2124 | 9
40 * - 2194
41 * - 2212 | 4
42 * - 2292 | 4
43 *
44 * variant 2 (lpc2000_v2):
45 * - 213x
46 * - 214x
47 * - 2101 | 2 | 3
48 * - 2364 | 6 | 8
49 * - 2378
50 *
51 * lpc1700:
52 * - 175x
53 * - 176x (tested with LPC1768)
54 */
55
56 static int lpc2000_build_sector_list(struct flash_bank *bank)
57 {
58 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
59 int i;
60 uint32_t offset = 0;
61
62 /* default to a 4096 write buffer */
63 lpc2000_info->cmd51_max_buffer = 4096;
64
65 if (lpc2000_info->variant == lpc2000_v1)
66 {
67 /* variant 1 has different layout for 128kb and 256kb flashes */
68 if (bank->size == 128 * 1024)
69 {
70 bank->num_sectors = 16;
71 bank->sectors = malloc(sizeof(struct flash_sector) * 16);
72 for (i = 0; i < 16; i++)
73 {
74 bank->sectors[i].offset = offset;
75 bank->sectors[i].size = 8 * 1024;
76 offset += bank->sectors[i].size;
77 bank->sectors[i].is_erased = -1;
78 bank->sectors[i].is_protected = 1;
79 }
80 }
81 else if (bank->size == 256 * 1024)
82 {
83 bank->num_sectors = 18;
84 bank->sectors = malloc(sizeof(struct flash_sector) * 18);
85
86 for (i = 0; i < 8; i++)
87 {
88 bank->sectors[i].offset = offset;
89 bank->sectors[i].size = 8 * 1024;
90 offset += bank->sectors[i].size;
91 bank->sectors[i].is_erased = -1;
92 bank->sectors[i].is_protected = 1;
93 }
94 for (i = 8; i < 10; i++)
95 {
96 bank->sectors[i].offset = offset;
97 bank->sectors[i].size = 64 * 1024;
98 offset += bank->sectors[i].size;
99 bank->sectors[i].is_erased = -1;
100 bank->sectors[i].is_protected = 1;
101 }
102 for (i = 10; i < 18; i++)
103 {
104 bank->sectors[i].offset = offset;
105 bank->sectors[i].size = 8 * 1024;
106 offset += bank->sectors[i].size;
107 bank->sectors[i].is_erased = -1;
108 bank->sectors[i].is_protected = 1;
109 }
110 }
111 else
112 {
113 LOG_ERROR("BUG: unknown bank->size encountered");
114 exit(-1);
115 }
116 }
117 else if (lpc2000_info->variant == lpc2000_v2)
118 {
119 /* variant 2 has a uniform layout, only number of sectors differs */
120 switch (bank->size)
121 {
122 case 4 * 1024:
123 lpc2000_info->cmd51_max_buffer = 1024;
124 bank->num_sectors = 1;
125 break;
126 case 8 * 1024:
127 lpc2000_info->cmd51_max_buffer = 1024;
128 bank->num_sectors = 2;
129 break;
130 case 16 * 1024:
131 bank->num_sectors = 4;
132 break;
133 case 32 * 1024:
134 bank->num_sectors = 8;
135 break;
136 case 64 * 1024:
137 bank->num_sectors = 9;
138 break;
139 case 128 * 1024:
140 bank->num_sectors = 11;
141 break;
142 case 256 * 1024:
143 bank->num_sectors = 15;
144 break;
145 case 512 * 1024:
146 case 500 * 1024:
147 bank->num_sectors = 27;
148 break;
149 default:
150 LOG_ERROR("BUG: unknown bank->size encountered");
151 exit(-1);
152 break;
153 }
154
155 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
156
157 for (i = 0; i < bank->num_sectors; i++)
158 {
159 if ((i >= 0) && (i < 8))
160 {
161 bank->sectors[i].offset = offset;
162 bank->sectors[i].size = 4 * 1024;
163 offset += bank->sectors[i].size;
164 bank->sectors[i].is_erased = -1;
165 bank->sectors[i].is_protected = 1;
166 }
167 if ((i >= 8) && (i < 22))
168 {
169 bank->sectors[i].offset = offset;
170 bank->sectors[i].size = 32 * 1024;
171 offset += bank->sectors[i].size;
172 bank->sectors[i].is_erased = -1;
173 bank->sectors[i].is_protected = 1;
174 }
175 if ((i >= 22) && (i < 27))
176 {
177 bank->sectors[i].offset = offset;
178 bank->sectors[i].size = 4 * 1024;
179 offset += bank->sectors[i].size;
180 bank->sectors[i].is_erased = -1;
181 bank->sectors[i].is_protected = 1;
182 }
183 }
184 }
185 else if (lpc2000_info->variant == lpc1700)
186 {
187 switch(bank->size)
188 {
189 case 32 * 1024:
190 bank->num_sectors = 8;
191 break;
192 case 64 * 1024:
193 bank->num_sectors = 16;
194 break;
195 case 128 * 1024:
196 bank->num_sectors = 18;
197 break;
198 case 256 * 1024:
199 bank->num_sectors = 22;
200 break;
201 case 512 * 1024:
202 bank->num_sectors = 30;
203 break;
204 default:
205 LOG_ERROR("BUG: unknown bank->size encountered");
206 exit(-1);
207 }
208
209 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
210
211 for(i = 0; i < bank->num_sectors; i++)
212 {
213 bank->sectors[i].offset = offset;
214 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
215 bank->sectors[i].size = (i < 16)? 4 * 1024 : 32 * 1024;
216 offset += bank->sectors[i].size;
217 bank->sectors[i].is_erased = -1;
218 bank->sectors[i].is_protected = 1;
219 }
220 }
221 else
222 {
223 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
224 exit(-1);
225 }
226
227 return ERROR_OK;
228 }
229
230 /* call LPC1700/LPC2000 IAP function
231 * uses 180 bytes working area
232 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
233 * 0x8 to 0x1f: command parameter table (1+5 words)
234 * 0x20 to 0x33: command result table (1+4 words)
235 * 0x34 to 0xb3: stack (only 128b needed)
236 */
237 static int lpc2000_iap_call(struct flash_bank *bank, int code, uint32_t param_table[5], uint32_t result_table[4])
238 {
239 int retval;
240 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
241 struct target *target = bank->target;
242 struct mem_param mem_params[2];
243 struct reg_param reg_params[5];
244 struct armv4_5_algorithm armv4_5_info; /* for LPC2000 */
245 struct armv7m_algorithm armv7m_info; /* for LPC1700 */
246 uint32_t status_code;
247 uint32_t iap_entry_point = 0; /* to make compiler happier */
248
249 /* regrab previously allocated working_area, or allocate a new one */
250 if (!lpc2000_info->iap_working_area)
251 {
252 uint8_t jump_gate[8];
253
254 /* make sure we have a working area */
255 if (target_alloc_working_area(target, 180, &lpc2000_info->iap_working_area) != ERROR_OK)
256 {
257 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
258 return ERROR_FLASH_OPERATION_FAILED;
259 }
260
261 /* write IAP code to working area */
262 switch(lpc2000_info->variant)
263 {
264 case lpc1700:
265 target_buffer_set_u32(target, jump_gate, ARMV7M_T_BX(12));
266 target_buffer_set_u32(target, jump_gate + 4, ARMV7M_T_B(0xfffffe));
267 break;
268 case lpc2000_v1:
269 case lpc2000_v2:
270 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
271 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
272 break;
273 default:
274 LOG_ERROR("BUG: unknown bank->size encountered");
275 exit(-1);
276 }
277
278 if ((retval = target_write_memory(target, lpc2000_info->iap_working_area->address, 4, 2, jump_gate)) != ERROR_OK)
279 {
280 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)", lpc2000_info->iap_working_area->address);
281 return retval;
282 }
283 }
284
285 switch(lpc2000_info->variant)
286 {
287 case lpc1700:
288 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
289 armv7m_info.core_mode = ARMV7M_MODE_ANY;
290 iap_entry_point = 0x1fff1ff1;
291 break;
292 case lpc2000_v1:
293 case lpc2000_v2:
294 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
295 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
296 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
297 iap_entry_point = 0x7ffffff1;
298 break;
299 default:
300 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
301 exit(-1);
302 }
303
304 /* command parameter table */
305 init_mem_param(&mem_params[0], lpc2000_info->iap_working_area->address + 8, 6 * 4, PARAM_OUT);
306 target_buffer_set_u32(target, mem_params[0].value, code);
307 target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
308 target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
309 target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
310 target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
311 target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
312
313 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
314 buf_set_u32(reg_params[0].value, 0, 32, lpc2000_info->iap_working_area->address + 0x08);
315
316 /* command result table */
317 init_mem_param(&mem_params[1], lpc2000_info->iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
318
319 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
320 buf_set_u32(reg_params[1].value, 0, 32, lpc2000_info->iap_working_area->address + 0x20);
321
322 /* IAP entry point */
323 init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
324 buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
325
326 switch(lpc2000_info->variant)
327 {
328 case lpc1700:
329 /* IAP stack */
330 init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
331 buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xb4);
332
333 /* return address */
334 init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
335 buf_set_u32(reg_params[4].value, 0, 32, (lpc2000_info->iap_working_area->address + 0x04) | 1); /* bit0 of LR = 1 to return in Thumb mode */
336
337 target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv7m_info);
338 break;
339 case lpc2000_v1:
340 case lpc2000_v2:
341 /* IAP stack */
342 init_reg_param(&reg_params[3], "r13_svc", 32, PARAM_OUT);
343 buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xb4);
344
345 /* return address */
346 init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
347 buf_set_u32(reg_params[4].value, 0, 32, lpc2000_info->iap_working_area->address + 0x04);
348
349 target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv4_5_info);
350 break;
351 default:
352 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
353 exit(-1);
354 }
355
356
357 status_code = target_buffer_get_u32(target, mem_params[1].value);
358 result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
359 result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
360 result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
361 result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
362
363 LOG_DEBUG("IAP command = %i (0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32") completed with result = %8.8" PRIx32,
364 code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
365
366 destroy_mem_param(&mem_params[0]);
367 destroy_mem_param(&mem_params[1]);
368
369 destroy_reg_param(&reg_params[0]);
370 destroy_reg_param(&reg_params[1]);
371 destroy_reg_param(&reg_params[2]);
372 destroy_reg_param(&reg_params[3]);
373 destroy_reg_param(&reg_params[4]);
374
375 return status_code;
376 }
377
378 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
379 {
380 uint32_t param_table[5];
381 uint32_t result_table[4];
382 int status_code;
383 int i;
384
385 if ((first < 0) || (last >= bank->num_sectors))
386 return ERROR_FLASH_SECTOR_INVALID;
387
388 for (i = first; i <= last; i++)
389 {
390 /* check single sector */
391 param_table[0] = param_table[1] = i;
392 status_code = lpc2000_iap_call(bank, 53, param_table, result_table);
393
394 switch (status_code)
395 {
396 case ERROR_FLASH_OPERATION_FAILED:
397 return ERROR_FLASH_OPERATION_FAILED;
398 case LPC2000_CMD_SUCCESS:
399 bank->sectors[i].is_erased = 1;
400 break;
401 case LPC2000_SECTOR_NOT_BLANK:
402 bank->sectors[i].is_erased = 0;
403 break;
404 case LPC2000_INVALID_SECTOR:
405 bank->sectors[i].is_erased = 0;
406 break;
407 case LPC2000_BUSY:
408 return ERROR_FLASH_BUSY;
409 break;
410 default:
411 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
412 exit(-1);
413 }
414 }
415
416 return ERROR_OK;
417 }
418
419 /*
420 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
421 */
422 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
423 {
424 struct lpc2000_flash_bank *lpc2000_info;
425
426 if (CMD_ARGC < 8)
427 {
428 LOG_WARNING("incomplete flash_bank lpc2000 configuration");
429 return ERROR_FLASH_BANK_INVALID;
430 }
431
432 lpc2000_info = malloc(sizeof(struct lpc2000_flash_bank));
433 bank->driver_priv = lpc2000_info;
434
435 if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0)
436 {
437 lpc2000_info->variant = lpc2000_v1;
438 lpc2000_info->cmd51_dst_boundary = 512;
439 lpc2000_info->cmd51_can_256b = 0;
440 lpc2000_info->cmd51_can_8192b = 1;
441 lpc2000_info->checksum_vector = 5;
442 }
443 else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0)
444 {
445 lpc2000_info->variant = lpc2000_v2;
446 lpc2000_info->cmd51_dst_boundary = 256;
447 lpc2000_info->cmd51_can_256b = 1;
448 lpc2000_info->cmd51_can_8192b = 0;
449 lpc2000_info->checksum_vector = 5;
450 }
451 else if (strcmp(CMD_ARGV[6], "lpc1700") == 0)
452 {
453 lpc2000_info->variant = lpc1700;
454 lpc2000_info->cmd51_dst_boundary = 256;
455 lpc2000_info->cmd51_can_256b = 1;
456 lpc2000_info->cmd51_can_8192b = 0;
457 lpc2000_info->checksum_vector = 7;
458 }
459 else
460 {
461 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
462 free(lpc2000_info);
463 return ERROR_FLASH_BANK_INVALID;
464 }
465
466 lpc2000_info->iap_working_area = NULL;
467 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
468 lpc2000_info->calc_checksum = 0;
469 lpc2000_build_sector_list(bank);
470
471 if (CMD_ARGC >= 9)
472 {
473 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
474 lpc2000_info->calc_checksum = 1;
475 }
476
477 return ERROR_OK;
478 }
479
480 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
481 {
482 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
483 uint32_t param_table[5];
484 uint32_t result_table[4];
485 int status_code;
486
487 if (bank->target->state != TARGET_HALTED)
488 {
489 LOG_ERROR("Target not halted");
490 return ERROR_TARGET_NOT_HALTED;
491 }
492
493 param_table[0] = first;
494 param_table[1] = last;
495 param_table[2] = lpc2000_info->cclk;
496
497 /* Prepare sectors */
498 status_code = lpc2000_iap_call(bank, 50, param_table, result_table);
499 switch (status_code)
500 {
501 case ERROR_FLASH_OPERATION_FAILED:
502 return ERROR_FLASH_OPERATION_FAILED;
503 case LPC2000_CMD_SUCCESS:
504 break;
505 case LPC2000_INVALID_SECTOR:
506 return ERROR_FLASH_SECTOR_INVALID;
507 break;
508 default:
509 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
510 return ERROR_FLASH_OPERATION_FAILED;
511 }
512
513 /* Erase sectors */
514 status_code = lpc2000_iap_call(bank, 52, param_table, result_table);
515 switch (status_code)
516 {
517 case ERROR_FLASH_OPERATION_FAILED:
518 return ERROR_FLASH_OPERATION_FAILED;
519 case LPC2000_CMD_SUCCESS:
520 break;
521 case LPC2000_INVALID_SECTOR:
522 return ERROR_FLASH_SECTOR_INVALID;
523 break;
524 default:
525 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
526 return ERROR_FLASH_OPERATION_FAILED;
527 }
528
529 return ERROR_OK;
530 }
531
532 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
533 {
534 /* can't protect/unprotect on the lpc2000 */
535 return ERROR_OK;
536 }
537
538 static int lpc2000_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
539 {
540 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
541 struct target *target = bank->target;
542 uint32_t dst_min_alignment;
543 uint32_t bytes_remaining = count;
544 uint32_t bytes_written = 0;
545 int first_sector = 0;
546 int last_sector = 0;
547 uint32_t param_table[5];
548 uint32_t result_table[4];
549 int status_code;
550 int i;
551 struct working_area *download_area;
552 int retval = ERROR_OK;
553
554 if (bank->target->state != TARGET_HALTED)
555 {
556 LOG_ERROR("Target not halted");
557 return ERROR_TARGET_NOT_HALTED;
558 }
559
560 if (offset + count > bank->size)
561 return ERROR_FLASH_DST_OUT_OF_BANK;
562
563 dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
564
565 if (offset % dst_min_alignment)
566 {
567 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
568 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
569 }
570
571 for (i = 0; i < bank->num_sectors; i++)
572 {
573 if (offset >= bank->sectors[i].offset)
574 first_sector = i;
575 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
576 last_sector = i;
577 }
578
579 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
580
581 /* check if exception vectors should be flashed */
582 if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum)
583 {
584 uint32_t checksum = 0;
585 int i;
586 for (i = 0; i < 8; i++)
587 {
588 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
589 if (i != lpc2000_info->checksum_vector)
590 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
591 }
592 checksum = 0 - checksum;
593 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
594
595 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
596 if (original_value != checksum)
597 {
598 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is different from calculated vector checksum (0x%8.8" PRIx32 ").",
599 original_value, checksum);
600 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.");
601 }
602
603 buf_set_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
604 }
605
606 /* allocate a working area */
607 if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK)
608 {
609 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
610 return ERROR_FLASH_OPERATION_FAILED;
611 }
612
613 while (bytes_remaining > 0)
614 {
615 uint32_t thisrun_bytes;
616 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
617 thisrun_bytes = lpc2000_info->cmd51_max_buffer;
618 else if (bytes_remaining >= 1024)
619 thisrun_bytes = 1024;
620 else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
621 thisrun_bytes = 512;
622 else
623 thisrun_bytes = 256;
624
625 /* Prepare sectors */
626 param_table[0] = first_sector;
627 param_table[1] = last_sector;
628 status_code = lpc2000_iap_call(bank, 50, param_table, result_table);
629 switch (status_code)
630 {
631 case ERROR_FLASH_OPERATION_FAILED:
632 retval = ERROR_FLASH_OPERATION_FAILED;
633 break;
634 case LPC2000_CMD_SUCCESS:
635 break;
636 case LPC2000_INVALID_SECTOR:
637 retval = ERROR_FLASH_SECTOR_INVALID;
638 break;
639 default:
640 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
641 retval = ERROR_FLASH_OPERATION_FAILED;
642 break;
643 }
644
645 /* Exit if error occured */
646 if (retval != ERROR_OK)
647 break;
648
649 if (bytes_remaining >= thisrun_bytes)
650 {
651 if ((retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written)) != ERROR_OK)
652 {
653 retval = ERROR_FLASH_OPERATION_FAILED;
654 break;
655 }
656 }
657 else
658 {
659 uint8_t *last_buffer = malloc(thisrun_bytes);
660 memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
661 memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
662 target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
663 free(last_buffer);
664 }
665
666 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32 , thisrun_bytes, bank->base + offset + bytes_written);
667
668 /* Write data */
669 param_table[0] = bank->base + offset + bytes_written;
670 param_table[1] = download_area->address;
671 param_table[2] = thisrun_bytes;
672 param_table[3] = lpc2000_info->cclk;
673 status_code = lpc2000_iap_call(bank, 51, param_table, result_table);
674 switch (status_code)
675 {
676 case ERROR_FLASH_OPERATION_FAILED:
677 retval = ERROR_FLASH_OPERATION_FAILED;
678 break;
679 case LPC2000_CMD_SUCCESS:
680 break;
681 case LPC2000_INVALID_SECTOR:
682 retval = ERROR_FLASH_SECTOR_INVALID;
683 break;
684 default:
685 LOG_WARNING("lpc2000 returned %i", status_code);
686 retval = ERROR_FLASH_OPERATION_FAILED;
687 break;
688 }
689
690 /* Exit if error occured */
691 if (retval != ERROR_OK)
692 break;
693
694 if (bytes_remaining > thisrun_bytes)
695 bytes_remaining -= thisrun_bytes;
696 else
697 bytes_remaining = 0;
698 bytes_written += thisrun_bytes;
699 }
700
701 target_free_working_area(target, download_area);
702
703 return retval;
704 }
705
706 static int lpc2000_probe(struct flash_bank *bank)
707 {
708 /* we can't probe on an lpc2000
709 * if this is an lpc2xxx, it has the configured flash
710 */
711 return ERROR_OK;
712 }
713
714 static int lpc2000_erase_check(struct flash_bank *bank)
715 {
716 if (bank->target->state != TARGET_HALTED)
717 {
718 LOG_ERROR("Target not halted");
719 return ERROR_TARGET_NOT_HALTED;
720 }
721
722 return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
723 }
724
725 static int lpc2000_protect_check(struct flash_bank *bank)
726 {
727 /* sectors are always protected */
728 return ERROR_OK;
729 }
730
731 static int lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
732 {
733 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
734
735 snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz" , lpc2000_info->variant, lpc2000_info->cclk);
736
737 return ERROR_OK;
738 }
739
740 COMMAND_HANDLER(lpc2000_handle_part_id_command)
741 {
742 uint32_t param_table[5];
743 uint32_t result_table[4];
744 int status_code;
745
746 if (CMD_ARGC < 1)
747 {
748 return ERROR_COMMAND_SYNTAX_ERROR;
749 }
750
751 struct flash_bank *bank;
752 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
753 if (ERROR_OK != retval)
754 return retval;
755
756 if (bank->target->state != TARGET_HALTED)
757 {
758 LOG_ERROR("Target not halted");
759 return ERROR_TARGET_NOT_HALTED;
760 }
761
762 if ((status_code = lpc2000_iap_call(bank, 54, param_table, result_table)) != 0x0)
763 {
764 if (status_code == ERROR_FLASH_OPERATION_FAILED)
765 {
766 command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
767 return ERROR_OK;
768 }
769 command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
770 }
771 else
772 {
773 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32 , result_table[0]);
774 }
775
776 return ERROR_OK;
777 }
778
779 static int lpc2000_register_commands(struct command_context *cmd_ctx)
780 {
781 struct command *lpc2000_cmd = register_command(cmd_ctx, NULL, "lpc2000",
782 NULL, COMMAND_ANY, NULL);
783
784 register_command(cmd_ctx, lpc2000_cmd, "part_id",
785 lpc2000_handle_part_id_command, COMMAND_EXEC,
786 "print part id of lpc2000 flash bank <num>");
787
788 return ERROR_OK;
789 }
790
791 struct flash_driver lpc2000_flash = {
792 .name = "lpc2000",
793 .register_commands = &lpc2000_register_commands,
794 .flash_bank_command = &lpc2000_flash_bank_command,
795 .erase = &lpc2000_erase,
796 .protect = &lpc2000_protect,
797 .write = &lpc2000_write,
798 .probe = &lpc2000_probe,
799 .auto_probe = &lpc2000_probe,
800 .erase_check = &lpc2000_erase_check,
801 .protect_check = &lpc2000_protect_check,
802 .info = &lpc2000_info,
803 };
804
805

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)