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
;
306 bank
->sectors
[banknr
].is_erased
= 1;
310 LOG_ERROR("All pages protected %u to %u", first
, last
);
311 max32xxx_flash_op_post(bank
);
315 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
321 static int max32xxx_protect(struct flash_bank
*bank
, int set
,
322 unsigned int first
, unsigned int last
)
324 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
325 struct target
*target
= bank
->target
;
328 if (bank
->target
->state
!= TARGET_HALTED
) {
329 LOG_ERROR("Target not halted");
330 return ERROR_TARGET_NOT_HALTED
;
334 return ERROR_FLASH_BANK_NOT_PROBED
;
337 return ERROR_FLASH_OPER_UNSUPPORTED
;
339 if ((last
< first
) || (last
>= bank
->num_sectors
))
340 return ERROR_FLASH_SECTOR_INVALID
;
342 /* Setup the protection on the pages given */
343 for (unsigned int page
= first
; page
<= last
; page
++) {
345 /* Set the write/erase bit for this page */
346 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
347 temp_reg
|= (0x1 << page
%32);
348 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
349 bank
->sectors
[page
].is_protected
= 1;
351 /* Clear the write/erase bit for this page */
352 target_read_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), &temp_reg
);
353 temp_reg
&= ~(0x1 << page
%32);
354 target_write_u32(target
, info
->flc_base
+ FLSH_PROT
+ (page
/32), temp_reg
);
355 bank
->sectors
[page
].is_protected
= 0;
362 static int max32xxx_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
363 uint32_t offset
, uint32_t wcount
)
365 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
366 struct target
*target
= bank
->target
;
367 uint32_t buffer_size
= 16384;
368 struct working_area
*source
;
369 struct working_area
*write_algorithm
;
370 uint32_t address
= bank
->base
+ offset
;
371 struct reg_param reg_params
[5];
372 struct armv7m_algorithm armv7m_info
;
373 int retval
= ERROR_OK
;
374 /* power of two, and multiple of word size */
375 static const unsigned buf_min
= 128;
377 /* for small buffers it's faster not to download an algorithm */
378 if (wcount
* 4 < buf_min
)
379 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
381 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
382 bank
, buffer
, offset
, wcount
);
384 /* flash write code */
385 if (target_alloc_working_area(target
, sizeof(write_code
), &write_algorithm
) != ERROR_OK
) {
386 LOG_DEBUG("no working area for block memory writes");
387 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
390 /* plus a buffer big enough for this data */
391 if (wcount
* 4 < buffer_size
)
392 buffer_size
= wcount
* 4;
395 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
398 if (buffer_size
<= buf_min
) {
399 target_free_working_area(target
, write_algorithm
);
400 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
403 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
404 target_name(target
), (unsigned) buffer_size
);
407 target_write_buffer(target
, write_algorithm
->address
, sizeof(write_code
),
410 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
411 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
412 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
413 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
414 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
415 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
416 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
418 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
419 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
420 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
421 buf_set_u32(reg_params
[3].value
, 0, 32, wcount
);
422 buf_set_u32(reg_params
[4].value
, 0, 32, info
->flc_base
);
423 retval
= target_run_flash_async_algorithm(target
, buffer
, wcount
, 4, 0, NULL
,
424 5, reg_params
, source
->address
, source
->size
, write_algorithm
->address
, 0, &armv7m_info
);
426 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
427 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval
);
429 target_free_working_area(target
, write_algorithm
);
430 target_free_working_area(target
, source
);
431 destroy_reg_param(®_params
[0]);
432 destroy_reg_param(®_params
[1]);
433 destroy_reg_param(®_params
[2]);
434 destroy_reg_param(®_params
[3]);
435 destroy_reg_param(®_params
[4]);
439 static int max32xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
440 uint32_t offset
, uint32_t count
)
442 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
443 struct target
*target
= bank
->target
;
444 uint32_t flsh_cn
, flsh_int
;
445 uint32_t address
= offset
;
446 uint32_t remaining
= count
;
447 uint32_t words_remaining
;
451 if (bank
->target
->state
!= TARGET_HALTED
) {
452 LOG_ERROR("Target not halted");
453 return ERROR_TARGET_NOT_HALTED
;
456 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
457 bank
, buffer
, offset
, count
);
460 return ERROR_FLASH_BANK_NOT_PROBED
;
463 LOG_WARNING("offset size must be word aligned");
464 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
467 if (offset
+ count
> bank
->size
)
468 return ERROR_FLASH_DST_OUT_OF_BANK
;
470 /* Prepare to issue flash operation */
471 retval
= max32xxx_flash_op_pre(bank
);
473 if (retval
!= ERROR_OK
)
476 if (remaining
>= 4) {
477 /* write in 32-bit units */
478 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
479 flsh_cn
&= 0xF7FFFFFF;
480 flsh_cn
|= 0x00000010;
481 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
483 /* try using a block write */
484 words_remaining
= remaining
/ 4;
485 retval
= max32xxx_write_block(bank
, buffer
, offset
, words_remaining
);
487 if (retval
!= ERROR_OK
) {
488 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
489 LOG_DEBUG("writing flash word-at-a-time");
491 max32xxx_flash_op_post(bank
);
492 return ERROR_FLASH_OPERATION_FAILED
;
495 /* all 32-bit words have been written */
496 buffer
+= words_remaining
* 4;
497 address
+= words_remaining
* 4;
498 remaining
-= words_remaining
* 4;
502 if ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
503 /* write in 32-bit units until we are 128-bit aligned */
504 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
505 flsh_cn
&= 0xF7FFFFFF;
506 flsh_cn
|= 0x00000010;
507 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
509 while ((remaining
>= 4) && ((address
& 0x1F) != 0)) {
510 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
511 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
512 flsh_cn
|= 0x00000001;
513 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
514 /* Wait until flash operation is complete */
518 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
519 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
522 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
523 return ERROR_FLASH_OPERATION_FAILED
;
532 if ((info
->burst_size_bits
== 128) && (remaining
>= 16)) {
533 /* write in 128-bit bursts while we can */
534 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
536 flsh_cn
&= 0xFFFFFFEF;
537 flsh_cn
|= 0x08000000;
538 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
539 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
541 while (remaining
>= 16) {
542 if ((address
& 0xFFF) == 0)
543 LOG_DEBUG("Writing @ 0x%08" PRIx32
, address
);
545 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 16, buffer
);
546 flsh_cn
|= 0x00000001;
547 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
548 /* Wait until flash operation is complete */
552 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
553 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
556 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
557 return ERROR_FLASH_OPERATION_FAILED
;
566 if (remaining
>= 4) {
568 /* write in 32-bit units while we can */
569 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
570 flsh_cn
&= 0xF7FFFFFF;
571 flsh_cn
|= 0x00000010;
572 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
574 while (remaining
>= 4) {
575 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
576 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, buffer
);
577 flsh_cn
|= 0x00000001;
578 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
579 /* Wait until flash operation is complete */
583 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
584 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
587 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
588 return ERROR_FLASH_OPERATION_FAILED
;
598 /* write remaining bytes in a 32-bit unit */
599 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
600 flsh_cn
&= 0xF7FFFFFF;
601 flsh_cn
|= 0x00000010;
602 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
604 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
607 while (remaining
> 0) {
608 last_word
[i
++] = *buffer
;
613 target_write_u32(target
, info
->flc_base
+ FLSH_ADDR
, address
);
614 target_write_buffer(target
, info
->flc_base
+ FLSH_DATA0
, 4, last_word
);
615 flsh_cn
|= 0x00000001;
616 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
617 /* Wait until flash operation is complete */
621 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
622 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
625 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32
, address
);
626 return ERROR_FLASH_OPERATION_FAILED
;
630 /* Check access violations */
631 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
632 if (flsh_int
& FLSH_INT_AF
) {
633 LOG_ERROR("Flash Error writing 0x%" PRIx32
" bytes at 0x%08" PRIx32
, count
, offset
);
634 max32xxx_flash_op_post(bank
);
635 return ERROR_FLASH_OPERATION_FAILED
;
638 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
644 static int max32xxx_probe(struct flash_bank
*bank
)
646 struct max32xxx_flash_bank
*info
= bank
->driver_priv
;
647 struct target
*target
= bank
->target
;
653 /* provide this for the benefit of the NOR flash framework */
654 bank
->size
= info
->flash_size
;
655 bank
->num_sectors
= info
->flash_size
/ info
->sector_size
;
656 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
658 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
659 bank
->sectors
[i
].offset
= i
* info
->sector_size
;
660 bank
->sectors
[i
].size
= info
->sector_size
;
661 bank
->sectors
[i
].is_erased
= -1;
662 bank
->sectors
[i
].is_protected
= -1;
665 /* Probe to determine if this part is in the max326xx family */
667 target_read_u32(target
, ARM_PID_REG
, &arm_id
[0]);
668 target_read_u32(target
, ARM_PID_REG
+4, &arm_id
[1]);
669 arm_pid
= (arm_id
[1] << 8) + arm_id
[0];
670 LOG_DEBUG("arm_pid = 0x%x", arm_pid
);
672 if ((arm_pid
== ARM_PID_DEFAULT_CM3
) || arm_pid
== ARM_PID_DEFAULT_CM4
) {
673 uint32_t max326xx_id
;
674 target_read_u32(target
, MAX326XX_ID_REG
, &max326xx_id
);
675 LOG_DEBUG("max326xx_id = 0x%" PRIx32
, max326xx_id
);
676 max326xx_id
= ((max326xx_id
& 0xFF000000) >> 24);
677 if (max326xx_id
== MAX326XX_ID
)
680 LOG_DEBUG("info->max326xx = %d", info
->max326xx
);
682 /* Initialize the protection bits for each flash page */
683 if (max32xxx_protect_check(bank
) == ERROR_FLASH_OPER_UNSUPPORTED
)
684 LOG_WARNING("Flash protection not supported on this device");
690 static int max32xxx_mass_erase(struct flash_bank
*bank
)
692 struct target
*target
= NULL
;
693 struct max32xxx_flash_bank
*info
= NULL
;
694 uint32_t flsh_cn
, flsh_int
;
697 info
= bank
->driver_priv
;
698 target
= bank
->target
;
700 if (target
->state
!= TARGET_HALTED
) {
701 LOG_ERROR("Target not halted");
702 return ERROR_TARGET_NOT_HALTED
;
706 return ERROR_FLASH_BANK_NOT_PROBED
;
708 int not_protected
= 0;
709 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
710 if (bank
->sectors
[i
].is_protected
== 1)
711 LOG_WARNING("Flash sector %u is protected", i
);
716 if (!not_protected
) {
717 LOG_ERROR("All pages protected");
721 /* Prepare to issue flash operation */
722 retval
= max32xxx_flash_op_pre(bank
);
724 if (retval
!= ERROR_OK
)
727 /* Write mass erase code */
728 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
729 flsh_cn
|= FLSH_CN_ERASE_CODE_ME
;
730 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
732 /* Issue mass erase command */
734 target_write_u32(target
, info
->flc_base
+ FLSH_CN
, flsh_cn
);
736 /* Wait until erase complete */
739 target_read_u32(target
, info
->flc_base
+ FLSH_CN
, &flsh_cn
);
740 } while ((--retry
> 0) && (flsh_cn
& FLSH_CN_PEND
));
743 LOG_ERROR("Timed out waiting for flash mass erase");
744 return ERROR_FLASH_OPERATION_FAILED
;
747 /* Check access violations */
748 target_read_u32(target
, info
->flc_base
+ FLSH_INT
, &flsh_int
);
749 if (flsh_int
& FLSH_INT_AF
) {
750 LOG_ERROR("Error mass erasing");
751 target_write_u32(target
, info
->flc_base
+ FLSH_INT
, 0);
752 return ERROR_FLASH_OPERATION_FAILED
;
755 if (max32xxx_flash_op_post(bank
) != ERROR_OK
)
761 COMMAND_HANDLER(max32xxx_handle_mass_erase_command
)
763 struct flash_bank
*bank
;
764 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
767 command_print(CMD
, "max32xxx mass_erase <bank>");
771 if (ERROR_OK
!= retval
)
774 if (max32xxx_mass_erase(bank
) == ERROR_OK
) {
775 /* set all sectors as erased */
776 for (unsigned i
= 0; i
< bank
->num_sectors
; i
++)
777 bank
->sectors
[i
].is_erased
= 1;
779 command_print(CMD
, "max32xxx mass erase complete");
781 command_print(CMD
, "max32xxx mass erase failed");
786 COMMAND_HANDLER(max32xxx_handle_protection_set_command
)
788 struct flash_bank
*bank
;
790 struct max32xxx_flash_bank
*info
;
794 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
798 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
799 if (ERROR_OK
!= retval
)
801 info
= bank
->driver_priv
;
803 /* Convert the range to the page numbers */
804 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
805 LOG_WARNING("Error parsing address");
806 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
809 /* Mask off the top portion on the address */
810 addr
= (addr
& 0x0FFFFFFF);
812 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
813 LOG_WARNING("Error parsing length");
814 command_print(CMD
, "max32xxx protection_set <bank> <addr> <size>");
818 /* Check the address is in the range of the flash */
819 if ((addr
+len
) >= info
->flash_size
)
820 return ERROR_FLASH_SECTOR_INVALID
;
825 /* Convert the address and length to the page boundaries */
826 addr
= addr
- (addr
% info
->sector_size
);
827 if (len
% info
->sector_size
)
828 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
830 /* Convert the address and length to page numbers */
831 addr
= (addr
/ info
->sector_size
);
832 len
= addr
+ (len
/ info
->sector_size
) - 1;
834 if (max32xxx_protect(bank
, 1, addr
, len
) == ERROR_OK
)
835 command_print(CMD
, "max32xxx protection set complete");
837 command_print(CMD
, "max32xxx protection set failed");
842 COMMAND_HANDLER(max32xxx_handle_protection_clr_command
)
844 struct flash_bank
*bank
;
846 struct max32xxx_flash_bank
*info
;
850 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
854 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
855 if (ERROR_OK
!= retval
)
857 info
= bank
->driver_priv
;
859 /* Convert the range to the page numbers */
860 if (1 != sscanf(CMD_ARGV
[1], "0x%"SCNx32
, &addr
)) {
861 LOG_WARNING("Error parsing address");
862 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
865 /* Mask off the top portion on the address */
866 addr
= (addr
& 0x0FFFFFFF);
868 if (1 != sscanf(CMD_ARGV
[2], "0x%"SCNx32
, &len
)) {
869 LOG_WARNING("Error parsing length");
870 command_print(CMD
, "max32xxx protection_clr <bank> <addr> <size>");
874 /* Check the address is in the range of the flash */
875 if ((addr
+len
) >= info
->flash_size
)
876 return ERROR_FLASH_SECTOR_INVALID
;
881 /* Convert the address and length to the page boundaries */
882 addr
= addr
- (addr
% info
->sector_size
);
883 if (len
% info
->sector_size
)
884 len
= len
+ info
->sector_size
- (len
% info
->sector_size
);
886 /* Convert the address and length to page numbers */
887 addr
= (addr
/ info
->sector_size
);
888 len
= addr
+ (len
/ info
->sector_size
) - 1;
890 if (max32xxx_protect(bank
, 0, addr
, len
) == ERROR_OK
)
891 command_print(CMD
, "max32xxx protection clear complete");
893 command_print(CMD
, "max32xxx protection clear failed");
898 COMMAND_HANDLER(max32xxx_handle_protection_check_command
)
900 struct flash_bank
*bank
;
902 struct max32xxx_flash_bank
*info
;
905 command_print(CMD
, "max32xxx protection_check <bank>");
909 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
910 if (ERROR_OK
!= retval
)
912 info
= bank
->driver_priv
;
914 /* Update the protection array */
915 retval
= max32xxx_protect_check(bank
);
916 if (ERROR_OK
!= retval
) {
917 LOG_WARNING("Error updating the protection array");
921 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
922 for (unsigned i
= 0; i
< bank
->num_sectors
; i
+= 4) {
923 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",
924 (i
+0), (i
+0)*info
->sector_size
, bank
->sectors
[(i
+0)].is_protected
,
925 (i
+1), (i
+1)*info
->sector_size
, bank
->sectors
[(i
+1)].is_protected
,
926 (i
+2), (i
+2)*info
->sector_size
, bank
->sectors
[(i
+2)].is_protected
,
927 (i
+3), (i
+3)*info
->sector_size
, bank
->sectors
[(i
+3)].is_protected
);
933 static const struct command_registration max32xxx_exec_command_handlers
[] = {
935 .name
= "mass_erase",
936 .handler
= max32xxx_handle_mass_erase_command
,
937 .mode
= COMMAND_EXEC
,
939 .help
= "mass erase flash",
942 .name
= "protection_set",
943 .handler
= max32xxx_handle_protection_set_command
,
944 .mode
= COMMAND_EXEC
,
945 .usage
= "bank_id addr size",
946 .help
= "set flash protection for address range",
949 .name
= "protection_clr",
950 .handler
= max32xxx_handle_protection_clr_command
,
951 .mode
= COMMAND_EXEC
,
952 .usage
= "bank_id addr size",
953 .help
= "clear flash protection for address range",
956 .name
= "protection_check",
957 .handler
= max32xxx_handle_protection_check_command
,
958 .mode
= COMMAND_EXEC
,
960 .help
= "check flash protection",
962 COMMAND_REGISTRATION_DONE
965 static const struct command_registration max32xxx_command_handlers
[] = {
968 .mode
= COMMAND_EXEC
,
969 .help
= "max32xxx flash command group",
970 .chain
= max32xxx_exec_command_handlers
,
973 COMMAND_REGISTRATION_DONE
976 const struct flash_driver max32xxx_flash
= {
978 .commands
= max32xxx_command_handlers
,
979 .flash_bank_command
= max32xxx_flash_bank_command
,
980 .erase
= max32xxx_erase
,
981 .protect
= max32xxx_protect
,
982 .write
= max32xxx_write
,
983 .read
= default_flash_read
,
984 .probe
= max32xxx_probe
,
985 .auto_probe
= max32xxx_probe
,
986 .erase_check
= default_flash_blank_check
,
987 .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)