SPI table updates (some new devices and new info)
[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 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;
81 };
82
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"
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(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);
105
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;
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 == 0)
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 int i;
213 uint32_t temp_reg;
214
215 if (info->probed == 0)
216 return ERROR_FLASH_BANK_NOT_PROBED;
217
218 if (!info->max326xx) {
219 for (i = 0; i < bank->num_sectors; i++)
220 bank->sectors[i].is_protected = -1;
221
222 return ERROR_FLASH_OPER_UNSUPPORTED;
223 }
224
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);
229
230 if (temp_reg & (0x1 << i%32))
231 bank->sectors[i].is_protected = 1;
232 else
233 bank->sectors[i].is_protected = 0;
234 }
235 return ERROR_OK;
236 }
237
238 static int max32xxx_erase(struct flash_bank *bank, int first, int last)
239 {
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;
246
247 if (bank->target->state != TARGET_HALTED) {
248 LOG_ERROR("Target not halted");
249 return ERROR_TARGET_NOT_HALTED;
250 }
251
252 if (info->probed == 0)
253 return ERROR_FLASH_BANK_NOT_PROBED;
254
255 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
256 return ERROR_FLASH_SECTOR_INVALID;
257
258 if ((first == 0) && (last == (bank->num_sectors - 1)))
259 return max32xxx_mass_erase(bank);
260
261 /* Prepare to issue flash operation */
262 retval = max32xxx_flash_op_pre(bank);
263
264 if (retval != ERROR_OK)
265 return retval;
266
267 int erased = 0;
268 for (banknr = first; banknr <= last; banknr++) {
269
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;
276
277 /* Address is first word in page */
278 target_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);
279
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);
284
285 /* Issue page erase command */
286 flsh_cn |= 0x4;
287 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
288
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));
294
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;
299 }
300
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;
308 }
309
310 bank->sectors[banknr].is_erased = 1;
311 }
312
313 if (!erased) {
314 LOG_ERROR("All pages protected %d to %d", first, last);
315 max32xxx_flash_op_post(bank);
316 return ERROR_FAIL;
317 }
318
319 if (max32xxx_flash_op_post(bank) != ERROR_OK)
320 return ERROR_FAIL;
321
322 return ERROR_OK;
323 }
324
325 static int max32xxx_protect(struct flash_bank *bank, int set, int first, int last)
326 {
327 struct max32xxx_flash_bank *info = bank->driver_priv;
328 struct target *target = bank->target;
329 int page;
330 uint32_t temp_reg;
331
332 if (bank->target->state != TARGET_HALTED) {
333 LOG_ERROR("Target not halted");
334 return ERROR_TARGET_NOT_HALTED;
335 }
336
337 if (info->probed == 0)
338 return ERROR_FLASH_BANK_NOT_PROBED;
339
340 if (!info->max326xx)
341 return ERROR_FLASH_OPER_UNSUPPORTED;
342
343 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
344 return ERROR_FLASH_SECTOR_INVALID;
345
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;
360 }
361 }
362
363 return ERROR_OK;
364 }
365
366 static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
367 uint32_t offset, uint32_t wcount)
368 {
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;
380
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;
384
385 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
386 bank, buffer, offset, wcount);
387
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;
392 }
393
394 /* plus a buffer big enough for this data */
395 if (wcount * 4 < buffer_size)
396 buffer_size = wcount * 4;
397
398 /* memory buffer */
399 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
400 buffer_size /= 2;
401
402 if (buffer_size <= buf_min) {
403 target_free_working_area(target, write_algorithm);
404 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
405 }
406
407 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
408 target_name(target), (unsigned) buffer_size);
409 }
410
411 target_write_buffer(target, write_algorithm->address, sizeof(write_code),
412 write_code);
413
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);
421
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);
429
430 if (retval == ERROR_FLASH_OPERATION_FAILED)
431 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
432
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;
441 }
442
443 static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
444 uint32_t offset, uint32_t count)
445 {
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;
454
455 if (bank->target->state != TARGET_HALTED) {
456 LOG_ERROR("Target not halted");
457 return ERROR_TARGET_NOT_HALTED;
458 }
459
460 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
461 bank, buffer, offset, count);
462
463 if (info->probed == 0)
464 return ERROR_FLASH_BANK_NOT_PROBED;
465
466 if (offset & 0x3) {
467 LOG_WARNING("offset size must be word aligned");
468 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
469 }
470
471 if (offset + count > bank->size)
472 return ERROR_FLASH_DST_OUT_OF_BANK;
473
474 /* Prepare to issue flash operation */
475 retval = max32xxx_flash_op_pre(bank);
476
477 if (retval != ERROR_OK)
478 return retval;
479
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);
486
487 /* try using a block write */
488 words_remaining = remaining / 4;
489 retval = max32xxx_write_block(bank, buffer, offset, words_remaining);
490
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;
497 }
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;
503 }
504 }
505
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);
512
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;
520
521 do {
522 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
523 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
524
525 if (retry <= 0) {
526 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
527 return ERROR_FLASH_OPERATION_FAILED;
528 }
529
530 buffer += 4;
531 address += 4;
532 remaining -= 4;
533 }
534 }
535
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);
539
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);
544
545 while (remaining >= 16) {
546 if ((address & 0xFFF) == 0)
547 LOG_DEBUG("Writing @ 0x%08x", address);
548
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;
554
555 do {
556 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
557 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
558
559 if (retry <= 0) {
560 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
561 return ERROR_FLASH_OPERATION_FAILED;
562 }
563
564 buffer += 16;
565 address += 16;
566 remaining -= 16;
567 }
568 }
569
570 if (remaining >= 4) {
571
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);
577
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;
585
586 do {
587 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
588 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
589
590 if (retry <= 0) {
591 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
592 return ERROR_FLASH_OPERATION_FAILED;
593 }
594
595 buffer += 4;
596 address += 4;
597 remaining -= 4;
598 }
599 }
600
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);
607
608 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
609 int i = 0;
610
611 while (remaining > 0) {
612 last_word[i++] = *buffer;
613 buffer++;
614 remaining--;
615 }
616
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;
623
624 do {
625 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
626 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
627
628 if (retry <= 0) {
629 LOG_ERROR("Timed out waiting for flash write @ 0x%08x", address);
630 return ERROR_FLASH_OPERATION_FAILED;
631 }
632 }
633
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;
640 }
641
642 if (max32xxx_flash_op_post(bank) != ERROR_OK)
643 return ERROR_FAIL;
644
645 return ERROR_OK;
646 }
647
648 static int max32xxx_probe(struct flash_bank *bank)
649 {
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;
654
655 if (bank->sectors) {
656 free(bank->sectors);
657 bank->sectors = NULL;
658 }
659
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));
664
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;
670 }
671
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);
678
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;
686 }
687 LOG_DEBUG("info->max326xx = %d", info->max326xx);
688
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");
692
693 info->probed = 1;
694 return ERROR_OK;
695 }
696
697 static int max32xxx_mass_erase(struct flash_bank *bank)
698 {
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;
706
707 if (target->state != TARGET_HALTED) {
708 LOG_ERROR("Target not halted");
709 return ERROR_TARGET_NOT_HALTED;
710 }
711
712 if (info->probed == 0)
713 return ERROR_FLASH_BANK_NOT_PROBED;
714
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;
721 }
722
723 if (!not_protected) {
724 LOG_ERROR("All pages protected");
725 return ERROR_FAIL;
726 }
727
728 /* Prepare to issue flash operation */
729 retval = max32xxx_flash_op_pre(bank);
730
731 if (retval != ERROR_OK)
732 return retval;
733
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);
738
739 /* Issue mass erase command */
740 flsh_cn |= 0x2;
741 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
742
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));
748
749 if (retry <= 0) {
750 LOG_ERROR("Timed out waiting for flash mass erase");
751 return ERROR_FLASH_OPERATION_FAILED;
752 }
753
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;
760 }
761
762 if (max32xxx_flash_op_post(bank) != ERROR_OK)
763 return ERROR_FAIL;
764
765 return ERROR_OK;
766 }
767
768 COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
769 {
770 int i;
771 struct flash_bank *bank;
772 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
773
774 if (CMD_ARGC < 1) {
775 command_print(CMD_CTX, "max32xxx mass_erase <bank>");
776 return ERROR_OK;
777 }
778
779 if (ERROR_OK != retval)
780 return retval;
781
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;
786
787 command_print(CMD_CTX, "max32xxx mass erase complete");
788 } else
789 command_print(CMD_CTX, "max32xxx mass erase failed");
790
791 return ERROR_OK;
792 }
793
794 COMMAND_HANDLER(max32xxx_handle_protection_set_command)
795 {
796 struct flash_bank *bank;
797 int retval;
798 struct max32xxx_flash_bank *info;
799 uint32_t addr, len;
800
801 if (CMD_ARGC != 3) {
802 command_print(CMD_CTX, "max32xxx protection_set <bank> <addr> <size>");
803 return ERROR_OK;
804 }
805
806 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
807 if (ERROR_OK != retval)
808 return retval;
809 info = bank->driver_priv;
810
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;
816 }
817 /* Mask off the top portion on the address */
818 addr = (addr & 0x0FFFFFFF);
819
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;
824 }
825
826 /* Check the address is in the range of the flash */
827 if ((addr+len) >= info->flash_size)
828 return ERROR_FLASH_SECTOR_INVALID;
829
830 if (len == 0)
831 return ERROR_OK;
832
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);
837
838 /* Convert the address and length to page numbers */
839 addr = (addr / info->sector_size);
840 len = addr + (len / info->sector_size) - 1;
841
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");
846
847 return ERROR_OK;
848 }
849
850 COMMAND_HANDLER(max32xxx_handle_protection_clr_command)
851 {
852 struct flash_bank *bank;
853 int retval;
854 struct max32xxx_flash_bank *info;
855 uint32_t addr, len;
856
857 if (CMD_ARGC != 3) {
858 command_print(CMD_CTX, "max32xxx protection_clr <bank> <addr> <size>");
859 return ERROR_OK;
860 }
861
862 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
863 if (ERROR_OK != retval)
864 return retval;
865 info = bank->driver_priv;
866
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;
872 }
873 /* Mask off the top portion on the address */
874 addr = (addr & 0x0FFFFFFF);
875
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;
880 }
881
882 /* Check the address is in the range of the flash */
883 if ((addr+len) >= info->flash_size)
884 return ERROR_FLASH_SECTOR_INVALID;
885
886 if (len == 0)
887 return ERROR_OK;
888
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);
893
894 /* Convert the address and length to page numbers */
895 addr = (addr / info->sector_size);
896 len = addr + (len / info->sector_size) - 1;
897
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");
902
903 return ERROR_OK;
904 }
905
906 COMMAND_HANDLER(max32xxx_handle_protection_check_command)
907 {
908 struct flash_bank *bank;
909 int retval;
910 struct max32xxx_flash_bank *info;
911 int i;
912
913 if (CMD_ARGC < 1) {
914 command_print(CMD_CTX, "max32xxx protection_check <bank>");
915 return ERROR_OK;
916 }
917
918 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
919 if (ERROR_OK != retval)
920 return retval;
921 info = bank->driver_priv;
922
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;
928 }
929
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);
937 }
938
939 return ERROR_OK;
940 }
941
942 static const struct command_registration max32xxx_exec_command_handlers[] = {
943 {
944 .name = "mass_erase",
945 .handler = max32xxx_handle_mass_erase_command,
946 .mode = COMMAND_EXEC,
947 .usage = "bank_id",
948 .help = "mass erase flash",
949 },
950 {
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",
956 },
957 {
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",
963 },
964 {
965 .name = "protection_check",
966 .handler = max32xxx_handle_protection_check_command,
967 .mode = COMMAND_EXEC,
968 .usage = "bank_id",
969 .help = "check flash protection",
970 },
971 COMMAND_REGISTRATION_DONE
972 };
973
974 static const struct command_registration max32xxx_command_handlers[] = {
975 {
976 .name = "max32xxx",
977 .mode = COMMAND_EXEC,
978 .help = "max32xxx flash command group",
979 .chain = max32xxx_exec_command_handlers,
980 },
981 COMMAND_REGISTRATION_DONE
982 };
983
984 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,
997 };

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)