1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 /***************************************************************************
22 There are some things to notice
24 * AT91SAM7S64 is tested
25 * All AT91SAM7Sxx and AT91SAM7Xxx should work but is not tested
26 * All parameters are identified from onchip configuartion registers
28 * The flash controller handles erases automatically on a page (128/265 byte) basis
29 * Only an EraseAll command is supported by the controller
30 * Partial erases can be implemented in software by writing one 0xFFFFFFFF word to
31 * some location in every page in the region to be erased
33 * Lock regions (sectors) are 32 or 64 pages
35 ***************************************************************************/
40 #include "replacements.h"
47 #include "binarybuffer.h"
54 int at91sam7_register_commands(struct command_context_s
*cmd_ctx
);
55 int at91sam7_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
56 int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
);
57 int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
58 int at91sam7_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
59 int at91sam7_probe(struct flash_bank_s
*bank
);
60 int at91sam7_erase_check(struct flash_bank_s
*bank
);
61 int at91sam7_protect_check(struct flash_bank_s
*bank
);
62 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
64 u32
at91sam7_get_flash_status(flash_bank_t
*bank
, u8 flashplane
);
65 void at91sam7_set_flash_mode(flash_bank_t
*bank
, u8 flashplane
, int mode
);
66 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u8 flashplane
, u32 waitbits
, int timeout
);
67 int at91sam7_flash_command(struct flash_bank_s
*bank
, u8 flashplane
, u8 cmd
, u16 pagen
);
68 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
70 flash_driver_t at91sam7_flash
=
73 .register_commands
= at91sam7_register_commands
,
74 .flash_bank_command
= at91sam7_flash_bank_command
,
75 .erase
= at91sam7_erase
,
76 .protect
= at91sam7_protect
,
77 .write
= at91sam7_write
,
78 .probe
= at91sam7_probe
,
79 .erase_check
= at91sam7_erase_check
,
80 .protect_check
= at91sam7_protect_check
,
84 u32 MC_FMR
[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
85 u32 MC_FCR
[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
86 u32 MC_FSR
[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
88 char * EPROC
[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
102 0x100000, /* 1024K */
104 0x200000, /* 2048K */
127 int at91sam7_register_commands(struct command_context_s
*cmd_ctx
)
129 command_t
*at91sam7_cmd
= register_command(cmd_ctx
, NULL
, "at91sam7", NULL
, COMMAND_ANY
, NULL
);
130 register_command(cmd_ctx
, at91sam7_cmd
, "gpnvm", at91sam7_handle_gpnvm_command
, COMMAND_EXEC
,
131 "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
136 u32
at91sam7_get_flash_status(flash_bank_t
*bank
, u8 flashplane
)
138 target_t
*target
= bank
->target
;
141 target_read_u32(target
, MC_FSR
[flashplane
], &fsr
);
146 /** Read clock configuration and set at91sam7_info->usec_clocks*/
147 void at91sam7_read_clock_info(flash_bank_t
*bank
)
149 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
150 target_t
*target
= bank
->target
;
151 u32 mckr
, mcfr
, pllr
;
152 unsigned long tmp
= 0, mainfreq
;
155 /* Read main clock freqency register */
156 target_read_u32(target
, CKGR_MCFR
, &mcfr
);
157 /* Read master clock register */
158 target_read_u32(target
, PMC_MCKR
, &mckr
);
159 /* Read Clock Generator PLL Register */
160 target_read_u32(target
, CKGR_PLLR
, &pllr
);
162 at91sam7_info
->mck_valid
= 0;
163 switch (mckr
& PMC_MCKR_CSS
)
165 case 0: /* Slow Clock */
166 at91sam7_info
->mck_valid
= 1;
167 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
170 case 1: /* Main Clock */
171 if (mcfr
& CKGR_MCFR_MAINRDY
)
173 at91sam7_info
->mck_valid
= 1;
174 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
179 case 2: /* Reserved */
181 case 3: /* PLL Clock */
182 if (mcfr
& CKGR_MCFR_MAINRDY
)
184 target_read_u32(target
, CKGR_PLLR
, &pllr
);
185 if (!(pllr
& CKGR_PLLR_DIV
))
187 at91sam7_info
->mck_valid
= 1;
188 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
189 /* Integer arithmetic should have sufficient precision
190 as long as PLL is properly configured. */
191 tmp
= mainfreq
/ (pllr
& CKGR_PLLR_DIV
) *
192 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
197 /* Prescaler adjust */
198 if (((mckr
& PMC_MCKR_PRES
) >> 2) == 7)
199 at91sam7_info
->mck_valid
= 0;
201 at91sam7_info
->mck_freq
= tmp
>> ((mckr
& PMC_MCKR_PRES
) >> 2);
203 /* Forget old flash timing */
204 for (flashplane
= 0; flashplane
<at91sam7_info
->num_planes
; flashplane
++)
206 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_NONE
);
210 /* Setup the timimg registers for nvbits or normal flash */
211 void at91sam7_set_flash_mode(flash_bank_t
*bank
, u8 flashplane
, int mode
)
213 u32 fmr
, fmcn
= 0, fws
= 0;
214 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
215 target_t
*target
= bank
->target
;
217 if (mode
&& (mode
!= at91sam7_info
->flashmode
[flashplane
]))
219 /* Always round up (ceil) */
220 if (mode
==FMR_TIMING_NVBITS
)
222 if (at91sam7_info
->cidr_arch
== 0x60)
224 /* AT91SAM7A3 uses master clocks in 100 ns */
225 fmcn
= (at91sam7_info
->mck_freq
/10000000ul)+1;
229 /* master clocks in 1uS for ARCH 0x7 types */
230 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+1;
233 else if (mode
==FMR_TIMING_FLASH
)
234 /* main clocks in 1.5uS */
235 fmcn
= (at91sam7_info
->mck_freq
/666666ul)+1;
237 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
238 if (at91sam7_info
->mck_freq
<= 33333ul)
240 /* Only allow fws=0 if clock frequency is < 30 MHz. */
241 if (at91sam7_info
->mck_freq
> 30000000ul)
244 DEBUG("fmcn[%i]: %i", flashplane
, fmcn
);
245 fmr
= fmcn
<< 16 | fws
<< 8;
246 target_write_u32(target
, MC_FMR
[flashplane
], fmr
);
249 at91sam7_info
->flashmode
[flashplane
] = mode
;
252 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u8 flashplane
, u32 waitbits
, int timeout
)
256 while ((!((status
= at91sam7_get_flash_status(bank
,flashplane
)) & waitbits
)) && (timeout
-- > 0))
258 DEBUG("status[%i]: 0x%x", flashplane
, status
);
262 DEBUG("status[%i]: 0x%x", flashplane
, status
);
266 ERROR("status register: 0x%x", status
);
268 ERROR("Lock Error Bit Detected, Operation Abort");
270 ERROR("Invalid command and/or bad keyword, Operation Abort");
272 ERROR("Security Bit Set, Operation Abort");
279 /* Send one command to the AT91SAM flash controller */
280 int at91sam7_flash_command(struct flash_bank_s
*bank
, u8 flashplane
, u8 cmd
, u16 pagen
)
283 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
284 target_t
*target
= bank
->target
;
286 fcr
= (0x5A<<24) | ((pagen
&0x3FF)<<8) | cmd
;
287 target_write_u32(target
, MC_FCR
[flashplane
], fcr
);
288 DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr
, flashplane
, pagen
);
290 if ((at91sam7_info
->cidr_arch
== 0x60)&&((cmd
==SLB
)|(cmd
==CLB
)))
292 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
293 if (at91sam7_wait_status_busy(bank
, flashplane
, MC_FSR_EOL
, 10)&0x0C)
295 return ERROR_FLASH_OPERATION_FAILED
;
300 if (at91sam7_wait_status_busy(bank
, flashplane
, MC_FSR_FRDY
, 10)&0x0C)
302 return ERROR_FLASH_OPERATION_FAILED
;
307 /* Read device id register, main clock frequency register and fill in driver info structure */
308 int at91sam7_read_part_info(struct flash_bank_s
*bank
)
310 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
311 target_t
*target
= bank
->target
;
315 if (bank
->target
->state
!= TARGET_HALTED
)
317 return ERROR_TARGET_NOT_HALTED
;
320 /* Read and parse chip identification register */
321 target_read_u32(target
, DBGU_CIDR
, &cidr
);
325 WARNING("Cannot identify target as an AT91SAM");
326 return ERROR_FLASH_OPERATION_FAILED
;
329 at91sam7_info
->cidr
= cidr
;
330 at91sam7_info
->cidr_ext
= (cidr
>>31)&0x0001;
331 at91sam7_info
->cidr_nvptyp
= (cidr
>>28)&0x0007;
332 at91sam7_info
->cidr_arch
= (cidr
>>20)&0x00FF;
333 at91sam7_info
->cidr_sramsiz
= (cidr
>>16)&0x000F;
334 at91sam7_info
->cidr_nvpsiz2
= (cidr
>>12)&0x000F;
335 at91sam7_info
->cidr_nvpsiz
= (cidr
>>8)&0x000F;
336 at91sam7_info
->cidr_eproc
= (cidr
>>5)&0x0007;
337 at91sam7_info
->cidr_version
= cidr
&0x001F;
338 bank
->size
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
];
339 at91sam7_info
->target_name
= "Unknown";
341 /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
342 if (NVPSIZ
[at91sam7_info
->cidr_nvpsiz
]<0x80000) /* Flash size less than 512K, one flash plane */
344 bank
->num_sectors
= 1;
345 bank
->sectors
= malloc(sizeof(flash_sector_t
));
346 bank
->sectors
[0].offset
= 0;
347 bank
->sectors
[0].size
= bank
->size
;
348 bank
->sectors
[0].is_erased
= -1;
349 bank
->sectors
[0].is_protected
= -1;
351 else /* Flash size 512K or larger, several flash planes */
353 bank
->num_sectors
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
]/0x40000;
354 bank
->sectors
= malloc(bank
->num_sectors
*sizeof(flash_sector_t
));
355 for (sectornum
=0; sectornum
<bank
->num_sectors
; sectornum
++)
357 bank
->sectors
[sectornum
].offset
= sectornum
*0x40000;
358 bank
->sectors
[sectornum
].size
= 0x40000;
359 bank
->sectors
[sectornum
].is_erased
= -1;
360 bank
->sectors
[sectornum
].is_protected
= -1;
366 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info
->cidr_nvptyp
, at91sam7_info
->cidr_arch
);
368 /* Read main and master clock freqency register */
369 at91sam7_read_clock_info(bank
);
371 at91sam7_info
->num_planes
= 1;
372 status
= at91sam7_get_flash_status(bank
, 0);
373 at91sam7_info
->securitybit
= (status
>>4)&0x01;
374 at91sam7_protect_check(bank
); /* TODO Check the protect check */
376 if (at91sam7_info
->cidr_arch
== 0x70 )
378 at91sam7_info
->num_nvmbits
= 2;
379 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
380 bank
->base
= 0x100000;
382 if (bank
->size
==0x80000) /* AT91SAM7S512 */
384 at91sam7_info
->target_name
= "AT91SAM7S512";
385 at91sam7_info
->num_planes
= 2;
386 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
387 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
388 at91sam7_info
->num_lockbits
= 2*16;
389 at91sam7_info
->pagesize
= 256;
390 at91sam7_info
->pages_in_lockregion
= 64;
391 at91sam7_info
->num_pages
= 2*16*64;
393 if (bank
->size
==0x40000) /* AT91SAM7S256 */
395 at91sam7_info
->target_name
= "AT91SAM7S256";
396 at91sam7_info
->num_lockbits
= 16;
397 at91sam7_info
->pagesize
= 256;
398 at91sam7_info
->pages_in_lockregion
= 64;
399 at91sam7_info
->num_pages
= 16*64;
401 if (bank
->size
==0x20000) /* AT91SAM7S128 */
403 at91sam7_info
->target_name
= "AT91SAM7S128";
404 at91sam7_info
->num_lockbits
= 8;
405 at91sam7_info
->pagesize
= 256;
406 at91sam7_info
->pages_in_lockregion
= 64;
407 at91sam7_info
->num_pages
= 8*64;
409 if (bank
->size
==0x10000) /* AT91SAM7S64 */
411 at91sam7_info
->target_name
= "AT91SAM7S64";
412 at91sam7_info
->num_lockbits
= 16;
413 at91sam7_info
->pagesize
= 128;
414 at91sam7_info
->pages_in_lockregion
= 32;
415 at91sam7_info
->num_pages
= 16*32;
417 if (bank
->size
==0x08000) /* AT91SAM7S321/32 */
419 at91sam7_info
->target_name
= "AT91SAM7S321/32";
420 at91sam7_info
->num_lockbits
= 8;
421 at91sam7_info
->pagesize
= 128;
422 at91sam7_info
->pages_in_lockregion
= 32;
423 at91sam7_info
->num_pages
= 8*32;
429 if (at91sam7_info
->cidr_arch
== 0x71 )
431 at91sam7_info
->num_nvmbits
= 3;
432 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
433 bank
->base
= 0x100000;
435 if (bank
->size
==0x80000) /* AT91SAM7XC512 */
437 at91sam7_info
->target_name
= "AT91SAM7XC512";
438 at91sam7_info
->num_planes
= 2;
439 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
440 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
441 at91sam7_info
->num_lockbits
= 2*16;
442 at91sam7_info
->pagesize
= 256;
443 at91sam7_info
->pages_in_lockregion
= 64;
444 at91sam7_info
->num_pages
= 2*16*64;
446 if (bank
->size
==0x40000) /* AT91SAM7XC256 */
448 at91sam7_info
->target_name
= "AT91SAM7XC256";
449 at91sam7_info
->num_lockbits
= 16;
450 at91sam7_info
->pagesize
= 256;
451 at91sam7_info
->pages_in_lockregion
= 64;
452 at91sam7_info
->num_pages
= 16*64;
454 if (bank
->size
==0x20000) /* AT91SAM7XC128 */
456 at91sam7_info
->target_name
= "AT91SAM7XC128";
457 at91sam7_info
->num_lockbits
= 8;
458 at91sam7_info
->pagesize
= 256;
459 at91sam7_info
->pages_in_lockregion
= 64;
460 at91sam7_info
->num_pages
= 8*64;
466 if (at91sam7_info
->cidr_arch
== 0x72 )
468 at91sam7_info
->num_nvmbits
= 2;
469 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
470 bank
->base
= 0x100000;
472 if (bank
->size
==0x80000) /* AT91SAM7SE512 */
474 at91sam7_info
->target_name
= "AT91SAM7SE512";
475 at91sam7_info
->num_planes
= 2;
476 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
477 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
478 at91sam7_info
->num_lockbits
= 32;
479 at91sam7_info
->pagesize
= 256;
480 at91sam7_info
->pages_in_lockregion
= 64;
481 at91sam7_info
->num_pages
= 32*64;
483 if (bank
->size
==0x40000)
485 at91sam7_info
->target_name
= "AT91SAM7SE256";
486 at91sam7_info
->num_lockbits
= 16;
487 at91sam7_info
->pagesize
= 256;
488 at91sam7_info
->pages_in_lockregion
= 64;
489 at91sam7_info
->num_pages
= 16*64;
491 if (bank
->size
==0x08000)
493 at91sam7_info
->target_name
= "AT91SAM7SE32";
494 at91sam7_info
->num_lockbits
= 8;
495 at91sam7_info
->pagesize
= 128;
496 at91sam7_info
->pages_in_lockregion
= 32;
497 at91sam7_info
->num_pages
= 8*32;
503 if (at91sam7_info
->cidr_arch
== 0x75 )
505 at91sam7_info
->num_nvmbits
= 3;
506 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
507 bank
->base
= 0x100000;
509 if (bank
->size
==0x80000) /* AT91SAM7X512 */
511 at91sam7_info
->target_name
= "AT91SAM7X512";
512 at91sam7_info
->num_planes
= 2;
513 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
514 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
515 at91sam7_info
->num_lockbits
= 32;
516 at91sam7_info
->pagesize
= 256;
517 at91sam7_info
->pages_in_lockregion
= 64;
518 at91sam7_info
->num_pages
= 2*16*64;
519 DEBUG("Support for AT91SAM7X512 is experimental in this version!");
521 if (bank
->size
==0x40000) /* AT91SAM7X256 */
523 at91sam7_info
->target_name
= "AT91SAM7X256";
524 at91sam7_info
->num_lockbits
= 16;
525 at91sam7_info
->pagesize
= 256;
526 at91sam7_info
->pages_in_lockregion
= 64;
527 at91sam7_info
->num_pages
= 16*64;
529 if (bank
->size
==0x20000) /* AT91SAM7X128 */
531 at91sam7_info
->target_name
= "AT91SAM7X128";
532 at91sam7_info
->num_lockbits
= 8;
533 at91sam7_info
->pagesize
= 256;
534 at91sam7_info
->pages_in_lockregion
= 64;
535 at91sam7_info
->num_pages
= 8*64;
541 if (at91sam7_info
->cidr_arch
== 0x60 )
543 at91sam7_info
->num_nvmbits
= 3;
544 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
545 bank
->base
= 0x100000;
548 if (bank
->size
== 0x40000) /* AT91SAM7A3 */
550 at91sam7_info
->target_name
= "AT91SAM7A3";
551 at91sam7_info
->num_lockbits
= 16;
552 at91sam7_info
->pagesize
= 256;
553 at91sam7_info
->pages_in_lockregion
= 16;
554 at91sam7_info
->num_pages
= 16*64;
559 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
564 int at91sam7_erase_check(struct flash_bank_s
*bank
)
566 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
568 if (!at91sam7_info
->working_area_size
)
578 int at91sam7_protect_check(struct flash_bank_s
*bank
)
583 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
585 if (at91sam7_info
->cidr
== 0)
587 at91sam7_read_part_info(bank
);
590 if (at91sam7_info
->cidr
== 0)
592 WARNING("Cannot identify target as an AT91SAM");
593 return ERROR_FLASH_OPERATION_FAILED
;
596 for (flashplane
=0;flashplane
<at91sam7_info
->num_planes
;flashplane
++)
598 status
= at91sam7_get_flash_status(bank
, flashplane
);
599 at91sam7_info
->lockbits
[flashplane
] = (status
>> 16);
605 /* flash_bank at91sam7 0 0 0 0 <target#>
607 int at91sam7_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
609 at91sam7_flash_bank_t
*at91sam7_info
;
614 WARNING("incomplete flash_bank at91sam7 configuration");
615 return ERROR_FLASH_BANK_INVALID
;
618 at91sam7_info
= malloc(sizeof(at91sam7_flash_bank_t
));
619 bank
->driver_priv
= at91sam7_info
;
621 /* part wasn't probed for info yet */
622 at91sam7_info
->cidr
= 0;
624 at91sam7_info
->flashmode
[i
]=0;
629 int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
)
631 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
634 if (bank
->target
->state
!= TARGET_HALTED
)
636 return ERROR_TARGET_NOT_HALTED
;
639 if (at91sam7_info
->cidr
== 0)
641 at91sam7_read_part_info(bank
);
644 if (at91sam7_info
->cidr
== 0)
646 WARNING("Cannot identify target as an AT91SAM");
647 return ERROR_FLASH_OPERATION_FAILED
;
650 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
652 if ((first
== 0) && (last
== (at91sam7_info
->num_lockbits
-1)))
654 WARNING("Sector numbers based on lockbit count, probably a deprecated script");
655 last
= bank
->num_sectors
-1;
657 else return ERROR_FLASH_SECTOR_INVALID
;
660 /* Configure the flash controller timing */
661 at91sam7_read_clock_info(bank
);
662 for (flashplane
= first
; flashplane
<=last
; flashplane
++)
664 /* Configure the flash controller timing */
665 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_FLASH
);
666 if (at91sam7_flash_command(bank
, flashplane
, EA
, 0) != ERROR_OK
)
668 return ERROR_FLASH_OPERATION_FAILED
;
675 int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
677 u32 cmd
, pagen
, status
;
681 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
683 if (bank
->target
->state
!= TARGET_HALTED
)
685 return ERROR_TARGET_NOT_HALTED
;
688 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
690 return ERROR_FLASH_SECTOR_INVALID
;
693 if (at91sam7_info
->cidr
== 0)
695 at91sam7_read_part_info(bank
);
698 if (at91sam7_info
->cidr
== 0)
700 WARNING("Cannot identify target as an AT91SAM");
701 return ERROR_FLASH_OPERATION_FAILED
;
704 at91sam7_read_clock_info(bank
);
706 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
708 pagen
= lockregion
*at91sam7_info
->pages_in_lockregion
;
709 flashplane
= (pagen
>>10)&0x03;
710 /* Configure the flash controller timing */
711 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_NVBITS
);
718 if (at91sam7_flash_command(bank
, flashplane
, cmd
, pagen
) != ERROR_OK
)
720 return ERROR_FLASH_OPERATION_FAILED
;
724 at91sam7_protect_check(bank
);
730 int at91sam7_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
732 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
733 target_t
*target
= bank
->target
;
734 u32 dst_min_alignment
, wcount
, bytes_remaining
= count
;
735 u32 first_page
, last_page
, pagen
, buffer_pos
;
738 if (bank
->target
->state
!= TARGET_HALTED
)
740 return ERROR_TARGET_NOT_HALTED
;
743 if (at91sam7_info
->cidr
== 0)
745 at91sam7_read_part_info(bank
);
748 if (at91sam7_info
->cidr
== 0)
750 WARNING("Cannot identify target as an AT91SAM");
751 return ERROR_FLASH_OPERATION_FAILED
;
754 if (offset
+ count
> bank
->size
)
755 return ERROR_FLASH_DST_OUT_OF_BANK
;
757 dst_min_alignment
= at91sam7_info
->pagesize
;
759 if (offset
% dst_min_alignment
)
761 WARNING("offset 0x%x breaks required alignment 0x%x", offset
, dst_min_alignment
);
762 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
765 if (at91sam7_info
->cidr_arch
== 0)
766 return ERROR_FLASH_BANK_NOT_PROBED
;
768 first_page
= offset
/dst_min_alignment
;
769 last_page
= CEIL(offset
+ count
, dst_min_alignment
);
771 DEBUG("first_page: %i, last_page: %i, count %i", first_page
, last_page
, count
);
773 at91sam7_read_clock_info(bank
);
775 for (pagen
=first_page
; pagen
<last_page
; pagen
++)
777 if (bytes_remaining
<dst_min_alignment
)
778 count
= bytes_remaining
;
780 count
= dst_min_alignment
;
781 bytes_remaining
-= count
;
783 /* Write one block to the PageWriteBuffer */
784 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
785 wcount
= CEIL(count
,4);
786 target
->type
->write_memory(target
, bank
->base
+pagen
*dst_min_alignment
, 4, wcount
, buffer
+buffer_pos
);
787 flashplane
= (pagen
>>10)&0x3;
789 /* Configure the flash controller timing */
790 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_FLASH
);
791 /* Send Write Page command to Flash Controller */
792 if (at91sam7_flash_command(bank
, flashplane
, WP
, pagen
) != ERROR_OK
)
794 return ERROR_FLASH_OPERATION_FAILED
;
796 DEBUG("Write flash plane:%i page number:%i", flashplane
, pagen
);
803 int at91sam7_probe(struct flash_bank_s
*bank
)
805 /* we can't probe on an at91sam7
806 * if this is an at91sam7, it has the configured flash
808 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
810 if (at91sam7_info
->cidr
== 0)
812 at91sam7_read_part_info(bank
);
815 if (at91sam7_info
->cidr
== 0)
817 WARNING("Cannot identify target as an AT91SAM");
818 return ERROR_FLASH_OPERATION_FAILED
;
824 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
826 int printed
, flashplane
;
827 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
829 at91sam7_read_part_info(bank
);
831 if (at91sam7_info
->cidr
== 0)
833 printed
= snprintf(buf
, buf_size
, "Cannot identify target as an AT91SAM\n");
836 return ERROR_FLASH_OPERATION_FAILED
;
839 printed
= snprintf(buf
, buf_size
, "\nat91sam7 information: Chip is %s\n",at91sam7_info
->target_name
);
843 printed
= snprintf(buf
, buf_size
, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n",
844 at91sam7_info
->cidr
, at91sam7_info
->cidr_arch
, EPROC
[at91sam7_info
->cidr_eproc
], at91sam7_info
->cidr_version
, bank
->size
);
848 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz \n", at91sam7_info
->mck_freq
/ 1000);
852 if (at91sam7_info
->num_planes
>1) {
853 printed
= snprintf(buf
, buf_size
, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n",
854 at91sam7_info
->num_planes
, at91sam7_info
->pagesize
, at91sam7_info
->num_lockbits
, at91sam7_info
->num_pages
/at91sam7_info
->num_lockbits
);
857 for (flashplane
=0; flashplane
<at91sam7_info
->num_planes
; flashplane
++)
859 printed
= snprintf(buf
, buf_size
, "lockbits[%i]: 0x%4.4x, ", flashplane
, at91sam7_info
->lockbits
[flashplane
]);
865 if (at91sam7_info
->num_lockbits
>0) {
866 printed
= snprintf(buf
, buf_size
, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n",
867 at91sam7_info
->pagesize
, at91sam7_info
->num_lockbits
, at91sam7_info
->lockbits
[0], at91sam7_info
->num_pages
/at91sam7_info
->num_lockbits
);
872 printed
= snprintf(buf
, buf_size
, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info
->securitybit
, at91sam7_info
->nvmbits
);
880 * On AT91SAM7S: When the gpnmv bits are set with
881 * > at91sam7 gpnvm 0 bitnr set
882 * the changes are not visible in the flash controller status register MC_FSR
883 * until the processor has been reset.
884 * On the Olimex board this requires a power cycle.
885 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
886 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
887 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
889 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
896 at91sam7_flash_bank_t
*at91sam7_info
;
900 command_print(cmd_ctx
, "at91sam7 gpnvm <num> <bit> <set|clear>");
904 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
910 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
914 at91sam7_info
= bank
->driver_priv
;
916 if (bank
->target
->state
!= TARGET_HALTED
)
918 return ERROR_TARGET_NOT_HALTED
;
921 if (at91sam7_info
->cidr
== 0)
923 at91sam7_read_part_info(bank
);
926 if (at91sam7_info
->cidr
== 0)
928 WARNING("Cannot identify target as an AT91SAM");
929 return ERROR_FLASH_OPERATION_FAILED
;
932 if ((bit
<0) || (at91sam7_info
->num_nvmbits
<= bit
))
934 command_print(cmd_ctx
, "gpnvm bit '#%s' is out of bounds for target %s", args
[1],at91sam7_info
->target_name
);
938 if (strcmp(value
, "set") == 0)
942 else if (strcmp(value
, "clear") == 0)
948 command_print(cmd_ctx
, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
952 /* Configure the flash controller timing */
953 at91sam7_read_clock_info(bank
);
954 at91sam7_set_flash_mode(bank
, 0, FMR_TIMING_NVBITS
);
956 if (at91sam7_flash_command(bank
, 0, flashcmd
, (u16
)(bit
)) != ERROR_OK
)
958 return ERROR_FLASH_OPERATION_FAILED
;
961 status
= at91sam7_get_flash_status(bank
, 0);
962 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd
,bit
,status
);
963 at91sam7_info
->nvmbits
= (status
>>8)&((1<<at91sam7_info
->num_nvmbits
)-1);
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)