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

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)