1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2016 by Maxim Integrated *
5 * Kevin Gillespie <kevin.gillespie@maximintegrated.com> *
6 ***************************************************************************/
13 #include <helper/binarybuffer.h>
14 #include <target/algorithm.h>
15 #include <target/armv7m.h>
17 /* Register Addresses */
18 #define FLSH_ADDR 0x000
19 #define FLSH_CLKDIV 0x004
21 #define PR1E_ADDR 0x00C
22 #define PR2S_ADDR 0x010
23 #define PR2E_ADDR 0x014
24 #define PR3S_ADDR 0x018
25 #define PR3E_ADDR 0x01C
27 #define FLSH_INT 0x024
28 #define FLSH_DATA0 0x030
29 #define FLSH_DATA1 0x034
30 #define FLSH_DATA2 0x038
31 #define FLSH_DATA3 0x03C
32 #define FLSH_BL_CTRL 0x170
33 #define FLSH_PROT 0x300
35 #define ARM_PID_REG 0xE00FFFE0
36 #define MAX326XX_ID_REG 0x40000838
38 /* Register settings */
39 #define FLSH_INT_AF 0x00000002
41 #define FLSH_CN_UNLOCK_MASK 0xF0000000
42 #define FLSH_CN_UNLOCK_VALUE 0x20000000
44 #define FLSH_CN_PEND 0x01000000
46 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
47 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
48 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
50 #define FLSH_CN_PGE 0x00000004
51 #define FLSH_CN_ME 0x00000002
52 #define FLSH_CN_WR 0x00000001
53 #define FLASH_BL_CTRL_23 0x00020000
54 #define FLASH_BL_CTRL_IFREN 0x00000001
56 #define ARM_PID_DEFAULT_CM3 0xB4C3
57 #define ARM_PID_DEFAULT_CM4 0xB4C4
58 #define MAX326XX_ID 0x4D
60 static int max32xxx_mass_erase(struct flash_bank
*bank
);
62 struct max32xxx_flash_bank
{
65 unsigned int flash_size
;
66 unsigned int flc_base
;
67 unsigned int sector_size
;
68 unsigned int clkdiv_value
;
70 unsigned int burst_size_bits
;
73 /* see contrib/loaders/flash/max32xxx/max32xxx.s for src */
74 static const uint8_t write_code
[] = {
75 #include "../../../contrib/loaders/flash/max32xxx/max32xxx.inc"
78 /* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
79 flash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]
81 FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command
)
83 struct max32xxx_flash_bank
*info
;
86 LOG_WARNING("incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
87 return ERROR_FLASH_BANK_INVALID
;
90 info
= calloc(sizeof(struct max32xxx_flash_bank
), 1);
91 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], info
->flash_size
);
92 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[6], info
->flc_base
);
93 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[7], info
->sector_size
);
94 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[8], info
->clkdiv_value
);
97 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[9], info
->burst_size_bits
);
99 info
->burst_size_bits
= 32;
102 bank
->driver_priv
= info
;
106 static int get_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
108 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
111 return ERROR_FLASH_BANK_NOT_PROBED
;
113 command_print_sameline(cmd
, "\nMaxim Integrated max32xxx flash driver\n");
117 /***************************************************************************
119 ***************************************************************************/
121 static int max32xxx_flash_op_pre(struct flash_bank
*bank
)
123 struct target
*target
= bank
->target
;
124 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
128 /* Check if the flash controller is busy */
129 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
130 if (flsh_cn
& (FLSH_CN_PEND
| FLSH_CN_ERASE_CODE_MASK
| FLSH_CN_PGE
|
131 FLSH_CN_ME
| FLSH_CN_WR
))
132 return ERROR_FLASH_BUSY
;
134 /* Refresh flash controller timing */
135 target_write_u32(target
, info
->flc_base
+ FLSH_CLKDIV
, info
->clkdiv_value
);
137 /* Clear and disable flash programming interrupts */
138 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &info
->int_state
);
139 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0x00000000);
141 /* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
142 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
143 LOG_ERROR("Read failure on FLSH_BL_CTRL");
146 if (bootloader
& FLASH_BL_CTRL_23
) {
147 LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
148 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
149 LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
150 bootloader
&= ~(FLASH_BL_CTRL_IFREN
);
151 if (target_write_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, bootloader
) != ERROR_OK
) {
152 LOG_ERROR("Write failure on FLSH_BL_CTRL");
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_IFREN
) {
161 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
167 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
168 flsh_cn
|= FLSH_CN_UNLOCK_VALUE
;
169 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
171 /* Confirm flash is unlocked */
172 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
173 if ((flsh_cn
& FLSH_CN_UNLOCK_VALUE
) != FLSH_CN_UNLOCK_VALUE
)
179 static int max32xxx_flash_op_post(struct flash_bank
*bank
)
181 struct target
*target
= bank
->target
;
182 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
185 /* Restore flash programming interrupts */
186 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, info
->int_state
);
189 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
190 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
191 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
195 static int max32xxx_protect_check(struct flash_bank
*bank
)
197 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
198 struct target
*target
= bank
->target
;
202 return ERROR_FLASH_BANK_NOT_PROBED
;
204 if (!info
->max326xx
) {
205 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
206 bank
->sectors
[i
].is_protected
= -1;
208 return ERROR_FLASH_OPER_UNSUPPORTED
;
211 /* Check the protection */
212 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++) {
214 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ ((i
/32)*4), &temp_reg
);
216 if (temp_reg
& (0x1 << i
%32))
217 bank
->sectors
[i
].is_protected
= 1;
219 bank
->sectors
[i
].is_protected
= 0;
224 static int max32xxx_erase(struct flash_bank
*bank
, unsigned int first
,
227 uint32_t flsh_cn
, flsh_int
;
228 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
229 struct target
*target
= bank
->target
;
233 if (bank
->target
->state
!= TARGET_HALTED
) {
234 LOG_ERROR("Target not halted");
235 return ERROR_TARGET_NOT_HALTED
;
239 return ERROR_FLASH_BANK_NOT_PROBED
;
241 if ((last
< first
) || (last
>= bank
->num_sectors
))
242 return ERROR_FLASH_SECTOR_INVALID
;
244 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
245 return max32xxx_mass_erase(bank
);
247 /* Prepare to issue flash operation */
248 retval
= max32xxx_flash_op_pre(bank
);
250 if (retval
!= ERROR_OK
)
254 for (unsigned int banknr
= first
; banknr
<= last
; banknr
++) {
256 /* Check the protection */
257 if (bank
->sectors
[banknr
].is_protected
== 1) {
258 LOG_WARNING("Flash sector %u is protected", banknr
);
263 /* Address is first word in page */
264 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, banknr
* info
->sector_size
);
266 /* Write page erase code */
267 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
268 flsh_cn
|= FLSH_CN_ERASE_CODE_PGE
;
269 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
271 /* Issue page erase command */
273 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
275 /* Wait until erase complete */
278 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
279 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
282 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
283 banknr
* info
->sector_size
);
284 return ERROR_FLASH_OPERATION_FAILED
;
287 /* Check access violations */
288 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
289 if (flsh_int
& FLSH_INT_AF
) {
290 LOG_ERROR("Error erasing flash page %i", banknr
);
291 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
292 max32xxx_flash_op_post(bank
);
293 return ERROR_FLASH_OPERATION_FAILED
;
298 LOG_ERROR("All pages protected %u to %u", first
, last
);
299 max32xxx_flash_op_post(bank
);
303 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
309 static int max32xxx_protect(struct flash_bank
*bank
, int set
,
310 unsigned int first
, unsigned int last
)
312 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
313 struct target
*target
= bank
->target
;
316 if (bank
->target
->state
!= TARGET_HALTED
) {
317 LOG_ERROR("Target not halted");
318 return ERROR_TARGET_NOT_HALTED
;
322 return ERROR_FLASH_BANK_NOT_PROBED
;
325 return ERROR_FLASH_OPER_UNSUPPORTED
;
327 if ((last
< first
) || (last
>= bank
->num_sectors
))
328 return ERROR_FLASH_SECTOR_INVALID
;
330 /* Setup the protection on the pages given */
331 for (unsigned int page
= first
; page
<= last
; page
++) {
333 /* Set the write/erase bit for this page */
334 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
335 temp_reg
|= (0x1 << page
%32);
336 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
337 bank
->sectors
[page
].is_protected
= 1;
339 /* Clear the write/erase bit for this page */
340 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
341 temp_reg
&= ~(0x1 << page
%32);
342 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
343 bank
->sectors
[page
].is_protected
= 0;
350 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
351 uint32_t offset
, uint32_t wcount
)
353 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
354 struct target
*target
= bank
->target
;
355 uint32_t buffer_size
= 16384;
356 struct working_area
*source
;
357 struct working_area
*write_algorithm
;
358 uint32_t address
= bank
->base
+ offset
;
359 struct reg_param reg_params
[5];
360 struct armv7m_algorithm armv7m_info
;
361 int retval
= ERROR_OK
;
362 /* power of two, and multiple of word size */
363 static const unsigned buf_min
= 128;
365 /* for small buffers it's faster not to download an algorithm */
366 if (wcount
* 4 < buf_min
)
367 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
369 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
370 bank
, buffer
, offset
, wcount
);
372 /* flash write code */
373 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
374 LOG_DEBUG("no working area for block memory writes");
375 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
378 /* plus a buffer big enough for this data */
379 if (wcount
* 4 < buffer_size
)
380 buffer_size
= wcount
* 4;
383 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
386 if (buffer_size
<= buf_min
) {
387 target_free_working_area(target
, write_algorithm
);
388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
391 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
392 target_name(target
), (unsigned) buffer_size
);
395 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
398 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
399 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
400 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
401 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
402 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
403 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
404 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
406 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
407 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
408 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
409 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
410 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
411 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
412 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
414 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
415 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
417 target_free_working_area(target
, write_algorithm
);
418 target_free_working_area(target
, source
);
419 destroy_reg_param(®_params
[0]);
420 destroy_reg_param(®_params
[1]);
421 destroy_reg_param(®_params
[2]);
422 destroy_reg_param(®_params
[3]);
423 destroy_reg_param(®_params
[4]);
427 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
428 uint32_t offset
, uint32_t count
)
430 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
431 struct target
*target
= bank
->target
;
432 uint32_t flsh_cn
, flsh_int
;
433 uint32_t address
= offset
;
434 uint32_t remaining
= count
;
435 uint32_t words_remaining
;
439 if (bank
->target
->state
!= TARGET_HALTED
) {
440 LOG_ERROR("Target not halted");
441 return ERROR_TARGET_NOT_HALTED
;
444 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
445 bank
, buffer
, offset
, count
);
448 return ERROR_FLASH_BANK_NOT_PROBED
;
451 LOG_WARNING("offset size must be word aligned");
452 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
455 if (offset
+ count
> bank
->size
)
456 return ERROR_FLASH_DST_OUT_OF_BANK
;
458 /* Prepare to issue flash operation */
459 retval
= max32xxx_flash_op_pre(bank
);
461 if (retval
!= ERROR_OK
)
464 if (remaining
>= 4) {
465 /* write in 32-bit units */
466 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
467 flsh_cn
&= 0xF7FFFFFF;
468 flsh_cn
|= 0x00000010;
469 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
471 /* try using a block write */
472 words_remaining
= remaining
/ 4;
473 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
475 if (retval
!= ERROR_OK
) {
476 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
477 LOG_DEBUG("writing flash word-at-a-time");
479 max32xxx_flash_op_post(bank
);
480 return ERROR_FLASH_OPERATION_FAILED
;
483 /* all 32-bit words have been written */
484 buffer
+= words_remaining
* 4;
485 address
+= words_remaining
* 4;
486 remaining
-= words_remaining
* 4;
490 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
491 /* write in 32-bit units until we are 128-bit aligned */
492 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
493 flsh_cn
&= 0xF7FFFFFF;
494 flsh_cn
|= 0x00000010;
495 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
497 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
498 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
499 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
500 flsh_cn
|= 0x00000001;
501 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
502 /* Wait until flash operation is complete */
506 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
507 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
510 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
511 return ERROR_FLASH_OPERATION_FAILED
;
520 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
521 /* write in 128-bit bursts while we can */
522 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
524 flsh_cn
&= 0xFFFFFFEF;
525 flsh_cn
|= 0x08000000;
526 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
527 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
529 while (remaining
>= 16) {
530 if ((address
& 0xFFF) == 0)
531 LOG_DEBUG("Writing @ 0x%08" PRIx32
, address
);
533 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
534 flsh_cn
|= 0x00000001;
535 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
536 /* Wait until flash operation is complete */
540 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
541 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
544 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
545 return ERROR_FLASH_OPERATION_FAILED
;
554 if (remaining
>= 4) {
556 /* write in 32-bit units while we can */
557 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
558 flsh_cn
&= 0xF7FFFFFF;
559 flsh_cn
|= 0x00000010;
560 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
562 while (remaining
>= 4) {
563 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
564 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
565 flsh_cn
|= 0x00000001;
566 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
567 /* Wait until flash operation is complete */
571 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
572 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
575 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
576 return ERROR_FLASH_OPERATION_FAILED
;
586 /* write remaining bytes in a 32-bit unit */
587 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
588 flsh_cn
&= 0xF7FFFFFF;
589 flsh_cn
|= 0x00000010;
590 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
592 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
595 while (remaining
> 0) {
596 last_word
[i
++] = *buffer
;
601 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
602 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
603 flsh_cn
|= 0x00000001;
604 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
605 /* Wait until flash operation is complete */
609 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
610 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
613 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
614 return ERROR_FLASH_OPERATION_FAILED
;
618 /* Check access violations */
619 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
620 if (flsh_int
& FLSH_INT_AF
) {
621 LOG_ERROR("Flash Error writing 0x%" PRIx32
" bytes at 0x%08" PRIx32
, count
, offset
);
622 max32xxx_flash_op_post(bank
);
623 return ERROR_FLASH_OPERATION_FAILED
;
626 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
632 static int max32xxx_probe(struct flash_bank
*bank
)
634 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
635 struct target
*target
= bank
->target
;
641 /* provide this for the benefit of the NOR flash framework */
642 bank
->size
= info
->flash_size
;
643 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
644 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
646 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
647 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
648 bank
->sectors
[i
].size
= info
->sector_size
;
649 bank
->sectors
[i
].is_erased
= -1;
650 bank
->sectors
[i
].is_protected
= -1;
653 /* Probe to determine if this part is in the max326xx family */
655 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
656 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
657 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
658 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
660 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
661 uint32_t max326xx_id
;
662 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
663 LOG_DEBUG("max326xx_id = 0x%" PRIx32
, max326xx_id
);
664 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
665 if (max326xx_id
== MAX326XX_ID
)
668 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
670 /* Initialize the protection bits for each flash page */
671 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
672 LOG_WARNING("Flash protection not supported on this device");
678 static int max32xxx_mass_erase(struct flash_bank
*bank
)
680 struct target
*target
= NULL
;
681 struct max32xxx_flash_bank
*info
= NULL
;
682 uint32_t flsh_cn
, flsh_int
;
685 info
= bank
->driver_priv
;
686 target
= bank
->target
;
688 if (target
->state
!= TARGET_HALTED
) {
689 LOG_ERROR("Target not halted");
690 return ERROR_TARGET_NOT_HALTED
;
694 return ERROR_FLASH_BANK_NOT_PROBED
;
696 int not_protected
= 0;
697 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
698 if (bank
->sectors
[i
].is_protected
== 1)
699 LOG_WARNING("Flash sector %u is protected", i
);
704 if (!not_protected
) {
705 LOG_ERROR("All pages protected");
709 /* Prepare to issue flash operation */
710 retval
= max32xxx_flash_op_pre(bank
);
712 if (retval
!= ERROR_OK
)
715 /* Write mass erase code */
716 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
717 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
718 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
720 /* Issue mass erase command */
722 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
724 /* Wait until erase complete */
727 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
728 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
731 LOG_ERROR("Timed out waiting for flash mass erase");
732 return ERROR_FLASH_OPERATION_FAILED
;
735 /* Check access violations */
736 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
737 if (flsh_int
& FLSH_INT_AF
) {
738 LOG_ERROR("Error mass erasing");
739 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
740 return ERROR_FLASH_OPERATION_FAILED
;
743 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
749 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
751 struct flash_bank
*bank
;
752 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
755 command_print(CMD
, "max32xxx mass_erase <bank>");
759 if (retval
!= ERROR_OK
)
762 if (max32xxx_mass_erase(bank
) == ERROR_OK
)
763 command_print(CMD
, "max32xxx mass erase complete");
765 command_print(CMD
, "max32xxx mass erase failed");
770 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
772 struct flash_bank
*bank
;
774 struct max32xxx_flash_bank
*info
;
778 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
782 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
783 if (retval
!= ERROR_OK
)
785 info
= bank
->driver_priv
;
787 /* Convert the range to the page numbers */
788 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
789 LOG_WARNING("Error parsing address");
790 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
793 /* Mask off the top portion on the address */
794 addr
= (addr
& 0x0FFFFFFF);
796 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
797 LOG_WARNING("Error parsing length");
798 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
802 /* Check the address is in the range of the flash */
803 if ((addr
+len
) >= info
->flash_size
)
804 return ERROR_FLASH_SECTOR_INVALID
;
809 /* Convert the address and length to the page boundaries */
810 addr
= addr
- (addr
% info
->sector_size
);
811 if (len
% info
->sector_size
)
812 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
814 /* Convert the address and length to page numbers */
815 addr
= (addr
/ info
->sector_size
);
816 len
= addr
+ (len
/ info
->sector_size
) - 1;
818 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
819 command_print(CMD
, "max32xxx protection set complete");
821 command_print(CMD
, "max32xxx protection set failed");
826 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
828 struct flash_bank
*bank
;
830 struct max32xxx_flash_bank
*info
;
834 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
838 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
839 if (retval
!= ERROR_OK
)
841 info
= bank
->driver_priv
;
843 /* Convert the range to the page numbers */
844 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
845 LOG_WARNING("Error parsing address");
846 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
849 /* Mask off the top portion on the address */
850 addr
= (addr
& 0x0FFFFFFF);
852 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
853 LOG_WARNING("Error parsing length");
854 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
858 /* Check the address is in the range of the flash */
859 if ((addr
+len
) >= info
->flash_size
)
860 return ERROR_FLASH_SECTOR_INVALID
;
865 /* Convert the address and length to the page boundaries */
866 addr
= addr
- (addr
% info
->sector_size
);
867 if (len
% info
->sector_size
)
868 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
870 /* Convert the address and length to page numbers */
871 addr
= (addr
/ info
->sector_size
);
872 len
= addr
+ (len
/ info
->sector_size
) - 1;
874 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
875 command_print(CMD
, "max32xxx protection clear complete");
877 command_print(CMD
, "max32xxx protection clear failed");
882 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
884 struct flash_bank
*bank
;
886 struct max32xxx_flash_bank
*info
;
889 command_print(CMD
, "max32xxx protection_check <bank>");
893 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
894 if (retval
!= ERROR_OK
)
896 info
= bank
->driver_priv
;
898 /* Update the protection array */
899 retval
= max32xxx_protect_check(bank
);
900 if (retval
!= ERROR_OK
) {
901 LOG_WARNING("Error updating the protection array");
905 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
906 for (unsigned i
= 0; i
< bank
->num_sectors
; i
+= 4) {
907 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",
908 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
909 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
910 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
911 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
917 static const struct command_registration max32xxx_exec_command_handlers
[] = {
919 .name
= "mass_erase",
920 .handler
= max32xxx_handle_mass_erase_command
,
921 .mode
= COMMAND_EXEC
,
923 .help
= "mass erase flash",
926 .name
= "protection_set",
927 .handler
= max32xxx_handle_protection_set_command
,
928 .mode
= COMMAND_EXEC
,
929 .usage
= "bank_id addr size",
930 .help
= "set flash protection for address range",
933 .name
= "protection_clr",
934 .handler
= max32xxx_handle_protection_clr_command
,
935 .mode
= COMMAND_EXEC
,
936 .usage
= "bank_id addr size",
937 .help
= "clear flash protection for address range",
940 .name
= "protection_check",
941 .handler
= max32xxx_handle_protection_check_command
,
942 .mode
= COMMAND_EXEC
,
944 .help
= "check flash protection",
946 COMMAND_REGISTRATION_DONE
949 static const struct command_registration max32xxx_command_handlers
[] = {
952 .mode
= COMMAND_EXEC
,
953 .help
= "max32xxx flash command group",
954 .chain
= max32xxx_exec_command_handlers
,
957 COMMAND_REGISTRATION_DONE
960 const struct flash_driver max32xxx_flash
= {
962 .commands
= max32xxx_command_handlers
,
963 .flash_bank_command
= max32xxx_flash_bank_command
,
964 .erase
= max32xxx_erase
,
965 .protect
= max32xxx_protect
,
966 .write
= max32xxx_write
,
967 .read
= default_flash_read
,
968 .probe
= max32xxx_probe
,
969 .auto_probe
= max32xxx_probe
,
970 .erase_check
= default_flash_blank_check
,
971 .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)