cc10a3bb3a021387aff654a3819d4e64f42088d0
[openocd.git] / src / flash / nor / 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 * LPC1100 variant and auto-probing support Copyright (C) 2014 *
9 * by Cosmin Gorgovan cosmin [at] linux-geek [dot] org *
10 * *
11 * LPC800/LPC1500/LPC54100 support Copyright (C) 2013/2014 *
12 * by Nemui Trinomius *
13 * nemuisan_kawausogasuki@live.jp *
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
24 * *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
29 ***************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "imp.h"
36 #include <helper/binarybuffer.h>
37 #include <target/algorithm.h>
38 #include <target/arm_opcodes.h>
39 #include <target/armv7m.h>
40
41 /**
42 * @file
43 * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x and LPC2xxx devices.
44 *
45 * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
46 * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
47 */
48 /*
49 * currently supported devices:
50 * variant 1 (lpc2000_v1):
51 * - 2104 | 5 | 6
52 * - 2114 | 9
53 * - 2124 | 9
54 * - 2194
55 * - 2212 | 4
56 * - 2292 | 4
57 *
58 * variant 2 (lpc2000_v2):
59 * - 213x
60 * - 214x
61 * - 2101 | 2 | 3
62 * - 2364 | 6 | 8
63 * - 2378
64 *
65 * lpc1700:
66 * - 175x
67 * - 176x (tested with LPC1768)
68 * - 177x
69 * - 178x (tested with LPC1788)
70 *
71 * lpc4000: (lpc1700's alias)
72 * - 407x
73 * - 408x (tested with LPC4088)
74 *
75 * lpc4300: (also available as lpc1800 - alias)
76 * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357)
77 * - 18x2 | 3 | 5 | 7
78 *
79 * lpc800:
80 * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812)
81 * - 822 | 4 (tested with LPC824)
82 *
83 * lpc1100:
84 * - 11xx
85 * - 11Axx
86 * - 11Cxx
87 * - 11Dxx
88 * - 11Exx
89 * - 11Uxx (tested with LPC11U34)
90 * - 131x
91 * - 134x
92 *
93 * lpc1500:
94 * - 15x7 | 8 | 9 (tested with LPC1549)
95 *
96 * lpc54100:
97 * - 54101 | 2 (tested with LPC54102)
98 *
99 * The auto variant auto-detects parts from the following series:
100 * - 11xx
101 * - 11Axx
102 * - 11Cxx
103 * - 11Dxx
104 * - 11Exx
105 * - 11Uxx
106 * - 131x
107 * - 134x
108 * - 175x
109 * - 176x
110 * - 177x
111 * - 178x
112 * - 407x
113 * - 408x
114 * - 81x
115 * - 82x
116 */
117
118 /* Part IDs for autodetection */
119 /* A script which can automatically extract part ids from user manuals is available here:
120 * https://github.com/lgeek/lpc_part_ids
121 */
122 #define LPC1110_1 0x0A07102B
123 #define LPC1110_2 0x1A07102B
124 #define LPC1111_002_1 0x0A16D02B
125 #define LPC1111_002_2 0x1A16D02B
126 #define LPC1111_101_1 0x041E502B
127 #define LPC1111_101_2 0x2516D02B
128 #define LPC1111_103_1 0x00010013
129 #define LPC1111_201_1 0x0416502B
130 #define LPC1111_201_2 0x2516902B
131 #define LPC1111_203_1 0x00010012
132 #define LPC1112_101_1 0x042D502B
133 #define LPC1112_101_2 0x2524D02B
134 #define LPC1112_102_1 0x0A24902B
135 #define LPC1112_102_2 0x1A24902B
136 #define LPC1112_103_1 0x00020023
137 #define LPC1112_201_1 0x0425502B
138 #define LPC1112_201_2 0x2524902B
139 #define LPC1112_203_1 0x00020022
140 #define LPC1113_201_1 0x0434502B
141 #define LPC1113_201_2 0x2532902B
142 #define LPC1113_203_1 0x00030032
143 #define LPC1113_301_1 0x0434102B
144 #define LPC1113_301_2 0x2532102B
145 #define LPC1113_303_1 0x00030030
146 #define LPC1114_102_1 0x0A40902B
147 #define LPC1114_102_2 0x1A40902B
148 #define LPC1114_201_1 0x0444502B
149 #define LPC1114_201_2 0x2540902B
150 #define LPC1114_203_1 0x00040042
151 #define LPC1114_301_1 0x0444102B
152 #define LPC1114_301_2 0x2540102B
153 #define LPC1114_303_1 0x00040040
154 #define LPC1114_323_1 0x00040060
155 #define LPC1114_333_1 0x00040070
156 #define LPC1115_303_1 0x00050080
157
158 #define LPC11A02_1 0x4D4C802B
159 #define LPC11A04_1 0x4D80002B
160 #define LPC11A11_001_1 0x455EC02B
161 #define LPC11A12_101_1 0x4574802B
162 #define LPC11A13_201_1 0x458A402B
163 #define LPC11A14_301_1 0x35A0002B
164 #define LPC11A14_301_2 0x45A0002B
165
166 #define LPC11C12_301_1 0x1421102B
167 #define LPC11C14_301_1 0x1440102B
168 #define LPC11C22_301_1 0x1431102B
169 #define LPC11C24_301_1 0x1430102B
170
171 #define LPC11E11_101 0x293E902B
172 #define LPC11E12_201 0x2954502B
173 #define LPC11E13_301 0x296A102B
174 #define LPC11E14_401 0x2980102B
175 #define LPC11E36_501 0x00009C41
176 #define LPC11E37_401 0x00007C45
177 #define LPC11E37_501 0x00007C41
178
179 #define LPC11U12_201_1 0x095C802B
180 #define LPC11U12_201_2 0x295C802B
181 #define LPC11U13_201_1 0x097A802B
182 #define LPC11U13_201_2 0x297A802B
183 #define LPC11U14_201_1 0x0998802B
184 #define LPC11U14_201_2 0x2998802B
185 #define LPC11U23_301 0x2972402B
186 #define LPC11U24_301 0x2988402B
187 #define LPC11U24_401 0x2980002B
188 #define LPC11U34_311 0x0003D440
189 #define LPC11U34_421 0x0001CC40
190 #define LPC11U35_401 0x0001BC40
191 #define LPC11U35_501 0x0000BC40
192 #define LPC11U36_401 0x00019C40
193 #define LPC11U37_401 0x00017C40
194 #define LPC11U37H_401 0x00007C44
195 #define LPC11U37_501 0x00007C40
196
197 #define LPC11E66 0x0000DCC1
198 #define LPC11E67 0x0000BC81
199 #define LPC11E68 0x00007C01
200
201 #define LPC11U66 0x0000DCC8
202 #define LPC11U67_1 0x0000BC88
203 #define LPC11U67_2 0x0000BC80
204 #define LPC11U68_1 0x00007C08
205 #define LPC11U68_2 0x00007C00
206
207 #define LPC1311 0x2C42502B
208 #define LPC1311_1 0x1816902B
209 #define LPC1313 0x2C40102B
210 #define LPC1313_1 0x1830102B
211 #define LPC1315 0x3A010523
212 #define LPC1316 0x1A018524
213 #define LPC1317 0x1A020525
214 #define LPC1342 0x3D01402B
215 #define LPC1343 0x3D00002B
216 #define LPC1343_1 0x3000002B
217 #define LPC1345 0x28010541
218 #define LPC1346 0x08018542
219 #define LPC1347 0x08020543
220
221 #define LPC1751_1 0x25001110
222 #define LPC1751_2 0x25001118
223 #define LPC1752 0x25001121
224 #define LPC1754 0x25011722
225 #define LPC1756 0x25011723
226 #define LPC1758 0x25013F37
227 #define LPC1759 0x25113737
228 #define LPC1763 0x26012033
229 #define LPC1764 0x26011922
230 #define LPC1765 0x26013733
231 #define LPC1766 0x26013F33
232 #define LPC1767 0x26012837
233 #define LPC1768 0x26013F37
234 #define LPC1769 0x26113F37
235 #define LPC1774 0x27011132
236 #define LPC1776 0x27191F43
237 #define LPC1777 0x27193747
238 #define LPC1778 0x27193F47
239 #define LPC1785 0x281D1743
240 #define LPC1786 0x281D1F43
241 #define LPC1787 0x281D3747
242 #define LPC1788 0x281D3F47
243
244 #define LPC4072 0x47011121
245 #define LPC4074 0x47011132
246 #define LPC4076 0x47191F43
247 #define LPC4078 0x47193F47
248 #define LPC4088 0x481D3F47
249
250 #define LPC810_021 0x00008100
251 #define LPC811_001 0x00008110
252 #define LPC812_101 0x00008120
253 #define LPC812_101_1 0x00008121
254 #define LPC812_101_2 0x00008122
255 #define LPC812_101_3 0x00008123
256
257 #define LPC822_101 0x00008221
258 #define LPC822_101_1 0x00008222
259 #define LPC824_201 0x00008241
260 #define LPC824_201_1 0x00008242
261
262 #define IAP_CODE_LEN 0x34
263
264 typedef enum {
265 lpc2000_v1,
266 lpc2000_v2,
267 lpc1700,
268 lpc4300,
269 lpc800,
270 lpc1100,
271 lpc1500,
272 lpc54100,
273 lpc_auto,
274 } lpc2000_variant;
275
276 struct lpc2000_flash_bank {
277 lpc2000_variant variant;
278 uint32_t cclk;
279 int cmd51_dst_boundary;
280 int calc_checksum;
281 uint32_t cmd51_max_buffer;
282 int checksum_vector;
283 uint32_t iap_max_stack;
284 uint32_t lpc4300_bank;
285 bool probed;
286 };
287
288 enum lpc2000_status_codes {
289 LPC2000_CMD_SUCCESS = 0,
290 LPC2000_INVALID_COMMAND = 1,
291 LPC2000_SRC_ADDR_ERROR = 2,
292 LPC2000_DST_ADDR_ERROR = 3,
293 LPC2000_SRC_ADDR_NOT_MAPPED = 4,
294 LPC2000_DST_ADDR_NOT_MAPPED = 5,
295 LPC2000_COUNT_ERROR = 6,
296 LPC2000_INVALID_SECTOR = 7,
297 LPC2000_SECTOR_NOT_BLANK = 8,
298 LPC2000_SECTOR_NOT_PREPARED = 9,
299 LPC2000_COMPARE_ERROR = 10,
300 LPC2000_BUSY = 11,
301 LPC2000_PARAM_ERROR = 12,
302 LPC2000_ADDR_ERROR = 13,
303 LPC2000_ADDR_NOT_MAPPED = 14,
304 LPC2000_CMD_NOT_LOCKED = 15,
305 LPC2000_INVALID_CODE = 16,
306 LPC2000_INVALID_BAUD_RATE = 17,
307 LPC2000_INVALID_STOP_BIT = 18,
308 LPC2000_CRP_ENABLED = 19,
309 LPC2000_INVALID_FLASH_UNIT = 20,
310 LPC2000_USER_CODE_CHECKSUM = 21,
311 LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22,
312 };
313
314 static int lpc2000_build_sector_list(struct flash_bank *bank)
315 {
316 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
317 uint32_t offset = 0;
318
319 /* default to a 4096 write buffer */
320 lpc2000_info->cmd51_max_buffer = 4096;
321
322 if (lpc2000_info->variant == lpc2000_v1) {
323 lpc2000_info->cmd51_dst_boundary = 512;
324 lpc2000_info->checksum_vector = 5;
325 lpc2000_info->iap_max_stack = 128;
326
327 /* variant 1 has different layout for 128kb and 256kb flashes */
328 if (bank->size == 128 * 1024) {
329 bank->num_sectors = 16;
330 bank->sectors = malloc(sizeof(struct flash_sector) * 16);
331 for (int i = 0; i < 16; i++) {
332 bank->sectors[i].offset = offset;
333 bank->sectors[i].size = 8 * 1024;
334 offset += bank->sectors[i].size;
335 bank->sectors[i].is_erased = -1;
336 bank->sectors[i].is_protected = 1;
337 }
338 } else if (bank->size == 256 * 1024) {
339 bank->num_sectors = 18;
340 bank->sectors = malloc(sizeof(struct flash_sector) * 18);
341
342 for (int i = 0; i < 8; i++) {
343 bank->sectors[i].offset = offset;
344 bank->sectors[i].size = 8 * 1024;
345 offset += bank->sectors[i].size;
346 bank->sectors[i].is_erased = -1;
347 bank->sectors[i].is_protected = 1;
348 }
349 for (int i = 8; i < 10; i++) {
350 bank->sectors[i].offset = offset;
351 bank->sectors[i].size = 64 * 1024;
352 offset += bank->sectors[i].size;
353 bank->sectors[i].is_erased = -1;
354 bank->sectors[i].is_protected = 1;
355 }
356 for (int i = 10; i < 18; i++) {
357 bank->sectors[i].offset = offset;
358 bank->sectors[i].size = 8 * 1024;
359 offset += bank->sectors[i].size;
360 bank->sectors[i].is_erased = -1;
361 bank->sectors[i].is_protected = 1;
362 }
363 } else {
364 LOG_ERROR("BUG: unknown bank->size encountered");
365 exit(-1);
366 }
367 } else if (lpc2000_info->variant == lpc2000_v2) {
368 lpc2000_info->cmd51_dst_boundary = 256;
369 lpc2000_info->checksum_vector = 5;
370 lpc2000_info->iap_max_stack = 128;
371
372 /* variant 2 has a uniform layout, only number of sectors differs */
373 switch (bank->size) {
374 case 4 * 1024:
375 lpc2000_info->cmd51_max_buffer = 1024;
376 bank->num_sectors = 1;
377 break;
378 case 8 * 1024:
379 lpc2000_info->cmd51_max_buffer = 1024;
380 bank->num_sectors = 2;
381 break;
382 case 16 * 1024:
383 bank->num_sectors = 4;
384 break;
385 case 32 * 1024:
386 bank->num_sectors = 8;
387 break;
388 case 64 * 1024:
389 bank->num_sectors = 9;
390 break;
391 case 128 * 1024:
392 bank->num_sectors = 11;
393 break;
394 case 256 * 1024:
395 bank->num_sectors = 15;
396 break;
397 case 500 * 1024:
398 bank->num_sectors = 27;
399 break;
400 case 512 * 1024:
401 case 504 * 1024:
402 bank->num_sectors = 28;
403 break;
404 default:
405 LOG_ERROR("BUG: unknown bank->size encountered");
406 exit(-1);
407 break;
408 }
409
410 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
411
412 for (int i = 0; i < bank->num_sectors; i++) {
413 if (i < 8) {
414 bank->sectors[i].offset = offset;
415 bank->sectors[i].size = 4 * 1024;
416 offset += bank->sectors[i].size;
417 bank->sectors[i].is_erased = -1;
418 bank->sectors[i].is_protected = 1;
419 } else if (i < 22) {
420 bank->sectors[i].offset = offset;
421 bank->sectors[i].size = 32 * 1024;
422 offset += bank->sectors[i].size;
423 bank->sectors[i].is_erased = -1;
424 bank->sectors[i].is_protected = 1;
425 } else if (i < 28) {
426 bank->sectors[i].offset = offset;
427 bank->sectors[i].size = 4 * 1024;
428 offset += bank->sectors[i].size;
429 bank->sectors[i].is_erased = -1;
430 bank->sectors[i].is_protected = 1;
431 }
432 }
433 } else if (lpc2000_info->variant == lpc1700) {
434 lpc2000_info->cmd51_dst_boundary = 256;
435 lpc2000_info->checksum_vector = 7;
436 lpc2000_info->iap_max_stack = 128;
437
438 switch (bank->size) {
439 case 4 * 1024:
440 lpc2000_info->cmd51_max_buffer = 256;
441 bank->num_sectors = 1;
442 break;
443 case 8 * 1024:
444 lpc2000_info->cmd51_max_buffer = 512;
445 bank->num_sectors = 2;
446 break;
447 case 16 * 1024:
448 lpc2000_info->cmd51_max_buffer = 512;
449 bank->num_sectors = 4;
450 break;
451 case 32 * 1024:
452 lpc2000_info->cmd51_max_buffer = 1024;
453 bank->num_sectors = 8;
454 break;
455 case 64 * 1024:
456 bank->num_sectors = 16;
457 break;
458 case 128 * 1024:
459 bank->num_sectors = 18;
460 break;
461 case 256 * 1024:
462 bank->num_sectors = 22;
463 break;
464 case 512 * 1024:
465 bank->num_sectors = 30;
466 break;
467 default:
468 LOG_ERROR("BUG: unknown bank->size encountered");
469 exit(-1);
470 }
471
472 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
473
474 for (int i = 0; i < bank->num_sectors; i++) {
475 bank->sectors[i].offset = offset;
476 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */
477 bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;
478 offset += bank->sectors[i].size;
479 bank->sectors[i].is_erased = -1;
480 bank->sectors[i].is_protected = 1;
481 }
482 } else if (lpc2000_info->variant == lpc4300) {
483 lpc2000_info->cmd51_dst_boundary = 512;
484 lpc2000_info->checksum_vector = 7;
485 lpc2000_info->iap_max_stack = 208;
486
487 switch (bank->size) {
488 case 256 * 1024:
489 bank->num_sectors = 11;
490 break;
491 case 384 * 1024:
492 bank->num_sectors = 13;
493 break;
494 case 512 * 1024:
495 bank->num_sectors = 15;
496 break;
497 default:
498 LOG_ERROR("BUG: unknown bank->size encountered");
499 exit(-1);
500 }
501
502 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
503
504 for (int i = 0; i < bank->num_sectors; i++) {
505 bank->sectors[i].offset = offset;
506 /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
507 bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024;
508 offset += bank->sectors[i].size;
509 bank->sectors[i].is_erased = -1;
510 bank->sectors[i].is_protected = 1;
511 }
512
513 } else if (lpc2000_info->variant == lpc800) {
514 lpc2000_info->cmd51_dst_boundary = 64;
515 lpc2000_info->checksum_vector = 7;
516 lpc2000_info->iap_max_stack = 208; /* 148byte for LPC81x,208byte for LPC82x. */
517 lpc2000_info->cmd51_max_buffer = 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */
518
519 switch (bank->size) {
520 case 4 * 1024:
521 bank->num_sectors = 4;
522 break;
523 case 8 * 1024:
524 bank->num_sectors = 8;
525 break;
526 case 16 * 1024:
527 bank->num_sectors = 16;
528 break;
529 case 32 * 1024:
530 lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */
531 bank->num_sectors = 32;
532 break;
533 default:
534 LOG_ERROR("BUG: unknown bank->size encountered");
535 exit(-1);
536 }
537
538 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
539
540 for (int i = 0; i < bank->num_sectors; i++) {
541 bank->sectors[i].offset = offset;
542 /* all sectors are 1kB-sized for LPC8xx devices */
543 bank->sectors[i].size = 1 * 1024;
544 offset += bank->sectors[i].size;
545 bank->sectors[i].is_erased = -1;
546 bank->sectors[i].is_protected = 1;
547 }
548
549 } else if (lpc2000_info->variant == lpc1100) {
550 lpc2000_info->cmd51_dst_boundary = 256;
551 lpc2000_info->checksum_vector = 7;
552 lpc2000_info->iap_max_stack = 128;
553
554 if ((bank->size % (4 * 1024)) != 0) {
555 LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096");
556 exit(-1);
557 }
558 lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
559 bank->num_sectors = bank->size / 4096;
560
561 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
562
563 for (int i = 0; i < bank->num_sectors; i++) {
564 bank->sectors[i].offset = offset;
565 /* all sectors are 4kB-sized */
566 bank->sectors[i].size = 4 * 1024;
567 offset += bank->sectors[i].size;
568 bank->sectors[i].is_erased = -1;
569 bank->sectors[i].is_protected = 1;
570 }
571
572 } else if (lpc2000_info->variant == lpc1500) {
573 lpc2000_info->cmd51_dst_boundary = 256;
574 lpc2000_info->checksum_vector = 7;
575 lpc2000_info->iap_max_stack = 128;
576
577 switch (bank->size) {
578 case 64 * 1024:
579 bank->num_sectors = 16;
580 break;
581 case 128 * 1024:
582 bank->num_sectors = 32;
583 break;
584 case 256 * 1024:
585 bank->num_sectors = 64;
586 break;
587 default:
588 LOG_ERROR("BUG: unknown bank->size encountered");
589 exit(-1);
590 }
591
592 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
593
594 for (int i = 0; i < bank->num_sectors; i++) {
595 bank->sectors[i].offset = offset;
596 /* all sectors are 4kB-sized */
597 bank->sectors[i].size = 4 * 1024;
598 offset += bank->sectors[i].size;
599 bank->sectors[i].is_erased = -1;
600 bank->sectors[i].is_protected = 1;
601 }
602
603 } else if (lpc2000_info->variant == lpc54100) {
604 lpc2000_info->cmd51_dst_boundary = 256;
605 lpc2000_info->checksum_vector = 7;
606 lpc2000_info->iap_max_stack = 128;
607
608 switch (bank->size) {
609 case 256 * 1024:
610 bank->num_sectors = 8;
611 break;
612 case 512 * 1024:
613 bank->num_sectors = 16;
614 break;
615 default:
616 LOG_ERROR("BUG: unknown bank->size encountered");
617 exit(-1);
618 }
619
620 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
621
622 for (int i = 0; i < bank->num_sectors; i++) {
623 bank->sectors[i].offset = offset;
624 /* all sectors are 32kB-sized */
625 bank->sectors[i].size = 32 * 1024;
626 offset += bank->sectors[i].size;
627 bank->sectors[i].is_erased = -1;
628 bank->sectors[i].is_protected = 1;
629 }
630
631 } else {
632 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
633 exit(-1);
634 }
635
636 return ERROR_OK;
637 }
638
639 /* this function allocates and initializes working area used for IAP algorithm
640 * uses 52 + max IAP stack bytes working area
641 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
642 * 0x8 to 0x1f: command parameter table (1+5 words)
643 * 0x20 to 0x33: command result table (1+4 words)
644 * 0x34 to 0xb3|0x104: stack
645 * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x)
646 */
647
648 static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
649 {
650 struct target *target = bank->target;
651 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
652
653 if (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {
654 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
655 return ERROR_FLASH_OPERATION_FAILED;
656 }
657
658 uint8_t jump_gate[8];
659
660 /* write IAP code to working area */
661 switch (lpc2000_info->variant) {
662 case lpc800:
663 case lpc1100:
664 case lpc1500:
665 case lpc1700:
666 case lpc4300:
667 case lpc54100:
668 case lpc_auto:
669 target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
670 target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
671 break;
672 case lpc2000_v1:
673 case lpc2000_v2:
674 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
675 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
676 break;
677 default:
678 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
679 exit(-1);
680 }
681
682 int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
683 if (retval != ERROR_OK) {
684 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
685 (*iap_working_area)->address);
686 target_free_working_area(target, *iap_working_area);
687 }
688
689 return retval;
690 }
691
692 /* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */
693
694 static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
695 uint32_t param_table[5], uint32_t result_table[4])
696 {
697 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
698 struct target *target = bank->target;
699
700 struct arm_algorithm arm_algo; /* for LPC2000 */
701 struct armv7m_algorithm armv7m_info; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */
702 uint32_t iap_entry_point = 0; /* to make compiler happier */
703
704 switch (lpc2000_info->variant) {
705 case lpc800:
706 case lpc1100:
707 case lpc1700:
708 case lpc_auto:
709 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
710 armv7m_info.core_mode = ARM_MODE_THREAD;
711 iap_entry_point = 0x1fff1ff1;
712 break;
713 case lpc1500:
714 case lpc54100:
715 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
716 armv7m_info.core_mode = ARM_MODE_THREAD;
717 iap_entry_point = 0x03000205;
718 break;
719 case lpc2000_v1:
720 case lpc2000_v2:
721 arm_algo.common_magic = ARM_COMMON_MAGIC;
722 arm_algo.core_mode = ARM_MODE_SVC;
723 arm_algo.core_state = ARM_STATE_ARM;
724 iap_entry_point = 0x7ffffff1;
725 break;
726 case lpc4300:
727 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
728 armv7m_info.core_mode = ARM_MODE_THREAD;
729 /* read out IAP entry point from ROM driver table at 0x10400100 */
730 target_read_u32(target, 0x10400100, &iap_entry_point);
731 break;
732 default:
733 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
734 exit(-1);
735 }
736
737 struct mem_param mem_params[2];
738
739 /* command parameter table */
740 init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
741 target_buffer_set_u32(target, mem_params[0].value, code);
742 target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
743 target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
744 target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
745 target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
746 target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
747
748 struct reg_param reg_params[5];
749
750 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
751 buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
752
753 /* command result table */
754 init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
755
756 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
757 buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
758
759 /* IAP entry point */
760 init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
761 buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
762
763 switch (lpc2000_info->variant) {
764 case lpc800:
765 case lpc1100:
766 case lpc1500:
767 case lpc1700:
768 case lpc4300:
769 case lpc54100:
770 case lpc_auto:
771 /* IAP stack */
772 init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
773 buf_set_u32(reg_params[3].value, 0, 32,
774 iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);
775
776 /* return address */
777 init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
778 buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
779 /* bit0 of LR = 1 to return in Thumb mode */
780
781 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
782 &armv7m_info);
783 break;
784 case lpc2000_v1:
785 case lpc2000_v2:
786 /* IAP stack */
787 init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
788 buf_set_u32(reg_params[3].value, 0, 32,
789 iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);
790
791 /* return address */
792 init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
793 buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
794
795 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
796 iap_working_area->address + 0x4, 10000, &arm_algo);
797 break;
798 default:
799 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
800 exit(-1);
801 }
802
803 int status_code = target_buffer_get_u32(target, mem_params[1].value);
804 result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
805 result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
806 result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
807 result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
808
809 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
810 ") completed with result = %8.8x",
811 code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
812
813 destroy_mem_param(&mem_params[0]);
814 destroy_mem_param(&mem_params[1]);
815
816 destroy_reg_param(&reg_params[0]);
817 destroy_reg_param(&reg_params[1]);
818 destroy_reg_param(&reg_params[2]);
819 destroy_reg_param(&reg_params[3]);
820 destroy_reg_param(&reg_params[4]);
821
822 return status_code;
823 }
824
825 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
826 {
827 if ((first < 0) || (last >= bank->num_sectors))
828 return ERROR_FLASH_SECTOR_INVALID;
829
830 uint32_t param_table[5] = {0};
831 uint32_t result_table[4];
832 struct working_area *iap_working_area;
833
834 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
835
836 if (retval != ERROR_OK)
837 return retval;
838
839 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
840 if (lpc2000_info->variant == lpc4300)
841 param_table[2] = lpc2000_info->lpc4300_bank;
842
843 for (int i = first; i <= last && retval == ERROR_OK; i++) {
844 /* check single sector */
845 param_table[0] = param_table[1] = i;
846 int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
847
848 switch (status_code) {
849 case ERROR_FLASH_OPERATION_FAILED:
850 retval = ERROR_FLASH_OPERATION_FAILED;
851 break;
852 case LPC2000_CMD_SUCCESS:
853 bank->sectors[i].is_erased = 1;
854 break;
855 case LPC2000_SECTOR_NOT_BLANK:
856 bank->sectors[i].is_erased = 0;
857 break;
858 case LPC2000_INVALID_SECTOR:
859 bank->sectors[i].is_erased = 0;
860 break;
861 case LPC2000_BUSY:
862 retval = ERROR_FLASH_BUSY;
863 break;
864 default:
865 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
866 exit(-1);
867 }
868 }
869
870 struct target *target = bank->target;
871 target_free_working_area(target, iap_working_area);
872
873 return retval;
874 }
875
876 /*
877 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
878 */
879 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
880 {
881 if (CMD_ARGC < 8)
882 return ERROR_COMMAND_SYNTAX_ERROR;
883
884 struct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info));
885 lpc2000_info->probed = false;
886
887 bank->driver_priv = lpc2000_info;
888
889 if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
890 lpc2000_info->variant = lpc2000_v1;
891 } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
892 lpc2000_info->variant = lpc2000_v2;
893 } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0 || strcmp(CMD_ARGV[6], "lpc4000") == 0) {
894 lpc2000_info->variant = lpc1700;
895 } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) {
896 lpc2000_info->variant = lpc4300;
897 } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) {
898 lpc2000_info->variant = lpc800;
899 } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) {
900 lpc2000_info->variant = lpc1100;
901 } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) {
902 lpc2000_info->variant = lpc1500;
903 } else if (strcmp(CMD_ARGV[6], "lpc54100") == 0) {
904 lpc2000_info->variant = lpc54100;
905 } else if (strcmp(CMD_ARGV[6], "auto") == 0) {
906 lpc2000_info->variant = lpc_auto;
907 } else {
908 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
909 free(lpc2000_info);
910 return ERROR_FLASH_BANK_INVALID;
911 }
912
913 /* Maximum size required for the IAP stack.
914 This value only gets used when probing, only for auto, lpc1100 and lpc1700.
915 We use the maximum size for any part supported by the driver(!) to be safe
916 in case the auto variant is mistakenly used on a MCU from one of the series
917 for which we don't support auto-probing. */
918 lpc2000_info->iap_max_stack = 208;
919
920 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
921 lpc2000_info->calc_checksum = 0;
922
923 uint32_t temp_base = 0;
924 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
925 if (temp_base >= 0x1B000000)
926 lpc2000_info->lpc4300_bank = 1; /* bank B */
927 else
928 lpc2000_info->lpc4300_bank = 0; /* bank A */
929
930 if (CMD_ARGC >= 9) {
931 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
932 lpc2000_info->calc_checksum = 1;
933 }
934
935 return ERROR_OK;
936 }
937
938 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
939 {
940 if (bank->target->state != TARGET_HALTED) {
941 LOG_ERROR("Target not halted");
942 return ERROR_TARGET_NOT_HALTED;
943 }
944
945 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
946 uint32_t param_table[5] = {0};
947
948 param_table[0] = first;
949 param_table[1] = last;
950
951 if (lpc2000_info->variant == lpc4300)
952 param_table[2] = lpc2000_info->lpc4300_bank;
953 else
954 param_table[2] = lpc2000_info->cclk;
955
956 uint32_t result_table[4];
957 struct working_area *iap_working_area;
958
959 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
960
961 if (retval != ERROR_OK)
962 return retval;
963
964 if (lpc2000_info->variant == lpc4300)
965 /* Init IAP Anyway */
966 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
967
968 /* Prepare sectors */
969 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
970 switch (status_code) {
971 case ERROR_FLASH_OPERATION_FAILED:
972 retval = ERROR_FLASH_OPERATION_FAILED;
973 break;
974 case LPC2000_CMD_SUCCESS:
975 break;
976 case LPC2000_INVALID_SECTOR:
977 retval = ERROR_FLASH_SECTOR_INVALID;
978 break;
979 default:
980 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
981 retval = ERROR_FLASH_OPERATION_FAILED;
982 break;
983 }
984
985 if (retval == ERROR_OK) {
986 /* Erase sectors */
987 param_table[2] = lpc2000_info->cclk;
988 if (lpc2000_info->variant == lpc4300)
989 param_table[3] = lpc2000_info->lpc4300_bank;
990
991 status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
992 switch (status_code) {
993 case ERROR_FLASH_OPERATION_FAILED:
994 retval = ERROR_FLASH_OPERATION_FAILED;
995 break;
996 case LPC2000_CMD_SUCCESS:
997 break;
998 case LPC2000_INVALID_SECTOR:
999 retval = ERROR_FLASH_SECTOR_INVALID;
1000 break;
1001 default:
1002 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
1003 retval = ERROR_FLASH_OPERATION_FAILED;
1004 break;
1005 }
1006 }
1007
1008 struct target *target = bank->target;
1009 target_free_working_area(target, iap_working_area);
1010
1011 return retval;
1012 }
1013
1014 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
1015 {
1016 /* can't protect/unprotect on the lpc2000 */
1017 return ERROR_OK;
1018 }
1019
1020 static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
1021 {
1022 struct target *target = bank->target;
1023
1024 if (bank->target->state != TARGET_HALTED) {
1025 LOG_ERROR("Target not halted");
1026 return ERROR_TARGET_NOT_HALTED;
1027 }
1028
1029 if (offset + count > bank->size)
1030 return ERROR_FLASH_DST_OUT_OF_BANK;
1031
1032 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1033
1034 uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
1035
1036 if (offset % dst_min_alignment) {
1037 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
1038 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1039 }
1040
1041 int first_sector = 0;
1042 int last_sector = 0;
1043
1044 for (int i = 0; i < bank->num_sectors; i++) {
1045 if (offset >= bank->sectors[i].offset)
1046 first_sector = i;
1047 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
1048 last_sector = i;
1049 }
1050
1051 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
1052
1053 /* check if exception vectors should be flashed */
1054 if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
1055 assert(lpc2000_info->checksum_vector < 8);
1056 uint32_t checksum = 0;
1057 for (int i = 0; i < 8; i++) {
1058 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
1059 if (i != lpc2000_info->checksum_vector)
1060 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
1061 }
1062 checksum = 0 - checksum;
1063 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
1064
1065 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
1066 if (original_value != checksum) {
1067 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
1068 "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
1069 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
1070 "checksum.");
1071 }
1072
1073 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
1074 buf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
1075 }
1076
1077 struct working_area *iap_working_area;
1078
1079 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
1080
1081 if (retval != ERROR_OK)
1082 return retval;
1083
1084 struct working_area *download_area;
1085
1086 /* allocate a working area */
1087 if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
1088 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
1089 target_free_working_area(target, iap_working_area);
1090 return ERROR_FLASH_OPERATION_FAILED;
1091 }
1092
1093 uint32_t bytes_remaining = count;
1094 uint32_t bytes_written = 0;
1095 uint32_t param_table[5] = {0};
1096 uint32_t result_table[4];
1097
1098 if (lpc2000_info->variant == lpc4300)
1099 /* Init IAP Anyway */
1100 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
1101
1102 while (bytes_remaining > 0) {
1103 uint32_t thisrun_bytes;
1104 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
1105 thisrun_bytes = lpc2000_info->cmd51_max_buffer;
1106 else
1107 thisrun_bytes = lpc2000_info->cmd51_dst_boundary;
1108
1109 /* Prepare sectors */
1110 param_table[0] = first_sector;
1111 param_table[1] = last_sector;
1112
1113 if (lpc2000_info->variant == lpc4300)
1114 param_table[2] = lpc2000_info->lpc4300_bank;
1115 else
1116 param_table[2] = lpc2000_info->cclk;
1117
1118 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
1119 switch (status_code) {
1120 case ERROR_FLASH_OPERATION_FAILED:
1121 retval = ERROR_FLASH_OPERATION_FAILED;
1122 break;
1123 case LPC2000_CMD_SUCCESS:
1124 break;
1125 case LPC2000_INVALID_SECTOR:
1126 retval = ERROR_FLASH_SECTOR_INVALID;
1127 break;
1128 default:
1129 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
1130 retval = ERROR_FLASH_OPERATION_FAILED;
1131 break;
1132 }
1133
1134 /* Exit if error occured */
1135 if (retval != ERROR_OK)
1136 break;
1137
1138 if (bytes_remaining >= thisrun_bytes) {
1139 retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
1140 if (retval != ERROR_OK) {
1141 retval = ERROR_FLASH_OPERATION_FAILED;
1142 break;
1143 }
1144 } else {
1145 uint8_t *last_buffer = malloc(thisrun_bytes);
1146 memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
1147 memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
1148 target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
1149 free(last_buffer);
1150 }
1151
1152 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
1153 bank->base + offset + bytes_written);
1154
1155 /* Write data */
1156 param_table[0] = bank->base + offset + bytes_written;
1157 param_table[1] = download_area->address;
1158 param_table[2] = thisrun_bytes;
1159 param_table[3] = lpc2000_info->cclk;
1160 status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
1161 switch (status_code) {
1162 case ERROR_FLASH_OPERATION_FAILED:
1163 retval = ERROR_FLASH_OPERATION_FAILED;
1164 break;
1165 case LPC2000_CMD_SUCCESS:
1166 break;
1167 case LPC2000_INVALID_SECTOR:
1168 retval = ERROR_FLASH_SECTOR_INVALID;
1169 break;
1170 default:
1171 LOG_WARNING("lpc2000 returned %i", status_code);
1172 retval = ERROR_FLASH_OPERATION_FAILED;
1173 break;
1174 }
1175
1176 /* Exit if error occured */
1177 if (retval != ERROR_OK)
1178 break;
1179
1180 if (bytes_remaining > thisrun_bytes)
1181 bytes_remaining -= thisrun_bytes;
1182 else
1183 bytes_remaining = 0;
1184 bytes_written += thisrun_bytes;
1185 }
1186
1187 target_free_working_area(target, iap_working_area);
1188 target_free_working_area(target, download_area);
1189
1190 return retval;
1191 }
1192
1193 static int get_lpc2000_part_id(struct flash_bank *bank, uint32_t *part_id)
1194 {
1195 if (bank->target->state != TARGET_HALTED) {
1196 LOG_ERROR("Target not halted");
1197 return ERROR_TARGET_NOT_HALTED;
1198 }
1199
1200 uint32_t param_table[5] = {0};
1201 uint32_t result_table[4];
1202 struct working_area *iap_working_area;
1203
1204 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
1205
1206 if (retval != ERROR_OK)
1207 return retval;
1208
1209 /* The status seems to be bogus with the part ID command on some IAP
1210 firmwares, so ignore it. */
1211 lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
1212
1213 struct target *target = bank->target;
1214 target_free_working_area(target, iap_working_area);
1215
1216 /* If the result is zero, the command probably didn't work out. */
1217 if (result_table[0] == 0)
1218 return LPC2000_INVALID_COMMAND;
1219
1220 *part_id = result_table[0];
1221 return LPC2000_CMD_SUCCESS;
1222 }
1223
1224 static int lpc2000_auto_probe_flash(struct flash_bank *bank)
1225 {
1226 uint32_t part_id;
1227 int retval;
1228 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1229
1230 if (bank->target->state != TARGET_HALTED) {
1231 LOG_ERROR("Target not halted");
1232 return ERROR_TARGET_NOT_HALTED;
1233 }
1234
1235 retval = get_lpc2000_part_id(bank, &part_id);
1236 if (retval != LPC2000_CMD_SUCCESS) {
1237 LOG_ERROR("Could not get part ID");
1238 return retval;
1239 }
1240
1241 switch (part_id) {
1242 case LPC1110_1:
1243 case LPC1110_2:
1244 lpc2000_info->variant = lpc1100;
1245 bank->size = 4 * 1024;
1246 break;
1247
1248 case LPC1111_002_1:
1249 case LPC1111_002_2:
1250 case LPC1111_101_1:
1251 case LPC1111_101_2:
1252 case LPC1111_103_1:
1253 case LPC1111_201_1:
1254 case LPC1111_201_2:
1255 case LPC1111_203_1:
1256 case LPC11A11_001_1:
1257 case LPC11E11_101:
1258 case LPC1311:
1259 case LPC1311_1:
1260 lpc2000_info->variant = lpc1100;
1261 bank->size = 8 * 1024;
1262 break;
1263
1264 case LPC1112_101_1:
1265 case LPC1112_101_2:
1266 case LPC1112_102_1:
1267 case LPC1112_102_2:
1268 case LPC1112_103_1:
1269 case LPC1112_201_1:
1270 case LPC1112_201_2:
1271 case LPC1112_203_1:
1272 case LPC11A02_1:
1273 case LPC11C12_301_1:
1274 case LPC11C22_301_1:
1275 case LPC11A12_101_1:
1276 case LPC11E12_201:
1277 case LPC11U12_201_1:
1278 case LPC11U12_201_2:
1279 case LPC1342:
1280 lpc2000_info->variant = lpc1100;
1281 bank->size = 16 * 1024;
1282 break;
1283
1284 case LPC1113_201_1:
1285 case LPC1113_201_2:
1286 case LPC1113_203_1:
1287 case LPC1113_301_1:
1288 case LPC1113_301_2:
1289 case LPC1113_303_1:
1290 case LPC11A13_201_1:
1291 case LPC11E13_301:
1292 case LPC11U13_201_1:
1293 case LPC11U13_201_2:
1294 case LPC11U23_301:
1295 lpc2000_info->variant = lpc1100;
1296 bank->size = 24 * 1024;
1297 break;
1298
1299 case LPC1114_102_1:
1300 case LPC1114_102_2:
1301 case LPC1114_201_1:
1302 case LPC1114_201_2:
1303 case LPC1114_203_1:
1304 case LPC1114_301_1:
1305 case LPC1114_301_2:
1306 case LPC1114_303_1:
1307 case LPC11A04_1:
1308 case LPC11A14_301_1:
1309 case LPC11A14_301_2:
1310 case LPC11C14_301_1:
1311 case LPC11C24_301_1:
1312 case LPC11E14_401:
1313 case LPC11U14_201_1:
1314 case LPC11U14_201_2:
1315 case LPC11U24_301:
1316 case LPC11U24_401:
1317 case LPC1313:
1318 case LPC1313_1:
1319 case LPC1315:
1320 case LPC1343:
1321 case LPC1343_1:
1322 case LPC1345:
1323 lpc2000_info->variant = lpc1100;
1324 bank->size = 32 * 1024;
1325 break;
1326
1327 case LPC1751_1:
1328 case LPC1751_2:
1329 lpc2000_info->variant = lpc1700;
1330 bank->size = 32 * 1024;
1331 break;
1332
1333 case LPC11U34_311:
1334 lpc2000_info->variant = lpc1100;
1335 bank->size = 40 * 1024;
1336 break;
1337
1338 case LPC1114_323_1:
1339 case LPC11U34_421:
1340 case LPC1316:
1341 case LPC1346:
1342 lpc2000_info->variant = lpc1100;
1343 bank->size = 48 * 1024;
1344 break;
1345
1346 case LPC1114_333_1:
1347 lpc2000_info->variant = lpc1100;
1348 bank->size = 56 * 1024;
1349 break;
1350
1351 case LPC1115_303_1:
1352 case LPC11U35_401:
1353 case LPC11U35_501:
1354 case LPC11E66:
1355 case LPC11U66:
1356 case LPC1317:
1357 case LPC1347:
1358 lpc2000_info->variant = lpc1100;
1359 bank->size = 64 * 1024;
1360 break;
1361
1362 case LPC1752:
1363 case LPC4072:
1364 lpc2000_info->variant = lpc1700;
1365 bank->size = 64 * 1024;
1366 break;
1367
1368 case LPC11E36_501:
1369 case LPC11U36_401:
1370 lpc2000_info->variant = lpc1100;
1371 bank->size = 96 * 1024;
1372 break;
1373
1374 case LPC11E37_401:
1375 case LPC11E37_501:
1376 case LPC11U37_401:
1377 case LPC11U37H_401:
1378 case LPC11U37_501:
1379 case LPC11E67:
1380 case LPC11E68:
1381 case LPC11U67_1:
1382 case LPC11U67_2:
1383 lpc2000_info->variant = lpc1100;
1384 bank->size = 128 * 1024;
1385 break;
1386
1387 case LPC1754:
1388 case LPC1764:
1389 case LPC1774:
1390 case LPC4074:
1391 lpc2000_info->variant = lpc1700;
1392 bank->size = 128 * 1024;
1393 break;
1394
1395 case LPC11U68_1:
1396 case LPC11U68_2:
1397 lpc2000_info->variant = lpc1100;
1398 bank->size = 256 * 1024;
1399 break;
1400
1401 case LPC1756:
1402 case LPC1763:
1403 case LPC1765:
1404 case LPC1766:
1405 case LPC1776:
1406 case LPC1785:
1407 case LPC1786:
1408 case LPC4076:
1409 lpc2000_info->variant = lpc1700;
1410 bank->size = 256 * 1024;
1411 break;
1412
1413 case LPC1758:
1414 case LPC1759:
1415 case LPC1767:
1416 case LPC1768:
1417 case LPC1769:
1418 case LPC1777:
1419 case LPC1778:
1420 case LPC1787:
1421 case LPC1788:
1422 case LPC4078:
1423 case LPC4088:
1424 lpc2000_info->variant = lpc1700;
1425 bank->size = 512 * 1024;
1426 break;
1427
1428 case LPC810_021:
1429 lpc2000_info->variant = lpc800;
1430 bank->size = 4 * 1024;
1431 break;
1432
1433 case LPC811_001:
1434 lpc2000_info->variant = lpc800;
1435 bank->size = 8 * 1024;
1436 break;
1437
1438 case LPC812_101:
1439 case LPC812_101_1:
1440 case LPC812_101_2:
1441 case LPC812_101_3:
1442 case LPC822_101:
1443 case LPC822_101_1:
1444 lpc2000_info->variant = lpc800;
1445 bank->size = 16 * 1024;
1446 break;
1447
1448 case LPC824_201:
1449 case LPC824_201_1:
1450 lpc2000_info->variant = lpc800;
1451 bank->size = 32 * 1024;
1452 break;
1453
1454 default:
1455 LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32, part_id);
1456 exit(-1);
1457 }
1458
1459 return ERROR_OK;
1460 }
1461
1462 static int lpc2000_probe(struct flash_bank *bank)
1463 {
1464 int status;
1465 uint32_t part_id;
1466 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1467
1468 if (!lpc2000_info->probed) {
1469 if (lpc2000_info->variant == lpc_auto) {
1470 status = lpc2000_auto_probe_flash(bank);
1471 if (status != ERROR_OK)
1472 return status;
1473 } else if (lpc2000_info->variant == lpc1100 || lpc2000_info->variant == lpc1700) {
1474 status = get_lpc2000_part_id(bank, &part_id);
1475 if (status == LPC2000_CMD_SUCCESS)
1476 LOG_INFO("If auto-detection fails for this part, please email "
1477 "openocd-devel@lists.sourceforge.net, citing part id 0x%" PRIx32 ".\n", part_id);
1478 }
1479
1480 lpc2000_build_sector_list(bank);
1481 lpc2000_info->probed = true;
1482 }
1483
1484 return ERROR_OK;
1485 }
1486
1487 static int lpc2000_erase_check(struct flash_bank *bank)
1488 {
1489 if (bank->target->state != TARGET_HALTED) {
1490 LOG_ERROR("Target not halted");
1491 return ERROR_TARGET_NOT_HALTED;
1492 }
1493
1494 return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
1495 }
1496
1497 static int lpc2000_protect_check(struct flash_bank *bank)
1498 {
1499 /* sectors are always protected */
1500 return ERROR_OK;
1501 }
1502
1503 static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
1504 {
1505 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1506
1507 snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
1508 lpc2000_info->cclk);
1509
1510 return ERROR_OK;
1511 }
1512
1513 COMMAND_HANDLER(lpc2000_handle_part_id_command)
1514 {
1515 if (CMD_ARGC < 1)
1516 return ERROR_COMMAND_SYNTAX_ERROR;
1517
1518 struct flash_bank *bank;
1519 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1520 if (ERROR_OK != retval)
1521 return retval;
1522
1523 if (bank->target->state != TARGET_HALTED) {
1524 LOG_ERROR("Target not halted");
1525 return ERROR_TARGET_NOT_HALTED;
1526 }
1527
1528 uint32_t part_id;
1529 int status_code = get_lpc2000_part_id(bank, &part_id);
1530 if (status_code != 0x0) {
1531 if (status_code == ERROR_FLASH_OPERATION_FAILED) {
1532 command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
1533 } else
1534 command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
1535 } else
1536 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, part_id);
1537
1538 return retval;
1539 }
1540
1541 static const struct command_registration lpc2000_exec_command_handlers[] = {
1542 {
1543 .name = "part_id",
1544 .handler = lpc2000_handle_part_id_command,
1545 .mode = COMMAND_EXEC,
1546 .help = "print part id of lpc2000 flash bank <num>",
1547 .usage = "<bank>",
1548 },
1549 COMMAND_REGISTRATION_DONE
1550 };
1551 static const struct command_registration lpc2000_command_handlers[] = {
1552 {
1553 .name = "lpc2000",
1554 .mode = COMMAND_ANY,
1555 .help = "lpc2000 flash command group",
1556 .usage = "",
1557 .chain = lpc2000_exec_command_handlers,
1558 },
1559 COMMAND_REGISTRATION_DONE
1560 };
1561
1562 struct flash_driver lpc2000_flash = {
1563 .name = "lpc2000",
1564 .commands = lpc2000_command_handlers,
1565 .flash_bank_command = lpc2000_flash_bank_command,
1566 .erase = lpc2000_erase,
1567 .protect = lpc2000_protect,
1568 .write = lpc2000_write,
1569 .read = default_flash_read,
1570 .probe = lpc2000_probe,
1571 .auto_probe = lpc2000_probe,
1572 .erase_check = lpc2000_erase_check,
1573 .protect_check = lpc2000_protect_check,
1574 .info = get_lpc2000_info,
1575 };

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)