at91sam3: fix warnings
[openocd/jflash.git] / src / flash / nor / at91sam3.c
blob43db51d8bf6469304b69dab716329443aa0ec8e6
1 /***************************************************************************
2 * Copyright (C) 2009 by Duane Ellis *
3 * openocd@duaneellis.com *
4 * *
5 * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
6 * olaf@uni-paderborn.de *
7 * *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
17 * GNU General public License for more details. *
18 * *
19 * You should have received a copy of the GNU General public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ****************************************************************************/
25 /* Some of the the lower level code was based on code supplied by
26 * ATMEL under this copyright. */
28 /* BEGIN ATMEL COPYRIGHT */
29 /* ----------------------------------------------------------------------------
30 * ATMEL Microcontroller Software Support
31 * ----------------------------------------------------------------------------
32 * Copyright (c) 2009, Atmel Corporation
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions are met:
39 * - Redistributions of source code must retain the above copyright notice,
40 * this list of conditions and the disclaimer below.
42 * Atmel's name may not be used to endorse or promote products derived from
43 * this software without specific prior written permission.
45 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
48 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
51 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
54 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 * ----------------------------------------------------------------------------
57 /* END ATMEL COPYRIGHT */
59 #ifdef HAVE_CONFIG_H
60 #include "config.h"
61 #endif
64 #include "imp.h"
65 #include <helper/time_support.h>
67 #define REG_NAME_WIDTH (12)
69 // at91sam3u series (has one or two flash banks)
70 #define FLASH_BANK0_BASE_U 0x00080000
71 #define FLASH_BANK1_BASE_U 0x00100000
73 // at91sam3s series (has always one flash bank)
74 #define FLASH_BANK_BASE_S 0x00400000
76 // at91sam3n series (has always one flash bank)
77 #define FLASH_BANK_BASE_N 0x00400000
79 #define AT91C_EFC_FCMD_GETD (0x0) // (EFC) Get Flash Descriptor
80 #define AT91C_EFC_FCMD_WP (0x1) // (EFC) Write Page
81 #define AT91C_EFC_FCMD_WPL (0x2) // (EFC) Write Page and Lock
82 #define AT91C_EFC_FCMD_EWP (0x3) // (EFC) Erase Page and Write Page
83 #define AT91C_EFC_FCMD_EWPL (0x4) // (EFC) Erase Page and Write Page then Lock
84 #define AT91C_EFC_FCMD_EA (0x5) // (EFC) Erase All
85 // cmd6 is not present int he at91sam3u4/2/1 data sheet table 17-2
86 // #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane?
87 // cmd7 is not present int he at91sam3u4/2/1 data sheet table 17-2
88 // #define AT91C_EFC_FCMD_EPA (0x7) // (EFC) Erase pages?
89 #define AT91C_EFC_FCMD_SLB (0x8) // (EFC) Set Lock Bit
90 #define AT91C_EFC_FCMD_CLB (0x9) // (EFC) Clear Lock Bit
91 #define AT91C_EFC_FCMD_GLB (0xA) // (EFC) Get Lock Bit
92 #define AT91C_EFC_FCMD_SFB (0xB) // (EFC) Set Fuse Bit
93 #define AT91C_EFC_FCMD_CFB (0xC) // (EFC) Clear Fuse Bit
94 #define AT91C_EFC_FCMD_GFB (0xD) // (EFC) Get Fuse Bit
95 #define AT91C_EFC_FCMD_STUI (0xE) // (EFC) Start Read Unique ID
96 #define AT91C_EFC_FCMD_SPUI (0xF) // (EFC) Stop Read Unique ID
98 #define offset_EFC_FMR 0
99 #define offset_EFC_FCR 4
100 #define offset_EFC_FSR 8
101 #define offset_EFC_FRR 12
104 extern struct flash_driver at91sam3_flash;
106 static float
107 _tomhz(uint32_t freq_hz)
109 float f;
111 f = ((float)(freq_hz)) / 1000000.0;
112 return f;
115 // How the chip is configured.
116 struct sam3_cfg {
117 uint32_t unique_id[4];
119 uint32_t slow_freq;
120 uint32_t rc_freq;
121 uint32_t mainosc_freq;
122 uint32_t plla_freq;
123 uint32_t mclk_freq;
124 uint32_t cpu_freq;
125 uint32_t fclk_freq;
126 uint32_t pclk0_freq;
127 uint32_t pclk1_freq;
128 uint32_t pclk2_freq;
131 #define SAM3_CHIPID_CIDR (0x400E0740)
132 uint32_t CHIPID_CIDR;
133 #define SAM3_CHIPID_EXID (0x400E0744)
134 uint32_t CHIPID_EXID;
136 #define SAM3_SUPC_CR (0x400E1210)
137 uint32_t SUPC_CR;
139 #define SAM3_PMC_BASE (0x400E0400)
140 #define SAM3_PMC_SCSR (SAM3_PMC_BASE + 0x0008)
141 uint32_t PMC_SCSR;
142 #define SAM3_PMC_PCSR (SAM3_PMC_BASE + 0x0018)
143 uint32_t PMC_PCSR;
144 #define SAM3_CKGR_UCKR (SAM3_PMC_BASE + 0x001c)
145 uint32_t CKGR_UCKR;
146 #define SAM3_CKGR_MOR (SAM3_PMC_BASE + 0x0020)
147 uint32_t CKGR_MOR;
148 #define SAM3_CKGR_MCFR (SAM3_PMC_BASE + 0x0024)
149 uint32_t CKGR_MCFR;
150 #define SAM3_CKGR_PLLAR (SAM3_PMC_BASE + 0x0028)
151 uint32_t CKGR_PLLAR;
152 #define SAM3_PMC_MCKR (SAM3_PMC_BASE + 0x0030)
153 uint32_t PMC_MCKR;
154 #define SAM3_PMC_PCK0 (SAM3_PMC_BASE + 0x0040)
155 uint32_t PMC_PCK0;
156 #define SAM3_PMC_PCK1 (SAM3_PMC_BASE + 0x0044)
157 uint32_t PMC_PCK1;
158 #define SAM3_PMC_PCK2 (SAM3_PMC_BASE + 0x0048)
159 uint32_t PMC_PCK2;
160 #define SAM3_PMC_SR (SAM3_PMC_BASE + 0x0068)
161 uint32_t PMC_SR;
162 #define SAM3_PMC_IMR (SAM3_PMC_BASE + 0x006c)
163 uint32_t PMC_IMR;
164 #define SAM3_PMC_FSMR (SAM3_PMC_BASE + 0x0070)
165 uint32_t PMC_FSMR;
166 #define SAM3_PMC_FSPR (SAM3_PMC_BASE + 0x0074)
167 uint32_t PMC_FSPR;
171 struct sam3_bank_private {
172 int probed;
173 // DANGER: THERE ARE DRAGONS HERE..
174 // NOTE: If you add more 'ghost' pointers
175 // be aware that you must *manually* update
176 // these pointers in the function sam3_GetDetails()
177 // See the comment "Here there be dragons"
179 // so we can find the chip we belong to
180 struct sam3_chip *pChip;
181 // so we can find the orginal bank pointer
182 struct flash_bank *pBank;
183 unsigned bank_number;
184 uint32_t controller_address;
185 uint32_t base_address;
186 bool present;
187 unsigned size_bytes;
188 unsigned nsectors;
189 unsigned sector_size;
190 unsigned page_size;
193 struct sam3_chip_details {
194 // THERE ARE DRAGONS HERE..
195 // note: If you add pointers here
196 // becareful about them as they
197 // may need to be updated inside
198 // the function: "sam3_GetDetails()
199 // which copy/overwrites the
200 // 'runtime' copy of this structure
201 uint32_t chipid_cidr;
202 const char *name;
204 unsigned n_gpnvms;
205 #define SAM3_N_NVM_BITS 3
206 unsigned gpnvm[SAM3_N_NVM_BITS];
207 unsigned total_flash_size;
208 unsigned total_sram_size;
209 unsigned n_banks;
210 #define SAM3_MAX_FLASH_BANKS 2
211 // these are "initialized" from the global const data
212 struct sam3_bank_private bank[SAM3_MAX_FLASH_BANKS];
216 struct sam3_chip {
217 struct sam3_chip *next;
218 int probed;
220 // this is "initialized" from the global const structure
221 struct sam3_chip_details details;
222 struct target *target;
223 struct sam3_cfg cfg;
227 struct sam3_reg_list {
228 uint32_t address; size_t struct_offset; const char *name;
229 void (*explain_func)(struct sam3_chip *pInfo);
233 static struct sam3_chip *all_sam3_chips;
235 static struct sam3_chip *
236 get_current_sam3(struct command_context *cmd_ctx)
238 struct target *t;
239 static struct sam3_chip *p;
241 t = get_current_target(cmd_ctx);
242 if (!t) {
243 command_print(cmd_ctx, "No current target?");
244 return NULL;
247 p = all_sam3_chips;
248 if (!p) {
249 // this should not happen
250 // the command is not registered until the chip is created?
251 command_print(cmd_ctx, "No SAM3 chips exist?");
252 return NULL;
255 while (p) {
256 if (p->target == t) {
257 return p;
259 p = p->next;
261 command_print(cmd_ctx, "Cannot find SAM3 chip?");
262 return NULL;
266 // these are used to *initialize* the "pChip->details" structure.
267 static const struct sam3_chip_details all_sam3_details[] = {
268 // Start at91sam3u* series
270 .chipid_cidr = 0x28100960,
271 .name = "at91sam3u4e",
272 .total_flash_size = 256 * 1024,
273 .total_sram_size = 52 * 1024,
274 .n_gpnvms = 3,
275 .n_banks = 2,
277 // System boots at address 0x0
278 // gpnvm[1] = selects boot code
279 // if gpnvm[1] == 0
280 // boot is via "SAMBA" (rom)
281 // else
282 // boot is via FLASH
283 // Selection is via gpnvm[2]
284 // endif
286 // NOTE: banks 0 & 1 switch places
287 // if gpnvm[2] == 0
288 // Bank0 is the boot rom
289 // else
290 // Bank1 is the boot rom
291 // endif
292 // .bank[0] = {
295 .probed = 0,
296 .pChip = NULL,
297 .pBank = NULL,
298 .bank_number = 0,
299 .base_address = FLASH_BANK0_BASE_U,
300 .controller_address = 0x400e0800,
301 .present = 1,
302 .size_bytes = 128 * 1024,
303 .nsectors = 16,
304 .sector_size = 8192,
305 .page_size = 256,
308 // .bank[1] = {
310 .probed = 0,
311 .pChip = NULL,
312 .pBank = NULL,
313 .bank_number = 1,
314 .base_address = FLASH_BANK1_BASE_U,
315 .controller_address = 0x400e0a00,
316 .present = 1,
317 .size_bytes = 128 * 1024,
318 .nsectors = 16,
319 .sector_size = 8192,
320 .page_size = 256,
326 .chipid_cidr = 0x281a0760,
327 .name = "at91sam3u2e",
328 .total_flash_size = 128 * 1024,
329 .total_sram_size = 36 * 1024,
330 .n_gpnvms = 2,
331 .n_banks = 1,
333 // System boots at address 0x0
334 // gpnvm[1] = selects boot code
335 // if gpnvm[1] == 0
336 // boot is via "SAMBA" (rom)
337 // else
338 // boot is via FLASH
339 // Selection is via gpnvm[2]
340 // endif
341 // .bank[0] = {
344 .probed = 0,
345 .pChip = NULL,
346 .pBank = NULL,
347 .bank_number = 0,
348 .base_address = FLASH_BANK0_BASE_U,
349 .controller_address = 0x400e0800,
350 .present = 1,
351 .size_bytes = 128 * 1024,
352 .nsectors = 16,
353 .sector_size = 8192,
354 .page_size = 256,
356 // .bank[1] = {
358 .present = 0,
359 .probed = 0,
360 .bank_number = 1,
365 .chipid_cidr = 0x28190560,
366 .name = "at91sam3u1e",
367 .total_flash_size = 64 * 1024,
368 .total_sram_size = 20 * 1024,
369 .n_gpnvms = 2,
370 .n_banks = 1,
372 // System boots at address 0x0
373 // gpnvm[1] = selects boot code
374 // if gpnvm[1] == 0
375 // boot is via "SAMBA" (rom)
376 // else
377 // boot is via FLASH
378 // Selection is via gpnvm[2]
379 // endif
382 // .bank[0] = {
385 .probed = 0,
386 .pChip = NULL,
387 .pBank = NULL,
388 .bank_number = 0,
389 .base_address = FLASH_BANK0_BASE_U,
390 .controller_address = 0x400e0800,
391 .present = 1,
392 .size_bytes = 64 * 1024,
393 .nsectors = 8,
394 .sector_size = 8192,
395 .page_size = 256,
398 // .bank[1] = {
400 .present = 0,
401 .probed = 0,
402 .bank_number = 1,
408 .chipid_cidr = 0x28000960,
409 .name = "at91sam3u4c",
410 .total_flash_size = 256 * 1024,
411 .total_sram_size = 52 * 1024,
412 .n_gpnvms = 3,
413 .n_banks = 2,
415 // System boots at address 0x0
416 // gpnvm[1] = selects boot code
417 // if gpnvm[1] == 0
418 // boot is via "SAMBA" (rom)
419 // else
420 // boot is via FLASH
421 // Selection is via gpnvm[2]
422 // endif
424 // NOTE: banks 0 & 1 switch places
425 // if gpnvm[2] == 0
426 // Bank0 is the boot rom
427 // else
428 // Bank1 is the boot rom
429 // endif
432 // .bank[0] = {
433 .probed = 0,
434 .pChip = NULL,
435 .pBank = NULL,
436 .bank_number = 0,
437 .base_address = FLASH_BANK0_BASE_U,
438 .controller_address = 0x400e0800,
439 .present = 1,
440 .size_bytes = 128 * 1024,
441 .nsectors = 16,
442 .sector_size = 8192,
443 .page_size = 256,
445 // .bank[1] = {
447 .probed = 0,
448 .pChip = NULL,
449 .pBank = NULL,
450 .bank_number = 1,
451 .base_address = FLASH_BANK1_BASE_U,
452 .controller_address = 0x400e0a00,
453 .present = 1,
454 .size_bytes = 128 * 1024,
455 .nsectors = 16,
456 .sector_size = 8192,
457 .page_size = 256,
463 .chipid_cidr = 0x280a0760,
464 .name = "at91sam3u2c",
465 .total_flash_size = 128 * 1024,
466 .total_sram_size = 36 * 1024,
467 .n_gpnvms = 2,
468 .n_banks = 1,
470 // System boots at address 0x0
471 // gpnvm[1] = selects boot code
472 // if gpnvm[1] == 0
473 // boot is via "SAMBA" (rom)
474 // else
475 // boot is via FLASH
476 // Selection is via gpnvm[2]
477 // endif
479 // .bank[0] = {
481 .probed = 0,
482 .pChip = NULL,
483 .pBank = NULL,
484 .bank_number = 0,
485 .base_address = FLASH_BANK0_BASE_U,
486 .controller_address = 0x400e0800,
487 .present = 1,
488 .size_bytes = 128 * 1024,
489 .nsectors = 16,
490 .sector_size = 8192,
491 .page_size = 256,
493 // .bank[1] = {
495 .present = 0,
496 .probed = 0,
497 .bank_number = 1,
502 .chipid_cidr = 0x28090560,
503 .name = "at91sam3u1c",
504 .total_flash_size = 64 * 1024,
505 .total_sram_size = 20 * 1024,
506 .n_gpnvms = 2,
507 .n_banks = 1,
509 // System boots at address 0x0
510 // gpnvm[1] = selects boot code
511 // if gpnvm[1] == 0
512 // boot is via "SAMBA" (rom)
513 // else
514 // boot is via FLASH
515 // Selection is via gpnvm[2]
516 // endif
520 // .bank[0] = {
522 .probed = 0,
523 .pChip = NULL,
524 .pBank = NULL,
525 .bank_number = 0,
526 .base_address = FLASH_BANK0_BASE_U,
527 .controller_address = 0x400e0800,
528 .present = 1,
529 .size_bytes = 64 * 1024,
530 .nsectors = 8,
531 .sector_size = 8192,
532 .page_size = 256,
534 // .bank[1] = {
536 .present = 0,
537 .probed = 0,
538 .bank_number = 1,
544 // Start at91sam3s* series
546 // Note: The preliminary at91sam3s datasheet says on page 302
547 // that the flash controller is at address 0x400E0800.
548 // This is _not_ the case, the controller resides at address 0x400e0a0.
550 .chipid_cidr = 0x28A00960,
551 .name = "at91sam3s4c",
552 .total_flash_size = 256 * 1024,
553 .total_sram_size = 48 * 1024,
554 .n_gpnvms = 2,
555 .n_banks = 1,
557 // .bank[0] = {
559 .probed = 0,
560 .pChip = NULL,
561 .pBank = NULL,
562 .bank_number = 0,
563 .base_address = FLASH_BANK_BASE_S,
565 .controller_address = 0x400e0a00,
566 .present = 1,
567 .size_bytes = 256 * 1024,
568 .nsectors = 32,
569 .sector_size = 8192,
570 .page_size = 256,
572 // .bank[1] = {
574 .present = 0,
575 .probed = 0,
576 .bank_number = 1,
583 .chipid_cidr = 0x28900960,
584 .name = "at91sam3s4b",
585 .total_flash_size = 256 * 1024,
586 .total_sram_size = 48 * 1024,
587 .n_gpnvms = 2,
588 .n_banks = 1,
590 // .bank[0] = {
592 .probed = 0,
593 .pChip = NULL,
594 .pBank = NULL,
595 .bank_number = 0,
596 .base_address = FLASH_BANK_BASE_S,
598 .controller_address = 0x400e0a00,
599 .present = 1,
600 .size_bytes = 256 * 1024,
601 .nsectors = 32,
602 .sector_size = 8192,
603 .page_size = 256,
605 // .bank[1] = {
607 .present = 0,
608 .probed = 0,
609 .bank_number = 1,
615 .chipid_cidr = 0x28800960,
616 .name = "at91sam3s4a",
617 .total_flash_size = 256 * 1024,
618 .total_sram_size = 48 * 1024,
619 .n_gpnvms = 2,
620 .n_banks = 1,
622 // .bank[0] = {
624 .probed = 0,
625 .pChip = NULL,
626 .pBank = NULL,
627 .bank_number = 0,
628 .base_address = FLASH_BANK_BASE_S,
630 .controller_address = 0x400e0a00,
631 .present = 1,
632 .size_bytes = 256 * 1024,
633 .nsectors = 32,
634 .sector_size = 8192,
635 .page_size = 256,
637 // .bank[1] = {
639 .present = 0,
640 .probed = 0,
641 .bank_number = 1,
647 .chipid_cidr = 0x28AA0760,
648 .name = "at91sam3s2c",
649 .total_flash_size = 128 * 1024,
650 .total_sram_size = 32 * 1024,
651 .n_gpnvms = 2,
652 .n_banks = 1,
654 // .bank[0] = {
656 .probed = 0,
657 .pChip = NULL,
658 .pBank = NULL,
659 .bank_number = 0,
660 .base_address = FLASH_BANK_BASE_S,
662 .controller_address = 0x400e0a00,
663 .present = 1,
664 .size_bytes = 128 * 1024,
665 .nsectors = 16,
666 .sector_size = 8192,
667 .page_size = 256,
669 // .bank[1] = {
671 .present = 0,
672 .probed = 0,
673 .bank_number = 1,
679 .chipid_cidr = 0x289A0760,
680 .name = "at91sam3s2b",
681 .total_flash_size = 128 * 1024,
682 .total_sram_size = 32 * 1024,
683 .n_gpnvms = 2,
684 .n_banks = 1,
686 // .bank[0] = {
688 .probed = 0,
689 .pChip = NULL,
690 .pBank = NULL,
691 .bank_number = 0,
692 .base_address = FLASH_BANK_BASE_S,
694 .controller_address = 0x400e0a00,
695 .present = 1,
696 .size_bytes = 128 * 1024,
697 .nsectors = 16,
698 .sector_size = 8192,
699 .page_size = 256,
701 // .bank[1] = {
703 .present = 0,
704 .probed = 0,
705 .bank_number = 1,
711 .chipid_cidr = 0x288A0760,
712 .name = "at91sam3s2a",
713 .total_flash_size = 128 * 1024,
714 .total_sram_size = 32 * 1024,
715 .n_gpnvms = 2,
716 .n_banks = 1,
718 // .bank[0] = {
720 .probed = 0,
721 .pChip = NULL,
722 .pBank = NULL,
723 .bank_number = 0,
724 .base_address = FLASH_BANK_BASE_S,
726 .controller_address = 0x400e0a00,
727 .present = 1,
728 .size_bytes = 128 * 1024,
729 .nsectors = 16,
730 .sector_size = 8192,
731 .page_size = 256,
733 // .bank[1] = {
735 .present = 0,
736 .probed = 0,
737 .bank_number = 1,
743 .chipid_cidr = 0x28A90560,
744 .name = "at91sam3s1c",
745 .total_flash_size = 64 * 1024,
746 .total_sram_size = 16 * 1024,
747 .n_gpnvms = 2,
748 .n_banks = 1,
750 // .bank[0] = {
752 .probed = 0,
753 .pChip = NULL,
754 .pBank = NULL,
755 .bank_number = 0,
756 .base_address = FLASH_BANK_BASE_S,
758 .controller_address = 0x400e0a00,
759 .present = 1,
760 .size_bytes = 64 * 1024,
761 .nsectors = 8,
762 .sector_size = 8192,
763 .page_size = 256,
765 // .bank[1] = {
767 .present = 0,
768 .probed = 0,
769 .bank_number = 1,
775 .chipid_cidr = 0x28990560,
776 .name = "at91sam3s1b",
777 .total_flash_size = 64 * 1024,
778 .total_sram_size = 16 * 1024,
779 .n_gpnvms = 2,
780 .n_banks = 1,
782 // .bank[0] = {
784 .probed = 0,
785 .pChip = NULL,
786 .pBank = NULL,
787 .bank_number = 0,
788 .base_address = FLASH_BANK_BASE_S,
790 .controller_address = 0x400e0a00,
791 .present = 1,
792 .size_bytes = 64 * 1024,
793 .nsectors = 8,
794 .sector_size = 8192,
795 .page_size = 256,
797 // .bank[1] = {
799 .present = 0,
800 .probed = 0,
801 .bank_number = 1,
807 .chipid_cidr = 0x28890560,
808 .name = "at91sam3s1a",
809 .total_flash_size = 64 * 1024,
810 .total_sram_size = 16 * 1024,
811 .n_gpnvms = 2,
812 .n_banks = 1,
814 // .bank[0] = {
816 .probed = 0,
817 .pChip = NULL,
818 .pBank = NULL,
819 .bank_number = 0,
820 .base_address = FLASH_BANK_BASE_S,
822 .controller_address = 0x400e0a00,
823 .present = 1,
824 .size_bytes = 64 * 1024,
825 .nsectors = 8,
826 .sector_size = 8192,
827 .page_size = 256,
829 // .bank[1] = {
831 .present = 0,
832 .probed = 0,
833 .bank_number = 1,
839 // Start at91sam3n* series
841 .chipid_cidr = 0x29540960,
842 .name = "at91sam3n4c",
843 .total_flash_size = 256 * 1024,
844 .total_sram_size = 24 * 1024,
845 .n_gpnvms = 3,
846 .n_banks = 1,
848 // System boots at address 0x0
849 // gpnvm[1] = selects boot code
850 // if gpnvm[1] == 0
851 // boot is via "SAMBA" (rom)
852 // else
853 // boot is via FLASH
854 // Selection is via gpnvm[2]
855 // endif
857 // NOTE: banks 0 & 1 switch places
858 // if gpnvm[2] == 0
859 // Bank0 is the boot rom
860 // else
861 // Bank1 is the boot rom
862 // endif
863 // .bank[0] = {
866 .probed = 0,
867 .pChip = NULL,
868 .pBank = NULL,
869 .bank_number = 0,
870 .base_address = FLASH_BANK_BASE_N,
871 .controller_address = 0x400e0A00,
872 .present = 1,
873 .size_bytes = 256 * 1024,
874 .nsectors = 16,
875 .sector_size = 16384,
876 .page_size = 256,
879 // .bank[1] = {
881 .present = 0,
882 .probed = 0,
883 .bank_number = 1,
889 .chipid_cidr = 0x29440960,
890 .name = "at91sam3n4b",
891 .total_flash_size = 256 * 1024,
892 .total_sram_size = 24 * 1024,
893 .n_gpnvms = 3,
894 .n_banks = 1,
896 // System boots at address 0x0
897 // gpnvm[1] = selects boot code
898 // if gpnvm[1] == 0
899 // boot is via "SAMBA" (rom)
900 // else
901 // boot is via FLASH
902 // Selection is via gpnvm[2]
903 // endif
905 // NOTE: banks 0 & 1 switch places
906 // if gpnvm[2] == 0
907 // Bank0 is the boot rom
908 // else
909 // Bank1 is the boot rom
910 // endif
911 // .bank[0] = {
914 .probed = 0,
915 .pChip = NULL,
916 .pBank = NULL,
917 .bank_number = 0,
918 .base_address = FLASH_BANK_BASE_N,
919 .controller_address = 0x400e0A00,
920 .present = 1,
921 .size_bytes = 256 * 1024,
922 .nsectors = 16,
923 .sector_size = 16384,
924 .page_size = 256,
927 // .bank[1] = {
929 .present = 0,
930 .probed = 0,
931 .bank_number = 1,
937 .chipid_cidr = 0x29340960,
938 .name = "at91sam3n4a",
939 .total_flash_size = 256 * 1024,
940 .total_sram_size = 24 * 1024,
941 .n_gpnvms = 3,
942 .n_banks = 1,
944 // System boots at address 0x0
945 // gpnvm[1] = selects boot code
946 // if gpnvm[1] == 0
947 // boot is via "SAMBA" (rom)
948 // else
949 // boot is via FLASH
950 // Selection is via gpnvm[2]
951 // endif
953 // NOTE: banks 0 & 1 switch places
954 // if gpnvm[2] == 0
955 // Bank0 is the boot rom
956 // else
957 // Bank1 is the boot rom
958 // endif
959 // .bank[0] = {
962 .probed = 0,
963 .pChip = NULL,
964 .pBank = NULL,
965 .bank_number = 0,
966 .base_address = FLASH_BANK_BASE_N,
967 .controller_address = 0x400e0A00,
968 .present = 1,
969 .size_bytes = 256 * 1024,
970 .nsectors = 16,
971 .sector_size = 16384,
972 .page_size = 256,
975 // .bank[1] = {
977 .present = 0,
978 .probed = 0,
979 .bank_number = 1,
985 .chipid_cidr = 0x29590760,
986 .name = "at91sam3n2c",
987 .total_flash_size = 128 * 1024,
988 .total_sram_size = 16 * 1024,
989 .n_gpnvms = 3,
990 .n_banks = 1,
992 // System boots at address 0x0
993 // gpnvm[1] = selects boot code
994 // if gpnvm[1] == 0
995 // boot is via "SAMBA" (rom)
996 // else
997 // boot is via FLASH
998 // Selection is via gpnvm[2]
999 // endif
1001 // NOTE: banks 0 & 1 switch places
1002 // if gpnvm[2] == 0
1003 // Bank0 is the boot rom
1004 // else
1005 // Bank1 is the boot rom
1006 // endif
1007 // .bank[0] = {
1010 .probed = 0,
1011 .pChip = NULL,
1012 .pBank = NULL,
1013 .bank_number = 0,
1014 .base_address = FLASH_BANK_BASE_N,
1015 .controller_address = 0x400e0A00,
1016 .present = 1,
1017 .size_bytes = 128 * 1024,
1018 .nsectors = 8,
1019 .sector_size = 16384,
1020 .page_size = 256,
1023 // .bank[1] = {
1025 .present = 0,
1026 .probed = 0,
1027 .bank_number = 1,
1033 .chipid_cidr = 0x29490760,
1034 .name = "at91sam3n2b",
1035 .total_flash_size = 128 * 1024,
1036 .total_sram_size = 16 * 1024,
1037 .n_gpnvms = 3,
1038 .n_banks = 1,
1040 // System boots at address 0x0
1041 // gpnvm[1] = selects boot code
1042 // if gpnvm[1] == 0
1043 // boot is via "SAMBA" (rom)
1044 // else
1045 // boot is via FLASH
1046 // Selection is via gpnvm[2]
1047 // endif
1049 // NOTE: banks 0 & 1 switch places
1050 // if gpnvm[2] == 0
1051 // Bank0 is the boot rom
1052 // else
1053 // Bank1 is the boot rom
1054 // endif
1055 // .bank[0] = {
1058 .probed = 0,
1059 .pChip = NULL,
1060 .pBank = NULL,
1061 .bank_number = 0,
1062 .base_address = FLASH_BANK_BASE_N,
1063 .controller_address = 0x400e0A00,
1064 .present = 1,
1065 .size_bytes = 128 * 1024,
1066 .nsectors = 8,
1067 .sector_size = 16384,
1068 .page_size = 256,
1071 // .bank[1] = {
1073 .present = 0,
1074 .probed = 0,
1075 .bank_number = 1,
1081 .chipid_cidr = 0x29390760,
1082 .name = "at91sam3n2a",
1083 .total_flash_size = 128 * 1024,
1084 .total_sram_size = 16 * 1024,
1085 .n_gpnvms = 3,
1086 .n_banks = 1,
1088 // System boots at address 0x0
1089 // gpnvm[1] = selects boot code
1090 // if gpnvm[1] == 0
1091 // boot is via "SAMBA" (rom)
1092 // else
1093 // boot is via FLASH
1094 // Selection is via gpnvm[2]
1095 // endif
1097 // NOTE: banks 0 & 1 switch places
1098 // if gpnvm[2] == 0
1099 // Bank0 is the boot rom
1100 // else
1101 // Bank1 is the boot rom
1102 // endif
1103 // .bank[0] = {
1106 .probed = 0,
1107 .pChip = NULL,
1108 .pBank = NULL,
1109 .bank_number = 0,
1110 .base_address = FLASH_BANK_BASE_N,
1111 .controller_address = 0x400e0A00,
1112 .present = 1,
1113 .size_bytes = 128 * 1024,
1114 .nsectors = 8,
1115 .sector_size = 16384,
1116 .page_size = 256,
1119 // .bank[1] = {
1121 .present = 0,
1122 .probed = 0,
1123 .bank_number = 1,
1129 .chipid_cidr = 0x29580560,
1130 .name = "at91sam3n1c",
1131 .total_flash_size = 64 * 1024,
1132 .total_sram_size = 8 * 1024,
1133 .n_gpnvms = 3,
1134 .n_banks = 1,
1136 // System boots at address 0x0
1137 // gpnvm[1] = selects boot code
1138 // if gpnvm[1] == 0
1139 // boot is via "SAMBA" (rom)
1140 // else
1141 // boot is via FLASH
1142 // Selection is via gpnvm[2]
1143 // endif
1145 // NOTE: banks 0 & 1 switch places
1146 // if gpnvm[2] == 0
1147 // Bank0 is the boot rom
1148 // else
1149 // Bank1 is the boot rom
1150 // endif
1151 // .bank[0] = {
1154 .probed = 0,
1155 .pChip = NULL,
1156 .pBank = NULL,
1157 .bank_number = 0,
1158 .base_address = FLASH_BANK_BASE_N,
1159 .controller_address = 0x400e0A00,
1160 .present = 1,
1161 .size_bytes = 64 * 1024,
1162 .nsectors = 4,
1163 .sector_size = 16384,
1164 .page_size = 256,
1167 // .bank[1] = {
1169 .present = 0,
1170 .probed = 0,
1171 .bank_number = 1,
1177 .chipid_cidr = 0x29480560,
1178 .name = "at91sam3n1b",
1179 .total_flash_size = 64 * 1024,
1180 .total_sram_size = 8 * 1024,
1181 .n_gpnvms = 3,
1182 .n_banks = 1,
1184 // System boots at address 0x0
1185 // gpnvm[1] = selects boot code
1186 // if gpnvm[1] == 0
1187 // boot is via "SAMBA" (rom)
1188 // else
1189 // boot is via FLASH
1190 // Selection is via gpnvm[2]
1191 // endif
1193 // NOTE: banks 0 & 1 switch places
1194 // if gpnvm[2] == 0
1195 // Bank0 is the boot rom
1196 // else
1197 // Bank1 is the boot rom
1198 // endif
1199 // .bank[0] = {
1202 .probed = 0,
1203 .pChip = NULL,
1204 .pBank = NULL,
1205 .bank_number = 0,
1206 .base_address = FLASH_BANK_BASE_N,
1207 .controller_address = 0x400e0A00,
1208 .present = 1,
1209 .size_bytes = 64 * 1024,
1210 .nsectors = 4,
1211 .sector_size = 16384,
1212 .page_size = 256,
1215 // .bank[1] = {
1217 .present = 0,
1218 .probed = 0,
1219 .bank_number = 1,
1225 .chipid_cidr = 0x29380560,
1226 .name = "at91sam3n1a",
1227 .total_flash_size = 64 * 1024,
1228 .total_sram_size = 8 * 1024,
1229 .n_gpnvms = 3,
1230 .n_banks = 1,
1232 // System boots at address 0x0
1233 // gpnvm[1] = selects boot code
1234 // if gpnvm[1] == 0
1235 // boot is via "SAMBA" (rom)
1236 // else
1237 // boot is via FLASH
1238 // Selection is via gpnvm[2]
1239 // endif
1241 // NOTE: banks 0 & 1 switch places
1242 // if gpnvm[2] == 0
1243 // Bank0 is the boot rom
1244 // else
1245 // Bank1 is the boot rom
1246 // endif
1247 // .bank[0] = {
1250 .probed = 0,
1251 .pChip = NULL,
1252 .pBank = NULL,
1253 .bank_number = 0,
1254 .base_address = FLASH_BANK_BASE_N,
1255 .controller_address = 0x400e0A00,
1256 .present = 1,
1257 .size_bytes = 64 * 1024,
1258 .nsectors = 4,
1259 .sector_size = 16384,
1260 .page_size = 256,
1263 // .bank[1] = {
1265 .present = 0,
1266 .probed = 0,
1267 .bank_number = 1,
1272 // terminate
1274 .chipid_cidr = 0,
1275 .name = NULL,
1279 /* Globals above */
1280 /***********************************************************************
1281 **********************************************************************
1282 **********************************************************************
1283 **********************************************************************
1284 **********************************************************************
1285 **********************************************************************/
1286 /* *ATMEL* style code - from the SAM3 driver code */
1289 * Get the current status of the EEFC and
1290 * the value of some status bits (LOCKE, PROGE).
1291 * @param pPrivate - info about the bank
1292 * @param v - result goes here
1294 static int
1295 EFC_GetStatus(struct sam3_bank_private *pPrivate, uint32_t *v)
1297 int r;
1298 r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address + offset_EFC_FSR, v);
1299 LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)",
1300 (unsigned int)(*v),
1301 ((unsigned int)((*v >> 2) & 1)),
1302 ((unsigned int)((*v >> 1) & 1)),
1303 ((unsigned int)((*v >> 0) & 1)));
1305 return r;
1309 * Get the result of the last executed command.
1310 * @param pPrivate - info about the bank
1311 * @param v - result goes here
1313 static int
1314 EFC_GetResult(struct sam3_bank_private *pPrivate, uint32_t *v)
1316 int r;
1317 uint32_t rv;
1318 r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address + offset_EFC_FRR, &rv);
1319 if (v) {
1320 *v = rv;
1322 LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv)));
1323 return r;
1326 static int
1327 EFC_StartCommand(struct sam3_bank_private *pPrivate,
1328 unsigned command, unsigned argument)
1330 uint32_t n,v;
1331 int r;
1332 int retry;
1334 retry = 0;
1335 do_retry:
1337 // Check command & argument
1338 switch (command) {
1340 case AT91C_EFC_FCMD_WP:
1341 case AT91C_EFC_FCMD_WPL:
1342 case AT91C_EFC_FCMD_EWP:
1343 case AT91C_EFC_FCMD_EWPL:
1344 // case AT91C_EFC_FCMD_EPL:
1345 // case AT91C_EFC_FCMD_EPA:
1346 case AT91C_EFC_FCMD_SLB:
1347 case AT91C_EFC_FCMD_CLB:
1348 n = (pPrivate->size_bytes / pPrivate->page_size);
1349 if (argument >= n) {
1350 LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
1352 break;
1354 case AT91C_EFC_FCMD_SFB:
1355 case AT91C_EFC_FCMD_CFB:
1356 if (argument >= pPrivate->pChip->details.n_gpnvms) {
1357 LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs",
1358 pPrivate->pChip->details.n_gpnvms);
1360 break;
1362 case AT91C_EFC_FCMD_GETD:
1363 case AT91C_EFC_FCMD_EA:
1364 case AT91C_EFC_FCMD_GLB:
1365 case AT91C_EFC_FCMD_GFB:
1366 case AT91C_EFC_FCMD_STUI:
1367 case AT91C_EFC_FCMD_SPUI:
1368 if (argument != 0) {
1369 LOG_ERROR("Argument is meaningless for cmd: %d", command);
1371 break;
1372 default:
1373 LOG_ERROR("Unknown command %d", command);
1374 break;
1377 if (command == AT91C_EFC_FCMD_SPUI) {
1378 // this is a very special situation.
1379 // Situation (1) - error/retry - see below
1380 // And we are being called recursively
1381 // Situation (2) - normal, finished reading unique id
1382 } else {
1383 // it should be "ready"
1384 EFC_GetStatus(pPrivate, &v);
1385 if (v & 1) {
1386 // then it is ready
1387 // we go on
1388 } else {
1389 if (retry) {
1390 // we have done this before
1391 // the controller is not responding.
1392 LOG_ERROR("flash controller(%d) is not ready! Error", pPrivate->bank_number);
1393 return ERROR_FAIL;
1394 } else {
1395 retry++;
1396 LOG_ERROR("Flash controller(%d) is not ready, attempting reset",
1397 pPrivate->bank_number);
1398 // we do that by issuing the *STOP* command
1399 EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0);
1400 // above is recursive, and further recursion is blocked by
1401 // if (command == AT91C_EFC_FCMD_SPUI) above
1402 goto do_retry;
1407 v = (0x5A << 24) | (argument << 8) | command;
1408 LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v)));
1409 r = target_write_u32(pPrivate->pBank->target,
1410 pPrivate->controller_address + offset_EFC_FCR,
1412 if (r != ERROR_OK) {
1413 LOG_DEBUG("Error Write failed");
1415 return r;
1419 * Performs the given command and wait until its completion (or an error).
1420 * @param pPrivate - info about the bank
1421 * @param command - Command to perform.
1422 * @param argument - Optional command argument.
1423 * @param status - put command status bits here
1425 static int
1426 EFC_PerformCommand(struct sam3_bank_private *pPrivate,
1427 unsigned command,
1428 unsigned argument,
1429 uint32_t *status)
1432 int r;
1433 uint32_t v;
1434 long long ms_now, ms_end;
1436 // default
1437 if (status) {
1438 *status = 0;
1441 r = EFC_StartCommand(pPrivate, command, argument);
1442 if (r != ERROR_OK) {
1443 return r;
1446 ms_end = 500 + timeval_ms();
1449 do {
1450 r = EFC_GetStatus(pPrivate, &v);
1451 if (r != ERROR_OK) {
1452 return r;
1454 ms_now = timeval_ms();
1455 if (ms_now > ms_end) {
1456 // error
1457 LOG_ERROR("Command timeout");
1458 return ERROR_FAIL;
1461 while ((v & 1) == 0)
1464 // error bits..
1465 if (status) {
1466 *status = (v & 0x6);
1468 return ERROR_OK;
1477 * Read the unique ID.
1478 * @param pPrivate - info about the bank
1479 * The unique ID is stored in the 'pPrivate' structure.
1481 static int
1482 FLASHD_ReadUniqueID (struct sam3_bank_private *pPrivate)
1484 int r;
1485 uint32_t v;
1486 int x;
1487 // assume 0
1488 pPrivate->pChip->cfg.unique_id[0] = 0;
1489 pPrivate->pChip->cfg.unique_id[1] = 0;
1490 pPrivate->pChip->cfg.unique_id[2] = 0;
1491 pPrivate->pChip->cfg.unique_id[3] = 0;
1493 LOG_DEBUG("Begin");
1494 r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0);
1495 if (r < 0) {
1496 return r;
1499 for (x = 0 ; x < 4 ; x++) {
1500 r = target_read_u32(pPrivate->pChip->target,
1501 pPrivate->pBank->base + (x * 4),
1502 &v);
1503 if (r < 0) {
1504 return r;
1506 pPrivate->pChip->cfg.unique_id[x] = v;
1509 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL);
1510 LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x",
1512 (unsigned int)(pPrivate->pChip->cfg.unique_id[0]),
1513 (unsigned int)(pPrivate->pChip->cfg.unique_id[1]),
1514 (unsigned int)(pPrivate->pChip->cfg.unique_id[2]),
1515 (unsigned int)(pPrivate->pChip->cfg.unique_id[3]));
1516 return r;
1521 * Erases the entire flash.
1522 * @param pPrivate - the info about the bank.
1524 static int
1525 FLASHD_EraseEntireBank(struct sam3_bank_private *pPrivate)
1527 LOG_DEBUG("Here");
1528 return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL);
1534 * Gets current GPNVM state.
1535 * @param pPrivate - info about the bank.
1536 * @param gpnvm - GPNVM bit index.
1537 * @param puthere - result stored here.
1539 //------------------------------------------------------------------------------
1540 static int
1541 FLASHD_GetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere)
1543 uint32_t v;
1544 int r;
1546 LOG_DEBUG("Here");
1547 if (pPrivate->bank_number != 0) {
1548 LOG_ERROR("GPNVM only works with Bank0");
1549 return ERROR_FAIL;
1552 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1553 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1554 gpnvm,pPrivate->pChip->details.n_gpnvms);
1555 return ERROR_FAIL;
1558 // Get GPNVMs status
1559 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL);
1560 if (r != ERROR_OK) {
1561 LOG_ERROR("Failed");
1562 return r;
1565 r = EFC_GetResult(pPrivate, &v);
1567 if (puthere) {
1568 // Check if GPNVM is set
1569 // get the bit and make it a 0/1
1570 *puthere = (v >> gpnvm) & 1;
1573 return r;
1580 * Clears the selected GPNVM bit.
1581 * @param pPrivate info about the bank
1582 * @param gpnvm GPNVM index.
1583 * @returns 0 if successful; otherwise returns an error code.
1585 static int
1586 FLASHD_ClrGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm)
1588 int r;
1589 unsigned v;
1591 LOG_DEBUG("Here");
1592 if (pPrivate->bank_number != 0) {
1593 LOG_ERROR("GPNVM only works with Bank0");
1594 return ERROR_FAIL;
1597 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1598 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1599 gpnvm,pPrivate->pChip->details.n_gpnvms);
1600 return ERROR_FAIL;
1603 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1604 if (r != ERROR_OK) {
1605 LOG_DEBUG("Failed: %d",r);
1606 return r;
1608 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL);
1609 LOG_DEBUG("End: %d",r);
1610 return r;
1616 * Sets the selected GPNVM bit.
1617 * @param pPrivate info about the bank
1618 * @param gpnvm GPNVM index.
1620 static int
1621 FLASHD_SetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm)
1623 int r;
1624 unsigned v;
1626 if (pPrivate->bank_number != 0) {
1627 LOG_ERROR("GPNVM only works with Bank0");
1628 return ERROR_FAIL;
1631 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1632 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1633 gpnvm,pPrivate->pChip->details.n_gpnvms);
1634 return ERROR_FAIL;
1637 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1638 if (r != ERROR_OK) {
1639 return r;
1641 if (v) {
1642 // already set
1643 r = ERROR_OK;
1644 } else {
1645 // set it
1646 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL);
1648 return r;
1653 * Returns a bit field (at most 64) of locked regions within a page.
1654 * @param pPrivate info about the bank
1655 * @param v where to store locked bits
1657 static int
1658 FLASHD_GetLockBits(struct sam3_bank_private *pPrivate, uint32_t *v)
1660 int r;
1661 LOG_DEBUG("Here");
1662 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL);
1663 if (r == ERROR_OK) {
1664 r = EFC_GetResult(pPrivate, v);
1666 LOG_DEBUG("End: %d",r);
1667 return r;
1672 * Unlocks all the regions in the given address range.
1673 * @param pPrivate info about the bank
1674 * @param start_sector first sector to unlock
1675 * @param end_sector last (inclusive) to unlock
1678 static int
1679 FLASHD_Unlock(struct sam3_bank_private *pPrivate,
1680 unsigned start_sector,
1681 unsigned end_sector)
1683 int r;
1684 uint32_t status;
1685 uint32_t pg;
1686 uint32_t pages_per_sector;
1688 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1690 /* Unlock all pages */
1691 while (start_sector <= end_sector) {
1692 pg = start_sector * pages_per_sector;
1694 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status);
1695 if (r != ERROR_OK) {
1696 return r;
1698 start_sector++;
1701 return ERROR_OK;
1706 * Locks regions
1707 * @param pPrivate - info about the bank
1708 * @param start_sector - first sector to lock
1709 * @param end_sector - last sector (inclusive) to lock
1711 static int
1712 FLASHD_Lock(struct sam3_bank_private *pPrivate,
1713 unsigned start_sector,
1714 unsigned end_sector)
1716 uint32_t status;
1717 uint32_t pg;
1718 uint32_t pages_per_sector;
1719 int r;
1721 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1723 /* Lock all pages */
1724 while (start_sector <= end_sector) {
1725 pg = start_sector * pages_per_sector;
1727 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status);
1728 if (r != ERROR_OK) {
1729 return r;
1731 start_sector++;
1733 return ERROR_OK;
1737 /****** END SAM3 CODE ********/
1739 /* begin helpful debug code */
1740 // print the fieldname, the field value, in dec & hex, and return field value
1741 static uint32_t
1742 sam3_reg_fieldname(struct sam3_chip *pChip,
1743 const char *regname,
1744 uint32_t value,
1745 unsigned shift,
1746 unsigned width)
1748 uint32_t v;
1749 int hwidth, dwidth;
1752 // extract the field
1753 v = value >> shift;
1754 v = v & ((1 << width)-1);
1755 if (width <= 16) {
1756 hwidth = 4;
1757 dwidth = 5;
1758 } else {
1759 hwidth = 8;
1760 dwidth = 12;
1763 // show the basics
1764 LOG_USER_N("\t%*s: %*d [0x%0*x] ",
1765 REG_NAME_WIDTH, regname,
1766 dwidth, v,
1767 hwidth, v);
1768 return v;
1772 static const char _unknown[] = "unknown";
1773 static const char * const eproc_names[] = {
1774 _unknown, // 0
1775 "arm946es", // 1
1776 "arm7tdmi", // 2
1777 "cortex-m3", // 3
1778 "arm920t", // 4
1779 "arm926ejs", // 5
1780 _unknown, // 6
1781 _unknown, // 7
1782 _unknown, // 8
1783 _unknown, // 9
1784 _unknown, // 10
1785 _unknown, // 11
1786 _unknown, // 12
1787 _unknown, // 13
1788 _unknown, // 14
1789 _unknown, // 15
1792 #define nvpsize2 nvpsize // these two tables are identical
1793 static const char * const nvpsize[] = {
1794 "none", // 0
1795 "8K bytes", // 1
1796 "16K bytes", // 2
1797 "32K bytes", // 3
1798 _unknown, // 4
1799 "64K bytes", // 5
1800 _unknown, // 6
1801 "128K bytes", // 7
1802 _unknown, // 8
1803 "256K bytes", // 9
1804 "512K bytes", // 10
1805 _unknown, // 11
1806 "1024K bytes", // 12
1807 _unknown, // 13
1808 "2048K bytes", // 14
1809 _unknown, // 15
1813 static const char * const sramsize[] = {
1814 "48K Bytes", // 0
1815 "1K Bytes", // 1
1816 "2K Bytes", // 2
1817 "6K Bytes", // 3
1818 "112K Bytes", // 4
1819 "4K Bytes", // 5
1820 "80K Bytes", // 6
1821 "160K Bytes", // 7
1822 "8K Bytes", // 8
1823 "16K Bytes", // 9
1824 "32K Bytes", // 10
1825 "64K Bytes", // 11
1826 "128K Bytes", // 12
1827 "256K Bytes", // 13
1828 "96K Bytes", // 14
1829 "512K Bytes", // 15
1833 static const struct archnames { unsigned value; const char *name; } archnames[] = {
1834 { 0x19, "AT91SAM9xx Series" },
1835 { 0x29, "AT91SAM9XExx Series" },
1836 { 0x34, "AT91x34 Series" },
1837 { 0x37, "CAP7 Series" },
1838 { 0x39, "CAP9 Series" },
1839 { 0x3B, "CAP11 Series" },
1840 { 0x40, "AT91x40 Series" },
1841 { 0x42, "AT91x42 Series" },
1842 { 0x55, "AT91x55 Series" },
1843 { 0x60, "AT91SAM7Axx Series" },
1844 { 0x61, "AT91SAM7AQxx Series" },
1845 { 0x63, "AT91x63 Series" },
1846 { 0x70, "AT91SAM7Sxx Series" },
1847 { 0x71, "AT91SAM7XCxx Series" },
1848 { 0x72, "AT91SAM7SExx Series" },
1849 { 0x73, "AT91SAM7Lxx Series" },
1850 { 0x75, "AT91SAM7Xxx Series" },
1851 { 0x76, "AT91SAM7SLxx Series" },
1852 { 0x80, "ATSAM3UxC Series (100-pin version)" },
1853 { 0x81, "ATSAM3UxE Series (144-pin version)" },
1854 { 0x83, "ATSAM3AxC Series (100-pin version)" },
1855 { 0x84, "ATSAM3XxC Series (100-pin version)" },
1856 { 0x85, "ATSAM3XxE Series (144-pin version)" },
1857 { 0x86, "ATSAM3XxG Series (208/217-pin version)" },
1858 { 0x88, "ATSAM3SxA Series (48-pin version)" },
1859 { 0x89, "ATSAM3SxB Series (64-pin version)" },
1860 { 0x8A, "ATSAM3SxC Series (100-pin version)" },
1861 { 0x92, "AT91x92 Series" },
1862 { 0xF0, "AT75Cxx Series" },
1863 { -1, NULL },
1867 static const char * const nvptype[] = {
1868 "rom", // 0
1869 "romless or onchip flash", // 1
1870 "embedded flash memory", // 2
1871 "rom(nvpsiz) + embedded flash (nvpsiz2)", //3
1872 "sram emulating flash", // 4
1873 _unknown, // 5
1874 _unknown, // 6
1875 _unknown, // 7
1879 static const char *_yes_or_no(uint32_t v)
1881 if (v) {
1882 return "YES";
1883 } else {
1884 return "NO";
1888 static const char * const _rc_freq[] = {
1889 "4 MHz", "8 MHz", "12 MHz", "reserved"
1892 static void
1893 sam3_explain_ckgr_mor(struct sam3_chip *pChip)
1895 uint32_t v;
1896 uint32_t rcen;
1898 v = sam3_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1);
1899 LOG_USER("(main xtal enabled: %s)",
1900 _yes_or_no(v));
1901 v = sam3_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1);
1902 LOG_USER("(main osc bypass: %s)",
1903 _yes_or_no(v));
1904 rcen = sam3_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1);
1905 LOG_USER("(onchip RC-OSC enabled: %s)",
1906 _yes_or_no(rcen));
1907 v = sam3_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3);
1908 LOG_USER("(onchip RC-OSC freq: %s)",
1909 _rc_freq[v]);
1911 pChip->cfg.rc_freq = 0;
1912 if (rcen) {
1913 switch (v) {
1914 default:
1915 pChip->cfg.rc_freq = 0;
1916 break;
1917 case 0:
1918 pChip->cfg.rc_freq = 4 * 1000 * 1000;
1919 break;
1920 case 1:
1921 pChip->cfg.rc_freq = 8 * 1000 * 1000;
1922 break;
1923 case 2:
1924 pChip->cfg.rc_freq = 12* 1000 * 1000;
1925 break;
1929 v = sam3_reg_fieldname(pChip,"MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8);
1930 LOG_USER("(startup clks, time= %f uSecs)",
1931 ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq)));
1932 v = sam3_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1);
1933 LOG_USER("(mainosc source: %s)",
1934 v ? "external xtal" : "internal RC");
1936 v = sam3_reg_fieldname(pChip,"CFDEN", pChip->cfg.CKGR_MOR, 25, 1);
1937 LOG_USER("(clock failure enabled: %s)",
1938 _yes_or_no(v));
1943 static void
1944 sam3_explain_chipid_cidr(struct sam3_chip *pChip)
1946 int x;
1947 uint32_t v;
1948 const char *cp;
1950 sam3_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5);
1951 LOG_USER_N("\n");
1953 v = sam3_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3);
1954 LOG_USER("%s", eproc_names[v]);
1956 v = sam3_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4);
1957 LOG_USER("%s", nvpsize[v]);
1959 v = sam3_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4);
1960 LOG_USER("%s", nvpsize2[v]);
1962 v = sam3_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16,4);
1963 LOG_USER("%s", sramsize[ v ]);
1965 v = sam3_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8);
1966 cp = _unknown;
1967 for (x = 0 ; archnames[x].name ; x++) {
1968 if (v == archnames[x].value) {
1969 cp = archnames[x].name;
1970 break;
1974 LOG_USER("%s", cp);
1976 v = sam3_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3);
1977 LOG_USER("%s", nvptype[ v ]);
1979 v = sam3_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1);
1980 LOG_USER("(exists: %s)", _yes_or_no(v));
1983 static void
1984 sam3_explain_ckgr_mcfr(struct sam3_chip *pChip)
1986 uint32_t v;
1989 v = sam3_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1);
1990 LOG_USER("(main ready: %s)", _yes_or_no(v));
1992 v = sam3_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16);
1994 v = (v * pChip->cfg.slow_freq) / 16;
1995 pChip->cfg.mainosc_freq = v;
1997 LOG_USER("(%3.03f Mhz (%d.%03dkhz slowclk)",
1998 _tomhz(v),
1999 pChip->cfg.slow_freq / 1000,
2000 pChip->cfg.slow_freq % 1000);
2004 static void
2005 sam3_explain_ckgr_plla(struct sam3_chip *pChip)
2007 uint32_t mula,diva;
2009 diva = sam3_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8);
2010 LOG_USER_N("\n");
2011 mula = sam3_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11);
2012 LOG_USER_N("\n");
2013 pChip->cfg.plla_freq = 0;
2014 if (mula == 0) {
2015 LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
2016 } else if (diva == 0) {
2017 LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
2018 } else if (diva == 1) {
2019 pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1));
2020 LOG_USER("\tPLLA Freq: %3.03f MHz",
2021 _tomhz(pChip->cfg.plla_freq));
2026 static void
2027 sam3_explain_mckr(struct sam3_chip *pChip)
2029 uint32_t css, pres, fin = 0;
2030 int pdiv = 0;
2031 const char *cp = NULL;
2033 css = sam3_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2);
2034 switch (css & 3) {
2035 case 0:
2036 fin = pChip->cfg.slow_freq;
2037 cp = "slowclk";
2038 break;
2039 case 1:
2040 fin = pChip->cfg.mainosc_freq;
2041 cp = "mainosc";
2042 break;
2043 case 2:
2044 fin = pChip->cfg.plla_freq;
2045 cp = "plla";
2046 break;
2047 case 3:
2048 if (pChip->cfg.CKGR_UCKR & (1 << 16)) {
2049 fin = 480 * 1000 * 1000;
2050 cp = "upll";
2051 } else {
2052 fin = 0;
2053 cp = "upll (*ERROR* UPLL is disabled)";
2055 break;
2056 default:
2057 assert(0);
2058 break;
2061 LOG_USER("%s (%3.03f Mhz)",
2063 _tomhz(fin));
2064 pres = sam3_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3);
2065 switch (pres & 0x07) {
2066 case 0:
2067 pdiv = 1;
2068 cp = "selected clock";
2069 break;
2070 case 1:
2071 pdiv = 2;
2072 cp = "clock/2";
2073 break;
2074 case 2:
2075 pdiv = 4;
2076 cp = "clock/4";
2077 break;
2078 case 3:
2079 pdiv = 8;
2080 cp = "clock/8";
2081 break;
2082 case 4:
2083 pdiv = 16;
2084 cp = "clock/16";
2085 break;
2086 case 5:
2087 pdiv = 32;
2088 cp = "clock/32";
2089 break;
2090 case 6:
2091 pdiv = 64;
2092 cp = "clock/64";
2093 break;
2094 case 7:
2095 pdiv = 6;
2096 cp = "clock/6";
2097 break;
2098 default:
2099 assert(0);
2100 break;
2102 LOG_USER("(%s)", cp);
2103 fin = fin / pdiv;
2104 // sam3 has a *SINGLE* clock -
2105 // other at91 series parts have divisors for these.
2106 pChip->cfg.cpu_freq = fin;
2107 pChip->cfg.mclk_freq = fin;
2108 pChip->cfg.fclk_freq = fin;
2109 LOG_USER("\t\tResult CPU Freq: %3.03f",
2110 _tomhz(fin));
2113 #if 0
2114 static struct sam3_chip *
2115 target2sam3(struct target *pTarget)
2117 struct sam3_chip *pChip;
2119 if (pTarget == NULL) {
2120 return NULL;
2123 pChip = all_sam3_chips;
2124 while (pChip) {
2125 if (pChip->target == pTarget) {
2126 break; // return below
2127 } else {
2128 pChip = pChip->next;
2131 return pChip;
2133 #endif
2135 static uint32_t *
2136 sam3_get_reg_ptr(struct sam3_cfg *pCfg, const struct sam3_reg_list *pList)
2138 // this function exists to help
2139 // keep funky offsetof() errors
2140 // and casting from causing bugs
2142 // By using prototypes - we can detect what would
2143 // be casting errors.
2145 return ((uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset));
2149 #define SAM3_ENTRY(NAME, FUNC) { .address = SAM3_ ## NAME, .struct_offset = offsetof(struct sam3_cfg, NAME), #NAME, FUNC }
2150 static const struct sam3_reg_list sam3_all_regs[] = {
2151 SAM3_ENTRY(CKGR_MOR , sam3_explain_ckgr_mor),
2152 SAM3_ENTRY(CKGR_MCFR , sam3_explain_ckgr_mcfr),
2153 SAM3_ENTRY(CKGR_PLLAR , sam3_explain_ckgr_plla),
2154 SAM3_ENTRY(CKGR_UCKR , NULL),
2155 SAM3_ENTRY(PMC_FSMR , NULL),
2156 SAM3_ENTRY(PMC_FSPR , NULL),
2157 SAM3_ENTRY(PMC_IMR , NULL),
2158 SAM3_ENTRY(PMC_MCKR , sam3_explain_mckr),
2159 SAM3_ENTRY(PMC_PCK0 , NULL),
2160 SAM3_ENTRY(PMC_PCK1 , NULL),
2161 SAM3_ENTRY(PMC_PCK2 , NULL),
2162 SAM3_ENTRY(PMC_PCSR , NULL),
2163 SAM3_ENTRY(PMC_SCSR , NULL),
2164 SAM3_ENTRY(PMC_SR , NULL),
2165 SAM3_ENTRY(CHIPID_CIDR , sam3_explain_chipid_cidr),
2166 SAM3_ENTRY(CHIPID_EXID , NULL),
2167 SAM3_ENTRY(SUPC_CR, NULL),
2169 // TERMINATE THE LIST
2170 { .name = NULL }
2172 #undef SAM3_ENTRY
2177 static struct sam3_bank_private *
2178 get_sam3_bank_private(struct flash_bank *bank)
2180 return (struct sam3_bank_private *)(bank->driver_priv);
2184 * Given a pointer to where it goes in the structure,
2185 * determine the register name, address from the all registers table.
2187 static const struct sam3_reg_list *
2188 sam3_GetReg(struct sam3_chip *pChip, uint32_t *goes_here)
2190 const struct sam3_reg_list *pReg;
2192 pReg = &(sam3_all_regs[0]);
2193 while (pReg->name) {
2194 uint32_t *pPossible;
2196 // calculate where this one go..
2197 // it is "possibly" this register.
2199 pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset));
2201 // well? Is it this register
2202 if (pPossible == goes_here) {
2203 // Jump for joy!
2204 return pReg;
2207 // next...
2208 pReg++;
2210 // This is *TOTAL*PANIC* - we are totally screwed.
2211 LOG_ERROR("INVALID SAM3 REGISTER");
2212 return NULL;
2216 static int
2217 sam3_ReadThisReg(struct sam3_chip *pChip, uint32_t *goes_here)
2219 const struct sam3_reg_list *pReg;
2220 int r;
2222 pReg = sam3_GetReg(pChip, goes_here);
2223 if (!pReg) {
2224 return ERROR_FAIL;
2227 r = target_read_u32(pChip->target, pReg->address, goes_here);
2228 if (r != ERROR_OK) {
2229 LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Err: %d",
2230 pReg->name, (unsigned)(pReg->address), r);
2232 return r;
2237 static int
2238 sam3_ReadAllRegs(struct sam3_chip *pChip)
2240 int r;
2241 const struct sam3_reg_list *pReg;
2243 pReg = &(sam3_all_regs[0]);
2244 while (pReg->name) {
2245 r = sam3_ReadThisReg(pChip,
2246 sam3_get_reg_ptr(&(pChip->cfg), pReg));
2247 if (r != ERROR_OK) {
2248 LOG_ERROR("Cannot read SAM3 registere: %s @ 0x%08x, Error: %d",
2249 pReg->name, ((unsigned)(pReg->address)), r);
2250 return r;
2253 pReg++;
2256 return ERROR_OK;
2260 static int
2261 sam3_GetInfo(struct sam3_chip *pChip)
2263 const struct sam3_reg_list *pReg;
2264 uint32_t regval;
2266 pReg = &(sam3_all_regs[0]);
2267 while (pReg->name) {
2268 // display all regs
2269 LOG_DEBUG("Start: %s", pReg->name);
2270 regval = *sam3_get_reg_ptr(&(pChip->cfg), pReg);
2271 LOG_USER("%*s: [0x%08x] -> 0x%08x",
2272 REG_NAME_WIDTH,
2273 pReg->name,
2274 pReg->address,
2275 regval);
2276 if (pReg->explain_func) {
2277 (*(pReg->explain_func))(pChip);
2279 LOG_DEBUG("End: %s", pReg->name);
2280 pReg++;
2282 LOG_USER(" rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq));
2283 LOG_USER(" mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq));
2284 LOG_USER(" plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq));
2285 LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
2286 LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
2289 LOG_USER(" UniqueId: 0x%08x 0x%08x 0x%08x 0x%08x",
2290 pChip->cfg.unique_id[0],
2291 pChip->cfg.unique_id[1],
2292 pChip->cfg.unique_id[2],
2293 pChip->cfg.unique_id[3]);
2296 return ERROR_OK;
2300 static int
2301 sam3_erase_check(struct flash_bank *bank)
2303 int x;
2305 LOG_DEBUG("Here");
2306 if (bank->target->state != TARGET_HALTED) {
2307 LOG_ERROR("Target not halted");
2308 return ERROR_TARGET_NOT_HALTED;
2310 if (0 == bank->num_sectors) {
2311 LOG_ERROR("Target: not supported/not probed");
2312 return ERROR_FAIL;
2315 LOG_INFO("sam3 - supports auto-erase, erase_check ignored");
2316 for (x = 0 ; x < bank->num_sectors ; x++) {
2317 bank->sectors[x].is_erased = 1;
2320 LOG_DEBUG("Done");
2321 return ERROR_OK;
2324 static int
2325 sam3_protect_check(struct flash_bank *bank)
2327 int r;
2328 uint32_t v=0;
2329 unsigned x;
2330 struct sam3_bank_private *pPrivate;
2332 LOG_DEBUG("Begin");
2333 if (bank->target->state != TARGET_HALTED) {
2334 LOG_ERROR("Target not halted");
2335 return ERROR_TARGET_NOT_HALTED;
2338 pPrivate = get_sam3_bank_private(bank);
2339 if (!pPrivate) {
2340 LOG_ERROR("no private for this bank?");
2341 return ERROR_FAIL;
2343 if (!(pPrivate->probed)) {
2344 return ERROR_FLASH_BANK_NOT_PROBED;
2347 r = FLASHD_GetLockBits(pPrivate , &v);
2348 if (r != ERROR_OK) {
2349 LOG_DEBUG("Failed: %d",r);
2350 return r;
2353 for (x = 0 ; x < pPrivate->nsectors ; x++) {
2354 bank->sectors[x].is_protected = (!!(v & (1 << x)));
2356 LOG_DEBUG("Done");
2357 return ERROR_OK;
2360 FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
2362 struct sam3_chip *pChip;
2364 pChip = all_sam3_chips;
2366 // is this an existing chip?
2367 while (pChip) {
2368 if (pChip->target == bank->target) {
2369 break;
2371 pChip = pChip->next;
2374 if (!pChip) {
2375 // this is a *NEW* chip
2376 pChip = calloc(1, sizeof(struct sam3_chip));
2377 if (!pChip) {
2378 LOG_ERROR("NO RAM!");
2379 return ERROR_FAIL;
2381 pChip->target = bank->target;
2382 // insert at head
2383 pChip->next = all_sam3_chips;
2384 all_sam3_chips = pChip;
2385 pChip->target = bank->target;
2386 // assumption is this runs at 32khz
2387 pChip->cfg.slow_freq = 32768;
2388 pChip->probed = 0;
2391 switch (bank->base) {
2392 default:
2393 LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x or 0x%08x \
2394 [at91sam3u series] or 0x%08x [at91sam3s series])",
2395 ((unsigned int)(bank->base)),
2396 ((unsigned int)(FLASH_BANK0_BASE_U)),
2397 ((unsigned int)(FLASH_BANK1_BASE_U)),
2398 ((unsigned int)(FLASH_BANK_BASE_S)));
2399 return ERROR_FAIL;
2400 break;
2402 // at91sam3u series
2403 case FLASH_BANK0_BASE_U:
2404 bank->driver_priv = &(pChip->details.bank[0]);
2405 bank->bank_number = 0;
2406 pChip->details.bank[0].pChip = pChip;
2407 pChip->details.bank[0].pBank = bank;
2408 break;
2409 case FLASH_BANK1_BASE_U:
2410 bank->driver_priv = &(pChip->details.bank[1]);
2411 bank->bank_number = 1;
2412 pChip->details.bank[1].pChip = pChip;
2413 pChip->details.bank[1].pBank = bank;
2414 break;
2416 // at91sam3s series
2417 case FLASH_BANK_BASE_S:
2418 bank->driver_priv = &(pChip->details.bank[0]);
2419 bank->bank_number = 0;
2420 pChip->details.bank[0].pChip = pChip;
2421 pChip->details.bank[0].pBank = bank;
2422 break;
2425 // we initialize after probing.
2426 return ERROR_OK;
2429 static int
2430 sam3_GetDetails(struct sam3_bank_private *pPrivate)
2432 const struct sam3_chip_details *pDetails;
2433 struct sam3_chip *pChip;
2434 struct flash_bank *saved_banks[SAM3_MAX_FLASH_BANKS];
2435 unsigned x;
2437 LOG_DEBUG("Begin");
2438 pDetails = all_sam3_details;
2439 while (pDetails->name) {
2440 // Compare cidr without version bits
2441 if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0)) {
2442 break;
2443 } else {
2444 pDetails++;
2447 if (pDetails->name == NULL) {
2448 LOG_ERROR("SAM3 ChipID 0x%08x not found in table (perhaps you can this chip?)",
2449 (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
2450 // Help the victim, print details about the chip
2451 LOG_INFO("SAM3 CHIPID_CIDR: 0x%08x decodes as follows",
2452 pPrivate->pChip->cfg.CHIPID_CIDR);
2453 sam3_explain_chipid_cidr(pPrivate->pChip);
2454 return ERROR_FAIL;
2457 // DANGER: THERE ARE DRAGONS HERE
2459 // get our pChip - it is going
2460 // to be over-written shortly
2461 pChip = pPrivate->pChip;
2463 // Note that, in reality:
2465 // pPrivate = &(pChip->details.bank[0])
2466 // or pPrivate = &(pChip->details.bank[1])
2469 // save the "bank" pointers
2470 for (x = 0 ; x < SAM3_MAX_FLASH_BANKS ; x++) {
2471 saved_banks[ x ] = pChip->details.bank[x].pBank;
2474 // Overwrite the "details" structure.
2475 memcpy(&(pPrivate->pChip->details),
2476 pDetails,
2477 sizeof(pPrivate->pChip->details));
2479 // now fix the ghosted pointers
2480 for (x = 0 ; x < SAM3_MAX_FLASH_BANKS ; x++) {
2481 pChip->details.bank[x].pChip = pChip;
2482 pChip->details.bank[x].pBank = saved_banks[x];
2485 // update the *BANK*SIZE*
2487 LOG_DEBUG("End");
2488 return ERROR_OK;
2493 static int
2494 _sam3_probe(struct flash_bank *bank, int noise)
2496 unsigned x;
2497 int r;
2498 struct sam3_bank_private *pPrivate;
2501 LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise);
2502 if (bank->target->state != TARGET_HALTED)
2504 LOG_ERROR("Target not halted");
2505 return ERROR_TARGET_NOT_HALTED;
2508 pPrivate = get_sam3_bank_private(bank);
2509 if (!pPrivate) {
2510 LOG_ERROR("Invalid/unknown bank number");
2511 return ERROR_FAIL;
2514 r = sam3_ReadAllRegs(pPrivate->pChip);
2515 if (r != ERROR_OK) {
2516 return r;
2520 LOG_DEBUG("Here");
2521 if (pPrivate->pChip->probed) {
2522 r = sam3_GetInfo(pPrivate->pChip);
2523 } else {
2524 r = sam3_GetDetails(pPrivate);
2526 if (r != ERROR_OK) {
2527 return r;
2530 // update the flash bank size
2531 for (x = 0 ; x < SAM3_MAX_FLASH_BANKS ; x++) {
2532 if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
2533 bank->size = pPrivate->pChip->details.bank[x].size_bytes;
2534 break;
2538 if (bank->sectors == NULL) {
2539 bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0])));
2540 if (bank->sectors == NULL) {
2541 LOG_ERROR("No memory!");
2542 return ERROR_FAIL;
2544 bank->num_sectors = pPrivate->nsectors;
2546 for (x = 0 ; ((int)(x)) < bank->num_sectors ; x++) {
2547 bank->sectors[x].size = pPrivate->sector_size;
2548 bank->sectors[x].offset = x * (pPrivate->sector_size);
2549 // mark as unknown
2550 bank->sectors[x].is_erased = -1;
2551 bank->sectors[x].is_protected = -1;
2555 pPrivate->probed = 1;
2557 r = sam3_protect_check(bank);
2558 if (r != ERROR_OK) {
2559 return r;
2562 LOG_DEBUG("Bank = %d, nbanks = %d",
2563 pPrivate->bank_number , pPrivate->pChip->details.n_banks);
2564 if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) {
2565 // read unique id,
2566 // it appears to be associated with the *last* flash bank.
2567 FLASHD_ReadUniqueID(pPrivate);
2570 return r;
2573 static int
2574 sam3_probe(struct flash_bank *bank)
2576 return _sam3_probe(bank, 1);
2579 static int
2580 sam3_auto_probe(struct flash_bank *bank)
2582 return _sam3_probe(bank, 0);
2587 static int
2588 sam3_erase(struct flash_bank *bank, int first, int last)
2590 struct sam3_bank_private *pPrivate;
2591 int r;
2593 LOG_DEBUG("Here");
2594 if (bank->target->state != TARGET_HALTED) {
2595 LOG_ERROR("Target not halted");
2596 return ERROR_TARGET_NOT_HALTED;
2599 r = sam3_auto_probe(bank);
2600 if (r != ERROR_OK) {
2601 LOG_DEBUG("Here,r=%d",r);
2602 return r;
2605 pPrivate = get_sam3_bank_private(bank);
2606 if (!(pPrivate->probed)) {
2607 return ERROR_FLASH_BANK_NOT_PROBED;
2610 if ((first == 0) && ((last + 1)== ((int)(pPrivate->nsectors)))) {
2611 // whole chip
2612 LOG_DEBUG("Here");
2613 return FLASHD_EraseEntireBank(pPrivate);
2615 LOG_INFO("sam3 auto-erases while programing (request ignored)");
2616 return ERROR_OK;
2619 static int
2620 sam3_protect(struct flash_bank *bank, int set, int first, int last)
2622 struct sam3_bank_private *pPrivate;
2623 int r;
2625 LOG_DEBUG("Here");
2626 if (bank->target->state != TARGET_HALTED) {
2627 LOG_ERROR("Target not halted");
2628 return ERROR_TARGET_NOT_HALTED;
2631 pPrivate = get_sam3_bank_private(bank);
2632 if (!(pPrivate->probed)) {
2633 return ERROR_FLASH_BANK_NOT_PROBED;
2636 if (set) {
2637 r = FLASHD_Lock(pPrivate, (unsigned)(first), (unsigned)(last));
2638 } else {
2639 r = FLASHD_Unlock(pPrivate, (unsigned)(first), (unsigned)(last));
2641 LOG_DEBUG("End: r=%d",r);
2643 return r;
2648 static int
2649 sam3_info(struct flash_bank *bank, char *buf, int buf_size)
2651 if (bank->target->state != TARGET_HALTED) {
2652 LOG_ERROR("Target not halted");
2653 return ERROR_TARGET_NOT_HALTED;
2655 buf[ 0 ] = 0;
2656 return ERROR_OK;
2659 static int
2660 sam3_page_read(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
2662 uint32_t adr;
2663 int r;
2665 adr = pagenum * pPrivate->page_size;
2666 adr += adr + pPrivate->base_address;
2668 r = target_read_memory(pPrivate->pChip->target,
2669 adr,
2670 4, /* THIS*MUST*BE* in 32bit values */
2671 pPrivate->page_size / 4,
2672 buf);
2673 if (r != ERROR_OK) {
2674 LOG_ERROR("SAM3: Flash program failed to read page phys address: 0x%08x", (unsigned int)(adr));
2676 return r;
2679 // The code below is basically this:
2680 // compiled with
2681 // arm-none-eabi-gcc -mthumb -mcpu = cortex-m3 -O9 -S ./foobar.c -o foobar.s
2683 // Only the *CPU* can write to the flash buffer.
2684 // the DAP cannot... so - we download this 28byte thing
2685 // Run the algorithm - (below)
2686 // to program the device
2688 // ========================================
2689 // #include <stdint.h>
2691 // struct foo {
2692 // uint32_t *dst;
2693 // const uint32_t *src;
2694 // int n;
2695 // volatile uint32_t *base;
2696 // uint32_t cmd;
2697 // };
2700 // uint32_t sam3_function(struct foo *p)
2701 // {
2702 // volatile uint32_t *v;
2703 // uint32_t *d;
2704 // const uint32_t *s;
2705 // int n;
2706 // uint32_t r;
2708 // d = p->dst;
2709 // s = p->src;
2710 // n = p->n;
2712 // do {
2713 // *d++ = *s++;
2714 // } while (--n)
2715 // ;
2717 // v = p->base;
2719 // v[ 1 ] = p->cmd;
2720 // do {
2721 // r = v[8/4];
2722 // } while (!(r&1))
2723 // ;
2724 // return r;
2725 // }
2726 // ========================================
2730 static const uint8_t
2731 sam3_page_write_opcodes[] = {
2732 // 24 0000 0446 mov r4, r0
2733 0x04,0x46,
2734 // 25 0002 6168 ldr r1, [r4, #4]
2735 0x61,0x68,
2736 // 26 0004 0068 ldr r0, [r0, #0]
2737 0x00,0x68,
2738 // 27 0006 A268 ldr r2, [r4, #8]
2739 0xa2,0x68,
2740 // 28 @ lr needed for prologue
2741 // 29 .L2:
2742 // 30 0008 51F8043B ldr r3, [r1], #4
2743 0x51,0xf8,0x04,0x3b,
2744 // 31 000c 12F1FF32 adds r2, r2, #-1
2745 0x12,0xf1,0xff,0x32,
2746 // 32 0010 40F8043B str r3, [r0], #4
2747 0x40,0xf8,0x04,0x3b,
2748 // 33 0014 F8D1 bne .L2
2749 0xf8,0xd1,
2750 // 34 0016 E268 ldr r2, [r4, #12]
2751 0xe2,0x68,
2752 // 35 0018 2369 ldr r3, [r4, #16]
2753 0x23,0x69,
2754 // 36 001a 5360 str r3, [r2, #4]
2755 0x53,0x60,
2756 // 37 001c 0832 adds r2, r2, #8
2757 0x08,0x32,
2758 // 38 .L4:
2759 // 39 001e 1068 ldr r0, [r2, #0]
2760 0x10,0x68,
2761 // 40 0020 10F0010F tst r0, #1
2762 0x10,0xf0,0x01,0x0f,
2763 // 41 0024 FBD0 beq .L4
2764 0xfb,0xd0,
2765 0x00,0xBE /* bkpt #0 */
2769 static int
2770 sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
2772 uint32_t adr;
2773 uint32_t status;
2774 int r;
2776 adr = pagenum * pPrivate->page_size;
2777 adr += (adr + pPrivate->base_address);
2779 LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr));
2780 r = target_write_memory(pPrivate->pChip->target,
2781 adr,
2782 4, /* THIS*MUST*BE* in 32bit values */
2783 pPrivate->page_size / 4,
2784 buf);
2785 if (r != ERROR_OK) {
2786 LOG_ERROR("SAM3: Failed to write (buffer) page at phys address 0x%08x", (unsigned int)(adr));
2787 return r;
2790 r = EFC_PerformCommand(pPrivate,
2791 // send Erase & Write Page
2792 AT91C_EFC_FCMD_EWP,
2793 pagenum,
2794 &status);
2796 if (r != ERROR_OK) {
2797 LOG_ERROR("SAM3: Error performing Erase & Write page @ phys address 0x%08x", (unsigned int)(adr));
2799 if (status & (1 << 2)) {
2800 LOG_ERROR("SAM3: Page @ Phys address 0x%08x is locked", (unsigned int)(adr));
2801 return ERROR_FAIL;
2803 if (status & (1 << 1)) {
2804 LOG_ERROR("SAM3: Flash Command error @phys address 0x%08x", (unsigned int)(adr));
2805 return ERROR_FAIL;
2807 return ERROR_OK;
2814 static int
2815 sam3_write(struct flash_bank *bank,
2816 uint8_t *buffer,
2817 uint32_t offset,
2818 uint32_t count)
2820 int n;
2821 unsigned page_cur;
2822 unsigned page_end;
2823 int r;
2824 unsigned page_offset;
2825 struct sam3_bank_private *pPrivate;
2826 uint8_t *pagebuffer;
2828 // incase we bail further below, set this to null
2829 pagebuffer = NULL;
2831 // ignore dumb requests
2832 if (count == 0) {
2833 r = ERROR_OK;
2834 goto done;
2837 if (bank->target->state != TARGET_HALTED) {
2838 LOG_ERROR("Target not halted");
2839 r = ERROR_TARGET_NOT_HALTED;
2840 goto done;
2843 pPrivate = get_sam3_bank_private(bank);
2844 if (!(pPrivate->probed)) {
2845 r = ERROR_FLASH_BANK_NOT_PROBED;
2846 goto done;
2850 if ((offset + count) > pPrivate->size_bytes) {
2851 LOG_ERROR("Flash write error - past end of bank");
2852 LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x",
2853 (unsigned int)(offset),
2854 (unsigned int)(count),
2855 (unsigned int)(pPrivate->size_bytes));
2856 r = ERROR_FAIL;
2857 goto done;
2860 pagebuffer = malloc(pPrivate->page_size);
2861 if( !pagebuffer ){
2862 LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size));
2863 r = ERROR_FAIL;
2864 goto done;
2867 // what page do we start & end in?
2868 page_cur = offset / pPrivate->page_size;
2869 page_end = (offset + count - 1) / pPrivate->page_size;
2871 LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count));
2872 LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end));
2874 // Special case: all one page
2876 // Otherwise:
2877 // (1) non-aligned start
2878 // (2) body pages
2879 // (3) non-aligned end.
2881 // Handle special case - all one page.
2882 if (page_cur == page_end) {
2883 LOG_DEBUG("Special case, all in one page");
2884 r = sam3_page_read(pPrivate, page_cur, pagebuffer);
2885 if (r != ERROR_OK) {
2886 goto done;
2889 page_offset = (offset & (pPrivate->page_size-1));
2890 memcpy(pagebuffer + page_offset,
2891 buffer,
2892 count);
2894 r = sam3_page_write(pPrivate, page_cur, pagebuffer);
2895 if (r != ERROR_OK) {
2896 goto done;
2898 r = ERROR_OK;
2899 goto done;
2902 // non-aligned start
2903 page_offset = offset & (pPrivate->page_size - 1);
2904 if (page_offset) {
2905 LOG_DEBUG("Not-Aligned start");
2906 // read the partial
2907 r = sam3_page_read(pPrivate, page_cur, pagebuffer);
2908 if (r != ERROR_OK) {
2909 goto done;
2912 // over-write with new data
2913 n = (pPrivate->page_size - page_offset);
2914 memcpy(pagebuffer + page_offset,
2915 buffer,
2918 r = sam3_page_write(pPrivate, page_cur, pagebuffer);
2919 if (r != ERROR_OK) {
2920 goto done;
2923 count -= n;
2924 offset += n;
2925 buffer += n;
2926 page_cur++;
2929 /* By checking that offset is correct here, we also
2930 fix a clang warning */
2931 assert(offset == pPrivate->page_size);
2933 // intermediate large pages
2934 // also - the final *terminal*
2935 // if that terminal page is a full page
2936 LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x",
2937 (int)page_cur, (int)page_end, (unsigned int)(count));
2939 while ((page_cur < page_end) &&
2940 (count >= pPrivate->page_size)) {
2941 r = sam3_page_write(pPrivate, page_cur, buffer);
2942 if (r != ERROR_OK) {
2943 goto done;
2945 count -= pPrivate->page_size;
2946 buffer += pPrivate->page_size;
2947 page_cur += 1;
2950 // terminal partial page?
2951 if (count) {
2952 LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count));
2953 // we have a partial page
2954 r = sam3_page_read(pPrivate, page_cur, pagebuffer);
2955 if (r != ERROR_OK) {
2956 goto done;
2958 // data goes at start
2959 memcpy(pagebuffer, buffer, count);
2960 r = sam3_page_write(pPrivate, page_cur, pagebuffer);
2961 if (r != ERROR_OK) {
2962 goto done;
2964 buffer += count;
2965 count -= count;
2967 LOG_DEBUG("Done!");
2968 r = ERROR_OK;
2969 done:
2970 if( pagebuffer ){
2971 free(pagebuffer);
2973 return r;
2976 COMMAND_HANDLER(sam3_handle_info_command)
2978 struct sam3_chip *pChip;
2979 pChip = get_current_sam3(CMD_CTX);
2980 if (!pChip) {
2981 return ERROR_OK;
2984 unsigned x;
2985 int r;
2986 r = 0;
2988 // bank0 must exist before we can do anything
2989 if (pChip->details.bank[0].pBank == NULL) {
2990 x = 0;
2991 need_define:
2992 command_print(CMD_CTX,
2993 "Please define bank %d via command: flash bank %s ... ",
2995 at91sam3_flash.name);
2996 return ERROR_FAIL;
2999 // if bank 0 is not probed, then probe it
3000 if (!(pChip->details.bank[0].probed)) {
3001 r = sam3_auto_probe(pChip->details.bank[0].pBank);
3002 if (r != ERROR_OK) {
3003 return ERROR_FAIL;
3006 // above guarantees the "chip details" structure is valid
3007 // and thus, bank private areas are valid
3008 // and we have a SAM3 chip, what a concept!
3011 // auto-probe other banks, 0 done above
3012 for (x = 1 ; x < SAM3_MAX_FLASH_BANKS ; x++) {
3013 // skip banks not present
3014 if (!(pChip->details.bank[x].present)) {
3015 continue;
3018 if (pChip->details.bank[x].pBank == NULL) {
3019 goto need_define;
3022 if (pChip->details.bank[x].probed) {
3023 continue;
3026 r = sam3_auto_probe(pChip->details.bank[x].pBank);
3027 if (r != ERROR_OK) {
3028 return r;
3033 r = sam3_GetInfo(pChip);
3034 if (r != ERROR_OK) {
3035 LOG_DEBUG("Sam3Info, Failed %d",r);
3036 return r;
3039 return ERROR_OK;
3042 COMMAND_HANDLER(sam3_handle_gpnvm_command)
3044 unsigned x,v;
3045 int r,who;
3046 struct sam3_chip *pChip;
3048 pChip = get_current_sam3(CMD_CTX);
3049 if (!pChip) {
3050 return ERROR_OK;
3053 if (pChip->target->state != TARGET_HALTED) {
3054 LOG_ERROR("sam3 - target not halted");
3055 return ERROR_TARGET_NOT_HALTED;
3059 if (pChip->details.bank[0].pBank == NULL) {
3060 command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
3061 at91sam3_flash.name);
3062 return ERROR_FAIL;
3064 if (!pChip->details.bank[0].probed) {
3065 r = sam3_auto_probe(pChip->details.bank[0].pBank);
3066 if (r != ERROR_OK) {
3067 return r;
3072 switch (CMD_ARGC) {
3073 default:
3074 command_print(CMD_CTX,"Too many parameters\n");
3075 return ERROR_COMMAND_SYNTAX_ERROR;
3076 break;
3077 case 0:
3078 who = -1;
3079 goto showall;
3080 break;
3081 case 1:
3082 who = -1;
3083 break;
3084 case 2:
3085 if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all"))) {
3086 who = -1;
3087 } else {
3088 uint32_t v32;
3089 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
3090 who = v32;
3092 break;
3095 if (0 == strcmp("show", CMD_ARGV[0])) {
3096 if (who == -1) {
3097 showall:
3098 r = ERROR_OK;
3099 for (x = 0 ; x < pChip->details.n_gpnvms ; x++) {
3100 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
3101 if (r != ERROR_OK) {
3102 break;
3104 command_print(CMD_CTX, "sam3-gpnvm%u: %u", x, v);
3106 return r;
3108 if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
3109 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
3110 command_print(CMD_CTX, "sam3-gpnvm%u: %u", who, v);
3111 return r;
3112 } else {
3113 command_print(CMD_CTX, "sam3-gpnvm invalid GPNVM: %u", who);
3114 return ERROR_COMMAND_SYNTAX_ERROR;
3118 if (who == -1) {
3119 command_print(CMD_CTX, "Missing GPNVM number");
3120 return ERROR_COMMAND_SYNTAX_ERROR;
3123 if (0 == strcmp("set", CMD_ARGV[0])) {
3124 r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who);
3125 } else if ((0 == strcmp("clr", CMD_ARGV[0])) ||
3126 (0 == strcmp("clear", CMD_ARGV[0]))) { // quietly accept both
3127 r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
3128 } else {
3129 command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
3130 r = ERROR_COMMAND_SYNTAX_ERROR;
3132 return r;
3135 COMMAND_HANDLER(sam3_handle_slowclk_command)
3137 struct sam3_chip *pChip;
3139 pChip = get_current_sam3(CMD_CTX);
3140 if (!pChip) {
3141 return ERROR_OK;
3145 switch (CMD_ARGC) {
3146 case 0:
3147 // show
3148 break;
3149 case 1:
3151 // set
3152 uint32_t v;
3153 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
3154 if (v > 200000) {
3155 // absurd slow clock of 200Khz?
3156 command_print(CMD_CTX,"Absurd/illegal slow clock freq: %d\n", (int)(v));
3157 return ERROR_COMMAND_SYNTAX_ERROR;
3159 pChip->cfg.slow_freq = v;
3160 break;
3162 default:
3163 // error
3164 command_print(CMD_CTX,"Too many parameters");
3165 return ERROR_COMMAND_SYNTAX_ERROR;
3166 break;
3168 command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
3169 (int)(pChip->cfg.slow_freq/ 1000),
3170 (int)(pChip->cfg.slow_freq% 1000));
3171 return ERROR_OK;
3174 static const struct command_registration at91sam3_exec_command_handlers[] = {
3176 .name = "gpnvm",
3177 .handler = sam3_handle_gpnvm_command,
3178 .mode = COMMAND_EXEC,
3179 .usage = "[('clr'|'set'|'show') bitnum]",
3180 .help = "Without arguments, shows all bits in the gpnvm "
3181 "register. Otherwise, clears, sets, or shows one "
3182 "General Purpose Non-Volatile Memory (gpnvm) bit.",
3185 .name = "info",
3186 .handler = sam3_handle_info_command,
3187 .mode = COMMAND_EXEC,
3188 .help = "Print information about the current at91sam3 chip"
3189 "and its flash configuration.",
3192 .name = "slowclk",
3193 .handler = sam3_handle_slowclk_command,
3194 .mode = COMMAND_EXEC,
3195 .usage = "[clock_hz]",
3196 .help = "Display or set the slowclock frequency "
3197 "(default 32768 Hz).",
3199 COMMAND_REGISTRATION_DONE
3201 static const struct command_registration at91sam3_command_handlers[] = {
3203 .name = "at91sam3",
3204 .mode = COMMAND_ANY,
3205 .help = "at91sam3 flash command group",
3206 .chain = at91sam3_exec_command_handlers,
3208 COMMAND_REGISTRATION_DONE
3211 struct flash_driver at91sam3_flash = {
3212 .name = "at91sam3",
3213 .commands = at91sam3_command_handlers,
3214 .flash_bank_command = sam3_flash_bank_command,
3215 .erase = sam3_erase,
3216 .protect = sam3_protect,
3217 .write = sam3_write,
3218 .read = default_flash_read,
3219 .probe = sam3_probe,
3220 .auto_probe = sam3_auto_probe,
3221 .erase_check = sam3_erase_check,
3222 .protect_check = sam3_protect_check,
3223 .info = sam3_info,