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

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)