1 /***************************************************************************
2 * Copyright (C) 2016 by Maxim Integrated *
3 * Kevin Gillespie <kevin.gillespie@maximintegrated.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
24 #include <target/algorithm.h>
25 #include <target/armv7m.h>
27 /* Register Addresses */
28 #define FLSH_ADDR 0x000
29 #define FLSH_CLKDIV 0x004
31 #define PR1E_ADDR 0x00C
32 #define PR2S_ADDR 0x010
33 #define PR2E_ADDR 0x014
34 #define PR3S_ADDR 0x018
35 #define PR3E_ADDR 0x01C
37 #define FLSH_INT 0x024
38 #define FLSH_DATA0 0x030
39 #define FLSH_DATA1 0x034
40 #define FLSH_DATA2 0x038
41 #define FLSH_DATA3 0x03C
42 #define FLSH_BL_CTRL 0x170
43 #define FLSH_PROT 0x300
45 #define ARM_PID_REG 0xE00FFFE0
46 #define MAX326XX_ID_REG 0x40000838
48 /* Register settings */
49 #define FLSH_INT_AF 0x00000002
51 #define FLSH_CN_UNLOCK_MASK 0xF0000000
52 #define FLSH_CN_UNLOCK_VALUE 0x20000000
54 #define FLSH_CN_PEND 0x01000000
56 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
57 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
58 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
60 #define FLSH_CN_PGE 0x00000004
61 #define FLSH_CN_ME 0x00000002
62 #define FLSH_CN_WR 0x00000001
63 #define FLASH_BL_CTRL_23 0x00020000
64 #define FLASH_BL_CTRL_IFREN 0x00000001
66 #define ARM_PID_DEFAULT_CM3 0xB4C3
67 #define ARM_PID_DEFAULT_CM4 0xB4C4
68 #define MAX326XX_ID 0x4D
70 static int max32xxx_mass_erase(struct flash_bank
*bank
);
72 struct max32xxx_flash_bank
{
75 unsigned int flash_size
;
76 unsigned int flc_base
;
77 unsigned int sector_size
;
78 unsigned int clkdiv_value
;
79 unsigned int int_state
;
80 unsigned int burst_size_bits
;
83 /* see contib/loaders/flash/max32xxx/max32xxx.s for src */
84 static const uint8_t write_code
[] = {
85 #include "../../contrib/loaders/flash/max32xxx/max32xxx.inc"
88 /* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
89 flash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]
91 FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command
)
93 struct max32xxx_flash_bank
*info
;
96 LOG_WARNING("incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
97 return ERROR_FLASH_BANK_INVALID
;
100 info
= calloc(sizeof(struct max32xxx_flash_bank
), 1);
101 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], info
->flash_size
);
102 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], info
->flc_base
);
103 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[7], info
->sector_size
);
104 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[8], info
->clkdiv_value
);
107 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[9], info
->burst_size_bits
);
109 info
->burst_size_bits
= 32;
112 bank
->driver_priv
= info
;
116 static int get_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
119 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
121 if (info
->probed
== 0)
122 return ERROR_FLASH_BANK_NOT_PROBED
;
124 printed
= snprintf(buf
, buf_size
, "\nMaxim Integrated max32xxx flash driver\n");
130 /***************************************************************************
132 ***************************************************************************/
134 static int max32xxx_flash_op_pre(struct flash_bank
*bank
)
136 struct target
*target
= bank
->target
;
137 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
141 /* Check if the flash controller is busy */
142 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
143 if (flsh_cn
& (FLSH_CN_PEND
| FLSH_CN_ERASE_CODE_MASK
| FLSH_CN_PGE
|
144 FLSH_CN_ME
| FLSH_CN_WR
))
145 return ERROR_FLASH_BUSY
;
147 /* Refresh flash controller timing */
148 target_write_u32(target
, info
->flc_base
+ FLSH_CLKDIV
, info
->clkdiv_value
);
150 /* Clear and disable flash programming interrupts */
151 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &info
->int_state
);
152 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0x00000000);
154 /* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
155 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
156 LOG_ERROR("Read failure on FLSH_BL_CTRL");
159 if (bootloader
& FLASH_BL_CTRL_23
) {
160 LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
161 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
162 LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
163 bootloader
&= ~(FLASH_BL_CTRL_IFREN
);
164 if (target_write_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, bootloader
) != ERROR_OK
) {
165 LOG_ERROR("Write failure on FLSH_BL_CTRL");
168 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
169 LOG_ERROR("Read failure on FLSH_BL_CTRL");
172 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
174 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
180 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
181 flsh_cn
|= FLSH_CN_UNLOCK_VALUE
;
182 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
184 /* Confirm flash is unlocked */
185 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
186 if ((flsh_cn
& FLSH_CN_UNLOCK_VALUE
) != FLSH_CN_UNLOCK_VALUE
)
192 static int max32xxx_flash_op_post(struct flash_bank
*bank
)
194 struct target
*target
= bank
->target
;
195 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
198 /* Restore flash programming interrupts */
199 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, info
->int_state
);
202 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
203 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
204 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
208 static int max32xxx_protect_check(struct flash_bank
*bank
)
210 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
211 struct target
*target
= bank
->target
;
215 if (info
->probed
== 0)
216 return ERROR_FLASH_BANK_NOT_PROBED
;
218 if (!info
->max326xx
) {
219 for (i
= 0; i
< bank
->num_sectors
; i
++)
220 bank
->sectors
[i
].is_protected
= -1;
222 return ERROR_FLASH_OPER_UNSUPPORTED
;
225 /* Check the protection */
226 for (i
= 0; i
< bank
->num_sectors
; i
++) {
228 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ ((i
/32)*4), &temp_reg
);
230 if (temp_reg
& (0x1 << i
%32))
231 bank
->sectors
[i
].is_protected
= 1;
233 bank
->sectors
[i
].is_protected
= 0;
238 static int max32xxx_erase(struct flash_bank
*bank
, int first
, int last
)
241 uint32_t flsh_cn
, flsh_int
;
242 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
243 struct target
*target
= bank
->target
;
247 if (bank
->target
->state
!= TARGET_HALTED
) {
248 LOG_ERROR("Target not halted");
249 return ERROR_TARGET_NOT_HALTED
;
252 if (info
->probed
== 0)
253 return ERROR_FLASH_BANK_NOT_PROBED
;
255 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
256 return ERROR_FLASH_SECTOR_INVALID
;
258 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
259 return max32xxx_mass_erase(bank
);
261 /* Prepare to issue flash operation */
262 retval
= max32xxx_flash_op_pre(bank
);
264 if (retval
!= ERROR_OK
)
268 for (banknr
= first
; banknr
<= last
; banknr
++) {
270 /* Check the protection */
271 if (bank
->sectors
[banknr
].is_protected
== 1) {
272 LOG_WARNING("Flash sector %d is protected", banknr
);
277 /* Address is first word in page */
278 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, banknr
* info
->sector_size
);
280 /* Write page erase code */
281 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
282 flsh_cn
|= FLSH_CN_ERASE_CODE_PGE
;
283 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
285 /* Issue page erase command */
287 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
289 /* Wait until erase complete */
292 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
293 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
296 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
297 banknr
* info
->sector_size
);
298 return ERROR_FLASH_OPERATION_FAILED
;
301 /* Check access violations */
302 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
303 if (flsh_int
& FLSH_INT_AF
) {
304 LOG_ERROR("Error erasing flash page %i", banknr
);
305 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
306 max32xxx_flash_op_post(bank
);
307 return ERROR_FLASH_OPERATION_FAILED
;
310 bank
->sectors
[banknr
].is_erased
= 1;
314 LOG_ERROR("All pages protected %d to %d", first
, last
);
315 max32xxx_flash_op_post(bank
);
319 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
325 static int max32xxx_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
327 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
328 struct target
*target
= bank
->target
;
332 if (bank
->target
->state
!= TARGET_HALTED
) {
333 LOG_ERROR("Target not halted");
334 return ERROR_TARGET_NOT_HALTED
;
337 if (info
->probed
== 0)
338 return ERROR_FLASH_BANK_NOT_PROBED
;
341 return ERROR_FLASH_OPER_UNSUPPORTED
;
343 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
344 return ERROR_FLASH_SECTOR_INVALID
;
346 /* Setup the protection on the pages given */
347 for (page
= first
; page
<= last
; page
++) {
349 /* Set the write/erase bit for this page */
350 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
351 temp_reg
|= (0x1 << page
%32);
352 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
353 bank
->sectors
[page
].is_protected
= 1;
355 /* Clear the write/erase bit for this page */
356 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
357 temp_reg
&= ~(0x1 << page
%32);
358 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
359 bank
->sectors
[page
].is_protected
= 0;
366 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
367 uint32_t offset
, uint32_t wcount
)
369 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
370 struct target
*target
= bank
->target
;
371 uint32_t buffer_size
= 16384;
372 struct working_area
*source
;
373 struct working_area
*write_algorithm
;
374 uint32_t address
= bank
->base
+ offset
;
375 struct reg_param reg_params
[5];
376 struct armv7m_algorithm armv7m_info
;
377 int retval
= ERROR_OK
;
378 /* power of two, and multiple of word size */
379 static const unsigned buf_min
= 128;
381 /* for small buffers it's faster not to download an algorithm */
382 if (wcount
* 4 < buf_min
)
383 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
385 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
386 bank
, buffer
, offset
, wcount
);
388 /* flash write code */
389 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
390 LOG_DEBUG("no working area for block memory writes");
391 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
394 /* plus a buffer big enough for this data */
395 if (wcount
* 4 < buffer_size
)
396 buffer_size
= wcount
* 4;
399 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
402 if (buffer_size
<= buf_min
) {
403 target_free_working_area(target
, write_algorithm
);
404 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
407 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
408 target_name(target
), (unsigned) buffer_size
);
411 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
414 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
415 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
416 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
417 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
418 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
419 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
420 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
422 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
423 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
424 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
425 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
426 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
427 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
428 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
430 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
431 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
433 target_free_working_area(target
, write_algorithm
);
434 target_free_working_area(target
, source
);
435 destroy_reg_param(®_params
[0]);
436 destroy_reg_param(®_params
[1]);
437 destroy_reg_param(®_params
[2]);
438 destroy_reg_param(®_params
[3]);
439 destroy_reg_param(®_params
[4]);
443 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
444 uint32_t offset
, uint32_t count
)
446 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
447 struct target
*target
= bank
->target
;
448 uint32_t flsh_cn
, flsh_int
;
449 uint32_t address
= offset
;
450 uint32_t remaining
= count
;
451 uint32_t words_remaining
;
455 if (bank
->target
->state
!= TARGET_HALTED
) {
456 LOG_ERROR("Target not halted");
457 return ERROR_TARGET_NOT_HALTED
;
460 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
461 bank
, buffer
, offset
, count
);
463 if (info
->probed
== 0)
464 return ERROR_FLASH_BANK_NOT_PROBED
;
467 LOG_WARNING("offset size must be word aligned");
468 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
471 if (offset
+ count
> bank
->size
)
472 return ERROR_FLASH_DST_OUT_OF_BANK
;
474 /* Prepare to issue flash operation */
475 retval
= max32xxx_flash_op_pre(bank
);
477 if (retval
!= ERROR_OK
)
480 if (remaining
>= 4) {
481 /* write in 32-bit units */
482 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
483 flsh_cn
&= 0xF7FFFFFF;
484 flsh_cn
|= 0x00000010;
485 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
487 /* try using a block write */
488 words_remaining
= remaining
/ 4;
489 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
491 if (retval
!= ERROR_OK
) {
492 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
493 LOG_DEBUG("writing flash word-at-a-time");
495 max32xxx_flash_op_post(bank
);
496 return ERROR_FLASH_OPERATION_FAILED
;
499 /* all 32-bit words have been written */
500 buffer
+= words_remaining
* 4;
501 address
+= words_remaining
* 4;
502 remaining
-= words_remaining
* 4;
506 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
507 /* write in 32-bit units until we are 128-bit aligned */
508 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
509 flsh_cn
&= 0xF7FFFFFF;
510 flsh_cn
|= 0x00000010;
511 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
513 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
514 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
515 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
516 flsh_cn
|= 0x00000001;
517 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
518 /* Wait until flash operation is complete */
522 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
523 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
526 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
527 return ERROR_FLASH_OPERATION_FAILED
;
536 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
537 /* write in 128-bit bursts while we can */
538 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
540 flsh_cn
&= 0xFFFFFFEF;
541 flsh_cn
|= 0x08000000;
542 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
543 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
545 while (remaining
>= 16) {
546 if ((address
& 0xFFF) == 0)
547 LOG_DEBUG("Writing @ 0x%08x", address
);
549 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
550 flsh_cn
|= 0x00000001;
551 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
552 /* Wait until flash operation is complete */
556 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
557 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
560 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
561 return ERROR_FLASH_OPERATION_FAILED
;
570 if (remaining
>= 4) {
572 /* write in 32-bit units while we can */
573 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
574 flsh_cn
&= 0xF7FFFFFF;
575 flsh_cn
|= 0x00000010;
576 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
578 while (remaining
>= 4) {
579 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
580 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
581 flsh_cn
|= 0x00000001;
582 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
583 /* Wait until flash operation is complete */
587 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
588 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
591 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
592 return ERROR_FLASH_OPERATION_FAILED
;
602 /* write remaining bytes in a 32-bit unit */
603 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
604 flsh_cn
&= 0xF7FFFFFF;
605 flsh_cn
|= 0x00000010;
606 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
608 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
611 while (remaining
> 0) {
612 last_word
[i
++] = *buffer
;
617 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
618 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
619 flsh_cn
|= 0x00000001;
620 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
621 /* Wait until flash operation is complete */
625 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
626 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
629 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
630 return ERROR_FLASH_OPERATION_FAILED
;
634 /* Check access violations */
635 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
636 if (flsh_int
& FLSH_INT_AF
) {
637 LOG_ERROR("Flash Error writing 0x%x bytes at 0x%08x", count
, offset
);
638 max32xxx_flash_op_post(bank
);
639 return ERROR_FLASH_OPERATION_FAILED
;
642 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
648 static int max32xxx_probe(struct flash_bank
*bank
)
650 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
651 struct target
*target
= bank
->target
;
657 bank
->sectors
= NULL
;
660 /* provide this for the benefit of the NOR flash framework */
661 bank
->size
= info
->flash_size
;
662 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
663 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
665 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
666 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
667 bank
->sectors
[i
].size
= info
->sector_size
;
668 bank
->sectors
[i
].is_erased
= -1;
669 bank
->sectors
[i
].is_protected
= -1;
672 /* Probe to determine if this part is in the max326xx family */
674 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
675 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
676 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
677 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
679 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
680 uint32_t max326xx_id
;
681 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
682 LOG_DEBUG("max326xx_id = 0x%x", max326xx_id
);
683 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
684 if (max326xx_id
== MAX326XX_ID
)
687 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
689 /* Initialize the protection bits for each flash page */
690 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
691 LOG_WARNING("Flash protection not supported on this device");
697 static int max32xxx_mass_erase(struct flash_bank
*bank
)
699 struct target
*target
= NULL
;
700 struct max32xxx_flash_bank
*info
= NULL
;
701 uint32_t flsh_cn
, flsh_int
;
704 info
= bank
->driver_priv
;
705 target
= bank
->target
;
707 if (target
->state
!= TARGET_HALTED
) {
708 LOG_ERROR("Target not halted");
709 return ERROR_TARGET_NOT_HALTED
;
712 if (info
->probed
== 0)
713 return ERROR_FLASH_BANK_NOT_PROBED
;
715 int not_protected
= 0;
716 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
717 if (bank
->sectors
[i
].is_protected
== 1)
718 LOG_WARNING("Flash sector %d is protected", i
);
723 if (!not_protected
) {
724 LOG_ERROR("All pages protected");
728 /* Prepare to issue flash operation */
729 retval
= max32xxx_flash_op_pre(bank
);
731 if (retval
!= ERROR_OK
)
734 /* Write mass erase code */
735 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
736 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
737 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
739 /* Issue mass erase command */
741 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
743 /* Wait until erase complete */
746 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
747 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
750 LOG_ERROR("Timed out waiting for flash mass erase");
751 return ERROR_FLASH_OPERATION_FAILED
;
754 /* Check access violations */
755 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
756 if (flsh_int
& FLSH_INT_AF
) {
757 LOG_ERROR("Error mass erasing");
758 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
759 return ERROR_FLASH_OPERATION_FAILED
;
762 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
768 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
771 struct flash_bank
*bank
;
772 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
775 command_print(CMD
, "max32xxx mass_erase <bank>");
779 if (ERROR_OK
!= retval
)
782 if (max32xxx_mass_erase(bank
) == ERROR_OK
) {
783 /* set all sectors as erased */
784 for (i
= 0; i
< bank
->num_sectors
; i
++)
785 bank
->sectors
[i
].is_erased
= 1;
787 command_print(CMD
, "max32xxx mass erase complete");
789 command_print(CMD
, "max32xxx mass erase failed");
794 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
796 struct flash_bank
*bank
;
798 struct max32xxx_flash_bank
*info
;
802 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
806 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
807 if (ERROR_OK
!= retval
)
809 info
= bank
->driver_priv
;
811 /* Convert the range to the page numbers */
812 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
813 LOG_WARNING("Error parsing address");
814 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
817 /* Mask off the top portion on the address */
818 addr
= (addr
& 0x0FFFFFFF);
820 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
821 LOG_WARNING("Error parsing length");
822 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
826 /* Check the address is in the range of the flash */
827 if ((addr
+len
) >= info
->flash_size
)
828 return ERROR_FLASH_SECTOR_INVALID
;
833 /* Convert the address and length to the page boundaries */
834 addr
= addr
- (addr
% info
->sector_size
);
835 if (len
% info
->sector_size
)
836 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
838 /* Convert the address and length to page numbers */
839 addr
= (addr
/ info
->sector_size
);
840 len
= addr
+ (len
/ info
->sector_size
) - 1;
842 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
843 command_print(CMD
, "max32xxx protection set complete");
845 command_print(CMD
, "max32xxx protection set failed");
850 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
852 struct flash_bank
*bank
;
854 struct max32xxx_flash_bank
*info
;
858 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
862 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
863 if (ERROR_OK
!= retval
)
865 info
= bank
->driver_priv
;
867 /* Convert the range to the page numbers */
868 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
869 LOG_WARNING("Error parsing address");
870 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
873 /* Mask off the top portion on the address */
874 addr
= (addr
& 0x0FFFFFFF);
876 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
877 LOG_WARNING("Error parsing length");
878 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
882 /* Check the address is in the range of the flash */
883 if ((addr
+len
) >= info
->flash_size
)
884 return ERROR_FLASH_SECTOR_INVALID
;
889 /* Convert the address and length to the page boundaries */
890 addr
= addr
- (addr
% info
->sector_size
);
891 if (len
% info
->sector_size
)
892 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
894 /* Convert the address and length to page numbers */
895 addr
= (addr
/ info
->sector_size
);
896 len
= addr
+ (len
/ info
->sector_size
) - 1;
898 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
899 command_print(CMD
, "max32xxx protection clear complete");
901 command_print(CMD
, "max32xxx protection clear failed");
906 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
908 struct flash_bank
*bank
;
910 struct max32xxx_flash_bank
*info
;
914 command_print(CMD
, "max32xxx protection_check <bank>");
918 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
919 if (ERROR_OK
!= retval
)
921 info
= bank
->driver_priv
;
923 /* Update the protection array */
924 retval
= max32xxx_protect_check(bank
);
925 if (ERROR_OK
!= retval
) {
926 LOG_WARNING("Error updating the protection array");
930 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
931 for (i
= 0; i
< bank
->num_sectors
; i
+= 4) {
932 LOG_WARNING("s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d",
933 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
934 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
935 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
936 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
942 static const struct command_registration max32xxx_exec_command_handlers
[] = {
944 .name
= "mass_erase",
945 .handler
= max32xxx_handle_mass_erase_command
,
946 .mode
= COMMAND_EXEC
,
948 .help
= "mass erase flash",
951 .name
= "protection_set",
952 .handler
= max32xxx_handle_protection_set_command
,
953 .mode
= COMMAND_EXEC
,
954 .usage
= "bank_id addr size",
955 .help
= "set flash protection for address range",
958 .name
= "protection_clr",
959 .handler
= max32xxx_handle_protection_clr_command
,
960 .mode
= COMMAND_EXEC
,
961 .usage
= "bank_id addr size",
962 .help
= "clear flash protection for address range",
965 .name
= "protection_check",
966 .handler
= max32xxx_handle_protection_check_command
,
967 .mode
= COMMAND_EXEC
,
969 .help
= "check flash protection",
971 COMMAND_REGISTRATION_DONE
974 static const struct command_registration max32xxx_command_handlers
[] = {
977 .mode
= COMMAND_EXEC
,
978 .help
= "max32xxx flash command group",
979 .chain
= max32xxx_exec_command_handlers
,
982 COMMAND_REGISTRATION_DONE
985 const struct flash_driver max32xxx_flash
= {
987 .commands
= max32xxx_command_handlers
,
988 .flash_bank_command
= max32xxx_flash_bank_command
,
989 .erase
= max32xxx_erase
,
990 .protect
= max32xxx_protect
,
991 .write
= max32xxx_write
,
992 .read
= default_flash_read
,
993 .probe
= max32xxx_probe
,
994 .auto_probe
= max32xxx_probe
,
995 .erase_check
= default_flash_blank_check
,
996 .protect_check
= max32xxx_protect_check
,
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)