4710512abc485e8e3c2c5fd31bad9482be56857a
[openocd.git] / src / flash / nor / at91sam4l.c
1 /***************************************************************************
2 * Copyright (C) 2013 by Andrey Yurovsky *
3 * Andrey Yurovsky <yurovsky@gmail.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
25 #include <target/cortex_m.h>
26
27 /* At this time, the SAM4L Flash is available in these capacities:
28 * ATSAM4Lx4xx: 256KB (512 pages)
29 * ATSAM4Lx2xx: 128KB (256 pages)
30 * ATSAM4Lx8xx: 512KB (1024 pages)
31 */
32
33 /* There are 16 lockable regions regardless of overall capacity. The number
34 * of pages per sector is therefore dependant on capacity. */
35 #define SAM4L_NUM_SECTORS 16
36
37 /* Locations in memory map */
38 #define SAM4L_FLASH ((uint32_t)0x00000000) /* Flash region */
39 #define SAM4L_FLASH_USER 0x00800000 /* Flash user page region */
40 #define SAM4L_FLASHCALW 0x400A0000 /* Flash controller */
41 #define SAM4L_CHIPID 0x400E0740 /* Chip Identification */
42
43 /* Offsets from SAM4L_FLASHCALW */
44 #define SAM4L_FCR 0x00 /* Flash Control Register (RW) */
45 #define SAM4L_FCMD 0x04 /* Flash Command Register (RW) */
46 #define SAM4L_FSR 0x08 /* Flash Status Register (RO) */
47 #define SAM4L_FPR 0x0C /* Flash Parameter Register (RO) */
48 #define SAM4L_FVR 0x10 /* Flash Version Register (RO) */
49 #define SAM4L_FGPFRHI 0x14 /* Flash General Purpose Register High (RO) */
50 #define SAM4L_FGPFRLO 0x18 /* Flash General Purpose Register Low (RO) */
51
52 /* Offsets from SAM4L_CHIPID */
53 #define SAM4L_CIDR 0x00 /* Chip ID Register (RO) */
54 #define SAM4L_EXID 0x04 /* Chip ID Extension Register (RO) */
55
56 /* Flash commands (for SAM4L_FCMD), see Table 14-5 */
57 #define SAM4L_FCMD_NOP 0 /* No Operation */
58 #define SAM4L_FCMD_WP 1 /* Write Page */
59 #define SAM4L_FCMD_EP 2 /* Erase Page */
60 #define SAM4L_FCMD_CPB 3 /* Clear Page Buffer */
61 #define SAM4L_FCMD_LP 4 /* Lock region containing given page */
62 #define SAM4L_FCMD_UP 5 /* Unlock region containing given page */
63 #define SAM4L_FCMD_EA 6 /* Erase All */
64 #define SAM4L_FCMD_WGPB 7 /* Write general-purpose fuse bit */
65 #define SAM4L_FCMD_EGPB 8 /* Erase general-purpose fuse bit */
66 #define SAM4L_FCMD_SSB 9 /* Set security fuses */
67 #define SAM4L_FCMD_PGPFB 10 /* Program general-purpose fuse byte */
68 #define SAM4L_FCMD_EAGPF 11 /* Erase all general-purpose fuse bits */
69 #define SAM4L_FCMD_QPR 12 /* Quick page read */
70 #define SAM4L_FCMD_WUP 13 /* Write user page */
71 #define SAM4L_FCMD_EUP 14 /* Erase user page */
72 #define SAM4L_FCMD_QPRUP 15 /* Quick page read (user page) */
73 #define SAM4L_FCMD_HSEN 16 /* High speed mode enable */
74 #define SAM4L_FCMD_HSDIS 17 /* High speed mode disable */
75
76 #define SAM4L_FMCD_CMDKEY 0xA5UL /* 'key' to issue commands, see 14.10.2 */
77
78
79 /* SMAP registers and bits */
80 #define SMAP_BASE 0x400A3000
81
82 #define SMAP_SCR (SMAP_BASE + 8)
83 #define SMAP_SCR_HCR (1 << 1)
84
85
86 struct sam4l_chip_info {
87 uint32_t id;
88 uint32_t exid;
89 const char *name;
90 };
91
92 /* These are taken from Table 9-1 in 42023E-SAM-07/2013 */
93 static const struct sam4l_chip_info sam4l_known_chips[] = {
94 { 0xAB0B0AE0, 0x1400000F, "ATSAM4LC8C" },
95 { 0xAB0A09E0, 0x0400000F, "ATSAM4LC4C" },
96 { 0xAB0A07E0, 0x0400000F, "ATSAM4LC2C" },
97 { 0xAB0B0AE0, 0x1300000F, "ATSAM4LC8B" },
98 { 0xAB0A09E0, 0x0300000F, "ATSAM4LC4B" },
99 { 0xAB0A07E0, 0x0300000F, "ATSAM4LC2B" },
100 { 0xAB0B0AE0, 0x1200000F, "ATSAM4LC8A" },
101 { 0xAB0A09E0, 0x0200000F, "ATSAM4LC4A" },
102 { 0xAB0A07E0, 0x0200000F, "ATSAM4LC2A" },
103 { 0xAB0B0AE0, 0x14000002, "ATSAM4LS8C" },
104 { 0xAB0A09E0, 0x04000002, "ATSAM4LS4C" },
105 { 0xAB0A07E0, 0x04000002, "ATSAM4LS2C" },
106 { 0xAB0B0AE0, 0x13000002, "ATSAM4LS8B" },
107 { 0xAB0A09E0, 0x03000002, "ATSAM4LS4B" },
108 { 0xAB0A07E0, 0x03000002, "ATSAM4LS2B" },
109 { 0xAB0B0AE0, 0x12000002, "ATSAM4LS8A" },
110 { 0xAB0A09E0, 0x02000002, "ATSAM4LS4A" },
111 { 0xAB0A07E0, 0x02000002, "ATSAM4LS2A" },
112 };
113
114 /* Meaning of SRAMSIZ field in CHIPID, see 9.3.1 in 42023E-SAM-07/2013 */
115 static const uint16_t sam4l_ram_sizes[16] = { 48, 1, 2, 6, 24, 4, 80, 160, 8, 16, 32, 64, 128, 256, 96, 512 };
116
117 /* Meaning of PSZ field in FPR, see 14.10.4 in 42023E-SAM-07/2013 */
118 static const uint16_t sam4l_page_sizes[8] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
119
120 struct sam4l_info {
121 const struct sam4l_chip_info *details;
122
123 uint32_t flash_kb;
124 uint32_t ram_kb;
125 uint32_t page_size;
126 int num_pages;
127 int sector_size;
128 int pages_per_sector;
129
130 bool probed;
131 struct target *target;
132 struct sam4l_info *next;
133 };
134
135 static struct sam4l_info *sam4l_chips;
136
137 static int sam4l_flash_wait_until_ready(struct target *target)
138 {
139 volatile unsigned int t = 0;
140 uint32_t st;
141 int res;
142
143 /* Poll the status register until the FRDY bit is set */
144 do {
145 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
146 } while (res == ERROR_OK && !(st & (1<<0)) && ++t < 10);
147
148 return res;
149 }
150
151 static int sam4l_flash_check_error(struct target *target, uint32_t *err)
152 {
153 uint32_t st;
154 int res;
155
156 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
157
158 if (res == ERROR_OK)
159 *err = st & ((1<<3) | (1<<2)); /* grab PROGE and LOCKE bits */
160
161 return res;
162 }
163
164 static int sam4l_flash_command(struct target *target, uint8_t cmd, int page)
165 {
166 int res;
167 uint32_t fcmd;
168 uint32_t err;
169
170 res = sam4l_flash_wait_until_ready(target);
171 if (res != ERROR_OK)
172 return res;
173
174 if (page >= 0) {
175 /* Set the page number. For some commands, the page number is just an
176 * argument (ex: fuse bit number). */
177 fcmd = (SAM4L_FMCD_CMDKEY << 24) | ((page & 0xFFFF) << 8) | (cmd & 0x3F);
178 } else {
179 /* Reuse the page number that was read from the flash command register. */
180 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, &fcmd);
181 if (res != ERROR_OK)
182 return res;
183
184 fcmd &= ~0x3F; /* clear out the command code */
185 fcmd |= (SAM4L_FMCD_CMDKEY << 24) | (cmd & 0x3F);
186 }
187
188 /* Send the command */
189 res = target_write_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, fcmd);
190 if (res != ERROR_OK)
191 return res;
192
193 res = sam4l_flash_check_error(target, &err);
194 if (res != ERROR_OK)
195 return res;
196
197 if (err != 0)
198 LOG_ERROR("%s got error status 0x%08" PRIx32, __func__, err);
199
200 res = sam4l_flash_wait_until_ready(target);
201
202 return res;
203 }
204
205 FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command)
206 {
207 struct sam4l_info *chip = sam4l_chips;
208
209 while (chip) {
210 if (chip->target == bank->target)
211 break;
212 chip = chip->next;
213 }
214
215 if (!chip) {
216 /* Create a new chip */
217 chip = calloc(1, sizeof(*chip));
218 if (!chip)
219 return ERROR_FAIL;
220
221 chip->target = bank->target;
222 chip->probed = false;
223
224 bank->driver_priv = chip;
225
226 /* Insert it into the chips list (at head) */
227 chip->next = sam4l_chips;
228 sam4l_chips = chip;
229 }
230
231 if (bank->base != SAM4L_FLASH) {
232 LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
233 "[at91sam4l series] )",
234 bank->base, SAM4L_FLASH);
235 return ERROR_FAIL;
236 }
237
238 return ERROR_OK;
239 }
240
241 static const struct sam4l_chip_info *sam4l_find_chip_name(uint32_t id, uint32_t exid)
242 {
243 unsigned int i;
244
245 id &= ~0xF;
246
247 for (i = 0; i < ARRAY_SIZE(sam4l_known_chips); i++) {
248 if (sam4l_known_chips[i].id == id && sam4l_known_chips[i].exid == exid)
249 return &sam4l_known_chips[i];
250 }
251
252 return NULL;
253 }
254
255 static int sam4l_check_page_erased(struct flash_bank *bank, uint32_t pn,
256 bool *is_erased_p)
257 {
258 int res;
259 uint32_t st;
260
261 /* Issue a quick page read to verify that we've erased this page */
262 res = sam4l_flash_command(bank->target, SAM4L_FCMD_QPR, pn);
263 if (res != ERROR_OK) {
264 LOG_ERROR("Quick page read %" PRIu32 " failed", pn);
265 return res;
266 }
267
268 /* Retrieve the flash status */
269 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
270 if (res != ERROR_OK) {
271 LOG_ERROR("Couldn't read erase status");
272 return res;
273 }
274
275 /* Is the page in question really erased? */
276 *is_erased_p = !!(st & (1<<5));
277
278 return ERROR_OK;
279 }
280
281 static int sam4l_probe(struct flash_bank *bank)
282 {
283 uint32_t id, exid, param;
284 int res;
285 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
286
287 if (chip->probed)
288 return ERROR_OK;
289
290 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_CIDR, &id);
291 if (res != ERROR_OK) {
292 LOG_ERROR("Couldn't read chip ID");
293 return res;
294 }
295
296 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_EXID, &exid);
297 if (res != ERROR_OK) {
298 LOG_ERROR("Couldn't read extended chip ID");
299 return res;
300 }
301
302 chip->details = sam4l_find_chip_name(id, exid);
303
304 /* The RAM capacity is in a lookup table. */
305 chip->ram_kb = sam4l_ram_sizes[0xF & (id >> 16)];
306
307 switch (0xF & (id >> 8)) {
308 case 0x07:
309 chip->flash_kb = 128;
310 break;
311 case 0x09:
312 chip->flash_kb = 256;
313 break;
314 case 0x0A:
315 chip->flash_kb = 512;
316 break;
317 default:
318 LOG_ERROR("Unknown flash size (chip ID is %08" PRIx32 "), assuming 128K", id);
319 chip->flash_kb = 128;
320 break;
321 }
322
323 /* Retrieve the Flash parameters */
324 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FPR, &param);
325 if (res != ERROR_OK) {
326 LOG_ERROR("Couldn't read Flash parameters");
327 return res;
328 }
329
330 /* Fetch the page size from the parameter register. Technically the flash
331 * capacity is there too though the manual mentions that not all parts will
332 * have it set so we use the Chip ID capacity information instead. */
333 chip->page_size = sam4l_page_sizes[0x7 & (param >> 8)];
334 assert(chip->page_size);
335 chip->num_pages = chip->flash_kb * 1024 / chip->page_size;
336
337 chip->sector_size = (chip->flash_kb * 1024) / SAM4L_NUM_SECTORS;
338 chip->pages_per_sector = chip->sector_size / chip->page_size;
339
340 /* Make sure the bank size is correct */
341 bank->size = chip->flash_kb * 1024;
342
343 /* Allocate the sector table. */
344 bank->num_sectors = SAM4L_NUM_SECTORS;
345 bank->sectors = calloc(bank->num_sectors, (sizeof((bank->sectors)[0])));
346 if (!bank->sectors)
347 return ERROR_FAIL;
348
349 /* Fill out the sector information: all SAM4L sectors are the same size and
350 * there is always a fixed number of them. */
351 for (int i = 0; i < bank->num_sectors; i++) {
352 bank->sectors[i].size = chip->sector_size;
353 bank->sectors[i].offset = i * chip->sector_size;
354 /* mark as unknown */
355 bank->sectors[i].is_erased = -1;
356 bank->sectors[i].is_protected = -1;
357 }
358
359 /* Done */
360 chip->probed = true;
361
362 LOG_INFO("SAM4L MCU: %s (Rev %c) (%" PRIu32 "KB Flash with %d %" PRId32 "B pages, %" PRIu32 "KB RAM)",
363 chip->details ? chip->details->name : "unknown", (char)('A' + (id & 0xF)),
364 chip->flash_kb, chip->num_pages, chip->page_size, chip->ram_kb);
365
366 return ERROR_OK;
367 }
368
369 static int sam4l_protect_check(struct flash_bank *bank)
370 {
371 int res;
372 uint32_t st;
373 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
374
375 if (bank->target->state != TARGET_HALTED) {
376 LOG_ERROR("Target not halted");
377
378 return ERROR_TARGET_NOT_HALTED;
379 }
380
381 if (!chip->probed) {
382 if (sam4l_probe(bank) != ERROR_OK)
383 return ERROR_FLASH_BANK_NOT_PROBED;
384 }
385
386 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
387 if (res != ERROR_OK)
388 return res;
389
390 st >>= 16; /* There are 16 lock region bits in the upper half word */
391 for (int i = 0; i < bank->num_sectors; i++)
392 bank->sectors[i].is_protected = !!(st & (1<<i));
393
394 return ERROR_OK;
395 }
396
397 static int sam4l_protect(struct flash_bank *bank, int set, int first, int last)
398 {
399 struct sam4l_info *chip = sam4l_chips;
400
401 if (bank->target->state != TARGET_HALTED) {
402 LOG_ERROR("Target not halted");
403
404 return ERROR_TARGET_NOT_HALTED;
405 }
406
407 if (!chip->probed) {
408 if (sam4l_probe(bank) != ERROR_OK)
409 return ERROR_FLASH_BANK_NOT_PROBED;
410 }
411
412 /* Make sure the pages make sense. */
413 if (first >= bank->num_sectors || last >= bank->num_sectors) {
414 LOG_ERROR("Protect range %d - %d not valid (%d sectors total)", first, last,
415 bank->num_sectors);
416 return ERROR_FAIL;
417 }
418
419 /* Try to lock or unlock each sector in the range. This is done by locking
420 * a region containing one page in that sector, we arbitrarily choose the 0th
421 * page in the sector. */
422 for (int i = first; i <= last; i++) {
423 int res;
424
425 res = sam4l_flash_command(bank->target,
426 set ? SAM4L_FCMD_LP : SAM4L_FCMD_UP, i * chip->pages_per_sector);
427 if (res != ERROR_OK) {
428 LOG_ERROR("Can't %slock region containing page %d", set ? "" : "un", i);
429 return res;
430 }
431 }
432
433 return ERROR_OK;
434 }
435
436 static int sam4l_erase(struct flash_bank *bank, int first, int last)
437 {
438 int ret;
439 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
440
441 if (bank->target->state != TARGET_HALTED) {
442 LOG_ERROR("Target not halted");
443
444 return ERROR_TARGET_NOT_HALTED;
445 }
446
447 if (!chip->probed) {
448 if (sam4l_probe(bank) != ERROR_OK)
449 return ERROR_FLASH_BANK_NOT_PROBED;
450 }
451
452 /* Make sure the pages make sense. */
453 if (first >= bank->num_sectors || last >= bank->num_sectors) {
454 LOG_ERROR("Erase range %d - %d not valid (%d sectors total)", first, last,
455 bank->num_sectors);
456 return ERROR_FAIL;
457 }
458
459 /* Erase */
460 if ((first == 0) && ((last + 1) == bank->num_sectors)) {
461 LOG_DEBUG("Erasing the whole chip");
462
463 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EA, -1);
464 if (ret != ERROR_OK) {
465 LOG_ERROR("Erase All failed");
466 return ret;
467 }
468 } else {
469 LOG_DEBUG("Erasing sectors %d through %d...\n", first, last);
470
471 /* For each sector... */
472 for (int i = first; i <= last; i++) {
473 /* For each page in that sector... */
474 for (int j = 0; j < chip->pages_per_sector; j++) {
475 int pn = i * chip->pages_per_sector + j;
476 bool is_erased = false;
477
478 /* Issue the page erase */
479 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EP, pn);
480 if (ret != ERROR_OK) {
481 LOG_ERROR("Erasing page %d failed", pn);
482 return ret;
483 }
484
485 ret = sam4l_check_page_erased(bank, pn, &is_erased);
486 if (ret != ERROR_OK)
487 return ret;
488
489 if (!is_erased) {
490 LOG_DEBUG("Page %d was not erased.", pn);
491 return ERROR_FAIL;
492 }
493 }
494
495 /* This sector is definitely erased. */
496 bank->sectors[i].is_erased = 1;
497 }
498 }
499
500 return ERROR_OK;
501 }
502
503 /* Write an entire page from host buffer 'buf' to page-aligned 'address' in the
504 * Flash. */
505 static int sam4l_write_page(struct sam4l_info *chip, struct target *target,
506 uint32_t address, const uint8_t *buf)
507 {
508 int res;
509
510 LOG_DEBUG("sam4l_write_page address=%08" PRIx32, address);
511
512 /* Clear the page buffer before we write to it */
513 res = sam4l_flash_command(target, SAM4L_FCMD_CPB, -1);
514 if (res != ERROR_OK) {
515 LOG_ERROR("%s: can't clear page buffer", __func__);
516 return res;
517 }
518
519 /* Write the modified page back to the target's page buffer */
520 res = target_write_memory(target, address, 4, chip->page_size / 4, buf);
521
522 if (res != ERROR_OK) {
523 LOG_ERROR("%s: %d", __func__, __LINE__);
524 return res;
525 }
526
527 /* Commit the page contents to Flash: erase the current page and then
528 * write it out. */
529 res = sam4l_flash_command(target, SAM4L_FCMD_EP, -1);
530 if (res != ERROR_OK)
531 return res;
532 res = sam4l_flash_command(target, SAM4L_FCMD_WP, -1);
533
534 return res;
535 }
536
537 /* Write partial contents into page-aligned 'address' on the Flash from host
538 * buffer 'buf' by writing 'nb' of 'buf' at 'offset' into the Flash page. */
539 static int sam4l_write_page_partial(struct sam4l_info *chip,
540 struct flash_bank *bank, uint32_t address, const uint8_t *buf,
541 uint32_t page_offset, uint32_t nb)
542 {
543 int res;
544 uint8_t *pg = malloc(chip->page_size);
545 if (!pg)
546 return ERROR_FAIL;
547
548 LOG_DEBUG("sam4l_write_page_partial address=%08" PRIx32 " nb=%08" PRIx32, address, nb);
549
550 assert(page_offset + nb < chip->page_size);
551 assert((address % chip->page_size) == 0);
552
553 /* Retrieve the full page contents from Flash */
554 res = target_read_memory(bank->target, address, 4,
555 chip->page_size / 4, pg);
556 if (res != ERROR_OK) {
557 free(pg);
558 return res;
559 }
560
561 /* Insert our partial page over the data from Flash */
562 memcpy(pg + (page_offset % chip->page_size), buf, nb);
563
564 /* Write the page back out */
565 res = sam4l_write_page(chip, bank->target, address, pg);
566 free(pg);
567
568 return res;
569 }
570
571 static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,
572 uint32_t offset, uint32_t count)
573 {
574 int res;
575 uint32_t nb = 0;
576 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
577
578 LOG_DEBUG("sam4l_write offset=%08" PRIx32 " count=%08" PRIx32, offset, count);
579
580 if (bank->target->state != TARGET_HALTED) {
581 LOG_ERROR("Target not halted");
582
583 return ERROR_TARGET_NOT_HALTED;
584 }
585
586 if (!chip->probed) {
587 if (sam4l_probe(bank) != ERROR_OK)
588 return ERROR_FLASH_BANK_NOT_PROBED;
589 }
590
591 if (offset % chip->page_size) {
592 /* We're starting at an unaligned offset so we'll write a partial page
593 * comprising that offset and up to the end of that page. */
594 nb = chip->page_size - (offset % chip->page_size);
595 if (nb > count)
596 nb = count;
597 } else if (count < chip->page_size) {
598 /* We're writing an aligned but partial page. */
599 nb = count;
600 }
601
602 if (nb > 0) {
603 res = sam4l_write_page_partial(chip, bank,
604 (offset / chip->page_size) * chip->page_size + bank->base,
605 buffer,
606 offset % chip->page_size, nb);
607 if (res != ERROR_OK)
608 return res;
609
610 /* We're done with the page contents */
611 count -= nb;
612 offset += nb;
613 }
614
615 /* There's at least one aligned page to write out. */
616 if (count >= chip->page_size) {
617 int np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0);
618
619 for (int i = 0; i < np; i++) {
620 if (count >= chip->page_size) {
621 res = sam4l_write_page(chip, bank->target,
622 bank->base + offset,
623 buffer + (i * chip->page_size));
624 /* Advance one page */
625 offset += chip->page_size;
626 count -= chip->page_size;
627 } else {
628 res = sam4l_write_page_partial(chip, bank,
629 bank->base + offset,
630 buffer + (i * chip->page_size), 0, count);
631 /* We're done after this. */
632 offset += count;
633 count = 0;
634 }
635
636 if (res != ERROR_OK)
637 return res;
638 }
639 }
640
641 return ERROR_OK;
642 }
643
644
645 COMMAND_HANDLER(sam4l_handle_reset_deassert)
646 {
647 struct target *target = get_current_target(CMD_CTX);
648 struct armv7m_common *armv7m = target_to_armv7m(target);
649 int retval = ERROR_OK;
650 enum reset_types jtag_reset_config = jtag_get_reset_config();
651
652 /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
653 * so we just release reset held by SMAP
654 *
655 * n_RESET (srst) clears the DP, so reenable debug and set vector catch here
656 *
657 * After vectreset SMAP release is not needed however makes no harm
658 */
659 if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
660 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
661 if (retval == ERROR_OK)
662 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
663 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
664 /* do not return on error here, releasing SMAP reset is more important */
665 }
666
667 int retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, SMAP_SCR, SMAP_SCR_HCR);
668 if (retval2 != ERROR_OK)
669 return retval2;
670
671 return retval;
672 }
673
674 static const struct command_registration at91sam4l_exec_command_handlers[] = {
675 {
676 .name = "smap_reset_deassert",
677 .handler = sam4l_handle_reset_deassert,
678 .mode = COMMAND_EXEC,
679 .help = "deasert internal reset held by SMAP"
680 },
681 COMMAND_REGISTRATION_DONE
682 };
683
684 static const struct command_registration at91sam4l_command_handlers[] = {
685 {
686 .name = "at91sam4l",
687 .mode = COMMAND_ANY,
688 .help = "at91sam4l flash command group",
689 .usage = "",
690 .chain = at91sam4l_exec_command_handlers,
691 },
692 COMMAND_REGISTRATION_DONE
693 };
694
695 struct flash_driver at91sam4l_flash = {
696 .name = "at91sam4l",
697 .commands = at91sam4l_command_handlers,
698 .flash_bank_command = sam4l_flash_bank_command,
699 .erase = sam4l_erase,
700 .protect = sam4l_protect,
701 .write = sam4l_write,
702 .read = default_flash_read,
703 .probe = sam4l_probe,
704 .auto_probe = sam4l_probe,
705 .erase_check = default_flash_blank_check,
706 .protect_check = sam4l_protect_check,
707 };

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)