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, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ****************************************************************************/
23 /***************************************************************************
25 * New flash setup command:
27 * flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>
28 * [<chip_type> <banks>
29 * <sectors_per_bank> <pages_per_sector>
30 * <page_size> <num_nvmbits>
33 * <ext_freq_khz> - MUST be used if clock is from external source,
34 * CAN be used if main oscillator frequency is known (recommended)
36 * ==== RECOMMENDED (covers clock speed) ============
37 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000
38 * (if auto-detect fails; provides clock spec)
39 * flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000
40 * (auto-detect everything except the clock)
41 * ==== NOT RECOMMENDED !!! (clock speed is not configured) ====
42 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0
43 * (if auto-detect fails)
44 * flash bank at91sam7 0 0 0 0 $_TARGETNAME
45 * (old style, auto-detect everything)
46 ****************************************************************************/
53 #include "binarybuffer.h"
55 static int at91sam7_protect_check(struct flash_bank_s
*bank
);
56 static int at91sam7_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
58 static uint32_t at91sam7_get_flash_status(target_t
*target
, int bank_number
);
59 static void at91sam7_set_flash_mode(flash_bank_t
*bank
, int mode
);
60 static uint32_t at91sam7_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
);
61 static int at91sam7_flash_command(struct flash_bank_s
*bank
, uint8_t cmd
, uint16_t pagen
);
63 static uint32_t MC_FMR
[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
64 static uint32_t MC_FCR
[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
65 static uint32_t MC_FSR
[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
67 static char * EPROC
[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
70 static long SRAMSIZ
[16] = {
91 static uint32_t at91sam7_get_flash_status(target_t
*target
, int bank_number
)
94 target_read_u32(target
, MC_FSR
[bank_number
], &fsr
);
99 /* Read clock configuration and set at91sam7_info->mck_freq */
100 static void at91sam7_read_clock_info(flash_bank_t
*bank
)
102 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
103 target_t
*target
= bank
->target
;
104 uint32_t mckr
, mcfr
, pllr
, mor
;
105 unsigned long tmp
= 0, mainfreq
;
107 /* Read Clock Generator Main Oscillator Register */
108 target_read_u32(target
, CKGR_MOR
, &mor
);
109 /* Read Clock Generator Main Clock Frequency Register */
110 target_read_u32(target
, CKGR_MCFR
, &mcfr
);
111 /* Read Master Clock Register*/
112 target_read_u32(target
, PMC_MCKR
, &mckr
);
113 /* Read Clock Generator PLL Register */
114 target_read_u32(target
, CKGR_PLLR
, &pllr
);
116 at91sam7_info
->mck_valid
= 0;
117 at91sam7_info
->mck_freq
= 0;
118 switch (mckr
& PMC_MCKR_CSS
)
120 case 0: /* Slow Clock */
121 at91sam7_info
->mck_valid
= 1;
125 case 1: /* Main Clock */
126 if ((mcfr
& CKGR_MCFR_MAINRDY
) &&
127 (at91sam7_info
->ext_freq
== 0))
129 at91sam7_info
->mck_valid
= 1;
130 tmp
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
132 else if (at91sam7_info
->ext_freq
!= 0)
134 at91sam7_info
->mck_valid
= 1;
135 tmp
= at91sam7_info
->ext_freq
;
139 case 2: /* Reserved */
142 case 3: /* PLL Clock */
143 if ((mcfr
& CKGR_MCFR_MAINRDY
) &&
144 (at91sam7_info
->ext_freq
== 0))
146 target_read_u32(target
, CKGR_PLLR
, &pllr
);
147 if (!(pllr
& CKGR_PLLR_DIV
))
149 at91sam7_info
->mck_valid
= 1;
150 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
151 /* Integer arithmetic should have sufficient precision
152 * as long as PLL is properly configured. */
153 tmp
= mainfreq
/ (pllr
& CKGR_PLLR_DIV
)*
154 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
156 else if ((at91sam7_info
->ext_freq
!= 0) &&
157 ((pllr
&CKGR_PLLR_DIV
) != 0))
159 at91sam7_info
->mck_valid
= 1;
160 tmp
= at91sam7_info
->ext_freq
/ (pllr
&CKGR_PLLR_DIV
)*
161 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
166 /* Prescaler adjust */
167 if ((((mckr
& PMC_MCKR_PRES
) >> 2) == 7) || (tmp
== 0))
169 at91sam7_info
->mck_valid
= 0;
170 at91sam7_info
->mck_freq
= 0;
172 else if (((mckr
& PMC_MCKR_PRES
) >> 2) != 0)
173 at91sam7_info
->mck_freq
= tmp
>> ((mckr
& PMC_MCKR_PRES
) >> 2);
175 at91sam7_info
->mck_freq
= tmp
;
178 /* Setup the timimg registers for nvbits or normal flash */
179 static void at91sam7_set_flash_mode(flash_bank_t
*bank
, int mode
)
181 uint32_t fmr
, fmcn
= 0, fws
= 0;
182 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
183 target_t
*target
= bank
->target
;
185 if (mode
&& (mode
!= at91sam7_info
->flashmode
))
187 /* Always round up (ceil) */
188 if (mode
== FMR_TIMING_NVBITS
)
190 if (at91sam7_info
->cidr_arch
== 0x60)
192 /* AT91SAM7A3 uses master clocks in 100 ns */
193 fmcn
= (at91sam7_info
->mck_freq
/10000000ul) + 1;
197 /* master clocks in 1uS for ARCH 0x7 types */
198 fmcn
= (at91sam7_info
->mck_freq
/1000000ul) + 1;
201 else if (mode
== FMR_TIMING_FLASH
)
203 /* main clocks in 1.5uS */
204 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+
205 (at91sam7_info
->mck_freq
/2000000ul) + 1;
208 /* hard overclocking */
212 /* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */
213 if (at91sam7_info
->mck_freq
<= 33333ul)
215 /* Only allow fws = 0 if clock frequency is < 30 MHz. */
216 if (at91sam7_info
->mck_freq
> 30000000ul)
219 LOG_DEBUG("fmcn[%i]: %i", bank
->bank_number
, (int)(fmcn
));
220 fmr
= fmcn
<< 16 | fws
<< 8;
221 target_write_u32(target
, MC_FMR
[bank
->bank_number
], fmr
);
224 at91sam7_info
->flashmode
= mode
;
227 static uint32_t at91sam7_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
)
231 while ((!((status
= at91sam7_get_flash_status(bank
->target
, bank
->bank_number
)) & waitbits
)) && (timeout
-- > 0))
233 LOG_DEBUG("status[%i]: 0x%" PRIx32
"", (int)bank
->bank_number
, status
);
237 LOG_DEBUG("status[%i]: 0x%" PRIx32
"", bank
->bank_number
, status
);
241 LOG_ERROR("status register: 0x%" PRIx32
"", status
);
243 LOG_ERROR("Lock Error Bit Detected, Operation Abort");
245 LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
247 LOG_ERROR("Security Bit Set, Operation Abort");
253 /* Send one command to the AT91SAM flash controller */
254 static int at91sam7_flash_command(struct flash_bank_s
*bank
, uint8_t cmd
, uint16_t pagen
)
257 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
258 target_t
*target
= bank
->target
;
260 fcr
= (0x5A << 24) | ((pagen
&0x3FF) << 8) | cmd
;
261 target_write_u32(target
, MC_FCR
[bank
->bank_number
], fcr
);
262 LOG_DEBUG("Flash command: 0x%" PRIx32
", flash bank: %i, page number: %u", fcr
, bank
->bank_number
+ 1, pagen
);
264 if ((at91sam7_info
->cidr_arch
== 0x60) && ((cmd
== SLB
) | (cmd
== CLB
)))
266 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
267 if (at91sam7_wait_status_busy(bank
, MC_FSR_EOL
, 10)&0x0C)
269 return ERROR_FLASH_OPERATION_FAILED
;
274 if (at91sam7_wait_status_busy(bank
, MC_FSR_FRDY
, 10)&0x0C)
276 return ERROR_FLASH_OPERATION_FAILED
;
282 /* Read device id register, main clock frequency register and fill in driver info structure */
283 static int at91sam7_read_part_info(struct flash_bank_s
*bank
)
285 flash_bank_t
*t_bank
= bank
;
286 at91sam7_flash_bank_t
*at91sam7_info
;
287 target_t
*target
= t_bank
->target
;
292 uint8_t banks_num
= 0;
293 uint16_t num_nvmbits
= 0;
294 uint16_t sectors_num
= 0;
295 uint16_t pages_per_sector
= 0;
296 uint16_t page_size
= 0;
299 uint32_t base_address
= 0;
300 char *target_name
= "Unknown";
302 at91sam7_info
= t_bank
->driver_priv
;
304 if (at91sam7_info
->cidr
!= 0)
306 /* flash already configured, update clock and check for protected sectors */
307 flash_bank_t
*fb
= bank
;
312 /* re-calculate master clock frequency */
313 at91sam7_read_clock_info(t_bank
);
316 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
318 /* check protect state */
319 at91sam7_protect_check(t_bank
);
328 /* Read and parse chip identification register */
329 target_read_u32(target
, DBGU_CIDR
, &cidr
);
332 LOG_WARNING("Cannot identify target as an AT91SAM");
333 return ERROR_FLASH_OPERATION_FAILED
;
336 if (at91sam7_info
->flash_autodetection
== 0)
338 /* banks and sectors are already created, based on data from input file */
339 flash_bank_t
*fb
= bank
;
343 at91sam7_info
= t_bank
->driver_priv
;
345 at91sam7_info
->cidr
= cidr
;
346 at91sam7_info
->cidr_ext
= (cidr
>> 31)&0x0001;
347 at91sam7_info
->cidr_nvptyp
= (cidr
>> 28)&0x0007;
348 at91sam7_info
->cidr_arch
= (cidr
>> 20)&0x00FF;
349 at91sam7_info
->cidr_sramsiz
= (cidr
>> 16)&0x000F;
350 at91sam7_info
->cidr_nvpsiz2
= (cidr
>> 12)&0x000F;
351 at91sam7_info
->cidr_nvpsiz
= (cidr
>> 8)&0x000F;
352 at91sam7_info
->cidr_eproc
= (cidr
>> 5)&0x0007;
353 at91sam7_info
->cidr_version
= cidr
&0x001F;
355 /* calculate master clock frequency */
356 at91sam7_read_clock_info(t_bank
);
359 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
361 /* check protect state */
362 at91sam7_protect_check(t_bank
);
371 arch
= (cidr
>> 20)&0x00FF;
373 /* check flash size */
374 switch ((cidr
>> 8)&0x000F)
379 case FLASH_SIZE_16KB
:
382 pages_per_sector
= 32;
384 base_address
= 0x00100000;
388 target_name
= "AT91SAM7S161/16";
392 case FLASH_SIZE_32KB
:
395 pages_per_sector
= 32;
397 base_address
= 0x00100000;
401 target_name
= "AT91SAM7S321/32";
406 target_name
= "AT91SAM7SE32";
410 case FLASH_SIZE_64KB
:
413 pages_per_sector
= 32;
415 base_address
= 0x00100000;
419 target_name
= "AT91SAM7S64";
423 case FLASH_SIZE_128KB
:
426 pages_per_sector
= 64;
428 base_address
= 0x00100000;
432 target_name
= "AT91SAM7S128";
437 target_name
= "AT91SAM7XC128";
442 target_name
= "AT91SAM7SE128";
447 target_name
= "AT91SAM7X128";
451 case FLASH_SIZE_256KB
:
454 pages_per_sector
= 64;
456 base_address
= 0x00100000;
460 target_name
= "AT91SAM7A3";
465 target_name
= "AT91SAM7S256";
470 target_name
= "AT91SAM7XC256";
475 target_name
= "AT91SAM7SE256";
480 target_name
= "AT91SAM7X256";
484 case FLASH_SIZE_512KB
:
487 pages_per_sector
= 64;
489 base_address
= 0x00100000;
493 target_name
= "AT91SAM7S512";
498 target_name
= "AT91SAM7XC512";
503 target_name
= "AT91SAM7SE512";
508 target_name
= "AT91SAM7X512";
512 case FLASH_SIZE_1024KB
:
515 case FLASH_SIZE_2048KB
:
519 if (strcmp(target_name
, "Unknown") == 0)
521 LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
522 return ERROR_FLASH_OPERATION_FAILED
;
525 ext_freq
= at91sam7_info
->ext_freq
;
527 /* calculate bank size */
528 bank_size
= sectors_num
* pages_per_sector
* page_size
;
530 for (bnk
= 0; bnk
< banks_num
; bnk
++)
534 /* create a new flash bank element */
535 flash_bank_t
*fb
= malloc(sizeof(flash_bank_t
));
537 fb
->driver
= bank
->driver
;
538 fb
->driver_priv
= malloc(sizeof(at91sam7_flash_bank_t
));
541 /* link created bank in 'flash_banks' list and redirect t_bank */
546 t_bank
->bank_number
= bnk
;
547 t_bank
->base
= base_address
+ bnk
* bank_size
;
548 t_bank
->size
= bank_size
;
549 t_bank
->chip_width
= 0;
550 t_bank
->bus_width
= 4;
551 t_bank
->num_sectors
= sectors_num
;
553 /* allocate sectors */
554 t_bank
->sectors
= malloc(sectors_num
* sizeof(flash_sector_t
));
555 for (sec
= 0; sec
< sectors_num
; sec
++)
557 t_bank
->sectors
[sec
].offset
= sec
* pages_per_sector
* page_size
;
558 t_bank
->sectors
[sec
].size
= pages_per_sector
* page_size
;
559 t_bank
->sectors
[sec
].is_erased
= -1;
560 t_bank
->sectors
[sec
].is_protected
= -1;
563 at91sam7_info
= t_bank
->driver_priv
;
565 at91sam7_info
->cidr
= cidr
;
566 at91sam7_info
->cidr_ext
= (cidr
>> 31)&0x0001;
567 at91sam7_info
->cidr_nvptyp
= (cidr
>> 28)&0x0007;
568 at91sam7_info
->cidr_arch
= (cidr
>> 20)&0x00FF;
569 at91sam7_info
->cidr_sramsiz
= (cidr
>> 16)&0x000F;
570 at91sam7_info
->cidr_nvpsiz2
= (cidr
>> 12)&0x000F;
571 at91sam7_info
->cidr_nvpsiz
= (cidr
>> 8)&0x000F;
572 at91sam7_info
->cidr_eproc
= (cidr
>> 5)&0x0007;
573 at91sam7_info
->cidr_version
= cidr
&0x001F;
575 at91sam7_info
->target_name
= target_name
;
576 at91sam7_info
->flashmode
= 0;
577 at91sam7_info
->ext_freq
= ext_freq
;
578 at91sam7_info
->num_nvmbits
= num_nvmbits
;
579 at91sam7_info
->num_nvmbits_on
= 0;
580 at91sam7_info
->pagesize
= page_size
;
581 at91sam7_info
->pages_per_sector
= pages_per_sector
;
583 /* calculate master clock frequency */
584 at91sam7_read_clock_info(t_bank
);
587 at91sam7_set_flash_mode(t_bank
, FMR_TIMING_NONE
);
589 /* check protect state */
590 at91sam7_protect_check(t_bank
);
593 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info
->cidr_nvptyp
, at91sam7_info
->cidr_arch
);
598 static int at91sam7_erase_check(struct flash_bank_s
*bank
)
600 target_t
*target
= bank
->target
;
608 if (bank
->target
->state
!= TARGET_HALTED
)
610 LOG_ERROR("Target not halted");
611 return ERROR_TARGET_NOT_HALTED
;
614 /* Configure the flash controller timing */
615 at91sam7_read_clock_info(bank
);
616 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
619 for (nSector
= 0; nSector
< bank
->num_sectors
; nSector
++)
621 retval
= target_blank_check_memory(target
, bank
->base
+ bank
->sectors
[nSector
].offset
,
622 bank
->sectors
[nSector
].size
, &blank
);
623 if (retval
!= ERROR_OK
)
629 bank
->sectors
[nSector
].is_erased
= 1;
631 bank
->sectors
[nSector
].is_erased
= 0;
639 LOG_USER("Running slow fallback erase check - add working memory");
641 buffer
= malloc(bank
->sectors
[0].size
);
642 for (nSector
= 0; nSector
< bank
->num_sectors
; nSector
++)
644 bank
->sectors
[nSector
].is_erased
= 1;
645 retval
= target_read_memory(target
, bank
->base
+ bank
->sectors
[nSector
].offset
, 4,
646 bank
->sectors
[nSector
].size
/4, buffer
);
647 if (retval
!= ERROR_OK
)
650 for (nByte
= 0; nByte
< bank
->sectors
[nSector
].size
; nByte
++)
652 if (buffer
[nByte
] != 0xFF)
654 bank
->sectors
[nSector
].is_erased
= 0;
664 static int at91sam7_protect_check(struct flash_bank_s
*bank
)
666 uint8_t lock_pos
, gpnvm_pos
;
669 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
671 if (at91sam7_info
->cidr
== 0)
673 return ERROR_FLASH_BANK_NOT_PROBED
;
675 if (bank
->target
->state
!= TARGET_HALTED
)
677 LOG_ERROR("Target not halted");
678 return ERROR_TARGET_NOT_HALTED
;
681 status
= at91sam7_get_flash_status(bank
->target
, bank
->bank_number
);
682 at91sam7_info
->lockbits
= (status
>> 16);
684 at91sam7_info
->num_lockbits_on
= 0;
685 for (lock_pos
= 0; lock_pos
< bank
->num_sectors
; lock_pos
++)
687 if (((status
>> (16 + lock_pos
))&(0x0001)) == 1)
689 at91sam7_info
->num_lockbits_on
++;
690 bank
->sectors
[lock_pos
].is_protected
= 1;
693 bank
->sectors
[lock_pos
].is_protected
= 0;
696 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
697 status
= at91sam7_get_flash_status(bank
->target
, 0);
699 at91sam7_info
->securitybit
= (status
>> 4)&0x01;
700 at91sam7_info
->nvmbits
= (status
>> 8)&0xFF;
702 at91sam7_info
->num_nvmbits_on
= 0;
703 for (gpnvm_pos
= 0; gpnvm_pos
< at91sam7_info
->num_nvmbits
; gpnvm_pos
++)
705 if (((status
>> (8 + gpnvm_pos
))&(0x01)) == 1)
707 at91sam7_info
->num_nvmbits_on
++;
714 FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command
)
716 flash_bank_t
*t_bank
= bank
;
717 at91sam7_flash_bank_t
*at91sam7_info
;
718 target_t
*target
= t_bank
->target
;
720 uint32_t base_address
;
722 uint32_t ext_freq
= 0;
729 uint16_t pages_per_sector
;
731 uint16_t num_nvmbits
;
737 at91sam7_info
= malloc(sizeof(at91sam7_flash_bank_t
));
738 t_bank
->driver_priv
= at91sam7_info
;
740 /* part wasn't probed for info yet */
741 at91sam7_info
->cidr
= 0;
742 at91sam7_info
->flashmode
= 0;
743 at91sam7_info
->ext_freq
= 0;
744 at91sam7_info
->flash_autodetection
= 0;
748 at91sam7_info
->flash_autodetection
= 1;
752 COMMAND_PARSE_NUMBER(u32
, args
[1], base_address
);
754 COMMAND_PARSE_NUMBER(int, args
[3], chip_width
);
755 COMMAND_PARSE_NUMBER(int, args
[4], bus_width
);
757 COMMAND_PARSE_NUMBER(int, args
[8], banks_num
);
758 COMMAND_PARSE_NUMBER(int, args
[9], num_sectors
);
759 COMMAND_PARSE_NUMBER(u16
, args
[10], pages_per_sector
);
760 COMMAND_PARSE_NUMBER(u16
, args
[11], page_size
);
761 COMMAND_PARSE_NUMBER(u16
, args
[12], num_nvmbits
);
765 COMMAND_PARSE_NUMBER(ulong
, args
[13], freq
);
766 ext_freq
= freq
* 1000;
767 at91sam7_info
->ext_freq
= ext_freq
;
770 if ((bus_width
== 0) || (banks_num
== 0) || (num_sectors
== 0) ||
771 (pages_per_sector
== 0) || (page_size
== 0) || (num_nvmbits
== 0))
773 at91sam7_info
->flash_autodetection
= 1;
777 target_name
= calloc(strlen(args
[7]) + 1, sizeof(char));
778 strcpy(target_name
, args
[7]);
780 /* calculate bank size */
781 bank_size
= num_sectors
* pages_per_sector
* page_size
;
783 for (bnk
= 0; bnk
< banks_num
; bnk
++)
787 /* create a new bank element */
788 flash_bank_t
*fb
= malloc(sizeof(flash_bank_t
));
790 fb
->driver
= bank
->driver
;
791 fb
->driver_priv
= malloc(sizeof(at91sam7_flash_bank_t
));
794 /* link created bank in 'flash_banks' list and redirect t_bank */
799 t_bank
->bank_number
= bnk
;
800 t_bank
->base
= base_address
+ bnk
* bank_size
;
801 t_bank
->size
= bank_size
;
802 t_bank
->chip_width
= chip_width
;
803 t_bank
->bus_width
= bus_width
;
804 t_bank
->num_sectors
= num_sectors
;
806 /* allocate sectors */
807 t_bank
->sectors
= malloc(num_sectors
* sizeof(flash_sector_t
));
808 for (sec
= 0; sec
< num_sectors
; sec
++)
810 t_bank
->sectors
[sec
].offset
= sec
* pages_per_sector
* page_size
;
811 t_bank
->sectors
[sec
].size
= pages_per_sector
* page_size
;
812 t_bank
->sectors
[sec
].is_erased
= -1;
813 t_bank
->sectors
[sec
].is_protected
= -1;
816 at91sam7_info
= t_bank
->driver_priv
;
818 at91sam7_info
->target_name
= target_name
;
819 at91sam7_info
->flashmode
= 0;
820 at91sam7_info
->ext_freq
= ext_freq
;
821 at91sam7_info
->num_nvmbits
= num_nvmbits
;
822 at91sam7_info
->num_nvmbits_on
= 0;
823 at91sam7_info
->pagesize
= page_size
;
824 at91sam7_info
->pages_per_sector
= pages_per_sector
;
830 static int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
)
832 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
834 uint32_t nbytes
, pos
;
838 if (at91sam7_info
->cidr
== 0)
840 return ERROR_FLASH_BANK_NOT_PROBED
;
843 if (bank
->target
->state
!= TARGET_HALTED
)
845 LOG_ERROR("Target not halted");
846 return ERROR_TARGET_NOT_HALTED
;
849 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
851 return ERROR_FLASH_SECTOR_INVALID
;
855 if ((first
== 0) && (last
== (bank
->num_sectors
-1)))
860 /* Configure the flash controller timing */
861 at91sam7_read_clock_info(bank
);
862 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
866 if (at91sam7_flash_command(bank
, EA
, 0) != ERROR_OK
)
868 return ERROR_FLASH_OPERATION_FAILED
;
873 /* allocate and clean buffer */
874 nbytes
= (last
- first
+ 1) * bank
->sectors
[first
].size
;
875 buffer
= malloc(nbytes
* sizeof(uint8_t));
876 for (pos
= 0; pos
< nbytes
; pos
++)
881 if (at91sam7_write(bank
, buffer
, bank
->sectors
[first
].offset
, nbytes
) != ERROR_OK
)
883 return ERROR_FLASH_OPERATION_FAILED
;
889 /* mark erased sectors */
890 for (sec
= first
; sec
<= last
; sec
++)
892 bank
->sectors
[sec
].is_erased
= 1;
898 static int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
904 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
906 if (at91sam7_info
->cidr
== 0)
908 return ERROR_FLASH_BANK_NOT_PROBED
;
911 if (bank
->target
->state
!= TARGET_HALTED
)
913 LOG_ERROR("Target not halted");
914 return ERROR_TARGET_NOT_HALTED
;
917 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
919 return ERROR_FLASH_SECTOR_INVALID
;
922 /* Configure the flash controller timing */
923 at91sam7_read_clock_info(bank
);
924 at91sam7_set_flash_mode(bank
, FMR_TIMING_NVBITS
);
926 for (sector
= first
; sector
<= last
; sector
++)
933 /* if we lock a page from one sector then entire sector will be locked, also,
934 * if we unlock a page from a locked sector, entire sector will be unlocked */
935 pagen
= sector
* at91sam7_info
->pages_per_sector
;
937 if (at91sam7_flash_command(bank
, cmd
, pagen
) != ERROR_OK
)
939 return ERROR_FLASH_OPERATION_FAILED
;
943 at91sam7_protect_check(bank
);
948 static int at91sam7_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
951 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
952 target_t
*target
= bank
->target
;
953 uint32_t dst_min_alignment
, wcount
, bytes_remaining
= count
;
954 uint32_t first_page
, last_page
, pagen
, buffer_pos
;
956 if (at91sam7_info
->cidr
== 0)
958 return ERROR_FLASH_BANK_NOT_PROBED
;
961 if (bank
->target
->state
!= TARGET_HALTED
)
963 LOG_ERROR("Target not halted");
964 return ERROR_TARGET_NOT_HALTED
;
967 if (offset
+ count
> bank
->size
)
968 return ERROR_FLASH_DST_OUT_OF_BANK
;
970 dst_min_alignment
= at91sam7_info
->pagesize
;
972 if (offset
% dst_min_alignment
)
974 LOG_WARNING("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"", offset
, dst_min_alignment
);
975 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
978 if (at91sam7_info
->cidr_arch
== 0)
979 return ERROR_FLASH_BANK_NOT_PROBED
;
981 first_page
= offset
/dst_min_alignment
;
982 last_page
= CEIL(offset
+ count
, dst_min_alignment
);
984 LOG_DEBUG("first_page: %i, last_page: %i, count %i", (int)first_page
, (int)last_page
, (int)count
);
986 /* Configure the flash controller timing */
987 at91sam7_read_clock_info(bank
);
988 at91sam7_set_flash_mode(bank
, FMR_TIMING_FLASH
);
990 for (pagen
= first_page
; pagen
< last_page
; pagen
++)
992 if (bytes_remaining
< dst_min_alignment
)
993 count
= bytes_remaining
;
995 count
= dst_min_alignment
;
996 bytes_remaining
-= count
;
998 /* Write one block to the PageWriteBuffer */
999 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
1000 wcount
= CEIL(count
,4);
1001 if ((retval
= target_write_memory(target
, bank
->base
+ pagen
*dst_min_alignment
, 4, wcount
, buffer
+ buffer_pos
)) != ERROR_OK
)
1006 /* Send Write Page command to Flash Controller */
1007 if (at91sam7_flash_command(bank
, WP
, pagen
) != ERROR_OK
)
1009 return ERROR_FLASH_OPERATION_FAILED
;
1011 LOG_DEBUG("Write flash bank:%i page number:%" PRIi32
"", bank
->bank_number
, pagen
);
1017 static int at91sam7_probe(struct flash_bank_s
*bank
)
1019 /* we can't probe on an at91sam7
1020 * if this is an at91sam7, it has the configured flash */
1023 if (bank
->target
->state
!= TARGET_HALTED
)
1025 LOG_ERROR("Target not halted");
1026 return ERROR_TARGET_NOT_HALTED
;
1029 retval
= at91sam7_read_part_info(bank
);
1030 if (retval
!= ERROR_OK
)
1036 static int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
1039 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
1041 if (at91sam7_info
->cidr
== 0)
1043 return ERROR_FLASH_BANK_NOT_PROBED
;
1046 printed
= snprintf(buf
, buf_size
,
1047 "\n at91sam7 driver information: Chip is %s\n",
1048 at91sam7_info
->target_name
);
1051 buf_size
-= printed
;
1053 printed
= snprintf(buf
,
1055 " Cidr: 0x%8.8" PRIx32
" | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8" PRIx32
"\n",
1056 at91sam7_info
->cidr
,
1057 at91sam7_info
->cidr_arch
,
1058 EPROC
[at91sam7_info
->cidr_eproc
],
1059 at91sam7_info
->cidr_version
,
1063 buf_size
-= printed
;
1065 printed
= snprintf(buf
, buf_size
,
1066 " Master clock (estimated): %u KHz | External clock: %u KHz\n",
1067 (unsigned)(at91sam7_info
->mck_freq
/ 1000), (unsigned)(at91sam7_info
->ext_freq
/ 1000));
1070 buf_size
-= printed
;
1072 printed
= snprintf(buf
, buf_size
,
1073 " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i \n",
1074 at91sam7_info
->pagesize
, bank
->num_sectors
, at91sam7_info
->num_lockbits_on
,
1075 at91sam7_info
->lockbits
, at91sam7_info
->pages_per_sector
*at91sam7_info
->num_lockbits_on
);
1078 buf_size
-= printed
;
1080 printed
= snprintf(buf
, buf_size
,
1081 " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1082 at91sam7_info
->securitybit
, at91sam7_info
->num_nvmbits
,
1083 at91sam7_info
->num_nvmbits_on
, at91sam7_info
->nvmbits
);
1086 buf_size
-= printed
;
1092 * On AT91SAM7S: When the gpnvm bits are set with
1093 * > at91sam7 gpnvm bitnr set
1094 * the changes are not visible in the flash controller status register MC_FSR
1095 * until the processor has been reset.
1096 * On the Olimex board this requires a power cycle.
1097 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1098 * The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1099 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1101 COMMAND_HANDLER(at91sam7_handle_gpnvm_command
)
1107 at91sam7_flash_bank_t
*at91sam7_info
;
1112 command_print(cmd_ctx
, "at91sam7 gpnvm <bit> <set | clear>");
1116 bank
= get_flash_bank_by_num_noprobe(0);
1119 return ERROR_FLASH_BANK_INVALID
;
1121 if (strcmp(bank
->driver
->name
, "at91sam7"))
1123 command_print(cmd_ctx
, "not an at91sam7 flash bank '%s'", args
[0]);
1124 return ERROR_FLASH_BANK_INVALID
;
1126 if (bank
->target
->state
!= TARGET_HALTED
)
1128 LOG_ERROR("target has to be halted to perform flash operation");
1129 return ERROR_TARGET_NOT_HALTED
;
1132 if (strcmp(args
[1], "set") == 0)
1136 else if (strcmp(args
[1], "clear") == 0)
1142 return ERROR_COMMAND_SYNTAX_ERROR
;
1145 at91sam7_info
= bank
->driver_priv
;
1146 if (at91sam7_info
->cidr
== 0)
1148 retval
= at91sam7_read_part_info(bank
);
1149 if (retval
!= ERROR_OK
)
1155 COMMAND_PARSE_NUMBER(int, args
[0], bit
);
1156 if ((bit
< 0) || (bit
>= at91sam7_info
->num_nvmbits
))
1158 command_print(cmd_ctx
, "gpnvm bit '#%s' is out of bounds for target %s", args
[0], at91sam7_info
->target_name
);
1162 /* Configure the flash controller timing */
1163 at91sam7_read_clock_info(bank
);
1164 at91sam7_set_flash_mode(bank
, FMR_TIMING_NVBITS
);
1166 if (at91sam7_flash_command(bank
, flashcmd
, bit
) != ERROR_OK
)
1168 return ERROR_FLASH_OPERATION_FAILED
;
1171 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1172 status
= at91sam7_get_flash_status(bank
->target
, 0);
1173 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32
" \n", flashcmd
, bit
, status
);
1175 /* check protect state */
1176 at91sam7_protect_check(bank
);
1181 static int at91sam7_register_commands(struct command_context_s
*cmd_ctx
)
1183 command_t
*at91sam7_cmd
= register_command(cmd_ctx
, NULL
, "at91sam7",
1184 NULL
, COMMAND_ANY
, NULL
);
1186 register_command(cmd_ctx
, at91sam7_cmd
, "gpnvm",
1187 at91sam7_handle_gpnvm_command
, COMMAND_EXEC
,
1188 "at91sam7 gpnvm <bit> set | clear, "
1189 "set or clear one gpnvm bit");
1194 flash_driver_t at91sam7_flash
= {
1196 .register_commands
= &at91sam7_register_commands
,
1197 .flash_bank_command
= &at91sam7_flash_bank_command
,
1198 .erase
= &at91sam7_erase
,
1199 .protect
= &at91sam7_protect
,
1200 .write
= &at91sam7_write
,
1201 .probe
= &at91sam7_probe
,
1202 .auto_probe
= &at91sam7_probe
,
1203 .erase_check
= &at91sam7_erase_check
,
1204 .protect_check
= &at91sam7_protect_check
,
1205 .info
= &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)