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

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)