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 contrib/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
;
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 return ERROR_FLASH_BANK_NOT_PROBED
;
217 if (!info
->max326xx
) {
218 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
219 bank
->sectors
[i
].is_protected
= -1;
221 return ERROR_FLASH_OPER_UNSUPPORTED
;
224 /* Check the protection */
225 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++) {
227 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ ((i
/32)*4), &temp_reg
);
229 if (temp_reg
& (0x1 << i
%32))
230 bank
->sectors
[i
].is_protected
= 1;
232 bank
->sectors
[i
].is_protected
= 0;
237 static int max32xxx_erase(struct flash_bank
*bank
, unsigned int first
,
240 uint32_t flsh_cn
, flsh_int
;
241 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
242 struct target
*target
= bank
->target
;
246 if (bank
->target
->state
!= TARGET_HALTED
) {
247 LOG_ERROR("Target not halted");
248 return ERROR_TARGET_NOT_HALTED
;
252 return ERROR_FLASH_BANK_NOT_PROBED
;
254 if ((last
< first
) || (last
>= bank
->num_sectors
))
255 return ERROR_FLASH_SECTOR_INVALID
;
257 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
258 return max32xxx_mass_erase(bank
);
260 /* Prepare to issue flash operation */
261 retval
= max32xxx_flash_op_pre(bank
);
263 if (retval
!= ERROR_OK
)
267 for (unsigned int banknr
= first
; banknr
<= last
; banknr
++) {
269 /* Check the protection */
270 if (bank
->sectors
[banknr
].is_protected
== 1) {
271 LOG_WARNING("Flash sector %u is protected", banknr
);
276 /* Address is first word in page */
277 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, banknr
* info
->sector_size
);
279 /* Write page erase code */
280 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
281 flsh_cn
|= FLSH_CN_ERASE_CODE_PGE
;
282 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
284 /* Issue page erase command */
286 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
288 /* Wait until erase complete */
291 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
292 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
295 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
296 banknr
* info
->sector_size
);
297 return ERROR_FLASH_OPERATION_FAILED
;
300 /* Check access violations */
301 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
302 if (flsh_int
& FLSH_INT_AF
) {
303 LOG_ERROR("Error erasing flash page %i", banknr
);
304 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
305 max32xxx_flash_op_post(bank
);
306 return ERROR_FLASH_OPERATION_FAILED
;
309 bank
->sectors
[banknr
].is_erased
= 1;
313 LOG_ERROR("All pages protected %u to %u", first
, last
);
314 max32xxx_flash_op_post(bank
);
318 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
324 static int max32xxx_protect(struct flash_bank
*bank
, int set
,
325 unsigned int first
, unsigned int last
)
327 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
328 struct target
*target
= bank
->target
;
331 if (bank
->target
->state
!= TARGET_HALTED
) {
332 LOG_ERROR("Target not halted");
333 return ERROR_TARGET_NOT_HALTED
;
337 return ERROR_FLASH_BANK_NOT_PROBED
;
340 return ERROR_FLASH_OPER_UNSUPPORTED
;
342 if ((last
< first
) || (last
>= bank
->num_sectors
))
343 return ERROR_FLASH_SECTOR_INVALID
;
345 /* Setup the protection on the pages given */
346 for (unsigned int page
= first
; page
<= last
; page
++) {
348 /* Set the write/erase bit for this page */
349 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
350 temp_reg
|= (0x1 << page
%32);
351 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
352 bank
->sectors
[page
].is_protected
= 1;
354 /* Clear the write/erase bit for this page */
355 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
356 temp_reg
&= ~(0x1 << page
%32);
357 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
358 bank
->sectors
[page
].is_protected
= 0;
365 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
366 uint32_t offset
, uint32_t wcount
)
368 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
369 struct target
*target
= bank
->target
;
370 uint32_t buffer_size
= 16384;
371 struct working_area
*source
;
372 struct working_area
*write_algorithm
;
373 uint32_t address
= bank
->base
+ offset
;
374 struct reg_param reg_params
[5];
375 struct armv7m_algorithm armv7m_info
;
376 int retval
= ERROR_OK
;
377 /* power of two, and multiple of word size */
378 static const unsigned buf_min
= 128;
380 /* for small buffers it's faster not to download an algorithm */
381 if (wcount
* 4 < buf_min
)
382 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
384 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
385 bank
, buffer
, offset
, wcount
);
387 /* flash write code */
388 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
389 LOG_DEBUG("no working area for block memory writes");
390 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
393 /* plus a buffer big enough for this data */
394 if (wcount
* 4 < buffer_size
)
395 buffer_size
= wcount
* 4;
398 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
401 if (buffer_size
<= buf_min
) {
402 target_free_working_area(target
, write_algorithm
);
403 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
406 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
407 target_name(target
), (unsigned) buffer_size
);
410 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
413 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
414 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
415 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
416 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
417 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
418 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
419 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
421 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
422 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
423 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
424 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
425 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
426 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
427 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
429 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
430 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
432 target_free_working_area(target
, write_algorithm
);
433 target_free_working_area(target
, source
);
434 destroy_reg_param(®_params
[0]);
435 destroy_reg_param(®_params
[1]);
436 destroy_reg_param(®_params
[2]);
437 destroy_reg_param(®_params
[3]);
438 destroy_reg_param(®_params
[4]);
442 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
443 uint32_t offset
, uint32_t count
)
445 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
446 struct target
*target
= bank
->target
;
447 uint32_t flsh_cn
, flsh_int
;
448 uint32_t address
= offset
;
449 uint32_t remaining
= count
;
450 uint32_t words_remaining
;
454 if (bank
->target
->state
!= TARGET_HALTED
) {
455 LOG_ERROR("Target not halted");
456 return ERROR_TARGET_NOT_HALTED
;
459 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
460 bank
, buffer
, offset
, count
);
463 return ERROR_FLASH_BANK_NOT_PROBED
;
466 LOG_WARNING("offset size must be word aligned");
467 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
470 if (offset
+ count
> bank
->size
)
471 return ERROR_FLASH_DST_OUT_OF_BANK
;
473 /* Prepare to issue flash operation */
474 retval
= max32xxx_flash_op_pre(bank
);
476 if (retval
!= ERROR_OK
)
479 if (remaining
>= 4) {
480 /* write in 32-bit units */
481 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
482 flsh_cn
&= 0xF7FFFFFF;
483 flsh_cn
|= 0x00000010;
484 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
486 /* try using a block write */
487 words_remaining
= remaining
/ 4;
488 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
490 if (retval
!= ERROR_OK
) {
491 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
492 LOG_DEBUG("writing flash word-at-a-time");
494 max32xxx_flash_op_post(bank
);
495 return ERROR_FLASH_OPERATION_FAILED
;
498 /* all 32-bit words have been written */
499 buffer
+= words_remaining
* 4;
500 address
+= words_remaining
* 4;
501 remaining
-= words_remaining
* 4;
505 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
506 /* write in 32-bit units until we are 128-bit aligned */
507 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
508 flsh_cn
&= 0xF7FFFFFF;
509 flsh_cn
|= 0x00000010;
510 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
512 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
513 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
514 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
515 flsh_cn
|= 0x00000001;
516 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
517 /* Wait until flash operation is complete */
521 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
522 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
525 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
526 return ERROR_FLASH_OPERATION_FAILED
;
535 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
536 /* write in 128-bit bursts while we can */
537 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
539 flsh_cn
&= 0xFFFFFFEF;
540 flsh_cn
|= 0x08000000;
541 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
542 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
544 while (remaining
>= 16) {
545 if ((address
& 0xFFF) == 0)
546 LOG_DEBUG("Writing @ 0x%08x", address
);
548 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
549 flsh_cn
|= 0x00000001;
550 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
551 /* Wait until flash operation is complete */
555 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
556 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
559 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
560 return ERROR_FLASH_OPERATION_FAILED
;
569 if (remaining
>= 4) {
571 /* write in 32-bit units while we can */
572 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
573 flsh_cn
&= 0xF7FFFFFF;
574 flsh_cn
|= 0x00000010;
575 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
577 while (remaining
>= 4) {
578 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
579 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
580 flsh_cn
|= 0x00000001;
581 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
582 /* Wait until flash operation is complete */
586 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
587 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
590 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
591 return ERROR_FLASH_OPERATION_FAILED
;
601 /* write remaining bytes in a 32-bit unit */
602 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
603 flsh_cn
&= 0xF7FFFFFF;
604 flsh_cn
|= 0x00000010;
605 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
607 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
610 while (remaining
> 0) {
611 last_word
[i
++] = *buffer
;
616 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
617 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
618 flsh_cn
|= 0x00000001;
619 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
620 /* Wait until flash operation is complete */
624 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
625 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
628 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address
);
629 return ERROR_FLASH_OPERATION_FAILED
;
633 /* Check access violations */
634 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
635 if (flsh_int
& FLSH_INT_AF
) {
636 LOG_ERROR("Flash Error writing 0x%x bytes at 0x%08x", count
, offset
);
637 max32xxx_flash_op_post(bank
);
638 return ERROR_FLASH_OPERATION_FAILED
;
641 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
647 static int max32xxx_probe(struct flash_bank
*bank
)
649 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
650 struct target
*target
= bank
->target
;
656 /* provide this for the benefit of the NOR flash framework */
657 bank
->size
= info
->flash_size
;
658 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
659 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
661 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
662 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
663 bank
->sectors
[i
].size
= info
->sector_size
;
664 bank
->sectors
[i
].is_erased
= -1;
665 bank
->sectors
[i
].is_protected
= -1;
668 /* Probe to determine if this part is in the max326xx family */
670 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
671 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
672 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
673 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
675 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
676 uint32_t max326xx_id
;
677 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
678 LOG_DEBUG("max326xx_id = 0x%x", max326xx_id
);
679 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
680 if (max326xx_id
== MAX326XX_ID
)
683 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
685 /* Initialize the protection bits for each flash page */
686 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
687 LOG_WARNING("Flash protection not supported on this device");
693 static int max32xxx_mass_erase(struct flash_bank
*bank
)
695 struct target
*target
= NULL
;
696 struct max32xxx_flash_bank
*info
= NULL
;
697 uint32_t flsh_cn
, flsh_int
;
700 info
= bank
->driver_priv
;
701 target
= bank
->target
;
703 if (target
->state
!= TARGET_HALTED
) {
704 LOG_ERROR("Target not halted");
705 return ERROR_TARGET_NOT_HALTED
;
709 return ERROR_FLASH_BANK_NOT_PROBED
;
711 int not_protected
= 0;
712 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
713 if (bank
->sectors
[i
].is_protected
== 1)
714 LOG_WARNING("Flash sector %u is protected", i
);
719 if (!not_protected
) {
720 LOG_ERROR("All pages protected");
724 /* Prepare to issue flash operation */
725 retval
= max32xxx_flash_op_pre(bank
);
727 if (retval
!= ERROR_OK
)
730 /* Write mass erase code */
731 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
732 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
733 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
735 /* Issue mass erase command */
737 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
739 /* Wait until erase complete */
742 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
743 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
746 LOG_ERROR("Timed out waiting for flash mass erase");
747 return ERROR_FLASH_OPERATION_FAILED
;
750 /* Check access violations */
751 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
752 if (flsh_int
& FLSH_INT_AF
) {
753 LOG_ERROR("Error mass erasing");
754 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
755 return ERROR_FLASH_OPERATION_FAILED
;
758 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
764 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
766 struct flash_bank
*bank
;
767 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
770 command_print(CMD
, "max32xxx mass_erase <bank>");
774 if (ERROR_OK
!= retval
)
777 if (max32xxx_mass_erase(bank
) == ERROR_OK
) {
778 /* set all sectors as erased */
779 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
780 bank
->sectors
[i
].is_erased
= 1;
782 command_print(CMD
, "max32xxx mass erase complete");
784 command_print(CMD
, "max32xxx mass erase failed");
789 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
791 struct flash_bank
*bank
;
793 struct max32xxx_flash_bank
*info
;
797 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
801 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
802 if (ERROR_OK
!= retval
)
804 info
= bank
->driver_priv
;
806 /* Convert the range to the page numbers */
807 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
808 LOG_WARNING("Error parsing address");
809 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
812 /* Mask off the top portion on the address */
813 addr
= (addr
& 0x0FFFFFFF);
815 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
816 LOG_WARNING("Error parsing length");
817 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
821 /* Check the address is in the range of the flash */
822 if ((addr
+len
) >= info
->flash_size
)
823 return ERROR_FLASH_SECTOR_INVALID
;
828 /* Convert the address and length to the page boundaries */
829 addr
= addr
- (addr
% info
->sector_size
);
830 if (len
% info
->sector_size
)
831 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
833 /* Convert the address and length to page numbers */
834 addr
= (addr
/ info
->sector_size
);
835 len
= addr
+ (len
/ info
->sector_size
) - 1;
837 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
838 command_print(CMD
, "max32xxx protection set complete");
840 command_print(CMD
, "max32xxx protection set failed");
845 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
847 struct flash_bank
*bank
;
849 struct max32xxx_flash_bank
*info
;
853 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
857 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
858 if (ERROR_OK
!= retval
)
860 info
= bank
->driver_priv
;
862 /* Convert the range to the page numbers */
863 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
864 LOG_WARNING("Error parsing address");
865 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
868 /* Mask off the top portion on the address */
869 addr
= (addr
& 0x0FFFFFFF);
871 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
872 LOG_WARNING("Error parsing length");
873 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
877 /* Check the address is in the range of the flash */
878 if ((addr
+len
) >= info
->flash_size
)
879 return ERROR_FLASH_SECTOR_INVALID
;
884 /* Convert the address and length to the page boundaries */
885 addr
= addr
- (addr
% info
->sector_size
);
886 if (len
% info
->sector_size
)
887 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
889 /* Convert the address and length to page numbers */
890 addr
= (addr
/ info
->sector_size
);
891 len
= addr
+ (len
/ info
->sector_size
) - 1;
893 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
894 command_print(CMD
, "max32xxx protection clear complete");
896 command_print(CMD
, "max32xxx protection clear failed");
901 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
903 struct flash_bank
*bank
;
905 struct max32xxx_flash_bank
*info
;
908 command_print(CMD
, "max32xxx protection_check <bank>");
912 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
913 if (ERROR_OK
!= retval
)
915 info
= bank
->driver_priv
;
917 /* Update the protection array */
918 retval
= max32xxx_protect_check(bank
);
919 if (ERROR_OK
!= retval
) {
920 LOG_WARNING("Error updating the protection array");
924 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
925 for (unsigned i
= 0; i
< bank
->num_sectors
; i
+= 4) {
926 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",
927 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
928 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
929 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
930 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
936 static const struct command_registration max32xxx_exec_command_handlers
[] = {
938 .name
= "mass_erase",
939 .handler
= max32xxx_handle_mass_erase_command
,
940 .mode
= COMMAND_EXEC
,
942 .help
= "mass erase flash",
945 .name
= "protection_set",
946 .handler
= max32xxx_handle_protection_set_command
,
947 .mode
= COMMAND_EXEC
,
948 .usage
= "bank_id addr size",
949 .help
= "set flash protection for address range",
952 .name
= "protection_clr",
953 .handler
= max32xxx_handle_protection_clr_command
,
954 .mode
= COMMAND_EXEC
,
955 .usage
= "bank_id addr size",
956 .help
= "clear flash protection for address range",
959 .name
= "protection_check",
960 .handler
= max32xxx_handle_protection_check_command
,
961 .mode
= COMMAND_EXEC
,
963 .help
= "check flash protection",
965 COMMAND_REGISTRATION_DONE
968 static const struct command_registration max32xxx_command_handlers
[] = {
971 .mode
= COMMAND_EXEC
,
972 .help
= "max32xxx flash command group",
973 .chain
= max32xxx_exec_command_handlers
,
976 COMMAND_REGISTRATION_DONE
979 const struct flash_driver max32xxx_flash
= {
981 .commands
= max32xxx_command_handlers
,
982 .flash_bank_command
= max32xxx_flash_bank_command
,
983 .erase
= max32xxx_erase
,
984 .protect
= max32xxx_protect
,
985 .write
= max32xxx_write
,
986 .read
= default_flash_read
,
987 .probe
= max32xxx_probe
,
988 .auto_probe
= max32xxx_probe
,
989 .erase_check
= default_flash_blank_check
,
990 .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)