- renamed M5960 USB JTAG to "flyswatter"
[openocd.git] / src / flash / at91sam7.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20
21 /***************************************************************************
22 There are some things to notice
23
24 * AT91SAM7S64 is tested
25 * All AT91SAM7Sxx and AT91SAM7Xxx should work but is not tested
26 * All parameters are identified from onchip configuartion registers
27 *
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
32 *
33 * Lock regions (sectors) are 32 or 64 pages
34 *
35 ***************************************************************************/
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "replacements.h"
41
42 #include "at91sam7.h"
43
44 #include "flash.h"
45 #include "target.h"
46 #include "log.h"
47 #include "binarybuffer.h"
48 #include "types.h"
49
50 #include <stdlib.h>
51 #include <string.h>
52 #include <unistd.h>
53
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);
63
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);
68
69 flash_driver_t at91sam7_flash =
70 {
71 .name = "at91sam7",
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,
80 .info = at91sam7_info
81 };
82
83
84 char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
85 long NVPSIZ[16] = {
86 0,
87 0x2000, /* 8K */
88 0x4000, /* 16K */
89 0x8000, /* 32K */
90 -1,
91 0x10000, /* 64K */
92 -1,
93 0x20000, /* 128K */
94 -1,
95 0x40000, /* 256K */
96 0x80000, /* 512K */
97 -1,
98 0x100000, /* 1024K */
99 -1,
100 0x200000, /* 2048K */
101 -1
102 };
103
104 long SRAMSIZ[16] = {
105 -1,
106 0x0400, /* 1K */
107 0x0800, /* 2K */
108 -1,
109 0x1c000, /* 112K */
110 0x1000, /* 4K */
111 0x14000, /* 80K */
112 0x28000, /* 160K */
113 0x2000, /* 8K */
114 0x4000, /* 16K */
115 0x8000, /* 32K */
116 0x10000, /* 64K */
117 0x20000, /* 128K */
118 0x40000, /* 256K */
119 0x18000, /* 96K */
120 0x80000, /* 512K */
121 };
122
123 int at91sam7_register_commands(struct command_context_s *cmd_ctx)
124 {
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");
128
129 return ERROR_OK;
130 }
131
132 u32 at91sam7_get_flash_status(flash_bank_t *bank)
133 {
134 target_t *target = bank->target;
135 u32 fsr;
136
137 target_read_u32(target, MC_FSR, &fsr);
138
139 return fsr;
140 }
141
142 /** Read clock configuration and set at91sam7_info->usec_clocks*/
143 void at91sam7_read_clock_info(flash_bank_t *bank)
144 {
145 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
146 target_t *target = bank->target;
147 u32 mckr, mcfr, pllr;
148 unsigned long tmp = 0, mainfreq;
149
150 /* Read main clock freqency register */
151 target_read_u32(target, CKGR_MCFR, &mcfr);
152 /* Read master clock register */
153 target_read_u32(target, PMC_MCKR, &mckr);
154 /* Read Clock Generator PLL Register */
155 target_read_u32(target, CKGR_PLLR, &pllr);
156
157 at91sam7_info->mck_valid = 0;
158 switch (mckr & PMC_MCKR_CSS) {
159 case 0: /* Slow Clock */
160 at91sam7_info->mck_valid = 1;
161 tmp = RC_FREQ;
162 break;
163 case 1: /* Main Clock */
164 if (mcfr & CKGR_MCFR_MAINRDY)
165 {
166 at91sam7_info->mck_valid = 1;
167 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
168 tmp = mainfreq;
169 }
170 break;
171
172 case 2: /* Reserved */
173 break;
174 case 3: /* PLL Clock */
175 if (mcfr & CKGR_MCFR_MAINRDY)
176 {
177 target_read_u32(target, CKGR_PLLR, &pllr);
178 if (!(pllr & CKGR_PLLR_DIV))
179 break; /* 0 Hz */
180 at91sam7_info->mck_valid = 1;
181 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
182 /* Integer arithmetic should have sufficient precision
183 as long as PLL is properly configured. */
184 tmp = mainfreq / (pllr & CKGR_PLLR_DIV) *
185 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
186 }
187 break;
188 }
189
190 /* Prescaler adjust */
191 if (((mckr & PMC_MCKR_PRES) >> 2) == 7)
192 at91sam7_info->mck_valid = 0;
193 else
194 at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
195
196 /* Forget old flash timing */
197 at91sam7_set_flash_mode(bank,FMR_TIMING_NONE);
198 }
199
200 /* Setup the timimg registers for nvbits or normal flash */
201 void at91sam7_set_flash_mode(flash_bank_t *bank,int mode)
202 {
203 u32 fmr, fmcn = 0, fws = 0;
204 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
205 target_t *target = bank->target;
206
207 if (mode && (mode != at91sam7_info->flashmode))
208 {
209 /* Always round up (ceil) */
210 if (mode==FMR_TIMING_NVBITS)
211 {
212 if (at91sam7_info->cidr_arch == 0x60)
213 {
214 /* AT91SAM7A3 uses master clocks in 100 ns */
215 fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
216 }
217 else
218 {
219 /* master clocks in 1uS for ARCH 0x7 types */
220 fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
221 }
222 }
223 else if (mode==FMR_TIMING_FLASH)
224 /* main clocks in 1.5uS */
225 fmcn = (at91sam7_info->mck_freq/666666ul)+1;
226
227 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
228 if (at91sam7_info->mck_freq <= 33333ul)
229 fmcn = 0;
230 /* Only allow fws=0 if clock frequency is < 30 MHz. */
231 if (at91sam7_info->mck_freq > 30000000ul)
232 fws = 1;
233
234 DEBUG("fmcn: %i", fmcn);
235 fmr = fmcn << 16 | fws << 8;
236 target_write_u32(target, MC_FMR, fmr);
237 }
238
239 at91sam7_info->flashmode = mode;
240 }
241
242 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
243 {
244 u32 status;
245
246 while ((!((status = at91sam7_get_flash_status(bank)) & waitbits)) && (timeout-- > 0))
247 {
248 DEBUG("status: 0x%x", status);
249 usleep(1000);
250 }
251
252 DEBUG("status: 0x%x", status);
253
254 if (status & 0x0C)
255 {
256 ERROR("status register: 0x%x", status);
257 if (status & 0x4)
258 ERROR("Lock Error Bit Detected, Operation Abort");
259 if (status & 0x8)
260 ERROR("Invalid command and/or bad keyword, Operation Abort");
261 if (status & 0x10)
262 ERROR("Security Bit Set, Operation Abort");
263 }
264
265 return status;
266 }
267
268
269 /* Send one command to the AT91SAM flash controller */
270 int at91sam7_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
271 {
272 u32 fcr;
273 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
274 target_t *target = bank->target;
275
276 fcr = (0x5A<<24) | (pagen<<8) | cmd;
277 target_write_u32(target, MC_FCR, fcr);
278 DEBUG("Flash command: 0x%x, pagenumber:%u", fcr, pagen);
279
280 if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
281 {
282 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
283 if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
284 {
285 return ERROR_FLASH_OPERATION_FAILED;
286 }
287 return ERROR_OK;
288 }
289
290 if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
291 {
292 return ERROR_FLASH_OPERATION_FAILED;
293 }
294 return ERROR_OK;
295 }
296
297 /* Read device id register, main clock frequency register and fill in driver info structure */
298 int at91sam7_read_part_info(struct flash_bank_s *bank)
299 {
300 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
301 target_t *target = bank->target;
302 u32 cidr, status;
303
304 if (bank->target->state != TARGET_HALTED)
305 {
306 return ERROR_TARGET_NOT_HALTED;
307 }
308
309 /* Read and parse chip identification register */
310 target_read_u32(target, DBGU_CIDR, &cidr);
311
312 if (cidr == 0)
313 {
314 WARNING("Cannot identify target as an AT91SAM");
315 return ERROR_FLASH_OPERATION_FAILED;
316 }
317
318 at91sam7_info->cidr = cidr;
319 at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
320 at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
321 at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
322 at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
323 at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
324 at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
325 at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
326 at91sam7_info->cidr_version = cidr&0x001F;
327 bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
328 at91sam7_info->target_name = "Unknown";
329
330 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
331
332 /* Read main and master clock freqency register */
333 at91sam7_read_clock_info(bank);
334
335 status = at91sam7_get_flash_status(bank);
336 at91sam7_info->lockbits = status>>16;
337 at91sam7_info->securitybit = (status>>4)&0x01;
338
339 if (at91sam7_info->cidr_arch == 0x70 )
340 {
341 at91sam7_info->num_nvmbits = 2;
342 at91sam7_info->nvmbits = (status>>8)&0x03;
343 bank->base = 0x100000;
344 bank->bus_width = 4;
345 if (bank->size==0x40000) /* AT91SAM7S256 */
346 {
347 at91sam7_info->target_name = "AT91SAM7S256";
348 at91sam7_info->num_lockbits = 16;
349 at91sam7_info->pagesize = 256;
350 at91sam7_info->pages_in_lockregion = 64;
351 at91sam7_info->num_pages = 16*64;
352 }
353 if (bank->size==0x20000) /* AT91SAM7S128 */
354 {
355 at91sam7_info->target_name = "AT91SAM7S128";
356 at91sam7_info->num_lockbits = 8;
357 at91sam7_info->pagesize = 256;
358 at91sam7_info->pages_in_lockregion = 64;
359 at91sam7_info->num_pages = 8*64;
360 }
361 if (bank->size==0x10000) /* AT91SAM7S64 */
362 {
363 at91sam7_info->target_name = "AT91SAM7S64";
364 at91sam7_info->num_lockbits = 16;
365 at91sam7_info->pagesize = 128;
366 at91sam7_info->pages_in_lockregion = 32;
367 at91sam7_info->num_pages = 16*32;
368 }
369 if (bank->size==0x08000) /* AT91SAM7S321/32 */
370 {
371 at91sam7_info->target_name = "AT91SAM7S321/32";
372 at91sam7_info->num_lockbits = 8;
373 at91sam7_info->pagesize = 128;
374 at91sam7_info->pages_in_lockregion = 32;
375 at91sam7_info->num_pages = 8*32;
376 }
377
378 return ERROR_OK;
379 }
380
381 if (at91sam7_info->cidr_arch == 0x71 )
382 {
383 at91sam7_info->num_nvmbits = 3;
384 at91sam7_info->nvmbits = (status>>8)&0x07;
385 bank->base = 0x100000;
386 bank->bus_width = 4;
387 if (bank->size==0x40000) /* AT91SAM7XC256 */
388 {
389 at91sam7_info->target_name = "AT91SAM7XC256";
390 at91sam7_info->num_lockbits = 16;
391 at91sam7_info->pagesize = 256;
392 at91sam7_info->pages_in_lockregion = 64;
393 at91sam7_info->num_pages = 16*64;
394 }
395 if (bank->size==0x20000) /* AT91SAM7XC128 */
396 {
397 at91sam7_info->target_name = "AT91SAM7XC128";
398 at91sam7_info->num_lockbits = 8;
399 at91sam7_info->pagesize = 256;
400 at91sam7_info->pages_in_lockregion = 64;
401 at91sam7_info->num_pages = 8*64;
402 }
403
404 return ERROR_OK;
405 }
406
407 if (at91sam7_info->cidr_arch == 0x72 )
408 {
409 at91sam7_info->num_nvmbits = 2;
410 at91sam7_info->nvmbits = (status>>8)&0x03;
411 bank->base = 0x100000;
412 bank->bus_width = 4;
413 if (bank->size==0x80000) /* AT91SAM7SE512 */
414 {
415 at91sam7_info->target_name = "AT91SAM7SE512";
416 at91sam7_info->num_lockbits = 32;
417 at91sam7_info->pagesize = 256;
418 at91sam7_info->pages_in_lockregion = 64;
419 at91sam7_info->num_pages = 32*64;
420 }
421 if (bank->size==0x40000)
422 {
423 at91sam7_info->target_name = "AT91SAM7SE256";
424 at91sam7_info->num_lockbits = 16;
425 at91sam7_info->pagesize = 256;
426 at91sam7_info->pages_in_lockregion = 64;
427 at91sam7_info->num_pages = 16*64;
428 }
429 if (bank->size==0x08000)
430 {
431 at91sam7_info->target_name = "AT91SAM7SE32";
432 at91sam7_info->num_lockbits = 8;
433 at91sam7_info->pagesize = 128;
434 at91sam7_info->pages_in_lockregion = 32;
435 at91sam7_info->num_pages = 8*32;
436 }
437
438 return ERROR_OK;
439 }
440
441 if (at91sam7_info->cidr_arch == 0x75 )
442 {
443 at91sam7_info->num_nvmbits = 3;
444 at91sam7_info->nvmbits = (status>>8)&0x07;
445 bank->base = 0x100000;
446 bank->bus_width = 4;
447 if (bank->size==0x40000) /* AT91SAM7X256 */
448 {
449 at91sam7_info->target_name = "AT91SAM7X256";
450 at91sam7_info->num_lockbits = 16;
451 at91sam7_info->pagesize = 256;
452 at91sam7_info->pages_in_lockregion = 64;
453 at91sam7_info->num_pages = 16*64;
454 }
455 if (bank->size==0x20000) /* AT91SAM7X128 */
456 {
457 at91sam7_info->target_name = "AT91SAM7X128";
458 at91sam7_info->num_lockbits = 8;
459 at91sam7_info->pagesize = 256;
460 at91sam7_info->pages_in_lockregion = 64;
461 at91sam7_info->num_pages = 8*64;
462 }
463
464 return ERROR_OK;
465 }
466
467 if (at91sam7_info->cidr_arch == 0x60 )
468 {
469 at91sam7_info->num_nvmbits = 3;
470 at91sam7_info->nvmbits = (status>>8)&0x07;
471 bank->base = 0x100000;
472 bank->bus_width = 4;
473
474 if (bank->size == 0x40000) /* AT91SAM7A3 */
475 {
476 at91sam7_info->target_name = "AT91SAM7A3";
477 at91sam7_info->num_lockbits = 16;
478 at91sam7_info->pagesize = 256;
479 at91sam7_info->pages_in_lockregion = 16;
480 at91sam7_info->num_pages = 16*64;
481 }
482 return ERROR_OK;
483 }
484
485 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
486
487 return ERROR_OK;
488 }
489
490 int at91sam7_erase_check(struct flash_bank_s *bank)
491 {
492 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
493
494 if (!at91sam7_info->working_area_size)
495 {
496 }
497 else
498 {
499 }
500
501 return ERROR_OK;
502 }
503
504 int at91sam7_protect_check(struct flash_bank_s *bank)
505 {
506 u32 status;
507
508 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
509
510 if (at91sam7_info->cidr == 0)
511 {
512 at91sam7_read_part_info(bank);
513 }
514
515 if (at91sam7_info->cidr == 0)
516 {
517 WARNING("Cannot identify target as an AT91SAM");
518 return ERROR_FLASH_OPERATION_FAILED;
519 }
520
521 status = at91sam7_get_flash_status(bank);
522 at91sam7_info->lockbits = status >> 16;
523
524 return ERROR_OK;
525 }
526
527 /* flash_bank at91sam7 0 0 0 0 <target#>
528 */
529 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
530 {
531 at91sam7_flash_bank_t *at91sam7_info;
532
533 if (argc < 6)
534 {
535 WARNING("incomplete flash_bank at91sam7 configuration");
536 return ERROR_FLASH_BANK_INVALID;
537 }
538
539 at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
540 bank->driver_priv = at91sam7_info;
541
542 /* part wasn't probed for info yet */
543 at91sam7_info->cidr = 0;
544
545 return ERROR_OK;
546 }
547
548 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
549 {
550 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
551
552 if (bank->target->state != TARGET_HALTED)
553 {
554 return ERROR_TARGET_NOT_HALTED;
555 }
556
557 if (at91sam7_info->cidr == 0)
558 {
559 at91sam7_read_part_info(bank);
560 }
561
562 if (at91sam7_info->cidr == 0)
563 {
564 WARNING("Cannot identify target as an AT91SAM");
565 return ERROR_FLASH_OPERATION_FAILED;
566 }
567
568 if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
569 {
570 return ERROR_FLASH_SECTOR_INVALID;
571 }
572
573 /* Configure the flash controller timing */
574 at91sam7_read_clock_info(bank);
575 at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
576
577 if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
578 {
579 return at91sam7_flash_command(bank, EA, 0);
580 }
581
582 WARNING("Can only erase the whole flash area, pages are autoerased on write");
583 return ERROR_FLASH_OPERATION_FAILED;
584 }
585
586 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
587 {
588 u32 cmd, pagen, status;
589 int lockregion;
590
591 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
592
593 if (bank->target->state != TARGET_HALTED)
594 {
595 return ERROR_TARGET_NOT_HALTED;
596 }
597
598 if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
599 {
600 return ERROR_FLASH_SECTOR_INVALID;
601 }
602
603 if (at91sam7_info->cidr == 0)
604 {
605 at91sam7_read_part_info(bank);
606 }
607
608 if (at91sam7_info->cidr == 0)
609 {
610 WARNING("Cannot identify target as an AT91SAM");
611 return ERROR_FLASH_OPERATION_FAILED;
612 }
613
614 /* Configure the flash controller timing */
615 at91sam7_read_clock_info(bank);
616 at91sam7_set_flash_mode(bank,FMR_TIMING_NVBITS);
617
618 for (lockregion=first;lockregion<=last;lockregion++)
619 {
620 pagen = lockregion*at91sam7_info->pages_in_lockregion;
621 if (set)
622 cmd = SLB;
623 else
624 cmd = CLB;
625 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
626 {
627 return ERROR_FLASH_OPERATION_FAILED;
628 }
629 }
630
631 status = at91sam7_get_flash_status(bank);
632 at91sam7_info->lockbits = status>>16;
633
634 return ERROR_OK;
635 }
636
637
638 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
639 {
640 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
641 target_t *target = bank->target;
642 u32 dst_min_alignment, wcount, bytes_remaining = count;
643 u32 first_page, last_page, pagen, buffer_pos;
644
645 if (bank->target->state != TARGET_HALTED)
646 {
647 return ERROR_TARGET_NOT_HALTED;
648 }
649
650 if (at91sam7_info->cidr == 0)
651 {
652 at91sam7_read_part_info(bank);
653 }
654
655 if (at91sam7_info->cidr == 0)
656 {
657 WARNING("Cannot identify target as an AT91SAM");
658 return ERROR_FLASH_OPERATION_FAILED;
659 }
660
661 if (offset + count > bank->size)
662 return ERROR_FLASH_DST_OUT_OF_BANK;
663
664 dst_min_alignment = at91sam7_info->pagesize;
665
666 if (offset % dst_min_alignment)
667 {
668 WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
669 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
670 }
671
672 if (at91sam7_info->cidr_arch == 0)
673 return ERROR_FLASH_BANK_NOT_PROBED;
674
675 first_page = offset/dst_min_alignment;
676 last_page = CEIL(offset + count, dst_min_alignment);
677
678 DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
679
680 /* Configure the flash controller timing */
681 at91sam7_read_clock_info(bank);
682 at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
683
684 for (pagen=first_page; pagen<last_page; pagen++) {
685 if (bytes_remaining<dst_min_alignment)
686 count = bytes_remaining;
687 else
688 count = dst_min_alignment;
689 bytes_remaining -= count;
690
691 /* Write one block to the PageWriteBuffer */
692 buffer_pos = (pagen-first_page)*dst_min_alignment;
693 wcount = CEIL(count,4);
694 target->type->write_memory(target, bank->base, 4, wcount, buffer+buffer_pos);
695
696 /* Send Write Page command to Flash Controller */
697 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
698 {
699 return ERROR_FLASH_OPERATION_FAILED;
700 }
701 DEBUG("Write page number:%i", pagen);
702 }
703
704 return ERROR_OK;
705 }
706
707
708 int at91sam7_probe(struct flash_bank_s *bank)
709 {
710 /* we can't probe on an at91sam7
711 * if this is an at91sam7, it has the configured flash
712 */
713 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
714
715 if (at91sam7_info->cidr == 0)
716 {
717 at91sam7_read_part_info(bank);
718 }
719
720 if (at91sam7_info->cidr == 0)
721 {
722 WARNING("Cannot identify target as an AT91SAM");
723 return ERROR_FLASH_OPERATION_FAILED;
724 }
725
726 return ERROR_OK;
727 }
728
729 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
730 {
731 int printed;
732 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
733
734 at91sam7_read_part_info(bank);
735
736 if (at91sam7_info->cidr == 0)
737 {
738 printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
739 buf += printed;
740 buf_size -= printed;
741 return ERROR_FLASH_OPERATION_FAILED;
742 }
743
744 printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
745 buf += printed;
746 buf_size -= printed;
747
748 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);
749 buf += printed;
750 buf_size -= printed;
751
752 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
753 buf += printed;
754 buf_size -= printed;
755
756 if (at91sam7_info->num_lockbits>0) {
757 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);
758 buf += printed;
759 buf_size -= printed;
760 }
761
762 printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
763 buf += printed;
764 buf_size -= printed;
765
766 return ERROR_OK;
767 }
768
769 /*
770 * On AT91SAM7S: When the gpnmv bits are set with
771 * > at91sam7 gpnvm 0 bitnr set
772 * the changes are not visible in the flash controller status register MC_FSR
773 * until the processor has been reset.
774 * On the Olimex board this requires a power cycle.
775 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
776 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
777 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
778 */
779 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
780 {
781 flash_bank_t *bank;
782 int bit;
783 u8 flashcmd;
784 u32 status;
785 char *value;
786 at91sam7_flash_bank_t *at91sam7_info;
787
788 if (argc < 3)
789 {
790 command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
791 return ERROR_OK;
792 }
793
794 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
795 bit = atoi(args[1]);
796 value = args[2];
797
798 if (!bank)
799 {
800 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
801 return ERROR_OK;
802 }
803
804 at91sam7_info = bank->driver_priv;
805
806 if (bank->target->state != TARGET_HALTED)
807 {
808 return ERROR_TARGET_NOT_HALTED;
809 }
810
811 if (at91sam7_info->cidr == 0)
812 {
813 at91sam7_read_part_info(bank);
814 }
815
816 if (at91sam7_info->cidr == 0)
817 {
818 WARNING("Cannot identify target as an AT91SAM");
819 return ERROR_FLASH_OPERATION_FAILED;
820 }
821
822 if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
823 {
824 command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
825 return ERROR_OK;
826 }
827
828 if (strcmp(value, "set") == 0)
829 {
830 flashcmd = SGPB;
831 }
832 else if (strcmp(value, "clear") == 0)
833 {
834 flashcmd = CGPB;
835 }
836 else
837 {
838 command_print(cmd_ctx, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
839 return ERROR_OK;
840 }
841
842 /* Configure the flash controller timing */
843 at91sam7_read_clock_info(bank);
844 at91sam7_set_flash_mode(bank,FMR_TIMING_NVBITS);
845
846 if (at91sam7_flash_command(bank, flashcmd, (u16)(bit)) != ERROR_OK)
847 {
848 return ERROR_FLASH_OPERATION_FAILED;
849 }
850
851 status = at91sam7_get_flash_status(bank);
852 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
853 at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
854
855 return ERROR_OK;
856 }

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)