atsamv: Support for ATSAMS70N19 Memory Configuration
[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 typedef enum {
263 lpc2000_v1,
264 lpc2000_v2,
265 lpc1700,
266 lpc4300,
267 lpc800,
268 lpc1100,
269 lpc1500,
270 lpc54100,
271 lpc_auto,
272 } lpc2000_variant;
273
274 struct lpc2000_flash_bank {
275 lpc2000_variant variant;
276 uint32_t cclk;
277 int cmd51_dst_boundary;
278 int calc_checksum;
279 uint32_t cmd51_max_buffer;
280 int checksum_vector;
281 uint32_t iap_max_stack;
282 uint32_t lpc4300_bank;
283 bool probed;
284 };
285
286 enum lpc2000_status_codes {
287 LPC2000_CMD_SUCCESS = 0,
288 LPC2000_INVALID_COMMAND = 1,
289 LPC2000_SRC_ADDR_ERROR = 2,
290 LPC2000_DST_ADDR_ERROR = 3,
291 LPC2000_SRC_ADDR_NOT_MAPPED = 4,
292 LPC2000_DST_ADDR_NOT_MAPPED = 5,
293 LPC2000_COUNT_ERROR = 6,
294 LPC2000_INVALID_SECTOR = 7,
295 LPC2000_SECTOR_NOT_BLANK = 8,
296 LPC2000_SECTOR_NOT_PREPARED = 9,
297 LPC2000_COMPARE_ERROR = 10,
298 LPC2000_BUSY = 11,
299 LPC2000_PARAM_ERROR = 12,
300 LPC2000_ADDR_ERROR = 13,
301 LPC2000_ADDR_NOT_MAPPED = 14,
302 LPC2000_CMD_NOT_LOCKED = 15,
303 LPC2000_INVALID_CODE = 16,
304 LPC2000_INVALID_BAUD_RATE = 17,
305 LPC2000_INVALID_STOP_BIT = 18,
306 LPC2000_CRP_ENABLED = 19,
307 LPC2000_INVALID_FLASH_UNIT = 20,
308 LPC2000_USER_CODE_CHECKSUM = 21,
309 LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22,
310 };
311
312 static int lpc2000_build_sector_list(struct flash_bank *bank)
313 {
314 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
315 uint32_t offset = 0;
316
317 /* default to a 4096 write buffer */
318 lpc2000_info->cmd51_max_buffer = 4096;
319
320 if (lpc2000_info->variant == lpc2000_v1) {
321 lpc2000_info->cmd51_dst_boundary = 512;
322 lpc2000_info->checksum_vector = 5;
323 lpc2000_info->iap_max_stack = 128;
324
325 /* variant 1 has different layout for 128kb and 256kb flashes */
326 if (bank->size == 128 * 1024) {
327 bank->num_sectors = 16;
328 bank->sectors = malloc(sizeof(struct flash_sector) * 16);
329 for (int i = 0; i < 16; i++) {
330 bank->sectors[i].offset = offset;
331 bank->sectors[i].size = 8 * 1024;
332 offset += bank->sectors[i].size;
333 bank->sectors[i].is_erased = -1;
334 bank->sectors[i].is_protected = 1;
335 }
336 } else if (bank->size == 256 * 1024) {
337 bank->num_sectors = 18;
338 bank->sectors = malloc(sizeof(struct flash_sector) * 18);
339
340 for (int i = 0; i < 8; i++) {
341 bank->sectors[i].offset = offset;
342 bank->sectors[i].size = 8 * 1024;
343 offset += bank->sectors[i].size;
344 bank->sectors[i].is_erased = -1;
345 bank->sectors[i].is_protected = 1;
346 }
347 for (int i = 8; i < 10; i++) {
348 bank->sectors[i].offset = offset;
349 bank->sectors[i].size = 64 * 1024;
350 offset += bank->sectors[i].size;
351 bank->sectors[i].is_erased = -1;
352 bank->sectors[i].is_protected = 1;
353 }
354 for (int i = 10; i < 18; i++) {
355 bank->sectors[i].offset = offset;
356 bank->sectors[i].size = 8 * 1024;
357 offset += bank->sectors[i].size;
358 bank->sectors[i].is_erased = -1;
359 bank->sectors[i].is_protected = 1;
360 }
361 } else {
362 LOG_ERROR("BUG: unknown bank->size encountered");
363 exit(-1);
364 }
365 } else if (lpc2000_info->variant == lpc2000_v2) {
366 lpc2000_info->cmd51_dst_boundary = 256;
367 lpc2000_info->checksum_vector = 5;
368 lpc2000_info->iap_max_stack = 128;
369
370 /* variant 2 has a uniform layout, only number of sectors differs */
371 switch (bank->size) {
372 case 4 * 1024:
373 lpc2000_info->cmd51_max_buffer = 1024;
374 bank->num_sectors = 1;
375 break;
376 case 8 * 1024:
377 lpc2000_info->cmd51_max_buffer = 1024;
378 bank->num_sectors = 2;
379 break;
380 case 16 * 1024:
381 bank->num_sectors = 4;
382 break;
383 case 32 * 1024:
384 bank->num_sectors = 8;
385 break;
386 case 64 * 1024:
387 bank->num_sectors = 9;
388 break;
389 case 128 * 1024:
390 bank->num_sectors = 11;
391 break;
392 case 256 * 1024:
393 bank->num_sectors = 15;
394 break;
395 case 500 * 1024:
396 bank->num_sectors = 27;
397 break;
398 case 512 * 1024:
399 case 504 * 1024:
400 bank->num_sectors = 28;
401 break;
402 default:
403 LOG_ERROR("BUG: unknown bank->size encountered");
404 exit(-1);
405 break;
406 }
407
408 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
409
410 for (int i = 0; i < bank->num_sectors; i++) {
411 if (i < 8) {
412 bank->sectors[i].offset = offset;
413 bank->sectors[i].size = 4 * 1024;
414 offset += bank->sectors[i].size;
415 bank->sectors[i].is_erased = -1;
416 bank->sectors[i].is_protected = 1;
417 } else if (i < 22) {
418 bank->sectors[i].offset = offset;
419 bank->sectors[i].size = 32 * 1024;
420 offset += bank->sectors[i].size;
421 bank->sectors[i].is_erased = -1;
422 bank->sectors[i].is_protected = 1;
423 } else if (i < 28) {
424 bank->sectors[i].offset = offset;
425 bank->sectors[i].size = 4 * 1024;
426 offset += bank->sectors[i].size;
427 bank->sectors[i].is_erased = -1;
428 bank->sectors[i].is_protected = 1;
429 }
430 }
431 } else if (lpc2000_info->variant == lpc1700) {
432 lpc2000_info->cmd51_dst_boundary = 256;
433 lpc2000_info->checksum_vector = 7;
434 lpc2000_info->iap_max_stack = 128;
435
436 switch (bank->size) {
437 case 4 * 1024:
438 lpc2000_info->cmd51_max_buffer = 256;
439 bank->num_sectors = 1;
440 break;
441 case 8 * 1024:
442 lpc2000_info->cmd51_max_buffer = 512;
443 bank->num_sectors = 2;
444 break;
445 case 16 * 1024:
446 lpc2000_info->cmd51_max_buffer = 512;
447 bank->num_sectors = 4;
448 break;
449 case 32 * 1024:
450 lpc2000_info->cmd51_max_buffer = 1024;
451 bank->num_sectors = 8;
452 break;
453 case 64 * 1024:
454 bank->num_sectors = 16;
455 break;
456 case 128 * 1024:
457 bank->num_sectors = 18;
458 break;
459 case 256 * 1024:
460 bank->num_sectors = 22;
461 break;
462 case 512 * 1024:
463 bank->num_sectors = 30;
464 break;
465 default:
466 LOG_ERROR("BUG: unknown bank->size encountered");
467 exit(-1);
468 }
469
470 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
471
472 for (int i = 0; i < bank->num_sectors; i++) {
473 bank->sectors[i].offset = offset;
474 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */
475 bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;
476 offset += bank->sectors[i].size;
477 bank->sectors[i].is_erased = -1;
478 bank->sectors[i].is_protected = 1;
479 }
480 } else if (lpc2000_info->variant == lpc4300) {
481 lpc2000_info->cmd51_dst_boundary = 512;
482 lpc2000_info->checksum_vector = 7;
483 lpc2000_info->iap_max_stack = 208;
484
485 switch (bank->size) {
486 case 256 * 1024:
487 bank->num_sectors = 11;
488 break;
489 case 384 * 1024:
490 bank->num_sectors = 13;
491 break;
492 case 512 * 1024:
493 bank->num_sectors = 15;
494 break;
495 default:
496 LOG_ERROR("BUG: unknown bank->size encountered");
497 exit(-1);
498 }
499
500 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
501
502 for (int i = 0; i < bank->num_sectors; i++) {
503 bank->sectors[i].offset = offset;
504 /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
505 bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024;
506 offset += bank->sectors[i].size;
507 bank->sectors[i].is_erased = -1;
508 bank->sectors[i].is_protected = 1;
509 }
510
511 } else if (lpc2000_info->variant == lpc800) {
512 lpc2000_info->cmd51_dst_boundary = 64;
513 lpc2000_info->checksum_vector = 7;
514 lpc2000_info->iap_max_stack = 208; /* 148byte for LPC81x,208byte for LPC82x. */
515 lpc2000_info->cmd51_max_buffer = 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */
516
517 switch (bank->size) {
518 case 4 * 1024:
519 bank->num_sectors = 4;
520 break;
521 case 8 * 1024:
522 bank->num_sectors = 8;
523 break;
524 case 16 * 1024:
525 bank->num_sectors = 16;
526 break;
527 case 32 * 1024:
528 lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */
529 bank->num_sectors = 32;
530 break;
531 default:
532 LOG_ERROR("BUG: unknown bank->size encountered");
533 exit(-1);
534 }
535
536 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
537
538 for (int i = 0; i < bank->num_sectors; i++) {
539 bank->sectors[i].offset = offset;
540 /* all sectors are 1kB-sized for LPC8xx devices */
541 bank->sectors[i].size = 1 * 1024;
542 offset += bank->sectors[i].size;
543 bank->sectors[i].is_erased = -1;
544 bank->sectors[i].is_protected = 1;
545 }
546
547 } else if (lpc2000_info->variant == lpc1100) {
548 lpc2000_info->cmd51_dst_boundary = 256;
549 lpc2000_info->checksum_vector = 7;
550 lpc2000_info->iap_max_stack = 128;
551
552 if ((bank->size % (4 * 1024)) != 0) {
553 LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096");
554 exit(-1);
555 }
556 lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
557 bank->num_sectors = bank->size / 4096;
558
559 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
560
561 for (int i = 0; i < bank->num_sectors; i++) {
562 bank->sectors[i].offset = offset;
563 /* all sectors are 4kB-sized */
564 bank->sectors[i].size = 4 * 1024;
565 offset += bank->sectors[i].size;
566 bank->sectors[i].is_erased = -1;
567 bank->sectors[i].is_protected = 1;
568 }
569
570 } else if (lpc2000_info->variant == lpc1500) {
571 lpc2000_info->cmd51_dst_boundary = 256;
572 lpc2000_info->checksum_vector = 7;
573 lpc2000_info->iap_max_stack = 128;
574
575 switch (bank->size) {
576 case 64 * 1024:
577 bank->num_sectors = 16;
578 break;
579 case 128 * 1024:
580 bank->num_sectors = 32;
581 break;
582 case 256 * 1024:
583 bank->num_sectors = 64;
584 break;
585 default:
586 LOG_ERROR("BUG: unknown bank->size encountered");
587 exit(-1);
588 }
589
590 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
591
592 for (int i = 0; i < bank->num_sectors; i++) {
593 bank->sectors[i].offset = offset;
594 /* all sectors are 4kB-sized */
595 bank->sectors[i].size = 4 * 1024;
596 offset += bank->sectors[i].size;
597 bank->sectors[i].is_erased = -1;
598 bank->sectors[i].is_protected = 1;
599 }
600
601 } else if (lpc2000_info->variant == lpc54100) {
602 lpc2000_info->cmd51_dst_boundary = 256;
603 lpc2000_info->checksum_vector = 7;
604 lpc2000_info->iap_max_stack = 128;
605
606 switch (bank->size) {
607 case 256 * 1024:
608 bank->num_sectors = 8;
609 break;
610 case 512 * 1024:
611 bank->num_sectors = 16;
612 break;
613 default:
614 LOG_ERROR("BUG: unknown bank->size encountered");
615 exit(-1);
616 }
617
618 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
619
620 for (int i = 0; i < bank->num_sectors; i++) {
621 bank->sectors[i].offset = offset;
622 /* all sectors are 32kB-sized */
623 bank->sectors[i].size = 32 * 1024;
624 offset += bank->sectors[i].size;
625 bank->sectors[i].is_erased = -1;
626 bank->sectors[i].is_protected = 1;
627 }
628
629 } else {
630 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
631 exit(-1);
632 }
633
634 return ERROR_OK;
635 }
636
637 /* this function allocates and initializes working area used for IAP algorithm
638 * uses 52 + max IAP stack bytes working area
639 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
640 * 0x8 to 0x1f: command parameter table (1+5 words)
641 * 0x20 to 0x33: command result table (1+4 words)
642 * 0x34 to 0xb3|0x104: stack
643 * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x)
644 */
645
646 static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
647 {
648 struct target *target = bank->target;
649 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
650
651 if (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {
652 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
653 return ERROR_FLASH_OPERATION_FAILED;
654 }
655
656 uint8_t jump_gate[8];
657
658 /* write IAP code to working area */
659 switch (lpc2000_info->variant) {
660 case lpc800:
661 case lpc1100:
662 case lpc1500:
663 case lpc1700:
664 case lpc4300:
665 case lpc54100:
666 case lpc_auto:
667 target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
668 target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
669 break;
670 case lpc2000_v1:
671 case lpc2000_v2:
672 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
673 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
674 break;
675 default:
676 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
677 exit(-1);
678 }
679
680 int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
681 if (retval != ERROR_OK) {
682 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
683 (*iap_working_area)->address);
684 target_free_working_area(target, *iap_working_area);
685 }
686
687 return retval;
688 }
689
690 /* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */
691
692 static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
693 uint32_t param_table[5], uint32_t result_table[4])
694 {
695 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
696 struct target *target = bank->target;
697
698 struct arm_algorithm arm_algo; /* for LPC2000 */
699 struct armv7m_algorithm armv7m_info; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */
700 uint32_t iap_entry_point = 0; /* to make compiler happier */
701
702 switch (lpc2000_info->variant) {
703 case lpc800:
704 case lpc1100:
705 case lpc1700:
706 case lpc_auto:
707 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
708 armv7m_info.core_mode = ARM_MODE_THREAD;
709 iap_entry_point = 0x1fff1ff1;
710 break;
711 case lpc1500:
712 case lpc54100:
713 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
714 armv7m_info.core_mode = ARM_MODE_THREAD;
715 iap_entry_point = 0x03000205;
716 break;
717 case lpc2000_v1:
718 case lpc2000_v2:
719 arm_algo.common_magic = ARM_COMMON_MAGIC;
720 arm_algo.core_mode = ARM_MODE_SVC;
721 arm_algo.core_state = ARM_STATE_ARM;
722 iap_entry_point = 0x7ffffff1;
723 break;
724 case lpc4300:
725 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
726 armv7m_info.core_mode = ARM_MODE_THREAD;
727 /* read out IAP entry point from ROM driver table at 0x10400100 */
728 target_read_u32(target, 0x10400100, &iap_entry_point);
729 break;
730 default:
731 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
732 exit(-1);
733 }
734
735 struct mem_param mem_params[2];
736
737 /* command parameter table */
738 init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
739 target_buffer_set_u32(target, mem_params[0].value, code);
740 target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
741 target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
742 target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
743 target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
744 target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
745
746 struct reg_param reg_params[5];
747
748 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
749 buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
750
751 /* command result table */
752 init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
753
754 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
755 buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
756
757 /* IAP entry point */
758 init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
759 buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
760
761 switch (lpc2000_info->variant) {
762 case lpc800:
763 case lpc1100:
764 case lpc1500:
765 case lpc1700:
766 case lpc4300:
767 case lpc54100:
768 case lpc_auto:
769 /* IAP stack */
770 init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
771 buf_set_u32(reg_params[3].value, 0, 32,
772 iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);
773
774 /* return address */
775 init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
776 buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
777 /* bit0 of LR = 1 to return in Thumb mode */
778
779 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
780 &armv7m_info);
781 break;
782 case lpc2000_v1:
783 case lpc2000_v2:
784 /* IAP stack */
785 init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
786 buf_set_u32(reg_params[3].value, 0, 32,
787 iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);
788
789 /* return address */
790 init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
791 buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
792
793 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
794 iap_working_area->address + 0x4, 10000, &arm_algo);
795 break;
796 default:
797 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
798 exit(-1);
799 }
800
801 int status_code = target_buffer_get_u32(target, mem_params[1].value);
802 result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
803 result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
804 result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
805 result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
806
807 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
808 ") completed with result = %8.8x",
809 code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
810
811 destroy_mem_param(&mem_params[0]);
812 destroy_mem_param(&mem_params[1]);
813
814 destroy_reg_param(&reg_params[0]);
815 destroy_reg_param(&reg_params[1]);
816 destroy_reg_param(&reg_params[2]);
817 destroy_reg_param(&reg_params[3]);
818 destroy_reg_param(&reg_params[4]);
819
820 return status_code;
821 }
822
823 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
824 {
825 if ((first < 0) || (last >= bank->num_sectors))
826 return ERROR_FLASH_SECTOR_INVALID;
827
828 uint32_t param_table[5] = {0};
829 uint32_t result_table[4];
830 struct working_area *iap_working_area;
831
832 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
833
834 if (retval != ERROR_OK)
835 return retval;
836
837 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
838 if (lpc2000_info->variant == lpc4300)
839 param_table[2] = lpc2000_info->lpc4300_bank;
840
841 for (int i = first; i <= last && retval == ERROR_OK; i++) {
842 /* check single sector */
843 param_table[0] = param_table[1] = i;
844 int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
845
846 switch (status_code) {
847 case ERROR_FLASH_OPERATION_FAILED:
848 retval = ERROR_FLASH_OPERATION_FAILED;
849 break;
850 case LPC2000_CMD_SUCCESS:
851 bank->sectors[i].is_erased = 1;
852 break;
853 case LPC2000_SECTOR_NOT_BLANK:
854 bank->sectors[i].is_erased = 0;
855 break;
856 case LPC2000_INVALID_SECTOR:
857 bank->sectors[i].is_erased = 0;
858 break;
859 case LPC2000_BUSY:
860 retval = ERROR_FLASH_BUSY;
861 break;
862 default:
863 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
864 exit(-1);
865 }
866 }
867
868 struct target *target = bank->target;
869 target_free_working_area(target, iap_working_area);
870
871 return retval;
872 }
873
874 /*
875 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
876 */
877 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
878 {
879 if (CMD_ARGC < 8)
880 return ERROR_COMMAND_SYNTAX_ERROR;
881
882 struct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info));
883 lpc2000_info->probed = false;
884
885 bank->driver_priv = lpc2000_info;
886
887 if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
888 lpc2000_info->variant = lpc2000_v1;
889 } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
890 lpc2000_info->variant = lpc2000_v2;
891 } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0 || strcmp(CMD_ARGV[6], "lpc4000") == 0) {
892 lpc2000_info->variant = lpc1700;
893 } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) {
894 lpc2000_info->variant = lpc4300;
895 } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) {
896 lpc2000_info->variant = lpc800;
897 } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) {
898 lpc2000_info->variant = lpc1100;
899 } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) {
900 lpc2000_info->variant = lpc1500;
901 } else if (strcmp(CMD_ARGV[6], "lpc54100") == 0) {
902 lpc2000_info->variant = lpc54100;
903 } else if (strcmp(CMD_ARGV[6], "auto") == 0) {
904 lpc2000_info->variant = lpc_auto;
905 } else {
906 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
907 free(lpc2000_info);
908 return ERROR_FLASH_BANK_INVALID;
909 }
910
911 /* Maximum size required for the IAP stack.
912 This value only gets used when probing, only for auto, lpc1100 and lpc1700.
913 We use the maximum size for any part supported by the driver(!) to be safe
914 in case the auto variant is mistakenly used on a MCU from one of the series
915 for which we don't support auto-probing. */
916 lpc2000_info->iap_max_stack = 208;
917
918 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
919 lpc2000_info->calc_checksum = 0;
920
921 uint32_t temp_base = 0;
922 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
923 if (temp_base >= 0x1B000000)
924 lpc2000_info->lpc4300_bank = 1; /* bank B */
925 else
926 lpc2000_info->lpc4300_bank = 0; /* bank A */
927
928 if (CMD_ARGC >= 9) {
929 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
930 lpc2000_info->calc_checksum = 1;
931 }
932
933 return ERROR_OK;
934 }
935
936 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
937 {
938 if (bank->target->state != TARGET_HALTED) {
939 LOG_ERROR("Target not halted");
940 return ERROR_TARGET_NOT_HALTED;
941 }
942
943 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
944 uint32_t param_table[5] = {0};
945
946 param_table[0] = first;
947 param_table[1] = last;
948
949 if (lpc2000_info->variant == lpc4300)
950 param_table[2] = lpc2000_info->lpc4300_bank;
951 else
952 param_table[2] = lpc2000_info->cclk;
953
954 uint32_t result_table[4];
955 struct working_area *iap_working_area;
956
957 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
958
959 if (retval != ERROR_OK)
960 return retval;
961
962 if (lpc2000_info->variant == lpc4300)
963 /* Init IAP Anyway */
964 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
965
966 /* Prepare sectors */
967 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
968 switch (status_code) {
969 case ERROR_FLASH_OPERATION_FAILED:
970 retval = ERROR_FLASH_OPERATION_FAILED;
971 break;
972 case LPC2000_CMD_SUCCESS:
973 break;
974 case LPC2000_INVALID_SECTOR:
975 retval = ERROR_FLASH_SECTOR_INVALID;
976 break;
977 default:
978 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
979 retval = ERROR_FLASH_OPERATION_FAILED;
980 break;
981 }
982
983 if (retval == ERROR_OK) {
984 /* Erase sectors */
985 param_table[2] = lpc2000_info->cclk;
986 if (lpc2000_info->variant == lpc4300)
987 param_table[3] = lpc2000_info->lpc4300_bank;
988
989 status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
990 switch (status_code) {
991 case ERROR_FLASH_OPERATION_FAILED:
992 retval = ERROR_FLASH_OPERATION_FAILED;
993 break;
994 case LPC2000_CMD_SUCCESS:
995 break;
996 case LPC2000_INVALID_SECTOR:
997 retval = ERROR_FLASH_SECTOR_INVALID;
998 break;
999 default:
1000 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
1001 retval = ERROR_FLASH_OPERATION_FAILED;
1002 break;
1003 }
1004 }
1005
1006 struct target *target = bank->target;
1007 target_free_working_area(target, iap_working_area);
1008
1009 return retval;
1010 }
1011
1012 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
1013 {
1014 /* can't protect/unprotect on the lpc2000 */
1015 return ERROR_OK;
1016 }
1017
1018 static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
1019 {
1020 struct target *target = bank->target;
1021
1022 if (bank->target->state != TARGET_HALTED) {
1023 LOG_ERROR("Target not halted");
1024 return ERROR_TARGET_NOT_HALTED;
1025 }
1026
1027 if (offset + count > bank->size)
1028 return ERROR_FLASH_DST_OUT_OF_BANK;
1029
1030 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1031
1032 uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
1033
1034 if (offset % dst_min_alignment) {
1035 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
1036 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1037 }
1038
1039 int first_sector = 0;
1040 int last_sector = 0;
1041
1042 for (int i = 0; i < bank->num_sectors; i++) {
1043 if (offset >= bank->sectors[i].offset)
1044 first_sector = i;
1045 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
1046 last_sector = i;
1047 }
1048
1049 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
1050
1051 /* check if exception vectors should be flashed */
1052 if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
1053 assert(lpc2000_info->checksum_vector < 8);
1054 uint32_t checksum = 0;
1055 for (int i = 0; i < 8; i++) {
1056 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
1057 if (i != lpc2000_info->checksum_vector)
1058 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
1059 }
1060 checksum = 0 - checksum;
1061 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
1062
1063 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
1064 if (original_value != checksum) {
1065 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
1066 "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
1067 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
1068 "checksum.");
1069 }
1070
1071 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
1072 buf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
1073 }
1074
1075 struct working_area *iap_working_area;
1076
1077 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
1078
1079 if (retval != ERROR_OK)
1080 return retval;
1081
1082 struct working_area *download_area;
1083
1084 /* allocate a working area */
1085 if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
1086 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
1087 target_free_working_area(target, iap_working_area);
1088 return ERROR_FLASH_OPERATION_FAILED;
1089 }
1090
1091 uint32_t bytes_remaining = count;
1092 uint32_t bytes_written = 0;
1093 uint32_t param_table[5] = {0};
1094 uint32_t result_table[4];
1095
1096 if (lpc2000_info->variant == lpc4300)
1097 /* Init IAP Anyway */
1098 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
1099
1100 while (bytes_remaining > 0) {
1101 uint32_t thisrun_bytes;
1102 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
1103 thisrun_bytes = lpc2000_info->cmd51_max_buffer;
1104 else
1105 thisrun_bytes = lpc2000_info->cmd51_dst_boundary;
1106
1107 /* Prepare sectors */
1108 param_table[0] = first_sector;
1109 param_table[1] = last_sector;
1110
1111 if (lpc2000_info->variant == lpc4300)
1112 param_table[2] = lpc2000_info->lpc4300_bank;
1113 else
1114 param_table[2] = lpc2000_info->cclk;
1115
1116 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
1117 switch (status_code) {
1118 case ERROR_FLASH_OPERATION_FAILED:
1119 retval = ERROR_FLASH_OPERATION_FAILED;
1120 break;
1121 case LPC2000_CMD_SUCCESS:
1122 break;
1123 case LPC2000_INVALID_SECTOR:
1124 retval = ERROR_FLASH_SECTOR_INVALID;
1125 break;
1126 default:
1127 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
1128 retval = ERROR_FLASH_OPERATION_FAILED;
1129 break;
1130 }
1131
1132 /* Exit if error occured */
1133 if (retval != ERROR_OK)
1134 break;
1135
1136 if (bytes_remaining >= thisrun_bytes) {
1137 retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
1138 if (retval != ERROR_OK) {
1139 retval = ERROR_FLASH_OPERATION_FAILED;
1140 break;
1141 }
1142 } else {
1143 uint8_t *last_buffer = malloc(thisrun_bytes);
1144 memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
1145 memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
1146 target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
1147 free(last_buffer);
1148 }
1149
1150 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
1151 bank->base + offset + bytes_written);
1152
1153 /* Write data */
1154 param_table[0] = bank->base + offset + bytes_written;
1155 param_table[1] = download_area->address;
1156 param_table[2] = thisrun_bytes;
1157 param_table[3] = lpc2000_info->cclk;
1158 status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
1159 switch (status_code) {
1160 case ERROR_FLASH_OPERATION_FAILED:
1161 retval = ERROR_FLASH_OPERATION_FAILED;
1162 break;
1163 case LPC2000_CMD_SUCCESS:
1164 break;
1165 case LPC2000_INVALID_SECTOR:
1166 retval = ERROR_FLASH_SECTOR_INVALID;
1167 break;
1168 default:
1169 LOG_WARNING("lpc2000 returned %i", status_code);
1170 retval = ERROR_FLASH_OPERATION_FAILED;
1171 break;
1172 }
1173
1174 /* Exit if error occured */
1175 if (retval != ERROR_OK)
1176 break;
1177
1178 if (bytes_remaining > thisrun_bytes)
1179 bytes_remaining -= thisrun_bytes;
1180 else
1181 bytes_remaining = 0;
1182 bytes_written += thisrun_bytes;
1183 }
1184
1185 target_free_working_area(target, iap_working_area);
1186 target_free_working_area(target, download_area);
1187
1188 return retval;
1189 }
1190
1191 static int get_lpc2000_part_id(struct flash_bank *bank, uint32_t *part_id)
1192 {
1193 if (bank->target->state != TARGET_HALTED) {
1194 LOG_ERROR("Target not halted");
1195 return ERROR_TARGET_NOT_HALTED;
1196 }
1197
1198 uint32_t param_table[5] = {0};
1199 uint32_t result_table[4];
1200 struct working_area *iap_working_area;
1201
1202 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
1203
1204 if (retval != ERROR_OK)
1205 return retval;
1206
1207 /* The status seems to be bogus with the part ID command on some IAP
1208 firmwares, so ignore it. */
1209 lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
1210
1211 struct target *target = bank->target;
1212 target_free_working_area(target, iap_working_area);
1213
1214 /* If the result is zero, the command probably didn't work out. */
1215 if (result_table[0] == 0)
1216 return LPC2000_INVALID_COMMAND;
1217
1218 *part_id = result_table[0];
1219 return LPC2000_CMD_SUCCESS;
1220 }
1221
1222 static int lpc2000_auto_probe_flash(struct flash_bank *bank)
1223 {
1224 uint32_t part_id;
1225 int retval;
1226 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1227
1228 if (bank->target->state != TARGET_HALTED) {
1229 LOG_ERROR("Target not halted");
1230 return ERROR_TARGET_NOT_HALTED;
1231 }
1232
1233 retval = get_lpc2000_part_id(bank, &part_id);
1234 if (retval != LPC2000_CMD_SUCCESS) {
1235 LOG_ERROR("Could not get part ID");
1236 return retval;
1237 }
1238
1239 switch (part_id) {
1240 case LPC1110_1:
1241 case LPC1110_2:
1242 lpc2000_info->variant = lpc1100;
1243 bank->size = 4 * 1024;
1244 break;
1245
1246 case LPC1111_002_1:
1247 case LPC1111_002_2:
1248 case LPC1111_101_1:
1249 case LPC1111_101_2:
1250 case LPC1111_103_1:
1251 case LPC1111_201_1:
1252 case LPC1111_201_2:
1253 case LPC1111_203_1:
1254 case LPC11A11_001_1:
1255 case LPC11E11_101:
1256 case LPC1311:
1257 case LPC1311_1:
1258 lpc2000_info->variant = lpc1100;
1259 bank->size = 8 * 1024;
1260 break;
1261
1262 case LPC1112_101_1:
1263 case LPC1112_101_2:
1264 case LPC1112_102_1:
1265 case LPC1112_102_2:
1266 case LPC1112_103_1:
1267 case LPC1112_201_1:
1268 case LPC1112_201_2:
1269 case LPC1112_203_1:
1270 case LPC11A02_1:
1271 case LPC11C12_301_1:
1272 case LPC11C22_301_1:
1273 case LPC11A12_101_1:
1274 case LPC11E12_201:
1275 case LPC11U12_201_1:
1276 case LPC11U12_201_2:
1277 case LPC1342:
1278 lpc2000_info->variant = lpc1100;
1279 bank->size = 16 * 1024;
1280 break;
1281
1282 case LPC1113_201_1:
1283 case LPC1113_201_2:
1284 case LPC1113_203_1:
1285 case LPC1113_301_1:
1286 case LPC1113_301_2:
1287 case LPC1113_303_1:
1288 case LPC11A13_201_1:
1289 case LPC11E13_301:
1290 case LPC11U13_201_1:
1291 case LPC11U13_201_2:
1292 case LPC11U23_301:
1293 lpc2000_info->variant = lpc1100;
1294 bank->size = 24 * 1024;
1295 break;
1296
1297 case LPC1114_102_1:
1298 case LPC1114_102_2:
1299 case LPC1114_201_1:
1300 case LPC1114_201_2:
1301 case LPC1114_203_1:
1302 case LPC1114_301_1:
1303 case LPC1114_301_2:
1304 case LPC1114_303_1:
1305 case LPC11A04_1:
1306 case LPC11A14_301_1:
1307 case LPC11A14_301_2:
1308 case LPC11C14_301_1:
1309 case LPC11C24_301_1:
1310 case LPC11E14_401:
1311 case LPC11U14_201_1:
1312 case LPC11U14_201_2:
1313 case LPC11U24_301:
1314 case LPC11U24_401:
1315 case LPC1313:
1316 case LPC1313_1:
1317 case LPC1315:
1318 case LPC1343:
1319 case LPC1343_1:
1320 case LPC1345:
1321 lpc2000_info->variant = lpc1100;
1322 bank->size = 32 * 1024;
1323 break;
1324
1325 case LPC1751_1:
1326 case LPC1751_2:
1327 lpc2000_info->variant = lpc1700;
1328 bank->size = 32 * 1024;
1329 break;
1330
1331 case LPC11U34_311:
1332 lpc2000_info->variant = lpc1100;
1333 bank->size = 40 * 1024;
1334 break;
1335
1336 case LPC1114_323_1:
1337 case LPC11U34_421:
1338 case LPC1316:
1339 case LPC1346:
1340 lpc2000_info->variant = lpc1100;
1341 bank->size = 48 * 1024;
1342 break;
1343
1344 case LPC1114_333_1:
1345 lpc2000_info->variant = lpc1100;
1346 bank->size = 56 * 1024;
1347 break;
1348
1349 case LPC1115_303_1:
1350 case LPC11U35_401:
1351 case LPC11U35_501:
1352 case LPC11E66:
1353 case LPC11U66:
1354 case LPC1317:
1355 case LPC1347:
1356 lpc2000_info->variant = lpc1100;
1357 bank->size = 64 * 1024;
1358 break;
1359
1360 case LPC1752:
1361 case LPC4072:
1362 lpc2000_info->variant = lpc1700;
1363 bank->size = 64 * 1024;
1364 break;
1365
1366 case LPC11E36_501:
1367 case LPC11U36_401:
1368 lpc2000_info->variant = lpc1100;
1369 bank->size = 96 * 1024;
1370 break;
1371
1372 case LPC11E37_401:
1373 case LPC11E37_501:
1374 case LPC11U37_401:
1375 case LPC11U37H_401:
1376 case LPC11U37_501:
1377 case LPC11E67:
1378 case LPC11E68:
1379 case LPC11U67_1:
1380 case LPC11U67_2:
1381 lpc2000_info->variant = lpc1100;
1382 bank->size = 128 * 1024;
1383 break;
1384
1385 case LPC1754:
1386 case LPC1764:
1387 case LPC1774:
1388 case LPC4074:
1389 lpc2000_info->variant = lpc1700;
1390 bank->size = 128 * 1024;
1391 break;
1392
1393 case LPC11U68_1:
1394 case LPC11U68_2:
1395 lpc2000_info->variant = lpc1100;
1396 bank->size = 256 * 1024;
1397 break;
1398
1399 case LPC1756:
1400 case LPC1763:
1401 case LPC1765:
1402 case LPC1766:
1403 case LPC1776:
1404 case LPC1785:
1405 case LPC1786:
1406 case LPC4076:
1407 lpc2000_info->variant = lpc1700;
1408 bank->size = 256 * 1024;
1409 break;
1410
1411 case LPC1758:
1412 case LPC1759:
1413 case LPC1767:
1414 case LPC1768:
1415 case LPC1769:
1416 case LPC1777:
1417 case LPC1778:
1418 case LPC1787:
1419 case LPC1788:
1420 case LPC4078:
1421 case LPC4088:
1422 lpc2000_info->variant = lpc1700;
1423 bank->size = 512 * 1024;
1424 break;
1425
1426 case LPC810_021:
1427 lpc2000_info->variant = lpc800;
1428 bank->size = 4 * 1024;
1429 break;
1430
1431 case LPC811_001:
1432 lpc2000_info->variant = lpc800;
1433 bank->size = 8 * 1024;
1434 break;
1435
1436 case LPC812_101:
1437 case LPC812_101_1:
1438 case LPC812_101_2:
1439 case LPC812_101_3:
1440 case LPC822_101:
1441 case LPC822_101_1:
1442 lpc2000_info->variant = lpc800;
1443 bank->size = 16 * 1024;
1444 break;
1445
1446 case LPC824_201:
1447 case LPC824_201_1:
1448 lpc2000_info->variant = lpc800;
1449 bank->size = 32 * 1024;
1450 break;
1451
1452 default:
1453 LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32, part_id);
1454 exit(-1);
1455 }
1456
1457 return ERROR_OK;
1458 }
1459
1460 static int lpc2000_probe(struct flash_bank *bank)
1461 {
1462 int status;
1463 uint32_t part_id;
1464 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1465
1466 if (!lpc2000_info->probed) {
1467 if (lpc2000_info->variant == lpc_auto) {
1468 status = lpc2000_auto_probe_flash(bank);
1469 if (status != ERROR_OK)
1470 return status;
1471 } else if (lpc2000_info->variant == lpc1100 || lpc2000_info->variant == lpc1700) {
1472 status = get_lpc2000_part_id(bank, &part_id);
1473 if (status == LPC2000_CMD_SUCCESS)
1474 LOG_INFO("If auto-detection fails for this part, please email "
1475 "openocd-devel@lists.sourceforge.net, citing part id 0x%" PRIx32 ".\n", part_id);
1476 }
1477
1478 lpc2000_build_sector_list(bank);
1479 lpc2000_info->probed = true;
1480 }
1481
1482 return ERROR_OK;
1483 }
1484
1485 static int lpc2000_erase_check(struct flash_bank *bank)
1486 {
1487 if (bank->target->state != TARGET_HALTED) {
1488 LOG_ERROR("Target not halted");
1489 return ERROR_TARGET_NOT_HALTED;
1490 }
1491
1492 return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
1493 }
1494
1495 static int lpc2000_protect_check(struct flash_bank *bank)
1496 {
1497 /* sectors are always protected */
1498 return ERROR_OK;
1499 }
1500
1501 static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
1502 {
1503 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
1504
1505 snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
1506 lpc2000_info->cclk);
1507
1508 return ERROR_OK;
1509 }
1510
1511 COMMAND_HANDLER(lpc2000_handle_part_id_command)
1512 {
1513 if (CMD_ARGC < 1)
1514 return ERROR_COMMAND_SYNTAX_ERROR;
1515
1516 struct flash_bank *bank;
1517 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1518 if (ERROR_OK != retval)
1519 return retval;
1520
1521 if (bank->target->state != TARGET_HALTED) {
1522 LOG_ERROR("Target not halted");
1523 return ERROR_TARGET_NOT_HALTED;
1524 }
1525
1526 uint32_t part_id;
1527 int status_code = get_lpc2000_part_id(bank, &part_id);
1528 if (status_code != 0x0) {
1529 if (status_code == ERROR_FLASH_OPERATION_FAILED) {
1530 command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
1531 } else
1532 command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
1533 } else
1534 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, part_id);
1535
1536 return retval;
1537 }
1538
1539 static const struct command_registration lpc2000_exec_command_handlers[] = {
1540 {
1541 .name = "part_id",
1542 .handler = lpc2000_handle_part_id_command,
1543 .mode = COMMAND_EXEC,
1544 .help = "print part id of lpc2000 flash bank <num>",
1545 .usage = "<bank>",
1546 },
1547 COMMAND_REGISTRATION_DONE
1548 };
1549 static const struct command_registration lpc2000_command_handlers[] = {
1550 {
1551 .name = "lpc2000",
1552 .mode = COMMAND_ANY,
1553 .help = "lpc2000 flash command group",
1554 .usage = "",
1555 .chain = lpc2000_exec_command_handlers,
1556 },
1557 COMMAND_REGISTRATION_DONE
1558 };
1559
1560 struct flash_driver lpc2000_flash = {
1561 .name = "lpc2000",
1562 .commands = lpc2000_command_handlers,
1563 .flash_bank_command = lpc2000_flash_bank_command,
1564 .erase = lpc2000_erase,
1565 .protect = lpc2000_protect,
1566 .write = lpc2000_write,
1567 .read = default_flash_read,
1568 .probe = lpc2000_probe,
1569 .auto_probe = lpc2000_probe,
1570 .erase_check = lpc2000_erase_check,
1571 .protect_check = lpc2000_protect_check,
1572 .info = get_lpc2000_info,
1573 };

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)