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 u8
at91sam7_wait_status_busy(flash_bank_t
*bank
, 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
,0);
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) */
212 /* main clocks in 1uS */
213 fmcn
= (at91sam7_info
->mck_freq
/1000000ul)+1;
215 /* main clocks in 1.5uS */
216 fmcn
= (at91sam7_info
->mck_freq
/666666ul)+1;
218 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
219 if (at91sam7_info
->mck_freq
<= 33333ul)
221 /* Only allow fws=0 if clock frequency is < 30 MHz. */
222 if (at91sam7_info
->mck_freq
> 30000000ul)
225 DEBUG("fmcn: %i", fmcn
);
226 fmr
= fmcn
<< 16 | fws
<< 8;
227 target_write_u32(target
, MC_FMR
, fmr
);
230 at91sam7_info
->flashmode
= mode
;
233 u8
at91sam7_wait_status_busy(flash_bank_t
*bank
, int timeout
)
237 while ((!((status
= at91sam7_get_flash_status(bank
)) & 0x01)) && (timeout
-- > 0))
239 DEBUG("status: 0x%x", status
);
243 DEBUG("status: 0x%x", status
);
247 ERROR("status register: 0x%x", status
);
249 ERROR("Lock Error Bit Detected, Operation Abort");
251 ERROR("Invalid command and/or bad keyword, Operation Abort");
253 ERROR("Security Bit Set, Operation Abort");
259 /* Send one command to the AT91SAM flash controller */
260 int at91sam7_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
263 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
264 target_t
*target
= at91sam7_info
->target
;
266 fcr
= (0x5A<<24) | (pagen
<<8) | cmd
;
267 target_write_u32(target
, MC_FCR
, fcr
);
268 DEBUG("Flash command: 0x%x, pagenumber:", fcr
, pagen
);
270 if (at91sam7_wait_status_busy(bank
, 10)&0x0C)
272 return ERROR_FLASH_OPERATION_FAILED
;
277 /* Read device id register, main clock frequency register and fill in driver info structure */
278 int at91sam7_read_part_info(struct flash_bank_s
*bank
)
280 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
281 target_t
*target
= at91sam7_info
->target
;
284 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
286 return ERROR_TARGET_NOT_HALTED
;
289 /* Read and parse chip identification register */
290 target_read_u32(target
, DBGU_CIDR
, &cidr
);
294 WARNING("Cannot identify target as an AT91SAM");
295 return ERROR_FLASH_OPERATION_FAILED
;
298 at91sam7_info
->cidr
= cidr
;
299 at91sam7_info
->cidr_ext
= (cidr
>>31)&0x0001;
300 at91sam7_info
->cidr_nvptyp
= (cidr
>>28)&0x0007;
301 at91sam7_info
->cidr_arch
= (cidr
>>20)&0x00FF;
302 at91sam7_info
->cidr_sramsiz
= (cidr
>>16)&0x000F;
303 at91sam7_info
->cidr_nvpsiz2
= (cidr
>>12)&0x000F;
304 at91sam7_info
->cidr_nvpsiz
= (cidr
>>8)&0x000F;
305 at91sam7_info
->cidr_eproc
= (cidr
>>5)&0x0007;
306 at91sam7_info
->cidr_version
= cidr
&0x001F;
307 bank
->size
= NVPSIZ
[at91sam7_info
->cidr_nvpsiz
];
308 at91sam7_info
->target_name
= "Unknown";
310 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
);
312 /* Read main and master clock freqency register */
313 at91sam7_read_clock_info(bank
);
315 status
= at91sam7_get_flash_status(bank
);
316 at91sam7_info
->lockbits
= status
>>16;
317 at91sam7_info
->securitybit
= (status
>>4)&0x01;
319 if (at91sam7_info
->cidr_arch
== 0x70 )
321 at91sam7_info
->num_nvmbits
= 2;
322 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
323 bank
->base
= 0x100000;
325 if (bank
->size
==0x40000) /* AT91SAM7S256 */
327 at91sam7_info
->target_name
= "AT91SAM7S256";
328 at91sam7_info
->num_lockbits
= 16;
329 at91sam7_info
->pagesize
= 256;
330 at91sam7_info
->pages_in_lockregion
= 64;
331 at91sam7_info
->num_pages
= 16*64;
333 if (bank
->size
==0x20000) /* AT91SAM7S128 */
335 at91sam7_info
->target_name
= "AT91SAM7S128";
336 at91sam7_info
->num_lockbits
= 8;
337 at91sam7_info
->pagesize
= 256;
338 at91sam7_info
->pages_in_lockregion
= 64;
339 at91sam7_info
->num_pages
= 8*64;
341 if (bank
->size
==0x10000) /* AT91SAM7S64 */
343 at91sam7_info
->target_name
= "AT91SAM7S64";
344 at91sam7_info
->num_lockbits
= 16;
345 at91sam7_info
->pagesize
= 128;
346 at91sam7_info
->pages_in_lockregion
= 32;
347 at91sam7_info
->num_pages
= 16*32;
349 if (bank
->size
==0x08000) /* AT91SAM7S321/32 */
351 at91sam7_info
->target_name
= "AT91SAM7S321/32";
352 at91sam7_info
->num_lockbits
= 8;
353 at91sam7_info
->pagesize
= 128;
354 at91sam7_info
->pages_in_lockregion
= 32;
355 at91sam7_info
->num_pages
= 8*32;
361 if (at91sam7_info
->cidr_arch
== 0x71 )
363 at91sam7_info
->num_nvmbits
= 2;
364 at91sam7_info
->nvmbits
= (status
>>8)&0x03;
365 bank
->base
= 0x100000;
367 if (bank
->size
==0x40000) /* AT91SAM7XC256 */
369 at91sam7_info
->target_name
= "AT91SAM7XC256";
370 at91sam7_info
->num_lockbits
= 16;
371 at91sam7_info
->pagesize
= 256;
372 at91sam7_info
->pages_in_lockregion
= 64;
373 at91sam7_info
->num_pages
= 16*64;
375 if (bank
->size
==0x20000) /* AT91SAM7XC128 */
377 at91sam7_info
->target_name
= "AT91SAM7XC128";
378 at91sam7_info
->num_lockbits
= 8;
379 at91sam7_info
->pagesize
= 256;
380 at91sam7_info
->pages_in_lockregion
= 64;
381 at91sam7_info
->num_pages
= 8*64;
387 if (at91sam7_info
->cidr_arch
== 0x75 )
389 at91sam7_info
->num_nvmbits
= 3;
390 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
391 bank
->base
= 0x100000;
393 if (bank
->size
==0x40000) /* AT91SAM7X256 */
395 at91sam7_info
->target_name
= "AT91SAM7X256";
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) /* AT91SAM7X128 */
403 at91sam7_info
->target_name
= "AT91SAM7X128";
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;
413 if (at91sam7_info
->cidr_arch
== 0x60 )
415 at91sam7_info
->num_nvmbits
= 3;
416 at91sam7_info
->nvmbits
= (status
>>8)&0x07;
417 bank
->base
= 0x100000;
420 if (bank
->size
== 0x40000) /* AT91SAM7A3 */
422 at91sam7_info
->target_name
= "AT91SAM7A3";
423 at91sam7_info
->num_lockbits
= 16;
424 at91sam7_info
->pagesize
= 256;
425 at91sam7_info
->pages_in_lockregion
= 64;
426 at91sam7_info
->num_pages
= 16*64;
431 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
436 int at91sam7_erase_check(struct flash_bank_s
*bank
)
438 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
439 target_t
*target
= at91sam7_info
->target
;
442 if (!at91sam7_info
->working_area_size
)
452 int at91sam7_protect_check(struct flash_bank_s
*bank
)
456 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
457 target_t
*target
= at91sam7_info
->target
;
459 if (at91sam7_info
->cidr
== 0)
461 at91sam7_read_part_info(bank
);
464 if (at91sam7_info
->cidr
== 0)
466 WARNING("Cannot identify target as an AT91SAM");
467 return ERROR_FLASH_OPERATION_FAILED
;
470 status
= at91sam7_get_flash_status(bank
);
471 at91sam7_info
->lockbits
= status
>> 16;
476 int at91sam7_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
478 at91sam7_flash_bank_t
*at91sam7_info
;
482 WARNING("incomplete flash_bank at91sam7 configuration");
483 return ERROR_FLASH_BANK_INVALID
;
486 at91sam7_info
= malloc(sizeof(at91sam7_flash_bank_t
));
487 bank
->driver_priv
= at91sam7_info
;
489 at91sam7_info
->target
= get_target_by_num(strtoul(args
[5], NULL
, 0));
490 if (!at91sam7_info
->target
)
492 ERROR("no target '%i' configured", args
[5]);
496 /* part wasn't probed for info yet */
497 at91sam7_info
->cidr
= 0;
502 int at91sam7_erase(struct flash_bank_s
*bank
, int first
, int last
)
504 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
506 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
508 return ERROR_TARGET_NOT_HALTED
;
511 if (at91sam7_info
->cidr
== 0)
513 at91sam7_read_part_info(bank
);
516 if (at91sam7_info
->cidr
== 0)
518 WARNING("Cannot identify target as an AT91SAM");
519 return ERROR_FLASH_OPERATION_FAILED
;
522 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
524 return ERROR_FLASH_SECTOR_INVALID
;
527 /* Configure the flash controller timing */
528 at91sam7_read_clock_info(bank
);
529 at91sam7_set_flash_mode(bank
,2);
531 if ((first
== 0) && (last
== (at91sam7_info
->num_lockbits
-1)))
533 return at91sam7_flash_command(bank
, EA
, 0);
536 WARNING("Can only erase the whole flash area, pages are autoerased on write");
537 return ERROR_FLASH_OPERATION_FAILED
;
540 int at91sam7_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
542 u32 cmd
, pagen
, status
;
545 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
546 target_t
*target
= at91sam7_info
->target
;
548 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
550 return ERROR_TARGET_NOT_HALTED
;
553 if ((first
< 0) || (last
< first
) || (last
>= at91sam7_info
->num_lockbits
))
555 return ERROR_FLASH_SECTOR_INVALID
;
558 if (at91sam7_info
->cidr
== 0)
560 at91sam7_read_part_info(bank
);
563 if (at91sam7_info
->cidr
== 0)
565 WARNING("Cannot identify target as an AT91SAM");
566 return ERROR_FLASH_OPERATION_FAILED
;
569 /* Configure the flash controller timing */
570 at91sam7_read_clock_info(bank
);
571 at91sam7_set_flash_mode(bank
,1);
573 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
575 pagen
= lockregion
*at91sam7_info
->pages_in_lockregion
;
580 if (at91sam7_flash_command(bank
, cmd
, pagen
) != ERROR_OK
)
582 return ERROR_FLASH_OPERATION_FAILED
;
586 status
= at91sam7_get_flash_status(bank
);
587 at91sam7_info
->lockbits
= status
>>16;
593 int at91sam7_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
595 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
596 target_t
*target
= at91sam7_info
->target
;
597 u32 dst_min_alignment
, wcount
, bytes_remaining
= count
;
598 u32 first_page
, last_page
, pagen
, buffer_pos
;
601 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
603 return ERROR_TARGET_NOT_HALTED
;
606 if (at91sam7_info
->cidr
== 0)
608 at91sam7_read_part_info(bank
);
611 if (at91sam7_info
->cidr
== 0)
613 WARNING("Cannot identify target as an AT91SAM");
614 return ERROR_FLASH_OPERATION_FAILED
;
617 if (offset
+ count
> bank
->size
)
618 return ERROR_FLASH_DST_OUT_OF_BANK
;
620 dst_min_alignment
= at91sam7_info
->pagesize
;
622 if (offset
% dst_min_alignment
)
624 WARNING("offset 0x%x breaks required alignment 0x%x", offset
, dst_min_alignment
);
625 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
628 if (offset
+ count
> bank
->size
)
629 return ERROR_FLASH_DST_OUT_OF_BANK
;
631 if (at91sam7_info
->cidr_arch
== 0)
632 return ERROR_FLASH_BANK_NOT_PROBED
;
634 first_page
= offset
/dst_min_alignment
;
635 last_page
= CEIL(offset
+ count
, dst_min_alignment
);
637 DEBUG("first_page: %i, last_page: %i, count %i", first_page
, last_page
, count
);
639 /* Configure the flash controller timing */
640 at91sam7_read_clock_info(bank
);
641 at91sam7_set_flash_mode(bank
,2);
643 for (pagen
=first_page
; pagen
<last_page
; pagen
++) {
644 if (bytes_remaining
<dst_min_alignment
)
645 count
= bytes_remaining
;
647 count
= dst_min_alignment
;
648 bytes_remaining
-= count
;
650 /* Write one block to the PageWriteBuffer */
651 buffer_pos
= (pagen
-first_page
)*dst_min_alignment
;
652 wcount
= CEIL(count
,4);
653 target
->type
->write_memory(target
, bank
->base
, 4, wcount
, buffer
+buffer_pos
);
655 /* Send Write Page command to Flash Controller */
656 if (at91sam7_flash_command(bank
, WP
, pagen
) != ERROR_OK
)
658 return ERROR_FLASH_OPERATION_FAILED
;
660 DEBUG("Flash command: 0x%x, pagenumber:", fcr
, pagen
);
667 int at91sam7_probe(struct flash_bank_s
*bank
)
669 /* we can't probe on an at91sam7
670 * if this is an at91sam7, it has the configured flash
672 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
674 if (at91sam7_info
->cidr
== 0)
676 at91sam7_read_part_info(bank
);
679 if (at91sam7_info
->cidr
== 0)
681 WARNING("Cannot identify target as an AT91SAM");
682 return ERROR_FLASH_OPERATION_FAILED
;
688 int at91sam7_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
691 at91sam7_flash_bank_t
*at91sam7_info
= bank
->driver_priv
;
693 at91sam7_read_part_info(bank
);
695 if (at91sam7_info
->cidr
== 0)
697 printed
= snprintf(buf
, buf_size
, "Cannot identify target as an AT91SAM\n");
700 return ERROR_FLASH_OPERATION_FAILED
;
703 printed
= snprintf(buf
, buf_size
, "\nat91sam7 information:\n");
707 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
);
711 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz \n", at91sam7_info
->mck_freq
/ 1000);
715 if (at91sam7_info
->num_lockbits
>0) {
716 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
);
721 printed
= snprintf(buf
, buf_size
, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info
->securitybit
, at91sam7_info
->nvmbits
);
729 * On AT91SAM7S: When the gpnmv bits are set with
730 * > at91sam7 gpnvm 0 bitnr set
731 * the changes are not visible in the flash controller status register MC_FSR
732 * until the processor has been reset.
733 * On the Olimex board this requires a power cycle.
734 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
735 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
736 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
738 int at91sam7_handle_gpnvm_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
745 at91sam7_flash_bank_t
*at91sam7_info
;
749 command_print(cmd_ctx
, "at91sam7 gpnvm <num> <bit> <set|clear>");
753 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
759 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
763 at91sam7_info
= bank
->driver_priv
;
765 if (at91sam7_info
->target
->state
!= TARGET_HALTED
)
767 return ERROR_TARGET_NOT_HALTED
;
770 if (at91sam7_info
->cidr
== 0)
772 at91sam7_read_part_info(bank
);
775 if (at91sam7_info
->cidr
== 0)
777 WARNING("Cannot identify target as an AT91SAM");
778 return ERROR_FLASH_OPERATION_FAILED
;
781 if ((bit
<0) || (at91sam7_info
->num_nvmbits
<= bit
))
783 command_print(cmd_ctx
, "gpnvm bit '#%s' is out of bounds for target %s", args
[1],at91sam7_info
->target_name
);
787 if (strcmp(value
, "set") == 0)
791 else if (strcmp(value
, "clear") == 0)
797 command_print(cmd_ctx
, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
801 /* Configure the flash controller timing */
802 at91sam7_read_clock_info(bank
);
803 at91sam7_set_flash_mode(bank
,1);
805 if (at91sam7_flash_command(bank
, flashcmd
, (u16
)(bit
)) != ERROR_OK
)
807 return ERROR_FLASH_OPERATION_FAILED
;
810 status
= at91sam7_get_flash_status(bank
);
811 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd
,bit
,status
);
812 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)