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

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)