1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
6 * didele.deze@gmail.com *
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. *
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. *
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 ***************************************************************************/
31 #include "binarybuffer.h"
34 /* flash programming support for NXP LPC17xx and LPC2xxx devices
35 * currently supported devices:
36 * variant 1 (lpc2000_v1):
44 * variant 2 (lpc2000_v2):
53 * - 176x (tested with LPC1768)
56 static int lpc2000_register_commands(struct command_context_s
*cmd_ctx
);
57 static int lpc2000_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
58 static int lpc2000_erase(struct flash_bank_s
*bank
, int first
, int last
);
59 static int lpc2000_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
60 static int lpc2000_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
61 static int lpc2000_probe(struct flash_bank_s
*bank
);
62 static int lpc2000_erase_check(struct flash_bank_s
*bank
);
63 static int lpc2000_protect_check(struct flash_bank_s
*bank
);
64 static int lpc2000_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
66 static int lpc2000_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
68 flash_driver_t lpc2000_flash
=
71 .register_commands
= lpc2000_register_commands
,
72 .flash_bank_command
= lpc2000_flash_bank_command
,
73 .erase
= lpc2000_erase
,
74 .protect
= lpc2000_protect
,
75 .write
= lpc2000_write
,
76 .probe
= lpc2000_probe
,
77 .auto_probe
= lpc2000_probe
,
78 .erase_check
= lpc2000_erase_check
,
79 .protect_check
= lpc2000_protect_check
,
83 static int lpc2000_register_commands(struct command_context_s
*cmd_ctx
)
85 command_t
*lpc2000_cmd
= register_command(cmd_ctx
, NULL
, "lpc2000", NULL
, COMMAND_ANY
, NULL
);
87 register_command(cmd_ctx
, lpc2000_cmd
, "part_id", lpc2000_handle_part_id_command
, COMMAND_EXEC
,
88 "print part id of lpc2000 flash bank <num>");
93 static int lpc2000_build_sector_list(struct flash_bank_s
*bank
)
95 lpc2000_flash_bank_t
*lpc2000_info
= bank
->driver_priv
;
99 /* default to a 4096 write buffer */
100 lpc2000_info
->cmd51_max_buffer
= 4096;
102 if (lpc2000_info
->variant
== lpc2000_v1
)
104 /* variant 1 has different layout for 128kb and 256kb flashes */
105 if (bank
->size
== 128 * 1024)
107 bank
->num_sectors
= 16;
108 bank
->sectors
= malloc(sizeof(flash_sector_t
) * 16);
109 for (i
= 0; i
< 16; i
++)
111 bank
->sectors
[i
].offset
= offset
;
112 bank
->sectors
[i
].size
= 8 * 1024;
113 offset
+= bank
->sectors
[i
].size
;
114 bank
->sectors
[i
].is_erased
= -1;
115 bank
->sectors
[i
].is_protected
= 1;
118 else if (bank
->size
== 256 * 1024)
120 bank
->num_sectors
= 18;
121 bank
->sectors
= malloc(sizeof(flash_sector_t
) * 18);
123 for (i
= 0; i
< 8; i
++)
125 bank
->sectors
[i
].offset
= offset
;
126 bank
->sectors
[i
].size
= 8 * 1024;
127 offset
+= bank
->sectors
[i
].size
;
128 bank
->sectors
[i
].is_erased
= -1;
129 bank
->sectors
[i
].is_protected
= 1;
131 for (i
= 8; i
< 10; i
++)
133 bank
->sectors
[i
].offset
= offset
;
134 bank
->sectors
[i
].size
= 64 * 1024;
135 offset
+= bank
->sectors
[i
].size
;
136 bank
->sectors
[i
].is_erased
= -1;
137 bank
->sectors
[i
].is_protected
= 1;
139 for (i
= 10; i
< 18; i
++)
141 bank
->sectors
[i
].offset
= offset
;
142 bank
->sectors
[i
].size
= 8 * 1024;
143 offset
+= bank
->sectors
[i
].size
;
144 bank
->sectors
[i
].is_erased
= -1;
145 bank
->sectors
[i
].is_protected
= 1;
150 LOG_ERROR("BUG: unknown bank->size encountered");
154 else if (lpc2000_info
->variant
== lpc2000_v2
)
156 /* variant 2 has a uniform layout, only number of sectors differs */
160 lpc2000_info
->cmd51_max_buffer
= 1024;
161 bank
->num_sectors
= 1;
164 lpc2000_info
->cmd51_max_buffer
= 1024;
165 bank
->num_sectors
= 2;
168 bank
->num_sectors
= 4;
171 bank
->num_sectors
= 8;
174 bank
->num_sectors
= 9;
177 bank
->num_sectors
= 11;
180 bank
->num_sectors
= 15;
184 bank
->num_sectors
= 27;
187 LOG_ERROR("BUG: unknown bank->size encountered");
192 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
194 for (i
= 0; i
< bank
->num_sectors
; i
++)
196 if ((i
>= 0) && (i
< 8))
198 bank
->sectors
[i
].offset
= offset
;
199 bank
->sectors
[i
].size
= 4 * 1024;
200 offset
+= bank
->sectors
[i
].size
;
201 bank
->sectors
[i
].is_erased
= -1;
202 bank
->sectors
[i
].is_protected
= 1;
204 if ((i
>= 8) && (i
< 22))
206 bank
->sectors
[i
].offset
= offset
;
207 bank
->sectors
[i
].size
= 32 * 1024;
208 offset
+= bank
->sectors
[i
].size
;
209 bank
->sectors
[i
].is_erased
= -1;
210 bank
->sectors
[i
].is_protected
= 1;
212 if ((i
>= 22) && (i
< 27))
214 bank
->sectors
[i
].offset
= offset
;
215 bank
->sectors
[i
].size
= 4 * 1024;
216 offset
+= bank
->sectors
[i
].size
;
217 bank
->sectors
[i
].is_erased
= -1;
218 bank
->sectors
[i
].is_protected
= 1;
222 else if (lpc2000_info
->variant
== lpc1700
)
227 bank
->num_sectors
= 8;
230 bank
->num_sectors
= 16;
233 bank
->num_sectors
= 18;
236 bank
->num_sectors
= 22;
239 bank
->num_sectors
= 30;
242 LOG_ERROR("BUG: unknown bank->size encountered");
246 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
248 for(i
= 0; i
< bank
->num_sectors
; i
++)
250 bank
->sectors
[i
].offset
= offset
;
251 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
252 bank
->sectors
[i
].size
= (i
< 16)? 4 * 1024 : 32 * 1024;
253 offset
+= bank
->sectors
[i
].size
;
254 bank
->sectors
[i
].is_erased
= -1;
255 bank
->sectors
[i
].is_protected
= 1;
260 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
267 /* call LPC1700/LPC2000 IAP function
268 * uses 180 bytes working area
269 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
270 * 0x8 to 0x1f: command parameter table (1+5 words)
271 * 0x20 to 0x33: command result table (1+4 words)
272 * 0x34 to 0xb3: stack (only 128b needed)
274 static int lpc2000_iap_call(flash_bank_t
*bank
, int code
, uint32_t param_table
[5], uint32_t result_table
[4])
277 lpc2000_flash_bank_t
*lpc2000_info
= bank
->driver_priv
;
278 target_t
*target
= bank
->target
;
279 mem_param_t mem_params
[2];
280 reg_param_t reg_params
[5];
281 armv4_5_algorithm_t armv4_5_info
; /* for LPC2000 */
282 armv7m_algorithm_t armv7m_info
; /* for LPC1700 */
283 uint32_t status_code
;
284 uint32_t iap_entry_point
= 0; /* to make compiler happier */
286 /* regrab previously allocated working_area, or allocate a new one */
287 if (!lpc2000_info
->iap_working_area
)
289 uint8_t jump_gate
[8];
291 /* make sure we have a working area */
292 if (target_alloc_working_area(target
, 180, &lpc2000_info
->iap_working_area
) != ERROR_OK
)
294 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
295 return ERROR_FLASH_OPERATION_FAILED
;
298 /* write IAP code to working area */
299 switch(lpc2000_info
->variant
)
302 target_buffer_set_u32(target
, jump_gate
, ARMV7M_T_BX(12));
303 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV7M_T_B(0xfffffe));
307 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_BX(12));
308 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV4_5_B(0xfffffe, 0));
311 LOG_ERROR("BUG: unknown bank->size encountered");
315 if ((retval
= target_write_memory(target
, lpc2000_info
->iap_working_area
->address
, 4, 2, jump_gate
)) != ERROR_OK
)
317 LOG_ERROR("Write memory at address 0x%8.8" PRIx32
" failed (check work_area definition)", lpc2000_info
->iap_working_area
->address
);
322 switch(lpc2000_info
->variant
)
325 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
326 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
327 iap_entry_point
= 0x1fff1ff1;
331 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
332 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
333 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
334 iap_entry_point
= 0x7ffffff1;
337 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
341 /* command parameter table */
342 init_mem_param(&mem_params
[0], lpc2000_info
->iap_working_area
->address
+ 8, 6 * 4, PARAM_OUT
);
343 target_buffer_set_u32(target
, mem_params
[0].value
, code
);
344 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x04, param_table
[0]);
345 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x08, param_table
[1]);
346 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x0c, param_table
[2]);
347 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x10, param_table
[3]);
348 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x14, param_table
[4]);
350 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
351 buf_set_u32(reg_params
[0].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x08);
353 /* command result table */
354 init_mem_param(&mem_params
[1], lpc2000_info
->iap_working_area
->address
+ 0x20, 5 * 4, PARAM_IN
);
356 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
357 buf_set_u32(reg_params
[1].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x20);
359 /* IAP entry point */
360 init_reg_param(®_params
[2], "r12", 32, PARAM_OUT
);
361 buf_set_u32(reg_params
[2].value
, 0, 32, iap_entry_point
);
363 switch(lpc2000_info
->variant
)
367 init_reg_param(®_params
[3], "sp", 32, PARAM_OUT
);
368 buf_set_u32(reg_params
[3].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0xb4);
371 init_reg_param(®_params
[4], "lr", 32, PARAM_OUT
);
372 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 */
374 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
);
379 init_reg_param(®_params
[3], "r13_svc", 32, PARAM_OUT
);
380 buf_set_u32(reg_params
[3].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0xb4);
383 init_reg_param(®_params
[4], "lr_svc", 32, PARAM_OUT
);
384 buf_set_u32(reg_params
[4].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x04);
386 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
);
389 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
394 status_code
= target_buffer_get_u32(target
, mem_params
[1].value
);
395 result_table
[0] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x04);
396 result_table
[1] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x08);
397 result_table
[2] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x0c);
398 result_table
[3] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x10);
400 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
,
401 code
, param_table
[0], param_table
[1], param_table
[2], param_table
[3], param_table
[4], status_code
);
403 destroy_mem_param(&mem_params
[0]);
404 destroy_mem_param(&mem_params
[1]);
406 destroy_reg_param(®_params
[0]);
407 destroy_reg_param(®_params
[1]);
408 destroy_reg_param(®_params
[2]);
409 destroy_reg_param(®_params
[3]);
410 destroy_reg_param(®_params
[4]);
415 static int lpc2000_iap_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
417 uint32_t param_table
[5];
418 uint32_t result_table
[4];
422 if ((first
< 0) || (last
>= bank
->num_sectors
))
423 return ERROR_FLASH_SECTOR_INVALID
;
425 for (i
= first
; i
<= last
; i
++)
427 /* check single sector */
428 param_table
[0] = param_table
[1] = i
;
429 status_code
= lpc2000_iap_call(bank
, 53, param_table
, result_table
);
433 case ERROR_FLASH_OPERATION_FAILED
:
434 return ERROR_FLASH_OPERATION_FAILED
;
435 case LPC2000_CMD_SUCCESS
:
436 bank
->sectors
[i
].is_erased
= 1;
438 case LPC2000_SECTOR_NOT_BLANK
:
439 bank
->sectors
[i
].is_erased
= 0;
441 case LPC2000_INVALID_SECTOR
:
442 bank
->sectors
[i
].is_erased
= 0;
445 return ERROR_FLASH_BUSY
;
448 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code
);
457 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
459 static int lpc2000_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
461 lpc2000_flash_bank_t
*lpc2000_info
;
465 LOG_WARNING("incomplete flash_bank lpc2000 configuration");
466 return ERROR_FLASH_BANK_INVALID
;
469 lpc2000_info
= malloc(sizeof(lpc2000_flash_bank_t
));
470 bank
->driver_priv
= lpc2000_info
;
472 if (strcmp(args
[6], "lpc2000_v1") == 0)
474 lpc2000_info
->variant
= lpc2000_v1
;
475 lpc2000_info
->cmd51_dst_boundary
= 512;
476 lpc2000_info
->cmd51_can_256b
= 0;
477 lpc2000_info
->cmd51_can_8192b
= 1;
478 lpc2000_info
->checksum_vector
= 5;
480 else if (strcmp(args
[6], "lpc2000_v2") == 0)
482 lpc2000_info
->variant
= lpc2000_v2
;
483 lpc2000_info
->cmd51_dst_boundary
= 256;
484 lpc2000_info
->cmd51_can_256b
= 1;
485 lpc2000_info
->cmd51_can_8192b
= 0;
486 lpc2000_info
->checksum_vector
= 5;
488 else if (strcmp(args
[6], "lpc1700") == 0)
490 lpc2000_info
->variant
= lpc1700
;
491 lpc2000_info
->cmd51_dst_boundary
= 256;
492 lpc2000_info
->cmd51_can_256b
= 1;
493 lpc2000_info
->cmd51_can_8192b
= 0;
494 lpc2000_info
->checksum_vector
= 7;
498 LOG_ERROR("unknown LPC2000 variant: %s", args
[6]);
500 return ERROR_FLASH_BANK_INVALID
;
503 lpc2000_info
->iap_working_area
= NULL
;
504 lpc2000_info
->cclk
= strtoul(args
[7], NULL
, 0);
505 lpc2000_info
->calc_checksum
= 0;
506 lpc2000_build_sector_list(bank
);
510 if (strcmp(args
[8], "calc_checksum") == 0)
511 lpc2000_info
->calc_checksum
= 1;
517 static int lpc2000_erase(struct flash_bank_s
*bank
, int first
, int last
)
519 lpc2000_flash_bank_t
*lpc2000_info
= bank
->driver_priv
;
520 uint32_t param_table
[5];
521 uint32_t result_table
[4];
524 if (bank
->target
->state
!= TARGET_HALTED
)
526 LOG_ERROR("Target not halted");
527 return ERROR_TARGET_NOT_HALTED
;
530 param_table
[0] = first
;
531 param_table
[1] = last
;
532 param_table
[2] = lpc2000_info
->cclk
;
534 /* Prepare sectors */
535 status_code
= lpc2000_iap_call(bank
, 50, param_table
, result_table
);
538 case ERROR_FLASH_OPERATION_FAILED
:
539 return ERROR_FLASH_OPERATION_FAILED
;
540 case LPC2000_CMD_SUCCESS
:
542 case LPC2000_INVALID_SECTOR
:
543 return ERROR_FLASH_SECTOR_INVALID
;
546 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
547 return ERROR_FLASH_OPERATION_FAILED
;
551 status_code
= lpc2000_iap_call(bank
, 52, param_table
, result_table
);
554 case ERROR_FLASH_OPERATION_FAILED
:
555 return ERROR_FLASH_OPERATION_FAILED
;
556 case LPC2000_CMD_SUCCESS
:
558 case LPC2000_INVALID_SECTOR
:
559 return ERROR_FLASH_SECTOR_INVALID
;
562 LOG_WARNING("lpc2000 erase sectors returned %i", status_code
);
563 return ERROR_FLASH_OPERATION_FAILED
;
569 static int lpc2000_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
571 /* can't protect/unprotect on the lpc2000 */
575 static int lpc2000_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
577 lpc2000_flash_bank_t
*lpc2000_info
= bank
->driver_priv
;
578 target_t
*target
= bank
->target
;
579 uint32_t dst_min_alignment
;
580 uint32_t bytes_remaining
= count
;
581 uint32_t bytes_written
= 0;
582 int first_sector
= 0;
584 uint32_t param_table
[5];
585 uint32_t result_table
[4];
588 working_area_t
*download_area
;
589 int retval
= ERROR_OK
;
591 if (bank
->target
->state
!= TARGET_HALTED
)
593 LOG_ERROR("Target not halted");
594 return ERROR_TARGET_NOT_HALTED
;
597 if (offset
+ count
> bank
->size
)
598 return ERROR_FLASH_DST_OUT_OF_BANK
;
600 dst_min_alignment
= lpc2000_info
->cmd51_dst_boundary
;
602 if (offset
% dst_min_alignment
)
604 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
, offset
, dst_min_alignment
);
605 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
608 for (i
= 0; i
< bank
->num_sectors
; i
++)
610 if (offset
>= bank
->sectors
[i
].offset
)
612 if (offset
+ CEIL(count
, dst_min_alignment
) * dst_min_alignment
> bank
->sectors
[i
].offset
)
616 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
618 /* check if exception vectors should be flashed */
619 if ((offset
== 0) && (count
>= 0x20) && lpc2000_info
->calc_checksum
)
621 uint32_t checksum
= 0;
623 for (i
= 0; i
< 8; i
++)
625 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32
, i
* 4, buf_get_u32(buffer
+ (i
* 4), 0, 32));
626 if (i
!= lpc2000_info
->checksum_vector
)
627 checksum
+= buf_get_u32(buffer
+ (i
* 4), 0, 32);
629 checksum
= 0 - checksum
;
630 LOG_DEBUG("checksum: 0x%8.8" PRIx32
, checksum
);
632 uint32_t original_value
= buf_get_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32);
633 if (original_value
!= checksum
)
635 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
").",
636 original_value
, checksum
);
637 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.");
640 buf_set_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32, checksum
);
643 /* allocate a working area */
644 if (target_alloc_working_area(target
, lpc2000_info
->cmd51_max_buffer
, &download_area
) != ERROR_OK
)
646 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
647 return ERROR_FLASH_OPERATION_FAILED
;
650 while (bytes_remaining
> 0)
652 uint32_t thisrun_bytes
;
653 if (bytes_remaining
>= lpc2000_info
->cmd51_max_buffer
)
654 thisrun_bytes
= lpc2000_info
->cmd51_max_buffer
;
655 else if (bytes_remaining
>= 1024)
656 thisrun_bytes
= 1024;
657 else if ((bytes_remaining
>= 512) || (!lpc2000_info
->cmd51_can_256b
))
662 /* Prepare sectors */
663 param_table
[0] = first_sector
;
664 param_table
[1] = last_sector
;
665 status_code
= lpc2000_iap_call(bank
, 50, param_table
, result_table
);
668 case ERROR_FLASH_OPERATION_FAILED
:
669 retval
= ERROR_FLASH_OPERATION_FAILED
;
671 case LPC2000_CMD_SUCCESS
:
673 case LPC2000_INVALID_SECTOR
:
674 retval
= ERROR_FLASH_SECTOR_INVALID
;
677 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
678 retval
= ERROR_FLASH_OPERATION_FAILED
;
682 /* Exit if error occured */
683 if (retval
!= ERROR_OK
)
686 if (bytes_remaining
>= thisrun_bytes
)
688 if ((retval
= target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, buffer
+ bytes_written
)) != ERROR_OK
)
690 retval
= ERROR_FLASH_OPERATION_FAILED
;
696 uint8_t *last_buffer
= malloc(thisrun_bytes
);
697 memcpy(last_buffer
, buffer
+ bytes_written
, bytes_remaining
);
698 memset(last_buffer
+ bytes_remaining
, 0xff, thisrun_bytes
- bytes_remaining
);
699 target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, last_buffer
);
703 LOG_DEBUG("writing 0x%" PRIx32
" bytes to address 0x%" PRIx32
, thisrun_bytes
, bank
->base
+ offset
+ bytes_written
);
706 param_table
[0] = bank
->base
+ offset
+ bytes_written
;
707 param_table
[1] = download_area
->address
;
708 param_table
[2] = thisrun_bytes
;
709 param_table
[3] = lpc2000_info
->cclk
;
710 status_code
= lpc2000_iap_call(bank
, 51, param_table
, result_table
);
713 case ERROR_FLASH_OPERATION_FAILED
:
714 retval
= ERROR_FLASH_OPERATION_FAILED
;
716 case LPC2000_CMD_SUCCESS
:
718 case LPC2000_INVALID_SECTOR
:
719 retval
= ERROR_FLASH_SECTOR_INVALID
;
722 LOG_WARNING("lpc2000 returned %i", status_code
);
723 retval
= ERROR_FLASH_OPERATION_FAILED
;
727 /* Exit if error occured */
728 if (retval
!= ERROR_OK
)
731 if (bytes_remaining
> thisrun_bytes
)
732 bytes_remaining
-= thisrun_bytes
;
735 bytes_written
+= thisrun_bytes
;
738 target_free_working_area(target
, download_area
);
743 static int lpc2000_probe(struct flash_bank_s
*bank
)
745 /* we can't probe on an lpc2000
746 * if this is an lpc2xxx, it has the configured flash
751 static int lpc2000_erase_check(struct flash_bank_s
*bank
)
753 if (bank
->target
->state
!= TARGET_HALTED
)
755 LOG_ERROR("Target not halted");
756 return ERROR_TARGET_NOT_HALTED
;
759 return lpc2000_iap_blank_check(bank
, 0, bank
->num_sectors
- 1);
762 static int lpc2000_protect_check(struct flash_bank_s
*bank
)
764 /* sectors are always protected */
768 static int lpc2000_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
770 lpc2000_flash_bank_t
*lpc2000_info
= bank
->driver_priv
;
772 snprintf(buf
, buf_size
, "lpc2000 flash driver variant: %i, clk: %" PRIi32
"kHz" , lpc2000_info
->variant
, lpc2000_info
->cclk
);
777 static int lpc2000_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
780 uint32_t param_table
[5];
781 uint32_t result_table
[4];
786 return ERROR_COMMAND_SYNTAX_ERROR
;
789 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
792 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
796 if (bank
->target
->state
!= TARGET_HALTED
)
798 LOG_ERROR("Target not halted");
799 return ERROR_TARGET_NOT_HALTED
;
802 if ((status_code
= lpc2000_iap_call(bank
, 54, param_table
, result_table
)) != 0x0)
804 if (status_code
== ERROR_FLASH_OPERATION_FAILED
)
806 command_print(cmd_ctx
, "no sufficient working area specified, can't access LPC2000 IAP interface");
809 command_print(cmd_ctx
, "lpc2000 IAP returned status code %i", status_code
);
813 command_print(cmd_ctx
, "lpc2000 part id: 0x%8.8" PRIx32
, result_table
[0]);
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)