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

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)