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
;
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(uint
, CMD_ARGV
[2], info
->flash_size
);
102 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[6], info
->flc_base
);
103 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[7], info
->sector_size
);
104 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[8], info
->clkdiv_value
);
107 COMMAND_PARSE_NUMBER(uint
, 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
, struct command_invocation
*cmd
)
118 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
121 return ERROR_FLASH_BANK_NOT_PROBED
;
123 command_print_sameline(cmd
, "\nMaxim Integrated max32xxx flash driver\n");
127 /***************************************************************************
129 ***************************************************************************/
131 static int max32xxx_flash_op_pre(struct flash_bank
*bank
)
133 struct target
*target
= bank
->target
;
134 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
138 /* Check if the flash controller is busy */
139 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
140 if (flsh_cn
& (FLSH_CN_PEND
| FLSH_CN_ERASE_CODE_MASK
| FLSH_CN_PGE
|
141 FLSH_CN_ME
| FLSH_CN_WR
))
142 return ERROR_FLASH_BUSY
;
144 /* Refresh flash controller timing */
145 target_write_u32(target
, info
->flc_base
+ FLSH_CLKDIV
, info
->clkdiv_value
);
147 /* Clear and disable flash programming interrupts */
148 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &info
->int_state
);
149 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0x00000000);
151 /* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
152 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
153 LOG_ERROR("Read failure on FLSH_BL_CTRL");
156 if (bootloader
& FLASH_BL_CTRL_23
) {
157 LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
158 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
159 LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
160 bootloader
&= ~(FLASH_BL_CTRL_IFREN
);
161 if (target_write_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, bootloader
) != ERROR_OK
) {
162 LOG_ERROR("Write failure on FLSH_BL_CTRL");
165 if (target_read_u32(target
, info
->flc_base
+ FLSH_BL_CTRL
, &bootloader
) != ERROR_OK
) {
166 LOG_ERROR("Read failure on FLSH_BL_CTRL");
169 if (bootloader
& FLASH_BL_CTRL_IFREN
) {
171 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
177 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
178 flsh_cn
|= FLSH_CN_UNLOCK_VALUE
;
179 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
181 /* Confirm flash is unlocked */
182 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
183 if ((flsh_cn
& FLSH_CN_UNLOCK_VALUE
) != FLSH_CN_UNLOCK_VALUE
)
189 static int max32xxx_flash_op_post(struct flash_bank
*bank
)
191 struct target
*target
= bank
->target
;
192 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
195 /* Restore flash programming interrupts */
196 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, info
->int_state
);
199 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
200 flsh_cn
&= ~FLSH_CN_UNLOCK_MASK
;
201 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
205 static int max32xxx_protect_check(struct flash_bank
*bank
)
207 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
208 struct target
*target
= bank
->target
;
212 return ERROR_FLASH_BANK_NOT_PROBED
;
214 if (!info
->max326xx
) {
215 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
216 bank
->sectors
[i
].is_protected
= -1;
218 return ERROR_FLASH_OPER_UNSUPPORTED
;
221 /* Check the protection */
222 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++) {
224 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ ((i
/32)*4), &temp_reg
);
226 if (temp_reg
& (0x1 << i
%32))
227 bank
->sectors
[i
].is_protected
= 1;
229 bank
->sectors
[i
].is_protected
= 0;
234 static int max32xxx_erase(struct flash_bank
*bank
, unsigned int first
,
237 uint32_t flsh_cn
, flsh_int
;
238 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
239 struct target
*target
= bank
->target
;
243 if (bank
->target
->state
!= TARGET_HALTED
) {
244 LOG_ERROR("Target not halted");
245 return ERROR_TARGET_NOT_HALTED
;
249 return ERROR_FLASH_BANK_NOT_PROBED
;
251 if ((last
< first
) || (last
>= bank
->num_sectors
))
252 return ERROR_FLASH_SECTOR_INVALID
;
254 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
255 return max32xxx_mass_erase(bank
);
257 /* Prepare to issue flash operation */
258 retval
= max32xxx_flash_op_pre(bank
);
260 if (retval
!= ERROR_OK
)
264 for (unsigned int banknr
= first
; banknr
<= last
; banknr
++) {
266 /* Check the protection */
267 if (bank
->sectors
[banknr
].is_protected
== 1) {
268 LOG_WARNING("Flash sector %u is protected", banknr
);
273 /* Address is first word in page */
274 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, banknr
* info
->sector_size
);
276 /* Write page erase code */
277 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
278 flsh_cn
|= FLSH_CN_ERASE_CODE_PGE
;
279 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
281 /* Issue page erase command */
283 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
285 /* Wait until erase complete */
288 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
289 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
292 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
293 banknr
* info
->sector_size
);
294 return ERROR_FLASH_OPERATION_FAILED
;
297 /* Check access violations */
298 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
299 if (flsh_int
& FLSH_INT_AF
) {
300 LOG_ERROR("Error erasing flash page %i", banknr
);
301 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
302 max32xxx_flash_op_post(bank
);
303 return ERROR_FLASH_OPERATION_FAILED
;
308 LOG_ERROR("All pages protected %u to %u", first
, last
);
309 max32xxx_flash_op_post(bank
);
313 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
319 static int max32xxx_protect(struct flash_bank
*bank
, int set
,
320 unsigned int first
, unsigned int last
)
322 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
323 struct target
*target
= bank
->target
;
326 if (bank
->target
->state
!= TARGET_HALTED
) {
327 LOG_ERROR("Target not halted");
328 return ERROR_TARGET_NOT_HALTED
;
332 return ERROR_FLASH_BANK_NOT_PROBED
;
335 return ERROR_FLASH_OPER_UNSUPPORTED
;
337 if ((last
< first
) || (last
>= bank
->num_sectors
))
338 return ERROR_FLASH_SECTOR_INVALID
;
340 /* Setup the protection on the pages given */
341 for (unsigned int page
= first
; page
<= last
; page
++) {
343 /* Set the write/erase bit for this page */
344 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
345 temp_reg
|= (0x1 << page
%32);
346 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
347 bank
->sectors
[page
].is_protected
= 1;
349 /* Clear 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
= 0;
360 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
361 uint32_t offset
, uint32_t wcount
)
363 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
364 struct target
*target
= bank
->target
;
365 uint32_t buffer_size
= 16384;
366 struct working_area
*source
;
367 struct working_area
*write_algorithm
;
368 uint32_t address
= bank
->base
+ offset
;
369 struct reg_param reg_params
[5];
370 struct armv7m_algorithm armv7m_info
;
371 int retval
= ERROR_OK
;
372 /* power of two, and multiple of word size */
373 static const unsigned buf_min
= 128;
375 /* for small buffers it's faster not to download an algorithm */
376 if (wcount
* 4 < buf_min
)
377 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
379 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
380 bank
, buffer
, offset
, wcount
);
382 /* flash write code */
383 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
384 LOG_DEBUG("no working area for block memory writes");
385 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
388 /* plus a buffer big enough for this data */
389 if (wcount
* 4 < buffer_size
)
390 buffer_size
= wcount
* 4;
393 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
396 if (buffer_size
<= buf_min
) {
397 target_free_working_area(target
, write_algorithm
);
398 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
401 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
402 target_name(target
), (unsigned) buffer_size
);
405 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
408 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
409 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
410 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
411 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
412 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
413 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
414 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
416 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
417 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
418 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
419 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
420 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
421 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
422 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
424 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
425 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
427 target_free_working_area(target
, write_algorithm
);
428 target_free_working_area(target
, source
);
429 destroy_reg_param(®_params
[0]);
430 destroy_reg_param(®_params
[1]);
431 destroy_reg_param(®_params
[2]);
432 destroy_reg_param(®_params
[3]);
433 destroy_reg_param(®_params
[4]);
437 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
438 uint32_t offset
, uint32_t count
)
440 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
441 struct target
*target
= bank
->target
;
442 uint32_t flsh_cn
, flsh_int
;
443 uint32_t address
= offset
;
444 uint32_t remaining
= count
;
445 uint32_t words_remaining
;
449 if (bank
->target
->state
!= TARGET_HALTED
) {
450 LOG_ERROR("Target not halted");
451 return ERROR_TARGET_NOT_HALTED
;
454 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
455 bank
, buffer
, offset
, count
);
458 return ERROR_FLASH_BANK_NOT_PROBED
;
461 LOG_WARNING("offset size must be word aligned");
462 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
465 if (offset
+ count
> bank
->size
)
466 return ERROR_FLASH_DST_OUT_OF_BANK
;
468 /* Prepare to issue flash operation */
469 retval
= max32xxx_flash_op_pre(bank
);
471 if (retval
!= ERROR_OK
)
474 if (remaining
>= 4) {
475 /* write in 32-bit units */
476 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
477 flsh_cn
&= 0xF7FFFFFF;
478 flsh_cn
|= 0x00000010;
479 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
481 /* try using a block write */
482 words_remaining
= remaining
/ 4;
483 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
485 if (retval
!= ERROR_OK
) {
486 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
487 LOG_DEBUG("writing flash word-at-a-time");
489 max32xxx_flash_op_post(bank
);
490 return ERROR_FLASH_OPERATION_FAILED
;
493 /* all 32-bit words have been written */
494 buffer
+= words_remaining
* 4;
495 address
+= words_remaining
* 4;
496 remaining
-= words_remaining
* 4;
500 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
501 /* write in 32-bit units until we are 128-bit aligned */
502 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
503 flsh_cn
&= 0xF7FFFFFF;
504 flsh_cn
|= 0x00000010;
505 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
507 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
508 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
509 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
510 flsh_cn
|= 0x00000001;
511 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
512 /* Wait until flash operation is complete */
516 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
517 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
520 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
521 return ERROR_FLASH_OPERATION_FAILED
;
530 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
531 /* write in 128-bit bursts while we can */
532 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
534 flsh_cn
&= 0xFFFFFFEF;
535 flsh_cn
|= 0x08000000;
536 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
537 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
539 while (remaining
>= 16) {
540 if ((address
& 0xFFF) == 0)
541 LOG_DEBUG("Writing @ 0x%08" PRIx32
, address
);
543 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
544 flsh_cn
|= 0x00000001;
545 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
546 /* Wait until flash operation is complete */
550 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
551 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
554 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
555 return ERROR_FLASH_OPERATION_FAILED
;
564 if (remaining
>= 4) {
566 /* write in 32-bit units while we can */
567 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
568 flsh_cn
&= 0xF7FFFFFF;
569 flsh_cn
|= 0x00000010;
570 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
572 while (remaining
>= 4) {
573 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
574 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
575 flsh_cn
|= 0x00000001;
576 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
577 /* Wait until flash operation is complete */
581 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
582 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
585 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
586 return ERROR_FLASH_OPERATION_FAILED
;
596 /* write remaining bytes in a 32-bit unit */
597 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
598 flsh_cn
&= 0xF7FFFFFF;
599 flsh_cn
|= 0x00000010;
600 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
602 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
605 while (remaining
> 0) {
606 last_word
[i
++] = *buffer
;
611 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
612 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
613 flsh_cn
|= 0x00000001;
614 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
615 /* Wait until flash operation is complete */
619 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
620 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
623 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
624 return ERROR_FLASH_OPERATION_FAILED
;
628 /* Check access violations */
629 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
630 if (flsh_int
& FLSH_INT_AF
) {
631 LOG_ERROR("Flash Error writing 0x%" PRIx32
" bytes at 0x%08" PRIx32
, count
, offset
);
632 max32xxx_flash_op_post(bank
);
633 return ERROR_FLASH_OPERATION_FAILED
;
636 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
642 static int max32xxx_probe(struct flash_bank
*bank
)
644 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
645 struct target
*target
= bank
->target
;
651 /* provide this for the benefit of the NOR flash framework */
652 bank
->size
= info
->flash_size
;
653 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
654 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
656 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
657 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
658 bank
->sectors
[i
].size
= info
->sector_size
;
659 bank
->sectors
[i
].is_erased
= -1;
660 bank
->sectors
[i
].is_protected
= -1;
663 /* Probe to determine if this part is in the max326xx family */
665 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
666 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
667 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
668 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
670 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
671 uint32_t max326xx_id
;
672 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
673 LOG_DEBUG("max326xx_id = 0x%" PRIx32
, max326xx_id
);
674 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
675 if (max326xx_id
== MAX326XX_ID
)
678 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
680 /* Initialize the protection bits for each flash page */
681 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
682 LOG_WARNING("Flash protection not supported on this device");
688 static int max32xxx_mass_erase(struct flash_bank
*bank
)
690 struct target
*target
= NULL
;
691 struct max32xxx_flash_bank
*info
= NULL
;
692 uint32_t flsh_cn
, flsh_int
;
695 info
= bank
->driver_priv
;
696 target
= bank
->target
;
698 if (target
->state
!= TARGET_HALTED
) {
699 LOG_ERROR("Target not halted");
700 return ERROR_TARGET_NOT_HALTED
;
704 return ERROR_FLASH_BANK_NOT_PROBED
;
706 int not_protected
= 0;
707 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
708 if (bank
->sectors
[i
].is_protected
== 1)
709 LOG_WARNING("Flash sector %u is protected", i
);
714 if (!not_protected
) {
715 LOG_ERROR("All pages protected");
719 /* Prepare to issue flash operation */
720 retval
= max32xxx_flash_op_pre(bank
);
722 if (retval
!= ERROR_OK
)
725 /* Write mass erase code */
726 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
727 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
728 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
730 /* Issue mass erase command */
732 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
734 /* Wait until erase complete */
737 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
738 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
741 LOG_ERROR("Timed out waiting for flash mass erase");
742 return ERROR_FLASH_OPERATION_FAILED
;
745 /* Check access violations */
746 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
747 if (flsh_int
& FLSH_INT_AF
) {
748 LOG_ERROR("Error mass erasing");
749 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
750 return ERROR_FLASH_OPERATION_FAILED
;
753 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
759 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
761 struct flash_bank
*bank
;
762 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
765 command_print(CMD
, "max32xxx mass_erase <bank>");
769 if (retval
!= ERROR_OK
)
772 if (max32xxx_mass_erase(bank
) == ERROR_OK
)
773 command_print(CMD
, "max32xxx mass erase complete");
775 command_print(CMD
, "max32xxx mass erase failed");
780 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
782 struct flash_bank
*bank
;
784 struct max32xxx_flash_bank
*info
;
788 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
792 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
793 if (retval
!= ERROR_OK
)
795 info
= bank
->driver_priv
;
797 /* Convert the range to the page numbers */
798 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
799 LOG_WARNING("Error parsing address");
800 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
803 /* Mask off the top portion on the address */
804 addr
= (addr
& 0x0FFFFFFF);
806 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
807 LOG_WARNING("Error parsing length");
808 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
812 /* Check the address is in the range of the flash */
813 if ((addr
+len
) >= info
->flash_size
)
814 return ERROR_FLASH_SECTOR_INVALID
;
819 /* Convert the address and length to the page boundaries */
820 addr
= addr
- (addr
% info
->sector_size
);
821 if (len
% info
->sector_size
)
822 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
824 /* Convert the address and length to page numbers */
825 addr
= (addr
/ info
->sector_size
);
826 len
= addr
+ (len
/ info
->sector_size
) - 1;
828 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
829 command_print(CMD
, "max32xxx protection set complete");
831 command_print(CMD
, "max32xxx protection set failed");
836 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
838 struct flash_bank
*bank
;
840 struct max32xxx_flash_bank
*info
;
844 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
848 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
849 if (retval
!= ERROR_OK
)
851 info
= bank
->driver_priv
;
853 /* Convert the range to the page numbers */
854 if (sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
) != 1) {
855 LOG_WARNING("Error parsing address");
856 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
859 /* Mask off the top portion on the address */
860 addr
= (addr
& 0x0FFFFFFF);
862 if (sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
) != 1) {
863 LOG_WARNING("Error parsing length");
864 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
868 /* Check the address is in the range of the flash */
869 if ((addr
+len
) >= info
->flash_size
)
870 return ERROR_FLASH_SECTOR_INVALID
;
875 /* Convert the address and length to the page boundaries */
876 addr
= addr
- (addr
% info
->sector_size
);
877 if (len
% info
->sector_size
)
878 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
880 /* Convert the address and length to page numbers */
881 addr
= (addr
/ info
->sector_size
);
882 len
= addr
+ (len
/ info
->sector_size
) - 1;
884 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
885 command_print(CMD
, "max32xxx protection clear complete");
887 command_print(CMD
, "max32xxx protection clear failed");
892 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
894 struct flash_bank
*bank
;
896 struct max32xxx_flash_bank
*info
;
899 command_print(CMD
, "max32xxx protection_check <bank>");
903 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
904 if (retval
!= ERROR_OK
)
906 info
= bank
->driver_priv
;
908 /* Update the protection array */
909 retval
= max32xxx_protect_check(bank
);
910 if (retval
!= ERROR_OK
) {
911 LOG_WARNING("Error updating the protection array");
915 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
916 for (unsigned i
= 0; i
< bank
->num_sectors
; i
+= 4) {
917 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",
918 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
919 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
920 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
921 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
927 static const struct command_registration max32xxx_exec_command_handlers
[] = {
929 .name
= "mass_erase",
930 .handler
= max32xxx_handle_mass_erase_command
,
931 .mode
= COMMAND_EXEC
,
933 .help
= "mass erase flash",
936 .name
= "protection_set",
937 .handler
= max32xxx_handle_protection_set_command
,
938 .mode
= COMMAND_EXEC
,
939 .usage
= "bank_id addr size",
940 .help
= "set flash protection for address range",
943 .name
= "protection_clr",
944 .handler
= max32xxx_handle_protection_clr_command
,
945 .mode
= COMMAND_EXEC
,
946 .usage
= "bank_id addr size",
947 .help
= "clear flash protection for address range",
950 .name
= "protection_check",
951 .handler
= max32xxx_handle_protection_check_command
,
952 .mode
= COMMAND_EXEC
,
954 .help
= "check flash protection",
956 COMMAND_REGISTRATION_DONE
959 static const struct command_registration max32xxx_command_handlers
[] = {
962 .mode
= COMMAND_EXEC
,
963 .help
= "max32xxx flash command group",
964 .chain
= max32xxx_exec_command_handlers
,
967 COMMAND_REGISTRATION_DONE
970 const struct flash_driver max32xxx_flash
= {
972 .commands
= max32xxx_command_handlers
,
973 .flash_bank_command
= max32xxx_flash_bank_command
,
974 .erase
= max32xxx_erase
,
975 .protect
= max32xxx_protect
,
976 .write
= max32xxx_write
,
977 .read
= default_flash_read
,
978 .probe
= max32xxx_probe
,
979 .auto_probe
= max32xxx_probe
,
980 .erase_check
= default_flash_blank_check
,
981 .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)