fixed not halted error messages
[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_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 LOG_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 LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
261 usleep(1000);
262 }
263
264 LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
265
266 if (status & 0x0C)
267 {
268 LOG_ERROR("status register: 0x%x", status);
269 if (status & 0x4)
270 LOG_ERROR("Lock Error Bit Detected, Operation Abort");
271 if (status & 0x8)
272 LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
273 if (status & 0x10)
274 LOG_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 LOG_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 (at91sam7_info->cidr != 0)
318 return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
319
320 /* Read and parse chip identification register */
321 target_read_u32(target, DBGU_CIDR, &cidr);
322
323 if (cidr == 0)
324 {
325 LOG_WARNING("Cannot identify target as an AT91SAM");
326 return ERROR_FLASH_OPERATION_FAILED;
327 }
328
329 at91sam7_info->cidr = cidr;
330 at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
331 at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
332 at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
333 at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
334 at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
335 at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
336 at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
337 at91sam7_info->cidr_version = cidr&0x001F;
338 bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz];
339 at91sam7_info->target_name = "Unknown";
340
341 /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
342 if (NVPSIZ[at91sam7_info->cidr_nvpsiz]<0x80000) /* Flash size less than 512K, one flash plane */
343 {
344 bank->num_sectors = 1;
345 bank->sectors = malloc(sizeof(flash_sector_t));
346 bank->sectors[0].offset = 0;
347 bank->sectors[0].size = bank->size;
348 bank->sectors[0].is_erased = -1;
349 bank->sectors[0].is_protected = -1;
350 }
351 else /* Flash size 512K or larger, several flash planes */
352 {
353 bank->num_sectors = NVPSIZ[at91sam7_info->cidr_nvpsiz]/0x40000;
354 bank->sectors = malloc(bank->num_sectors*sizeof(flash_sector_t));
355 for (sectornum=0; sectornum<bank->num_sectors; sectornum++)
356 {
357 bank->sectors[sectornum].offset = sectornum*0x40000;
358 bank->sectors[sectornum].size = 0x40000;
359 bank->sectors[sectornum].is_erased = -1;
360 bank->sectors[sectornum].is_protected = -1;
361 }
362 }
363
364
365
366 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
367
368 /* Read main and master clock freqency register */
369 at91sam7_read_clock_info(bank);
370
371 at91sam7_info->num_planes = 1;
372 status = at91sam7_get_flash_status(bank, 0);
373 at91sam7_info->securitybit = (status>>4)&0x01;
374 at91sam7_protect_check(bank); /* TODO Check the protect check */
375
376 if (at91sam7_info->cidr_arch == 0x70 )
377 {
378 at91sam7_info->num_nvmbits = 2;
379 at91sam7_info->nvmbits = (status>>8)&0x03;
380 bank->base = 0x100000;
381 bank->bus_width = 4;
382 if (bank->size==0x80000) /* AT91SAM7S512 */
383 {
384 at91sam7_info->target_name = "AT91SAM7S512";
385 at91sam7_info->num_planes = 2;
386 if (at91sam7_info->num_planes != bank->num_sectors)
387 LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
388 at91sam7_info->num_lockbits = 2*16;
389 at91sam7_info->pagesize = 256;
390 at91sam7_info->pages_in_lockregion = 64;
391 at91sam7_info->num_pages = 2*16*64;
392 }
393 if (bank->size==0x40000) /* AT91SAM7S256 */
394 {
395 at91sam7_info->target_name = "AT91SAM7S256";
396 at91sam7_info->num_lockbits = 16;
397 at91sam7_info->pagesize = 256;
398 at91sam7_info->pages_in_lockregion = 64;
399 at91sam7_info->num_pages = 16*64;
400 }
401 if (bank->size==0x20000) /* AT91SAM7S128 */
402 {
403 at91sam7_info->target_name = "AT91SAM7S128";
404 at91sam7_info->num_lockbits = 8;
405 at91sam7_info->pagesize = 256;
406 at91sam7_info->pages_in_lockregion = 64;
407 at91sam7_info->num_pages = 8*64;
408 }
409 if (bank->size==0x10000) /* AT91SAM7S64 */
410 {
411 at91sam7_info->target_name = "AT91SAM7S64";
412 at91sam7_info->num_lockbits = 16;
413 at91sam7_info->pagesize = 128;
414 at91sam7_info->pages_in_lockregion = 32;
415 at91sam7_info->num_pages = 16*32;
416 }
417 if (bank->size==0x08000) /* AT91SAM7S321/32 */
418 {
419 at91sam7_info->target_name = "AT91SAM7S321/32";
420 at91sam7_info->num_lockbits = 8;
421 at91sam7_info->pagesize = 128;
422 at91sam7_info->pages_in_lockregion = 32;
423 at91sam7_info->num_pages = 8*32;
424 }
425
426 return ERROR_OK;
427 }
428
429 if (at91sam7_info->cidr_arch == 0x71 )
430 {
431 at91sam7_info->num_nvmbits = 3;
432 at91sam7_info->nvmbits = (status>>8)&0x07;
433 bank->base = 0x100000;
434 bank->bus_width = 4;
435 if (bank->size==0x80000) /* AT91SAM7XC512 */
436 {
437 at91sam7_info->target_name = "AT91SAM7XC512";
438 at91sam7_info->num_planes = 2;
439 if (at91sam7_info->num_planes != bank->num_sectors)
440 LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
441 at91sam7_info->num_lockbits = 2*16;
442 at91sam7_info->pagesize = 256;
443 at91sam7_info->pages_in_lockregion = 64;
444 at91sam7_info->num_pages = 2*16*64;
445 }
446 if (bank->size==0x40000) /* AT91SAM7XC256 */
447 {
448 at91sam7_info->target_name = "AT91SAM7XC256";
449 at91sam7_info->num_lockbits = 16;
450 at91sam7_info->pagesize = 256;
451 at91sam7_info->pages_in_lockregion = 64;
452 at91sam7_info->num_pages = 16*64;
453 }
454 if (bank->size==0x20000) /* AT91SAM7XC128 */
455 {
456 at91sam7_info->target_name = "AT91SAM7XC128";
457 at91sam7_info->num_lockbits = 8;
458 at91sam7_info->pagesize = 256;
459 at91sam7_info->pages_in_lockregion = 64;
460 at91sam7_info->num_pages = 8*64;
461 }
462
463 return ERROR_OK;
464 }
465
466 if (at91sam7_info->cidr_arch == 0x72 )
467 {
468 at91sam7_info->num_nvmbits = 3;
469 at91sam7_info->nvmbits = (status>>8)&0x07;
470 bank->base = 0x100000;
471 bank->bus_width = 4;
472 if (bank->size==0x80000) /* AT91SAM7SE512 */
473 {
474 at91sam7_info->target_name = "AT91SAM7SE512";
475 at91sam7_info->num_planes = 2;
476 if (at91sam7_info->num_planes != bank->num_sectors)
477 LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
478 at91sam7_info->num_lockbits = 32;
479 at91sam7_info->pagesize = 256;
480 at91sam7_info->pages_in_lockregion = 64;
481 at91sam7_info->num_pages = 32*64;
482 }
483 if (bank->size==0x40000)
484 {
485 at91sam7_info->target_name = "AT91SAM7SE256";
486 at91sam7_info->num_lockbits = 16;
487 at91sam7_info->pagesize = 256;
488 at91sam7_info->pages_in_lockregion = 64;
489 at91sam7_info->num_pages = 16*64;
490 }
491 if (bank->size==0x08000)
492 {
493 at91sam7_info->target_name = "AT91SAM7SE32";
494 at91sam7_info->num_lockbits = 8;
495 at91sam7_info->pagesize = 128;
496 at91sam7_info->pages_in_lockregion = 32;
497 at91sam7_info->num_pages = 8*32;
498 }
499
500 return ERROR_OK;
501 }
502
503 if (at91sam7_info->cidr_arch == 0x75 )
504 {
505 at91sam7_info->num_nvmbits = 3;
506 at91sam7_info->nvmbits = (status>>8)&0x07;
507 bank->base = 0x100000;
508 bank->bus_width = 4;
509 if (bank->size==0x80000) /* AT91SAM7X512 */
510 {
511 at91sam7_info->target_name = "AT91SAM7X512";
512 at91sam7_info->num_planes = 2;
513 if (at91sam7_info->num_planes != bank->num_sectors)
514 LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
515 at91sam7_info->num_lockbits = 32;
516 at91sam7_info->pagesize = 256;
517 at91sam7_info->pages_in_lockregion = 64;
518 at91sam7_info->num_pages = 2*16*64;
519 LOG_DEBUG("Support for AT91SAM7X512 is experimental in this version!");
520 }
521 if (bank->size==0x40000) /* AT91SAM7X256 */
522 {
523 at91sam7_info->target_name = "AT91SAM7X256";
524 at91sam7_info->num_lockbits = 16;
525 at91sam7_info->pagesize = 256;
526 at91sam7_info->pages_in_lockregion = 64;
527 at91sam7_info->num_pages = 16*64;
528 }
529 if (bank->size==0x20000) /* AT91SAM7X128 */
530 {
531 at91sam7_info->target_name = "AT91SAM7X128";
532 at91sam7_info->num_lockbits = 8;
533 at91sam7_info->pagesize = 256;
534 at91sam7_info->pages_in_lockregion = 64;
535 at91sam7_info->num_pages = 8*64;
536 }
537
538 return ERROR_OK;
539 }
540
541 if (at91sam7_info->cidr_arch == 0x60 )
542 {
543 at91sam7_info->num_nvmbits = 3;
544 at91sam7_info->nvmbits = (status>>8)&0x07;
545 bank->base = 0x100000;
546 bank->bus_width = 4;
547
548 if (bank->size == 0x40000) /* AT91SAM7A3 */
549 {
550 at91sam7_info->target_name = "AT91SAM7A3";
551 at91sam7_info->num_lockbits = 16;
552 at91sam7_info->pagesize = 256;
553 at91sam7_info->pages_in_lockregion = 16;
554 at91sam7_info->num_pages = 16*64;
555 }
556 return ERROR_OK;
557 }
558
559 LOG_WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
560 return ERROR_OK;
561 }
562
563 int at91sam7_erase_check(struct flash_bank_s *bank)
564 {
565 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
566
567 if (!at91sam7_info->working_area_size)
568 {
569 }
570 else
571 {
572 }
573
574 return ERROR_OK;
575 }
576
577 int at91sam7_protect_check(struct flash_bank_s *bank)
578 {
579 u32 status;
580 int flashplane;
581
582 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
583
584 if (at91sam7_info->cidr == 0)
585 {
586 return ERROR_FLASH_BANK_NOT_PROBED;
587 }
588
589 if (bank->target->state != TARGET_HALTED)
590 {
591 LOG_ERROR("Target not halted");
592 return ERROR_TARGET_NOT_HALTED;
593 }
594
595 for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
596 {
597 status = at91sam7_get_flash_status(bank, flashplane);
598 at91sam7_info->lockbits[flashplane] = (status >> 16);
599 }
600
601 return ERROR_OK;
602 }
603
604 /* flash_bank at91sam7 0 0 0 0 <target#>
605 */
606 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
607 {
608 at91sam7_flash_bank_t *at91sam7_info;
609 int i;
610
611 if (argc < 6)
612 {
613 LOG_WARNING("incomplete flash_bank at91sam7 configuration");
614 return ERROR_FLASH_BANK_INVALID;
615 }
616
617 at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
618 bank->driver_priv = at91sam7_info;
619
620 /* part wasn't probed for info yet */
621 at91sam7_info->cidr = 0;
622 for (i=0;i<4;i++)
623 at91sam7_info->flashmode[i]=0;
624
625 return ERROR_OK;
626 }
627
628 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
629 {
630 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
631 u8 flashplane;
632
633 if (at91sam7_info->cidr == 0)
634 {
635 return ERROR_FLASH_BANK_NOT_PROBED;
636 }
637
638 if (bank->target->state != TARGET_HALTED)
639 {
640 LOG_ERROR("Target not halted");
641 return ERROR_TARGET_NOT_HALTED;
642 }
643
644 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
645 {
646 if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
647 {
648 LOG_WARNING("Sector numbers based on lockbit count, probably a deprecated script");
649 last = bank->num_sectors-1;
650 }
651 else return ERROR_FLASH_SECTOR_INVALID;
652 }
653
654 /* Configure the flash controller timing */
655 at91sam7_read_clock_info(bank);
656 for (flashplane = first; flashplane<=last; flashplane++)
657 {
658 /* Configure the flash controller timing */
659 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
660 if (at91sam7_flash_command(bank, flashplane, EA, 0) != ERROR_OK)
661 {
662 return ERROR_FLASH_OPERATION_FAILED;
663 }
664 }
665 return ERROR_OK;
666
667 }
668
669 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
670 {
671 u32 cmd, pagen;
672 u8 flashplane;
673 int lockregion;
674
675 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
676
677 if (at91sam7_info->cidr == 0)
678 {
679 return ERROR_FLASH_BANK_NOT_PROBED;
680 }
681
682 if (bank->target->state != TARGET_HALTED)
683 {
684 LOG_ERROR("Target not halted");
685 return ERROR_TARGET_NOT_HALTED;
686 }
687
688 if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits))
689 {
690 return ERROR_FLASH_SECTOR_INVALID;
691 }
692
693 at91sam7_read_clock_info(bank);
694
695 for (lockregion=first;lockregion<=last;lockregion++)
696 {
697 pagen = lockregion*at91sam7_info->pages_in_lockregion;
698 flashplane = (pagen>>10)&0x03;
699 /* Configure the flash controller timing */
700 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_NVBITS);
701
702 if (set)
703 cmd = SLB;
704 else
705 cmd = CLB;
706
707 if (at91sam7_flash_command(bank, flashplane, cmd, pagen) != ERROR_OK)
708 {
709 return ERROR_FLASH_OPERATION_FAILED;
710 }
711 }
712
713 at91sam7_protect_check(bank);
714
715 return ERROR_OK;
716 }
717
718
719 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
720 {
721 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
722 target_t *target = bank->target;
723 u32 dst_min_alignment, wcount, bytes_remaining = count;
724 u32 first_page, last_page, pagen, buffer_pos;
725 u8 flashplane;
726
727 if (at91sam7_info->cidr == 0)
728 {
729 return ERROR_FLASH_BANK_NOT_PROBED;
730 }
731
732 if (bank->target->state != TARGET_HALTED)
733 {
734 LOG_ERROR("Target not halted");
735 return ERROR_TARGET_NOT_HALTED;
736 }
737
738 if (offset + count > bank->size)
739 return ERROR_FLASH_DST_OUT_OF_BANK;
740
741 dst_min_alignment = at91sam7_info->pagesize;
742
743 if (offset % dst_min_alignment)
744 {
745 LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
746 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
747 }
748
749 if (at91sam7_info->cidr_arch == 0)
750 return ERROR_FLASH_BANK_NOT_PROBED;
751
752 first_page = offset/dst_min_alignment;
753 last_page = CEIL(offset + count, dst_min_alignment);
754
755 LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
756
757 at91sam7_read_clock_info(bank);
758
759 for (pagen=first_page; pagen<last_page; pagen++)
760 {
761 if (bytes_remaining<dst_min_alignment)
762 count = bytes_remaining;
763 else
764 count = dst_min_alignment;
765 bytes_remaining -= count;
766
767 /* Write one block to the PageWriteBuffer */
768 buffer_pos = (pagen-first_page)*dst_min_alignment;
769 wcount = CEIL(count,4);
770 target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
771 flashplane = (pagen>>10)&0x3;
772
773 /* Configure the flash controller timing */
774 at91sam7_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH);
775 /* Send Write Page command to Flash Controller */
776 if (at91sam7_flash_command(bank, flashplane, WP, pagen) != ERROR_OK)
777 {
778 return ERROR_FLASH_OPERATION_FAILED;
779 }
780 LOG_DEBUG("Write flash plane:%i page number:%i", flashplane, pagen);
781 }
782
783 return ERROR_OK;
784 }
785
786
787 int at91sam7_probe(struct flash_bank_s *bank)
788 {
789 /* we can't probe on an at91sam7
790 * if this is an at91sam7, it has the configured flash
791 */
792 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
793 int retval;
794
795 if (at91sam7_info->cidr != 0)
796 {
797 return ERROR_OK; /* already probed */
798 }
799
800 if (bank->target->state != TARGET_HALTED)
801 {
802 LOG_ERROR("Target not halted");
803 return ERROR_TARGET_NOT_HALTED;
804 }
805
806 retval = at91sam7_read_part_info(bank);
807 if (retval != ERROR_OK)
808 return retval;
809
810 return ERROR_OK;
811 }
812
813
814 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
815 {
816 int printed, flashplane;
817 at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
818
819 if (at91sam7_info->cidr == 0)
820 {
821 return ERROR_FLASH_BANK_NOT_PROBED;
822 }
823
824 printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
825 buf += printed;
826 buf_size -= printed;
827
828 printed = snprintf(buf, buf_size, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x, flashsize: 0x%8.8x\n",
829 at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc], at91sam7_info->cidr_version, bank->size);
830 buf += printed;
831 buf_size -= printed;
832
833 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_info->mck_freq / 1000);
834 buf += printed;
835 buf_size -= printed;
836
837 if (at91sam7_info->num_planes>1) {
838 printed = snprintf(buf, buf_size, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n",
839 at91sam7_info->num_planes, at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->num_pages/at91sam7_info->num_lockbits);
840 buf += printed;
841 buf_size -= printed;
842 for (flashplane=0; flashplane<at91sam7_info->num_planes; flashplane++)
843 {
844 printed = snprintf(buf, buf_size, "lockbits[%i]: 0x%4.4x, ", flashplane, at91sam7_info->lockbits[flashplane]);
845 buf += printed;
846 buf_size -= printed;
847 }
848 }
849 else
850 if (at91sam7_info->num_lockbits>0) {
851 printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n",
852 at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->lockbits[0], at91sam7_info->num_pages/at91sam7_info->num_lockbits);
853 buf += printed;
854 buf_size -= printed;
855 }
856
857 printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits);
858 buf += printed;
859 buf_size -= printed;
860
861 return ERROR_OK;
862 }
863
864 /*
865 * On AT91SAM7S: When the gpnvm bits are set with
866 * > at91sam7 gpnvm 0 bitnr set
867 * the changes are not visible in the flash controller status register MC_FSR
868 * until the processor has been reset.
869 * On the Olimex board this requires a power cycle.
870 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
871 * The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
872 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
873 */
874 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
875 {
876 flash_bank_t *bank;
877 int bit;
878 u8 flashcmd;
879 u32 status;
880 char *value;
881 at91sam7_flash_bank_t *at91sam7_info;
882 int retval;
883
884 if (argc < 3)
885 {
886 command_print(cmd_ctx, "at91sam7 gpnvm <num> <bit> <set|clear>");
887 return ERROR_OK;
888 }
889
890 bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
891 bit = atoi(args[1]);
892 value = args[2];
893
894 if (bank == NULL)
895 {
896 return ERROR_FLASH_BANK_INVALID;
897 }
898
899 if (bank->driver != &at91sam7_flash)
900 {
901 command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
902 return ERROR_FLASH_BANK_INVALID;
903 }
904
905 if (strcmp(value, "set") == 0)
906 {
907 flashcmd = SGPB;
908 }
909 else if (strcmp(value, "clear") == 0)
910 {
911 flashcmd = CGPB;
912 }
913 else
914 {
915 return ERROR_COMMAND_SYNTAX_ERROR;
916 }
917
918 at91sam7_info = bank->driver_priv;
919
920 if (bank->target->state != TARGET_HALTED)
921 {
922 LOG_ERROR("target has to be halted to perform flash operation");
923 return ERROR_TARGET_NOT_HALTED;
924 }
925
926 if (at91sam7_info->cidr == 0)
927 {
928 retval = at91sam7_read_part_info(bank);
929 if (retval != ERROR_OK) {
930 return retval;
931 }
932 }
933
934 if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
935 {
936 command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
937 return ERROR_OK;
938 }
939
940 /* Configure the flash controller timing */
941 at91sam7_read_clock_info(bank);
942 at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
943
944 if (at91sam7_flash_command(bank, 0, flashcmd, (u16)(bit)) != ERROR_OK)
945 {
946 return ERROR_FLASH_OPERATION_FAILED;
947 }
948
949 status = at91sam7_get_flash_status(bank, 0);
950 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
951 at91sam7_info->nvmbits = (status>>8)&((1<<at91sam7_info->num_nvmbits)-1);
952
953 return ERROR_OK;
954 }

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)