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

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)