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

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)