Gheorghe Guran <roatlasro@yahoo.com> redone at91sam7 driver. Old driver source file...
[openocd.git] / src / flash / at91sam7.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
5 * Copyright (C) 2008 by Gheorghe Guran (atlas) *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
15 * GNU General public License for more details. *
16 * *
17 * You should have received a copy of the GNU General public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ****************************************************************************/
22
23 /***************************************************************************************************************************************************************************************
24 *
25 * New flash setup command:
26 *
27 * flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]
28 *
29 * <ext_freq_khz> - MUST be used if clock is from external source,
30 * CAN be used if main oscillator frequency is known (recomended)
31 * Examples:
32 * flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 25000 ==== RECOMENDED ============
33 * flash bank at91sam7 0 0 0 0 0 0 0 0 0 0 0 0 25000 (auto-detection, except for clock) ==== RECOMENDED ============
34 * flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 0 ==== NOT RECOMENDED !!! ====
35 * flash bank at91sam7 0 0 0 0 0 (old style, full auto-detection) ==== NOT RECOMENDED !!! ====
36 ****************************************************************************************************************************************************************************************/
37
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #include "replacements.h"
43
44 #include "at91sam7.h"
45
46 #include "flash.h"
47 #include "target.h"
48 #include "log.h"
49 #include "binarybuffer.h"
50 #include "types.h"
51
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55
56 int at91sam7_register_commands(struct command_context_s *cmd_ctx);
57 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
58 int at91sam7_erase(struct flash_bank_s *bank, int first, int last);
59 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last);
60 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
61 int at91sam7_probe(struct flash_bank_s *bank);
62 int at91sam7_auto_probe(struct flash_bank_s *bank);
63 int at91sam7_erase_check(struct flash_bank_s *bank);
64 int at91sam7_protect_check(struct flash_bank_s *bank);
65 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size);
66
67 u32 at91sam7_get_flash_status(target_t *target, int bank_number);
68 void at91sam7_set_flash_mode(flash_bank_t *bank, int mode);
69 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
70 int at91sam7_flash_command(struct flash_bank_s *bank, u8 cmd, u16 pagen);
71 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
72
73 flash_driver_t at91sam7_flash =
74 {
75 .name = "at91sam7_new",
76 .register_commands = at91sam7_register_commands,
77 .flash_bank_command = at91sam7_flash_bank_command,
78 .erase = at91sam7_erase,
79 .protect = at91sam7_protect,
80 .write = at91sam7_write,
81 .probe = at91sam7_probe,
82 .auto_probe = at91sam7_probe,
83 .erase_check = at91sam7_erase_check,
84 .protect_check = at91sam7_protect_check,
85 .info = at91sam7_info
86 };
87
88
89 u32 MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
90 u32 MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
91 u32 MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
92
93 char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
94
95 long SRAMSIZ[16] = {
96 -1,
97 0x0400, /* 1K */
98 0x0800, /* 2K */
99 -1,
100 0x1c000, /* 112K */
101 0x1000, /* 4K */
102 0x14000, /* 80K */
103 0x28000, /* 160K */
104 0x2000, /* 8K */
105 0x4000, /* 16K */
106 0x8000, /* 32K */
107 0x10000, /* 64K */
108 0x20000, /* 128K */
109 0x40000, /* 256K */
110 0x18000, /* 96K */
111 0x80000, /* 512K */
112 };
113
114 int at91sam7_register_commands(struct command_context_s *cmd_ctx)
115 {
116 command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7_new", NULL, COMMAND_ANY, NULL);
117
118 register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
119 "at91sam7 gpnvm <bit> set|clear, set or clear one gpnvm bit");
120 return ERROR_OK;
121 }
122
123 u32 at91sam7_get_flash_status(target_t *target, int bank_number)
124 {
125 u32 fsr;
126 target_read_u32(target, MC_FSR[bank_number], &fsr);
127
128 return fsr;
129 }
130
131 /* Read clock configuration and set at91sam7_info->mck_freq */
132 void at91sam7_read_clock_info(flash_bank_t *bank)
133 {
134 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
135 target_t *target = bank->target;
136 u32 mckr, mcfr, pllr, mor;
137 unsigned long tmp = 0, mainfreq;
138
139 /* Read Clock Generator Main Oscillator Register */
140 target_read_u32(target, CKGR_MOR, &mor);
141 /* Read Clock Generator Main Clock Frequency Register */
142 target_read_u32(target, CKGR_MCFR, &mcfr);
143 /* Read Master Clock Register*/
144 target_read_u32(target, PMC_MCKR, &mckr);
145 /* Read Clock Generator PLL Register */
146 target_read_u32(target, CKGR_PLLR, &pllr);
147
148 at91sam7_info->mck_valid = 0;
149 at91sam7_info->mck_freq = 0;
150 switch (mckr & PMC_MCKR_CSS)
151 {
152 case 0: /* Slow Clock */
153 at91sam7_info->mck_valid = 1;
154 tmp = RC_FREQ;
155 break;
156
157 case 1: /* Main Clock */
158 if ((mcfr & CKGR_MCFR_MAINRDY) &&
159 (at91sam7_info->ext_freq == 0))
160 {
161 at91sam7_info->mck_valid = 1;
162 tmp = RC_FREQ / 16ul * (mcfr & 0xffff);
163 }
164 else if (at91sam7_info->ext_freq != 0)
165 {
166 at91sam7_info->mck_valid = 1;
167 tmp = at91sam7_info->ext_freq;
168 }
169 break;
170
171 case 2: /* Reserved */
172 break;
173
174 case 3: /* PLL Clock */
175 if ((mcfr & CKGR_MCFR_MAINRDY) &&
176 (at91sam7_info->ext_freq == 0))
177 {
178 target_read_u32(target, CKGR_PLLR, &pllr);
179 if (!(pllr & CKGR_PLLR_DIV))
180 break; /* 0 Hz */
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);
187 }
188 else if ((at91sam7_info->ext_freq != 0) &&
189 ((pllr&CKGR_PLLR_DIV) != 0))
190 {
191 at91sam7_info->mck_valid = 1;
192 tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*
193 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
194 }
195 break;
196 }
197
198 /* Prescaler adjust */
199 if ( (((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0) )
200 {
201 at91sam7_info->mck_valid = 0;
202 at91sam7_info->mck_freq = 0;
203 }
204 else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)
205 at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
206 else
207 at91sam7_info->mck_freq = tmp;
208 }
209
210 /* Setup the timimg registers for nvbits or normal flash */
211 void at91sam7_set_flash_mode(flash_bank_t *bank, int mode)
212 {
213 u32 fmr, fmcn = 0, fws = 0;
214 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
215 target_t *target = bank->target;
216
217 if (mode && (mode != at91sam7_info->flashmode))
218 {
219 /* Always round up (ceil) */
220 if (mode == FMR_TIMING_NVBITS)
221 {
222 if (at91sam7_info->cidr_arch == 0x60)
223 {
224 /* AT91SAM7A3 uses master clocks in 100 ns */
225 fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
226 }
227 else
228 {
229 /* master clocks in 1uS for ARCH 0x7 types */
230 fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
231 }
232 }
233 else if (mode == FMR_TIMING_FLASH)
234 {
235 /* main clocks in 1.5uS */
236 fmcn = (at91sam7_info->mck_freq/1000000ul)+
237 (at91sam7_info->mck_freq/2000000ul)+1;
238 }
239
240 /* hard overclocking */
241 if (fmcn > 0xFF)
242 fmcn = 0xFF;
243
244 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
245 if (at91sam7_info->mck_freq <= 33333ul)
246 fmcn = 0;
247 /* Only allow fws=0 if clock frequency is < 30 MHz. */
248 if (at91sam7_info->mck_freq > 30000000ul)
249 fws = 1;
250
251 LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, fmcn);
252 fmr = fmcn << 16 | fws << 8;
253 target_write_u32(target, MC_FMR[bank->bank_number], fmr);
254 }
255
256 at91sam7_info->flashmode = mode;
257 }
258
259 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
260 {
261 u32 status;
262
263 while ((!((status = at91sam7_get_flash_status(bank->target, bank->bank_number)) & waitbits)) && (timeout-- > 0))
264 {
265 LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
266 alive_sleep(1);
267 }
268
269 LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
270
271 if (status & 0x0C)
272 {
273 LOG_ERROR("status register: 0x%x", status);
274 if (status & 0x4)
275 LOG_ERROR("Lock Error Bit Detected, Operation Abort");
276 if (status & 0x8)
277 LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
278 if (status & 0x10)
279 LOG_ERROR("Security Bit Set, Operation Abort");
280 }
281
282 return status;
283 }
284
285 /* Send one command to the AT91SAM flash controller */
286 int at91sam7_flash_command(struct flash_bank_s *bank, u8 cmd, u16 pagen)
287 {
288 u32 fcr;
289 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
290 target_t *target = bank->target;
291
292 fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd;
293 target_write_u32(target, MC_FCR[bank->bank_number], fcr);
294 LOG_DEBUG("Flash command: 0x%x, flash bank: %i, page number: %u", fcr, bank->bank_number+1, pagen);
295
296 if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
297 {
298 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
299 if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
300 {
301 return ERROR_FLASH_OPERATION_FAILED;
302 }
303 return ERROR_OK;
304 }
305
306 if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
307 {
308 return ERROR_FLASH_OPERATION_FAILED;
309 }
310
311 return ERROR_OK;
312 }
313
314 /* Read device id register, main clock frequency register and fill in driver info structure */
315 int at91sam7_read_part_info(struct flash_bank_s *bank)
316 {
317 flash_bank_t *t_bank = bank;
318 at91sam7_flash_bank_t *at91sam7_info;
319 target_t *target = t_bank->target;
320
321 u16 bnk, sec;
322 u16 arch;
323 u32 cidr, status;
324 u8 banks_num;
325 u16 num_nvmbits;
326 u16 sectors_num;
327 u16 pages_per_sector;
328 u16 page_size;
329 u32 ext_freq;
330 u32 bank_size;
331 u32 base_address = 0;
332 char *target_name = "Unknown";
333
334 at91sam7_info = t_bank->driver_priv;
335
336 if (at91sam7_info->cidr != 0)
337 {
338 /* flash already configured, update clock and check for protected sectors */
339 flash_bank_t *fb = bank;
340 t_bank = fb;
341
342 while (t_bank)
343 {
344 /* re-calculate master clock frequency */
345 at91sam7_read_clock_info(t_bank);
346
347 /* no timming */
348 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
349
350 /* check protect state */
351 at91sam7_protect_check(t_bank);
352
353 t_bank = fb->next;
354 fb = t_bank;
355 }
356
357 return ERROR_OK;
358 }
359
360 /* Read and parse chip identification register */
361 target_read_u32(target, DBGU_CIDR, &cidr);
362 if (cidr == 0)
363 {
364 LOG_WARNING("Cannot identify target as an AT91SAM");
365 return ERROR_FLASH_OPERATION_FAILED;
366 }
367
368 if (at91sam7_info->flash_autodetection == 0)
369 {
370 /* banks and sectors are already created, based on data from input file */
371 flash_bank_t *fb = bank;
372 t_bank = fb;
373 while (t_bank)
374 {
375 at91sam7_info = t_bank->driver_priv;
376
377 at91sam7_info->cidr = cidr;
378 at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
379 at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
380 at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
381 at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
382 at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
383 at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
384 at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
385 at91sam7_info->cidr_version = cidr&0x001F;
386
387 /* calculate master clock frequency */
388 at91sam7_read_clock_info(t_bank);
389
390 /* no timming */
391 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
392
393 /* check protect state */
394 at91sam7_protect_check(t_bank);
395
396 t_bank = fb->next;
397 fb = t_bank;
398 }
399
400 return ERROR_OK;
401 }
402
403 arch = (cidr>>20)&0x00FF;
404
405 /* check flash size */
406 switch ((cidr>>8)&0x000F)
407 {
408 case FLASH_SIZE_8KB:
409 break;
410
411 case FLASH_SIZE_16KB:
412 banks_num = 1;
413 sectors_num = 8;
414 pages_per_sector = 32;
415 page_size = 64;
416 base_address = 0x00100000;
417 if (arch == 0x70)
418 {
419 num_nvmbits = 2;
420 target_name = "AT91SAM7S161/16";
421 }
422 break;
423
424 case FLASH_SIZE_32KB:
425 banks_num = 1;
426 sectors_num = 8;
427 pages_per_sector = 32;
428 page_size = 128;
429 base_address = 0x00100000;
430 if (arch == 0x70)
431 {
432 num_nvmbits = 2;
433 target_name = "AT91SAM7S321/32";
434 }
435 if (arch == 0x72)
436 {
437 num_nvmbits = 3;
438 target_name = "AT91SAM7SE32";
439 }
440 break;
441
442 case FLASH_SIZE_64KB:
443 banks_num = 1;
444 sectors_num = 16;
445 pages_per_sector = 32;
446 page_size = 128;
447 base_address = 0x00100000;
448 if (arch == 0x70)
449 {
450 num_nvmbits = 2;
451 target_name = "AT91SAM7S64";
452 }
453 break;
454
455 case FLASH_SIZE_128KB:
456 banks_num = 1;
457 sectors_num = 8;
458 pages_per_sector = 64;
459 page_size = 256;
460 base_address = 0x00100000;
461 if (arch == 0x70)
462 {
463 num_nvmbits = 2;
464 target_name = "AT91SAM7S128";
465 }
466 if (arch == 0x71)
467 {
468 num_nvmbits = 3;
469 target_name = "AT91SAM7XC128";
470 }
471 if (arch == 0x72)
472 {
473 num_nvmbits = 3;
474 target_name = "AT91SAM7SE128";
475 }
476 if (arch == 0x75)
477 {
478 num_nvmbits = 3;
479 target_name = "AT91SAM7X128";
480 }
481 break;
482
483 case FLASH_SIZE_256KB:
484 banks_num = 1;
485 sectors_num = 16;
486 pages_per_sector = 64;
487 page_size = 256;
488 base_address = 0x00100000;
489 if (arch == 0x60)
490 {
491 num_nvmbits = 3;
492 target_name = "AT91SAM7A3";
493 }
494 if (arch == 0x70)
495 {
496 num_nvmbits = 2;
497 target_name = "AT91SAM7S256";
498 }
499 if (arch == 0x71)
500 {
501 num_nvmbits = 3;
502 target_name = "AT91SAM7XC256";
503 }
504 if (arch == 0x72)
505 {
506 num_nvmbits = 3;
507 target_name = "AT91SAM7SE256";
508 }
509 if (arch == 0x75)
510 {
511 num_nvmbits = 3;
512 target_name = "AT91SAM7X256";
513 }
514 break;
515
516 case FLASH_SIZE_512KB:
517 banks_num = 2;
518 sectors_num = 16;
519 pages_per_sector = 64;
520 page_size = 256;
521 base_address = 0x00100000;
522 if (arch == 0x70)
523 {
524 num_nvmbits = 2;
525 target_name = "AT91SAM7S512";
526 }
527 if (arch == 0x71)
528 {
529 num_nvmbits = 3;
530 target_name = "AT91SAM7XC512";
531 }
532 if (arch == 0x72)
533 {
534 num_nvmbits = 3;
535 target_name = "AT91SAM7SE512";
536 }
537 if (arch == 0x75)
538 {
539 num_nvmbits = 3;
540 target_name = "AT91SAM7X512";
541 }
542 break;
543
544 case FLASH_SIZE_1024KB:
545 break;
546
547 case FLASH_SIZE_2048KB:
548 break;
549 }
550
551 if (strcmp(target_name, "Unknown") == 0)
552 {
553 LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
554 return ERROR_FLASH_OPERATION_FAILED;
555 }
556
557 ext_freq = at91sam7_info->ext_freq;
558
559 /* calculate bank size */
560 bank_size = sectors_num * pages_per_sector * page_size;
561
562 for (bnk=0; bnk<banks_num; bnk++)
563 {
564 if (bnk > 0)
565 {
566 /* create a new flash bank element */
567 flash_bank_t *fb = malloc(sizeof(flash_bank_t));
568 fb->target = target;
569 fb->driver = &at91sam7_flash;
570 fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
571 fb->next = NULL;
572
573 /* link created bank in 'flash_banks' list and redirect t_bank */
574 t_bank->next = fb;
575 t_bank = fb;
576 }
577
578 t_bank->bank_number = bnk;
579 t_bank->base = base_address + bnk * bank_size;
580 t_bank->size = bank_size;
581 t_bank->chip_width = 0;
582 t_bank->bus_width = 4;
583 t_bank->num_sectors = sectors_num;
584
585 /* allocate sectors */
586 t_bank->sectors = malloc(sectors_num * sizeof(flash_sector_t));
587 for (sec=0; sec<sectors_num; sec++)
588 {
589 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
590 t_bank->sectors[sec].size = pages_per_sector * page_size;
591 t_bank->sectors[sec].is_erased = -1;
592 t_bank->sectors[sec].is_protected = -1;
593 }
594
595 at91sam7_info = t_bank->driver_priv;
596
597 at91sam7_info->cidr = cidr;
598 at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
599 at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
600 at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
601 at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
602 at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
603 at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
604 at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
605 at91sam7_info->cidr_version = cidr&0x001F;
606
607 at91sam7_info->target_name = target_name;
608 at91sam7_info->flashmode = 0;
609 at91sam7_info->ext_freq = ext_freq;
610 at91sam7_info->num_nvmbits = num_nvmbits;
611 at91sam7_info->num_nvmbits_on = 0;
612 at91sam7_info->pagesize = page_size;
613 at91sam7_info->pages_per_sector = pages_per_sector;
614
615 /* calculate master clock frequency */
616 at91sam7_read_clock_info(t_bank);
617
618 /* no timming */
619 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
620
621 /* check protect state */
622 at91sam7_protect_check(t_bank);
623 }
624
625 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
626
627 return ERROR_OK;
628 }
629
630 int at91sam7_erase_check(struct flash_bank_s *bank)
631 {
632 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
633
634 target_t *target = bank->target;
635 u16 retval;
636 u32 blank;
637 u16 fast_check;
638 u8 *buffer;
639 u16 nSector;
640 u16 nByte;
641
642 if (bank->target->state != TARGET_HALTED)
643 {
644 LOG_ERROR("Target not halted");
645 return ERROR_TARGET_NOT_HALTED;
646 }
647
648 /* Configure the flash controller timing */
649 at91sam7_read_clock_info(bank);
650 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
651
652 fast_check = 1;
653 for (nSector=0; nSector<bank->num_sectors; nSector++)
654 {
655 retval = target_blank_check_memory(target, bank->base+bank->sectors[nSector].offset,
656 bank->sectors[nSector].size, &blank);
657 if (retval != ERROR_OK)
658 {
659 fast_check = 0;
660 break;
661 }
662 if (blank == 0xFF)
663 bank->sectors[nSector].is_erased = 1;
664 else
665 bank->sectors[nSector].is_erased = 0;
666 }
667
668 if (fast_check)
669 {
670 return ERROR_OK;
671 }
672
673 LOG_USER("Running slow fallback erase check - add working memory");
674
675 buffer = malloc(bank->sectors[0].size);
676 for (nSector=0; nSector<bank->num_sectors; nSector++)
677 {
678
679 bank->sectors[nSector].is_erased = 1;
680 retval = target->type->read_memory(target, bank->base+bank->sectors[nSector].offset, 4,
681 bank->sectors[nSector].size/4, buffer);
682 if (retval != ERROR_OK)
683 return retval;
684
685 for (nByte=0; nByte<bank->sectors[nSector].size; nByte++)
686 {
687 if (buffer[nByte] != 0xFF)
688 {
689 bank->sectors[nSector].is_erased = 0;
690 break;
691 }
692 }
693 }
694 free(buffer);
695
696 return ERROR_OK;
697 }
698
699 int at91sam7_protect_check(struct flash_bank_s *bank)
700 {
701 u8 lock_pos, gpnvm_pos;
702 u32 status;
703
704 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
705
706 if (at91sam7_info->cidr == 0)
707 {
708 return ERROR_FLASH_BANK_NOT_PROBED;
709 }
710 if (bank->target->state != TARGET_HALTED)
711 {
712 LOG_ERROR("Target not halted");
713 return ERROR_TARGET_NOT_HALTED;
714 }
715
716 status = at91sam7_get_flash_status(bank->target, bank->bank_number);
717 at91sam7_info->lockbits = (status>>16);
718
719 at91sam7_info->num_lockbits_on = 0;
720 for (lock_pos=0; lock_pos<bank->num_sectors; lock_pos++)
721 {
722 if ( ((status>>(16+lock_pos))&(0x0001)) == 1)
723 {
724 at91sam7_info->num_lockbits_on++;
725 bank->sectors[lock_pos].is_protected = 1;
726 }
727 else
728 bank->sectors[lock_pos].is_protected = 0;
729 }
730
731 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
732 status = at91sam7_get_flash_status(bank->target, 0);
733
734 at91sam7_info->securitybit = (status>>4)&0x01;
735 at91sam7_info->nvmbits = (status>>8)&0xFF;
736
737 at91sam7_info->num_nvmbits_on = 0;
738 for (gpnvm_pos=0; gpnvm_pos<at91sam7_info->num_nvmbits; gpnvm_pos++)
739 {
740 if ( ((status>>(8+gpnvm_pos))&(0x01)) == 1)
741 {
742 at91sam7_info->num_nvmbits_on++;
743 }
744 }
745
746 return ERROR_OK;
747 }
748
749 /***************************************************************************************************************************************************************************************
750 # flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]
751 # <ext_freq_khz> - MUST be used if clock is from external source
752 # CAN be used if main oscillator frequency is known
753 # Examples:
754 # flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 25000 ==== RECOMENDED ============
755 # flash bank at91sam7 0 0 0 0 0 0 0 0 0 0 0 0 25000 (auto-detection, except for clock) ==== RECOMENDED ============
756 # flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 0 ==== NOT RECOMENDED !!! ====
757 # flash bank at91sam7 0 0 0 0 0 (old style, full auto-detection) ==== NOT RECOMENDED !!! ====
758 ****************************************************************************************************************************************************************************************/
759 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
760 {
761 flash_bank_t *t_bank = bank;
762 at91sam7_flash_bank_t *at91sam7_info;
763 target_t *target = t_bank->target;
764
765 u32 base_address;
766 u32 bank_size;
767 u32 ext_freq;
768
769 int chip_width;
770 int bus_width;
771 int banks_num;
772 int num_sectors;
773
774 u16 pages_per_sector;
775 u16 page_size;
776 u16 num_nvmbits;
777
778 char *target_name;
779
780 int bnk, sec;
781
782 at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
783 t_bank->driver_priv = at91sam7_info;
784
785 /* part wasn't probed for info yet */
786 at91sam7_info->cidr = 0;
787 at91sam7_info->flashmode = 0;
788 at91sam7_info->ext_freq = 0;
789 at91sam7_info->flash_autodetection = 0;
790
791 if (argc == 14)
792 {
793 ext_freq = atol(args[13]) * 1000;
794 at91sam7_info->ext_freq = ext_freq;
795 }
796
797 if ((argc != 14) ||
798 (atoi(args[4]) == 0) || /* bus width */
799 (atoi(args[8]) == 0) || /* banks number */
800 (atoi(args[9]) == 0) || /* sectors per bank */
801 (atoi(args[10]) == 0) || /* pages per sector */
802 (atoi(args[11]) == 0) || /* page size */
803 (atoi(args[12]) == 0)) /* nvmbits number */
804 {
805 at91sam7_info->flash_autodetection = 1;
806 return ERROR_OK;
807 }
808
809 base_address = strtoul(args[1], NULL, 0);
810 chip_width = atoi(args[3]);
811 bus_width = atoi(args[4]);
812 banks_num = atoi(args[8]);
813 num_sectors = atoi(args[9]);
814 pages_per_sector = atoi(args[10]);
815 page_size = atoi(args[11]);
816 num_nvmbits = atoi(args[12]);
817
818 target_name = calloc(strlen(args[7])+1, sizeof(char));
819 strcpy(target_name, args[7]);
820
821 /* calculate bank size */
822 bank_size = num_sectors * pages_per_sector * page_size;
823
824 for (bnk=0; bnk<banks_num; bnk++)
825 {
826 if (bnk > 0)
827 {
828 /* create a new bank element */
829 flash_bank_t *fb = malloc(sizeof(flash_bank_t));
830 fb->target = target;
831 fb->driver = &at91sam7_flash;
832 fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
833 fb->next = NULL;
834
835 /* link created bank in 'flash_banks' list and redirect t_bank */
836 t_bank->next = fb;
837 t_bank = fb;
838 }
839
840 t_bank->bank_number = bnk;
841 t_bank->base = base_address + bnk * bank_size;
842 t_bank->size = bank_size;
843 t_bank->chip_width = chip_width;
844 t_bank->bus_width = bus_width;
845 t_bank->num_sectors = num_sectors;
846
847 /* allocate sectors */
848 t_bank->sectors = malloc(num_sectors * sizeof(flash_sector_t));
849 for (sec=0; sec<num_sectors; sec++)
850 {
851 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
852 t_bank->sectors[sec].size = pages_per_sector * page_size;
853 t_bank->sectors[sec].is_erased = -1;
854 t_bank->sectors[sec].is_protected = -1;
855 }
856
857 at91sam7_info = t_bank->driver_priv;
858
859 at91sam7_info->target_name = target_name;
860 at91sam7_info->flashmode = 0;
861 at91sam7_info->ext_freq = ext_freq;
862 at91sam7_info->num_nvmbits = num_nvmbits;
863 at91sam7_info->num_nvmbits_on = 0;
864 at91sam7_info->pagesize = page_size;
865 at91sam7_info->pages_per_sector = pages_per_sector;
866 }
867
868 return ERROR_OK;
869 }
870
871 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
872 {
873 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
874 int sec;
875 u32 nbytes, pos;
876 u8 *buffer;
877 u8 erase_all;
878
879 if (at91sam7_info->cidr == 0)
880 {
881 return ERROR_FLASH_BANK_NOT_PROBED;
882 }
883
884 if (bank->target->state != TARGET_HALTED)
885 {
886 LOG_ERROR("Target not halted");
887 return ERROR_TARGET_NOT_HALTED;
888 }
889
890 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
891 {
892 return ERROR_FLASH_SECTOR_INVALID;
893 }
894
895 erase_all = 0;
896 if ((first == 0) && (last == (bank->num_sectors-1)))
897 {
898 erase_all = 1;
899 }
900
901 /* Configure the flash controller timing */
902 at91sam7_read_clock_info(bank);
903 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
904
905 if(erase_all)
906 {
907 if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
908 {
909 return ERROR_FLASH_OPERATION_FAILED;
910 }
911 }
912 else
913 {
914 /* allocate and clean buffer */
915 nbytes = (last - first + 1) * bank->sectors[first].size;
916 buffer = malloc(nbytes * sizeof(u8));
917 for (pos=0; pos<nbytes; pos++)
918 {
919 buffer[pos] = 0xFF;
920 }
921
922 if ( at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK)
923 {
924 return ERROR_FLASH_OPERATION_FAILED;
925 }
926
927 free(buffer);
928 }
929
930 /* mark erased sectors */
931 for (sec=first; sec<=last; sec++)
932 {
933 bank->sectors[sec].is_erased = 1;
934 }
935
936 return ERROR_OK;
937 }
938
939 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
940 {
941 u32 cmd;
942 u32 sector, pagen;
943
944 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
945
946 if (at91sam7_info->cidr == 0)
947 {
948 return ERROR_FLASH_BANK_NOT_PROBED;
949 }
950
951 if (bank->target->state != TARGET_HALTED)
952 {
953 LOG_ERROR("Target not halted");
954 return ERROR_TARGET_NOT_HALTED;
955 }
956
957 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
958 {
959 return ERROR_FLASH_SECTOR_INVALID;
960 }
961
962 /* Configure the flash controller timing */
963 at91sam7_read_clock_info(bank);
964 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
965
966 for (sector=first; sector<=last; sector++)
967 {
968 if (set)
969 cmd = SLB;
970 else
971 cmd = CLB;
972
973 /* if we lock a page from one sector then entire sector will be locked, also,
974 if we unlock a page from a locked sector, entire sector will be unlocked */
975 pagen = sector * at91sam7_info->pages_per_sector;
976
977 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
978 {
979 return ERROR_FLASH_OPERATION_FAILED;
980 }
981 }
982
983 at91sam7_protect_check(bank);
984
985 return ERROR_OK;
986 }
987
988 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
989 {
990 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
991 target_t *target = bank->target;
992 u32 dst_min_alignment, wcount, bytes_remaining = count;
993 u32 first_page, last_page, pagen, buffer_pos;
994
995 if (at91sam7_info->cidr == 0)
996 {
997 return ERROR_FLASH_BANK_NOT_PROBED;
998 }
999
1000 if (bank->target->state != TARGET_HALTED)
1001 {
1002 LOG_ERROR("Target not halted");
1003 return ERROR_TARGET_NOT_HALTED;
1004 }
1005
1006 if (offset + count > bank->size)
1007 return ERROR_FLASH_DST_OUT_OF_BANK;
1008
1009 dst_min_alignment = at91sam7_info->pagesize;
1010
1011 if (offset % dst_min_alignment)
1012 {
1013 LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
1014 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1015 }
1016
1017 if (at91sam7_info->cidr_arch == 0)
1018 return ERROR_FLASH_BANK_NOT_PROBED;
1019
1020 first_page = offset/dst_min_alignment;
1021 last_page = CEIL(offset + count, dst_min_alignment);
1022
1023 LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
1024
1025 /* Configure the flash controller timing */
1026 at91sam7_read_clock_info(bank);
1027 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
1028
1029 for (pagen=first_page; pagen<last_page; pagen++)
1030 {
1031 if (bytes_remaining<dst_min_alignment)
1032 count = bytes_remaining;
1033 else
1034 count = dst_min_alignment;
1035 bytes_remaining -= count;
1036
1037 /* Write one block to the PageWriteBuffer */
1038 buffer_pos = (pagen-first_page)*dst_min_alignment;
1039 wcount = CEIL(count,4);
1040 target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
1041
1042 /* Send Write Page command to Flash Controller */
1043 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
1044 {
1045 return ERROR_FLASH_OPERATION_FAILED;
1046 }
1047 LOG_DEBUG("Write flash bank:%i page number:%i", bank->bank_number, pagen);
1048 }
1049
1050 return ERROR_OK;
1051 }
1052
1053 int at91sam7_probe(struct flash_bank_s *bank)
1054 {
1055 /* we can't probe on an at91sam7
1056 * if this is an at91sam7, it has the configured flash
1057 */
1058 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
1059 int retval;
1060
1061 if (bank->target->state != TARGET_HALTED)
1062 {
1063 LOG_ERROR("Target not halted");
1064 return ERROR_TARGET_NOT_HALTED;
1065 }
1066
1067 retval = at91sam7_read_part_info(bank);
1068 if (retval != ERROR_OK)
1069 return retval;
1070
1071 return ERROR_OK;
1072 }
1073
1074 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
1075 {
1076 int printed;
1077 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
1078
1079 if (at91sam7_info->cidr == 0)
1080 {
1081 return ERROR_FLASH_BANK_NOT_PROBED;
1082 }
1083
1084 printed = snprintf(buf, buf_size,
1085 "\n at91sam7 driver information: Chip is %s\n",
1086 at91sam7_info->target_name);
1087
1088 buf += printed;
1089 buf_size -= printed;
1090
1091 printed = snprintf(buf, buf_size,
1092 " Cidr: 0x%8.8x | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8x\n",
1093 at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc],
1094 at91sam7_info->cidr_version, bank->size);
1095
1096 buf += printed;
1097 buf_size -= printed;
1098
1099 printed = snprintf(buf, buf_size,
1100 " Master clock (estimated): %li KHz | External clock: %li KHz\n",
1101 at91sam7_info->mck_freq / 1000, at91sam7_info->ext_freq / 1000);
1102
1103 buf += printed;
1104 buf_size -= printed;
1105
1106 printed = snprintf(buf, buf_size,
1107 " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i \n",
1108 at91sam7_info->pagesize, bank->num_sectors, at91sam7_info->num_lockbits_on,
1109 at91sam7_info->lockbits, at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
1110
1111 buf += printed;
1112 buf_size -= printed;
1113
1114 printed = snprintf(buf, buf_size,
1115 " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1116 at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
1117 at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
1118
1119 buf += printed;
1120 buf_size -= printed;
1121
1122 return ERROR_OK;
1123 }
1124
1125 /*
1126 * On AT91SAM7S: When the gpnvm bits are set with
1127 * > at91sam7 gpnvm bitnr set
1128 * the changes are not visible in the flash controller status register MC_FSR
1129 * until the processor has been reset.
1130 * On the Olimex board this requires a power cycle.
1131 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1132 * The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1133 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1134 */
1135 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1136 {
1137 flash_bank_t *bank;
1138 int bit;
1139 u8 flashcmd;
1140 u32 status;
1141 at91sam7_flash_bank_t *at91sam7_info;
1142 int retval;
1143
1144 if (argc != 2)
1145 {
1146 command_print(cmd_ctx, "at91sam7 gpnvm <bit> <set|clear>");
1147 return ERROR_OK;
1148 }
1149
1150 bank = get_flash_bank_by_num_noprobe(0);
1151 if (bank == NULL)
1152 {
1153 return ERROR_FLASH_BANK_INVALID;
1154 }
1155 if (bank->driver != &at91sam7_flash)
1156 {
1157 command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
1158 return ERROR_FLASH_BANK_INVALID;
1159 }
1160 if (bank->target->state != TARGET_HALTED)
1161 {
1162 LOG_ERROR("target has to be halted to perform flash operation");
1163 return ERROR_TARGET_NOT_HALTED;
1164 }
1165
1166 if (strcmp(args[1], "set") == 0)
1167 {
1168 flashcmd = SGPB;
1169 }
1170 else if (strcmp(args[1], "clear") == 0)
1171 {
1172 flashcmd = CGPB;
1173 }
1174 else
1175 {
1176 return ERROR_COMMAND_SYNTAX_ERROR;
1177 }
1178
1179 at91sam7_info = bank->driver_priv;
1180 if (at91sam7_info->cidr == 0)
1181 {
1182 retval = at91sam7_read_part_info(bank);
1183 if (retval != ERROR_OK)
1184 {
1185 return retval;
1186 }
1187 }
1188
1189 bit = atoi(args[0]);
1190 if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits))
1191 {
1192 command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[0], at91sam7_info->target_name);
1193 return ERROR_OK;
1194 }
1195
1196 /* Configure the flash controller timing */
1197 at91sam7_read_clock_info(bank);
1198 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
1199
1200 if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
1201 {
1202 return ERROR_FLASH_OPERATION_FAILED;
1203 }
1204
1205 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1206 status = at91sam7_get_flash_status(bank->target, 0);
1207 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n", flashcmd, bit, status);
1208
1209 /* check protect state */
1210 at91sam7_protect_check(bank);
1211
1212 return ERROR_OK;
1213 }

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)