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

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)