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 <helper/binarybuffer.h>
25 #include <target/algorithm.h>
26 #include <target/armv7m.h>
28 /* Register Addresses */
29 #define FLSH_ADDR 0x000
30 #define FLSH_CLKDIV 0x004
32 #define PR1E_ADDR 0x00C
33 #define PR2S_ADDR 0x010
34 #define PR2E_ADDR 0x014
35 #define PR3S_ADDR 0x018
36 #define PR3E_ADDR 0x01C
38 #define FLSH_INT 0x024
39 #define FLSH_DATA0 0x030
40 #define FLSH_DATA1 0x034
41 #define FLSH_DATA2 0x038
42 #define FLSH_DATA3 0x03C
43 #define FLSH_BL_CTRL 0x170
44 #define FLSH_PROT 0x300
46 #define ARM_PID_REG 0xE00FFFE0
47 #define MAX326XX_ID_REG 0x40000838
49 /* Register settings */
50 #define FLSH_INT_AF 0x00000002
52 #define FLSH_CN_UNLOCK_MASK 0xF0000000
53 #define FLSH_CN_UNLOCK_VALUE 0x20000000
55 #define FLSH_CN_PEND 0x01000000
57 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
58 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
59 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
61 #define FLSH_CN_PGE 0x00000004
62 #define FLSH_CN_ME 0x00000002
63 #define FLSH_CN_WR 0x00000001
64 #define FLASH_BL_CTRL_23 0x00020000
65 #define FLASH_BL_CTRL_IFREN 0x00000001
67 #define ARM_PID_DEFAULT_CM3 0xB4C3
68 #define ARM_PID_DEFAULT_CM4 0xB4C4
69 #define MAX326XX_ID 0x4D
71 static int max32xxx_mass_erase(struct flash_bank
*bank
);
73 struct max32xxx_flash_bank
{
76 unsigned int flash_size
;
77 unsigned int flc_base
;
78 unsigned int sector_size
;
79 unsigned int clkdiv_value
;
81 unsigned int burst_size_bits
;
84 /* see contrib/loaders/flash/max32xxx/max32xxx.s for src */
85 static const uint8_t write_code
[] = {
86 #include "../../../contrib/loaders/flash/max32xxx/max32xxx.inc"
89 /* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
90 flash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]
92 FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command
)
94 struct max32xxx_flash_bank
*info
;
97 LOG_WARNING("incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
98 return ERROR_FLASH_BANK_INVALID
;
101 info
= calloc(sizeof(struct max32xxx_flash_bank
), 1);
102 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], info
->flash_size
);
103 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[6], info
->flc_base
);
104 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[7], info
->sector_size
);
105 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[8], info
->clkdiv_value
);
108 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[9], info
->burst_size_bits
);
110 info
->burst_size_bits
= 32;
113 bank
->driver_priv
= info
;
117 static int get_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
119 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
122 return ERROR_FLASH_BANK_NOT_PROBED
;
124 command_print_sameline(cmd
, "\nMaxim Integrated max32xxx flash driver\n");
128 /***************************************************************************
130 ***************************************************************************/
132 static int max32xxx_flash_op_pre(struct flash_bank
*bank
)
134 struct target
*target
= bank
->target
;
135 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
139 /* Check if the flash controller is busy */
140 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
141 if (flsh_cn
& (FLSH_CN_PEND
| FLSH_CN_ERASE_CODE_MASK
| FLSH_CN_PGE
|
142 FLSH_CN_ME
| FLSH_CN_WR
))
143 return ERROR_FLASH_BUSY
;
145 /* Refresh flash controller timing */
146 target_write_u32(target
, info
->flc_base
+ FLSH_CLKDIV
, info
->clkdiv_value
);
148 /* Clear and disable flash programming interrupts */
149 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &info
->int_state
);
150 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0x00000000);
152 /* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
153 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
154 LOG_ERROR("Read failure on FLSH_BL_CTRL");
157 if (bootloader
& FLASH_BL_CTRL_23
) {
158 LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
159 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
160 LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
161 bootloader
&= ~(FLASH_BL_CTRL_IFREN
);
162 if (target_write_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, bootloader
) != ERROR_OK
) {
163 LOG_ERROR("Write failure on FLSH_BL_CTRL");
166 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
167 LOG_ERROR("Read failure on FLSH_BL_CTRL");
170 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
172 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
178 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
179 flsh_cn
|= FLSH_CN_UNLOCK_VALUE
;
180 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
182 /* Confirm flash is unlocked */
183 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
184 if ((flsh_cn
& FLSH_CN_UNLOCK_VALUE
) != FLSH_CN_UNLOCK_VALUE
)
190 static int max32xxx_flash_op_post(struct flash_bank
*bank
)
192 struct target
*target
= bank
->target
;
193 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
196 /* Restore flash programming interrupts */
197 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, info
->int_state
);
200 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
201 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
202 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
206 static int max32xxx_protect_check(struct flash_bank
*bank
)
208 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
209 struct target
*target
= bank
->target
;
213 return ERROR_FLASH_BANK_NOT_PROBED
;
215 if (!info
->max326xx
) {
216 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
217 bank
->sectors
[i
].is_protected
= -1;
219 return ERROR_FLASH_OPER_UNSUPPORTED
;
222 /* Check the protection */
223 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++) {
225 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ ((i
/32)*4), &temp_reg
);
227 if (temp_reg
& (0x1 << i
%32))
228 bank
->sectors
[i
].is_protected
= 1;
230 bank
->sectors
[i
].is_protected
= 0;
235 static int max32xxx_erase(struct flash_bank
*bank
, unsigned int first
,
238 uint32_t flsh_cn
, flsh_int
;
239 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
240 struct target
*target
= bank
->target
;
244 if (bank
->target
->state
!= TARGET_HALTED
) {
245 LOG_ERROR("Target not halted");
246 return ERROR_TARGET_NOT_HALTED
;
250 return ERROR_FLASH_BANK_NOT_PROBED
;
252 if ((last
< first
) || (last
>= bank
->num_sectors
))
253 return ERROR_FLASH_SECTOR_INVALID
;
255 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
256 return max32xxx_mass_erase(bank
);
258 /* Prepare to issue flash operation */
259 retval
= max32xxx_flash_op_pre(bank
);
261 if (retval
!= ERROR_OK
)
265 for (unsigned int banknr
= first
; banknr
<= last
; banknr
++) {
267 /* Check the protection */
268 if (bank
->sectors
[banknr
].is_protected
== 1) {
269 LOG_WARNING("Flash sector %u is protected", banknr
);
274 /* Address is first word in page */
275 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, banknr
* info
->sector_size
);
277 /* Write page erase code */
278 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
279 flsh_cn
|= FLSH_CN_ERASE_CODE_PGE
;
280 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
282 /* Issue page erase command */
284 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
286 /* Wait until erase complete */
289 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
290 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
293 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
294 banknr
* info
->sector_size
);
295 return ERROR_FLASH_OPERATION_FAILED
;
298 /* Check access violations */
299 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
300 if (flsh_int
& FLSH_INT_AF
) {
301 LOG_ERROR("Error erasing flash page %i", banknr
);
302 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
303 max32xxx_flash_op_post(bank
);
304 return ERROR_FLASH_OPERATION_FAILED
;
309 LOG_ERROR("All pages protected %u to %u", first
, last
);
310 max32xxx_flash_op_post(bank
);
314 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
320 static int max32xxx_protect(struct flash_bank
*bank
, int set
,
321 unsigned int first
, unsigned int last
)
323 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
324 struct target
*target
= bank
->target
;
327 if (bank
->target
->state
!= TARGET_HALTED
) {
328 LOG_ERROR("Target not halted");
329 return ERROR_TARGET_NOT_HALTED
;
333 return ERROR_FLASH_BANK_NOT_PROBED
;
336 return ERROR_FLASH_OPER_UNSUPPORTED
;
338 if ((last
< first
) || (last
>= bank
->num_sectors
))
339 return ERROR_FLASH_SECTOR_INVALID
;
341 /* Setup the protection on the pages given */
342 for (unsigned int page
= first
; page
<= last
; page
++) {
344 /* Set the write/erase bit for this page */
345 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
346 temp_reg
|= (0x1 << page
%32);
347 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
348 bank
->sectors
[page
].is_protected
= 1;
350 /* Clear the write/erase bit for this page */
351 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
352 temp_reg
&= ~(0x1 << page
%32);
353 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
354 bank
->sectors
[page
].is_protected
= 0;
361 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
362 uint32_t offset
, uint32_t wcount
)
364 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
365 struct target
*target
= bank
->target
;
366 uint32_t buffer_size
= 16384;
367 struct working_area
*source
;
368 struct working_area
*write_algorithm
;
369 uint32_t address
= bank
->base
+ offset
;
370 struct reg_param reg_params
[5];
371 struct armv7m_algorithm armv7m_info
;
372 int retval
= ERROR_OK
;
373 /* power of two, and multiple of word size */
374 static const unsigned buf_min
= 128;
376 /* for small buffers it's faster not to download an algorithm */
377 if (wcount
* 4 < buf_min
)
378 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
380 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
381 bank
, buffer
, offset
, wcount
);
383 /* flash write code */
384 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
385 LOG_DEBUG("no working area for block memory writes");
386 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
389 /* plus a buffer big enough for this data */
390 if (wcount
* 4 < buffer_size
)
391 buffer_size
= wcount
* 4;
394 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
397 if (buffer_size
<= buf_min
) {
398 target_free_working_area(target
, write_algorithm
);
399 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
402 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
403 target_name(target
), (unsigned) buffer_size
);
406 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
409 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
410 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
411 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
412 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
413 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
414 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
415 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
417 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
418 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
419 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
420 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
421 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
422 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
423 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
425 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
426 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
428 target_free_working_area(target
, write_algorithm
);
429 target_free_working_area(target
, source
);
430 destroy_reg_param(®_params
[0]);
431 destroy_reg_param(®_params
[1]);
432 destroy_reg_param(®_params
[2]);
433 destroy_reg_param(®_params
[3]);
434 destroy_reg_param(®_params
[4]);
438 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
439 uint32_t offset
, uint32_t count
)
441 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
442 struct target
*target
= bank
->target
;
443 uint32_t flsh_cn
, flsh_int
;
444 uint32_t address
= offset
;
445 uint32_t remaining
= count
;
446 uint32_t words_remaining
;
450 if (bank
->target
->state
!= TARGET_HALTED
) {
451 LOG_ERROR("Target not halted");
452 return ERROR_TARGET_NOT_HALTED
;
455 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
456 bank
, buffer
, offset
, count
);
459 return ERROR_FLASH_BANK_NOT_PROBED
;
462 LOG_WARNING("offset size must be word aligned");
463 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
466 if (offset
+ count
> bank
->size
)
467 return ERROR_FLASH_DST_OUT_OF_BANK
;
469 /* Prepare to issue flash operation */
470 retval
= max32xxx_flash_op_pre(bank
);
472 if (retval
!= ERROR_OK
)
475 if (remaining
>= 4) {
476 /* write in 32-bit units */
477 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
478 flsh_cn
&= 0xF7FFFFFF;
479 flsh_cn
|= 0x00000010;
480 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
482 /* try using a block write */
483 words_remaining
= remaining
/ 4;
484 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
486 if (retval
!= ERROR_OK
) {
487 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
488 LOG_DEBUG("writing flash word-at-a-time");
490 max32xxx_flash_op_post(bank
);
491 return ERROR_FLASH_OPERATION_FAILED
;
494 /* all 32-bit words have been written */
495 buffer
+= words_remaining
* 4;
496 address
+= words_remaining
* 4;
497 remaining
-= words_remaining
* 4;
501 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
502 /* write in 32-bit units until we are 128-bit aligned */
503 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
504 flsh_cn
&= 0xF7FFFFFF;
505 flsh_cn
|= 0x00000010;
506 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
508 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
509 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
510 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
511 flsh_cn
|= 0x00000001;
512 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
513 /* Wait until flash operation is complete */
517 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
518 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
521 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
522 return ERROR_FLASH_OPERATION_FAILED
;
531 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
532 /* write in 128-bit bursts while we can */
533 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
535 flsh_cn
&= 0xFFFFFFEF;
536 flsh_cn
|= 0x08000000;
537 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
538 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
540 while (remaining
>= 16) {
541 if ((address
& 0xFFF) == 0)
542 LOG_DEBUG("Writing @ 0x%08" PRIx32
, address
);
544 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
545 flsh_cn
|= 0x00000001;
546 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
547 /* Wait until flash operation is complete */
551 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
552 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
555 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
556 return ERROR_FLASH_OPERATION_FAILED
;
565 if (remaining
>= 4) {
567 /* write in 32-bit units while we can */
568 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
569 flsh_cn
&= 0xF7FFFFFF;
570 flsh_cn
|= 0x00000010;
571 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
573 while (remaining
>= 4) {
574 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
575 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
576 flsh_cn
|= 0x00000001;
577 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
578 /* Wait until flash operation is complete */
582 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
583 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
586 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
587 return ERROR_FLASH_OPERATION_FAILED
;
597 /* write remaining bytes in a 32-bit unit */
598 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
599 flsh_cn
&= 0xF7FFFFFF;
600 flsh_cn
|= 0x00000010;
601 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
603 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
606 while (remaining
> 0) {
607 last_word
[i
++] = *buffer
;
612 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
613 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
614 flsh_cn
|= 0x00000001;
615 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
616 /* Wait until flash operation is complete */
620 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
621 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
624 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
625 return ERROR_FLASH_OPERATION_FAILED
;
629 /* Check access violations */
630 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
631 if (flsh_int
& FLSH_INT_AF
) {
632 LOG_ERROR("Flash Error writing 0x%" PRIx32
" bytes at 0x%08" PRIx32
, count
, offset
);
633 max32xxx_flash_op_post(bank
);
634 return ERROR_FLASH_OPERATION_FAILED
;
637 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
643 static int max32xxx_probe(struct flash_bank
*bank
)
645 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
646 struct target
*target
= bank
->target
;
652 /* provide this for the benefit of the NOR flash framework */
653 bank
->size
= info
->flash_size
;
654 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
655 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
657 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
658 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
659 bank
->sectors
[i
].size
= info
->sector_size
;
660 bank
->sectors
[i
].is_erased
= -1;
661 bank
->sectors
[i
].is_protected
= -1;
664 /* Probe to determine if this part is in the max326xx family */
666 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
667 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
668 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
669 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
671 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
672 uint32_t max326xx_id
;
673 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
674 LOG_DEBUG("max326xx_id = 0x%" PRIx32
, max326xx_id
);
675 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
676 if (max326xx_id
== MAX326XX_ID
)
679 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
681 /* Initialize the protection bits for each flash page */
682 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
683 LOG_WARNING("Flash protection not supported on this device");
689 static int max32xxx_mass_erase(struct flash_bank
*bank
)
691 struct target
*target
= NULL
;
692 struct max32xxx_flash_bank
*info
= NULL
;
693 uint32_t flsh_cn
, flsh_int
;
696 info
= bank
->driver_priv
;
697 target
= bank
->target
;
699 if (target
->state
!= TARGET_HALTED
) {
700 LOG_ERROR("Target not halted");
701 return ERROR_TARGET_NOT_HALTED
;
705 return ERROR_FLASH_BANK_NOT_PROBED
;
707 int not_protected
= 0;
708 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
709 if (bank
->sectors
[i
].is_protected
== 1)
710 LOG_WARNING("Flash sector %u is protected", i
);
715 if (!not_protected
) {
716 LOG_ERROR("All pages protected");
720 /* Prepare to issue flash operation */
721 retval
= max32xxx_flash_op_pre(bank
);
723 if (retval
!= ERROR_OK
)
726 /* Write mass erase code */
727 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
728 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
729 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
731 /* Issue mass erase command */
733 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
735 /* Wait until erase complete */
738 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
739 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
742 LOG_ERROR("Timed out waiting for flash mass erase");
743 return ERROR_FLASH_OPERATION_FAILED
;
746 /* Check access violations */
747 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
748 if (flsh_int
& FLSH_INT_AF
) {
749 LOG_ERROR("Error mass erasing");
750 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
751 return ERROR_FLASH_OPERATION_FAILED
;
754 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
760 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
762 struct flash_bank
*bank
;
763 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
766 command_print(CMD
, "max32xxx mass_erase <bank>");
770 if (retval
!= ERROR_OK
)
773 if (max32xxx_mass_erase(bank
) == ERROR_OK
)
774 command_print(CMD
, "max32xxx mass erase complete");
776 command_print(CMD
, "max32xxx mass erase failed");
781 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
783 struct flash_bank
*bank
;
785 struct max32xxx_flash_bank
*info
;
789 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
793 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
794 if (retval
!= ERROR_OK
)
796 info
= bank
->driver_priv
;
798 /* Convert the range to the page numbers */
799 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
800 LOG_WARNING("Error parsing address");
801 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
804 /* Mask off the top portion on the address */
805 addr
= (addr
& 0x0FFFFFFF);
807 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
808 LOG_WARNING("Error parsing length");
809 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
813 /* Check the address is in the range of the flash */
814 if ((addr
+len
) >= info
->flash_size
)
815 return ERROR_FLASH_SECTOR_INVALID
;
820 /* Convert the address and length to the page boundaries */
821 addr
= addr
- (addr
% info
->sector_size
);
822 if (len
% info
->sector_size
)
823 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
825 /* Convert the address and length to page numbers */
826 addr
= (addr
/ info
->sector_size
);
827 len
= addr
+ (len
/ info
->sector_size
) - 1;
829 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
830 command_print(CMD
, "max32xxx protection set complete");
832 command_print(CMD
, "max32xxx protection set failed");
837 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
839 struct flash_bank
*bank
;
841 struct max32xxx_flash_bank
*info
;
845 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
849 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
850 if (retval
!= ERROR_OK
)
852 info
= bank
->driver_priv
;
854 /* Convert the range to the page numbers */
855 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
856 LOG_WARNING("Error parsing address");
857 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
860 /* Mask off the top portion on the address */
861 addr
= (addr
& 0x0FFFFFFF);
863 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
864 LOG_WARNING("Error parsing length");
865 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
869 /* Check the address is in the range of the flash */
870 if ((addr
+len
) >= info
->flash_size
)
871 return ERROR_FLASH_SECTOR_INVALID
;
876 /* Convert the address and length to the page boundaries */
877 addr
= addr
- (addr
% info
->sector_size
);
878 if (len
% info
->sector_size
)
879 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
881 /* Convert the address and length to page numbers */
882 addr
= (addr
/ info
->sector_size
);
883 len
= addr
+ (len
/ info
->sector_size
) - 1;
885 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
886 command_print(CMD
, "max32xxx protection clear complete");
888 command_print(CMD
, "max32xxx protection clear failed");
893 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
895 struct flash_bank
*bank
;
897 struct max32xxx_flash_bank
*info
;
900 command_print(CMD
, "max32xxx protection_check <bank>");
904 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
905 if (retval
!= ERROR_OK
)
907 info
= bank
->driver_priv
;
909 /* Update the protection array */
910 retval
= max32xxx_protect_check(bank
);
911 if (retval
!= ERROR_OK
) {
912 LOG_WARNING("Error updating the protection array");
916 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
917 for (unsigned i
= 0; i
< bank
->num_sectors
; i
+= 4) {
918 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",
919 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
920 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
921 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
922 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
928 static const struct command_registration max32xxx_exec_command_handlers
[] = {
930 .name
= "mass_erase",
931 .handler
= max32xxx_handle_mass_erase_command
,
932 .mode
= COMMAND_EXEC
,
934 .help
= "mass erase flash",
937 .name
= "protection_set",
938 .handler
= max32xxx_handle_protection_set_command
,
939 .mode
= COMMAND_EXEC
,
940 .usage
= "bank_id addr size",
941 .help
= "set flash protection for address range",
944 .name
= "protection_clr",
945 .handler
= max32xxx_handle_protection_clr_command
,
946 .mode
= COMMAND_EXEC
,
947 .usage
= "bank_id addr size",
948 .help
= "clear flash protection for address range",
951 .name
= "protection_check",
952 .handler
= max32xxx_handle_protection_check_command
,
953 .mode
= COMMAND_EXEC
,
955 .help
= "check flash protection",
957 COMMAND_REGISTRATION_DONE
960 static const struct command_registration max32xxx_command_handlers
[] = {
963 .mode
= COMMAND_EXEC
,
964 .help
= "max32xxx flash command group",
965 .chain
= max32xxx_exec_command_handlers
,
968 COMMAND_REGISTRATION_DONE
971 const struct flash_driver max32xxx_flash
= {
973 .commands
= max32xxx_command_handlers
,
974 .flash_bank_command
= max32xxx_flash_bank_command
,
975 .erase
= max32xxx_erase
,
976 .protect
= max32xxx_protect
,
977 .write
= max32xxx_write
,
978 .read
= default_flash_read
,
979 .probe
= max32xxx_probe
,
980 .auto_probe
= max32xxx_probe
,
981 .erase_check
= default_flash_blank_check
,
982 .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)