flash/nor/max32xxx: fix path of include file
[openocd.git] / src / flash / nor / max32xxx.c
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 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24 #include <target/algorithm.h>
25 #include <target/armv7m.h>
26
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
44
45 #define ARM_PID_REG 0xE00FFFE0
46 #define MAX326XX_ID_REG 0x40000838
47
48 /* Register settings */
49 #define FLSH_INT_AF 0x00000002
50
51 #define FLSH_CN_UNLOCK_MASK 0xF0000000
52 #define FLSH_CN_UNLOCK_VALUE 0x20000000
53
54 #define FLSH_CN_PEND 0x01000000
55
56 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
57 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
58 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
59
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
65
66 #define ARM_PID_DEFAULT_CM3 0xB4C3
67 #define ARM_PID_DEFAULT_CM4 0xB4C4
68 #define MAX326XX_ID 0x4D
69
70 static int max32xxx_mass_erase(struct flash_bank *bank);
71
72 struct max32xxx_flash_bank {
73 bool 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 uint32_t int_state;
80 unsigned int burst_size_bits;
81 };
82
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"
86 };
87
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]
90 */
91 FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
92 {
93 struct max32xxx_flash_bank *info;
94
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;
98 }
99
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);
105
106 if (CMD_ARGC > 9)
107 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], info->burst_size_bits);
108 else
109 info->burst_size_bits = 32;
110
111 info->int_state = 0;
112 bank->driver_priv = info;
113 return ERROR_OK;
114 }
115
116 static int get_info(struct flash_bank *bank, char *buf, int buf_size)
117 {
118 int printed;
119 struct max32xxx_flash_bank *info = bank->driver_priv;
120
121 if (!info->probed)
122 return ERROR_FLASH_BANK_NOT_PROBED;
123
124 printed = snprintf(buf, buf_size, "\nMaxim Integrated max32xxx flash driver\n");
125 buf += printed;
126 buf_size -= printed;
127 return ERROR_OK;
128 }
129
130 /***************************************************************************
131 * flash operations
132 ***************************************************************************/
133
134 static int max32xxx_flash_op_pre(struct flash_bank *bank)
135 {
136 struct target *target = bank->target;
137 struct max32xxx_flash_bank *info = bank->driver_priv;
138 uint32_t flsh_cn;
139 uint32_t bootloader;
140
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;
146
147 /* Refresh flash controller timing */
148 target_write_u32(target, info->flc_base + FLSH_CLKDIV, info->clkdiv_value);
149
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);
153
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;
158 }
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;
167 }
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;
171 }
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.");
175 }
176 }
177 }
178
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);
183
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;
188
189 return ERROR_OK;
190 }
191
192 static int max32xxx_flash_op_post(struct flash_bank *bank)
193 {
194 struct target *target = bank->target;
195 struct max32xxx_flash_bank *info = bank->driver_priv;
196 uint32_t flsh_cn;
197
198 /* Restore flash programming interrupts */
199 target_write_u32(target, info->flc_base + FLSH_INT, info->int_state);
200
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;
206 }
207
208 static int max32xxx_protect_check(struct flash_bank *bank)
209 {
210 struct max32xxx_flash_bank *info = bank->driver_priv;
211 struct target *target = bank->target;
212 uint32_t temp_reg;
213
214 if (!info->probed)
215 return ERROR_FLASH_BANK_NOT_PROBED;
216
217 if (!info->max326xx) {
218 for (unsigned i = 0; i < bank->num_sectors; i++)
219 bank->sectors[i].is_protected = -1;
220
221 return ERROR_FLASH_OPER_UNSUPPORTED;
222 }
223
224 /* Check the protection */
225 for (unsigned i = 0; i < bank->num_sectors; i++) {
226 if (i%32 == 0)
227 target_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);
228
229 if (temp_reg & (0x1 << i%32))
230 bank->sectors[i].is_protected = 1;
231 else
232 bank->sectors[i].is_protected = 0;
233 }
234 return ERROR_OK;
235 }
236
237 static int max32xxx_erase(struct flash_bank *bank, unsigned int first,
238 unsigned int last)
239 {
240 uint32_t flsh_cn, flsh_int;
241 struct max32xxx_flash_bank *info = bank->driver_priv;
242 struct target *target = bank->target;
243 int retval;
244 int retry;
245
246 if (bank->target->state != TARGET_HALTED) {
247 LOG_ERROR("Target not halted");
248 return ERROR_TARGET_NOT_HALTED;
249 }
250
251 if (!info->probed)
252 return ERROR_FLASH_BANK_NOT_PROBED;
253
254 if ((last < first) || (last >= bank->num_sectors))
255 return ERROR_FLASH_SECTOR_INVALID;
256
257 if ((first == 0) && (last == (bank->num_sectors - 1)))
258 return max32xxx_mass_erase(bank);
259
260 /* Prepare to issue flash operation */
261 retval = max32xxx_flash_op_pre(bank);
262
263 if (retval != ERROR_OK)
264 return retval;
265
266 int erased = 0;
267 for (unsigned int banknr = first; banknr <= last; banknr++) {
268
269 /* Check the protection */
270 if (bank->sectors[banknr].is_protected == 1) {
271 LOG_WARNING("Flash sector %u is protected", banknr);
272 continue;
273 } else
274 erased = 1;
275
276 /* Address is first word in page */
277 target_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);
278
279 /* Write page erase code */
280 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
281 flsh_cn |= FLSH_CN_ERASE_CODE_PGE;
282 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
283
284 /* Issue page erase command */
285 flsh_cn |= 0x4;
286 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
287
288 /* Wait until erase complete */
289 retry = 1000;
290 do {
291 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
292 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
293
294 if (retry <= 0) {
295 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
296 banknr * info->sector_size);
297 return ERROR_FLASH_OPERATION_FAILED;
298 }
299
300 /* Check access violations */
301 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
302 if (flsh_int & FLSH_INT_AF) {
303 LOG_ERROR("Error erasing flash page %i", banknr);
304 target_write_u32(target, info->flc_base + FLSH_INT, 0);
305 max32xxx_flash_op_post(bank);
306 return ERROR_FLASH_OPERATION_FAILED;
307 }
308
309 bank->sectors[banknr].is_erased = 1;
310 }
311
312 if (!erased) {
313 LOG_ERROR("All pages protected %u to %u", first, last);
314 max32xxx_flash_op_post(bank);
315 return ERROR_FAIL;
316 }
317
318 if (max32xxx_flash_op_post(bank) != ERROR_OK)
319 return ERROR_FAIL;
320
321 return ERROR_OK;
322 }
323
324 static int max32xxx_protect(struct flash_bank *bank, int set,
325 unsigned int first, unsigned int last)
326 {
327 struct max32xxx_flash_bank *info = bank->driver_priv;
328 struct target *target = bank->target;
329 uint32_t temp_reg;
330
331 if (bank->target->state != TARGET_HALTED) {
332 LOG_ERROR("Target not halted");
333 return ERROR_TARGET_NOT_HALTED;
334 }
335
336 if (!info->probed)
337 return ERROR_FLASH_BANK_NOT_PROBED;
338
339 if (!info->max326xx)
340 return ERROR_FLASH_OPER_UNSUPPORTED;
341
342 if ((last < first) || (last >= bank->num_sectors))
343 return ERROR_FLASH_SECTOR_INVALID;
344
345 /* Setup the protection on the pages given */
346 for (unsigned int page = first; page <= last; page++) {
347 if (set) {
348 /* Set the write/erase bit for this page */
349 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
350 temp_reg |= (0x1 << page%32);
351 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
352 bank->sectors[page].is_protected = 1;
353 } else {
354 /* Clear the write/erase bit for this page */
355 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
356 temp_reg &= ~(0x1 << page%32);
357 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
358 bank->sectors[page].is_protected = 0;
359 }
360 }
361
362 return ERROR_OK;
363 }
364
365 static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
366 uint32_t offset, uint32_t wcount)
367 {
368 struct max32xxx_flash_bank *info = bank->driver_priv;
369 struct target *target = bank->target;
370 uint32_t buffer_size = 16384;
371 struct working_area *source;
372 struct working_area *write_algorithm;
373 uint32_t address = bank->base + offset;
374 struct reg_param reg_params[5];
375 struct armv7m_algorithm armv7m_info;
376 int retval = ERROR_OK;
377 /* power of two, and multiple of word size */
378 static const unsigned buf_min = 128;
379
380 /* for small buffers it's faster not to download an algorithm */
381 if (wcount * 4 < buf_min)
382 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
383
384 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
385 bank, buffer, offset, wcount);
386
387 /* flash write code */
388 if (target_alloc_working_area(target, sizeof(write_code), &write_algorithm) != ERROR_OK) {
389 LOG_DEBUG("no working area for block memory writes");
390 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
391 }
392
393 /* plus a buffer big enough for this data */
394 if (wcount * 4 < buffer_size)
395 buffer_size = wcount * 4;
396
397 /* memory buffer */
398 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
399 buffer_size /= 2;
400
401 if (buffer_size <= buf_min) {
402 target_free_working_area(target, write_algorithm);
403 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
404 }
405
406 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
407 target_name(target), (unsigned) buffer_size);
408 }
409
410 target_write_buffer(target, write_algorithm->address, sizeof(write_code),
411 write_code);
412
413 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
414 armv7m_info.core_mode = ARM_MODE_THREAD;
415 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
416 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
417 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
418 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
419 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
420
421 buf_set_u32(reg_params[0].value, 0, 32, source->address);
422 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
423 buf_set_u32(reg_params[2].value, 0, 32, address);
424 buf_set_u32(reg_params[3].value, 0, 32, wcount);
425 buf_set_u32(reg_params[4].value, 0, 32, info->flc_base);
426 retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,
427 5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
428
429 if (retval == ERROR_FLASH_OPERATION_FAILED)
430 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
431
432 target_free_working_area(target, write_algorithm);
433 target_free_working_area(target, source);
434 destroy_reg_param(&reg_params[0]);
435 destroy_reg_param(&reg_params[1]);
436 destroy_reg_param(&reg_params[2]);
437 destroy_reg_param(&reg_params[3]);
438 destroy_reg_param(&reg_params[4]);
439 return retval;
440 }
441
442 static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
443 uint32_t offset, uint32_t count)
444 {
445 struct max32xxx_flash_bank *info = bank->driver_priv;
446 struct target *target = bank->target;
447 uint32_t flsh_cn, flsh_int;
448 uint32_t address = offset;
449 uint32_t remaining = count;
450 uint32_t words_remaining;
451 int retval;
452 int retry;
453
454 if (bank->target->state != TARGET_HALTED) {
455 LOG_ERROR("Target not halted");
456 return ERROR_TARGET_NOT_HALTED;
457 }
458
459 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
460 bank, buffer, offset, count);
461
462 if (!info->probed)
463 return ERROR_FLASH_BANK_NOT_PROBED;
464
465 if (offset & 0x3) {
466 LOG_WARNING("offset size must be word aligned");
467 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
468 }
469
470 if (offset + count > bank->size)
471 return ERROR_FLASH_DST_OUT_OF_BANK;
472
473 /* Prepare to issue flash operation */
474 retval = max32xxx_flash_op_pre(bank);
475
476 if (retval != ERROR_OK)
477 return retval;
478
479 if (remaining >= 4) {
480 /* write in 32-bit units */
481 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
482 flsh_cn &= 0xF7FFFFFF;
483 flsh_cn |= 0x00000010;
484 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
485
486 /* try using a block write */
487 words_remaining = remaining / 4;
488 retval = max32xxx_write_block(bank, buffer, offset, words_remaining);
489
490 if (retval != ERROR_OK) {
491 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
492 LOG_DEBUG("writing flash word-at-a-time");
493 else {
494 max32xxx_flash_op_post(bank);
495 return ERROR_FLASH_OPERATION_FAILED;
496 }
497 } else {
498 /* all 32-bit words have been written */
499 buffer += words_remaining * 4;
500 address += words_remaining * 4;
501 remaining -= words_remaining * 4;
502 }
503 }
504
505 if ((remaining >= 4) && ((address & 0x1F) != 0)) {
506 /* write in 32-bit units until we are 128-bit aligned */
507 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
508 flsh_cn &= 0xF7FFFFFF;
509 flsh_cn |= 0x00000010;
510 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
511
512 while ((remaining >= 4) && ((address & 0x1F) != 0)) {
513 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
514 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
515 flsh_cn |= 0x00000001;
516 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
517 /* Wait until flash operation is complete */
518 retry = 10;
519
520 do {
521 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
522 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
523
524 if (retry <= 0) {
525 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
526 return ERROR_FLASH_OPERATION_FAILED;
527 }
528
529 buffer += 4;
530 address += 4;
531 remaining -= 4;
532 }
533 }
534
535 if ((info->burst_size_bits == 128) && (remaining >= 16)) {
536 /* write in 128-bit bursts while we can */
537 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
538
539 flsh_cn &= 0xFFFFFFEF;
540 flsh_cn |= 0x08000000;
541 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
542 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
543
544 while (remaining >= 16) {
545 if ((address & 0xFFF) == 0)
546 LOG_DEBUG("Writing @ 0x%08" PRIx32, address);
547
548 target_write_buffer(target, info->flc_base + FLSH_DATA0, 16, buffer);
549 flsh_cn |= 0x00000001;
550 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
551 /* Wait until flash operation is complete */
552 retry = 10;
553
554 do {
555 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
556 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
557
558 if (retry <= 0) {
559 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
560 return ERROR_FLASH_OPERATION_FAILED;
561 }
562
563 buffer += 16;
564 address += 16;
565 remaining -= 16;
566 }
567 }
568
569 if (remaining >= 4) {
570
571 /* write in 32-bit units while we can */
572 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
573 flsh_cn &= 0xF7FFFFFF;
574 flsh_cn |= 0x00000010;
575 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
576
577 while (remaining >= 4) {
578 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
579 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
580 flsh_cn |= 0x00000001;
581 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
582 /* Wait until flash operation is complete */
583 retry = 10;
584
585 do {
586 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
587 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
588
589 if (retry <= 0) {
590 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
591 return ERROR_FLASH_OPERATION_FAILED;
592 }
593
594 buffer += 4;
595 address += 4;
596 remaining -= 4;
597 }
598 }
599
600 if (remaining > 0) {
601 /* write remaining bytes in a 32-bit unit */
602 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
603 flsh_cn &= 0xF7FFFFFF;
604 flsh_cn |= 0x00000010;
605 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
606
607 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
608 int i = 0;
609
610 while (remaining > 0) {
611 last_word[i++] = *buffer;
612 buffer++;
613 remaining--;
614 }
615
616 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
617 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, last_word);
618 flsh_cn |= 0x00000001;
619 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
620 /* Wait until flash operation is complete */
621 retry = 10;
622
623 do {
624 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
625 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
626
627 if (retry <= 0) {
628 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
629 return ERROR_FLASH_OPERATION_FAILED;
630 }
631 }
632
633 /* Check access violations */
634 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
635 if (flsh_int & FLSH_INT_AF) {
636 LOG_ERROR("Flash Error writing 0x%" PRIx32 " bytes at 0x%08" PRIx32, count, offset);
637 max32xxx_flash_op_post(bank);
638 return ERROR_FLASH_OPERATION_FAILED;
639 }
640
641 if (max32xxx_flash_op_post(bank) != ERROR_OK)
642 return ERROR_FAIL;
643
644 return ERROR_OK;
645 }
646
647 static int max32xxx_probe(struct flash_bank *bank)
648 {
649 struct max32xxx_flash_bank *info = bank->driver_priv;
650 struct target *target = bank->target;
651 uint32_t arm_id[2];
652 uint16_t arm_pid;
653
654 free(bank->sectors);
655
656 /* provide this for the benefit of the NOR flash framework */
657 bank->size = info->flash_size;
658 bank->num_sectors = info->flash_size / info->sector_size;
659 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
660
661 for (unsigned int i = 0; i < bank->num_sectors; i++) {
662 bank->sectors[i].offset = i * info->sector_size;
663 bank->sectors[i].size = info->sector_size;
664 bank->sectors[i].is_erased = -1;
665 bank->sectors[i].is_protected = -1;
666 }
667
668 /* Probe to determine if this part is in the max326xx family */
669 info->max326xx = 0;
670 target_read_u32(target, ARM_PID_REG, &arm_id[0]);
671 target_read_u32(target, ARM_PID_REG+4, &arm_id[1]);
672 arm_pid = (arm_id[1] << 8) + arm_id[0];
673 LOG_DEBUG("arm_pid = 0x%x", arm_pid);
674
675 if ((arm_pid == ARM_PID_DEFAULT_CM3) || arm_pid == ARM_PID_DEFAULT_CM4) {
676 uint32_t max326xx_id;
677 target_read_u32(target, MAX326XX_ID_REG, &max326xx_id);
678 LOG_DEBUG("max326xx_id = 0x%" PRIx32, max326xx_id);
679 max326xx_id = ((max326xx_id & 0xFF000000) >> 24);
680 if (max326xx_id == MAX326XX_ID)
681 info->max326xx = 1;
682 }
683 LOG_DEBUG("info->max326xx = %d", info->max326xx);
684
685 /* Initialize the protection bits for each flash page */
686 if (max32xxx_protect_check(bank) == ERROR_FLASH_OPER_UNSUPPORTED)
687 LOG_WARNING("Flash protection not supported on this device");
688
689 info->probed = true;
690 return ERROR_OK;
691 }
692
693 static int max32xxx_mass_erase(struct flash_bank *bank)
694 {
695 struct target *target = NULL;
696 struct max32xxx_flash_bank *info = NULL;
697 uint32_t flsh_cn, flsh_int;
698 int retval;
699 int retry;
700 info = bank->driver_priv;
701 target = bank->target;
702
703 if (target->state != TARGET_HALTED) {
704 LOG_ERROR("Target not halted");
705 return ERROR_TARGET_NOT_HALTED;
706 }
707
708 if (!info->probed)
709 return ERROR_FLASH_BANK_NOT_PROBED;
710
711 int not_protected = 0;
712 for (unsigned int i = 0; i < bank->num_sectors; i++) {
713 if (bank->sectors[i].is_protected == 1)
714 LOG_WARNING("Flash sector %u is protected", i);
715 else
716 not_protected = 1;
717 }
718
719 if (!not_protected) {
720 LOG_ERROR("All pages protected");
721 return ERROR_FAIL;
722 }
723
724 /* Prepare to issue flash operation */
725 retval = max32xxx_flash_op_pre(bank);
726
727 if (retval != ERROR_OK)
728 return retval;
729
730 /* Write mass erase code */
731 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
732 flsh_cn |= FLSH_CN_ERASE_CODE_ME;
733 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
734
735 /* Issue mass erase command */
736 flsh_cn |= 0x2;
737 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
738
739 /* Wait until erase complete */
740 retry = 1000;
741 do {
742 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
743 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
744
745 if (retry <= 0) {
746 LOG_ERROR("Timed out waiting for flash mass erase");
747 return ERROR_FLASH_OPERATION_FAILED;
748 }
749
750 /* Check access violations */
751 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
752 if (flsh_int & FLSH_INT_AF) {
753 LOG_ERROR("Error mass erasing");
754 target_write_u32(target, info->flc_base + FLSH_INT, 0);
755 return ERROR_FLASH_OPERATION_FAILED;
756 }
757
758 if (max32xxx_flash_op_post(bank) != ERROR_OK)
759 return ERROR_FAIL;
760
761 return ERROR_OK;
762 }
763
764 COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
765 {
766 struct flash_bank *bank;
767 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
768
769 if (CMD_ARGC < 1) {
770 command_print(CMD, "max32xxx mass_erase <bank>");
771 return ERROR_OK;
772 }
773
774 if (ERROR_OK != retval)
775 return retval;
776
777 if (max32xxx_mass_erase(bank) == ERROR_OK) {
778 /* set all sectors as erased */
779 for (unsigned i = 0; i < bank->num_sectors; i++)
780 bank->sectors[i].is_erased = 1;
781
782 command_print(CMD, "max32xxx mass erase complete");
783 } else
784 command_print(CMD, "max32xxx mass erase failed");
785
786 return ERROR_OK;
787 }
788
789 COMMAND_HANDLER(max32xxx_handle_protection_set_command)
790 {
791 struct flash_bank *bank;
792 int retval;
793 struct max32xxx_flash_bank *info;
794 uint32_t addr, len;
795
796 if (CMD_ARGC != 3) {
797 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
798 return ERROR_OK;
799 }
800
801 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
802 if (ERROR_OK != retval)
803 return retval;
804 info = bank->driver_priv;
805
806 /* Convert the range to the page numbers */
807 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
808 LOG_WARNING("Error parsing address");
809 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
810 return ERROR_FAIL;
811 }
812 /* Mask off the top portion on the address */
813 addr = (addr & 0x0FFFFFFF);
814
815 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
816 LOG_WARNING("Error parsing length");
817 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
818 return ERROR_FAIL;
819 }
820
821 /* Check the address is in the range of the flash */
822 if ((addr+len) >= info->flash_size)
823 return ERROR_FLASH_SECTOR_INVALID;
824
825 if (len == 0)
826 return ERROR_OK;
827
828 /* Convert the address and length to the page boundaries */
829 addr = addr - (addr % info->sector_size);
830 if (len % info->sector_size)
831 len = len + info->sector_size - (len % info->sector_size);
832
833 /* Convert the address and length to page numbers */
834 addr = (addr / info->sector_size);
835 len = addr + (len / info->sector_size) - 1;
836
837 if (max32xxx_protect(bank, 1, addr, len) == ERROR_OK)
838 command_print(CMD, "max32xxx protection set complete");
839 else
840 command_print(CMD, "max32xxx protection set failed");
841
842 return ERROR_OK;
843 }
844
845 COMMAND_HANDLER(max32xxx_handle_protection_clr_command)
846 {
847 struct flash_bank *bank;
848 int retval;
849 struct max32xxx_flash_bank *info;
850 uint32_t addr, len;
851
852 if (CMD_ARGC != 3) {
853 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
854 return ERROR_OK;
855 }
856
857 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
858 if (ERROR_OK != retval)
859 return retval;
860 info = bank->driver_priv;
861
862 /* Convert the range to the page numbers */
863 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
864 LOG_WARNING("Error parsing address");
865 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
866 return ERROR_FAIL;
867 }
868 /* Mask off the top portion on the address */
869 addr = (addr & 0x0FFFFFFF);
870
871 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
872 LOG_WARNING("Error parsing length");
873 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
874 return ERROR_FAIL;
875 }
876
877 /* Check the address is in the range of the flash */
878 if ((addr+len) >= info->flash_size)
879 return ERROR_FLASH_SECTOR_INVALID;
880
881 if (len == 0)
882 return ERROR_OK;
883
884 /* Convert the address and length to the page boundaries */
885 addr = addr - (addr % info->sector_size);
886 if (len % info->sector_size)
887 len = len + info->sector_size - (len % info->sector_size);
888
889 /* Convert the address and length to page numbers */
890 addr = (addr / info->sector_size);
891 len = addr + (len / info->sector_size) - 1;
892
893 if (max32xxx_protect(bank, 0, addr, len) == ERROR_OK)
894 command_print(CMD, "max32xxx protection clear complete");
895 else
896 command_print(CMD, "max32xxx protection clear failed");
897
898 return ERROR_OK;
899 }
900
901 COMMAND_HANDLER(max32xxx_handle_protection_check_command)
902 {
903 struct flash_bank *bank;
904 int retval;
905 struct max32xxx_flash_bank *info;
906
907 if (CMD_ARGC < 1) {
908 command_print(CMD, "max32xxx protection_check <bank>");
909 return ERROR_OK;
910 }
911
912 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
913 if (ERROR_OK != retval)
914 return retval;
915 info = bank->driver_priv;
916
917 /* Update the protection array */
918 retval = max32xxx_protect_check(bank);
919 if (ERROR_OK != retval) {
920 LOG_WARNING("Error updating the protection array");
921 return retval;
922 }
923
924 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
925 for (unsigned i = 0; i < bank->num_sectors; i += 4) {
926 LOG_WARNING("s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d",
927 (i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,
928 (i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,
929 (i+2), (i+2)*info->sector_size, bank->sectors[(i+2)].is_protected,
930 (i+3), (i+3)*info->sector_size, bank->sectors[(i+3)].is_protected);
931 }
932
933 return ERROR_OK;
934 }
935
936 static const struct command_registration max32xxx_exec_command_handlers[] = {
937 {
938 .name = "mass_erase",
939 .handler = max32xxx_handle_mass_erase_command,
940 .mode = COMMAND_EXEC,
941 .usage = "bank_id",
942 .help = "mass erase flash",
943 },
944 {
945 .name = "protection_set",
946 .handler = max32xxx_handle_protection_set_command,
947 .mode = COMMAND_EXEC,
948 .usage = "bank_id addr size",
949 .help = "set flash protection for address range",
950 },
951 {
952 .name = "protection_clr",
953 .handler = max32xxx_handle_protection_clr_command,
954 .mode = COMMAND_EXEC,
955 .usage = "bank_id addr size",
956 .help = "clear flash protection for address range",
957 },
958 {
959 .name = "protection_check",
960 .handler = max32xxx_handle_protection_check_command,
961 .mode = COMMAND_EXEC,
962 .usage = "bank_id",
963 .help = "check flash protection",
964 },
965 COMMAND_REGISTRATION_DONE
966 };
967
968 static const struct command_registration max32xxx_command_handlers[] = {
969 {
970 .name = "max32xxx",
971 .mode = COMMAND_EXEC,
972 .help = "max32xxx flash command group",
973 .chain = max32xxx_exec_command_handlers,
974 .usage = "",
975 },
976 COMMAND_REGISTRATION_DONE
977 };
978
979 const struct flash_driver max32xxx_flash = {
980 .name = "max32xxx",
981 .commands = max32xxx_command_handlers,
982 .flash_bank_command = max32xxx_flash_bank_command,
983 .erase = max32xxx_erase,
984 .protect = max32xxx_protect,
985 .write = max32xxx_write,
986 .read = default_flash_read,
987 .probe = max32xxx_probe,
988 .auto_probe = max32xxx_probe,
989 .erase_check = default_flash_blank_check,
990 .protect_check = max32xxx_protect_check,
991 .info = get_info,
992 };

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)