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
);
65 void at91sam7_set_flash_mode(flash_bank_t
*bank
,int mode
);
66 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
);
67 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 flash_driver_t at91sam7_flash
=
72 .register_commands
= at91sam7_register_commands
,
73 .flash_bank_command
= at91sam7_flash_bank_command
,
74 .erase
= at91sam7_erase
,
75 .protect
= at91sam7_protect
,
76 .write
= at91sam7_write
,
77 .probe
= at91sam7_probe
,
78 .erase_check
= at91sam7_erase_check
,
79 .protect_check
= at91sam7_protect_check
,
84 char * EPROC
[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
100 0x200000, /* 2048K */
123 int at91sam7_register_commands(struct command_context_s
*cmd_ctx
)
125 command_t
*at91sam7_cmd
= register_command(cmd_ctx
, NULL
, "at91sam7", NULL
, COMMAND_ANY
, NULL
);
126 register_command(cmd_ctx
, at91sam7_cmd
, "gpnvm", at91sam7_handle_gpnvm_command
, COMMAND_EXEC
,
127 "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
132 u32
at91sam7_get_flash_status(flash_bank_t
*bank
)
134 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
135 target_t
*target
= at91sam7_info
->target
;
138 target_read_u32(target
, MC_FSR
, &fsr
);
143 /** Read clock configuration and set at91sam7_info->usec_clocks*/
144 void at91sam7_read_clock_info(flash_bank_t
*bank
)
146 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
147 target_t
*target
= at91sam7_info
->target
;
148 u32 mckr
, mcfr
, pllr
;
149 unsigned long tmp
, mainfreq
;
151 /* Read main clock freqency register */
152 target_read_u32(target
, CKGR_MCFR
, &mcfr
);
153 /* Read master clock register */
154 target_read_u32(target
, PMC_MCKR
, &mckr
);
155 /* Read Clock Generator PLL Register */
156 target_read_u32(target
, CKGR_PLLR
, &pllr
);
158 at91sam7_info
->mck_valid
= 0;
159 switch (mckr
& PMC_MCKR_CSS
) {
160 case 0: /* Slow Clock */
161 at91sam7_info
->mck_valid
= 1;
164 case 1: /* Main Clock */
165 if (mcfr
& CKGR_MCFR_MAINRDY
)
167 at91sam7_info
->mck_valid
= 1;
168 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
173 case 2: /* Reserved */
175 case 3: /* PLL Clock */
176 if (mcfr
& CKGR_MCFR_MAINRDY
)
178 target_read_u32(target
, CKGR_PLLR
, &pllr
);
179 if (!(pllr
& CKGR_PLLR_DIV
))
181 at91sam7_info
->mck_valid
= 1;
182 mainfreq
= RC_FREQ
/ 16ul * (mcfr
& 0xffff);
183 /* Integer arithmetic should have sufficient precision
184 as long as PLL is properly configured. */
185 tmp
= mainfreq
/ (pllr
& CKGR_PLLR_DIV
) *
186 (((pllr
& CKGR_PLLR_MUL
) >> 16) + 1);
191 /* Prescaler adjust */
192 if (((mckr
& PMC_MCKR_PRES
) >> 2) == 7)
193 at91sam7_info
->mck_valid
= 0;
195 at91sam7_info
->mck_freq
= tmp
>> ((mckr
& PMC_MCKR_PRES
) >> 2);
197 /* Forget old flash timing */
198 at91sam7_set_flash_mode(bank
,FMR_TIMING_NONE
);
201 /* Setup the timimg registers for nvbits or normal flash */
202 void at91sam7_set_flash_mode(flash_bank_t
*bank
,int mode
)
204 u32 fmr
, fmcn
= 0, fws
= 0;
205 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
206 target_t
*target
= at91sam7_info
->target
;
208 if (mode
&& (mode
!= at91sam7_info
->flashmode
))
210 /* Always round up (ceil) */
211 if (mode
==FMR_TIMING_NVBITS
)
213 if (at91sam7_info
->cidr_arch
== 0x60)
215 /* AT91SAM7A3 uses master clocks in 100 ns */
216 fmcn
= (at91sam7_info
->mck_freq
/10000000ul)+1;
220 /* master clocks in 1uS for ARCH 0x7 types */
221 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+1;
224 else if (mode
==FMR_TIMING_FLASH
)
225 /* main clocks in 1.5uS */
226 fmcn
= (at91sam7_info
->mck_freq
/666666ul)+1;
228 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
229 if (at91sam7_info
->mck_freq
<= 33333ul)
231 /* Only allow fws=0 if clock frequency is < 30 MHz. */
232 if (at91sam7_info
->mck_freq
> 30000000ul)
235 DEBUG("fmcn: %i", fmcn
);
236 fmr
= fmcn
<< 16 | fws
<< 8;
237 target_write_u32(target
, MC_FMR
, fmr
);
240 at91sam7_info
->flashmode
= mode
;
243 u32
at91sam7_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
247 while ((!((status
= at91sam7_get_flash_status(bank
)) & waitbits
)) && (timeout
-- > 0))
249 DEBUG("status: 0x%x", status
);
253 DEBUG("status: 0x%x", status
);
257 ERROR("status register: 0x%x", status
);
259 ERROR("Lock Error Bit Detected, Operation Abort");
261 ERROR("Invalid command and/or bad keyword, Operation Abort");
263 ERROR("Security Bit Set, Operation Abort");
270 /* Send one command to the AT91SAM flash controller */
271 int at91sam7_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
274 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
275 target_t
*target
= at91sam7_info
->target
;
277 fcr
= (0x5A<<24) | (pagen
<<8) | cmd
;
278 target_write_u32(target
, MC_FCR
, fcr
);
279 DEBUG("Flash command: 0x%x, pagenumber:", fcr
, pagen
);
281 if ((at91sam7_info
->cidr_arch
== 0x60)&&((cmd
==SLB
)|(cmd
==CLB
)))
283 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
284 if (at91sam7_wait_status_busy(bank
, MC_FSR_EOL
, 10)&0x0C)
286 return ERROR_FLASH_OPERATION_FAILED
;
291 if (at91sam7_wait_status_busy(bank
, MC_FSR_FRDY
, 10)&0x0C)
293 return ERROR_FLASH_OPERATION_FAILED
;
298 /* Read device id register, main clock frequency register and fill in driver info structure */
299 int at91sam7_read_part_info(struct flash_bank_s
*bank
)
301 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
302 target_t
*target
= at91sam7_info
->target
;
305 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
307 return ERROR_TARGET_NOT_HALTED
;
310 /* Read and parse chip identification register */
311 target_read_u32(target
, DBGU_CIDR
, &cidr
);
315 WARNING("Cannot identify target as an AT91SAM");
316 return ERROR_FLASH_OPERATION_FAILED
;
319 at91sam7_info
->cidr
= cidr
;
320 at91sam7_info
->cidr_ext
= (cidr
>>31)&0x0001;
321 at91sam7_info
->cidr_nvptyp
= (cidr
>>28)&0x0007;
322 at91sam7_info
->cidr_arch
= (cidr
>>20)&0x00FF;
323 at91sam7_info
->cidr_sramsiz
= (cidr
>>16)&0x000F;
324 at91sam7_info
->cidr_nvpsiz2
= (cidr
>>12)&0x000F;
325 at91sam7_info
->cidr_nvpsiz
= (cidr
>>8)&0x000F;
326 at91sam7_info
->cidr_eproc
= (cidr
>>5)&0x0007;
327 at91sam7_info
->cidr_version
= cidr
&0x001F;
328 bank
->size
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
];
329 at91sam7_info
->target_name
= "Unknown";
331 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", at91sam7_info
->cidr_nvptyp
, at91sam7_info
->cidr_arch
);
333 /* Read main and master clock freqency register */
334 at91sam7_read_clock_info(bank
);
336 status
= at91sam7_get_flash_status(bank
);
337 at91sam7_info
->lockbits
= status
>>16;
338 at91sam7_info
->securitybit
= (status
>>4)&0x01;
340 if (at91sam7_info
->cidr_arch
== 0x70 )
342 at91sam7_info
->num_nvmbits
= 2;
343 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
344 bank
->base
= 0x100000;
346 if (bank
->size
==0x40000) /* AT91SAM7S256 */
348 at91sam7_info
->target_name
= "AT91SAM7S256";
349 at91sam7_info
->num_lockbits
= 16;
350 at91sam7_info
->pagesize
= 256;
351 at91sam7_info
->pages_in_lockregion
= 64;
352 at91sam7_info
->num_pages
= 16*64;
354 if (bank
->size
==0x20000) /* AT91SAM7S128 */
356 at91sam7_info
->target_name
= "AT91SAM7S128";
357 at91sam7_info
->num_lockbits
= 8;
358 at91sam7_info
->pagesize
= 256;
359 at91sam7_info
->pages_in_lockregion
= 64;
360 at91sam7_info
->num_pages
= 8*64;
362 if (bank
->size
==0x10000) /* AT91SAM7S64 */
364 at91sam7_info
->target_name
= "AT91SAM7S64";
365 at91sam7_info
->num_lockbits
= 16;
366 at91sam7_info
->pagesize
= 128;
367 at91sam7_info
->pages_in_lockregion
= 32;
368 at91sam7_info
->num_pages
= 16*32;
370 if (bank
->size
==0x08000) /* AT91SAM7S321/32 */
372 at91sam7_info
->target_name
= "AT91SAM7S321/32";
373 at91sam7_info
->num_lockbits
= 8;
374 at91sam7_info
->pagesize
= 128;
375 at91sam7_info
->pages_in_lockregion
= 32;
376 at91sam7_info
->num_pages
= 8*32;
382 if (at91sam7_info
->cidr_arch
== 0x71 )
384 at91sam7_info
->num_nvmbits
= 2;
385 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
386 bank
->base
= 0x100000;
388 if (bank
->size
==0x40000) /* AT91SAM7XC256 */
390 at91sam7_info
->target_name
= "AT91SAM7XC256";
391 at91sam7_info
->num_lockbits
= 16;
392 at91sam7_info
->pagesize
= 256;
393 at91sam7_info
->pages_in_lockregion
= 64;
394 at91sam7_info
->num_pages
= 16*64;
396 if (bank
->size
==0x20000) /* AT91SAM7XC128 */
398 at91sam7_info
->target_name
= "AT91SAM7XC128";
399 at91sam7_info
->num_lockbits
= 8;
400 at91sam7_info
->pagesize
= 256;
401 at91sam7_info
->pages_in_lockregion
= 64;
402 at91sam7_info
->num_pages
= 8*64;
408 if (at91sam7_info
->cidr_arch
== 0x72 )
410 at91sam7_info
->num_nvmbits
= 2;
411 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
412 bank
->base
= 0x100000;
414 if (bank
->size
==0x80000) /* AT91SAM7SE512 */
416 at91sam7_info
->target_name
= "AT91SAM7SE512";
417 at91sam7_info
->num_lockbits
= 32;
418 at91sam7_info
->pagesize
= 256;
419 at91sam7_info
->pages_in_lockregion
= 64;
420 at91sam7_info
->num_pages
= 32*64;
422 if (bank
->size
==0x40000)
424 at91sam7_info
->target_name
= "AT91SAM7SE256";
425 at91sam7_info
->num_lockbits
= 16;
426 at91sam7_info
->pagesize
= 256;
427 at91sam7_info
->pages_in_lockregion
= 64;
428 at91sam7_info
->num_pages
= 16*64;
430 if (bank
->size
==0x08000)
432 at91sam7_info
->target_name
= "AT91SAM7SE32";
433 at91sam7_info
->num_lockbits
= 8;
434 at91sam7_info
->pagesize
= 128;
435 at91sam7_info
->pages_in_lockregion
= 32;
436 at91sam7_info
->num_pages
= 8*32;
442 if (at91sam7_info
->cidr_arch
== 0x75 )
444 at91sam7_info
->num_nvmbits
= 3;
445 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
446 bank
->base
= 0x100000;
448 if (bank
->size
==0x40000) /* AT91SAM7X256 */
450 at91sam7_info
->target_name
= "AT91SAM7X256";
451 at91sam7_info
->num_lockbits
= 16;
452 at91sam7_info
->pagesize
= 256;
453 at91sam7_info
->pages_in_lockregion
= 64;
454 at91sam7_info
->num_pages
= 16*64;
456 if (bank
->size
==0x20000) /* AT91SAM7X128 */
458 at91sam7_info
->target_name
= "AT91SAM7X128";
459 at91sam7_info
->num_lockbits
= 8;
460 at91sam7_info
->pagesize
= 256;
461 at91sam7_info
->pages_in_lockregion
= 64;
462 at91sam7_info
->num_pages
= 8*64;
468 if (at91sam7_info
->cidr_arch
== 0x60 )
470 at91sam7_info
->num_nvmbits
= 3;
471 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
472 bank
->base
= 0x100000;
475 if (bank
->size
== 0x40000) /* AT91SAM7A3 */
477 at91sam7_info
->target_name
= "AT91SAM7A3";
478 at91sam7_info
->num_lockbits
= 16;
479 at91sam7_info
->pagesize
= 256;
480 at91sam7_info
->pages_in_lockregion
= 16;
481 at91sam7_info
->num_pages
= 16*64;
486 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
491 int at91sam7_erase_check(struct flash_bank_s
*bank
)
493 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
494 target_t
*target
= at91sam7_info
->target
;
497 if (!at91sam7_info
->working_area_size
)
507 int at91sam7_protect_check(struct flash_bank_s
*bank
)
511 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
512 target_t
*target
= at91sam7_info
->target
;
514 if (at91sam7_info
->cidr
== 0)
516 at91sam7_read_part_info(bank
);
519 if (at91sam7_info
->cidr
== 0)
521 WARNING("Cannot identify target as an AT91SAM");
522 return ERROR_FLASH_OPERATION_FAILED
;
525 status
= at91sam7_get_flash_status(bank
);
526 at91sam7_info
->lockbits
= status
>> 16;
531 int at91sam7_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
533 at91sam7_flash_bank_t
*at91sam7_info
;
537 WARNING("incomplete flash_bank at91sam7 configuration");
538 return ERROR_FLASH_BANK_INVALID
;
541 at91sam7_info
= malloc(sizeof(at91sam7_flash_bank_t
));
542 bank
->driver_priv
= at91sam7_info
;
544 at91sam7_info
->target
= get_target_by_num(strtoul(args
[5], NULL
, 0));
545 if (!at91sam7_info
->target
)
547 ERROR("no target '%i' configured", args
[5]);
551 /* part wasn't probed for info yet */
552 at91sam7_info
->cidr
= 0;
557 int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
)
559 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
561 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
563 return ERROR_TARGET_NOT_HALTED
;
566 if (at91sam7_info
->cidr
== 0)
568 at91sam7_read_part_info(bank
);
571 if (at91sam7_info
->cidr
== 0)
573 WARNING("Cannot identify target as an AT91SAM");
574 return ERROR_FLASH_OPERATION_FAILED
;
577 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
579 return ERROR_FLASH_SECTOR_INVALID
;
582 /* Configure the flash controller timing */
583 at91sam7_read_clock_info(bank
);
584 at91sam7_set_flash_mode(bank
,FMR_TIMING_FLASH
);
586 if ((first
== 0) && (last
== (at91sam7_info
->num_lockbits
-1)))
588 return at91sam7_flash_command(bank
, EA
, 0);
591 WARNING("Can only erase the whole flash area, pages are autoerased on write");
592 return ERROR_FLASH_OPERATION_FAILED
;
595 int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
597 u32 cmd
, pagen
, status
;
600 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
601 target_t
*target
= at91sam7_info
->target
;
603 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
605 return ERROR_TARGET_NOT_HALTED
;
608 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
610 return ERROR_FLASH_SECTOR_INVALID
;
613 if (at91sam7_info
->cidr
== 0)
615 at91sam7_read_part_info(bank
);
618 if (at91sam7_info
->cidr
== 0)
620 WARNING("Cannot identify target as an AT91SAM");
621 return ERROR_FLASH_OPERATION_FAILED
;
624 /* Configure the flash controller timing */
625 at91sam7_read_clock_info(bank
);
626 at91sam7_set_flash_mode(bank
,FMR_TIMING_NVBITS
);
628 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
630 pagen
= lockregion
*at91sam7_info
->pages_in_lockregion
;
635 if (at91sam7_flash_command(bank
, cmd
, pagen
) != ERROR_OK
)
637 return ERROR_FLASH_OPERATION_FAILED
;
641 status
= at91sam7_get_flash_status(bank
);
642 at91sam7_info
->lockbits
= status
>>16;
648 int at91sam7_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
650 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
651 target_t
*target
= at91sam7_info
->target
;
652 u32 dst_min_alignment
, wcount
, bytes_remaining
= count
;
653 u32 first_page
, last_page
, pagen
, buffer_pos
;
656 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
658 return ERROR_TARGET_NOT_HALTED
;
661 if (at91sam7_info
->cidr
== 0)
663 at91sam7_read_part_info(bank
);
666 if (at91sam7_info
->cidr
== 0)
668 WARNING("Cannot identify target as an AT91SAM");
669 return ERROR_FLASH_OPERATION_FAILED
;
672 if (offset
+ count
> bank
->size
)
673 return ERROR_FLASH_DST_OUT_OF_BANK
;
675 dst_min_alignment
= at91sam7_info
->pagesize
;
677 if (offset
% dst_min_alignment
)
679 WARNING("offset 0x%x breaks required alignment 0x%x", offset
, dst_min_alignment
);
680 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
683 if (offset
+ count
> bank
->size
)
684 return ERROR_FLASH_DST_OUT_OF_BANK
;
686 if (at91sam7_info
->cidr_arch
== 0)
687 return ERROR_FLASH_BANK_NOT_PROBED
;
689 first_page
= offset
/dst_min_alignment
;
690 last_page
= CEIL(offset
+ count
, dst_min_alignment
);
692 DEBUG("first_page: %i, last_page: %i, count %i", first_page
, last_page
, count
);
694 /* Configure the flash controller timing */
695 at91sam7_read_clock_info(bank
);
696 at91sam7_set_flash_mode(bank
,FMR_TIMING_FLASH
);
698 for (pagen
=first_page
; pagen
<last_page
; pagen
++) {
699 if (bytes_remaining
<dst_min_alignment
)
700 count
= bytes_remaining
;
702 count
= dst_min_alignment
;
703 bytes_remaining
-= count
;
705 /* Write one block to the PageWriteBuffer */
706 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
707 wcount
= CEIL(count
,4);
708 target
->type
->write_memory(target
, bank
->base
, 4, wcount
, buffer
+buffer_pos
);
710 /* Send Write Page command to Flash Controller */
711 if (at91sam7_flash_command(bank
, WP
, pagen
) != ERROR_OK
)
713 return ERROR_FLASH_OPERATION_FAILED
;
715 DEBUG("Flash command: 0x%x, pagenumber:", fcr
, pagen
);
722 int at91sam7_probe(struct flash_bank_s
*bank
)
724 /* we can't probe on an at91sam7
725 * if this is an at91sam7, it has the configured flash
727 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
729 if (at91sam7_info
->cidr
== 0)
731 at91sam7_read_part_info(bank
);
734 if (at91sam7_info
->cidr
== 0)
736 WARNING("Cannot identify target as an AT91SAM");
737 return ERROR_FLASH_OPERATION_FAILED
;
743 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
746 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
748 at91sam7_read_part_info(bank
);
750 if (at91sam7_info
->cidr
== 0)
752 printed
= snprintf(buf
, buf_size
, "Cannot identify target as an AT91SAM\n");
755 return ERROR_FLASH_OPERATION_FAILED
;
758 printed
= snprintf(buf
, buf_size
, "\nat91sam7 information: Chip is %s\n",at91sam7_info
->target_name
);
762 printed
= snprintf(buf
, buf_size
, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n", at91sam7_info
->cidr
, at91sam7_info
->cidr_arch
, EPROC
[at91sam7_info
->cidr_eproc
], at91sam7_info
->cidr_version
, bank
->size
);
766 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz \n", at91sam7_info
->mck_freq
/ 1000);
770 if (at91sam7_info
->num_lockbits
>0) {
771 printed
= snprintf(buf
, buf_size
, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", at91sam7_info
->pagesize
, at91sam7_info
->num_lockbits
, at91sam7_info
->lockbits
,at91sam7_info
->num_pages
/at91sam7_info
->num_lockbits
);
776 printed
= snprintf(buf
, buf_size
, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info
->securitybit
, at91sam7_info
->nvmbits
);
784 * On AT91SAM7S: When the gpnmv bits are set with
785 * > at91sam7 gpnvm 0 bitnr set
786 * the changes are not visible in the flash controller status register MC_FSR
787 * until the processor has been reset.
788 * On the Olimex board this requires a power cycle.
789 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
790 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
791 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
793 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
800 at91sam7_flash_bank_t
*at91sam7_info
;
804 command_print(cmd_ctx
, "at91sam7 gpnvm <num> <bit> <set|clear>");
808 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
814 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
818 at91sam7_info
= bank
->driver_priv
;
820 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
822 return ERROR_TARGET_NOT_HALTED
;
825 if (at91sam7_info
->cidr
== 0)
827 at91sam7_read_part_info(bank
);
830 if (at91sam7_info
->cidr
== 0)
832 WARNING("Cannot identify target as an AT91SAM");
833 return ERROR_FLASH_OPERATION_FAILED
;
836 if ((bit
<0) || (at91sam7_info
->num_nvmbits
<= bit
))
838 command_print(cmd_ctx
, "gpnvm bit '#%s' is out of bounds for target %s", args
[1],at91sam7_info
->target_name
);
842 if (strcmp(value
, "set") == 0)
846 else if (strcmp(value
, "clear") == 0)
852 command_print(cmd_ctx
, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
856 /* Configure the flash controller timing */
857 at91sam7_read_clock_info(bank
);
858 at91sam7_set_flash_mode(bank
,FMR_TIMING_NVBITS
);
860 if (at91sam7_flash_command(bank
, flashcmd
, (u16
)(bit
)) != ERROR_OK
)
862 return ERROR_FLASH_OPERATION_FAILED
;
865 status
= at91sam7_get_flash_status(bank
);
866 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd
,bit
,status
);
867 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)