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_auto_probe(struct flash_bank_s
*bank
);
61 int at91sam7_erase_check(struct flash_bank_s
*bank
);
62 int at91sam7_protect_check(struct flash_bank_s
*bank
);
63 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
65 u32
at91sam7_get_flash_status(flash_bank_t
*bank
, u8 flashplane
);
66 void at91sam7_set_flash_mode(flash_bank_t
*bank
, u8 flashplane
, int mode
);
67 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u8 flashplane
, u32 waitbits
, int timeout
);
68 int at91sam7_flash_command(struct flash_bank_s
*bank
, u8 flashplane
, u8 cmd
, u16 pagen
);
69 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
71 flash_driver_t at91sam7_flash
=
74 .register_commands
= at91sam7_register_commands
,
75 .flash_bank_command
= at91sam7_flash_bank_command
,
76 .erase
= at91sam7_erase
,
77 .protect
= at91sam7_protect
,
78 .write
= at91sam7_write
,
79 .probe
= at91sam7_probe
,
80 .auto_probe
= at91sam7_auto_probe
,
81 .erase_check
= at91sam7_erase_check
,
82 .protect_check
= at91sam7_protect_check
,
86 u32 MC_FMR
[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
87 u32 MC_FCR
[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
88 u32 MC_FSR
[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
90 char * EPROC
[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
104 0x100000, /* 1024K */
106 0x200000, /* 2048K */
129 int at91sam7_register_commands(struct command_context_s
*cmd_ctx
)
131 command_t
*at91sam7_cmd
= register_command(cmd_ctx
, NULL
, "at91sam7", NULL
, COMMAND_ANY
, NULL
);
132 register_command(cmd_ctx
, at91sam7_cmd
, "gpnvm", at91sam7_handle_gpnvm_command
, COMMAND_EXEC
,
133 "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
138 u32
at91sam7_get_flash_status(flash_bank_t
*bank
, u8 flashplane
)
140 target_t
*target
= bank
->target
;
143 target_read_u32(target
, MC_FSR
[flashplane
], &fsr
);
148 /** Read clock configuration and set at91sam7_info->usec_clocks*/
149 void at91sam7_read_clock_info(flash_bank_t
*bank
)
151 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
152 target_t
*target
= bank
->target
;
153 u32 mckr
, mcfr
, pllr
;
154 unsigned long tmp
= 0, mainfreq
;
157 /* Read main clock freqency register */
158 target_read_u32(target
, CKGR_MCFR
, &mcfr
);
159 /* Read master clock register */
160 target_read_u32(target
, PMC_MCKR
, &mckr
);
161 /* Read Clock Generator PLL Register */
162 target_read_u32(target
, CKGR_PLLR
, &pllr
);
164 at91sam7_info
->mck_valid
= 0;
165 switch (mckr
& PMC_MCKR_CSS
)
167 case 0: /* Slow Clock */
168 at91sam7_info
->mck_valid
= 1;
169 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
172 case 1: /* Main Clock */
173 if (mcfr
& CKGR_MCFR_MAINRDY
)
175 at91sam7_info
->mck_valid
= 1;
176 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
181 case 2: /* Reserved */
183 case 3: /* PLL Clock */
184 if (mcfr
& CKGR_MCFR_MAINRDY
)
186 target_read_u32(target
, CKGR_PLLR
, &pllr
);
187 if (!(pllr
& CKGR_PLLR_DIV
))
189 at91sam7_info
->mck_valid
= 1;
190 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
191 /* Integer arithmetic should have sufficient precision
192 as long as PLL is properly configured. */
193 tmp
= mainfreq
/ (pllr
& CKGR_PLLR_DIV
) *
194 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
199 /* Prescaler adjust */
200 if (((mckr
& PMC_MCKR_PRES
) >> 2) == 7)
201 at91sam7_info
->mck_valid
= 0;
203 at91sam7_info
->mck_freq
= tmp
>> ((mckr
& PMC_MCKR_PRES
) >> 2);
205 /* Forget old flash timing */
206 for (flashplane
= 0; flashplane
<at91sam7_info
->num_planes
; flashplane
++)
208 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_NONE
);
212 /* Setup the timimg registers for nvbits or normal flash */
213 void at91sam7_set_flash_mode(flash_bank_t
*bank
, u8 flashplane
, int mode
)
215 u32 fmr
, fmcn
= 0, fws
= 0;
216 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
217 target_t
*target
= bank
->target
;
219 if (mode
&& (mode
!= at91sam7_info
->flashmode
[flashplane
]))
221 /* Always round up (ceil) */
222 if (mode
==FMR_TIMING_NVBITS
)
224 if (at91sam7_info
->cidr_arch
== 0x60)
226 /* AT91SAM7A3 uses master clocks in 100 ns */
227 fmcn
= (at91sam7_info
->mck_freq
/10000000ul)+1;
231 /* master clocks in 1uS for ARCH 0x7 types */
232 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+1;
235 else if (mode
==FMR_TIMING_FLASH
)
236 /* main clocks in 1.5uS */
237 fmcn
= (at91sam7_info
->mck_freq
/666666ul)+1;
239 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
240 if (at91sam7_info
->mck_freq
<= 33333ul)
242 /* Only allow fws=0 if clock frequency is < 30 MHz. */
243 if (at91sam7_info
->mck_freq
> 30000000ul)
246 DEBUG("fmcn[%i]: %i", flashplane
, fmcn
);
247 fmr
= fmcn
<< 16 | fws
<< 8;
248 target_write_u32(target
, MC_FMR
[flashplane
], fmr
);
251 at91sam7_info
->flashmode
[flashplane
] = mode
;
254 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u8 flashplane
, u32 waitbits
, int timeout
)
258 while ((!((status
= at91sam7_get_flash_status(bank
,flashplane
)) & waitbits
)) && (timeout
-- > 0))
260 DEBUG("status[%i]: 0x%x", flashplane
, status
);
264 DEBUG("status[%i]: 0x%x", flashplane
, status
);
268 ERROR("status register: 0x%x", status
);
270 ERROR("Lock Error Bit Detected, Operation Abort");
272 ERROR("Invalid command and/or bad keyword, Operation Abort");
274 ERROR("Security Bit Set, Operation Abort");
281 /* Send one command to the AT91SAM flash controller */
282 int at91sam7_flash_command(struct flash_bank_s
*bank
, u8 flashplane
, u8 cmd
, u16 pagen
)
285 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
286 target_t
*target
= bank
->target
;
288 fcr
= (0x5A<<24) | ((pagen
&0x3FF)<<8) | cmd
;
289 target_write_u32(target
, MC_FCR
[flashplane
], fcr
);
290 DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr
, flashplane
, pagen
);
292 if ((at91sam7_info
->cidr_arch
== 0x60)&&((cmd
==SLB
)|(cmd
==CLB
)))
294 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
295 if (at91sam7_wait_status_busy(bank
, flashplane
, MC_FSR_EOL
, 10)&0x0C)
297 return ERROR_FLASH_OPERATION_FAILED
;
302 if (at91sam7_wait_status_busy(bank
, flashplane
, MC_FSR_FRDY
, 10)&0x0C)
304 return ERROR_FLASH_OPERATION_FAILED
;
309 /* Read device id register, main clock frequency register and fill in driver info structure */
310 int at91sam7_read_part_info(struct flash_bank_s
*bank
)
312 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
313 target_t
*target
= bank
->target
;
317 /* Read and parse chip identification register */
318 target_read_u32(target
, DBGU_CIDR
, &cidr
);
322 WARNING("Cannot identify target as an AT91SAM");
323 return ERROR_FLASH_OPERATION_FAILED
;
326 at91sam7_info
->cidr
= cidr
;
327 at91sam7_info
->cidr_ext
= (cidr
>>31)&0x0001;
328 at91sam7_info
->cidr_nvptyp
= (cidr
>>28)&0x0007;
329 at91sam7_info
->cidr_arch
= (cidr
>>20)&0x00FF;
330 at91sam7_info
->cidr_sramsiz
= (cidr
>>16)&0x000F;
331 at91sam7_info
->cidr_nvpsiz2
= (cidr
>>12)&0x000F;
332 at91sam7_info
->cidr_nvpsiz
= (cidr
>>8)&0x000F;
333 at91sam7_info
->cidr_eproc
= (cidr
>>5)&0x0007;
334 at91sam7_info
->cidr_version
= cidr
&0x001F;
335 bank
->size
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
];
336 at91sam7_info
->target_name
= "Unknown";
338 /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
339 if (NVPSIZ
[at91sam7_info
->cidr_nvpsiz
]<0x80000) /* Flash size less than 512K, one flash plane */
341 bank
->num_sectors
= 1;
342 bank
->sectors
= malloc(sizeof(flash_sector_t
));
343 bank
->sectors
[0].offset
= 0;
344 bank
->sectors
[0].size
= bank
->size
;
345 bank
->sectors
[0].is_erased
= -1;
346 bank
->sectors
[0].is_protected
= -1;
348 else /* Flash size 512K or larger, several flash planes */
350 bank
->num_sectors
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
]/0x40000;
351 bank
->sectors
= malloc(bank
->num_sectors
*sizeof(flash_sector_t
));
352 for (sectornum
=0; sectornum
<bank
->num_sectors
; sectornum
++)
354 bank
->sectors
[sectornum
].offset
= sectornum
*0x40000;
355 bank
->sectors
[sectornum
].size
= 0x40000;
356 bank
->sectors
[sectornum
].is_erased
= -1;
357 bank
->sectors
[sectornum
].is_protected
= -1;
363 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info
->cidr_nvptyp
, at91sam7_info
->cidr_arch
);
365 /* Read main and master clock freqency register */
366 at91sam7_read_clock_info(bank
);
368 at91sam7_info
->num_planes
= 1;
369 status
= at91sam7_get_flash_status(bank
, 0);
370 at91sam7_info
->securitybit
= (status
>>4)&0x01;
371 at91sam7_protect_check(bank
); /* TODO Check the protect check */
373 if (at91sam7_info
->cidr_arch
== 0x70 )
375 at91sam7_info
->num_nvmbits
= 2;
376 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
377 bank
->base
= 0x100000;
379 if (bank
->size
==0x80000) /* AT91SAM7S512 */
381 at91sam7_info
->target_name
= "AT91SAM7S512";
382 at91sam7_info
->num_planes
= 2;
383 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
384 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
385 at91sam7_info
->num_lockbits
= 2*16;
386 at91sam7_info
->pagesize
= 256;
387 at91sam7_info
->pages_in_lockregion
= 64;
388 at91sam7_info
->num_pages
= 2*16*64;
390 if (bank
->size
==0x40000) /* AT91SAM7S256 */
392 at91sam7_info
->target_name
= "AT91SAM7S256";
393 at91sam7_info
->num_lockbits
= 16;
394 at91sam7_info
->pagesize
= 256;
395 at91sam7_info
->pages_in_lockregion
= 64;
396 at91sam7_info
->num_pages
= 16*64;
398 if (bank
->size
==0x20000) /* AT91SAM7S128 */
400 at91sam7_info
->target_name
= "AT91SAM7S128";
401 at91sam7_info
->num_lockbits
= 8;
402 at91sam7_info
->pagesize
= 256;
403 at91sam7_info
->pages_in_lockregion
= 64;
404 at91sam7_info
->num_pages
= 8*64;
406 if (bank
->size
==0x10000) /* AT91SAM7S64 */
408 at91sam7_info
->target_name
= "AT91SAM7S64";
409 at91sam7_info
->num_lockbits
= 16;
410 at91sam7_info
->pagesize
= 128;
411 at91sam7_info
->pages_in_lockregion
= 32;
412 at91sam7_info
->num_pages
= 16*32;
414 if (bank
->size
==0x08000) /* AT91SAM7S321/32 */
416 at91sam7_info
->target_name
= "AT91SAM7S321/32";
417 at91sam7_info
->num_lockbits
= 8;
418 at91sam7_info
->pagesize
= 128;
419 at91sam7_info
->pages_in_lockregion
= 32;
420 at91sam7_info
->num_pages
= 8*32;
426 if (at91sam7_info
->cidr_arch
== 0x71 )
428 at91sam7_info
->num_nvmbits
= 3;
429 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
430 bank
->base
= 0x100000;
432 if (bank
->size
==0x80000) /* AT91SAM7XC512 */
434 at91sam7_info
->target_name
= "AT91SAM7XC512";
435 at91sam7_info
->num_planes
= 2;
436 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
437 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
438 at91sam7_info
->num_lockbits
= 2*16;
439 at91sam7_info
->pagesize
= 256;
440 at91sam7_info
->pages_in_lockregion
= 64;
441 at91sam7_info
->num_pages
= 2*16*64;
443 if (bank
->size
==0x40000) /* AT91SAM7XC256 */
445 at91sam7_info
->target_name
= "AT91SAM7XC256";
446 at91sam7_info
->num_lockbits
= 16;
447 at91sam7_info
->pagesize
= 256;
448 at91sam7_info
->pages_in_lockregion
= 64;
449 at91sam7_info
->num_pages
= 16*64;
451 if (bank
->size
==0x20000) /* AT91SAM7XC128 */
453 at91sam7_info
->target_name
= "AT91SAM7XC128";
454 at91sam7_info
->num_lockbits
= 8;
455 at91sam7_info
->pagesize
= 256;
456 at91sam7_info
->pages_in_lockregion
= 64;
457 at91sam7_info
->num_pages
= 8*64;
463 if (at91sam7_info
->cidr_arch
== 0x72 )
465 at91sam7_info
->num_nvmbits
= 3;
466 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
467 bank
->base
= 0x100000;
469 if (bank
->size
==0x80000) /* AT91SAM7SE512 */
471 at91sam7_info
->target_name
= "AT91SAM7SE512";
472 at91sam7_info
->num_planes
= 2;
473 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
474 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
475 at91sam7_info
->num_lockbits
= 32;
476 at91sam7_info
->pagesize
= 256;
477 at91sam7_info
->pages_in_lockregion
= 64;
478 at91sam7_info
->num_pages
= 32*64;
480 if (bank
->size
==0x40000)
482 at91sam7_info
->target_name
= "AT91SAM7SE256";
483 at91sam7_info
->num_lockbits
= 16;
484 at91sam7_info
->pagesize
= 256;
485 at91sam7_info
->pages_in_lockregion
= 64;
486 at91sam7_info
->num_pages
= 16*64;
488 if (bank
->size
==0x08000)
490 at91sam7_info
->target_name
= "AT91SAM7SE32";
491 at91sam7_info
->num_lockbits
= 8;
492 at91sam7_info
->pagesize
= 128;
493 at91sam7_info
->pages_in_lockregion
= 32;
494 at91sam7_info
->num_pages
= 8*32;
500 if (at91sam7_info
->cidr_arch
== 0x75 )
502 at91sam7_info
->num_nvmbits
= 3;
503 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
504 bank
->base
= 0x100000;
506 if (bank
->size
==0x80000) /* AT91SAM7X512 */
508 at91sam7_info
->target_name
= "AT91SAM7X512";
509 at91sam7_info
->num_planes
= 2;
510 if (at91sam7_info
->num_planes
!= bank
->num_sectors
)
511 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
512 at91sam7_info
->num_lockbits
= 32;
513 at91sam7_info
->pagesize
= 256;
514 at91sam7_info
->pages_in_lockregion
= 64;
515 at91sam7_info
->num_pages
= 2*16*64;
516 DEBUG("Support for AT91SAM7X512 is experimental in this version!");
518 if (bank
->size
==0x40000) /* AT91SAM7X256 */
520 at91sam7_info
->target_name
= "AT91SAM7X256";
521 at91sam7_info
->num_lockbits
= 16;
522 at91sam7_info
->pagesize
= 256;
523 at91sam7_info
->pages_in_lockregion
= 64;
524 at91sam7_info
->num_pages
= 16*64;
526 if (bank
->size
==0x20000) /* AT91SAM7X128 */
528 at91sam7_info
->target_name
= "AT91SAM7X128";
529 at91sam7_info
->num_lockbits
= 8;
530 at91sam7_info
->pagesize
= 256;
531 at91sam7_info
->pages_in_lockregion
= 64;
532 at91sam7_info
->num_pages
= 8*64;
538 if (at91sam7_info
->cidr_arch
== 0x60 )
540 at91sam7_info
->num_nvmbits
= 3;
541 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
542 bank
->base
= 0x100000;
545 if (bank
->size
== 0x40000) /* AT91SAM7A3 */
547 at91sam7_info
->target_name
= "AT91SAM7A3";
548 at91sam7_info
->num_lockbits
= 16;
549 at91sam7_info
->pagesize
= 256;
550 at91sam7_info
->pages_in_lockregion
= 16;
551 at91sam7_info
->num_pages
= 16*64;
556 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
561 int at91sam7_erase_check(struct flash_bank_s
*bank
)
563 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
565 if (!at91sam7_info
->working_area_size
)
575 int at91sam7_protect_check(struct flash_bank_s
*bank
)
580 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
582 if (bank
->target
->state
!= TARGET_HALTED
)
584 return ERROR_TARGET_NOT_HALTED
;
587 if (at91sam7_info
->cidr
== 0)
589 at91sam7_read_part_info(bank
);
592 if (at91sam7_info
->cidr
== 0)
594 WARNING("Cannot identify target as an AT91SAM");
595 return ERROR_FLASH_OPERATION_FAILED
;
598 for (flashplane
=0;flashplane
<at91sam7_info
->num_planes
;flashplane
++)
600 status
= at91sam7_get_flash_status(bank
, flashplane
);
601 at91sam7_info
->lockbits
[flashplane
] = (status
>> 16);
607 /* flash_bank at91sam7 0 0 0 0 <target#>
609 int at91sam7_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
611 at91sam7_flash_bank_t
*at91sam7_info
;
616 WARNING("incomplete flash_bank at91sam7 configuration");
617 return ERROR_FLASH_BANK_INVALID
;
620 at91sam7_info
= malloc(sizeof(at91sam7_flash_bank_t
));
621 bank
->driver_priv
= at91sam7_info
;
622 at91sam7_info
->probed
= 0;
624 /* part wasn't probed for info yet */
625 at91sam7_info
->cidr
= 0;
627 at91sam7_info
->flashmode
[i
]=0;
632 int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
)
634 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
637 if (bank
->target
->state
!= TARGET_HALTED
)
639 return ERROR_TARGET_NOT_HALTED
;
642 if (at91sam7_info
->cidr
== 0)
644 at91sam7_read_part_info(bank
);
647 if (at91sam7_info
->cidr
== 0)
649 WARNING("Cannot identify target as an AT91SAM");
650 return ERROR_FLASH_OPERATION_FAILED
;
653 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
655 if ((first
== 0) && (last
== (at91sam7_info
->num_lockbits
-1)))
657 WARNING("Sector numbers based on lockbit count, probably a deprecated script");
658 last
= bank
->num_sectors
-1;
660 else return ERROR_FLASH_SECTOR_INVALID
;
663 /* Configure the flash controller timing */
664 at91sam7_read_clock_info(bank
);
665 for (flashplane
= first
; flashplane
<=last
; flashplane
++)
667 /* Configure the flash controller timing */
668 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_FLASH
);
669 if (at91sam7_flash_command(bank
, flashplane
, EA
, 0) != ERROR_OK
)
671 return ERROR_FLASH_OPERATION_FAILED
;
678 int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
684 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
686 if (bank
->target
->state
!= TARGET_HALTED
)
688 return ERROR_TARGET_NOT_HALTED
;
691 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
693 return ERROR_FLASH_SECTOR_INVALID
;
696 if (at91sam7_info
->cidr
== 0)
698 at91sam7_read_part_info(bank
);
701 if (at91sam7_info
->cidr
== 0)
703 WARNING("Cannot identify target as an AT91SAM");
704 return ERROR_FLASH_OPERATION_FAILED
;
707 at91sam7_read_clock_info(bank
);
709 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
711 pagen
= lockregion
*at91sam7_info
->pages_in_lockregion
;
712 flashplane
= (pagen
>>10)&0x03;
713 /* Configure the flash controller timing */
714 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_NVBITS
);
721 if (at91sam7_flash_command(bank
, flashplane
, cmd
, pagen
) != ERROR_OK
)
723 return ERROR_FLASH_OPERATION_FAILED
;
727 at91sam7_protect_check(bank
);
733 int at91sam7_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
735 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
736 target_t
*target
= bank
->target
;
737 u32 dst_min_alignment
, wcount
, bytes_remaining
= count
;
738 u32 first_page
, last_page
, pagen
, buffer_pos
;
741 if (bank
->target
->state
!= TARGET_HALTED
)
743 return ERROR_TARGET_NOT_HALTED
;
746 if (at91sam7_info
->cidr
== 0)
748 at91sam7_read_part_info(bank
);
751 if (at91sam7_info
->cidr
== 0)
753 WARNING("Cannot identify target as an AT91SAM");
754 return ERROR_FLASH_OPERATION_FAILED
;
757 if (offset
+ count
> bank
->size
)
758 return ERROR_FLASH_DST_OUT_OF_BANK
;
760 dst_min_alignment
= at91sam7_info
->pagesize
;
762 if (offset
% dst_min_alignment
)
764 WARNING("offset 0x%x breaks required alignment 0x%x", offset
, dst_min_alignment
);
765 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
768 if (at91sam7_info
->cidr_arch
== 0)
769 return ERROR_FLASH_BANK_NOT_PROBED
;
771 first_page
= offset
/dst_min_alignment
;
772 last_page
= CEIL(offset
+ count
, dst_min_alignment
);
774 DEBUG("first_page: %i, last_page: %i, count %i", first_page
, last_page
, count
);
776 at91sam7_read_clock_info(bank
);
778 for (pagen
=first_page
; pagen
<last_page
; pagen
++)
780 if (bytes_remaining
<dst_min_alignment
)
781 count
= bytes_remaining
;
783 count
= dst_min_alignment
;
784 bytes_remaining
-= count
;
786 /* Write one block to the PageWriteBuffer */
787 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
788 wcount
= CEIL(count
,4);
789 target
->type
->write_memory(target
, bank
->base
+pagen
*dst_min_alignment
, 4, wcount
, buffer
+buffer_pos
);
790 flashplane
= (pagen
>>10)&0x3;
792 /* Configure the flash controller timing */
793 at91sam7_set_flash_mode(bank
, flashplane
, FMR_TIMING_FLASH
);
794 /* Send Write Page command to Flash Controller */
795 if (at91sam7_flash_command(bank
, flashplane
, WP
, pagen
) != ERROR_OK
)
797 return ERROR_FLASH_OPERATION_FAILED
;
799 DEBUG("Write flash plane:%i page number:%i", flashplane
, pagen
);
806 int at91sam7_probe(struct flash_bank_s
*bank
)
808 /* we can't probe on an at91sam7
809 * if this is an at91sam7, it has the configured flash
811 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
812 at91sam7_info
->probed
= 0;
814 if (bank
->target
->state
!= TARGET_HALTED
)
816 return ERROR_TARGET_NOT_HALTED
;
819 if (at91sam7_info
->cidr
== 0)
821 at91sam7_read_part_info(bank
);
824 if (at91sam7_info
->cidr
== 0)
826 WARNING("Cannot identify target as an AT91SAM");
827 return ERROR_FLASH_OPERATION_FAILED
;
830 at91sam7_info
->probed
= 1;
836 int at91sam7_auto_probe(struct flash_bank_s
*bank
)
838 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
839 if (at91sam7_info
->probed
)
841 return at91sam7_probe(bank
);
844 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
846 int printed
, flashplane
;
847 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
849 if (bank
->target
->state
!= TARGET_HALTED
)
851 return ERROR_TARGET_NOT_HALTED
;
854 at91sam7_read_part_info(bank
);
856 if (at91sam7_info
->cidr
== 0)
858 printed
= snprintf(buf
, buf_size
, "Cannot identify target as an AT91SAM\n");
861 return ERROR_FLASH_OPERATION_FAILED
;
864 printed
= snprintf(buf
, buf_size
, "\nat91sam7 information: Chip is %s\n",at91sam7_info
->target_name
);
868 printed
= snprintf(buf
, buf_size
, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n",
869 at91sam7_info
->cidr
, at91sam7_info
->cidr_arch
, EPROC
[at91sam7_info
->cidr_eproc
], at91sam7_info
->cidr_version
, bank
->size
);
873 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz \n", at91sam7_info
->mck_freq
/ 1000);
877 if (at91sam7_info
->num_planes
>1) {
878 printed
= snprintf(buf
, buf_size
, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n",
879 at91sam7_info
->num_planes
, at91sam7_info
->pagesize
, at91sam7_info
->num_lockbits
, at91sam7_info
->num_pages
/at91sam7_info
->num_lockbits
);
882 for (flashplane
=0; flashplane
<at91sam7_info
->num_planes
; flashplane
++)
884 printed
= snprintf(buf
, buf_size
, "lockbits[%i]: 0x%4.4x, ", flashplane
, at91sam7_info
->lockbits
[flashplane
]);
890 if (at91sam7_info
->num_lockbits
>0) {
891 printed
= snprintf(buf
, buf_size
, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n",
892 at91sam7_info
->pagesize
, at91sam7_info
->num_lockbits
, at91sam7_info
->lockbits
[0], at91sam7_info
->num_pages
/at91sam7_info
->num_lockbits
);
897 printed
= snprintf(buf
, buf_size
, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info
->securitybit
, at91sam7_info
->nvmbits
);
905 * On AT91SAM7S: When the gpnvm bits are set with
906 * > at91sam7 gpnvm 0 bitnr set
907 * the changes are not visible in the flash controller status register MC_FSR
908 * until the processor has been reset.
909 * On the Olimex board this requires a power cycle.
910 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
911 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
912 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
914 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
921 at91sam7_flash_bank_t
*at91sam7_info
;
925 command_print(cmd_ctx
, "at91sam7 gpnvm <num> <bit> <set|clear>");
929 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
935 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
939 at91sam7_info
= bank
->driver_priv
;
941 if (bank
->target
->state
!= TARGET_HALTED
)
943 return ERROR_TARGET_NOT_HALTED
;
946 if (at91sam7_info
->cidr
== 0)
948 at91sam7_read_part_info(bank
);
951 if (at91sam7_info
->cidr
== 0)
953 WARNING("Cannot identify target as an AT91SAM");
954 return ERROR_FLASH_OPERATION_FAILED
;
957 if ((bit
<0) || (at91sam7_info
->num_nvmbits
<= bit
))
959 command_print(cmd_ctx
, "gpnvm bit '#%s' is out of bounds for target %s", args
[1],at91sam7_info
->target_name
);
963 if (strcmp(value
, "set") == 0)
967 else if (strcmp(value
, "clear") == 0)
973 return ERROR_COMMAND_SYNTAX_ERROR
;
976 /* Configure the flash controller timing */
977 at91sam7_read_clock_info(bank
);
978 at91sam7_set_flash_mode(bank
, 0, FMR_TIMING_NVBITS
);
980 if (at91sam7_flash_command(bank
, 0, flashcmd
, (u16
)(bit
)) != ERROR_OK
)
982 return ERROR_FLASH_OPERATION_FAILED
;
985 status
= at91sam7_get_flash_status(bank
, 0);
986 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd
,bit
,status
);
987 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)