1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
6 * didele.deze@gmail.com *
8 * LPC1100 variant and auto-probing support Copyright (C) 2014 *
9 * by Cosmin Gorgovan cosmin [at] linux-geek [dot] org *
11 * LPC800/LPC1500/LPC54100 support Copyright (C) 2013/2014 *
12 * by Nemui Trinomius *
13 * nemuisan_kawausogasuki@live.jp *
15 * LPC8N04/HNS31xx support Copyright (C) 2018 *
16 * by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch *
18 * This program is free software; you can redistribute it and/or modify *
19 * it under the terms of the GNU General Public License as published by *
20 * the Free Software Foundation; either version 2 of the License, or *
21 * (at your option) any later version. *
23 * This program is distributed in the hope that it will be useful, *
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
26 * GNU General Public License for more details. *
28 * You should have received a copy of the GNU General Public License *
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
30 ***************************************************************************/
37 #include <helper/binarybuffer.h>
38 #include <target/algorithm.h>
39 #include <target/arm_opcodes.h>
40 #include <target/armv7m.h>
44 * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x,LPC2xxx and NHS31xx devices.
46 * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
47 * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
50 * currently supported devices:
51 * variant 1 (lpc2000_v1):
59 * variant 2 (lpc2000_v2):
68 * - 176x (tested with LPC1768)
70 * - 178x (tested with LPC1788)
72 * lpc4000: (lpc1700's alias)
74 * - 408x (tested with LPC4088)
76 * lpc4300: (also available as lpc1800 - alias)
77 * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357)
81 * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812)
82 * - 822 | 4 (tested with LPC824)
84 * - NHS31xx (tested with NHS3100)
85 * - 844 | 5 (tested with LPC845)
93 * - 11Uxx (tested with LPC11U34)
98 * - 15x7 | 8 | 9 (tested with LPC1549)
101 * - 54101 | 2 (tested with LPC54102)
103 * The auto variant auto-detects parts from the following series:
124 /* Part IDs for autodetection */
125 /* A script which can automatically extract part ids from user manuals is available here:
126 * https://github.com/lgeek/lpc_part_ids
128 #define LPC1110_1 0x0A07102B
129 #define LPC1110_2 0x1A07102B
130 #define LPC1111_002_1 0x0A16D02B
131 #define LPC1111_002_2 0x1A16D02B
132 #define LPC1111_101_1 0x041E502B
133 #define LPC1111_101_2 0x2516D02B
134 #define LPC1111_103_1 0x00010013
135 #define LPC1111_201_1 0x0416502B
136 #define LPC1111_201_2 0x2516902B
137 #define LPC1111_203_1 0x00010012
138 #define LPC1112_101_1 0x042D502B
139 #define LPC1112_101_2 0x2524D02B
140 #define LPC1112_102_1 0x0A24902B
141 #define LPC1112_102_2 0x1A24902B
142 #define LPC1112_103_1 0x00020023
143 #define LPC1112_201_1 0x0425502B
144 #define LPC1112_201_2 0x2524902B
145 #define LPC1112_203_1 0x00020022
146 #define LPC1113_201_1 0x0434502B
147 #define LPC1113_201_2 0x2532902B
148 #define LPC1113_203_1 0x00030032
149 #define LPC1113_301_1 0x0434102B
150 #define LPC1113_301_2 0x2532102B
151 #define LPC1113_303_1 0x00030030
152 #define LPC1114_102_1 0x0A40902B
153 #define LPC1114_102_2 0x1A40902B
154 #define LPC1114_201_1 0x0444502B
155 #define LPC1114_201_2 0x2540902B
156 #define LPC1114_203_1 0x00040042
157 #define LPC1114_301_1 0x0444102B
158 #define LPC1114_301_2 0x2540102B
159 #define LPC1114_303_1 0x00040040
160 #define LPC1114_323_1 0x00040060
161 #define LPC1114_333_1 0x00040070
162 #define LPC1115_303_1 0x00050080
164 #define LPC11A02_1 0x4D4C802B
165 #define LPC11A04_1 0x4D80002B
166 #define LPC11A11_001_1 0x455EC02B
167 #define LPC11A12_101_1 0x4574802B
168 #define LPC11A13_201_1 0x458A402B
169 #define LPC11A14_301_1 0x35A0002B
170 #define LPC11A14_301_2 0x45A0002B
172 #define LPC11C12_301_1 0x1421102B
173 #define LPC11C14_301_1 0x1440102B
174 #define LPC11C22_301_1 0x1431102B
175 #define LPC11C24_301_1 0x1430102B
177 #define LPC11E11_101 0x293E902B
178 #define LPC11E12_201 0x2954502B
179 #define LPC11E13_301 0x296A102B
180 #define LPC11E14_401 0x2980102B
181 #define LPC11E36_501 0x00009C41
182 #define LPC11E37_401 0x00007C45
183 #define LPC11E37_501 0x00007C41
185 #define LPC11U12_201_1 0x095C802B
186 #define LPC11U12_201_2 0x295C802B
187 #define LPC11U13_201_1 0x097A802B
188 #define LPC11U13_201_2 0x297A802B
189 #define LPC11U14_201_1 0x0998802B
190 #define LPC11U14_201_2 0x2998802B
191 #define LPC11U23_301 0x2972402B
192 #define LPC11U24_301 0x2988402B
193 #define LPC11U24_401 0x2980002B
194 #define LPC11U34_311 0x0003D440
195 #define LPC11U34_421 0x0001CC40
196 #define LPC11U35_401 0x0001BC40
197 #define LPC11U35_501 0x0000BC40
198 #define LPC11U36_401 0x00019C40
199 #define LPC11U37_401 0x00017C40
200 #define LPC11U37H_401 0x00007C44
201 #define LPC11U37_501 0x00007C40
203 #define LPC11E66 0x0000DCC1
204 #define LPC11E67 0x0000BC81
205 #define LPC11E68 0x00007C01
207 #define LPC11U66 0x0000DCC8
208 #define LPC11U67_1 0x0000BC88
209 #define LPC11U67_2 0x0000BC80
210 #define LPC11U68_1 0x00007C08
211 #define LPC11U68_2 0x00007C00
213 #define LPC1311 0x2C42502B
214 #define LPC1311_1 0x1816902B
215 #define LPC1313 0x2C40102B
216 #define LPC1313_1 0x1830102B
217 #define LPC1315 0x3A010523
218 #define LPC1316 0x1A018524
219 #define LPC1317 0x1A020525
220 #define LPC1342 0x3D01402B
221 #define LPC1343 0x3D00002B
222 #define LPC1343_1 0x3000002B
223 #define LPC1345 0x28010541
224 #define LPC1346 0x08018542
225 #define LPC1347 0x08020543
227 #define LPC1751_1 0x25001110
228 #define LPC1751_2 0x25001118
229 #define LPC1752 0x25001121
230 #define LPC1754 0x25011722
231 #define LPC1756 0x25011723
232 #define LPC1758 0x25013F37
233 #define LPC1759 0x25113737
234 #define LPC1763 0x26012033
235 #define LPC1764 0x26011922
236 #define LPC1765 0x26013733
237 #define LPC1766 0x26013F33
238 #define LPC1767 0x26012837
239 #define LPC1768 0x26013F37
240 #define LPC1769 0x26113F37
241 #define LPC1774 0x27011132
242 #define LPC1776 0x27191F43
243 #define LPC1777 0x27193747
244 #define LPC1778 0x27193F47
245 #define LPC1785 0x281D1743
246 #define LPC1786 0x281D1F43
247 #define LPC1787 0x281D3747
248 #define LPC1788 0x281D3F47
250 #define LPC4072 0x47011121
251 #define LPC4074 0x47011132
252 #define LPC4076 0x47191F43
253 #define LPC4078 0x47193F47
254 #define LPC4088 0x481D3F47
256 #define LPC810_021 0x00008100
257 #define LPC811_001 0x00008110
258 #define LPC812_101 0x00008120
259 #define LPC812_101_1 0x00008121
260 #define LPC812_101_2 0x00008122
261 #define LPC812_101_3 0x00008123
263 #define LPC822_101 0x00008221
264 #define LPC822_101_1 0x00008222
265 #define LPC824_201 0x00008241
266 #define LPC824_201_1 0x00008242
268 #define LPC8N04 0x00008A04
269 #define NHS3100 0x4e310020
270 #define NHS3152 0x4e315220
271 #define NHS3153 0x4e315320 /* Only specified in Rev.1 of the datasheet */
273 #define LPC844_201 0x00008441
274 #define LPC844_201_1 0x00008442
275 #define LPC844_201_2 0x00008444
277 #define LPC845_301 0x00008451
278 #define LPC845_301_1 0x00008452
279 #define LPC845_301_2 0x00008453
280 #define LPC845_301_3 0x00008454
282 #define IAP_CODE_LEN 0x34
284 #define LPC11XX_REG_SECTORS 24
298 struct lpc2000_flash_bank
{
299 lpc2000_variant variant
;
301 int cmd51_dst_boundary
;
303 uint32_t cmd51_max_buffer
;
305 uint32_t iap_max_stack
;
306 uint32_t lpc4300_bank
;
307 uint32_t iap_entry_alternative
;
311 enum lpc2000_status_codes
{
312 LPC2000_CMD_SUCCESS
= 0,
313 LPC2000_INVALID_COMMAND
= 1,
314 LPC2000_SRC_ADDR_ERROR
= 2,
315 LPC2000_DST_ADDR_ERROR
= 3,
316 LPC2000_SRC_ADDR_NOT_MAPPED
= 4,
317 LPC2000_DST_ADDR_NOT_MAPPED
= 5,
318 LPC2000_COUNT_ERROR
= 6,
319 LPC2000_INVALID_SECTOR
= 7,
320 LPC2000_SECTOR_NOT_BLANK
= 8,
321 LPC2000_SECTOR_NOT_PREPARED
= 9,
322 LPC2000_COMPARE_ERROR
= 10,
324 LPC2000_PARAM_ERROR
= 12,
325 LPC2000_ADDR_ERROR
= 13,
326 LPC2000_ADDR_NOT_MAPPED
= 14,
327 LPC2000_CMD_NOT_LOCKED
= 15,
328 LPC2000_INVALID_CODE
= 16,
329 LPC2000_INVALID_BAUD_RATE
= 17,
330 LPC2000_INVALID_STOP_BIT
= 18,
331 LPC2000_CRP_ENABLED
= 19,
332 LPC2000_INVALID_FLASH_UNIT
= 20,
333 LPC2000_USER_CODE_CHECKSUM
= 21,
334 LCP2000_ERROR_SETTING_ACTIVE_PARTITION
= 22,
337 static int lpc2000_build_sector_list(struct flash_bank
*bank
)
339 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
342 /* default to a 4096 write buffer */
343 lpc2000_info
->cmd51_max_buffer
= 4096;
345 if (lpc2000_info
->variant
== LPC2000_V1
) {
346 lpc2000_info
->cmd51_dst_boundary
= 512;
347 lpc2000_info
->checksum_vector
= 5;
348 lpc2000_info
->iap_max_stack
= 128;
350 /* variant 1 has different layout for 128kb and 256kb flashes */
351 if (bank
->size
== 128 * 1024) {
352 bank
->num_sectors
= 16;
353 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 16);
354 for (int i
= 0; i
< 16; 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;
361 } else if (bank
->size
== 256 * 1024) {
362 bank
->num_sectors
= 18;
363 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 18);
365 for (int i
= 0; i
< 8; i
++) {
366 bank
->sectors
[i
].offset
= offset
;
367 bank
->sectors
[i
].size
= 8 * 1024;
368 offset
+= bank
->sectors
[i
].size
;
369 bank
->sectors
[i
].is_erased
= -1;
370 bank
->sectors
[i
].is_protected
= 1;
372 for (int i
= 8; i
< 10; i
++) {
373 bank
->sectors
[i
].offset
= offset
;
374 bank
->sectors
[i
].size
= 64 * 1024;
375 offset
+= bank
->sectors
[i
].size
;
376 bank
->sectors
[i
].is_erased
= -1;
377 bank
->sectors
[i
].is_protected
= 1;
379 for (int i
= 10; i
< 18; i
++) {
380 bank
->sectors
[i
].offset
= offset
;
381 bank
->sectors
[i
].size
= 8 * 1024;
382 offset
+= bank
->sectors
[i
].size
;
383 bank
->sectors
[i
].is_erased
= -1;
384 bank
->sectors
[i
].is_protected
= 1;
387 LOG_ERROR("BUG: unknown bank->size encountered");
390 } else if (lpc2000_info
->variant
== LPC2000_V2
) {
391 lpc2000_info
->cmd51_dst_boundary
= 256;
392 lpc2000_info
->checksum_vector
= 5;
393 lpc2000_info
->iap_max_stack
= 128;
395 /* variant 2 has a uniform layout, only number of sectors differs */
396 switch (bank
->size
) {
398 lpc2000_info
->cmd51_max_buffer
= 1024;
399 bank
->num_sectors
= 1;
402 lpc2000_info
->cmd51_max_buffer
= 1024;
403 bank
->num_sectors
= 2;
406 bank
->num_sectors
= 4;
409 bank
->num_sectors
= 8;
412 bank
->num_sectors
= 9;
415 bank
->num_sectors
= 11;
418 bank
->num_sectors
= 15;
421 bank
->num_sectors
= 27;
425 bank
->num_sectors
= 28;
428 LOG_ERROR("BUG: unknown bank->size encountered");
433 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
435 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
437 bank
->sectors
[i
].offset
= offset
;
438 bank
->sectors
[i
].size
= 4 * 1024;
439 offset
+= bank
->sectors
[i
].size
;
440 bank
->sectors
[i
].is_erased
= -1;
441 bank
->sectors
[i
].is_protected
= 1;
443 bank
->sectors
[i
].offset
= offset
;
444 bank
->sectors
[i
].size
= 32 * 1024;
445 offset
+= bank
->sectors
[i
].size
;
446 bank
->sectors
[i
].is_erased
= -1;
447 bank
->sectors
[i
].is_protected
= 1;
449 bank
->sectors
[i
].offset
= offset
;
450 bank
->sectors
[i
].size
= 4 * 1024;
451 offset
+= bank
->sectors
[i
].size
;
452 bank
->sectors
[i
].is_erased
= -1;
453 bank
->sectors
[i
].is_protected
= 1;
456 } else if (lpc2000_info
->variant
== LPC1700
) {
457 lpc2000_info
->cmd51_dst_boundary
= 256;
458 lpc2000_info
->checksum_vector
= 7;
459 lpc2000_info
->iap_max_stack
= 128;
461 switch (bank
->size
) {
463 lpc2000_info
->cmd51_max_buffer
= 256;
464 bank
->num_sectors
= 1;
467 lpc2000_info
->cmd51_max_buffer
= 512;
468 bank
->num_sectors
= 2;
471 lpc2000_info
->cmd51_max_buffer
= 512;
472 bank
->num_sectors
= 4;
475 lpc2000_info
->cmd51_max_buffer
= 1024;
476 bank
->num_sectors
= 8;
479 bank
->num_sectors
= 16;
482 bank
->num_sectors
= 18;
485 bank
->num_sectors
= 22;
488 bank
->num_sectors
= 30;
491 LOG_ERROR("BUG: unknown bank->size encountered");
495 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
497 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
498 bank
->sectors
[i
].offset
= offset
;
499 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */
500 bank
->sectors
[i
].size
= (i
< 16) ? 4 * 1024 : 32 * 1024;
501 offset
+= bank
->sectors
[i
].size
;
502 bank
->sectors
[i
].is_erased
= -1;
503 bank
->sectors
[i
].is_protected
= 1;
505 } else if (lpc2000_info
->variant
== LPC4300
) {
506 lpc2000_info
->cmd51_dst_boundary
= 512;
507 lpc2000_info
->checksum_vector
= 7;
508 lpc2000_info
->iap_max_stack
= 208;
510 switch (bank
->size
) {
512 bank
->num_sectors
= 11;
515 bank
->num_sectors
= 13;
518 bank
->num_sectors
= 15;
521 LOG_ERROR("BUG: unknown bank->size encountered");
525 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
527 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
528 bank
->sectors
[i
].offset
= offset
;
529 /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
530 bank
->sectors
[i
].size
= (i
< 8) ? 8 * 1024 : 64 * 1024;
531 offset
+= bank
->sectors
[i
].size
;
532 bank
->sectors
[i
].is_erased
= -1;
533 bank
->sectors
[i
].is_protected
= 1;
536 } else if (lpc2000_info
->variant
== LPC800
) {
537 lpc2000_info
->cmd51_dst_boundary
= 64;
538 lpc2000_info
->checksum_vector
= 7;
539 lpc2000_info
->iap_max_stack
= 208; /* 148byte for LPC81x,208byte for LPC82x. */
540 lpc2000_info
->cmd51_max_buffer
= 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */
542 switch (bank
->size
) {
544 bank
->num_sectors
= 4;
547 bank
->num_sectors
= 8;
550 bank
->num_sectors
= 16;
553 lpc2000_info
->cmd51_max_buffer
= 1024; /* For LPC8N04 and NHS31xx, have 8kB of SRAM */
554 bank
->num_sectors
= 30; /* There have only 30kB of writable Flash out of 32kB */
557 lpc2000_info
->cmd51_max_buffer
= 1024; /* For LPC824, has 8kB of SRAM */
558 bank
->num_sectors
= 32;
561 lpc2000_info
->cmd51_max_buffer
= 1024; /* For LPC844, has 8kB of SRAM */
562 bank
->num_sectors
= 64;
565 LOG_ERROR("BUG: unknown bank->size encountered");
569 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
571 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
572 bank
->sectors
[i
].offset
= offset
;
573 /* all sectors are 1kB-sized for LPC8xx devices */
574 bank
->sectors
[i
].size
= 1 * 1024;
575 offset
+= bank
->sectors
[i
].size
;
576 bank
->sectors
[i
].is_erased
= -1;
577 bank
->sectors
[i
].is_protected
= 1;
580 } else if (lpc2000_info
->variant
== LPC1100
) {
581 lpc2000_info
->cmd51_dst_boundary
= 256;
582 lpc2000_info
->checksum_vector
= 7;
583 lpc2000_info
->iap_max_stack
= 128;
585 if ((bank
->size
% (4 * 1024)) != 0) {
586 LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096");
589 lpc2000_info
->cmd51_max_buffer
= 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
590 unsigned int large_sectors
= 0;
591 unsigned int normal_sectors
= bank
->size
/ 4096;
593 if (normal_sectors
> LPC11XX_REG_SECTORS
) {
594 large_sectors
= (normal_sectors
- LPC11XX_REG_SECTORS
) / 8;
595 normal_sectors
= LPC11XX_REG_SECTORS
;
598 bank
->num_sectors
= normal_sectors
+ large_sectors
;
600 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
602 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
603 bank
->sectors
[i
].offset
= offset
;
604 bank
->sectors
[i
].size
= (i
< LPC11XX_REG_SECTORS
? 4 : 32) * 1024;
605 offset
+= bank
->sectors
[i
].size
;
606 bank
->sectors
[i
].is_erased
= -1;
607 bank
->sectors
[i
].is_protected
= 1;
610 } else if (lpc2000_info
->variant
== LPC1500
) {
611 lpc2000_info
->cmd51_dst_boundary
= 256;
612 lpc2000_info
->checksum_vector
= 7;
613 lpc2000_info
->iap_max_stack
= 128;
615 switch (bank
->size
) {
617 bank
->num_sectors
= 16;
620 bank
->num_sectors
= 32;
623 bank
->num_sectors
= 64;
626 LOG_ERROR("BUG: unknown bank->size encountered");
630 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
632 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
633 bank
->sectors
[i
].offset
= offset
;
634 /* all sectors are 4kB-sized */
635 bank
->sectors
[i
].size
= 4 * 1024;
636 offset
+= bank
->sectors
[i
].size
;
637 bank
->sectors
[i
].is_erased
= -1;
638 bank
->sectors
[i
].is_protected
= 1;
641 } else if (lpc2000_info
->variant
== LPC54100
) {
642 lpc2000_info
->cmd51_dst_boundary
= 256;
643 lpc2000_info
->checksum_vector
= 7;
644 lpc2000_info
->iap_max_stack
= 128;
646 switch (bank
->size
) {
648 bank
->num_sectors
= 8;
651 bank
->num_sectors
= 16;
654 LOG_ERROR("BUG: unknown bank->size encountered");
658 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
660 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
661 bank
->sectors
[i
].offset
= offset
;
662 /* all sectors are 32kB-sized */
663 bank
->sectors
[i
].size
= 32 * 1024;
664 offset
+= bank
->sectors
[i
].size
;
665 bank
->sectors
[i
].is_erased
= -1;
666 bank
->sectors
[i
].is_protected
= 1;
670 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
677 /* this function allocates and initializes working area used for IAP algorithm
678 * uses 52 + max IAP stack bytes working area
679 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
680 * 0x8 to 0x1f: command parameter table (1+5 words)
681 * 0x20 to 0x33: command result table (1+4 words)
682 * 0x34 to 0xb3|0x104: stack
683 * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x)
686 static int lpc2000_iap_working_area_init(struct flash_bank
*bank
, struct working_area
**iap_working_area
)
688 struct target
*target
= bank
->target
;
689 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
691 if (target_alloc_working_area(target
, IAP_CODE_LEN
+ lpc2000_info
->iap_max_stack
, iap_working_area
) != ERROR_OK
) {
692 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
693 return ERROR_FLASH_OPERATION_FAILED
;
696 uint8_t jump_gate
[8];
698 /* write IAP code to working area */
699 switch (lpc2000_info
->variant
) {
707 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_T_BX(12));
708 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV5_T_BKPT(0));
712 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_BX(12));
713 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV4_5_B(0xfffffe, 0));
716 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
720 int retval
= target_write_memory(target
, (*iap_working_area
)->address
, 4, 2, jump_gate
);
721 if (retval
!= ERROR_OK
) {
722 LOG_ERROR("Write memory at address " TARGET_ADDR_FMT
" failed (check work_area definition)",
723 (*iap_working_area
)->address
);
724 target_free_working_area(target
, *iap_working_area
);
730 /* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */
732 static int lpc2000_iap_call(struct flash_bank
*bank
, struct working_area
*iap_working_area
, int code
,
733 uint32_t param_table
[5], uint32_t result_table
[4])
735 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
736 struct target
*target
= bank
->target
;
738 struct arm_algorithm arm_algo
; /* for LPC2000 */
739 struct armv7m_algorithm armv7m_info
; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */
740 uint32_t iap_entry_point
= 0; /* to make compiler happier */
742 switch (lpc2000_info
->variant
) {
747 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
748 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
749 iap_entry_point
= 0x1fff1ff1;
753 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
754 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
755 iap_entry_point
= 0x03000205;
759 arm_algo
.common_magic
= ARM_COMMON_MAGIC
;
760 arm_algo
.core_mode
= ARM_MODE_SVC
;
761 arm_algo
.core_state
= ARM_STATE_ARM
;
762 iap_entry_point
= 0x7ffffff1;
765 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
766 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
767 /* read out IAP entry point from ROM driver table at 0x10400100 */
768 target_read_u32(target
, 0x10400100, &iap_entry_point
);
771 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
775 if (lpc2000_info
->iap_entry_alternative
!= 0x0)
776 iap_entry_point
= lpc2000_info
->iap_entry_alternative
;
778 struct mem_param mem_params
[2];
780 /* command parameter table */
781 init_mem_param(&mem_params
[0], iap_working_area
->address
+ 8, 6 * 4, PARAM_OUT
);
782 target_buffer_set_u32(target
, mem_params
[0].value
, code
);
783 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x04, param_table
[0]);
784 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x08, param_table
[1]);
785 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x0c, param_table
[2]);
786 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x10, param_table
[3]);
787 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x14, param_table
[4]);
789 struct reg_param reg_params
[5];
791 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
792 buf_set_u32(reg_params
[0].value
, 0, 32, iap_working_area
->address
+ 0x08);
794 /* command result table */
795 init_mem_param(&mem_params
[1], iap_working_area
->address
+ 0x20, 5 * 4, PARAM_IN
);
797 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
798 buf_set_u32(reg_params
[1].value
, 0, 32, iap_working_area
->address
+ 0x20);
800 /* IAP entry point */
801 init_reg_param(®_params
[2], "r12", 32, PARAM_OUT
);
802 buf_set_u32(reg_params
[2].value
, 0, 32, iap_entry_point
);
804 switch (lpc2000_info
->variant
) {
813 init_reg_param(®_params
[3], "sp", 32, PARAM_OUT
);
814 buf_set_u32(reg_params
[3].value
, 0, 32,
815 iap_working_area
->address
+ IAP_CODE_LEN
+ lpc2000_info
->iap_max_stack
);
818 init_reg_param(®_params
[4], "lr", 32, PARAM_OUT
);
819 buf_set_u32(reg_params
[4].value
, 0, 32, (iap_working_area
->address
+ 0x04) | 1);
820 /* bit0 of LR = 1 to return in Thumb mode */
822 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, iap_working_area
->address
, 0, 10000,
828 init_reg_param(®_params
[3], "sp_svc", 32, PARAM_OUT
);
829 buf_set_u32(reg_params
[3].value
, 0, 32,
830 iap_working_area
->address
+ IAP_CODE_LEN
+ lpc2000_info
->iap_max_stack
);
833 init_reg_param(®_params
[4], "lr_svc", 32, PARAM_OUT
);
834 buf_set_u32(reg_params
[4].value
, 0, 32, iap_working_area
->address
+ 0x04);
836 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, iap_working_area
->address
,
837 iap_working_area
->address
+ 0x4, 10000, &arm_algo
);
840 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
844 int status_code
= target_buffer_get_u32(target
, mem_params
[1].value
);
845 result_table
[0] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x04);
846 result_table
[1] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x08);
847 result_table
[2] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x0c);
848 result_table
[3] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x10);
850 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
851 ") completed with result = %8.8x",
852 code
, param_table
[0], param_table
[1], param_table
[2], param_table
[3], param_table
[4], status_code
);
854 destroy_mem_param(&mem_params
[0]);
855 destroy_mem_param(&mem_params
[1]);
857 destroy_reg_param(®_params
[0]);
858 destroy_reg_param(®_params
[1]);
859 destroy_reg_param(®_params
[2]);
860 destroy_reg_param(®_params
[3]);
861 destroy_reg_param(®_params
[4]);
866 static int lpc2000_iap_blank_check(struct flash_bank
*bank
, unsigned int first
,
869 if (last
>= bank
->num_sectors
)
870 return ERROR_FLASH_SECTOR_INVALID
;
872 uint32_t param_table
[5] = {0};
873 uint32_t result_table
[4];
874 struct working_area
*iap_working_area
;
876 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
878 if (retval
!= ERROR_OK
)
881 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
882 if (lpc2000_info
->variant
== LPC4300
)
883 param_table
[2] = lpc2000_info
->lpc4300_bank
;
885 for (unsigned int i
= first
; i
<= last
&& retval
== ERROR_OK
; i
++) {
886 /* check single sector */
887 param_table
[0] = param_table
[1] = i
;
888 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 53, param_table
, result_table
);
890 switch (status_code
) {
891 case ERROR_FLASH_OPERATION_FAILED
:
892 retval
= ERROR_FLASH_OPERATION_FAILED
;
894 case LPC2000_CMD_SUCCESS
:
895 bank
->sectors
[i
].is_erased
= 1;
897 case LPC2000_SECTOR_NOT_BLANK
:
898 bank
->sectors
[i
].is_erased
= 0;
900 case LPC2000_INVALID_SECTOR
:
901 bank
->sectors
[i
].is_erased
= 0;
904 retval
= ERROR_FLASH_BUSY
;
907 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code
);
912 struct target
*target
= bank
->target
;
913 target_free_working_area(target
, iap_working_area
);
919 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
921 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command
)
924 return ERROR_COMMAND_SYNTAX_ERROR
;
926 struct lpc2000_flash_bank
*lpc2000_info
= calloc(1, sizeof(*lpc2000_info
));
927 lpc2000_info
->probed
= false;
929 bank
->driver_priv
= lpc2000_info
;
931 if (strcmp(CMD_ARGV
[6], "lpc2000_v1") == 0) {
932 lpc2000_info
->variant
= LPC2000_V1
;
933 } else if (strcmp(CMD_ARGV
[6], "lpc2000_v2") == 0) {
934 lpc2000_info
->variant
= LPC2000_V2
;
935 } else if (strcmp(CMD_ARGV
[6], "lpc1700") == 0 || strcmp(CMD_ARGV
[6], "lpc4000") == 0) {
936 lpc2000_info
->variant
= LPC1700
;
937 } else if (strcmp(CMD_ARGV
[6], "lpc1800") == 0 || strcmp(CMD_ARGV
[6], "lpc4300") == 0) {
938 lpc2000_info
->variant
= LPC4300
;
939 } else if (strcmp(CMD_ARGV
[6], "lpc800") == 0) {
940 lpc2000_info
->variant
= LPC800
;
941 } else if (strcmp(CMD_ARGV
[6], "lpc1100") == 0) {
942 lpc2000_info
->variant
= LPC1100
;
943 } else if (strcmp(CMD_ARGV
[6], "lpc1500") == 0) {
944 lpc2000_info
->variant
= LPC1500
;
945 } else if (strcmp(CMD_ARGV
[6], "lpc54100") == 0) {
946 lpc2000_info
->variant
= LPC54100
;
947 } else if (strcmp(CMD_ARGV
[6], "auto") == 0) {
948 lpc2000_info
->variant
= LPC_AUTO
;
950 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV
[6]);
952 return ERROR_FLASH_BANK_INVALID
;
955 /* Maximum size required for the IAP stack.
956 This value only gets used when probing, only for auto, lpc1100 and lpc1700.
957 We use the maximum size for any part supported by the driver(!) to be safe
958 in case the auto variant is mistakenly used on a MCU from one of the series
959 for which we don't support auto-probing. */
960 lpc2000_info
->iap_max_stack
= 208;
962 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[7], lpc2000_info
->cclk
);
963 lpc2000_info
->calc_checksum
= 0;
965 uint32_t temp_base
= 0;
966 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], temp_base
);
967 if (temp_base
>= 0x1B000000)
968 lpc2000_info
->lpc4300_bank
= 1; /* bank B */
970 lpc2000_info
->lpc4300_bank
= 0; /* bank A */
973 if (strcmp(CMD_ARGV
[8], "calc_checksum") == 0)
974 lpc2000_info
->calc_checksum
= 1;
976 if (CMD_ARGC
>= 10 && !lpc2000_info
->iap_entry_alternative
)
977 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[9], lpc2000_info
->iap_entry_alternative
);
982 static int lpc2000_erase(struct flash_bank
*bank
, unsigned int first
,
985 if (bank
->target
->state
!= TARGET_HALTED
) {
986 LOG_ERROR("Target not halted");
987 return ERROR_TARGET_NOT_HALTED
;
990 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
991 uint32_t param_table
[5] = {0};
993 param_table
[0] = first
;
994 param_table
[1] = last
;
996 if (lpc2000_info
->variant
== LPC4300
)
997 param_table
[2] = lpc2000_info
->lpc4300_bank
;
999 param_table
[2] = lpc2000_info
->cclk
;
1001 uint32_t result_table
[4];
1002 struct working_area
*iap_working_area
;
1004 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
1006 if (retval
!= ERROR_OK
)
1009 if (lpc2000_info
->variant
== LPC4300
)
1010 /* Init IAP Anyway */
1011 lpc2000_iap_call(bank
, iap_working_area
, 49, param_table
, result_table
);
1013 /* Prepare sectors */
1014 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 50, param_table
, result_table
);
1015 switch (status_code
) {
1016 case ERROR_FLASH_OPERATION_FAILED
:
1017 retval
= ERROR_FLASH_OPERATION_FAILED
;
1019 case LPC2000_CMD_SUCCESS
:
1021 case LPC2000_INVALID_SECTOR
:
1022 retval
= ERROR_FLASH_SECTOR_INVALID
;
1025 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
1026 retval
= ERROR_FLASH_OPERATION_FAILED
;
1030 if (retval
== ERROR_OK
) {
1032 param_table
[2] = lpc2000_info
->cclk
;
1033 if (lpc2000_info
->variant
== LPC4300
)
1034 param_table
[3] = lpc2000_info
->lpc4300_bank
;
1036 status_code
= lpc2000_iap_call(bank
, iap_working_area
, 52, param_table
, result_table
);
1037 switch (status_code
) {
1038 case ERROR_FLASH_OPERATION_FAILED
:
1039 retval
= ERROR_FLASH_OPERATION_FAILED
;
1041 case LPC2000_CMD_SUCCESS
:
1043 case LPC2000_INVALID_SECTOR
:
1044 retval
= ERROR_FLASH_SECTOR_INVALID
;
1047 LOG_WARNING("lpc2000 erase sectors returned %i", status_code
);
1048 retval
= ERROR_FLASH_OPERATION_FAILED
;
1053 struct target
*target
= bank
->target
;
1054 target_free_working_area(target
, iap_working_area
);
1059 static int lpc2000_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
1061 struct target
*target
= bank
->target
;
1063 if (bank
->target
->state
!= TARGET_HALTED
) {
1064 LOG_ERROR("Target not halted");
1065 return ERROR_TARGET_NOT_HALTED
;
1068 if (offset
+ count
> bank
->size
)
1069 return ERROR_FLASH_DST_OUT_OF_BANK
;
1071 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
1073 uint32_t dst_min_alignment
= lpc2000_info
->cmd51_dst_boundary
;
1075 if (offset
% dst_min_alignment
) {
1076 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
, offset
, dst_min_alignment
);
1077 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
1080 int first_sector
= 0;
1081 int last_sector
= 0;
1083 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
1084 if (offset
>= bank
->sectors
[i
].offset
)
1086 if (offset
+ DIV_ROUND_UP(count
, dst_min_alignment
) * dst_min_alignment
> bank
->sectors
[i
].offset
)
1090 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
1092 /* check if exception vectors should be flashed */
1093 if ((offset
== 0) && (count
>= 0x20) && lpc2000_info
->calc_checksum
) {
1094 assert(lpc2000_info
->checksum_vector
< 8);
1095 uint32_t checksum
= 0;
1096 for (int i
= 0; i
< 8; i
++) {
1097 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32
, i
* 4, buf_get_u32(buffer
+ (i
* 4), 0, 32));
1098 if (i
!= lpc2000_info
->checksum_vector
)
1099 checksum
+= buf_get_u32(buffer
+ (i
* 4), 0, 32);
1101 checksum
= 0 - checksum
;
1102 LOG_DEBUG("checksum: 0x%8.8" PRIx32
, checksum
);
1104 uint32_t original_value
= buf_get_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32);
1105 if (original_value
!= checksum
) {
1106 LOG_WARNING("Boot verification checksum in image (0x%8.8" PRIx32
") to be written to flash is "
1107 "different from calculated vector checksum (0x%8.8" PRIx32
").", original_value
, checksum
);
1108 LOG_WARNING("OpenOCD will write the correct checksum. To remove this warning modify build tools on developer PC to inject correct LPC vector "
1112 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
1113 buf_set_u32((uint8_t *)buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32, checksum
);
1116 struct working_area
*iap_working_area
;
1118 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
1120 if (retval
!= ERROR_OK
)
1123 struct working_area
*download_area
;
1125 /* allocate a working area */
1126 if (target_alloc_working_area(target
, lpc2000_info
->cmd51_max_buffer
, &download_area
) != ERROR_OK
) {
1127 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
1128 target_free_working_area(target
, iap_working_area
);
1129 return ERROR_FLASH_OPERATION_FAILED
;
1132 uint32_t bytes_remaining
= count
;
1133 uint32_t bytes_written
= 0;
1134 uint32_t param_table
[5] = {0};
1135 uint32_t result_table
[4];
1137 if (lpc2000_info
->variant
== LPC4300
)
1138 /* Init IAP Anyway */
1139 lpc2000_iap_call(bank
, iap_working_area
, 49, param_table
, result_table
);
1141 while (bytes_remaining
> 0) {
1142 uint32_t thisrun_bytes
;
1143 if (bytes_remaining
>= lpc2000_info
->cmd51_max_buffer
)
1144 thisrun_bytes
= lpc2000_info
->cmd51_max_buffer
;
1146 thisrun_bytes
= lpc2000_info
->cmd51_dst_boundary
;
1148 /* Prepare sectors */
1149 param_table
[0] = first_sector
;
1150 param_table
[1] = last_sector
;
1152 if (lpc2000_info
->variant
== LPC4300
)
1153 param_table
[2] = lpc2000_info
->lpc4300_bank
;
1155 param_table
[2] = lpc2000_info
->cclk
;
1157 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 50, param_table
, result_table
);
1158 switch (status_code
) {
1159 case ERROR_FLASH_OPERATION_FAILED
:
1160 retval
= ERROR_FLASH_OPERATION_FAILED
;
1162 case LPC2000_CMD_SUCCESS
:
1164 case LPC2000_INVALID_SECTOR
:
1165 retval
= ERROR_FLASH_SECTOR_INVALID
;
1168 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
1169 retval
= ERROR_FLASH_OPERATION_FAILED
;
1173 /* Exit if error occurred */
1174 if (retval
!= ERROR_OK
)
1177 if (bytes_remaining
>= thisrun_bytes
) {
1178 retval
= target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, buffer
+ bytes_written
);
1179 if (retval
!= ERROR_OK
) {
1180 retval
= ERROR_FLASH_OPERATION_FAILED
;
1184 uint8_t *last_buffer
= malloc(thisrun_bytes
);
1185 memcpy(last_buffer
, buffer
+ bytes_written
, bytes_remaining
);
1186 memset(last_buffer
+ bytes_remaining
, 0xff, thisrun_bytes
- bytes_remaining
);
1187 target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, last_buffer
);
1191 LOG_DEBUG("writing 0x%" PRIx32
" bytes to address " TARGET_ADDR_FMT
,
1192 thisrun_bytes
, bank
->base
+ offset
+ bytes_written
);
1195 param_table
[0] = bank
->base
+ offset
+ bytes_written
;
1196 param_table
[1] = download_area
->address
;
1197 param_table
[2] = thisrun_bytes
;
1198 param_table
[3] = lpc2000_info
->cclk
;
1199 status_code
= lpc2000_iap_call(bank
, iap_working_area
, 51, param_table
, result_table
);
1200 switch (status_code
) {
1201 case ERROR_FLASH_OPERATION_FAILED
:
1202 retval
= ERROR_FLASH_OPERATION_FAILED
;
1204 case LPC2000_CMD_SUCCESS
:
1206 case LPC2000_INVALID_SECTOR
:
1207 retval
= ERROR_FLASH_SECTOR_INVALID
;
1210 LOG_WARNING("lpc2000 returned %i", status_code
);
1211 retval
= ERROR_FLASH_OPERATION_FAILED
;
1215 /* Exit if error occurred */
1216 if (retval
!= ERROR_OK
)
1219 if (bytes_remaining
> thisrun_bytes
)
1220 bytes_remaining
-= thisrun_bytes
;
1222 bytes_remaining
= 0;
1223 bytes_written
+= thisrun_bytes
;
1226 target_free_working_area(target
, iap_working_area
);
1227 target_free_working_area(target
, download_area
);
1232 static int get_lpc2000_part_id(struct flash_bank
*bank
, uint32_t *part_id
)
1234 if (bank
->target
->state
!= TARGET_HALTED
) {
1235 LOG_ERROR("Target not halted");
1236 return ERROR_TARGET_NOT_HALTED
;
1239 uint32_t param_table
[5] = {0};
1240 uint32_t result_table
[4];
1241 struct working_area
*iap_working_area
;
1243 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
1245 if (retval
!= ERROR_OK
)
1248 /* The status seems to be bogus with the part ID command on some IAP
1249 firmwares, so ignore it. */
1250 lpc2000_iap_call(bank
, iap_working_area
, 54, param_table
, result_table
);
1252 struct target
*target
= bank
->target
;
1253 target_free_working_area(target
, iap_working_area
);
1255 /* If the result is zero, the command probably didn't work out. */
1256 if (result_table
[0] == 0)
1257 return LPC2000_INVALID_COMMAND
;
1259 *part_id
= result_table
[0];
1260 return LPC2000_CMD_SUCCESS
;
1263 static int lpc2000_auto_probe_flash(struct flash_bank
*bank
)
1267 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
1269 if (bank
->target
->state
!= TARGET_HALTED
) {
1270 LOG_ERROR("Target not halted");
1271 return ERROR_TARGET_NOT_HALTED
;
1274 retval
= get_lpc2000_part_id(bank
, &part_id
);
1275 if (retval
!= LPC2000_CMD_SUCCESS
) {
1276 LOG_ERROR("Could not get part ID");
1283 lpc2000_info
->variant
= LPC1100
;
1284 bank
->size
= 4 * 1024;
1295 case LPC11A11_001_1
:
1299 lpc2000_info
->variant
= LPC1100
;
1300 bank
->size
= 8 * 1024;
1312 case LPC11C12_301_1
:
1313 case LPC11C22_301_1
:
1314 case LPC11A12_101_1
:
1316 case LPC11U12_201_1
:
1317 case LPC11U12_201_2
:
1319 lpc2000_info
->variant
= LPC1100
;
1320 bank
->size
= 16 * 1024;
1329 case LPC11A13_201_1
:
1331 case LPC11U13_201_1
:
1332 case LPC11U13_201_2
:
1334 lpc2000_info
->variant
= LPC1100
;
1335 bank
->size
= 24 * 1024;
1347 case LPC11A14_301_1
:
1348 case LPC11A14_301_2
:
1349 case LPC11C14_301_1
:
1350 case LPC11C24_301_1
:
1352 case LPC11U14_201_1
:
1353 case LPC11U14_201_2
:
1362 lpc2000_info
->variant
= LPC1100
;
1363 bank
->size
= 32 * 1024;
1368 lpc2000_info
->variant
= LPC1700
;
1369 bank
->size
= 32 * 1024;
1373 lpc2000_info
->variant
= LPC1100
;
1374 bank
->size
= 40 * 1024;
1381 lpc2000_info
->variant
= LPC1100
;
1382 bank
->size
= 48 * 1024;
1386 lpc2000_info
->variant
= LPC1100
;
1387 bank
->size
= 56 * 1024;
1397 lpc2000_info
->variant
= LPC1100
;
1398 bank
->size
= 64 * 1024;
1403 lpc2000_info
->variant
= LPC1700
;
1404 bank
->size
= 64 * 1024;
1409 lpc2000_info
->variant
= LPC1100
;
1410 bank
->size
= 96 * 1024;
1422 lpc2000_info
->variant
= LPC1100
;
1423 bank
->size
= 128 * 1024;
1430 lpc2000_info
->variant
= LPC1700
;
1431 bank
->size
= 128 * 1024;
1436 lpc2000_info
->variant
= LPC1100
;
1437 bank
->size
= 256 * 1024;
1448 lpc2000_info
->variant
= LPC1700
;
1449 bank
->size
= 256 * 1024;
1463 lpc2000_info
->variant
= LPC1700
;
1464 bank
->size
= 512 * 1024;
1468 lpc2000_info
->variant
= LPC800
;
1469 bank
->size
= 4 * 1024;
1473 lpc2000_info
->variant
= LPC800
;
1474 bank
->size
= 8 * 1024;
1483 lpc2000_info
->variant
= LPC800
;
1484 bank
->size
= 16 * 1024;
1489 lpc2000_info
->variant
= LPC800
;
1490 bank
->size
= 32 * 1024;
1497 lpc2000_info
->variant
= LPC800
;
1498 bank
->size
= 30 * 1024;
1508 lpc2000_info
->variant
= LPC800
;
1509 bank
->size
= 64 * 1024;
1513 LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32
, part_id
);
1520 static int lpc2000_probe(struct flash_bank
*bank
)
1524 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
1526 if (!lpc2000_info
->probed
) {
1527 if (lpc2000_info
->variant
== LPC_AUTO
) {
1528 status
= lpc2000_auto_probe_flash(bank
);
1529 if (status
!= ERROR_OK
)
1531 } else if (lpc2000_info
->variant
== LPC1100
|| lpc2000_info
->variant
== LPC1700
) {
1532 status
= get_lpc2000_part_id(bank
, &part_id
);
1533 if (status
== LPC2000_CMD_SUCCESS
)
1534 LOG_INFO("If auto-detection fails for this part, please email "
1535 "openocd-devel@lists.sourceforge.net, citing part id 0x%" PRIx32
".\n", part_id
);
1538 lpc2000_build_sector_list(bank
);
1539 lpc2000_info
->probed
= true;
1545 static int lpc2000_erase_check(struct flash_bank
*bank
)
1547 if (bank
->target
->state
!= TARGET_HALTED
) {
1548 LOG_ERROR("Target not halted");
1549 return ERROR_TARGET_NOT_HALTED
;
1552 return lpc2000_iap_blank_check(bank
, 0, bank
->num_sectors
- 1);
1555 static int get_lpc2000_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
1557 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
1559 command_print_sameline(cmd
, "lpc2000 flash driver variant: %i, clk: %" PRIu32
"kHz",
1560 lpc2000_info
->variant
, lpc2000_info
->cclk
);
1565 COMMAND_HANDLER(lpc2000_handle_part_id_command
)
1568 return ERROR_COMMAND_SYNTAX_ERROR
;
1570 struct flash_bank
*bank
;
1571 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1572 if (retval
!= ERROR_OK
)
1575 if (bank
->target
->state
!= TARGET_HALTED
) {
1576 LOG_ERROR("Target not halted");
1577 return ERROR_TARGET_NOT_HALTED
;
1581 int status_code
= get_lpc2000_part_id(bank
, &part_id
);
1582 if (status_code
!= 0x0) {
1583 if (status_code
== ERROR_FLASH_OPERATION_FAILED
) {
1584 command_print(CMD
, "no sufficient working area specified, can't access LPC2000 IAP interface");
1586 command_print(CMD
, "lpc2000 IAP returned status code %i", status_code
);
1588 command_print(CMD
, "lpc2000 part id: 0x%8.8" PRIx32
, part_id
);
1593 static const struct command_registration lpc2000_exec_command_handlers
[] = {
1596 .handler
= lpc2000_handle_part_id_command
,
1597 .mode
= COMMAND_EXEC
,
1598 .help
= "print part id of lpc2000 flash bank <num>",
1601 COMMAND_REGISTRATION_DONE
1603 static const struct command_registration lpc2000_command_handlers
[] = {
1606 .mode
= COMMAND_ANY
,
1607 .help
= "lpc2000 flash command group",
1609 .chain
= lpc2000_exec_command_handlers
,
1611 COMMAND_REGISTRATION_DONE
1614 const struct flash_driver lpc2000_flash
= {
1616 .commands
= lpc2000_command_handlers
,
1617 .flash_bank_command
= lpc2000_flash_bank_command
,
1618 .erase
= lpc2000_erase
,
1619 .write
= lpc2000_write
,
1620 .read
= default_flash_read
,
1621 .probe
= lpc2000_probe
,
1622 .auto_probe
= lpc2000_probe
,
1623 .erase_check
= lpc2000_erase_check
,
1624 .info
= get_lpc2000_info
,
1625 .free_driver_priv
= default_flash_free_driver_priv
,
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)