- added patch to solve problem with AT91SAM7SE MCU have 3, rather than just 2 GPNVM...
[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_auto_probe(struct flash_bank_s *bank);
61 int at91sam7_erase_check(struct flash_bank_s *bank);
62 int at91sam7_protect_check(struct flash_bank_s *bank);
63 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size);
64
65 u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane);
66 void at91sam7_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode);
67 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout);
68 int at91sam7_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen);
69 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
70
71 flash_driver_t at91sam7_flash =
72 {
73 .name = "at91sam7",
74 .register_commands = at91sam7_register_commands,
75 .flash_bank_command = at91sam7_flash_bank_command,
76 .erase = at91sam7_erase,
77 .protect = at91sam7_protect,
78 .write = at91sam7_write,
79 .probe = at91sam7_probe,
80 .auto_probe = at91sam7_auto_probe,
81 .erase_check = at91sam7_erase_check,
82 .protect_check = at91sam7_protect_check,
83 .info = at91sam7_info
84 };
85
86 u32 MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
87 u32 MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
88 u32 MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
89
90 char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
91 long NVPSIZ[16] = {
92 0,
93 0x2000, /* 8K */
94 0x4000, /* 16K */
95 0x8000, /* 32K */
96 -1,
97 0x10000, /* 64K */
98 -1,
99 0x20000, /* 128K */
100 -1,
101 0x40000, /* 256K */
102 0x80000, /* 512K */
103 -1,
104 0x100000, /* 1024K */
105 -1,
106 0x200000, /* 2048K */
107 -1
108 };
109
110 long SRAMSIZ[16] = {
111 -1,
112 0x0400, /* 1K */
113 0x0800, /* 2K */
114 -1,
115 0x1c000, /* 112K */
116 0x1000, /* 4K */
117 0x14000, /* 80K */
118 0x28000, /* 160K */
119 0x2000, /* 8K */
120 0x4000, /* 16K */
121 0x8000, /* 32K */
122 0x10000, /* 64K */
123 0x20000, /* 128K */
124 0x40000, /* 256K */
125 0x18000, /* 96K */
126 0x80000, /* 512K */
127 };
128
129 int at91sam7_register_commands(struct command_context_s *cmd_ctx)
130 {
131 command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);
132 register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
133 "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
134
135 return ERROR_OK;
136 }
137
138 u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane)
139 {
140 target_t *target = bank->target;
141 u32 fsr;
142
143 target_read_u32(target, MC_FSR[flashplane], &fsr);
144
145 return fsr;
146 }
147
148 /** Read clock configuration and set at91sam7_info->usec_clocks*/
149 void at91sam7_read_clock_info(flash_bank_t *bank)
150 {
151 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
152 target_t *target = bank->target;
153 u32 mckr, mcfr, pllr;
154 unsigned long tmp = 0, mainfreq;
155 int flashplane;
156
157 /* Read main clock freqency register */
158 target_read_u32(target, CKGR_MCFR, &mcfr);
159 /* Read master clock register */
160 target_read_u32(target, PMC_MCKR, &mckr);
161 /* Read Clock Generator PLL Register */
162 target_read_u32(target, CKGR_PLLR, &pllr);
163
164 at91sam7_info->mck_valid = 0;
165 switch (mckr & PMC_MCKR_CSS)
166 {
167 case 0: /* Slow Clock */
168 at91sam7_info->mck_valid = 1;
169 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
170 tmp = mainfreq;
171 break;
172 case 1: /* Main Clock */
173 if (mcfr & CKGR_MCFR_MAINRDY)
174 {
175 at91sam7_info->mck_valid = 1;
176 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
177 tmp = mainfreq;
178 }
179 break;
180
181 case 2: /* Reserved */
182 break;
183 case 3: /* PLL Clock */
184 if (mcfr & CKGR_MCFR_MAINRDY)
185 {
186 target_read_u32(target, CKGR_PLLR, &pllr);
187 if (!(pllr & CKGR_PLLR_DIV))
188 break; /* 0 Hz */
189 at91sam7_info->mck_valid = 1;
190 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
191 /* Integer arithmetic should have sufficient precision
192 as long as PLL is properly configured. */
193 tmp = mainfreq / (pllr & CKGR_PLLR_DIV) *
194 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
195 }
196 break;
197 }
198
199 /* Prescaler adjust */
200 if (((mckr & PMC_MCKR_PRES) >> 2) == 7)
201 at91sam7_info->mck_valid = 0;
202 else
203 at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
204
205 /* Forget old flash timing */
206 for (flashplane = 0; flashplane<at91sam7_info->num_planes; flashplane++)
207 {
208 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_NONE);
209 }
210 }
211
212 /* Setup the timimg registers for nvbits or normal flash */
213 void at91sam7_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode)
214 {
215 u32 fmr, fmcn = 0, fws = 0;
216 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
217 target_t *target = bank->target;
218
219 if (mode && (mode != at91sam7_info->flashmode[flashplane]))
220 {
221 /* Always round up (ceil) */
222 if (mode==FMR_TIMING_NVBITS)
223 {
224 if (at91sam7_info->cidr_arch == 0x60)
225 {
226 /* AT91SAM7A3 uses master clocks in 100 ns */
227 fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
228 }
229 else
230 {
231 /* master clocks in 1uS for ARCH 0x7 types */
232 fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
233 }
234 }
235 else if (mode==FMR_TIMING_FLASH)
236 /* main clocks in 1.5uS */
237 fmcn = (at91sam7_info->mck_freq/666666ul)+1;
238
239 /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
240 if (at91sam7_info->mck_freq <= 33333ul)
241 fmcn = 0;
242 /* Only allow fws=0 if clock frequency is < 30 MHz. */
243 if (at91sam7_info->mck_freq > 30000000ul)
244 fws = 1;
245
246 DEBUG("fmcn[%i]: %i", flashplane, fmcn);
247 fmr = fmcn << 16 | fws << 8;
248 target_write_u32(target, MC_FMR[flashplane], fmr);
249 }
250
251 at91sam7_info->flashmode[flashplane] = mode;
252 }
253
254 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout)
255 {
256 u32 status;
257
258 while ((!((status = at91sam7_get_flash_status(bank,flashplane)) & waitbits)) && (timeout-- > 0))
259 {
260 DEBUG("status[%i]: 0x%x", flashplane, status);
261 usleep(1000);
262 }
263
264 DEBUG("status[%i]: 0x%x", flashplane, status);
265
266 if (status & 0x0C)
267 {
268 ERROR("status register: 0x%x", status);
269 if (status & 0x4)
270 ERROR("Lock Error Bit Detected, Operation Abort");
271 if (status & 0x8)
272 ERROR("Invalid command and/or bad keyword, Operation Abort");
273 if (status & 0x10)
274 ERROR("Security Bit Set, Operation Abort");
275 }
276
277 return status;
278 }
279
280
281 /* Send one command to the AT91SAM flash controller */
282 int at91sam7_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen)
283 {
284 u32 fcr;
285 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
286 target_t *target = bank->target;
287
288 fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd;
289 target_write_u32(target, MC_FCR[flashplane], fcr);
290 DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen);
291
292 if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
293 {
294 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
295 if (at91sam7_wait_status_busy(bank, flashplane, MC_FSR_EOL, 10)&0x0C)
296 {
297 return ERROR_FLASH_OPERATION_FAILED;
298 }
299 return ERROR_OK;
300 }
301
302 if (at91sam7_wait_status_busy(bank, flashplane, MC_FSR_FRDY, 10)&0x0C)
303 {
304 return ERROR_FLASH_OPERATION_FAILED;
305 }
306 return ERROR_OK;
307 }
308
309 /* Read device id register, main clock frequency register and fill in driver info structure */
310 int at91sam7_read_part_info(struct flash_bank_s *bank)
311 {
312 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
313 target_t *target = bank->target;
314 u32 cidr, status;
315 int sectornum;
316
317 if (bank->target->state != TARGET_HALTED)
318 {
319 return ERROR_TARGET_NOT_HALTED;
320 }
321
322 /* Read and parse chip identification register */
323 target_read_u32(target, DBGU_CIDR, &cidr);
324
325 if (cidr == 0)
326 {
327 WARNING("Cannot identify target as an AT91SAM");
328 return ERROR_FLASH_OPERATION_FAILED;
329 }
330
331 at91sam7_info->cidr = cidr;
332 at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
333 at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
334 at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
335 at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
336 at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
337 at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
338 at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
339 at91sam7_info->cidr_version = cidr&0x001F;
340 bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
341 at91sam7_info->target_name = "Unknown";
342
343 /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
344 if (NVPSIZ[at91sam7_info->cidr_nvpsiz]<0x80000) /* Flash size less than 512K, one flash plane */
345 {
346 bank->num_sectors = 1;
347 bank->sectors = malloc(sizeof(flash_sector_t));
348 bank->sectors[0].offset = 0;
349 bank->sectors[0].size = bank->size;
350 bank->sectors[0].is_erased = -1;
351 bank->sectors[0].is_protected = -1;
352 }
353 else /* Flash size 512K or larger, several flash planes */
354 {
355 bank->num_sectors = NVPSIZ[at91sam7_info->cidr_nvpsiz]/0x40000;
356 bank->sectors = malloc(bank->num_sectors*sizeof(flash_sector_t));
357 for (sectornum=0; sectornum<bank->num_sectors; sectornum++)
358 {
359 bank->sectors[sectornum].offset = sectornum*0x40000;
360 bank->sectors[sectornum].size = 0x40000;
361 bank->sectors[sectornum].is_erased = -1;
362 bank->sectors[sectornum].is_protected = -1;
363 }
364 }
365
366
367
368 DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
369
370 /* Read main and master clock freqency register */
371 at91sam7_read_clock_info(bank);
372
373 at91sam7_info->num_planes = 1;
374 status = at91sam7_get_flash_status(bank, 0);
375 at91sam7_info->securitybit = (status>>4)&0x01;
376 at91sam7_protect_check(bank); /* TODO Check the protect check */
377
378 if (at91sam7_info->cidr_arch == 0x70 )
379 {
380 at91sam7_info->num_nvmbits = 2;
381 at91sam7_info->nvmbits = (status>>8)&0x03;
382 bank->base = 0x100000;
383 bank->bus_width = 4;
384 if (bank->size==0x80000) /* AT91SAM7S512 */
385 {
386 at91sam7_info->target_name = "AT91SAM7S512";
387 at91sam7_info->num_planes = 2;
388 if (at91sam7_info->num_planes != bank->num_sectors)
389 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
390 at91sam7_info->num_lockbits = 2*16;
391 at91sam7_info->pagesize = 256;
392 at91sam7_info->pages_in_lockregion = 64;
393 at91sam7_info->num_pages = 2*16*64;
394 }
395 if (bank->size==0x40000) /* AT91SAM7S256 */
396 {
397 at91sam7_info->target_name = "AT91SAM7S256";
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) /* AT91SAM7S128 */
404 {
405 at91sam7_info->target_name = "AT91SAM7S128";
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 if (bank->size==0x10000) /* AT91SAM7S64 */
412 {
413 at91sam7_info->target_name = "AT91SAM7S64";
414 at91sam7_info->num_lockbits = 16;
415 at91sam7_info->pagesize = 128;
416 at91sam7_info->pages_in_lockregion = 32;
417 at91sam7_info->num_pages = 16*32;
418 }
419 if (bank->size==0x08000) /* AT91SAM7S321/32 */
420 {
421 at91sam7_info->target_name = "AT91SAM7S321/32";
422 at91sam7_info->num_lockbits = 8;
423 at91sam7_info->pagesize = 128;
424 at91sam7_info->pages_in_lockregion = 32;
425 at91sam7_info->num_pages = 8*32;
426 }
427
428 return ERROR_OK;
429 }
430
431 if (at91sam7_info->cidr_arch == 0x71 )
432 {
433 at91sam7_info->num_nvmbits = 3;
434 at91sam7_info->nvmbits = (status>>8)&0x07;
435 bank->base = 0x100000;
436 bank->bus_width = 4;
437 if (bank->size==0x80000) /* AT91SAM7XC512 */
438 {
439 at91sam7_info->target_name = "AT91SAM7XC512";
440 at91sam7_info->num_planes = 2;
441 if (at91sam7_info->num_planes != bank->num_sectors)
442 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
443 at91sam7_info->num_lockbits = 2*16;
444 at91sam7_info->pagesize = 256;
445 at91sam7_info->pages_in_lockregion = 64;
446 at91sam7_info->num_pages = 2*16*64;
447 }
448 if (bank->size==0x40000) /* AT91SAM7XC256 */
449 {
450 at91sam7_info->target_name = "AT91SAM7XC256";
451 at91sam7_info->num_lockbits = 16;
452 at91sam7_info->pagesize = 256;
453 at91sam7_info->pages_in_lockregion = 64;
454 at91sam7_info->num_pages = 16*64;
455 }
456 if (bank->size==0x20000) /* AT91SAM7XC128 */
457 {
458 at91sam7_info->target_name = "AT91SAM7XC128";
459 at91sam7_info->num_lockbits = 8;
460 at91sam7_info->pagesize = 256;
461 at91sam7_info->pages_in_lockregion = 64;
462 at91sam7_info->num_pages = 8*64;
463 }
464
465 return ERROR_OK;
466 }
467
468 if (at91sam7_info->cidr_arch == 0x72 )
469 {
470 at91sam7_info->num_nvmbits = 3;
471 at91sam7_info->nvmbits = (status>>8)&0x07;
472 bank->base = 0x100000;
473 bank->bus_width = 4;
474 if (bank->size==0x80000) /* AT91SAM7SE512 */
475 {
476 at91sam7_info->target_name = "AT91SAM7SE512";
477 at91sam7_info->num_planes = 2;
478 if (at91sam7_info->num_planes != bank->num_sectors)
479 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
480 at91sam7_info->num_lockbits = 32;
481 at91sam7_info->pagesize = 256;
482 at91sam7_info->pages_in_lockregion = 64;
483 at91sam7_info->num_pages = 32*64;
484 }
485 if (bank->size==0x40000)
486 {
487 at91sam7_info->target_name = "AT91SAM7SE256";
488 at91sam7_info->num_lockbits = 16;
489 at91sam7_info->pagesize = 256;
490 at91sam7_info->pages_in_lockregion = 64;
491 at91sam7_info->num_pages = 16*64;
492 }
493 if (bank->size==0x08000)
494 {
495 at91sam7_info->target_name = "AT91SAM7SE32";
496 at91sam7_info->num_lockbits = 8;
497 at91sam7_info->pagesize = 128;
498 at91sam7_info->pages_in_lockregion = 32;
499 at91sam7_info->num_pages = 8*32;
500 }
501
502 return ERROR_OK;
503 }
504
505 if (at91sam7_info->cidr_arch == 0x75 )
506 {
507 at91sam7_info->num_nvmbits = 3;
508 at91sam7_info->nvmbits = (status>>8)&0x07;
509 bank->base = 0x100000;
510 bank->bus_width = 4;
511 if (bank->size==0x80000) /* AT91SAM7X512 */
512 {
513 at91sam7_info->target_name = "AT91SAM7X512";
514 at91sam7_info->num_planes = 2;
515 if (at91sam7_info->num_planes != bank->num_sectors)
516 WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
517 at91sam7_info->num_lockbits = 32;
518 at91sam7_info->pagesize = 256;
519 at91sam7_info->pages_in_lockregion = 64;
520 at91sam7_info->num_pages = 2*16*64;
521 DEBUG("Support for AT91SAM7X512 is experimental in this version!");
522 }
523 if (bank->size==0x40000) /* AT91SAM7X256 */
524 {
525 at91sam7_info->target_name = "AT91SAM7X256";
526 at91sam7_info->num_lockbits = 16;
527 at91sam7_info->pagesize = 256;
528 at91sam7_info->pages_in_lockregion = 64;
529 at91sam7_info->num_pages = 16*64;
530 }
531 if (bank->size==0x20000) /* AT91SAM7X128 */
532 {
533 at91sam7_info->target_name = "AT91SAM7X128";
534 at91sam7_info->num_lockbits = 8;
535 at91sam7_info->pagesize = 256;
536 at91sam7_info->pages_in_lockregion = 64;
537 at91sam7_info->num_pages = 8*64;
538 }
539
540 return ERROR_OK;
541 }
542
543 if (at91sam7_info->cidr_arch == 0x60 )
544 {
545 at91sam7_info->num_nvmbits = 3;
546 at91sam7_info->nvmbits = (status>>8)&0x07;
547 bank->base = 0x100000;
548 bank->bus_width = 4;
549
550 if (bank->size == 0x40000) /* AT91SAM7A3 */
551 {
552 at91sam7_info->target_name = "AT91SAM7A3";
553 at91sam7_info->num_lockbits = 16;
554 at91sam7_info->pagesize = 256;
555 at91sam7_info->pages_in_lockregion = 16;
556 at91sam7_info->num_pages = 16*64;
557 }
558 return ERROR_OK;
559 }
560
561 WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
562
563 return ERROR_OK;
564 }
565
566 int at91sam7_erase_check(struct flash_bank_s *bank)
567 {
568 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
569
570 if (!at91sam7_info->working_area_size)
571 {
572 }
573 else
574 {
575 }
576
577 return ERROR_OK;
578 }
579
580 int at91sam7_protect_check(struct flash_bank_s *bank)
581 {
582 u32 status;
583 int flashplane;
584
585 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
586
587 if (at91sam7_info->cidr == 0)
588 {
589 at91sam7_read_part_info(bank);
590 }
591
592 if (at91sam7_info->cidr == 0)
593 {
594 WARNING("Cannot identify target as an AT91SAM");
595 return ERROR_FLASH_OPERATION_FAILED;
596 }
597
598 for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
599 {
600 status = at91sam7_get_flash_status(bank, flashplane);
601 at91sam7_info->lockbits[flashplane] = (status >> 16);
602 }
603
604 return ERROR_OK;
605 }
606
607 /* flash_bank at91sam7 0 0 0 0 <target#>
608 */
609 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
610 {
611 at91sam7_flash_bank_t *at91sam7_info;
612 int i;
613
614 if (argc < 6)
615 {
616 WARNING("incomplete flash_bank at91sam7 configuration");
617 return ERROR_FLASH_BANK_INVALID;
618 }
619
620 at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
621 bank->driver_priv = at91sam7_info;
622 at91sam7_info->probed = 0;
623
624 /* part wasn't probed for info yet */
625 at91sam7_info->cidr = 0;
626 for (i=0;i<4;i++)
627 at91sam7_info->flashmode[i]=0;
628
629 return ERROR_OK;
630 }
631
632 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
633 {
634 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
635 u8 flashplane;
636
637 if (bank->target->state != TARGET_HALTED)
638 {
639 return ERROR_TARGET_NOT_HALTED;
640 }
641
642 if (at91sam7_info->cidr == 0)
643 {
644 at91sam7_read_part_info(bank);
645 }
646
647 if (at91sam7_info->cidr == 0)
648 {
649 WARNING("Cannot identify target as an AT91SAM");
650 return ERROR_FLASH_OPERATION_FAILED;
651 }
652
653 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
654 {
655 if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
656 {
657 WARNING("Sector numbers based on lockbit count, probably a deprecated script");
658 last = bank->num_sectors-1;
659 }
660 else return ERROR_FLASH_SECTOR_INVALID;
661 }
662
663 /* Configure the flash controller timing */
664 at91sam7_read_clock_info(bank);
665 for (flashplane = first; flashplane<=last; flashplane++)
666 {
667 /* Configure the flash controller timing */
668 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
669 if (at91sam7_flash_command(bank, flashplane, EA, 0) != ERROR_OK)
670 {
671 return ERROR_FLASH_OPERATION_FAILED;
672 }
673 }
674 return ERROR_OK;
675
676 }
677
678 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
679 {
680 u32 cmd, pagen;
681 u8 flashplane;
682 int lockregion;
683
684 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
685
686 if (bank->target->state != TARGET_HALTED)
687 {
688 return ERROR_TARGET_NOT_HALTED;
689 }
690
691 if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
692 {
693 return ERROR_FLASH_SECTOR_INVALID;
694 }
695
696 if (at91sam7_info->cidr == 0)
697 {
698 at91sam7_read_part_info(bank);
699 }
700
701 if (at91sam7_info->cidr == 0)
702 {
703 WARNING("Cannot identify target as an AT91SAM");
704 return ERROR_FLASH_OPERATION_FAILED;
705 }
706
707 at91sam7_read_clock_info(bank);
708
709 for (lockregion=first;lockregion<=last;lockregion++)
710 {
711 pagen = lockregion*at91sam7_info->pages_in_lockregion;
712 flashplane = (pagen>>10)&0x03;
713 /* Configure the flash controller timing */
714 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_NVBITS);
715
716 if (set)
717 cmd = SLB;
718 else
719 cmd = CLB;
720
721 if (at91sam7_flash_command(bank, flashplane, cmd, pagen) != ERROR_OK)
722 {
723 return ERROR_FLASH_OPERATION_FAILED;
724 }
725 }
726
727 at91sam7_protect_check(bank);
728
729 return ERROR_OK;
730 }
731
732
733 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
734 {
735 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
736 target_t *target = bank->target;
737 u32 dst_min_alignment, wcount, bytes_remaining = count;
738 u32 first_page, last_page, pagen, buffer_pos;
739 u8 flashplane;
740
741 if (bank->target->state != TARGET_HALTED)
742 {
743 return ERROR_TARGET_NOT_HALTED;
744 }
745
746 if (at91sam7_info->cidr == 0)
747 {
748 at91sam7_read_part_info(bank);
749 }
750
751 if (at91sam7_info->cidr == 0)
752 {
753 WARNING("Cannot identify target as an AT91SAM");
754 return ERROR_FLASH_OPERATION_FAILED;
755 }
756
757 if (offset + count > bank->size)
758 return ERROR_FLASH_DST_OUT_OF_BANK;
759
760 dst_min_alignment = at91sam7_info->pagesize;
761
762 if (offset % dst_min_alignment)
763 {
764 WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
765 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
766 }
767
768 if (at91sam7_info->cidr_arch == 0)
769 return ERROR_FLASH_BANK_NOT_PROBED;
770
771 first_page = offset/dst_min_alignment;
772 last_page = CEIL(offset + count, dst_min_alignment);
773
774 DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
775
776 at91sam7_read_clock_info(bank);
777
778 for (pagen=first_page; pagen<last_page; pagen++)
779 {
780 if (bytes_remaining<dst_min_alignment)
781 count = bytes_remaining;
782 else
783 count = dst_min_alignment;
784 bytes_remaining -= count;
785
786 /* Write one block to the PageWriteBuffer */
787 buffer_pos = (pagen-first_page)*dst_min_alignment;
788 wcount = CEIL(count,4);
789 target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
790 flashplane = (pagen>>10)&0x3;
791
792 /* Configure the flash controller timing */
793 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
794 /* Send Write Page command to Flash Controller */
795 if (at91sam7_flash_command(bank, flashplane, WP, pagen) != ERROR_OK)
796 {
797 return ERROR_FLASH_OPERATION_FAILED;
798 }
799 DEBUG("Write flash plane:%i page number:%i", flashplane, pagen);
800 }
801
802 return ERROR_OK;
803 }
804
805
806 int at91sam7_probe(struct flash_bank_s *bank)
807 {
808 /* we can't probe on an at91sam7
809 * if this is an at91sam7, it has the configured flash
810 */
811 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
812 at91sam7_info->probed = 0;
813
814 if (at91sam7_info->cidr == 0)
815 {
816 at91sam7_read_part_info(bank);
817 }
818
819 if (at91sam7_info->cidr == 0)
820 {
821 WARNING("Cannot identify target as an AT91SAM");
822 return ERROR_FLASH_OPERATION_FAILED;
823 }
824
825 at91sam7_info->probed = 1;
826
827 return ERROR_OK;
828 }
829
830
831 int at91sam7_auto_probe(struct flash_bank_s *bank)
832 {
833 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
834 if (at91sam7_info->probed)
835 return ERROR_OK;
836 return at91sam7_probe(bank);
837 }
838
839 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
840 {
841 int printed, flashplane;
842 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
843
844 at91sam7_read_part_info(bank);
845
846 if (at91sam7_info->cidr == 0)
847 {
848 printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
849 buf += printed;
850 buf_size -= printed;
851 return ERROR_FLASH_OPERATION_FAILED;
852 }
853
854 printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
855 buf += printed;
856 buf_size -= printed;
857
858 printed = snprintf(buf, buf_size, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n",
859 at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc], at91sam7_info->cidr_version, bank->size);
860 buf += printed;
861 buf_size -= printed;
862
863 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
864 buf += printed;
865 buf_size -= printed;
866
867 if (at91sam7_info->num_planes>1) {
868 printed = snprintf(buf, buf_size, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n",
869 at91sam7_info->num_planes, at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->num_pages/at91sam7_info->num_lockbits);
870 buf += printed;
871 buf_size -= printed;
872 for (flashplane=0; flashplane<at91sam7_info->num_planes; flashplane++)
873 {
874 printed = snprintf(buf, buf_size, "lockbits[%i]: 0x%4.4x, ", flashplane, at91sam7_info->lockbits[flashplane]);
875 buf += printed;
876 buf_size -= printed;
877 }
878 }
879 else
880 if (at91sam7_info->num_lockbits>0) {
881 printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n",
882 at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->lockbits[0], at91sam7_info->num_pages/at91sam7_info->num_lockbits);
883 buf += printed;
884 buf_size -= printed;
885 }
886
887 printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
888 buf += printed;
889 buf_size -= printed;
890
891 return ERROR_OK;
892 }
893
894 /*
895 * On AT91SAM7S: When the gpnvm bits are set with
896 * > at91sam7 gpnvm 0 bitnr set
897 * the changes are not visible in the flash controller status register MC_FSR
898 * until the processor has been reset.
899 * On the Olimex board this requires a power cycle.
900 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
901 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
902 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
903 */
904 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
905 {
906 flash_bank_t *bank;
907 int bit;
908 u8 flashcmd;
909 u32 status;
910 char *value;
911 at91sam7_flash_bank_t *at91sam7_info;
912
913 if (argc < 3)
914 {
915 command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
916 return ERROR_OK;
917 }
918
919 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
920 bit = atoi(args[1]);
921 value = args[2];
922
923 if (!bank)
924 {
925 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
926 return ERROR_OK;
927 }
928
929 at91sam7_info = bank->driver_priv;
930
931 if (bank->target->state != TARGET_HALTED)
932 {
933 return ERROR_TARGET_NOT_HALTED;
934 }
935
936 if (at91sam7_info->cidr == 0)
937 {
938 at91sam7_read_part_info(bank);
939 }
940
941 if (at91sam7_info->cidr == 0)
942 {
943 WARNING("Cannot identify target as an AT91SAM");
944 return ERROR_FLASH_OPERATION_FAILED;
945 }
946
947 if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
948 {
949 command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
950 return ERROR_OK;
951 }
952
953 if (strcmp(value, "set") == 0)
954 {
955 flashcmd = SGPB;
956 }
957 else if (strcmp(value, "clear") == 0)
958 {
959 flashcmd = CGPB;
960 }
961 else
962 {
963 command_print(cmd_ctx, "usage: at91sam7 gpnvm <num> <bit> <set|clear>");
964 return ERROR_OK;
965 }
966
967 /* Configure the flash controller timing */
968 at91sam7_read_clock_info(bank);
969 at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
970
971 if (at91sam7_flash_command(bank, 0, flashcmd, (u16)(bit)) != ERROR_OK)
972 {
973 return ERROR_FLASH_OPERATION_FAILED;
974 }
975
976 status = at91sam7_get_flash_status(bank, 0);
977 DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
978 at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
979
980 return ERROR_OK;
981 }

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)