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

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)