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 ***************************************************************************/
29 #include <helper/binarybuffer.h>
30 #include <target/algorithm.h>
31 #include <target/arm_opcodes.h>
32 #include <target/armv7m.h>
36 * flash programming support for NXP LPC17xx and LPC2xxx devices.
38 * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
39 * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
42 * currently supported devices:
43 * variant 1 (lpc2000_v1):
51 * variant 2 (lpc2000_v2):
60 * - 176x (tested with LPC1768)
69 struct lpc2000_flash_bank
{
70 lpc2000_variant variant
;
71 struct working_area
*iap_working_area
;
73 int cmd51_dst_boundary
;
77 uint32_t cmd51_max_buffer
;
81 enum lpc2000_status_codes
{
82 LPC2000_CMD_SUCCESS
= 0,
83 LPC2000_INVALID_COMMAND
= 1,
84 LPC2000_SRC_ADDR_ERROR
= 2,
85 LPC2000_DST_ADDR_ERROR
= 3,
86 LPC2000_SRC_ADDR_NOT_MAPPED
= 4,
87 LPC2000_DST_ADDR_NOT_MAPPED
= 5,
88 LPC2000_COUNT_ERROR
= 6,
89 LPC2000_INVALID_SECTOR
= 7,
90 LPC2000_SECTOR_NOT_BLANK
= 8,
91 LPC2000_SECTOR_NOT_PREPARED
= 9,
92 LPC2000_COMPARE_ERROR
= 10,
94 LPC2000_PARAM_ERROR
= 12,
95 LPC2000_ADDR_ERROR
= 13,
96 LPC2000_ADDR_NOT_MAPPED
= 14,
97 LPC2000_CMD_NOT_LOCKED
= 15,
98 LPC2000_INVALID_CODE
= 16,
99 LPC2000_INVALID_BAUD_RATE
= 17,
100 LPC2000_INVALID_STOP_BIT
= 18,
101 LPC2000_CRP_ENABLED
= 19
104 static int lpc2000_build_sector_list(struct flash_bank
*bank
)
106 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
109 /* default to a 4096 write buffer */
110 lpc2000_info
->cmd51_max_buffer
= 4096;
112 if (lpc2000_info
->variant
== lpc2000_v1
) {
113 /* variant 1 has different layout for 128kb and 256kb flashes */
114 if (bank
->size
== 128 * 1024) {
115 bank
->num_sectors
= 16;
116 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 16);
117 for (int i
= 0; i
< 16; i
++) {
118 bank
->sectors
[i
].offset
= offset
;
119 bank
->sectors
[i
].size
= 8 * 1024;
120 offset
+= bank
->sectors
[i
].size
;
121 bank
->sectors
[i
].is_erased
= -1;
122 bank
->sectors
[i
].is_protected
= 1;
124 } else if (bank
->size
== 256 * 1024) {
125 bank
->num_sectors
= 18;
126 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 18);
128 for (int i
= 0; i
< 8; i
++) {
129 bank
->sectors
[i
].offset
= offset
;
130 bank
->sectors
[i
].size
= 8 * 1024;
131 offset
+= bank
->sectors
[i
].size
;
132 bank
->sectors
[i
].is_erased
= -1;
133 bank
->sectors
[i
].is_protected
= 1;
135 for (int i
= 8; i
< 10; i
++) {
136 bank
->sectors
[i
].offset
= offset
;
137 bank
->sectors
[i
].size
= 64 * 1024;
138 offset
+= bank
->sectors
[i
].size
;
139 bank
->sectors
[i
].is_erased
= -1;
140 bank
->sectors
[i
].is_protected
= 1;
142 for (int i
= 10; i
< 18; i
++) {
143 bank
->sectors
[i
].offset
= offset
;
144 bank
->sectors
[i
].size
= 8 * 1024;
145 offset
+= bank
->sectors
[i
].size
;
146 bank
->sectors
[i
].is_erased
= -1;
147 bank
->sectors
[i
].is_protected
= 1;
150 LOG_ERROR("BUG: unknown bank->size encountered");
153 } else if (lpc2000_info
->variant
== lpc2000_v2
) {
154 /* variant 2 has a uniform layout, only number of sectors differs */
155 switch (bank
->size
) {
157 lpc2000_info
->cmd51_max_buffer
= 1024;
158 bank
->num_sectors
= 1;
161 lpc2000_info
->cmd51_max_buffer
= 1024;
162 bank
->num_sectors
= 2;
165 bank
->num_sectors
= 4;
168 bank
->num_sectors
= 8;
171 bank
->num_sectors
= 9;
174 bank
->num_sectors
= 11;
177 bank
->num_sectors
= 15;
180 bank
->num_sectors
= 27;
184 bank
->num_sectors
= 28;
187 LOG_ERROR("BUG: unknown bank->size encountered");
192 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
194 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
196 bank
->sectors
[i
].offset
= offset
;
197 bank
->sectors
[i
].size
= 4 * 1024;
198 offset
+= bank
->sectors
[i
].size
;
199 bank
->sectors
[i
].is_erased
= -1;
200 bank
->sectors
[i
].is_protected
= 1;
202 bank
->sectors
[i
].offset
= offset
;
203 bank
->sectors
[i
].size
= 32 * 1024;
204 offset
+= bank
->sectors
[i
].size
;
205 bank
->sectors
[i
].is_erased
= -1;
206 bank
->sectors
[i
].is_protected
= 1;
208 bank
->sectors
[i
].offset
= offset
;
209 bank
->sectors
[i
].size
= 4 * 1024;
210 offset
+= bank
->sectors
[i
].size
;
211 bank
->sectors
[i
].is_erased
= -1;
212 bank
->sectors
[i
].is_protected
= 1;
215 } else if (lpc2000_info
->variant
== lpc1700
) {
216 switch (bank
->size
) {
218 bank
->num_sectors
= 8;
221 bank
->num_sectors
= 16;
224 bank
->num_sectors
= 18;
227 bank
->num_sectors
= 22;
230 bank
->num_sectors
= 30;
233 LOG_ERROR("BUG: unknown bank->size encountered");
237 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
239 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
240 bank
->sectors
[i
].offset
= offset
;
241 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
242 bank
->sectors
[i
].size
= (i
< 16) ? 4 * 1024 : 32 * 1024;
243 offset
+= bank
->sectors
[i
].size
;
244 bank
->sectors
[i
].is_erased
= -1;
245 bank
->sectors
[i
].is_protected
= 1;
248 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
255 /* call LPC1700/LPC2000 IAP function
256 * uses 180 bytes working area
257 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
258 * 0x8 to 0x1f: command parameter table (1+5 words)
259 * 0x20 to 0x33: command result table (1+4 words)
260 * 0x34 to 0xb3: stack (only 128b needed)
262 static int lpc2000_iap_call(struct flash_bank
*bank
, int code
, uint32_t param_table
[5], uint32_t result_table
[4])
265 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
266 struct target
*target
= bank
->target
;
268 /* regrab previously allocated working_area, or allocate a new one */
269 if (!lpc2000_info
->iap_working_area
) {
270 uint8_t jump_gate
[8];
272 /* make sure we have a working area */
273 if (target_alloc_working_area(target
, 180, &lpc2000_info
->iap_working_area
) != ERROR_OK
) {
274 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
275 return ERROR_FLASH_OPERATION_FAILED
;
278 /* write IAP code to working area */
279 switch (lpc2000_info
->variant
) {
281 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_T_BX(12));
282 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV5_T_BKPT(0));
286 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_BX(12));
287 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV4_5_B(0xfffffe, 0));
290 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
294 retval
= target_write_memory(target
, lpc2000_info
->iap_working_area
->address
, 4, 2, jump_gate
);
295 if (retval
!= ERROR_OK
) {
296 LOG_ERROR("Write memory at address 0x%8.8" PRIx32
" failed (check work_area definition)",
297 lpc2000_info
->iap_working_area
->address
);
302 struct arm_algorithm arm_algo
; /* for LPC2000 */
303 struct armv7m_algorithm armv7m_info
; /* for LPC1700 */
304 uint32_t iap_entry_point
= 0; /* to make compiler happier */
306 switch (lpc2000_info
->variant
) {
308 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
309 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
310 iap_entry_point
= 0x1fff1ff1;
314 arm_algo
.common_magic
= ARM_COMMON_MAGIC
;
315 arm_algo
.core_mode
= ARM_MODE_SVC
;
316 arm_algo
.core_state
= ARM_STATE_ARM
;
317 iap_entry_point
= 0x7ffffff1;
320 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
324 struct mem_param mem_params
[2];
326 /* command parameter table */
327 init_mem_param(&mem_params
[0], lpc2000_info
->iap_working_area
->address
+ 8, 6 * 4, PARAM_OUT
);
328 target_buffer_set_u32(target
, mem_params
[0].value
, code
);
329 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x04, param_table
[0]);
330 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x08, param_table
[1]);
331 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x0c, param_table
[2]);
332 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x10, param_table
[3]);
333 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x14, param_table
[4]);
335 struct reg_param reg_params
[5];
337 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
338 buf_set_u32(reg_params
[0].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x08);
340 /* command result table */
341 init_mem_param(&mem_params
[1], lpc2000_info
->iap_working_area
->address
+ 0x20, 5 * 4, PARAM_IN
);
343 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
344 buf_set_u32(reg_params
[1].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x20);
346 /* IAP entry point */
347 init_reg_param(®_params
[2], "r12", 32, PARAM_OUT
);
348 buf_set_u32(reg_params
[2].value
, 0, 32, iap_entry_point
);
350 switch (lpc2000_info
->variant
) {
353 init_reg_param(®_params
[3], "sp", 32, PARAM_OUT
);
354 buf_set_u32(reg_params
[3].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0xb4);
357 init_reg_param(®_params
[4], "lr", 32, PARAM_OUT
);
358 buf_set_u32(reg_params
[4].value
, 0, 32, (lpc2000_info
->iap_working_area
->address
+ 0x04) | 1);
359 /* bit0 of LR = 1 to return in Thumb mode */
361 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, lpc2000_info
->iap_working_area
->address
, 0,
362 10000, &armv7m_info
);
367 init_reg_param(®_params
[3], "sp_svc", 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_svc", 32, PARAM_OUT
);
372 buf_set_u32(reg_params
[4].value
, 0, 32, lpc2000_info
->iap_working_area
->address
+ 0x04);
374 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, lpc2000_info
->iap_working_area
->address
,
375 lpc2000_info
->iap_working_area
->address
+ 0x4, 10000, &arm_algo
);
378 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
382 int status_code
= target_buffer_get_u32(target
, mem_params
[1].value
);
383 result_table
[0] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x04);
384 result_table
[1] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x08);
385 result_table
[2] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x0c);
386 result_table
[3] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x10);
388 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
389 ") completed with result = %8.8" PRIx32
,
390 code
, param_table
[0], param_table
[1], param_table
[2], param_table
[3], param_table
[4], status_code
);
392 destroy_mem_param(&mem_params
[0]);
393 destroy_mem_param(&mem_params
[1]);
395 destroy_reg_param(®_params
[0]);
396 destroy_reg_param(®_params
[1]);
397 destroy_reg_param(®_params
[2]);
398 destroy_reg_param(®_params
[3]);
399 destroy_reg_param(®_params
[4]);
404 static int lpc2000_iap_blank_check(struct flash_bank
*bank
, int first
, int last
)
406 if ((first
< 0) || (last
>= bank
->num_sectors
))
407 return ERROR_FLASH_SECTOR_INVALID
;
409 uint32_t param_table
[5] = {0};
410 uint32_t result_table
[4];
412 for (int i
= first
; i
<= last
; i
++) {
413 /* check single sector */
414 param_table
[0] = param_table
[1] = i
;
415 int status_code
= lpc2000_iap_call(bank
, 53, param_table
, result_table
);
417 switch (status_code
) {
418 case ERROR_FLASH_OPERATION_FAILED
:
419 return ERROR_FLASH_OPERATION_FAILED
;
420 case LPC2000_CMD_SUCCESS
:
421 bank
->sectors
[i
].is_erased
= 1;
423 case LPC2000_SECTOR_NOT_BLANK
:
424 bank
->sectors
[i
].is_erased
= 0;
426 case LPC2000_INVALID_SECTOR
:
427 bank
->sectors
[i
].is_erased
= 0;
430 return ERROR_FLASH_BUSY
;
433 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code
);
442 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
444 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command
)
447 return ERROR_COMMAND_SYNTAX_ERROR
;
449 struct lpc2000_flash_bank
*lpc2000_info
= malloc(sizeof(struct lpc2000_flash_bank
));
450 bank
->driver_priv
= lpc2000_info
;
452 if (strcmp(CMD_ARGV
[6], "lpc2000_v1") == 0) {
453 lpc2000_info
->variant
= lpc2000_v1
;
454 lpc2000_info
->cmd51_dst_boundary
= 512;
455 lpc2000_info
->cmd51_can_256b
= 0;
456 lpc2000_info
->cmd51_can_8192b
= 1;
457 lpc2000_info
->checksum_vector
= 5;
458 } else if (strcmp(CMD_ARGV
[6], "lpc2000_v2") == 0) {
459 lpc2000_info
->variant
= lpc2000_v2
;
460 lpc2000_info
->cmd51_dst_boundary
= 256;
461 lpc2000_info
->cmd51_can_256b
= 1;
462 lpc2000_info
->cmd51_can_8192b
= 0;
463 lpc2000_info
->checksum_vector
= 5;
464 } else if (strcmp(CMD_ARGV
[6], "lpc1700") == 0) {
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;
471 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV
[6]);
473 return ERROR_FLASH_BANK_INVALID
;
476 lpc2000_info
->iap_working_area
= NULL
;
477 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[7], lpc2000_info
->cclk
);
478 lpc2000_info
->calc_checksum
= 0;
479 lpc2000_build_sector_list(bank
);
482 if (strcmp(CMD_ARGV
[8], "calc_checksum") == 0)
483 lpc2000_info
->calc_checksum
= 1;
489 static int lpc2000_erase(struct flash_bank
*bank
, int first
, int last
)
491 if (bank
->target
->state
!= TARGET_HALTED
) {
492 LOG_ERROR("Target not halted");
493 return ERROR_TARGET_NOT_HALTED
;
496 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
497 uint32_t param_table
[5] = {0};
499 param_table
[0] = first
;
500 param_table
[1] = last
;
501 param_table
[2] = lpc2000_info
->cclk
;
503 uint32_t result_table
[4];
505 /* Prepare sectors */
506 int status_code
= lpc2000_iap_call(bank
, 50, param_table
, result_table
);
507 switch (status_code
) {
508 case ERROR_FLASH_OPERATION_FAILED
:
509 return ERROR_FLASH_OPERATION_FAILED
;
510 case LPC2000_CMD_SUCCESS
:
512 case LPC2000_INVALID_SECTOR
:
513 return ERROR_FLASH_SECTOR_INVALID
;
516 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
517 return ERROR_FLASH_OPERATION_FAILED
;
521 status_code
= lpc2000_iap_call(bank
, 52, param_table
, result_table
);
522 switch (status_code
) {
523 case ERROR_FLASH_OPERATION_FAILED
:
524 return ERROR_FLASH_OPERATION_FAILED
;
525 case LPC2000_CMD_SUCCESS
:
527 case LPC2000_INVALID_SECTOR
:
528 return ERROR_FLASH_SECTOR_INVALID
;
531 LOG_WARNING("lpc2000 erase sectors returned %i", status_code
);
532 return ERROR_FLASH_OPERATION_FAILED
;
538 static int lpc2000_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
540 /* can't protect/unprotect on the lpc2000 */
544 static int lpc2000_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
546 struct target
*target
= bank
->target
;
548 if (bank
->target
->state
!= TARGET_HALTED
) {
549 LOG_ERROR("Target not halted");
550 return ERROR_TARGET_NOT_HALTED
;
553 if (offset
+ count
> bank
->size
)
554 return ERROR_FLASH_DST_OUT_OF_BANK
;
556 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
558 uint32_t dst_min_alignment
= lpc2000_info
->cmd51_dst_boundary
;
560 if (offset
% dst_min_alignment
) {
561 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
, offset
, dst_min_alignment
);
562 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
565 int first_sector
= 0;
568 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
569 if (offset
>= bank
->sectors
[i
].offset
)
571 if (offset
+ DIV_ROUND_UP(count
, dst_min_alignment
) * dst_min_alignment
> bank
->sectors
[i
].offset
)
575 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
577 /* check if exception vectors should be flashed */
578 if ((offset
== 0) && (count
>= 0x20) && lpc2000_info
->calc_checksum
) {
579 uint32_t checksum
= 0;
580 for (int i
= 0; i
< 8; i
++) {
581 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32
, i
* 4, buf_get_u32(buffer
+ (i
* 4), 0, 32));
582 if (i
!= lpc2000_info
->checksum_vector
)
583 checksum
+= buf_get_u32(buffer
+ (i
* 4), 0, 32);
585 checksum
= 0 - checksum
;
586 LOG_DEBUG("checksum: 0x%8.8" PRIx32
, checksum
);
588 uint32_t original_value
= buf_get_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32);
589 if (original_value
!= checksum
) {
590 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32
") to be written to flash is "
591 "different from calculated vector checksum (0x%8.8" PRIx32
").", original_value
, checksum
);
592 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
596 buf_set_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32, checksum
);
599 struct working_area
*download_area
;
601 /* allocate a working area */
602 if (target_alloc_working_area(target
, lpc2000_info
->cmd51_max_buffer
, &download_area
) != ERROR_OK
) {
603 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
604 return ERROR_FLASH_OPERATION_FAILED
;
607 uint32_t bytes_remaining
= count
;
608 uint32_t bytes_written
= 0;
609 uint32_t param_table
[5] = {0};
610 uint32_t result_table
[4];
611 int retval
= ERROR_OK
;
613 while (bytes_remaining
> 0) {
614 uint32_t thisrun_bytes
;
615 if (bytes_remaining
>= lpc2000_info
->cmd51_max_buffer
)
616 thisrun_bytes
= lpc2000_info
->cmd51_max_buffer
;
617 else if (bytes_remaining
>= 1024)
618 thisrun_bytes
= 1024;
619 else if ((bytes_remaining
>= 512) || (!lpc2000_info
->cmd51_can_256b
))
624 /* Prepare sectors */
625 param_table
[0] = first_sector
;
626 param_table
[1] = last_sector
;
627 int status_code
= lpc2000_iap_call(bank
, 50, param_table
, result_table
);
628 switch (status_code
) {
629 case ERROR_FLASH_OPERATION_FAILED
:
630 retval
= ERROR_FLASH_OPERATION_FAILED
;
632 case LPC2000_CMD_SUCCESS
:
634 case LPC2000_INVALID_SECTOR
:
635 retval
= ERROR_FLASH_SECTOR_INVALID
;
638 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
639 retval
= ERROR_FLASH_OPERATION_FAILED
;
643 /* Exit if error occured */
644 if (retval
!= ERROR_OK
)
647 if (bytes_remaining
>= thisrun_bytes
) {
648 retval
= target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, buffer
+ bytes_written
);
649 if (retval
!= ERROR_OK
) {
650 retval
= ERROR_FLASH_OPERATION_FAILED
;
654 uint8_t *last_buffer
= malloc(thisrun_bytes
);
655 memcpy(last_buffer
, buffer
+ bytes_written
, bytes_remaining
);
656 memset(last_buffer
+ bytes_remaining
, 0xff, thisrun_bytes
- bytes_remaining
);
657 target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, last_buffer
);
661 LOG_DEBUG("writing 0x%" PRIx32
" bytes to address 0x%" PRIx32
, thisrun_bytes
,
662 bank
->base
+ offset
+ bytes_written
);
665 param_table
[0] = bank
->base
+ offset
+ bytes_written
;
666 param_table
[1] = download_area
->address
;
667 param_table
[2] = thisrun_bytes
;
668 param_table
[3] = lpc2000_info
->cclk
;
669 status_code
= lpc2000_iap_call(bank
, 51, param_table
, result_table
);
670 switch (status_code
) {
671 case ERROR_FLASH_OPERATION_FAILED
:
672 retval
= ERROR_FLASH_OPERATION_FAILED
;
674 case LPC2000_CMD_SUCCESS
:
676 case LPC2000_INVALID_SECTOR
:
677 retval
= ERROR_FLASH_SECTOR_INVALID
;
680 LOG_WARNING("lpc2000 returned %i", status_code
);
681 retval
= ERROR_FLASH_OPERATION_FAILED
;
685 /* Exit if error occured */
686 if (retval
!= ERROR_OK
)
689 if (bytes_remaining
> thisrun_bytes
)
690 bytes_remaining
-= thisrun_bytes
;
693 bytes_written
+= thisrun_bytes
;
696 target_free_working_area(target
, download_area
);
701 static int lpc2000_probe(struct flash_bank
*bank
)
703 /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
707 static int lpc2000_erase_check(struct flash_bank
*bank
)
709 if (bank
->target
->state
!= TARGET_HALTED
) {
710 LOG_ERROR("Target not halted");
711 return ERROR_TARGET_NOT_HALTED
;
714 return lpc2000_iap_blank_check(bank
, 0, bank
->num_sectors
- 1);
717 static int lpc2000_protect_check(struct flash_bank
*bank
)
719 /* sectors are always protected */
723 static int get_lpc2000_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
725 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
727 snprintf(buf
, buf_size
, "lpc2000 flash driver variant: %i, clk: %" PRIi32
"kHz", lpc2000_info
->variant
,
733 COMMAND_HANDLER(lpc2000_handle_part_id_command
)
736 return ERROR_COMMAND_SYNTAX_ERROR
;
738 struct flash_bank
*bank
;
739 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
740 if (ERROR_OK
!= retval
)
743 if (bank
->target
->state
!= TARGET_HALTED
) {
744 LOG_ERROR("Target not halted");
745 return ERROR_TARGET_NOT_HALTED
;
748 uint32_t param_table
[5] = {0};
749 uint32_t result_table
[4];
751 int status_code
= lpc2000_iap_call(bank
, 54, param_table
, result_table
);
752 if (status_code
!= 0x0) {
753 if (status_code
== ERROR_FLASH_OPERATION_FAILED
) {
754 command_print(CMD_CTX
, "no sufficient working area specified, can't access LPC2000 IAP interface");
757 command_print(CMD_CTX
, "lpc2000 IAP returned status code %i", status_code
);
759 command_print(CMD_CTX
, "lpc2000 part id: 0x%8.8" PRIx32
, result_table
[0]);
764 static const struct command_registration lpc2000_exec_command_handlers
[] = {
767 .handler
= lpc2000_handle_part_id_command
,
768 .mode
= COMMAND_EXEC
,
769 .help
= "print part id of lpc2000 flash bank <num>",
772 COMMAND_REGISTRATION_DONE
774 static const struct command_registration lpc2000_command_handlers
[] = {
778 .help
= "lpc2000 flash command group",
780 .chain
= lpc2000_exec_command_handlers
,
782 COMMAND_REGISTRATION_DONE
785 struct flash_driver lpc2000_flash
= {
787 .commands
= lpc2000_command_handlers
,
788 .flash_bank_command
= lpc2000_flash_bank_command
,
789 .erase
= lpc2000_erase
,
790 .protect
= lpc2000_protect
,
791 .write
= lpc2000_write
,
792 .read
= default_flash_read
,
793 .probe
= lpc2000_probe
,
794 .auto_probe
= lpc2000_probe
,
795 .erase_check
= lpc2000_erase_check
,
796 .protect_check
= lpc2000_protect_check
,
797 .info
= get_lpc2000_info
,
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)