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

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)