- reworked presto.c to allow use of either FTD2XX or libftdi (libftdi not functional...
[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 /* Support just for bulk erase of the whole device */
331 bank->num_sectors = 1;
332 bank->sectors = malloc(sizeof(flash_sector_t));
333 bank->sectors[0].offset = 0;
334 bank->sectors[0].size = bank->size;
335 bank->sectors[0].is_erased = -1;
336 bank->sectors[0].is_protected = -1;
337
338 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
339
340 /* Read main and master clock freqency register */
341 at91sam7_read_clock_info(bank);
342
343 status = at91sam7_get_flash_status(bank);
344 at91sam7_info->lockbits = status>>16;
345 at91sam7_info->securitybit = (status>>4)&0x01;
346
347 if (at91sam7_info->cidr_arch == 0x70 )
348 {
349 at91sam7_info->num_nvmbits = 2;
350 at91sam7_info->nvmbits = (status>>8)&0x03;
351 bank->base = 0x100000;
352 bank->bus_width = 4;
353 if (bank->size==0x40000) /* AT91SAM7S256 */
354 {
355 at91sam7_info->target_name = "AT91SAM7S256";
356 at91sam7_info->num_lockbits = 16;
357 at91sam7_info->pagesize = 256;
358 at91sam7_info->pages_in_lockregion = 64;
359 at91sam7_info->num_pages = 16*64;
360 }
361 if (bank->size==0x20000) /* AT91SAM7S128 */
362 {
363 at91sam7_info->target_name = "AT91SAM7S128";
364 at91sam7_info->num_lockbits = 8;
365 at91sam7_info->pagesize = 256;
366 at91sam7_info->pages_in_lockregion = 64;
367 at91sam7_info->num_pages = 8*64;
368 }
369 if (bank->size==0x10000) /* AT91SAM7S64 */
370 {
371 at91sam7_info->target_name = "AT91SAM7S64";
372 at91sam7_info->num_lockbits = 16;
373 at91sam7_info->pagesize = 128;
374 at91sam7_info->pages_in_lockregion = 32;
375 at91sam7_info->num_pages = 16*32;
376 }
377 if (bank->size==0x08000) /* AT91SAM7S321/32 */
378 {
379 at91sam7_info->target_name = "AT91SAM7S321/32";
380 at91sam7_info->num_lockbits = 8;
381 at91sam7_info->pagesize = 128;
382 at91sam7_info->pages_in_lockregion = 32;
383 at91sam7_info->num_pages = 8*32;
384 }
385
386 return ERROR_OK;
387 }
388
389 if (at91sam7_info->cidr_arch == 0x71 )
390 {
391 at91sam7_info->num_nvmbits = 3;
392 at91sam7_info->nvmbits = (status>>8)&0x07;
393 bank->base = 0x100000;
394 bank->bus_width = 4;
395 if (bank->size==0x40000) /* AT91SAM7XC256 */
396 {
397 at91sam7_info->target_name = "AT91SAM7XC256";
398 at91sam7_info->num_lockbits = 16;
399 at91sam7_info->pagesize = 256;
400 at91sam7_info->pages_in_lockregion = 64;
401 at91sam7_info->num_pages = 16*64;
402 }
403 if (bank->size==0x20000) /* AT91SAM7XC128 */
404 {
405 at91sam7_info->target_name = "AT91SAM7XC128";
406 at91sam7_info->num_lockbits = 8;
407 at91sam7_info->pagesize = 256;
408 at91sam7_info->pages_in_lockregion = 64;
409 at91sam7_info->num_pages = 8*64;
410 }
411
412 return ERROR_OK;
413 }
414
415 if (at91sam7_info->cidr_arch == 0x72 )
416 {
417 at91sam7_info->num_nvmbits = 2;
418 at91sam7_info->nvmbits = (status>>8)&0x03;
419 bank->base = 0x100000;
420 bank->bus_width = 4;
421 if (bank->size==0x80000) /* AT91SAM7SE512 */
422 {
423 at91sam7_info->target_name = "AT91SAM7SE512";
424 at91sam7_info->num_lockbits = 32;
425 at91sam7_info->pagesize = 256;
426 at91sam7_info->pages_in_lockregion = 64;
427 at91sam7_info->num_pages = 32*64;
428 }
429 if (bank->size==0x40000)
430 {
431 at91sam7_info->target_name = "AT91SAM7SE256";
432 at91sam7_info->num_lockbits = 16;
433 at91sam7_info->pagesize = 256;
434 at91sam7_info->pages_in_lockregion = 64;
435 at91sam7_info->num_pages = 16*64;
436 }
437 if (bank->size==0x08000)
438 {
439 at91sam7_info->target_name = "AT91SAM7SE32";
440 at91sam7_info->num_lockbits = 8;
441 at91sam7_info->pagesize = 128;
442 at91sam7_info->pages_in_lockregion = 32;
443 at91sam7_info->num_pages = 8*32;
444 }
445
446 return ERROR_OK;
447 }
448
449 if (at91sam7_info->cidr_arch == 0x75 )
450 {
451 at91sam7_info->num_nvmbits = 3;
452 at91sam7_info->nvmbits = (status>>8)&0x07;
453 bank->base = 0x100000;
454 bank->bus_width = 4;
455 if (bank->size==0x40000) /* AT91SAM7X256 */
456 {
457 at91sam7_info->target_name = "AT91SAM7X256";
458 at91sam7_info->num_lockbits = 16;
459 at91sam7_info->pagesize = 256;
460 at91sam7_info->pages_in_lockregion = 64;
461 at91sam7_info->num_pages = 16*64;
462 }
463 if (bank->size==0x20000) /* AT91SAM7X128 */
464 {
465 at91sam7_info->target_name = "AT91SAM7X128";
466 at91sam7_info->num_lockbits = 8;
467 at91sam7_info->pagesize = 256;
468 at91sam7_info->pages_in_lockregion = 64;
469 at91sam7_info->num_pages = 8*64;
470 }
471
472 return ERROR_OK;
473 }
474
475 if (at91sam7_info->cidr_arch == 0x60 )
476 {
477 at91sam7_info->num_nvmbits = 3;
478 at91sam7_info->nvmbits = (status>>8)&0x07;
479 bank->base = 0x100000;
480 bank->bus_width = 4;
481
482 if (bank->size == 0x40000) /* AT91SAM7A3 */
483 {
484 at91sam7_info->target_name = "AT91SAM7A3";
485 at91sam7_info->num_lockbits = 16;
486 at91sam7_info->pagesize = 256;
487 at91sam7_info->pages_in_lockregion = 16;
488 at91sam7_info->num_pages = 16*64;
489 }
490 return ERROR_OK;
491 }
492
493 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
494
495 return ERROR_OK;
496 }
497
498 int at91sam7_erase_check(struct flash_bank_s *bank)
499 {
500 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
501
502 if (!at91sam7_info->working_area_size)
503 {
504 }
505 else
506 {
507 }
508
509 return ERROR_OK;
510 }
511
512 int at91sam7_protect_check(struct flash_bank_s *bank)
513 {
514 u32 status;
515
516 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
517
518 if (at91sam7_info->cidr == 0)
519 {
520 at91sam7_read_part_info(bank);
521 }
522
523 if (at91sam7_info->cidr == 0)
524 {
525 WARNING("Cannot identify target as an AT91SAM");
526 return ERROR_FLASH_OPERATION_FAILED;
527 }
528
529 status = at91sam7_get_flash_status(bank);
530 at91sam7_info->lockbits = status >> 16;
531
532 return ERROR_OK;
533 }
534
535 /* flash_bank at91sam7 0 0 0 0 <target#>
536 */
537 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
538 {
539 at91sam7_flash_bank_t *at91sam7_info;
540
541 if (argc < 6)
542 {
543 WARNING("incomplete flash_bank at91sam7 configuration");
544 return ERROR_FLASH_BANK_INVALID;
545 }
546
547 at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
548 bank->driver_priv = at91sam7_info;
549
550 /* part wasn't probed for info yet */
551 at91sam7_info->cidr = 0;
552
553 return ERROR_OK;
554 }
555
556 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
557 {
558 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
559
560 if (bank->target->state != TARGET_HALTED)
561 {
562 return ERROR_TARGET_NOT_HALTED;
563 }
564
565 if (at91sam7_info->cidr == 0)
566 {
567 at91sam7_read_part_info(bank);
568 }
569
570 if (at91sam7_info->cidr == 0)
571 {
572 WARNING("Cannot identify target as an AT91SAM");
573 return ERROR_FLASH_OPERATION_FAILED;
574 }
575
576 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
577 {
578 if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
579 {
580 WARNING("Sector numbers based on lockbit count, probably a deprecated script");
581 last = bank->num_sectors-1;
582 }
583 else return ERROR_FLASH_SECTOR_INVALID;
584 }
585
586 if ((first != 0) || (last != (bank->num_sectors-1)))
587 {
588 WARNING("Can only erase the whole flash area, pages are autoerased on write");
589 return ERROR_FLASH_OPERATION_FAILED;
590 }
591
592 /* Configure the flash controller timing */
593 at91sam7_read_clock_info(bank);
594 at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
595
596 return at91sam7_flash_command(bank, EA, 0);
597 }
598
599 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
600 {
601 u32 cmd, pagen, status;
602 int lockregion;
603
604 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
605
606 if (bank->target->state != TARGET_HALTED)
607 {
608 return ERROR_TARGET_NOT_HALTED;
609 }
610
611 if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
612 {
613 return ERROR_FLASH_SECTOR_INVALID;
614 }
615
616 if (at91sam7_info->cidr == 0)
617 {
618 at91sam7_read_part_info(bank);
619 }
620
621 if (at91sam7_info->cidr == 0)
622 {
623 WARNING("Cannot identify target as an AT91SAM");
624 return ERROR_FLASH_OPERATION_FAILED;
625 }
626
627 /* Configure the flash controller timing */
628 at91sam7_read_clock_info(bank);
629 at91sam7_set_flash_mode(bank,FMR_TIMING_NVBITS);
630
631 for (lockregion=first;lockregion<=last;lockregion++)
632 {
633 pagen = lockregion*at91sam7_info->pages_in_lockregion;
634 if (set)
635 cmd = SLB;
636 else
637 cmd = CLB;
638 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
639 {
640 return ERROR_FLASH_OPERATION_FAILED;
641 }
642 }
643
644 status = at91sam7_get_flash_status(bank);
645 at91sam7_info->lockbits = status>>16;
646
647 return ERROR_OK;
648 }
649
650
651 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
652 {
653 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
654 target_t *target = bank->target;
655 u32 dst_min_alignment, wcount, bytes_remaining = count;
656 u32 first_page, last_page, pagen, buffer_pos;
657
658 if (bank->target->state != TARGET_HALTED)
659 {
660 return ERROR_TARGET_NOT_HALTED;
661 }
662
663 if (at91sam7_info->cidr == 0)
664 {
665 at91sam7_read_part_info(bank);
666 }
667
668 if (at91sam7_info->cidr == 0)
669 {
670 WARNING("Cannot identify target as an AT91SAM");
671 return ERROR_FLASH_OPERATION_FAILED;
672 }
673
674 if (offset + count > bank->size)
675 return ERROR_FLASH_DST_OUT_OF_BANK;
676
677 dst_min_alignment = at91sam7_info->pagesize;
678
679 if (offset % dst_min_alignment)
680 {
681 WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
682 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
683 }
684
685 if (at91sam7_info->cidr_arch == 0)
686 return ERROR_FLASH_BANK_NOT_PROBED;
687
688 first_page = offset/dst_min_alignment;
689 last_page = CEIL(offset + count, dst_min_alignment);
690
691 DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
692
693 /* Configure the flash controller timing */
694 at91sam7_read_clock_info(bank);
695 at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH);
696
697 for (pagen=first_page; pagen<last_page; pagen++) {
698 if (bytes_remaining<dst_min_alignment)
699 count = bytes_remaining;
700 else
701 count = dst_min_alignment;
702 bytes_remaining -= count;
703
704 /* Write one block to the PageWriteBuffer */
705 buffer_pos = (pagen-first_page)*dst_min_alignment;
706 wcount = CEIL(count,4);
707 target->type->write_memory(target, bank->base, 4, wcount, buffer+buffer_pos);
708
709 /* Send Write Page command to Flash Controller */
710 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
711 {
712 return ERROR_FLASH_OPERATION_FAILED;
713 }
714 DEBUG("Write page number:%i", pagen);
715 }
716
717 return ERROR_OK;
718 }
719
720
721 int at91sam7_probe(struct flash_bank_s *bank)
722 {
723 /* we can't probe on an at91sam7
724 * if this is an at91sam7, it has the configured flash
725 */
726 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
727
728 if (at91sam7_info->cidr == 0)
729 {
730 at91sam7_read_part_info(bank);
731 }
732
733 if (at91sam7_info->cidr == 0)
734 {
735 WARNING("Cannot identify target as an AT91SAM");
736 return ERROR_FLASH_OPERATION_FAILED;
737 }
738
739 return ERROR_OK;
740 }
741
742 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
743 {
744 int printed;
745 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
746
747 at91sam7_read_part_info(bank);
748
749 if (at91sam7_info->cidr == 0)
750 {
751 printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
752 buf += printed;
753 buf_size -= printed;
754 return ERROR_FLASH_OPERATION_FAILED;
755 }
756
757 printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
758 buf += printed;
759 buf_size -= printed;
760
761 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);
762 buf += printed;
763 buf_size -= printed;
764
765 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
766 buf += printed;
767 buf_size -= printed;
768
769 if (at91sam7_info->num_lockbits>0) {
770 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);
771 buf += printed;
772 buf_size -= printed;
773 }
774
775 printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
776 buf += printed;
777 buf_size -= printed;
778
779 return ERROR_OK;
780 }
781
782 /*
783 * On AT91SAM7S: When the gpnmv bits are set with
784 * > at91sam7 gpnvm 0 bitnr set
785 * the changes are not visible in the flash controller status register MC_FSR
786 * until the processor has been reset.
787 * On the Olimex board this requires a power cycle.
788 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
789 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
790 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
791 */
792 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
793 {
794 flash_bank_t *bank;
795 int bit;
796 u8 flashcmd;
797 u32 status;
798 char *value;
799 at91sam7_flash_bank_t *at91sam7_info;
800
801 if (argc < 3)
802 {
803 command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
804 return ERROR_OK;
805 }
806
807 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
808 bit = atoi(args[1]);
809 value = args[2];
810
811 if (!bank)
812 {
813 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
814 return ERROR_OK;
815 }
816
817 at91sam7_info = bank->driver_priv;
818
819 if (bank->target->state != TARGET_HALTED)
820 {
821 return ERROR_TARGET_NOT_HALTED;
822 }
823
824 if (at91sam7_info->cidr == 0)
825 {
826 at91sam7_read_part_info(bank);
827 }
828
829 if (at91sam7_info->cidr == 0)
830 {
831 WARNING("Cannot identify target as an AT91SAM");
832 return ERROR_FLASH_OPERATION_FAILED;
833 }
834
835 if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
836 {
837 command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
838 return ERROR_OK;
839 }
840
841 if (strcmp(value, "set") == 0)
842 {
843 flashcmd = SGPB;
844 }
845 else if (strcmp(value, "clear") == 0)
846 {
847 flashcmd = CGPB;
848 }
849 else
850 {
851 command_print(cmd_ctx, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
852 return ERROR_OK;
853 }
854
855 /* Configure the flash controller timing */
856 at91sam7_read_clock_info(bank);
857 at91sam7_set_flash_mode(bank,FMR_TIMING_NVBITS);
858
859 if (at91sam7_flash_command(bank, flashcmd, (u16)(bit)) != ERROR_OK)
860 {
861 return ERROR_FLASH_OPERATION_FAILED;
862 }
863
864 status = at91sam7_get_flash_status(bank);
865 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
866 at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
867
868 return ERROR_OK;
869 }

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)