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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
62 * lpc4300 (also available as lpc1800 - alias)
63 * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357)
67 * - 810 | 1 | 2 (tested with LPC810/LPC812)
75 * - 11Uxx (tested with LPC11U34)
89 struct lpc2000_flash_bank
{
90 lpc2000_variant variant
;
92 int cmd51_dst_boundary
;
97 uint32_t cmd51_max_buffer
;
99 uint32_t iap_max_stack
;
100 uint32_t cmd51_src_offset
;
101 uint32_t lpc4300_bank
;
104 enum lpc2000_status_codes
{
105 LPC2000_CMD_SUCCESS
= 0,
106 LPC2000_INVALID_COMMAND
= 1,
107 LPC2000_SRC_ADDR_ERROR
= 2,
108 LPC2000_DST_ADDR_ERROR
= 3,
109 LPC2000_SRC_ADDR_NOT_MAPPED
= 4,
110 LPC2000_DST_ADDR_NOT_MAPPED
= 5,
111 LPC2000_COUNT_ERROR
= 6,
112 LPC2000_INVALID_SECTOR
= 7,
113 LPC2000_SECTOR_NOT_BLANK
= 8,
114 LPC2000_SECTOR_NOT_PREPARED
= 9,
115 LPC2000_COMPARE_ERROR
= 10,
117 LPC2000_PARAM_ERROR
= 12,
118 LPC2000_ADDR_ERROR
= 13,
119 LPC2000_ADDR_NOT_MAPPED
= 14,
120 LPC2000_CMD_NOT_LOCKED
= 15,
121 LPC2000_INVALID_CODE
= 16,
122 LPC2000_INVALID_BAUD_RATE
= 17,
123 LPC2000_INVALID_STOP_BIT
= 18,
124 LPC2000_CRP_ENABLED
= 19,
125 LPC2000_INVALID_FLASH_UNIT
= 20,
126 LPC2000_USER_CODE_CHECKSUM
= 21,
127 LCP2000_ERROR_SETTING_ACTIVE_PARTITION
= 22,
130 static int lpc2000_build_sector_list(struct flash_bank
*bank
)
132 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
135 /* default to a 4096 write buffer */
136 lpc2000_info
->cmd51_max_buffer
= 4096;
138 if (lpc2000_info
->variant
== lpc2000_v1
) {
139 /* variant 1 has different layout for 128kb and 256kb flashes */
140 if (bank
->size
== 128 * 1024) {
141 bank
->num_sectors
= 16;
142 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 16);
143 for (int i
= 0; i
< 16; i
++) {
144 bank
->sectors
[i
].offset
= offset
;
145 bank
->sectors
[i
].size
= 8 * 1024;
146 offset
+= bank
->sectors
[i
].size
;
147 bank
->sectors
[i
].is_erased
= -1;
148 bank
->sectors
[i
].is_protected
= 1;
150 } else if (bank
->size
== 256 * 1024) {
151 bank
->num_sectors
= 18;
152 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 18);
154 for (int i
= 0; i
< 8; i
++) {
155 bank
->sectors
[i
].offset
= offset
;
156 bank
->sectors
[i
].size
= 8 * 1024;
157 offset
+= bank
->sectors
[i
].size
;
158 bank
->sectors
[i
].is_erased
= -1;
159 bank
->sectors
[i
].is_protected
= 1;
161 for (int i
= 8; i
< 10; i
++) {
162 bank
->sectors
[i
].offset
= offset
;
163 bank
->sectors
[i
].size
= 64 * 1024;
164 offset
+= bank
->sectors
[i
].size
;
165 bank
->sectors
[i
].is_erased
= -1;
166 bank
->sectors
[i
].is_protected
= 1;
168 for (int i
= 10; i
< 18; i
++) {
169 bank
->sectors
[i
].offset
= offset
;
170 bank
->sectors
[i
].size
= 8 * 1024;
171 offset
+= bank
->sectors
[i
].size
;
172 bank
->sectors
[i
].is_erased
= -1;
173 bank
->sectors
[i
].is_protected
= 1;
176 LOG_ERROR("BUG: unknown bank->size encountered");
179 } else if (lpc2000_info
->variant
== lpc2000_v2
) {
180 /* variant 2 has a uniform layout, only number of sectors differs */
181 switch (bank
->size
) {
183 lpc2000_info
->cmd51_max_buffer
= 1024;
184 bank
->num_sectors
= 1;
187 lpc2000_info
->cmd51_max_buffer
= 1024;
188 bank
->num_sectors
= 2;
191 bank
->num_sectors
= 4;
194 bank
->num_sectors
= 8;
197 bank
->num_sectors
= 9;
200 bank
->num_sectors
= 11;
203 bank
->num_sectors
= 15;
206 bank
->num_sectors
= 27;
210 bank
->num_sectors
= 28;
213 LOG_ERROR("BUG: unknown bank->size encountered");
218 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
220 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
222 bank
->sectors
[i
].offset
= offset
;
223 bank
->sectors
[i
].size
= 4 * 1024;
224 offset
+= bank
->sectors
[i
].size
;
225 bank
->sectors
[i
].is_erased
= -1;
226 bank
->sectors
[i
].is_protected
= 1;
228 bank
->sectors
[i
].offset
= offset
;
229 bank
->sectors
[i
].size
= 32 * 1024;
230 offset
+= bank
->sectors
[i
].size
;
231 bank
->sectors
[i
].is_erased
= -1;
232 bank
->sectors
[i
].is_protected
= 1;
234 bank
->sectors
[i
].offset
= offset
;
235 bank
->sectors
[i
].size
= 4 * 1024;
236 offset
+= bank
->sectors
[i
].size
;
237 bank
->sectors
[i
].is_erased
= -1;
238 bank
->sectors
[i
].is_protected
= 1;
241 } else if (lpc2000_info
->variant
== lpc1700
) {
242 switch (bank
->size
) {
244 lpc2000_info
->cmd51_max_buffer
= 256;
245 bank
->num_sectors
= 1;
248 lpc2000_info
->cmd51_max_buffer
= 512;
249 bank
->num_sectors
= 2;
252 lpc2000_info
->cmd51_max_buffer
= 512;
253 bank
->num_sectors
= 4;
256 lpc2000_info
->cmd51_max_buffer
= 1024;
257 bank
->num_sectors
= 8;
260 bank
->num_sectors
= 16;
263 bank
->num_sectors
= 18;
266 bank
->num_sectors
= 22;
269 bank
->num_sectors
= 30;
272 LOG_ERROR("BUG: unknown bank->size encountered");
276 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
278 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
279 bank
->sectors
[i
].offset
= offset
;
280 /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
281 bank
->sectors
[i
].size
= (i
< 16) ? 4 * 1024 : 32 * 1024;
282 offset
+= bank
->sectors
[i
].size
;
283 bank
->sectors
[i
].is_erased
= -1;
284 bank
->sectors
[i
].is_protected
= 1;
286 } else if (lpc2000_info
->variant
== lpc4300
) {
287 switch (bank
->size
) {
289 bank
->num_sectors
= 11;
292 bank
->num_sectors
= 13;
295 bank
->num_sectors
= 15;
298 LOG_ERROR("BUG: unknown bank->size encountered");
302 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
304 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
305 bank
->sectors
[i
].offset
= offset
;
306 /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
307 bank
->sectors
[i
].size
= (i
< 8) ? 8 * 1024 : 64 * 1024;
308 offset
+= bank
->sectors
[i
].size
;
309 bank
->sectors
[i
].is_erased
= -1;
310 bank
->sectors
[i
].is_protected
= 1;
313 } else if (lpc2000_info
->variant
== lpc800
) {
314 lpc2000_info
->cmd51_max_buffer
= 1024;
315 switch (bank
->size
) {
317 lpc2000_info
->cmd51_max_buffer
= 256;
318 bank
->num_sectors
= 4;
321 lpc2000_info
->cmd51_max_buffer
= 512;
322 bank
->num_sectors
= 8;
325 bank
->num_sectors
= 16;
328 LOG_ERROR("BUG: unknown bank->size encountered");
332 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
334 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
335 bank
->sectors
[i
].offset
= offset
;
336 /* sectors 0-15 are 1kB-sized for LPC8xx devices */
337 bank
->sectors
[i
].size
= 1 * 1024;
338 offset
+= bank
->sectors
[i
].size
;
339 bank
->sectors
[i
].is_erased
= -1;
340 bank
->sectors
[i
].is_protected
= 1;
343 } else if (lpc2000_info
->variant
== lpc1100
) {
344 if ((bank
->size
% (4 * 1024)) != 0) {
345 LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096");
348 lpc2000_info
->cmd51_max_buffer
= 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
349 bank
->num_sectors
= bank
->size
/ 4096;
351 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
353 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
354 bank
->sectors
[i
].offset
= offset
;
355 /* all sectors are 4kB-sized */
356 bank
->sectors
[i
].size
= 4 * 1024;
357 offset
+= bank
->sectors
[i
].size
;
358 bank
->sectors
[i
].is_erased
= -1;
359 bank
->sectors
[i
].is_protected
= 1;
363 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
370 /* this function allocates and initializes working area used for IAP algorithm
371 * uses 52 + max IAP stack bytes working area
372 * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
373 * 0x8 to 0x1f: command parameter table (1+5 words)
374 * 0x20 to 0x33: command result table (1+4 words)
375 * 0x34 to 0xb3|0x104: stack (only 128b needed for lpc17xx/2000, 208 for lpc43xx and 148b for lpc8xx)
378 static int lpc2000_iap_working_area_init(struct flash_bank
*bank
, struct working_area
**iap_working_area
)
380 struct target
*target
= bank
->target
;
381 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
383 if (target_alloc_working_area(target
, 0x34 + lpc2000_info
->iap_max_stack
, iap_working_area
) != ERROR_OK
) {
384 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
385 return ERROR_FLASH_OPERATION_FAILED
;
388 uint8_t jump_gate
[8];
390 /* write IAP code to working area */
391 switch (lpc2000_info
->variant
) {
396 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_T_BX(12));
397 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV5_T_BKPT(0));
401 target_buffer_set_u32(target
, jump_gate
, ARMV4_5_BX(12));
402 target_buffer_set_u32(target
, jump_gate
+ 4, ARMV4_5_B(0xfffffe, 0));
405 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
409 int retval
= target_write_memory(target
, (*iap_working_area
)->address
, 4, 2, jump_gate
);
410 if (retval
!= ERROR_OK
)
411 LOG_ERROR("Write memory at address 0x%8.8" PRIx32
" failed (check work_area definition)",
412 (*iap_working_area
)->address
);
417 /* call LPC1700/LPC2000 IAP function */
419 static int lpc2000_iap_call(struct flash_bank
*bank
, struct working_area
*iap_working_area
, int code
,
420 uint32_t param_table
[5], uint32_t result_table
[4])
422 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
423 struct target
*target
= bank
->target
;
425 struct arm_algorithm arm_algo
; /* for LPC2000 */
426 struct armv7m_algorithm armv7m_info
; /* for LPC1700 */
427 uint32_t iap_entry_point
= 0; /* to make compiler happier */
429 switch (lpc2000_info
->variant
) {
433 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
434 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
435 iap_entry_point
= 0x1fff1ff1;
439 arm_algo
.common_magic
= ARM_COMMON_MAGIC
;
440 arm_algo
.core_mode
= ARM_MODE_SVC
;
441 arm_algo
.core_state
= ARM_STATE_ARM
;
442 iap_entry_point
= 0x7ffffff1;
445 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
446 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
447 /* read out IAP entry point from ROM driver table at 0x10400100 */
448 target_read_u32(target
, 0x10400100, &iap_entry_point
);
451 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
455 struct mem_param mem_params
[2];
457 /* command parameter table */
458 init_mem_param(&mem_params
[0], iap_working_area
->address
+ 8, 6 * 4, PARAM_OUT
);
459 target_buffer_set_u32(target
, mem_params
[0].value
, code
);
460 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x04, param_table
[0]);
461 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x08, param_table
[1]);
462 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x0c, param_table
[2]);
463 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x10, param_table
[3]);
464 target_buffer_set_u32(target
, mem_params
[0].value
+ 0x14, param_table
[4]);
466 struct reg_param reg_params
[5];
468 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
469 buf_set_u32(reg_params
[0].value
, 0, 32, iap_working_area
->address
+ 0x08);
471 /* command result table */
472 init_mem_param(&mem_params
[1], iap_working_area
->address
+ 0x20, 5 * 4, PARAM_IN
);
474 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
475 buf_set_u32(reg_params
[1].value
, 0, 32, iap_working_area
->address
+ 0x20);
477 /* IAP entry point */
478 init_reg_param(®_params
[2], "r12", 32, PARAM_OUT
);
479 buf_set_u32(reg_params
[2].value
, 0, 32, iap_entry_point
);
481 switch (lpc2000_info
->variant
) {
487 init_reg_param(®_params
[3], "sp", 32, PARAM_OUT
);
488 buf_set_u32(reg_params
[3].value
, 0, 32, iap_working_area
->address
+ lpc2000_info
->cmd51_src_offset
);
491 init_reg_param(®_params
[4], "lr", 32, PARAM_OUT
);
492 buf_set_u32(reg_params
[4].value
, 0, 32, (iap_working_area
->address
+ 0x04) | 1);
493 /* bit0 of LR = 1 to return in Thumb mode */
495 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, iap_working_area
->address
, 0, 10000,
501 init_reg_param(®_params
[3], "sp_svc", 32, PARAM_OUT
);
502 buf_set_u32(reg_params
[3].value
, 0, 32, iap_working_area
->address
+ lpc2000_info
->cmd51_src_offset
);
505 init_reg_param(®_params
[4], "lr_svc", 32, PARAM_OUT
);
506 buf_set_u32(reg_params
[4].value
, 0, 32, iap_working_area
->address
+ 0x04);
508 target_run_algorithm(target
, 2, mem_params
, 5, reg_params
, iap_working_area
->address
,
509 iap_working_area
->address
+ 0x4, 10000, &arm_algo
);
512 LOG_ERROR("BUG: unknown lpc2000->variant encountered");
516 int status_code
= target_buffer_get_u32(target
, mem_params
[1].value
);
517 result_table
[0] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x04);
518 result_table
[1] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x08);
519 result_table
[2] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x0c);
520 result_table
[3] = target_buffer_get_u32(target
, mem_params
[1].value
+ 0x10);
522 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
523 ") completed with result = %8.8x",
524 code
, param_table
[0], param_table
[1], param_table
[2], param_table
[3], param_table
[4], status_code
);
526 destroy_mem_param(&mem_params
[0]);
527 destroy_mem_param(&mem_params
[1]);
529 destroy_reg_param(®_params
[0]);
530 destroy_reg_param(®_params
[1]);
531 destroy_reg_param(®_params
[2]);
532 destroy_reg_param(®_params
[3]);
533 destroy_reg_param(®_params
[4]);
538 static int lpc2000_iap_blank_check(struct flash_bank
*bank
, int first
, int last
)
540 if ((first
< 0) || (last
>= bank
->num_sectors
))
541 return ERROR_FLASH_SECTOR_INVALID
;
543 uint32_t param_table
[5] = {0};
544 uint32_t result_table
[4];
545 struct working_area
*iap_working_area
;
547 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
549 if (retval
!= ERROR_OK
)
552 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
553 if (lpc2000_info
->variant
== lpc4300
)
554 param_table
[2] = lpc2000_info
->lpc4300_bank
;
556 for (int i
= first
; i
<= last
&& retval
== ERROR_OK
; i
++) {
557 /* check single sector */
558 param_table
[0] = param_table
[1] = i
;
559 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 53, param_table
, result_table
);
561 switch (status_code
) {
562 case ERROR_FLASH_OPERATION_FAILED
:
563 retval
= ERROR_FLASH_OPERATION_FAILED
;
565 case LPC2000_CMD_SUCCESS
:
566 bank
->sectors
[i
].is_erased
= 1;
568 case LPC2000_SECTOR_NOT_BLANK
:
569 bank
->sectors
[i
].is_erased
= 0;
571 case LPC2000_INVALID_SECTOR
:
572 bank
->sectors
[i
].is_erased
= 0;
575 retval
= ERROR_FLASH_BUSY
;
578 LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code
);
583 struct target
*target
= bank
->target
;
584 target_free_working_area(target
, iap_working_area
);
590 * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
592 FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command
)
595 return ERROR_COMMAND_SYNTAX_ERROR
;
597 struct lpc2000_flash_bank
*lpc2000_info
= calloc(1, sizeof(*lpc2000_info
));
599 bank
->driver_priv
= lpc2000_info
;
601 if (strcmp(CMD_ARGV
[6], "lpc2000_v1") == 0) {
602 lpc2000_info
->variant
= lpc2000_v1
;
603 lpc2000_info
->cmd51_dst_boundary
= 512;
604 lpc2000_info
->cmd51_can_256b
= 0;
605 lpc2000_info
->cmd51_can_8192b
= 1;
606 lpc2000_info
->checksum_vector
= 5;
607 lpc2000_info
->iap_max_stack
= 128;
608 } else if (strcmp(CMD_ARGV
[6], "lpc2000_v2") == 0) {
609 lpc2000_info
->variant
= lpc2000_v2
;
610 lpc2000_info
->cmd51_dst_boundary
= 256;
611 lpc2000_info
->cmd51_can_256b
= 1;
612 lpc2000_info
->cmd51_can_8192b
= 0;
613 lpc2000_info
->checksum_vector
= 5;
614 lpc2000_info
->iap_max_stack
= 128;
615 } else if (strcmp(CMD_ARGV
[6], "lpc1700") == 0) {
616 lpc2000_info
->variant
= lpc1700
;
617 lpc2000_info
->cmd51_dst_boundary
= 256;
618 lpc2000_info
->cmd51_can_256b
= 1;
619 lpc2000_info
->cmd51_can_8192b
= 0;
620 lpc2000_info
->checksum_vector
= 7;
621 lpc2000_info
->iap_max_stack
= 128;
622 } else if (strcmp(CMD_ARGV
[6], "lpc1800") == 0 || strcmp(CMD_ARGV
[6], "lpc4300") == 0) {
623 lpc2000_info
->variant
= lpc4300
;
624 lpc2000_info
->cmd51_dst_boundary
= 512;
625 lpc2000_info
->cmd51_can_256b
= 0;
626 lpc2000_info
->cmd51_can_8192b
= 0;
627 lpc2000_info
->checksum_vector
= 7;
628 lpc2000_info
->iap_max_stack
= 208;
629 } else if (strcmp(CMD_ARGV
[6], "lpc800") == 0) {
630 lpc2000_info
->variant
= lpc800
;
631 lpc2000_info
->cmd51_dst_boundary
= 64;
632 lpc2000_info
->cmd51_can_64b
= 1;
633 lpc2000_info
->cmd51_can_256b
= 0;
634 lpc2000_info
->cmd51_can_8192b
= 0;
635 lpc2000_info
->checksum_vector
= 7;
636 lpc2000_info
->iap_max_stack
= 148;
637 } else if (strcmp(CMD_ARGV
[6], "lpc1100") == 0) {
638 lpc2000_info
->variant
= lpc1100
;
639 lpc2000_info
->cmd51_dst_boundary
= 256;
640 lpc2000_info
->cmd51_can_256b
= 1;
641 lpc2000_info
->cmd51_can_8192b
= 0;
642 lpc2000_info
->checksum_vector
= 7;
643 lpc2000_info
->iap_max_stack
= 128;
645 LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV
[6]);
647 return ERROR_FLASH_BANK_INVALID
;
650 /* see lpc2000_iap_working_area_init() for the reason behind the 0x34 value */
651 lpc2000_info
->cmd51_src_offset
= 0x34 + lpc2000_info
->iap_max_stack
;
653 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[7], lpc2000_info
->cclk
);
654 lpc2000_info
->calc_checksum
= 0;
655 lpc2000_build_sector_list(bank
);
657 uint32_t temp_base
= 0;
658 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], temp_base
);
659 if (temp_base
>= 0x1B000000)
660 lpc2000_info
->lpc4300_bank
= 1; /* bank B */
662 lpc2000_info
->lpc4300_bank
= 0; /* bank A */
665 if (strcmp(CMD_ARGV
[8], "calc_checksum") == 0)
666 lpc2000_info
->calc_checksum
= 1;
672 static int lpc2000_erase(struct flash_bank
*bank
, int first
, int last
)
674 if (bank
->target
->state
!= TARGET_HALTED
) {
675 LOG_ERROR("Target not halted");
676 return ERROR_TARGET_NOT_HALTED
;
679 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
680 uint32_t param_table
[5] = {0};
682 param_table
[0] = first
;
683 param_table
[1] = last
;
685 if (lpc2000_info
->variant
== lpc4300
)
686 param_table
[2] = lpc2000_info
->lpc4300_bank
;
688 param_table
[2] = lpc2000_info
->cclk
;
690 uint32_t result_table
[4];
691 struct working_area
*iap_working_area
;
693 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
695 if (retval
!= ERROR_OK
)
698 if (lpc2000_info
->variant
== lpc4300
)
699 /* Init IAP Anyway */
700 lpc2000_iap_call(bank
, iap_working_area
, 49, param_table
, result_table
);
702 /* Prepare sectors */
703 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 50, param_table
, result_table
);
704 switch (status_code
) {
705 case ERROR_FLASH_OPERATION_FAILED
:
706 retval
= ERROR_FLASH_OPERATION_FAILED
;
708 case LPC2000_CMD_SUCCESS
:
710 case LPC2000_INVALID_SECTOR
:
711 retval
= ERROR_FLASH_SECTOR_INVALID
;
714 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
715 retval
= ERROR_FLASH_OPERATION_FAILED
;
719 if (retval
== ERROR_OK
) {
721 param_table
[2] = lpc2000_info
->cclk
;
722 if (lpc2000_info
->variant
== lpc4300
)
723 param_table
[3] = lpc2000_info
->lpc4300_bank
;
725 status_code
= lpc2000_iap_call(bank
, iap_working_area
, 52, param_table
, result_table
);
726 switch (status_code
) {
727 case ERROR_FLASH_OPERATION_FAILED
:
728 retval
= ERROR_FLASH_OPERATION_FAILED
;
730 case LPC2000_CMD_SUCCESS
:
732 case LPC2000_INVALID_SECTOR
:
733 retval
= ERROR_FLASH_SECTOR_INVALID
;
736 LOG_WARNING("lpc2000 erase sectors returned %i", status_code
);
737 retval
= ERROR_FLASH_OPERATION_FAILED
;
742 struct target
*target
= bank
->target
;
743 target_free_working_area(target
, iap_working_area
);
748 static int lpc2000_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
750 /* can't protect/unprotect on the lpc2000 */
754 static int lpc2000_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
756 struct target
*target
= bank
->target
;
758 if (bank
->target
->state
!= TARGET_HALTED
) {
759 LOG_ERROR("Target not halted");
760 return ERROR_TARGET_NOT_HALTED
;
763 if (offset
+ count
> bank
->size
)
764 return ERROR_FLASH_DST_OUT_OF_BANK
;
766 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
768 uint32_t dst_min_alignment
= lpc2000_info
->cmd51_dst_boundary
;
770 if (offset
% dst_min_alignment
) {
771 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
, offset
, dst_min_alignment
);
772 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
775 int first_sector
= 0;
778 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
779 if (offset
>= bank
->sectors
[i
].offset
)
781 if (offset
+ DIV_ROUND_UP(count
, dst_min_alignment
) * dst_min_alignment
> bank
->sectors
[i
].offset
)
785 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
787 /* check if exception vectors should be flashed */
788 if ((offset
== 0) && (count
>= 0x20) && lpc2000_info
->calc_checksum
) {
789 assert(lpc2000_info
->checksum_vector
< 8);
790 uint32_t checksum
= 0;
791 for (int i
= 0; i
< 8; i
++) {
792 LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32
, i
* 4, buf_get_u32(buffer
+ (i
* 4), 0, 32));
793 if (i
!= lpc2000_info
->checksum_vector
)
794 checksum
+= buf_get_u32(buffer
+ (i
* 4), 0, 32);
796 checksum
= 0 - checksum
;
797 LOG_DEBUG("checksum: 0x%8.8" PRIx32
, checksum
);
799 uint32_t original_value
= buf_get_u32(buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32);
800 if (original_value
!= checksum
) {
801 LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32
") to be written to flash is "
802 "different from calculated vector checksum (0x%8.8" PRIx32
").", original_value
, checksum
);
803 LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
807 /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */
808 buf_set_u32((uint8_t *)buffer
+ (lpc2000_info
->checksum_vector
* 4), 0, 32, checksum
);
811 struct working_area
*iap_working_area
;
813 int retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
815 if (retval
!= ERROR_OK
)
818 struct working_area
*download_area
;
820 /* allocate a working area */
821 if (target_alloc_working_area(target
, lpc2000_info
->cmd51_max_buffer
, &download_area
) != ERROR_OK
) {
822 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
823 target_free_working_area(target
, iap_working_area
);
824 return ERROR_FLASH_OPERATION_FAILED
;
827 uint32_t bytes_remaining
= count
;
828 uint32_t bytes_written
= 0;
829 uint32_t param_table
[5] = {0};
830 uint32_t result_table
[4];
832 if (lpc2000_info
->variant
== lpc4300
)
833 /* Init IAP Anyway */
834 lpc2000_iap_call(bank
, iap_working_area
, 49, param_table
, result_table
);
836 while (bytes_remaining
> 0) {
837 uint32_t thisrun_bytes
;
838 if (bytes_remaining
>= lpc2000_info
->cmd51_max_buffer
)
839 thisrun_bytes
= lpc2000_info
->cmd51_max_buffer
;
840 else if (bytes_remaining
>= 1024)
841 thisrun_bytes
= 1024;
842 else if ((bytes_remaining
>= 512) || (!lpc2000_info
->cmd51_can_256b
))
844 else if ((bytes_remaining
>= 256) || (!lpc2000_info
->cmd51_can_64b
))
849 /* Prepare sectors */
850 param_table
[0] = first_sector
;
851 param_table
[1] = last_sector
;
853 if (lpc2000_info
->variant
== lpc4300
)
854 param_table
[2] = lpc2000_info
->lpc4300_bank
;
856 param_table
[2] = lpc2000_info
->cclk
;
858 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 50, param_table
, result_table
);
859 switch (status_code
) {
860 case ERROR_FLASH_OPERATION_FAILED
:
861 retval
= ERROR_FLASH_OPERATION_FAILED
;
863 case LPC2000_CMD_SUCCESS
:
865 case LPC2000_INVALID_SECTOR
:
866 retval
= ERROR_FLASH_SECTOR_INVALID
;
869 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code
);
870 retval
= ERROR_FLASH_OPERATION_FAILED
;
874 /* Exit if error occured */
875 if (retval
!= ERROR_OK
)
878 if (bytes_remaining
>= thisrun_bytes
) {
879 retval
= target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, buffer
+ bytes_written
);
880 if (retval
!= ERROR_OK
) {
881 retval
= ERROR_FLASH_OPERATION_FAILED
;
885 uint8_t *last_buffer
= malloc(thisrun_bytes
);
886 memcpy(last_buffer
, buffer
+ bytes_written
, bytes_remaining
);
887 memset(last_buffer
+ bytes_remaining
, 0xff, thisrun_bytes
- bytes_remaining
);
888 target_write_buffer(bank
->target
, download_area
->address
, thisrun_bytes
, last_buffer
);
892 LOG_DEBUG("writing 0x%" PRIx32
" bytes to address 0x%" PRIx32
, thisrun_bytes
,
893 bank
->base
+ offset
+ bytes_written
);
896 param_table
[0] = bank
->base
+ offset
+ bytes_written
;
897 param_table
[1] = download_area
->address
;
898 param_table
[2] = thisrun_bytes
;
899 param_table
[3] = lpc2000_info
->cclk
;
900 status_code
= lpc2000_iap_call(bank
, iap_working_area
, 51, param_table
, result_table
);
901 switch (status_code
) {
902 case ERROR_FLASH_OPERATION_FAILED
:
903 retval
= ERROR_FLASH_OPERATION_FAILED
;
905 case LPC2000_CMD_SUCCESS
:
907 case LPC2000_INVALID_SECTOR
:
908 retval
= ERROR_FLASH_SECTOR_INVALID
;
911 LOG_WARNING("lpc2000 returned %i", status_code
);
912 retval
= ERROR_FLASH_OPERATION_FAILED
;
916 /* Exit if error occured */
917 if (retval
!= ERROR_OK
)
920 if (bytes_remaining
> thisrun_bytes
)
921 bytes_remaining
-= thisrun_bytes
;
924 bytes_written
+= thisrun_bytes
;
927 target_free_working_area(target
, iap_working_area
);
928 target_free_working_area(target
, download_area
);
933 static int lpc2000_probe(struct flash_bank
*bank
)
935 /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
939 static int lpc2000_erase_check(struct flash_bank
*bank
)
941 if (bank
->target
->state
!= TARGET_HALTED
) {
942 LOG_ERROR("Target not halted");
943 return ERROR_TARGET_NOT_HALTED
;
946 return lpc2000_iap_blank_check(bank
, 0, bank
->num_sectors
- 1);
949 static int lpc2000_protect_check(struct flash_bank
*bank
)
951 /* sectors are always protected */
955 static int get_lpc2000_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
957 struct lpc2000_flash_bank
*lpc2000_info
= bank
->driver_priv
;
959 snprintf(buf
, buf_size
, "lpc2000 flash driver variant: %i, clk: %" PRIi32
"kHz", lpc2000_info
->variant
,
965 COMMAND_HANDLER(lpc2000_handle_part_id_command
)
968 return ERROR_COMMAND_SYNTAX_ERROR
;
970 struct flash_bank
*bank
;
971 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
972 if (ERROR_OK
!= retval
)
975 if (bank
->target
->state
!= TARGET_HALTED
) {
976 LOG_ERROR("Target not halted");
977 return ERROR_TARGET_NOT_HALTED
;
980 uint32_t param_table
[5] = {0};
981 uint32_t result_table
[4];
982 struct working_area
*iap_working_area
;
984 retval
= lpc2000_iap_working_area_init(bank
, &iap_working_area
);
986 if (retval
!= ERROR_OK
)
989 int status_code
= lpc2000_iap_call(bank
, iap_working_area
, 54, param_table
, result_table
);
990 if (status_code
!= 0x0) {
991 if (status_code
== ERROR_FLASH_OPERATION_FAILED
) {
992 command_print(CMD_CTX
, "no sufficient working area specified, can't access LPC2000 IAP interface");
994 command_print(CMD_CTX
, "lpc2000 IAP returned status code %i", status_code
);
996 command_print(CMD_CTX
, "lpc2000 part id: 0x%8.8" PRIx32
, result_table
[0]);
1001 static const struct command_registration lpc2000_exec_command_handlers
[] = {
1004 .handler
= lpc2000_handle_part_id_command
,
1005 .mode
= COMMAND_EXEC
,
1006 .help
= "print part id of lpc2000 flash bank <num>",
1009 COMMAND_REGISTRATION_DONE
1011 static const struct command_registration lpc2000_command_handlers
[] = {
1014 .mode
= COMMAND_ANY
,
1015 .help
= "lpc2000 flash command group",
1017 .chain
= lpc2000_exec_command_handlers
,
1019 COMMAND_REGISTRATION_DONE
1022 struct flash_driver lpc2000_flash
= {
1024 .commands
= lpc2000_command_handlers
,
1025 .flash_bank_command
= lpc2000_flash_bank_command
,
1026 .erase
= lpc2000_erase
,
1027 .protect
= lpc2000_protect
,
1028 .write
= lpc2000_write
,
1029 .read
= default_flash_read
,
1030 .probe
= lpc2000_probe
,
1031 .auto_probe
= lpc2000_probe
,
1032 .erase_check
= lpc2000_erase_check
,
1033 .protect_check
= lpc2000_protect_check
,
1034 .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)