69c8b0341e02ced7a1d8a7ffc138fb8930979cfe
[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
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 = 256;
234 bank->num_sectors = 1;
235 break;
236 case 8 * 1024:
237 lpc2000_info->cmd51_max_buffer = 512;
238 bank->num_sectors = 2;
239 break;
240 case 16 * 1024:
241 lpc2000_info->cmd51_max_buffer = 512;
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 lpc2000_info->cmd51_max_buffer = 256;
307 bank->num_sectors = 4;
308 break;
309 case 8 * 1024:
310 lpc2000_info->cmd51_max_buffer = 512;
311 bank->num_sectors = 8;
312 break;
313 case 16 * 1024:
314 bank->num_sectors = 16;
315 break;
316 default:
317 LOG_ERROR("BUG: unknown bank->size encountered");
318 exit(-1);
319 }
320
321 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
322
323 for (int i = 0; i < bank->num_sectors; i++) {
324 bank->sectors[i].offset = offset;
325 /* sectors 0-15 are 1kB-sized for LPC8xx devices */
326 bank->sectors[i].size = 1 * 1024;
327 offset += bank->sectors[i].size;
328 bank->sectors[i].is_erased = -1;
329 bank->sectors[i].is_protected = 1;
330 }
331
332 } else {
333 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
334 exit(-1);
335 }
336
337 return ERROR_OK;
338 }
339
340 /* this function allocates and initializes working area used for IAP algorithm
341 * uses 52 + max IAP stack bytes working area
342 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
343 * 0x8 to 0x1f: command parameter table (1+5 words)
344 * 0x20 to 0x33: command result table (1+4 words)
345 * 0x34 to 0xb3|0x104: stack (only 128b needed for lpc17xx/2000, 208 for lpc43xx and 148b for lpc8xx)
346 */
347
348 static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
349 {
350 struct target *target = bank->target;
351 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
352
353 if (target_alloc_working_area(target, 0x34 + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {
354 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
355 return ERROR_FLASH_OPERATION_FAILED;
356 }
357
358 uint8_t jump_gate[8];
359
360 /* write IAP code to working area */
361 switch (lpc2000_info->variant) {
362 case lpc800:
363 case lpc1700:
364 case lpc4300:
365 target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
366 target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
367 break;
368 case lpc2000_v1:
369 case lpc2000_v2:
370 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
371 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
372 break;
373 default:
374 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
375 exit(-1);
376 }
377
378 int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
379 if (retval != ERROR_OK)
380 LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
381 (*iap_working_area)->address);
382
383 return retval;
384 }
385
386 /* call LPC1700/LPC2000 IAP function */
387
388 static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
389 uint32_t param_table[5], uint32_t result_table[4])
390 {
391 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
392 struct target *target = bank->target;
393
394 struct arm_algorithm arm_algo; /* for LPC2000 */
395 struct armv7m_algorithm armv7m_info; /* for LPC1700 */
396 uint32_t iap_entry_point = 0; /* to make compiler happier */
397
398 switch (lpc2000_info->variant) {
399 case lpc800:
400 case lpc1700:
401 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
402 armv7m_info.core_mode = ARM_MODE_THREAD;
403 iap_entry_point = 0x1fff1ff1;
404 break;
405 case lpc2000_v1:
406 case lpc2000_v2:
407 arm_algo.common_magic = ARM_COMMON_MAGIC;
408 arm_algo.core_mode = ARM_MODE_SVC;
409 arm_algo.core_state = ARM_STATE_ARM;
410 iap_entry_point = 0x7ffffff1;
411 break;
412 case lpc4300:
413 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
414 armv7m_info.core_mode = ARM_MODE_THREAD;
415 /* read out IAP entry point from ROM driver table at 0x10400100 */
416 target_read_u32(target, 0x10400100, &iap_entry_point);
417 break;
418 default:
419 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
420 exit(-1);
421 }
422
423 struct mem_param mem_params[2];
424
425 /* command parameter table */
426 init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
427 target_buffer_set_u32(target, mem_params[0].value, code);
428 target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
429 target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
430 target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
431 target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
432 target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
433
434 struct reg_param reg_params[5];
435
436 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
437 buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
438
439 /* command result table */
440 init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
441
442 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
443 buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
444
445 /* IAP entry point */
446 init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
447 buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
448
449 switch (lpc2000_info->variant) {
450 case lpc800:
451 case lpc1700:
452 case lpc4300:
453 /* IAP stack */
454 init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
455 buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
456
457 /* return address */
458 init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
459 buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
460 /* bit0 of LR = 1 to return in Thumb mode */
461
462 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
463 &armv7m_info);
464 break;
465 case lpc2000_v1:
466 case lpc2000_v2:
467 /* IAP stack */
468 init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
469 buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
470
471 /* return address */
472 init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
473 buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
474
475 target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
476 iap_working_area->address + 0x4, 10000, &arm_algo);
477 break;
478 default:
479 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
480 exit(-1);
481 }
482
483 int status_code = target_buffer_get_u32(target, mem_params[1].value);
484 result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
485 result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
486 result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
487 result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
488
489 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
490 ") completed with result = %8.8x",
491 code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
492
493 destroy_mem_param(&mem_params[0]);
494 destroy_mem_param(&mem_params[1]);
495
496 destroy_reg_param(&reg_params[0]);
497 destroy_reg_param(&reg_params[1]);
498 destroy_reg_param(&reg_params[2]);
499 destroy_reg_param(&reg_params[3]);
500 destroy_reg_param(&reg_params[4]);
501
502 return status_code;
503 }
504
505 static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
506 {
507 if ((first < 0) || (last >= bank->num_sectors))
508 return ERROR_FLASH_SECTOR_INVALID;
509
510 uint32_t param_table[5] = {0};
511 uint32_t result_table[4];
512 struct working_area *iap_working_area;
513
514 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
515
516 if (retval != ERROR_OK)
517 return retval;
518
519 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
520 if (lpc2000_info->variant == lpc4300)
521 param_table[2] = lpc2000_info->lpc4300_bank;
522
523 for (int i = first; i <= last && retval == ERROR_OK; i++) {
524 /* check single sector */
525 param_table[0] = param_table[1] = i;
526 int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
527
528 switch (status_code) {
529 case ERROR_FLASH_OPERATION_FAILED:
530 retval = ERROR_FLASH_OPERATION_FAILED;
531 break;
532 case LPC2000_CMD_SUCCESS:
533 bank->sectors[i].is_erased = 1;
534 break;
535 case LPC2000_SECTOR_NOT_BLANK:
536 bank->sectors[i].is_erased = 0;
537 break;
538 case LPC2000_INVALID_SECTOR:
539 bank->sectors[i].is_erased = 0;
540 break;
541 case LPC2000_BUSY:
542 retval = ERROR_FLASH_BUSY;
543 break;
544 default:
545 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
546 exit(-1);
547 }
548 }
549
550 struct target *target = bank->target;
551 target_free_working_area(target, iap_working_area);
552
553 return retval;
554 }
555
556 /*
557 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
558 */
559 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
560 {
561 if (CMD_ARGC < 8)
562 return ERROR_COMMAND_SYNTAX_ERROR;
563
564 struct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info));
565
566 bank->driver_priv = lpc2000_info;
567
568 if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
569 lpc2000_info->variant = lpc2000_v1;
570 lpc2000_info->cmd51_dst_boundary = 512;
571 lpc2000_info->cmd51_can_256b = 0;
572 lpc2000_info->cmd51_can_8192b = 1;
573 lpc2000_info->checksum_vector = 5;
574 lpc2000_info->iap_max_stack = 128;
575 } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
576 lpc2000_info->variant = lpc2000_v2;
577 lpc2000_info->cmd51_dst_boundary = 256;
578 lpc2000_info->cmd51_can_256b = 1;
579 lpc2000_info->cmd51_can_8192b = 0;
580 lpc2000_info->checksum_vector = 5;
581 lpc2000_info->iap_max_stack = 128;
582 } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0) {
583 lpc2000_info->variant = lpc1700;
584 lpc2000_info->cmd51_dst_boundary = 256;
585 lpc2000_info->cmd51_can_256b = 1;
586 lpc2000_info->cmd51_can_8192b = 0;
587 lpc2000_info->checksum_vector = 7;
588 lpc2000_info->iap_max_stack = 128;
589 } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) {
590 lpc2000_info->variant = lpc4300;
591 lpc2000_info->cmd51_dst_boundary = 512;
592 lpc2000_info->cmd51_can_256b = 0;
593 lpc2000_info->cmd51_can_8192b = 0;
594 lpc2000_info->checksum_vector = 7;
595 lpc2000_info->iap_max_stack = 208;
596 } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) {
597 lpc2000_info->variant = lpc800;
598 lpc2000_info->cmd51_dst_boundary = 64;
599 lpc2000_info->cmd51_can_64b = 1;
600 lpc2000_info->cmd51_can_256b = 0;
601 lpc2000_info->cmd51_can_8192b = 0;
602 lpc2000_info->checksum_vector = 7;
603 lpc2000_info->iap_max_stack = 148;
604 } else {
605 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
606 free(lpc2000_info);
607 return ERROR_FLASH_BANK_INVALID;
608 }
609
610 /* see lpc2000_iap_working_area_init() for the reason behind the 0x34 value */
611 lpc2000_info->cmd51_src_offset = 0x34 + lpc2000_info->iap_max_stack;
612
613 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
614 lpc2000_info->calc_checksum = 0;
615 lpc2000_build_sector_list(bank);
616
617 uint32_t temp_base = 0;
618 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
619 if (temp_base >= 0x1B000000)
620 lpc2000_info->lpc4300_bank = 1; /* bank B */
621 else
622 lpc2000_info->lpc4300_bank = 0; /* bank A */
623
624 if (CMD_ARGC >= 9) {
625 if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
626 lpc2000_info->calc_checksum = 1;
627 }
628
629 return ERROR_OK;
630 }
631
632 static int lpc2000_erase(struct flash_bank *bank, int first, int last)
633 {
634 if (bank->target->state != TARGET_HALTED) {
635 LOG_ERROR("Target not halted");
636 return ERROR_TARGET_NOT_HALTED;
637 }
638
639 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
640 uint32_t param_table[5] = {0};
641
642 param_table[0] = first;
643 param_table[1] = last;
644
645 if (lpc2000_info->variant == lpc4300)
646 param_table[2] = lpc2000_info->lpc4300_bank;
647 else
648 param_table[2] = lpc2000_info->cclk;
649
650 uint32_t result_table[4];
651 struct working_area *iap_working_area;
652
653 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
654
655 if (retval != ERROR_OK)
656 return retval;
657
658 if (lpc2000_info->variant == lpc4300)
659 /* Init IAP Anyway */
660 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
661
662 /* Prepare sectors */
663 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
664 switch (status_code) {
665 case ERROR_FLASH_OPERATION_FAILED:
666 retval = ERROR_FLASH_OPERATION_FAILED;
667 break;
668 case LPC2000_CMD_SUCCESS:
669 break;
670 case LPC2000_INVALID_SECTOR:
671 retval = ERROR_FLASH_SECTOR_INVALID;
672 break;
673 default:
674 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
675 retval = ERROR_FLASH_OPERATION_FAILED;
676 break;
677 }
678
679 if (retval == ERROR_OK) {
680 /* Erase sectors */
681 param_table[2] = lpc2000_info->cclk;
682 if (lpc2000_info->variant == lpc4300)
683 param_table[3] = lpc2000_info->lpc4300_bank;
684
685 status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
686 switch (status_code) {
687 case ERROR_FLASH_OPERATION_FAILED:
688 retval = ERROR_FLASH_OPERATION_FAILED;
689 break;
690 case LPC2000_CMD_SUCCESS:
691 break;
692 case LPC2000_INVALID_SECTOR:
693 retval = ERROR_FLASH_SECTOR_INVALID;
694 break;
695 default:
696 LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
697 retval = ERROR_FLASH_OPERATION_FAILED;
698 break;
699 }
700 }
701
702 struct target *target = bank->target;
703 target_free_working_area(target, iap_working_area);
704
705 return retval;
706 }
707
708 static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
709 {
710 /* can't protect/unprotect on the lpc2000 */
711 return ERROR_OK;
712 }
713
714 static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
715 {
716 struct target *target = bank->target;
717
718 if (bank->target->state != TARGET_HALTED) {
719 LOG_ERROR("Target not halted");
720 return ERROR_TARGET_NOT_HALTED;
721 }
722
723 if (offset + count > bank->size)
724 return ERROR_FLASH_DST_OUT_OF_BANK;
725
726 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
727
728 uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
729
730 if (offset % dst_min_alignment) {
731 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
732 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
733 }
734
735 int first_sector = 0;
736 int last_sector = 0;
737
738 for (int i = 0; i < bank->num_sectors; i++) {
739 if (offset >= bank->sectors[i].offset)
740 first_sector = i;
741 if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
742 last_sector = i;
743 }
744
745 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
746
747 /* check if exception vectors should be flashed */
748 if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
749 assert(lpc2000_info->checksum_vector < 8);
750 uint32_t checksum = 0;
751 for (int i = 0; i < 8; i++) {
752 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
753 if (i != lpc2000_info->checksum_vector)
754 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
755 }
756 checksum = 0 - checksum;
757 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
758
759 uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
760 if (original_value != checksum) {
761 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
762 "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
763 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
764 "checksum.");
765 }
766
767 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
768 buf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
769 }
770
771 struct working_area *iap_working_area;
772
773 int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
774
775 if (retval != ERROR_OK)
776 return retval;
777
778 struct working_area *download_area;
779
780 /* allocate a working area */
781 if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
782 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
783 target_free_working_area(target, iap_working_area);
784 return ERROR_FLASH_OPERATION_FAILED;
785 }
786
787 uint32_t bytes_remaining = count;
788 uint32_t bytes_written = 0;
789 uint32_t param_table[5] = {0};
790 uint32_t result_table[4];
791
792 if (lpc2000_info->variant == lpc4300)
793 /* Init IAP Anyway */
794 lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);
795
796 while (bytes_remaining > 0) {
797 uint32_t thisrun_bytes;
798 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
799 thisrun_bytes = lpc2000_info->cmd51_max_buffer;
800 else if (bytes_remaining >= 1024)
801 thisrun_bytes = 1024;
802 else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
803 thisrun_bytes = 512;
804 else if ((bytes_remaining >= 256) || (!lpc2000_info->cmd51_can_64b))
805 thisrun_bytes = 256;
806 else
807 thisrun_bytes = 64;
808
809 /* Prepare sectors */
810 param_table[0] = first_sector;
811 param_table[1] = last_sector;
812
813 if (lpc2000_info->variant == lpc4300)
814 param_table[2] = lpc2000_info->lpc4300_bank;
815 else
816 param_table[2] = lpc2000_info->cclk;
817
818 int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
819 switch (status_code) {
820 case ERROR_FLASH_OPERATION_FAILED:
821 retval = ERROR_FLASH_OPERATION_FAILED;
822 break;
823 case LPC2000_CMD_SUCCESS:
824 break;
825 case LPC2000_INVALID_SECTOR:
826 retval = ERROR_FLASH_SECTOR_INVALID;
827 break;
828 default:
829 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
830 retval = ERROR_FLASH_OPERATION_FAILED;
831 break;
832 }
833
834 /* Exit if error occured */
835 if (retval != ERROR_OK)
836 break;
837
838 if (bytes_remaining >= thisrun_bytes) {
839 retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
840 if (retval != ERROR_OK) {
841 retval = ERROR_FLASH_OPERATION_FAILED;
842 break;
843 }
844 } else {
845 uint8_t *last_buffer = malloc(thisrun_bytes);
846 memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
847 memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
848 target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
849 free(last_buffer);
850 }
851
852 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
853 bank->base + offset + bytes_written);
854
855 /* Write data */
856 param_table[0] = bank->base + offset + bytes_written;
857 param_table[1] = download_area->address;
858 param_table[2] = thisrun_bytes;
859 param_table[3] = lpc2000_info->cclk;
860 status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
861 switch (status_code) {
862 case ERROR_FLASH_OPERATION_FAILED:
863 retval = ERROR_FLASH_OPERATION_FAILED;
864 break;
865 case LPC2000_CMD_SUCCESS:
866 break;
867 case LPC2000_INVALID_SECTOR:
868 retval = ERROR_FLASH_SECTOR_INVALID;
869 break;
870 default:
871 LOG_WARNING("lpc2000 returned %i", status_code);
872 retval = ERROR_FLASH_OPERATION_FAILED;
873 break;
874 }
875
876 /* Exit if error occured */
877 if (retval != ERROR_OK)
878 break;
879
880 if (bytes_remaining > thisrun_bytes)
881 bytes_remaining -= thisrun_bytes;
882 else
883 bytes_remaining = 0;
884 bytes_written += thisrun_bytes;
885 }
886
887 target_free_working_area(target, iap_working_area);
888 target_free_working_area(target, download_area);
889
890 return retval;
891 }
892
893 static int lpc2000_probe(struct flash_bank *bank)
894 {
895 /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
896 return ERROR_OK;
897 }
898
899 static int lpc2000_erase_check(struct flash_bank *bank)
900 {
901 if (bank->target->state != TARGET_HALTED) {
902 LOG_ERROR("Target not halted");
903 return ERROR_TARGET_NOT_HALTED;
904 }
905
906 return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
907 }
908
909 static int lpc2000_protect_check(struct flash_bank *bank)
910 {
911 /* sectors are always protected */
912 return ERROR_OK;
913 }
914
915 static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
916 {
917 struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
918
919 snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
920 lpc2000_info->cclk);
921
922 return ERROR_OK;
923 }
924
925 COMMAND_HANDLER(lpc2000_handle_part_id_command)
926 {
927 if (CMD_ARGC < 1)
928 return ERROR_COMMAND_SYNTAX_ERROR;
929
930 struct flash_bank *bank;
931 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
932 if (ERROR_OK != retval)
933 return retval;
934
935 if (bank->target->state != TARGET_HALTED) {
936 LOG_ERROR("Target not halted");
937 return ERROR_TARGET_NOT_HALTED;
938 }
939
940 uint32_t param_table[5] = {0};
941 uint32_t result_table[4];
942 struct working_area *iap_working_area;
943
944 retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
945
946 if (retval != ERROR_OK)
947 return retval;
948
949 int status_code = lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
950 if (status_code != 0x0) {
951 if (status_code == ERROR_FLASH_OPERATION_FAILED) {
952 command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
953 } else
954 command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
955 } else
956 command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, result_table[0]);
957
958 return retval;
959 }
960
961 static const struct command_registration lpc2000_exec_command_handlers[] = {
962 {
963 .name = "part_id",
964 .handler = lpc2000_handle_part_id_command,
965 .mode = COMMAND_EXEC,
966 .help = "print part id of lpc2000 flash bank <num>",
967 .usage = "<bank>",
968 },
969 COMMAND_REGISTRATION_DONE
970 };
971 static const struct command_registration lpc2000_command_handlers[] = {
972 {
973 .name = "lpc2000",
974 .mode = COMMAND_ANY,
975 .help = "lpc2000 flash command group",
976 .usage = "",
977 .chain = lpc2000_exec_command_handlers,
978 },
979 COMMAND_REGISTRATION_DONE
980 };
981
982 struct flash_driver lpc2000_flash = {
983 .name = "lpc2000",
984 .commands = lpc2000_command_handlers,
985 .flash_bank_command = lpc2000_flash_bank_command,
986 .erase = lpc2000_erase,
987 .protect = lpc2000_protect,
988 .write = lpc2000_write,
989 .read = default_flash_read,
990 .probe = lpc2000_probe,
991 .auto_probe = lpc2000_probe,
992 .erase_check = lpc2000_erase_check,
993 .protect_check = lpc2000_protect_check,
994 .info = get_lpc2000_info,
995 };

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)