1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * Copyright (C) 2008 by Gheorghe Guran (atlas) *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ****************************************************************************/
21 /***************************************************************************
23 * New flash setup command:
25 * flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>
26 * [<chip_type> <banks>
27 * <sectors_per_bank> <pages_per_sector>
28 * <page_size> <num_nvmbits>
31 * <ext_freq_khz> - MUST be used if clock is from external source,
32 * CAN be used if main oscillator frequency is known (recommended)
34 * ==== RECOMMENDED (covers clock speed) ============
35 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000
36 * (if auto-detect fails; provides clock spec)
37 * flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000
38 * (auto-detect everything except the clock)
39 * ==== NOT RECOMMENDED !!! (clock speed is not configured) ====
40 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0
41 * (if auto-detect fails)
42 * flash bank at91sam7 0 0 0 0 $_TARGETNAME
43 * (old style, auto-detect everything)
44 ****************************************************************************/
51 #include <helper/binarybuffer.h>
53 /* AT91SAM7 control registers */
54 #define DBGU_CIDR 0xFFFFF240
55 #define CKGR_MCFR 0xFFFFFC24
56 #define CKGR_MOR 0xFFFFFC20
57 #define CKGR_MCFR_MAINRDY 0x10000
58 #define CKGR_PLLR 0xFFFFFC2c
59 #define CKGR_PLLR_DIV 0xff
60 #define CKGR_PLLR_MUL 0x07ff0000
61 #define PMC_MCKR 0xFFFFFC30
62 #define PMC_MCKR_CSS 0x03
63 #define PMC_MCKR_PRES 0x1c
65 /* Flash Controller Commands */
75 /* MC_FSR bit definitions */
79 /* AT91SAM7 constants */
82 /* Flash timing modes */
83 #define FMR_TIMING_NONE 0
84 #define FMR_TIMING_NVBITS 1
85 #define FMR_TIMING_FLASH 2
87 /* Flash size constants */
88 #define FLASH_SIZE_8KB 1
89 #define FLASH_SIZE_16KB 2
90 #define FLASH_SIZE_32KB 3
91 #define FLASH_SIZE_64KB 5
92 #define FLASH_SIZE_128KB 7
93 #define FLASH_SIZE_256KB 9
94 #define FLASH_SIZE_512KB 10
95 #define FLASH_SIZE_1024KB 12
96 #define FLASH_SIZE_2048KB 14
98 static int at91sam7_protect_check(struct flash_bank
*bank
);
99 static int at91sam7_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
,
102 static uint32_t at91sam7_get_flash_status(struct target
*target
, int bank_number
);
103 static void at91sam7_set_flash_mode(struct flash_bank
*bank
, int mode
);
104 static uint32_t at91sam7_wait_status_busy(struct flash_bank
*bank
, uint32_t waitbits
, int timeout
);
105 static int at91sam7_flash_command(struct flash_bank
*bank
, uint8_t cmd
, uint16_t pagen
);
107 static const uint32_t mc_fmr
[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
108 static const uint32_t mc_fcr
[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
109 static const uint32_t mc_fsr
[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
111 static const char *eproc
[8] = {
112 "Unknown", "ARM946-E", "ARM7TDMI", "Unknown", "ARM920T", "ARM926EJ-S", "Unknown", "Unknown"
115 struct at91sam7_flash_bank
{
116 /* chip id register */
119 uint16_t cidr_nvptyp
;
121 uint16_t cidr_sramsiz
;
122 uint16_t cidr_nvpsiz
;
123 uint16_t cidr_nvpsiz2
;
125 uint16_t cidr_version
;
126 const char *target_name
;
128 /* flash auto-detection */
129 uint8_t flash_autodetection
;
132 uint16_t pages_per_sector
;
134 uint16_t pages_in_lockregion
;
137 uint16_t num_lockbits_on
;
139 uint16_t num_nvmbits
;
140 uint16_t num_nvmbits_on
;
145 * 1: fmcn for nvbits (1uS)
146 * 2: fmcn for flash (1.5uS) */
149 /* main clock status */
153 /* external clock frequency */
159 static long SRAMSIZ
[16] = {
179 static uint32_t at91sam7_get_flash_status(struct target
*target
, int bank_number
)
182 target_read_u32(target
, mc_fsr
[bank_number
], &fsr
);
187 /* Read clock configuration and set at91sam7_info->mck_freq */
188 static void at91sam7_read_clock_info(struct flash_bank
*bank
)
190 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
191 struct target
*target
= bank
->target
;
192 uint32_t mckr
, mcfr
, pllr
, mor
;
193 unsigned long tmp
= 0, mainfreq
;
195 /* Read Clock Generator Main Oscillator Register */
196 target_read_u32(target
, CKGR_MOR
, &mor
);
197 /* Read Clock Generator Main Clock Frequency Register */
198 target_read_u32(target
, CKGR_MCFR
, &mcfr
);
199 /* Read Master Clock Register*/
200 target_read_u32(target
, PMC_MCKR
, &mckr
);
201 /* Read Clock Generator PLL Register */
202 target_read_u32(target
, CKGR_PLLR
, &pllr
);
204 at91sam7_info
->mck_valid
= 0;
205 at91sam7_info
->mck_freq
= 0;
206 switch (mckr
& PMC_MCKR_CSS
) {
207 case 0: /* Slow Clock */
208 at91sam7_info
->mck_valid
= 1;
212 case 1: /* Main Clock */
213 if ((mcfr
& CKGR_MCFR_MAINRDY
) &&
214 (at91sam7_info
->ext_freq
== 0)) {
215 at91sam7_info
->mck_valid
= 1;
216 tmp
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
217 } else if (at91sam7_info
->ext_freq
!= 0) {
218 at91sam7_info
->mck_valid
= 1;
219 tmp
= at91sam7_info
->ext_freq
;
223 case 2: /* Reserved */
226 case 3: /* PLL Clock */
227 if ((mcfr
& CKGR_MCFR_MAINRDY
) &&
228 (at91sam7_info
->ext_freq
== 0)) {
229 target_read_u32(target
, CKGR_PLLR
, &pllr
);
230 if (!(pllr
& CKGR_PLLR_DIV
))
232 at91sam7_info
->mck_valid
= 1;
233 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
234 /* Integer arithmetic should have sufficient precision
235 * as long as PLL is properly configured. */
236 tmp
= mainfreq
/ (pllr
& CKGR_PLLR_DIV
)*
237 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
238 } else if ((at91sam7_info
->ext_freq
!= 0) &&
239 ((pllr
&CKGR_PLLR_DIV
) != 0)) {
240 at91sam7_info
->mck_valid
= 1;
241 tmp
= at91sam7_info
->ext_freq
/ (pllr
&CKGR_PLLR_DIV
)*
242 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
247 /* Prescaler adjust */
248 if ((((mckr
& PMC_MCKR_PRES
) >> 2) == 7) || (tmp
== 0)) {
249 at91sam7_info
->mck_valid
= 0;
250 at91sam7_info
->mck_freq
= 0;
251 } else if (((mckr
& PMC_MCKR_PRES
) >> 2) != 0)
252 at91sam7_info
->mck_freq
= tmp
>> ((mckr
& PMC_MCKR_PRES
) >> 2);
254 at91sam7_info
->mck_freq
= tmp
;
257 /* Setup the timing registers for nvbits or normal flash */
258 static void at91sam7_set_flash_mode(struct flash_bank
*bank
, int mode
)
260 uint32_t fmr
, fmcn
= 0, fws
= 0;
261 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
262 struct target
*target
= bank
->target
;
264 if (mode
&& (mode
!= at91sam7_info
->flashmode
)) {
265 /* Always round up (ceil) */
266 if (mode
== FMR_TIMING_NVBITS
) {
267 if (at91sam7_info
->cidr_arch
== 0x60) {
268 /* AT91SAM7A3 uses master clocks in 100 ns */
269 fmcn
= (at91sam7_info
->mck_freq
/10000000ul) + 1;
271 /* master clocks in 1uS for ARCH 0x7 types */
272 fmcn
= (at91sam7_info
->mck_freq
/1000000ul) + 1;
274 } else if (mode
== FMR_TIMING_FLASH
) {
275 /* main clocks in 1.5uS */
276 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+
277 (at91sam7_info
->mck_freq
/2000000ul) + 1;
280 /* hard overclocking */
284 /* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */
285 if (at91sam7_info
->mck_freq
<= 33333ul)
287 /* Only allow fws = 0 if clock frequency is < 30 MHz. */
288 if (at91sam7_info
->mck_freq
> 30000000ul)
291 LOG_DEBUG("fmcn[%i]: %i", bank
->bank_number
, (int)(fmcn
));
292 fmr
= fmcn
<< 16 | fws
<< 8;
293 target_write_u32(target
, mc_fmr
[bank
->bank_number
], fmr
);
296 at91sam7_info
->flashmode
= mode
;
299 static uint32_t at91sam7_wait_status_busy(struct flash_bank
*bank
, uint32_t waitbits
, int timeout
)
303 while ((!((status
= at91sam7_get_flash_status(bank
->target
,
304 bank
->bank_number
)) & waitbits
)) && (timeout
-- > 0)) {
305 LOG_DEBUG("status[%i]: 0x%" PRIx32
"", (int)bank
->bank_number
, status
);
309 LOG_DEBUG("status[%i]: 0x%" PRIx32
"", bank
->bank_number
, status
);
312 LOG_ERROR("status register: 0x%" PRIx32
"", status
);
314 LOG_ERROR("Lock Error Bit Detected, Operation Abort");
316 LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
318 LOG_ERROR("Security Bit Set, Operation Abort");
324 /* Send one command to the AT91SAM flash controller */
325 static int at91sam7_flash_command(struct flash_bank
*bank
, uint8_t cmd
, uint16_t pagen
)
328 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
329 struct target
*target
= bank
->target
;
331 fcr
= (0x5A << 24) | ((pagen
&0x3FF) << 8) | cmd
;
332 target_write_u32(target
, mc_fcr
[bank
->bank_number
], fcr
);
333 LOG_DEBUG("Flash command: 0x%" PRIx32
", flash bank: %i, page number: %u",
335 bank
->bank_number
+ 1,
338 if ((at91sam7_info
->cidr_arch
== 0x60) && ((cmd
== SLB
) | (cmd
== CLB
))) {
339 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
340 if (at91sam7_wait_status_busy(bank
, MC_FSR_EOL
, 10)&0x0C)
341 return ERROR_FLASH_OPERATION_FAILED
;
345 if (at91sam7_wait_status_busy(bank
, MC_FSR_FRDY
, 10)&0x0C)
346 return ERROR_FLASH_OPERATION_FAILED
;
351 /* Read device id register, main clock frequency register and fill in driver info structure */
352 static int at91sam7_read_part_info(struct flash_bank
*bank
)
354 struct at91sam7_flash_bank
*at91sam7_info
;
355 struct target
*target
= bank
->target
;
360 uint8_t banks_num
= 0;
361 uint16_t num_nvmbits
= 0;
362 uint16_t sectors_num
= 0;
363 uint16_t pages_per_sector
= 0;
364 uint16_t page_size
= 0;
367 uint32_t base_address
= 0;
368 char *target_name_t
= "Unknown";
370 at91sam7_info
= bank
->driver_priv
;
372 if (at91sam7_info
->cidr
!= 0) {
373 /* flash already configured, update clock and check for protected sectors */
374 for (struct flash_bank
*t_bank
= bank
; t_bank
; t_bank
= t_bank
->next
) {
375 if (t_bank
->target
!= target
)
377 /* re-calculate master clock frequency */
378 at91sam7_read_clock_info(t_bank
);
381 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
383 /* check protect state */
384 at91sam7_protect_check(t_bank
);
390 /* Read and parse chip identification register */
391 target_read_u32(target
, DBGU_CIDR
, &cidr
);
393 LOG_WARNING("Cannot identify target as an AT91SAM");
394 return ERROR_FLASH_OPERATION_FAILED
;
397 if (at91sam7_info
->flash_autodetection
== 0) {
398 /* banks and sectors are already created, based on data from input file */
399 for (struct flash_bank
*t_bank
= bank
; t_bank
; t_bank
= t_bank
->next
) {
400 if (t_bank
->target
!= target
)
403 at91sam7_info
= t_bank
->driver_priv
;
405 at91sam7_info
->cidr
= cidr
;
406 at91sam7_info
->cidr_ext
= (cidr
>> 31)&0x0001;
407 at91sam7_info
->cidr_nvptyp
= (cidr
>> 28)&0x0007;
408 at91sam7_info
->cidr_arch
= (cidr
>> 20)&0x00FF;
409 at91sam7_info
->cidr_sramsiz
= (cidr
>> 16)&0x000F;
410 at91sam7_info
->cidr_nvpsiz2
= (cidr
>> 12)&0x000F;
411 at91sam7_info
->cidr_nvpsiz
= (cidr
>> 8)&0x000F;
412 at91sam7_info
->cidr_eproc
= (cidr
>> 5)&0x0007;
413 at91sam7_info
->cidr_version
= cidr
&0x001F;
415 /* calculate master clock frequency */
416 at91sam7_read_clock_info(t_bank
);
419 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
421 /* check protect state */
422 at91sam7_protect_check(t_bank
);
428 arch
= (cidr
>> 20)&0x00FF;
430 /* check flash size */
431 switch ((cidr
>> 8)&0x000F) {
435 case FLASH_SIZE_16KB
:
438 pages_per_sector
= 32;
440 base_address
= 0x00100000;
443 target_name_t
= "AT91SAM7S161/16";
447 case FLASH_SIZE_32KB
:
450 pages_per_sector
= 32;
452 base_address
= 0x00100000;
455 target_name_t
= "AT91SAM7S321/32";
459 target_name_t
= "AT91SAM7SE32";
463 case FLASH_SIZE_64KB
:
466 pages_per_sector
= 32;
468 base_address
= 0x00100000;
471 target_name_t
= "AT91SAM7S64";
475 case FLASH_SIZE_128KB
:
478 pages_per_sector
= 64;
480 base_address
= 0x00100000;
483 target_name_t
= "AT91SAM7S128";
487 target_name_t
= "AT91SAM7XC128";
491 target_name_t
= "AT91SAM7SE128";
495 target_name_t
= "AT91SAM7X128";
499 case FLASH_SIZE_256KB
:
502 pages_per_sector
= 64;
504 base_address
= 0x00100000;
507 target_name_t
= "AT91SAM7A3";
511 target_name_t
= "AT91SAM7S256";
515 target_name_t
= "AT91SAM7XC256";
519 target_name_t
= "AT91SAM7SE256";
523 target_name_t
= "AT91SAM7X256";
527 case FLASH_SIZE_512KB
:
530 pages_per_sector
= 64;
532 base_address
= 0x00100000;
535 target_name_t
= "AT91SAM7S512";
539 target_name_t
= "AT91SAM7XC512";
543 target_name_t
= "AT91SAM7SE512";
547 target_name_t
= "AT91SAM7X512";
551 case FLASH_SIZE_1024KB
:
554 case FLASH_SIZE_2048KB
:
558 if (strcmp(target_name_t
, "Unknown") == 0) {
560 "Target autodetection failed! Please specify target parameters in configuration file");
561 return ERROR_FLASH_OPERATION_FAILED
;
564 ext_freq
= at91sam7_info
->ext_freq
;
566 /* calculate bank size */
567 bank_size
= sectors_num
* pages_per_sector
* page_size
;
569 for (bnk
= 0; bnk
< banks_num
; bnk
++) {
570 struct flash_bank
*t_bank
= bank
;
573 /* create a new flash bank element */
574 struct flash_bank
*fb
= malloc(sizeof(struct flash_bank
));
576 fb
->driver
= bank
->driver
;
577 fb
->driver_priv
= malloc(sizeof(struct at91sam7_flash_bank
));
578 fb
->name
= "sam7_probed";
581 /* link created bank in 'flash_banks' list */
584 t_bank
= t_bank
->next
;
587 t_bank
->bank_number
= bnk
;
588 t_bank
->base
= base_address
+ bnk
* bank_size
;
589 t_bank
->size
= bank_size
;
590 t_bank
->chip_width
= 0;
591 t_bank
->bus_width
= 4;
592 t_bank
->num_sectors
= sectors_num
;
594 /* allocate sectors */
595 t_bank
->sectors
= malloc(sectors_num
* sizeof(struct flash_sector
));
596 for (sec
= 0; sec
< sectors_num
; sec
++) {
597 t_bank
->sectors
[sec
].offset
= sec
* pages_per_sector
* page_size
;
598 t_bank
->sectors
[sec
].size
= pages_per_sector
* page_size
;
599 t_bank
->sectors
[sec
].is_erased
= -1;
600 t_bank
->sectors
[sec
].is_protected
= -1;
603 at91sam7_info
= t_bank
->driver_priv
;
605 at91sam7_info
->cidr
= cidr
;
606 at91sam7_info
->cidr_ext
= (cidr
>> 31)&0x0001;
607 at91sam7_info
->cidr_nvptyp
= (cidr
>> 28)&0x0007;
608 at91sam7_info
->cidr_arch
= (cidr
>> 20)&0x00FF;
609 at91sam7_info
->cidr_sramsiz
= (cidr
>> 16)&0x000F;
610 at91sam7_info
->cidr_nvpsiz2
= (cidr
>> 12)&0x000F;
611 at91sam7_info
->cidr_nvpsiz
= (cidr
>> 8)&0x000F;
612 at91sam7_info
->cidr_eproc
= (cidr
>> 5)&0x0007;
613 at91sam7_info
->cidr_version
= cidr
&0x001F;
615 at91sam7_info
->target_name
= target_name_t
;
616 at91sam7_info
->flashmode
= 0;
617 at91sam7_info
->ext_freq
= ext_freq
;
618 at91sam7_info
->num_nvmbits
= num_nvmbits
;
619 at91sam7_info
->num_nvmbits_on
= 0;
620 at91sam7_info
->pagesize
= page_size
;
621 at91sam7_info
->pages_per_sector
= pages_per_sector
;
623 /* calculate master clock frequency */
624 at91sam7_read_clock_info(t_bank
);
627 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
629 /* check protect state */
630 at91sam7_protect_check(t_bank
);
633 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x",
634 at91sam7_info
->cidr_nvptyp
,
635 at91sam7_info
->cidr_arch
);
640 static int at91sam7_erase_check(struct flash_bank
*bank
)
642 if (bank
->target
->state
!= TARGET_HALTED
) {
643 LOG_ERROR("Target not halted");
644 return ERROR_TARGET_NOT_HALTED
;
647 /* Configure the flash controller timing */
648 at91sam7_read_clock_info(bank
);
649 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
651 return default_flash_blank_check(bank
);
654 static int at91sam7_protect_check(struct flash_bank
*bank
)
656 uint8_t lock_pos
, gpnvm_pos
;
659 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
661 if (at91sam7_info
->cidr
== 0)
662 return ERROR_FLASH_BANK_NOT_PROBED
;
663 if (bank
->target
->state
!= TARGET_HALTED
) {
664 LOG_ERROR("Target not halted");
665 return ERROR_TARGET_NOT_HALTED
;
668 status
= at91sam7_get_flash_status(bank
->target
, bank
->bank_number
);
669 at91sam7_info
->lockbits
= (status
>> 16);
671 at91sam7_info
->num_lockbits_on
= 0;
672 for (lock_pos
= 0; lock_pos
< bank
->num_sectors
; lock_pos
++) {
673 if (((status
>> (16 + lock_pos
))&(0x0001)) == 1) {
674 at91sam7_info
->num_lockbits_on
++;
675 bank
->sectors
[lock_pos
].is_protected
= 1;
677 bank
->sectors
[lock_pos
].is_protected
= 0;
680 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
681 status
= at91sam7_get_flash_status(bank
->target
, 0);
683 at91sam7_info
->securitybit
= (status
>> 4)&0x01;
684 at91sam7_info
->nvmbits
= (status
>> 8)&0xFF;
686 at91sam7_info
->num_nvmbits_on
= 0;
687 for (gpnvm_pos
= 0; gpnvm_pos
< at91sam7_info
->num_nvmbits
; gpnvm_pos
++) {
688 if (((status
>> (8 + gpnvm_pos
))&(0x01)) == 1)
689 at91sam7_info
->num_nvmbits_on
++;
695 FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command
)
697 struct flash_bank
*t_bank
= bank
;
698 struct at91sam7_flash_bank
*at91sam7_info
;
699 struct target
*target
= t_bank
->target
;
701 uint32_t base_address
;
703 uint32_t ext_freq
= 0;
705 unsigned int chip_width
;
706 unsigned int bus_width
;
707 unsigned int banks_num
;
708 unsigned int num_sectors
;
710 uint16_t pages_per_sector
;
712 uint16_t num_nvmbits
;
714 at91sam7_info
= malloc(sizeof(struct at91sam7_flash_bank
));
715 t_bank
->driver_priv
= at91sam7_info
;
717 /* part wasn't probed for info yet */
718 at91sam7_info
->cidr
= 0;
719 at91sam7_info
->flashmode
= 0;
720 at91sam7_info
->ext_freq
= 0;
721 at91sam7_info
->flash_autodetection
= 0;
724 at91sam7_info
->flash_autodetection
= 1;
728 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], base_address
);
730 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[3], chip_width
);
731 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[4], bus_width
);
733 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[8], banks_num
);
734 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[9], num_sectors
);
735 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[10], pages_per_sector
);
736 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[11], page_size
);
737 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[12], num_nvmbits
);
739 if (CMD_ARGC
== 14) {
741 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[13], freq
);
742 ext_freq
= freq
* 1000;
743 at91sam7_info
->ext_freq
= ext_freq
;
746 if ((bus_width
== 0) || (banks_num
== 0) || (num_sectors
== 0) ||
747 (pages_per_sector
== 0) || (page_size
== 0) || (num_nvmbits
== 0)) {
748 at91sam7_info
->flash_autodetection
= 1;
752 /* calculate bank size */
753 bank_size
= num_sectors
* pages_per_sector
* page_size
;
755 for (unsigned int bnk
= 0; bnk
< banks_num
; bnk
++) {
758 /* create a new bank element */
759 struct flash_bank
*fb
= malloc(sizeof(struct flash_bank
));
761 fb
->driver
= bank
->driver
;
762 fb
->driver_priv
= malloc(sizeof(struct at91sam7_flash_bank
));
763 fb
->name
= "sam7_probed";
766 /* link created bank in 'flash_banks' list */
769 t_bank
= t_bank
->next
;
772 t_bank
->bank_number
= bnk
;
773 t_bank
->base
= base_address
+ bnk
* bank_size
;
774 t_bank
->size
= bank_size
;
775 t_bank
->chip_width
= chip_width
;
776 t_bank
->bus_width
= bus_width
;
777 t_bank
->num_sectors
= num_sectors
;
779 /* allocate sectors */
780 t_bank
->sectors
= malloc(num_sectors
* sizeof(struct flash_sector
));
781 for (unsigned int sec
= 0; sec
< num_sectors
; sec
++) {
782 t_bank
->sectors
[sec
].offset
= sec
* pages_per_sector
* page_size
;
783 t_bank
->sectors
[sec
].size
= pages_per_sector
* page_size
;
784 t_bank
->sectors
[sec
].is_erased
= -1;
785 t_bank
->sectors
[sec
].is_protected
= -1;
788 at91sam7_info
= t_bank
->driver_priv
;
790 at91sam7_info
->target_name
= strdup(CMD_ARGV
[7]);
791 at91sam7_info
->flashmode
= 0;
792 at91sam7_info
->ext_freq
= ext_freq
;
793 at91sam7_info
->num_nvmbits
= num_nvmbits
;
794 at91sam7_info
->num_nvmbits_on
= 0;
795 at91sam7_info
->pagesize
= page_size
;
796 at91sam7_info
->pages_per_sector
= pages_per_sector
;
802 static int at91sam7_erase(struct flash_bank
*bank
, unsigned int first
,
805 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
806 uint32_t nbytes
, pos
;
810 if (at91sam7_info
->cidr
== 0)
811 return ERROR_FLASH_BANK_NOT_PROBED
;
813 if (bank
->target
->state
!= TARGET_HALTED
) {
814 LOG_ERROR("Target not halted");
815 return ERROR_TARGET_NOT_HALTED
;
818 if ((last
< first
) || (last
>= bank
->num_sectors
))
819 return ERROR_FLASH_SECTOR_INVALID
;
822 if ((first
== 0) && (last
== (bank
->num_sectors
-1)))
825 /* Configure the flash controller timing */
826 at91sam7_read_clock_info(bank
);
827 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
830 if (at91sam7_flash_command(bank
, EA
, 0) != ERROR_OK
)
831 return ERROR_FLASH_OPERATION_FAILED
;
833 /* allocate and clean buffer */
834 nbytes
= (last
- first
+ 1) * bank
->sectors
[first
].size
;
835 buffer
= malloc(nbytes
* sizeof(uint8_t));
836 for (pos
= 0; pos
< nbytes
; pos
++)
839 if (at91sam7_write(bank
, buffer
, bank
->sectors
[first
].offset
, nbytes
) != ERROR_OK
) {
841 return ERROR_FLASH_OPERATION_FAILED
;
847 /* mark erased sectors */
848 for (unsigned int sec
= first
; sec
<= last
; sec
++)
849 bank
->sectors
[sec
].is_erased
= 1;
854 static int at91sam7_protect(struct flash_bank
*bank
, int set
,
855 unsigned int first
, unsigned int last
)
860 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
862 if (at91sam7_info
->cidr
== 0)
863 return ERROR_FLASH_BANK_NOT_PROBED
;
865 if (bank
->target
->state
!= TARGET_HALTED
) {
866 LOG_ERROR("Target not halted");
867 return ERROR_TARGET_NOT_HALTED
;
870 if ((last
< first
) || (last
>= bank
->num_sectors
))
871 return ERROR_FLASH_SECTOR_INVALID
;
873 /* Configure the flash controller timing */
874 at91sam7_read_clock_info(bank
);
875 at91sam7_set_flash_mode(bank
, FMR_TIMING_NVBITS
);
877 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
883 /* if we lock a page from one sector then entire sector will be locked, also,
884 * if we unlock a page from a locked sector, entire sector will be unlocked */
885 pagen
= sector
* at91sam7_info
->pages_per_sector
;
887 if (at91sam7_flash_command(bank
, cmd
, pagen
) != ERROR_OK
)
888 return ERROR_FLASH_OPERATION_FAILED
;
891 at91sam7_protect_check(bank
);
896 static int at91sam7_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
899 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
900 struct target
*target
= bank
->target
;
901 uint32_t dst_min_alignment
, wcount
, bytes_remaining
= count
;
902 uint32_t first_page
, last_page
, pagen
, buffer_pos
;
904 if (at91sam7_info
->cidr
== 0)
905 return ERROR_FLASH_BANK_NOT_PROBED
;
907 if (bank
->target
->state
!= TARGET_HALTED
) {
908 LOG_ERROR("Target not halted");
909 return ERROR_TARGET_NOT_HALTED
;
912 if (offset
+ count
> bank
->size
)
913 return ERROR_FLASH_DST_OUT_OF_BANK
;
915 dst_min_alignment
= at91sam7_info
->pagesize
;
917 if (offset
% dst_min_alignment
) {
918 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"",
921 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
924 if (at91sam7_info
->cidr_arch
== 0)
925 return ERROR_FLASH_BANK_NOT_PROBED
;
927 first_page
= offset
/dst_min_alignment
;
928 last_page
= DIV_ROUND_UP(offset
+ count
, dst_min_alignment
);
930 LOG_DEBUG("first_page: %i, last_page: %i, count %i",
935 /* Configure the flash controller timing */
936 at91sam7_read_clock_info(bank
);
937 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
939 for (pagen
= first_page
; pagen
< last_page
; pagen
++) {
940 if (bytes_remaining
< dst_min_alignment
)
941 count
= bytes_remaining
;
943 count
= dst_min_alignment
;
944 bytes_remaining
-= count
;
946 /* Write one block to the PageWriteBuffer */
947 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
948 wcount
= DIV_ROUND_UP(count
, 4);
949 retval
= target_write_memory(target
, bank
->base
+ pagen
*dst_min_alignment
, 4,
950 wcount
, buffer
+ buffer_pos
);
951 if (retval
!= ERROR_OK
)
954 /* Send Write Page command to Flash Controller */
955 if (at91sam7_flash_command(bank
, WP
, pagen
) != ERROR_OK
)
956 return ERROR_FLASH_OPERATION_FAILED
;
957 LOG_DEBUG("Write flash bank:%u page number:%" PRIu32
, bank
->bank_number
, pagen
);
963 static int at91sam7_probe(struct flash_bank
*bank
)
965 /* we can't probe on an at91sam7
966 * if this is an at91sam7, it has the configured flash */
969 if (bank
->target
->state
!= TARGET_HALTED
) {
970 LOG_ERROR("Target not halted");
971 return ERROR_TARGET_NOT_HALTED
;
974 retval
= at91sam7_read_part_info(bank
);
975 if (retval
!= ERROR_OK
)
981 static int get_at91sam7_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
983 struct at91sam7_flash_bank
*at91sam7_info
= bank
->driver_priv
;
985 if (at91sam7_info
->cidr
== 0)
986 return ERROR_FLASH_BANK_NOT_PROBED
;
988 command_print_sameline(cmd
, "\n at91sam7 driver information: Chip is %s\n",
989 at91sam7_info
->target_name
);
991 command_print_sameline(cmd
,
992 " Cidr: 0x%8.8" PRIx32
" | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | "
993 "Flashsize: 0x%8.8" PRIx32
"\n",
995 at91sam7_info
->cidr_arch
,
996 eproc
[at91sam7_info
->cidr_eproc
],
997 at91sam7_info
->cidr_version
,
1000 command_print_sameline(cmd
,
1001 " Master clock (estimated): %u kHz | External clock: %u kHz\n",
1002 (unsigned)(at91sam7_info
->mck_freq
/ 1000),
1003 (unsigned)(at91sam7_info
->ext_freq
/ 1000));
1005 command_print_sameline(cmd
,
1006 " Pagesize: %i bytes | Lockbits(%u): %i 0x%4.4x | Pages in lock region: %i\n",
1007 at91sam7_info
->pagesize
,
1009 at91sam7_info
->num_lockbits_on
,
1010 at91sam7_info
->lockbits
,
1011 at91sam7_info
->pages_per_sector
* at91sam7_info
->num_lockbits_on
);
1013 command_print_sameline(cmd
, " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1014 at91sam7_info
->securitybit
, at91sam7_info
->num_nvmbits
,
1015 at91sam7_info
->num_nvmbits_on
, at91sam7_info
->nvmbits
);
1021 * On AT91SAM7S: When the gpnvm bits are set with
1022 * > at91sam7 gpnvm bitnr set
1023 * the changes are not visible in the flash controller status register MC_FSR
1024 * until the processor has been reset.
1025 * On the Olimex board this requires a power cycle.
1026 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1027 * The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1028 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1030 COMMAND_HANDLER(at91sam7_handle_gpnvm_command
)
1032 struct flash_bank
*bank
;
1036 struct at91sam7_flash_bank
*at91sam7_info
;
1040 return ERROR_COMMAND_SYNTAX_ERROR
;
1042 bank
= get_flash_bank_by_num_noprobe(0);
1044 return ERROR_FLASH_BANK_INVALID
;
1045 if (strcmp(bank
->driver
->name
, "at91sam7")) {
1046 command_print(CMD
, "not an at91sam7 flash bank '%s'", CMD_ARGV
[0]);
1047 return ERROR_FLASH_BANK_INVALID
;
1049 if (bank
->target
->state
!= TARGET_HALTED
) {
1050 LOG_ERROR("target has to be halted to perform flash operation");
1051 return ERROR_TARGET_NOT_HALTED
;
1054 if (strcmp(CMD_ARGV
[1], "set") == 0)
1056 else if (strcmp(CMD_ARGV
[1], "clear") == 0)
1059 return ERROR_COMMAND_SYNTAX_ERROR
;
1061 at91sam7_info
= bank
->driver_priv
;
1062 if (at91sam7_info
->cidr
== 0) {
1063 retval
= at91sam7_read_part_info(bank
);
1064 if (retval
!= ERROR_OK
)
1068 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], bit
);
1069 if ((bit
< 0) || (bit
>= at91sam7_info
->num_nvmbits
)) {
1071 "gpnvm bit '#%s' is out of bounds for target %s",
1073 at91sam7_info
->target_name
);
1077 /* Configure the flash controller timing */
1078 at91sam7_read_clock_info(bank
);
1079 at91sam7_set_flash_mode(bank
, FMR_TIMING_NVBITS
);
1081 if (at91sam7_flash_command(bank
, flashcmd
, bit
) != ERROR_OK
)
1082 return ERROR_FLASH_OPERATION_FAILED
;
1084 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1085 status
= at91sam7_get_flash_status(bank
->target
, 0);
1086 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32
,
1091 /* check protect state */
1092 at91sam7_protect_check(bank
);
1097 static const struct command_registration at91sam7_exec_command_handlers
[] = {
1100 .handler
= at91sam7_handle_gpnvm_command
,
1101 .mode
= COMMAND_EXEC
,
1102 .help
= "set or clear one General Purpose Non-Volatile Memory "
1104 .usage
= "bitnum ('set'|'clear')",
1106 COMMAND_REGISTRATION_DONE
1108 static const struct command_registration at91sam7_command_handlers
[] = {
1111 .mode
= COMMAND_ANY
,
1112 .help
= "at91sam7 flash command group",
1114 .chain
= at91sam7_exec_command_handlers
,
1116 COMMAND_REGISTRATION_DONE
1119 const struct flash_driver at91sam7_flash
= {
1121 .usage
= "gpnvm <bit> <set | clear>",
1122 .commands
= at91sam7_command_handlers
,
1123 .flash_bank_command
= at91sam7_flash_bank_command
,
1124 .erase
= at91sam7_erase
,
1125 .protect
= at91sam7_protect
,
1126 .write
= at91sam7_write
,
1127 .read
= default_flash_read
,
1128 .probe
= at91sam7_probe
,
1129 .auto_probe
= at91sam7_probe
,
1130 .erase_check
= at91sam7_erase_check
,
1131 .protect_check
= at91sam7_protect_check
,
1132 .info
= get_at91sam7_info
,
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)