Flash/LPC2000: Add support for LPC11(x)xx, LPC13xx
[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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "imp.h"
29 #include <helper/binarybuffer.h>
30 #include <target/algorithm.h>
31 #include <target/arm_opcodes.h>
32 #include <target/armv7m.h>
33
34 /**
35 * @file
36 * flash programming support for NXP LPC17xx and LPC2xxx devices.
37 *
38 * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
39 * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
40 */
41 /*
42 * currently supported devices:
43 * variant 1 (lpc2000_v1):
44 * - 2104 | 5 | 6
45 * - 2114 | 9
46 * - 2124 | 9
47 * - 2194
48 * - 2212 | 4
49 * - 2292 | 4
50 *
51 * variant 2 (lpc2000_v2):
52 * - 213x
53 * - 214x
54 * - 2101 | 2 | 3
55 * - 2364 | 6 | 8
56 * - 2378
57 *
58 * lpc1700:
59 * - 175x
60 * - 176x (tested with LPC1768)
61 *
62 * lpc4300 (also available as lpc1800 - alias)
63 * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357)
64 * - 18x2 | 3 | 5 | 7
65 *
66 * lpc800:
67 * - 810 | 1 | 2 (tested with LPC810/LPC812)
68 *
69 * lpc1100:
70 * - 11xx
71 * - 11Axx
72 * - 11Cxx
73 * - 11Dxx
74 * - 11Exx
75 * - 11Uxx (tested with LPC11U34)
76 * - 131x
77 * - 134x
78 */
79
80 typedef enum {
81 lpc2000_v1,
82 lpc2000_v2,
83 lpc1700,
84 lpc4300,
85 lpc800,
86 lpc1100,
87 } lpc2000_variant;
88
89 struct lpc2000_flash_bank {
90 lpc2000_variant variant;
91 uint32_t cclk;
92 int cmd51_dst_boundary;
93 int cmd51_can_64b;
94 int cmd51_can_256b;
95 int cmd51_can_8192b;
96 int calc_checksum;
97 uint32_t cmd51_max_buffer;
98 int checksum_vector;
99 uint32_t iap_max_stack;
100 uint32_t cmd51_src_offset;
101 uint32_t lpc4300_bank;
102 };
103
104 enum lpc2000_status_codes {
105 LPC2000_CMD_SUCCESS = 0,
106 LPC2000_INVALID_COMMAND = 1,
107 LPC2000_SRC_ADDR_ERROR = 2,
108 LPC2000_DST_ADDR_ERROR = 3,
109 LPC2000_SRC_ADDR_NOT_MAPPED = 4,
110 LPC2000_DST_ADDR_NOT_MAPPED = 5,
111 LPC2000_COUNT_ERROR = 6,
112 LPC2000_INVALID_SECTOR = 7,
113 LPC2000_SECTOR_NOT_BLANK = 8,
114 LPC2000_SECTOR_NOT_PREPARED = 9,
115 LPC2000_COMPARE_ERROR = 10,
116 LPC2000_BUSY = 11,
117 LPC2000_PARAM_ERROR = 12,
118 LPC2000_ADDR_ERROR = 13,
119 LPC2000_ADDR_NOT_MAPPED = 14,
120 LPC2000_CMD_NOT_LOCKED = 15,
121 LPC2000_INVALID_CODE = 16,
122 LPC2000_INVALID_BAUD_RATE = 17,
123 LPC2000_INVALID_STOP_BIT = 18,
124 LPC2000_CRP_ENABLED = 19,
125 LPC2000_INVALID_FLASH_UNIT = 20,
126 LPC2000_USER_CODE_CHECKSUM = 21,
127 LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22,
128 };
129
130 static int lpc2000_build_sector_list(struct flash_bank *bank)
131 {
132 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
133 uint32_t offset = 0;
134
135 /* default to a 4096 write buffer */
136 lpc2000_info->cmd51_max_buffer = 4096;
137
138 if (lpc2000_info->variant == lpc2000_v1) {
139 /* variant 1 has different layout for 128kb and 256kb flashes */
140 if (bank->size == 128 * 1024) {
141 bank->num_sectors = 16;
142 bank->sectors = malloc(sizeof(struct flash_sector) * 16);
143 for (int i = 0; i < 16; i++) {
144 bank->sectors[i].offset = offset;
145 bank->sectors[i].size = 8 * 1024;
146 offset += bank->sectors[i].size;
147 bank->sectors[i].is_erased = -1;
148 bank->sectors[i].is_protected = 1;
149 }
150 } else if (bank->size == 256 * 1024) {
151 bank->num_sectors = 18;
152 bank->sectors = malloc(sizeof(struct flash_sector) * 18);
153
154 for (int i = 0; i < 8; i++) {
155 bank->sectors[i].offset = offset;
156 bank->sectors[i].size = 8 * 1024;
157 offset += bank->sectors[i].size;
158 bank->sectors[i].is_erased = -1;
159 bank->sectors[i].is_protected = 1;
160 }
161 for (int i = 8; i < 10; i++) {
162 bank->sectors[i].offset = offset;
163 bank->sectors[i].size = 64 * 1024;
164 offset += bank->sectors[i].size;
165 bank->sectors[i].is_erased = -1;
166 bank->sectors[i].is_protected = 1;
167 }
168 for (int i = 10; i < 18; i++) {
169 bank->sectors[i].offset = offset;
170 bank->sectors[i].size = 8 * 1024;
171 offset += bank->sectors[i].size;
172 bank->sectors[i].is_erased = -1;
173 bank->sectors[i].is_protected = 1;
174 }
175 } else {
176 LOG_ERROR("BUG: unknown bank->size encountered");
177 exit(-1);
178 }
179 } else if (lpc2000_info->variant == lpc2000_v2) {
180 /* variant 2 has a uniform layout, only number of sectors differs */
181 switch (bank->size) {
182 case 4 * 1024:
183 lpc2000_info->cmd51_max_buffer = 1024;
184 bank->num_sectors = 1;
185 break;
186 case 8 * 1024:
187 lpc2000_info->cmd51_max_buffer = 1024;
188 bank->num_sectors = 2;
189 break;
190 case 16 * 1024:
191 bank->num_sectors = 4;
192 break;
193 case 32 * 1024:
194 bank->num_sectors = 8;
195 break;
196 case 64 * 1024:
197 bank->num_sectors = 9;
198 break;
199 case 128 * 1024:
200 bank->num_sectors = 11;
201 break;
202 case 256 * 1024:
203 bank->num_sectors = 15;
204 break;
205 case 500 * 1024:
206 bank->num_sectors = 27;
207 break;
208 case 512 * 1024:
209 case 504 * 1024:
210 bank->num_sectors = 28;
211 break;
212 default:
213 LOG_ERROR("BUG: unknown bank->size encountered");
214 exit(-1);
215 break;
216 }
217
218 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
219
220 for (int i = 0; i < bank->num_sectors; i++) {
221 if (i < 8) {
222 bank->sectors[i].offset = offset;
223 bank->sectors[i].size = 4 * 1024;
224 offset += bank->sectors[i].size;
225 bank->sectors[i].is_erased = -1;
226 bank->sectors[i].is_protected = 1;
227 } else if (i < 22) {
228 bank->sectors[i].offset = offset;
229 bank->sectors[i].size = 32 * 1024;
230 offset += bank->sectors[i].size;
231 bank->sectors[i].is_erased = -1;
232 bank->sectors[i].is_protected = 1;
233 } else if (i < 28) {
234 bank->sectors[i].offset = offset;
235 bank->sectors[i].size = 4 * 1024;
236 offset += bank->sectors[i].size;
237 bank->sectors[i].is_erased = -1;
238 bank->sectors[i].is_protected = 1;
239 }
240 }
241 } else if (lpc2000_info->variant == lpc1700) {
242 switch (bank->size) {
243 case 4 * 1024:
244 lpc2000_info->cmd51_max_buffer = 256;
245 bank->num_sectors = 1;
246 break;
247 case 8 * 1024:
248 lpc2000_info->cmd51_max_buffer = 512;
249 bank->num_sectors = 2;
250 break;
251 case 16 * 1024:
252 lpc2000_info->cmd51_max_buffer = 512;
253 bank->num_sectors = 4;
254 break;
255 case 32 * 1024:
256 lpc2000_info->cmd51_max_buffer = 1024;
257 bank->num_sectors = 8;
258 break;
259 case 64 * 1024:
260 bank->num_sectors = 16;
261 break;
262 case 128 * 1024:
263 bank->num_sectors = 18;
264 break;
265 case 256 * 1024:
266 bank->num_sectors = 22;
267 break;
268 case 512 * 1024:
269 bank->num_sectors = 30;
270 break;
271 default:
272 LOG_ERROR("BUG: unknown bank->size encountered");
273 exit(-1);
274 }
275
276 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
277
278 for (int i = 0; i < bank->num_sectors; i++) {
279 bank->sectors[i].offset = offset;
280 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
281 bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;
282 offset += bank->sectors[i].size;
283 bank->sectors[i].is_erased = -1;
284 bank->sectors[i].is_protected = 1;
285 }
286 } else if (lpc2000_info->variant == lpc4300) {
287 switch (bank->size) {
288 case 256 * 1024:
289 bank->num_sectors = 11;
290 break;
291 case 384 * 1024:
292 bank->num_sectors = 13;
293 break;
294 case 512 * 1024:
295 bank->num_sectors = 15;
296 break;
297 default:
298 LOG_ERROR("BUG: unknown bank->size encountered");
299 exit(-1);
300 }
301
302 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
303
304 for (int i = 0; i < bank->num_sectors; i++) {
305 bank->sectors[i].offset = offset;
306 /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
307 bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024;
308 offset += bank->sectors[i].size;
309 bank->sectors[i].is_erased = -1;
310 bank->sectors[i].is_protected = 1;
311 }
312
313 } else if (lpc2000_info->variant == lpc800) {
314 lpc2000_info->cmd51_max_buffer = 1024;
315 switch (bank->size) {
316 case 4 * 1024:
317 lpc2000_info->cmd51_max_buffer = 256;
318 bank->num_sectors = 4;
319 break;
320 case 8 * 1024:
321 lpc2000_info->cmd51_max_buffer = 512;
322 bank->num_sectors = 8;
323 break;
324 case 16 * 1024:
325 bank->num_sectors = 16;
326 break;
327 default:
328 LOG_ERROR("BUG: unknown bank->size encountered");
329 exit(-1);
330 }
331
332 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
333
334 for (int i = 0; i < bank->num_sectors; i++) {
335 bank->sectors[i].offset = offset;
336 /* sectors 0-15 are 1kB-sized for LPC8xx devices */
337 bank->sectors[i].size = 1 * 1024;
338 offset += bank->sectors[i].size;
339 bank->sectors[i].is_erased = -1;
340 bank->sectors[i].is_protected = 1;
341 }
342
343 } else if (lpc2000_info->variant == lpc1100) {
344 if ((bank->size % (4 * 1024)) != 0) {
345 LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096");
346 exit(-1);
347 }
348 lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
349 bank->num_sectors = bank->size / 4096;
350
351 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
352
353 for (int i = 0; i < bank->num_sectors; i++) {
354 bank->sectors[i].offset = offset;
355 /* all sectors are 4kB-sized */
356 bank->sectors[i].size = 4 * 1024;
357 offset += bank->sectors[i].size;
358 bank->sectors[i].is_erased = -1;
359 bank->sectors[i].is_protected = 1;
360 }
361
362 } else {
363 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
364 exit(-1);
365 }
366
367 return ERROR_OK;
368 }
369
370 /* this function allocates and initializes working area used for IAP algorithm
371 * uses 52 + max IAP stack bytes working area
372 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
373 * 0x8 to 0x1f: command parameter table (1+5 words)
374 * 0x20 to 0x33: command result table (1+4 words)
375 * 0x34 to 0xb3|0x104: stack (only 128b needed for lpc17xx/2000, 208 for lpc43xx and 148b for lpc8xx)
376 */
377
378 static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
379 {
380 struct target *target = bank->target;
381 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
382
383 if (target_alloc_working_area(target, 0x34 + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {
384 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
385 return ERROR_FLASH_OPERATION_FAILED;
386 }
387
388 uint8_t jump_gate[8];
389
390 /* write IAP code to working area */
391 switch (lpc2000_info->variant) {
392 case lpc800:
393 case lpc1100:
394 case lpc1700:
395 case lpc4300:
396 target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
397 target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
398 break;
399 case lpc2000_v1:
400 case lpc2000_v2:
401 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
402 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
403 break;
404 default:
405 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
406 exit(-1);
407 }
408
409 int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
410 if (retval != ERROR_OK)
411 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
412 (*iap_working_area)->address);
413
414 return retval;
415 }
416
417 /* call LPC1700/LPC2000 IAP function */
418
419 static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
420 uint32_t param_table[5], uint32_t result_table[4])
421 {
422 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
423 struct target *target = bank->target;
424
425 struct arm_algorithm arm_algo; /* for LPC2000 */
426 struct armv7m_algorithm armv7m_info; /* for LPC1700 */
427 uint32_t iap_entry_point = 0; /* to make compiler happier */
428
429 switch (lpc2000_info->variant) {
430 case lpc800:
431 case lpc1100:
432 case lpc1700:
433 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
434 armv7m_info.core_mode = ARM_MODE_THREAD;
435 iap_entry_point = 0x1fff1ff1;
436 break;
437 case lpc2000_v1:
438 case lpc2000_v2:
439 arm_algo.common_magic = ARM_COMMON_MAGIC;
440 arm_algo.core_mode = ARM_MODE_SVC;
441 arm_algo.core_state = ARM_STATE_ARM;
442 iap_entry_point = 0x7ffffff1;
443 break;
444 case lpc4300:
445 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
446 armv7m_info.core_mode = ARM_MODE_THREAD;
447 /* read out IAP entry point from ROM driver table at 0x10400100 */
448 target_read_u32(target, 0x10400100, &iap_entry_point);
449 break;
450 default:
451 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
452 exit(-1);
453 }
454
455 struct mem_param mem_params[2];
456
457 /* command parameter table */
458 init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
459 target_buffer_set_u32(target, mem_params[0].value, code);
460 target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
461 target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
462 target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
463 target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
464 target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
465
466 struct reg_param reg_params[5];
467
468 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
469 buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
470
471 /* command result table */
472 init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
473
474 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
475 buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
476
477 /* IAP entry point */
478 init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
479 buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
480
481 switch (lpc2000_info->variant) {
482 case lpc800:
483 case lpc1100:
484 case lpc1700:
485 case lpc4300:
486 /* IAP stack */
487 init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
488 buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
489
490 /* return address */
491 init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
492 buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
493 /* bit0 of LR = 1 to return in Thumb mode */
494
495 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
496 &armv7m_info);
497 break;
498 case lpc2000_v1:
499 case lpc2000_v2:
500 /* IAP stack */
501 init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
502 buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
503
504 /* return address */
505 init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
506 buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
507
508 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
509 iap_working_area->address + 0x4, 10000, &arm_algo);
510 break;
511 default:
512 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
513 exit(-1);
514 }
515
516 int status_code = target_buffer_get_u32(target, mem_params[1].value);
517 result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
518 result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
519 result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
520 result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
521
522 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
523 ") completed with result = %8.8x",
524 code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
525
526 destroy_mem_param(&mem_params[0]);
527 destroy_mem_param(&mem_params[1]);
528
529 destroy_reg_param(&reg_params[0]);
530 destroy_reg_param(&reg_params[1]);
531 destroy_reg_param(&reg_params[2]);
532 destroy_reg_param(&reg_params[3]);
533 destroy_reg_param(&reg_params[4]);
534
535 return status_code;
536 }
537
538 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
539 {
540 if ((first < 0) || (last >= bank->num_sectors))
541 return ERROR_FLASH_SECTOR_INVALID;
542
543 uint32_t param_table[5] = {0};
544 uint32_t result_table[4];
545 struct working_area *iap_working_area;
546
547 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
548
549 if (retval != ERROR_OK)
550 return retval;
551
552 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
553 if (lpc2000_info->variant == lpc4300)
554 param_table[2] = lpc2000_info->lpc4300_bank;
555
556 for (int i = first; i <= last && retval == ERROR_OK; i++) {
557 /* check single sector */
558 param_table[0] = param_table[1] = i;
559 int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
560
561 switch (status_code) {
562 case ERROR_FLASH_OPERATION_FAILED:
563 retval = ERROR_FLASH_OPERATION_FAILED;
564 break;
565 case LPC2000_CMD_SUCCESS:
566 bank->sectors[i].is_erased = 1;
567 break;
568 case LPC2000_SECTOR_NOT_BLANK:
569 bank->sectors[i].is_erased = 0;
570 break;
571 case LPC2000_INVALID_SECTOR:
572 bank->sectors[i].is_erased = 0;
573 break;
574 case LPC2000_BUSY:
575 retval = ERROR_FLASH_BUSY;
576 break;
577 default:
578 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
579 exit(-1);
580 }
581 }
582
583 struct target *target = bank->target;
584 target_free_working_area(target, iap_working_area);
585
586 return retval;
587 }
588
589 /*
590 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
591 */
592 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
593 {
594 if (CMD_ARGC < 8)
595 return ERROR_COMMAND_SYNTAX_ERROR;
596
597 struct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info));
598
599 bank->driver_priv = lpc2000_info;
600
601 if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
602 lpc2000_info->variant = lpc2000_v1;
603 lpc2000_info->cmd51_dst_boundary = 512;
604 lpc2000_info->cmd51_can_256b = 0;
605 lpc2000_info->cmd51_can_8192b = 1;
606 lpc2000_info->checksum_vector = 5;
607 lpc2000_info->iap_max_stack = 128;
608 } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
609 lpc2000_info->variant = lpc2000_v2;
610 lpc2000_info->cmd51_dst_boundary = 256;
611 lpc2000_info->cmd51_can_256b = 1;
612 lpc2000_info->cmd51_can_8192b = 0;
613 lpc2000_info->checksum_vector = 5;
614 lpc2000_info->iap_max_stack = 128;
615 } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0) {
616 lpc2000_info->variant = lpc1700;
617 lpc2000_info->cmd51_dst_boundary = 256;
618 lpc2000_info->cmd51_can_256b = 1;
619 lpc2000_info->cmd51_can_8192b = 0;
620 lpc2000_info->checksum_vector = 7;
621 lpc2000_info->iap_max_stack = 128;
622 } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) {
623 lpc2000_info->variant = lpc4300;
624 lpc2000_info->cmd51_dst_boundary = 512;
625 lpc2000_info->cmd51_can_256b = 0;
626 lpc2000_info->cmd51_can_8192b = 0;
627 lpc2000_info->checksum_vector = 7;
628 lpc2000_info->iap_max_stack = 208;
629 } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) {
630 lpc2000_info->variant = lpc800;
631 lpc2000_info->cmd51_dst_boundary = 64;
632 lpc2000_info->cmd51_can_64b = 1;
633 lpc2000_info->cmd51_can_256b = 0;
634 lpc2000_info->cmd51_can_8192b = 0;
635 lpc2000_info->checksum_vector = 7;
636 lpc2000_info->iap_max_stack = 148;
637 } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) {
638 lpc2000_info->variant = lpc1100;
639 lpc2000_info->cmd51_dst_boundary = 256;
640 lpc2000_info->cmd51_can_256b = 1;
641 lpc2000_info->cmd51_can_8192b = 0;
642 lpc2000_info->checksum_vector = 7;
643 lpc2000_info->iap_max_stack = 128;
644 } else {
645 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
646 free(lpc2000_info);
647 return ERROR_FLASH_BANK_INVALID;
648 }
649
650 /* see lpc2000_iap_working_area_init() for the reason behind the 0x34 value */
651 lpc2000_info->cmd51_src_offset = 0x34 + lpc2000_info->iap_max_stack;
652
653 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
654 lpc2000_info->calc_checksum = 0;
655 lpc2000_build_sector_list(bank);
656
657 uint32_t temp_base = 0;
658 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
659 if (temp_base >= 0x1B000000)
660 lpc2000_info->lpc4300_bank = 1; /* bank B */
661 else
662 lpc2000_info->lpc4300_bank = 0; /* bank A */
663
664 if (CMD_ARGC >= 9) {
665 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
666 lpc2000_info->calc_checksum = 1;
667 }
668
669 return ERROR_OK;
670 }
671
672 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
673 {
674 if (bank->target->state != TARGET_HALTED) {
675 LOG_ERROR("Target not halted");
676 return ERROR_TARGET_NOT_HALTED;
677 }
678
679 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
680 uint32_t param_table[5] = {0};
681
682 param_table[0] = first;
683 param_table[1] = last;
684
685 if (lpc2000_info->variant == lpc4300)
686 param_table[2] = lpc2000_info->lpc4300_bank;
687 else
688 param_table[2] = lpc2000_info->cclk;
689
690 uint32_t result_table[4];
691 struct working_area *iap_working_area;
692
693 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
694
695 if (retval != ERROR_OK)
696 return retval;
697
698 if (lpc2000_info->variant == lpc4300)
699 /* Init IAP Anyway */
700 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
701
702 /* Prepare sectors */
703 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
704 switch (status_code) {
705 case ERROR_FLASH_OPERATION_FAILED:
706 retval = ERROR_FLASH_OPERATION_FAILED;
707 break;
708 case LPC2000_CMD_SUCCESS:
709 break;
710 case LPC2000_INVALID_SECTOR:
711 retval = ERROR_FLASH_SECTOR_INVALID;
712 break;
713 default:
714 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
715 retval = ERROR_FLASH_OPERATION_FAILED;
716 break;
717 }
718
719 if (retval == ERROR_OK) {
720 /* Erase sectors */
721 param_table[2] = lpc2000_info->cclk;
722 if (lpc2000_info->variant == lpc4300)
723 param_table[3] = lpc2000_info->lpc4300_bank;
724
725 status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
726 switch (status_code) {
727 case ERROR_FLASH_OPERATION_FAILED:
728 retval = ERROR_FLASH_OPERATION_FAILED;
729 break;
730 case LPC2000_CMD_SUCCESS:
731 break;
732 case LPC2000_INVALID_SECTOR:
733 retval = ERROR_FLASH_SECTOR_INVALID;
734 break;
735 default:
736 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
737 retval = ERROR_FLASH_OPERATION_FAILED;
738 break;
739 }
740 }
741
742 struct target *target = bank->target;
743 target_free_working_area(target, iap_working_area);
744
745 return retval;
746 }
747
748 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
749 {
750 /* can't protect/unprotect on the lpc2000 */
751 return ERROR_OK;
752 }
753
754 static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
755 {
756 struct target *target = bank->target;
757
758 if (bank->target->state != TARGET_HALTED) {
759 LOG_ERROR("Target not halted");
760 return ERROR_TARGET_NOT_HALTED;
761 }
762
763 if (offset + count > bank->size)
764 return ERROR_FLASH_DST_OUT_OF_BANK;
765
766 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
767
768 uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
769
770 if (offset % dst_min_alignment) {
771 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
772 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
773 }
774
775 int first_sector = 0;
776 int last_sector = 0;
777
778 for (int i = 0; i < bank->num_sectors; i++) {
779 if (offset >= bank->sectors[i].offset)
780 first_sector = i;
781 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
782 last_sector = i;
783 }
784
785 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
786
787 /* check if exception vectors should be flashed */
788 if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
789 assert(lpc2000_info->checksum_vector < 8);
790 uint32_t checksum = 0;
791 for (int i = 0; i < 8; i++) {
792 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
793 if (i != lpc2000_info->checksum_vector)
794 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
795 }
796 checksum = 0 - checksum;
797 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
798
799 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
800 if (original_value != checksum) {
801 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
802 "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
803 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
804 "checksum.");
805 }
806
807 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
808 buf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
809 }
810
811 struct working_area *iap_working_area;
812
813 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
814
815 if (retval != ERROR_OK)
816 return retval;
817
818 struct working_area *download_area;
819
820 /* allocate a working area */
821 if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
822 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
823 target_free_working_area(target, iap_working_area);
824 return ERROR_FLASH_OPERATION_FAILED;
825 }
826
827 uint32_t bytes_remaining = count;
828 uint32_t bytes_written = 0;
829 uint32_t param_table[5] = {0};
830 uint32_t result_table[4];
831
832 if (lpc2000_info->variant == lpc4300)
833 /* Init IAP Anyway */
834 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
835
836 while (bytes_remaining > 0) {
837 uint32_t thisrun_bytes;
838 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
839 thisrun_bytes = lpc2000_info->cmd51_max_buffer;
840 else if (bytes_remaining >= 1024)
841 thisrun_bytes = 1024;
842 else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
843 thisrun_bytes = 512;
844 else if ((bytes_remaining >= 256) || (!lpc2000_info->cmd51_can_64b))
845 thisrun_bytes = 256;
846 else
847 thisrun_bytes = 64;
848
849 /* Prepare sectors */
850 param_table[0] = first_sector;
851 param_table[1] = last_sector;
852
853 if (lpc2000_info->variant == lpc4300)
854 param_table[2] = lpc2000_info->lpc4300_bank;
855 else
856 param_table[2] = lpc2000_info->cclk;
857
858 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
859 switch (status_code) {
860 case ERROR_FLASH_OPERATION_FAILED:
861 retval = ERROR_FLASH_OPERATION_FAILED;
862 break;
863 case LPC2000_CMD_SUCCESS:
864 break;
865 case LPC2000_INVALID_SECTOR:
866 retval = ERROR_FLASH_SECTOR_INVALID;
867 break;
868 default:
869 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
870 retval = ERROR_FLASH_OPERATION_FAILED;
871 break;
872 }
873
874 /* Exit if error occured */
875 if (retval != ERROR_OK)
876 break;
877
878 if (bytes_remaining >= thisrun_bytes) {
879 retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
880 if (retval != ERROR_OK) {
881 retval = ERROR_FLASH_OPERATION_FAILED;
882 break;
883 }
884 } else {
885 uint8_t *last_buffer = malloc(thisrun_bytes);
886 memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
887 memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
888 target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
889 free(last_buffer);
890 }
891
892 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
893 bank->base + offset + bytes_written);
894
895 /* Write data */
896 param_table[0] = bank->base + offset + bytes_written;
897 param_table[1] = download_area->address;
898 param_table[2] = thisrun_bytes;
899 param_table[3] = lpc2000_info->cclk;
900 status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
901 switch (status_code) {
902 case ERROR_FLASH_OPERATION_FAILED:
903 retval = ERROR_FLASH_OPERATION_FAILED;
904 break;
905 case LPC2000_CMD_SUCCESS:
906 break;
907 case LPC2000_INVALID_SECTOR:
908 retval = ERROR_FLASH_SECTOR_INVALID;
909 break;
910 default:
911 LOG_WARNING("lpc2000 returned %i", status_code);
912 retval = ERROR_FLASH_OPERATION_FAILED;
913 break;
914 }
915
916 /* Exit if error occured */
917 if (retval != ERROR_OK)
918 break;
919
920 if (bytes_remaining > thisrun_bytes)
921 bytes_remaining -= thisrun_bytes;
922 else
923 bytes_remaining = 0;
924 bytes_written += thisrun_bytes;
925 }
926
927 target_free_working_area(target, iap_working_area);
928 target_free_working_area(target, download_area);
929
930 return retval;
931 }
932
933 static int lpc2000_probe(struct flash_bank *bank)
934 {
935 /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
936 return ERROR_OK;
937 }
938
939 static int lpc2000_erase_check(struct flash_bank *bank)
940 {
941 if (bank->target->state != TARGET_HALTED) {
942 LOG_ERROR("Target not halted");
943 return ERROR_TARGET_NOT_HALTED;
944 }
945
946 return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
947 }
948
949 static int lpc2000_protect_check(struct flash_bank *bank)
950 {
951 /* sectors are always protected */
952 return ERROR_OK;
953 }
954
955 static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
956 {
957 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
958
959 snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
960 lpc2000_info->cclk);
961
962 return ERROR_OK;
963 }
964
965 COMMAND_HANDLER(lpc2000_handle_part_id_command)
966 {
967 if (CMD_ARGC < 1)
968 return ERROR_COMMAND_SYNTAX_ERROR;
969
970 struct flash_bank *bank;
971 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
972 if (ERROR_OK != retval)
973 return retval;
974
975 if (bank->target->state != TARGET_HALTED) {
976 LOG_ERROR("Target not halted");
977 return ERROR_TARGET_NOT_HALTED;
978 }
979
980 uint32_t param_table[5] = {0};
981 uint32_t result_table[4];
982 struct working_area *iap_working_area;
983
984 retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
985
986 if (retval != ERROR_OK)
987 return retval;
988
989 int status_code = lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
990 if (status_code != 0x0) {
991 if (status_code == ERROR_FLASH_OPERATION_FAILED) {
992 command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
993 } else
994 command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
995 } else
996 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, result_table[0]);
997
998 return retval;
999 }
1000
1001 static const struct command_registration lpc2000_exec_command_handlers[] = {
1002 {
1003 .name = "part_id",
1004 .handler = lpc2000_handle_part_id_command,
1005 .mode = COMMAND_EXEC,
1006 .help = "print part id of lpc2000 flash bank <num>",
1007 .usage = "<bank>",
1008 },
1009 COMMAND_REGISTRATION_DONE
1010 };
1011 static const struct command_registration lpc2000_command_handlers[] = {
1012 {
1013 .name = "lpc2000",
1014 .mode = COMMAND_ANY,
1015 .help = "lpc2000 flash command group",
1016 .usage = "",
1017 .chain = lpc2000_exec_command_handlers,
1018 },
1019 COMMAND_REGISTRATION_DONE
1020 };
1021
1022 struct flash_driver lpc2000_flash = {
1023 .name = "lpc2000",
1024 .commands = lpc2000_command_handlers,
1025 .flash_bank_command = lpc2000_flash_bank_command,
1026 .erase = lpc2000_erase,
1027 .protect = lpc2000_protect,
1028 .write = lpc2000_write,
1029 .read = default_flash_read,
1030 .probe = lpc2000_probe,
1031 .auto_probe = lpc2000_probe,
1032 .erase_check = lpc2000_erase_check,
1033 .protect_check = lpc2000_protect_check,
1034 .info = get_lpc2000_info,
1035 };

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)