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

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)