Constify struct flash_driver instances
[openocd.git] / src / flash / nor / max32xxx.c
blob12e3db9403530e942a7ab1872bf9e29106345ccf
1 /***************************************************************************
2 * Copyright (C) 2016 by Maxim Integrated *
3 * Kevin Gillespie <kevin.gillespie@maximintegrated.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
23 #include "imp.h"
24 #include <target/algorithm.h>
25 #include <target/armv7m.h>
27 /* Register Addresses */
28 #define FLSH_ADDR 0x000
29 #define FLSH_CLKDIV 0x004
30 #define FLSH_CN 0x008
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
36 #define FLSH_MD 0x020
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 {
73 int probed;
74 int max326xx;
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 contib/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;
95 if (CMD_ARGC < 9) {
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);
106 if (CMD_ARGC > 9)
107 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[9], info->burst_size_bits);
108 else
109 info->burst_size_bits = 32;
111 info->int_state = 0;
112 bank->driver_priv = info;
113 return ERROR_OK;
116 static int get_info(struct flash_bank *bank, char *buf, int buf_size)
118 int printed;
119 struct max32xxx_flash_bank *info = bank->driver_priv;
121 if (info->probed == 0)
122 return ERROR_FLASH_BANK_NOT_PROBED;
124 printed = snprintf(buf, buf_size, "\nMaxim Integrated max32xxx flash driver\n");
125 buf += printed;
126 buf_size -= printed;
127 return ERROR_OK;
130 /***************************************************************************
131 * flash operations
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;
138 uint32_t flsh_cn;
139 uint32_t bootloader;
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");
157 return ERROR_FAIL;
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");
166 return ERROR_FAIL;
168 if (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {
169 LOG_ERROR("Read failure on FLSH_BL_CTRL");
170 return ERROR_FAIL;
172 if (bootloader & FLASH_BL_CTRL_IFREN) {
173 /* Bummer */
174 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
179 /* Unlock flash */
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)
187 return ERROR_FAIL;
189 return ERROR_OK;
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;
196 uint32_t flsh_cn;
198 /* Restore flash programming interrupts */
199 target_write_u32(target, info->flc_base + FLSH_INT, info->int_state);
201 /* Lock flash */
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);
205 return ERROR_OK;
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;
212 int i;
213 uint32_t temp_reg;
215 if (info->probed == 0)
216 return ERROR_FLASH_BANK_NOT_PROBED;
218 if (!info->max326xx) {
219 for (i = 0; i < bank->num_sectors; i++)
220 bank->sectors[i].is_protected = -1;
222 return ERROR_FLASH_OPER_UNSUPPORTED;
225 /* Check the protection */
226 for (i = 0; i < bank->num_sectors; i++) {
227 if (i%32 == 0)
228 target_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);
230 if (temp_reg & (0x1 << i%32))
231 bank->sectors[i].is_protected = 1;
232 else
233 bank->sectors[i].is_protected = 0;
235 return ERROR_OK;
238 static int max32xxx_erase(struct flash_bank *bank, int first, int last)
240 int banknr;
241 uint32_t flsh_cn, flsh_int;
242 struct max32xxx_flash_bank *info = bank->driver_priv;
243 struct target *target = bank->target;
244 int retval;
245 int retry;
247 if (bank->target->state != TARGET_HALTED) {
248 LOG_ERROR("Target not halted");
249 return ERROR_TARGET_NOT_HALTED;
252 if (info->probed == 0)
253 return ERROR_FLASH_BANK_NOT_PROBED;
255 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
256 return ERROR_FLASH_SECTOR_INVALID;
258 if ((first == 0) && (last == (bank->num_sectors - 1)))
259 return max32xxx_mass_erase(bank);
261 /* Prepare to issue flash operation */
262 retval = max32xxx_flash_op_pre(bank);
264 if (retval != ERROR_OK)
265 return retval;
267 int erased = 0;
268 for (banknr = first; banknr <= last; banknr++) {
270 /* Check the protection */
271 if (bank->sectors[banknr].is_protected == 1) {
272 LOG_WARNING("Flash sector %d is protected", banknr);
273 continue;
274 } else
275 erased = 1;
277 /* Address is first word in page */
278 target_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);
280 /* Write page erase code */
281 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
282 flsh_cn |= FLSH_CN_ERASE_CODE_PGE;
283 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
285 /* Issue page erase command */
286 flsh_cn |= 0x4;
287 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
289 /* Wait until erase complete */
290 retry = 1000;
291 do {
292 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
293 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
295 if (retry <= 0) {
296 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
297 banknr * info->sector_size);
298 return ERROR_FLASH_OPERATION_FAILED;
301 /* Check access violations */
302 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
303 if (flsh_int & FLSH_INT_AF) {
304 LOG_ERROR("Error erasing flash page %i", banknr);
305 target_write_u32(target, info->flc_base + FLSH_INT, 0);
306 max32xxx_flash_op_post(bank);
307 return ERROR_FLASH_OPERATION_FAILED;
310 bank->sectors[banknr].is_erased = 1;
313 if (!erased) {
314 LOG_ERROR("All pages protected %d to %d", first, last);
315 max32xxx_flash_op_post(bank);
316 return ERROR_FAIL;
319 if (max32xxx_flash_op_post(bank) != ERROR_OK)
320 return ERROR_FAIL;
322 return ERROR_OK;
325 static int max32xxx_protect(struct flash_bank *bank, int set, int first, int last)
327 struct max32xxx_flash_bank *info = bank->driver_priv;
328 struct target *target = bank->target;
329 int page;
330 uint32_t temp_reg;
332 if (bank->target->state != TARGET_HALTED) {
333 LOG_ERROR("Target not halted");
334 return ERROR_TARGET_NOT_HALTED;
337 if (info->probed == 0)
338 return ERROR_FLASH_BANK_NOT_PROBED;
340 if (!info->max326xx)
341 return ERROR_FLASH_OPER_UNSUPPORTED;
343 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
344 return ERROR_FLASH_SECTOR_INVALID;
346 /* Setup the protection on the pages given */
347 for (page = first; page <= last; page++) {
348 if (set) {
349 /* Set 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 = 1;
354 } else {
355 /* Clear the write/erase bit for this page */
356 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
357 temp_reg &= ~(0x1 << page%32);
358 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
359 bank->sectors[page].is_protected = 0;
363 return ERROR_OK;
366 static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
367 uint32_t offset, uint32_t wcount)
369 struct max32xxx_flash_bank *info = bank->driver_priv;
370 struct target *target = bank->target;
371 uint32_t buffer_size = 16384;
372 struct working_area *source;
373 struct working_area *write_algorithm;
374 uint32_t address = bank->base + offset;
375 struct reg_param reg_params[5];
376 struct armv7m_algorithm armv7m_info;
377 int retval = ERROR_OK;
378 /* power of two, and multiple of word size */
379 static const unsigned buf_min = 128;
381 /* for small buffers it's faster not to download an algorithm */
382 if (wcount * 4 < buf_min)
383 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
385 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
386 bank, buffer, offset, wcount);
388 /* flash write code */
389 if (target_alloc_working_area(target, sizeof(write_code), &write_algorithm) != ERROR_OK) {
390 LOG_DEBUG("no working area for block memory writes");
391 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
394 /* plus a buffer big enough for this data */
395 if (wcount * 4 < buffer_size)
396 buffer_size = wcount * 4;
398 /* memory buffer */
399 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
400 buffer_size /= 2;
402 if (buffer_size <= buf_min) {
403 target_free_working_area(target, write_algorithm);
404 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
407 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
408 target_name(target), (unsigned) buffer_size);
411 target_write_buffer(target, write_algorithm->address, sizeof(write_code),
412 write_code);
414 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
415 armv7m_info.core_mode = ARM_MODE_THREAD;
416 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
417 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
418 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
419 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
420 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
422 buf_set_u32(reg_params[0].value, 0, 32, source->address);
423 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
424 buf_set_u32(reg_params[2].value, 0, 32, address);
425 buf_set_u32(reg_params[3].value, 0, 32, wcount);
426 buf_set_u32(reg_params[4].value, 0, 32, info->flc_base);
427 retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,
428 5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
430 if (retval == ERROR_FLASH_OPERATION_FAILED)
431 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
433 target_free_working_area(target, write_algorithm);
434 target_free_working_area(target, source);
435 destroy_reg_param(&reg_params[0]);
436 destroy_reg_param(&reg_params[1]);
437 destroy_reg_param(&reg_params[2]);
438 destroy_reg_param(&reg_params[3]);
439 destroy_reg_param(&reg_params[4]);
440 return retval;
443 static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
444 uint32_t offset, uint32_t count)
446 struct max32xxx_flash_bank *info = bank->driver_priv;
447 struct target *target = bank->target;
448 uint32_t flsh_cn, flsh_int;
449 uint32_t address = offset;
450 uint32_t remaining = count;
451 uint32_t words_remaining;
452 int retval;
453 int retry;
455 if (bank->target->state != TARGET_HALTED) {
456 LOG_ERROR("Target not halted");
457 return ERROR_TARGET_NOT_HALTED;
460 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
461 bank, buffer, offset, count);
463 if (info->probed == 0)
464 return ERROR_FLASH_BANK_NOT_PROBED;
466 if (offset & 0x3) {
467 LOG_WARNING("offset size must be word aligned");
468 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
471 if (offset + count > bank->size)
472 return ERROR_FLASH_DST_OUT_OF_BANK;
474 /* Prepare to issue flash operation */
475 retval = max32xxx_flash_op_pre(bank);
477 if (retval != ERROR_OK)
478 return retval;
480 if (remaining >= 4) {
481 /* write in 32-bit units */
482 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
483 flsh_cn &= 0xF7FFFFFF;
484 flsh_cn |= 0x00000010;
485 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
487 /* try using a block write */
488 words_remaining = remaining / 4;
489 retval = max32xxx_write_block(bank, buffer, offset, words_remaining);
491 if (retval != ERROR_OK) {
492 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
493 LOG_DEBUG("writing flash word-at-a-time");
494 else {
495 max32xxx_flash_op_post(bank);
496 return ERROR_FLASH_OPERATION_FAILED;
498 } else {
499 /* all 32-bit words have been written */
500 buffer += words_remaining * 4;
501 address += words_remaining * 4;
502 remaining -= words_remaining * 4;
506 if ((remaining >= 4) && ((address & 0x1F) != 0)) {
507 /* write in 32-bit units until we are 128-bit aligned */
508 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
509 flsh_cn &= 0xF7FFFFFF;
510 flsh_cn |= 0x00000010;
511 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
513 while ((remaining >= 4) && ((address & 0x1F) != 0)) {
514 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
515 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
516 flsh_cn |= 0x00000001;
517 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
518 /* Wait until flash operation is complete */
519 retry = 10;
521 do {
522 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
523 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
525 if (retry <= 0) {
526 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
527 return ERROR_FLASH_OPERATION_FAILED;
530 buffer += 4;
531 address += 4;
532 remaining -= 4;
536 if ((info->burst_size_bits == 128) && (remaining >= 16)) {
537 /* write in 128-bit bursts while we can */
538 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
540 flsh_cn &= 0xFFFFFFEF;
541 flsh_cn |= 0x08000000;
542 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
543 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
545 while (remaining >= 16) {
546 if ((address & 0xFFF) == 0)
547 LOG_DEBUG("Writing @ 0x%08x", address);
549 target_write_buffer(target, info->flc_base + FLSH_DATA0, 16, buffer);
550 flsh_cn |= 0x00000001;
551 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
552 /* Wait until flash operation is complete */
553 retry = 10;
555 do {
556 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
557 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
559 if (retry <= 0) {
560 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
561 return ERROR_FLASH_OPERATION_FAILED;
564 buffer += 16;
565 address += 16;
566 remaining -= 16;
570 if (remaining >= 4) {
572 /* write in 32-bit units while we can */
573 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
574 flsh_cn &= 0xF7FFFFFF;
575 flsh_cn |= 0x00000010;
576 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
578 while (remaining >= 4) {
579 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
580 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
581 flsh_cn |= 0x00000001;
582 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
583 /* Wait until flash operation is complete */
584 retry = 10;
586 do {
587 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
588 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
590 if (retry <= 0) {
591 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
592 return ERROR_FLASH_OPERATION_FAILED;
595 buffer += 4;
596 address += 4;
597 remaining -= 4;
601 if (remaining > 0) {
602 /* write remaining bytes in a 32-bit unit */
603 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
604 flsh_cn &= 0xF7FFFFFF;
605 flsh_cn |= 0x00000010;
606 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
608 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
609 int i = 0;
611 while (remaining > 0) {
612 last_word[i++] = *buffer;
613 buffer++;
614 remaining--;
617 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
618 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, last_word);
619 flsh_cn |= 0x00000001;
620 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
621 /* Wait until flash operation is complete */
622 retry = 10;
624 do {
625 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
626 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
628 if (retry <= 0) {
629 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
630 return ERROR_FLASH_OPERATION_FAILED;
634 /* Check access violations */
635 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
636 if (flsh_int & FLSH_INT_AF) {
637 LOG_ERROR("Flash Error writing 0x%x bytes at 0x%08x", count, offset);
638 max32xxx_flash_op_post(bank);
639 return ERROR_FLASH_OPERATION_FAILED;
642 if (max32xxx_flash_op_post(bank) != ERROR_OK)
643 return ERROR_FAIL;
645 return ERROR_OK;
648 static int max32xxx_probe(struct flash_bank *bank)
650 struct max32xxx_flash_bank *info = bank->driver_priv;
651 struct target *target = bank->target;
652 uint32_t arm_id[2];
653 uint16_t arm_pid;
655 if (bank->sectors) {
656 free(bank->sectors);
657 bank->sectors = NULL;
660 /* provide this for the benefit of the NOR flash framework */
661 bank->size = info->flash_size;
662 bank->num_sectors = info->flash_size / info->sector_size;
663 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
665 for (int i = 0; i < bank->num_sectors; i++) {
666 bank->sectors[i].offset = i * info->sector_size;
667 bank->sectors[i].size = info->sector_size;
668 bank->sectors[i].is_erased = -1;
669 bank->sectors[i].is_protected = -1;
672 /* Probe to determine if this part is in the max326xx family */
673 info->max326xx = 0;
674 target_read_u32(target, ARM_PID_REG, &arm_id[0]);
675 target_read_u32(target, ARM_PID_REG+4, &arm_id[1]);
676 arm_pid = (arm_id[1] << 8) + arm_id[0];
677 LOG_DEBUG("arm_pid = 0x%x", arm_pid);
679 if ((arm_pid == ARM_PID_DEFAULT_CM3) || arm_pid == ARM_PID_DEFAULT_CM4) {
680 uint32_t max326xx_id;
681 target_read_u32(target, MAX326XX_ID_REG, &max326xx_id);
682 LOG_DEBUG("max326xx_id = 0x%x", max326xx_id);
683 max326xx_id = ((max326xx_id & 0xFF000000) >> 24);
684 if (max326xx_id == MAX326XX_ID)
685 info->max326xx = 1;
687 LOG_DEBUG("info->max326xx = %d", info->max326xx);
689 /* Initialize the protection bits for each flash page */
690 if (max32xxx_protect_check(bank) == ERROR_FLASH_OPER_UNSUPPORTED)
691 LOG_WARNING("Flash protection not supported on this device");
693 info->probed = 1;
694 return ERROR_OK;
697 static int max32xxx_mass_erase(struct flash_bank *bank)
699 struct target *target = NULL;
700 struct max32xxx_flash_bank *info = NULL;
701 uint32_t flsh_cn, flsh_int;
702 int retval;
703 int retry;
704 info = bank->driver_priv;
705 target = bank->target;
707 if (target->state != TARGET_HALTED) {
708 LOG_ERROR("Target not halted");
709 return ERROR_TARGET_NOT_HALTED;
712 if (info->probed == 0)
713 return ERROR_FLASH_BANK_NOT_PROBED;
715 int not_protected = 0;
716 for (int i = 0; i < bank->num_sectors; i++) {
717 if (bank->sectors[i].is_protected == 1)
718 LOG_WARNING("Flash sector %d is protected", i);
719 else
720 not_protected = 1;
723 if (!not_protected) {
724 LOG_ERROR("All pages protected");
725 return ERROR_FAIL;
728 /* Prepare to issue flash operation */
729 retval = max32xxx_flash_op_pre(bank);
731 if (retval != ERROR_OK)
732 return retval;
734 /* Write mass erase code */
735 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
736 flsh_cn |= FLSH_CN_ERASE_CODE_ME;
737 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
739 /* Issue mass erase command */
740 flsh_cn |= 0x2;
741 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
743 /* Wait until erase complete */
744 retry = 1000;
745 do {
746 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
747 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
749 if (retry <= 0) {
750 LOG_ERROR("Timed out waiting for flash mass erase");
751 return ERROR_FLASH_OPERATION_FAILED;
754 /* Check access violations */
755 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
756 if (flsh_int & FLSH_INT_AF) {
757 LOG_ERROR("Error mass erasing");
758 target_write_u32(target, info->flc_base + FLSH_INT, 0);
759 return ERROR_FLASH_OPERATION_FAILED;
762 if (max32xxx_flash_op_post(bank) != ERROR_OK)
763 return ERROR_FAIL;
765 return ERROR_OK;
768 COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
770 int i;
771 struct flash_bank *bank;
772 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
774 if (CMD_ARGC < 1) {
775 command_print(CMD_CTX, "max32xxx mass_erase <bank>");
776 return ERROR_OK;
779 if (ERROR_OK != retval)
780 return retval;
782 if (max32xxx_mass_erase(bank) == ERROR_OK) {
783 /* set all sectors as erased */
784 for (i = 0; i < bank->num_sectors; i++)
785 bank->sectors[i].is_erased = 1;
787 command_print(CMD_CTX, "max32xxx mass erase complete");
788 } else
789 command_print(CMD_CTX, "max32xxx mass erase failed");
791 return ERROR_OK;
794 COMMAND_HANDLER(max32xxx_handle_protection_set_command)
796 struct flash_bank *bank;
797 int retval;
798 struct max32xxx_flash_bank *info;
799 uint32_t addr, len;
801 if (CMD_ARGC != 3) {
802 command_print(CMD_CTX, "max32xxx protection_set <bank> <addr> <size>");
803 return ERROR_OK;
806 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
807 if (ERROR_OK != retval)
808 return retval;
809 info = bank->driver_priv;
811 /* Convert the range to the page numbers */
812 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
813 LOG_WARNING("Error parsing address");
814 command_print(CMD_CTX, "max32xxx protection_set <bank> <addr> <size>");
815 return ERROR_FAIL;
817 /* Mask off the top portion on the address */
818 addr = (addr & 0x0FFFFFFF);
820 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
821 LOG_WARNING("Error parsing length");
822 command_print(CMD_CTX, "max32xxx protection_set <bank> <addr> <size>");
823 return ERROR_FAIL;
826 /* Check the address is in the range of the flash */
827 if ((addr+len) >= info->flash_size)
828 return ERROR_FLASH_SECTOR_INVALID;
830 if (len == 0)
831 return ERROR_OK;
833 /* Convert the address and length to the page boundaries */
834 addr = addr - (addr % info->sector_size);
835 if (len % info->sector_size)
836 len = len + info->sector_size - (len % info->sector_size);
838 /* Convert the address and length to page numbers */
839 addr = (addr / info->sector_size);
840 len = addr + (len / info->sector_size) - 1;
842 if (max32xxx_protect(bank, 1, addr, len) == ERROR_OK)
843 command_print(CMD_CTX, "max32xxx protection set complete");
844 else
845 command_print(CMD_CTX, "max32xxx protection set failed");
847 return ERROR_OK;
850 COMMAND_HANDLER(max32xxx_handle_protection_clr_command)
852 struct flash_bank *bank;
853 int retval;
854 struct max32xxx_flash_bank *info;
855 uint32_t addr, len;
857 if (CMD_ARGC != 3) {
858 command_print(CMD_CTX, "max32xxx protection_clr <bank> <addr> <size>");
859 return ERROR_OK;
862 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
863 if (ERROR_OK != retval)
864 return retval;
865 info = bank->driver_priv;
867 /* Convert the range to the page numbers */
868 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
869 LOG_WARNING("Error parsing address");
870 command_print(CMD_CTX, "max32xxx protection_clr <bank> <addr> <size>");
871 return ERROR_FAIL;
873 /* Mask off the top portion on the address */
874 addr = (addr & 0x0FFFFFFF);
876 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
877 LOG_WARNING("Error parsing length");
878 command_print(CMD_CTX, "max32xxx protection_clr <bank> <addr> <size>");
879 return ERROR_FAIL;
882 /* Check the address is in the range of the flash */
883 if ((addr+len) >= info->flash_size)
884 return ERROR_FLASH_SECTOR_INVALID;
886 if (len == 0)
887 return ERROR_OK;
889 /* Convert the address and length to the page boundaries */
890 addr = addr - (addr % info->sector_size);
891 if (len % info->sector_size)
892 len = len + info->sector_size - (len % info->sector_size);
894 /* Convert the address and length to page numbers */
895 addr = (addr / info->sector_size);
896 len = addr + (len / info->sector_size) - 1;
898 if (max32xxx_protect(bank, 0, addr, len) == ERROR_OK)
899 command_print(CMD_CTX, "max32xxx protection clear complete");
900 else
901 command_print(CMD_CTX, "max32xxx protection clear failed");
903 return ERROR_OK;
906 COMMAND_HANDLER(max32xxx_handle_protection_check_command)
908 struct flash_bank *bank;
909 int retval;
910 struct max32xxx_flash_bank *info;
911 int i;
913 if (CMD_ARGC < 1) {
914 command_print(CMD_CTX, "max32xxx protection_check <bank>");
915 return ERROR_OK;
918 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
919 if (ERROR_OK != retval)
920 return retval;
921 info = bank->driver_priv;
923 /* Update the protection array */
924 retval = max32xxx_protect_check(bank);
925 if (ERROR_OK != retval) {
926 LOG_WARNING("Error updating the protection array");
927 return retval;
930 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
931 for (i = 0; i < bank->num_sectors; i += 4) {
932 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",
933 (i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,
934 (i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,
935 (i+2), (i+2)*info->sector_size, bank->sectors[(i+2)].is_protected,
936 (i+3), (i+3)*info->sector_size, bank->sectors[(i+3)].is_protected);
939 return ERROR_OK;
942 static const struct command_registration max32xxx_exec_command_handlers[] = {
944 .name = "mass_erase",
945 .handler = max32xxx_handle_mass_erase_command,
946 .mode = COMMAND_EXEC,
947 .usage = "bank_id",
948 .help = "mass erase flash",
951 .name = "protection_set",
952 .handler = max32xxx_handle_protection_set_command,
953 .mode = COMMAND_EXEC,
954 .usage = "bank_id addr size",
955 .help = "set flash protection for address range",
958 .name = "protection_clr",
959 .handler = max32xxx_handle_protection_clr_command,
960 .mode = COMMAND_EXEC,
961 .usage = "bank_id addr size",
962 .help = "clear flash protection for address range",
965 .name = "protection_check",
966 .handler = max32xxx_handle_protection_check_command,
967 .mode = COMMAND_EXEC,
968 .usage = "bank_id",
969 .help = "check flash protection",
971 COMMAND_REGISTRATION_DONE
974 static const struct command_registration max32xxx_command_handlers[] = {
976 .name = "max32xxx",
977 .mode = COMMAND_EXEC,
978 .help = "max32xxx flash command group",
979 .chain = max32xxx_exec_command_handlers,
981 COMMAND_REGISTRATION_DONE
984 const struct flash_driver max32xxx_flash = {
985 .name = "max32xxx",
986 .commands = max32xxx_command_handlers,
987 .flash_bank_command = max32xxx_flash_bank_command,
988 .erase = max32xxx_erase,
989 .protect = max32xxx_protect,
990 .write = max32xxx_write,
991 .read = default_flash_read,
992 .probe = max32xxx_probe,
993 .auto_probe = max32xxx_probe,
994 .erase_check = default_flash_blank_check,
995 .protect_check = max32xxx_protect_check,
996 .info = get_info,