search and replace usleep(1000) with alive_sleep(1) to avoid GDB timeouts.
[openocd.git] / src / flash / stellaris.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 * STELLARIS is tested on LM3S811, LM3S6965
23 ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "replacements.h"
29
30 #include "stellaris.h"
31 #include "cortex_m3.h"
32
33 #include "flash.h"
34 #include "target.h"
35 #include "log.h"
36 #include "binarybuffer.h"
37 #include "types.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 #define DID0_VER(did0) ((did0>>28)&0x07)
44 int stellaris_register_commands(struct command_context_s *cmd_ctx);
45 int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
46 int stellaris_erase(struct flash_bank_s *bank, int first, int last);
47 int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last);
48 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
49 int stellaris_auto_probe(struct flash_bank_s *bank);
50 int stellaris_probe(struct flash_bank_s *bank);
51 int stellaris_protect_check(struct flash_bank_s *bank);
52 int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size);
53
54 int stellaris_read_part_info(struct flash_bank_s *bank);
55 u32 stellaris_get_flash_status(flash_bank_t *bank);
56 void stellaris_set_flash_mode(flash_bank_t *bank,int mode);
57 u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
58
59 int stellaris_read_part_info(struct flash_bank_s *bank);
60 int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
61 int stellaris_mass_erase(struct flash_bank_s *bank);
62
63 flash_driver_t stellaris_flash =
64 {
65 .name = "stellaris",
66 .register_commands = stellaris_register_commands,
67 .flash_bank_command = stellaris_flash_bank_command,
68 .erase = stellaris_erase,
69 .protect = stellaris_protect,
70 .write = stellaris_write,
71 .probe = stellaris_probe,
72 .auto_probe = stellaris_auto_probe,
73 .erase_check = default_flash_mem_blank_check,
74 .protect_check = stellaris_protect_check,
75 .info = stellaris_info
76 };
77
78 struct {
79 u32 partno;
80 char *partname;
81 } StellarisParts[] =
82 {
83 {0x01,"LM3S101"},
84 {0x02,"LM3S102"},
85 {0x03,"LM3S1625"},
86 {0x04,"LM3S1626"},
87 {0x05,"LM3S1627"},
88 {0x06,"LM3S1607"},
89 {0x10,"LM3S1776"},
90 {0x19,"LM3S300"},
91 {0x11,"LM3S301"},
92 {0x12,"LM3S310"},
93 {0x1A,"LM3S308"},
94 {0x13,"LM3S315"},
95 {0x14,"LM3S316"},
96 {0x17,"LM3S317"},
97 {0x18,"LM3S318"},
98 {0x15,"LM3S328"},
99 {0x2A,"LM3S600"},
100 {0x21,"LM3S601"},
101 {0x2B,"LM3S608"},
102 {0x22,"LM3S610"},
103 {0x23,"LM3S611"},
104 {0x24,"LM3S612"},
105 {0x25,"LM3S613"},
106 {0x26,"LM3S615"},
107 {0x28,"LM3S617"},
108 {0x29,"LM3S618"},
109 {0x27,"LM3S628"},
110 {0x38,"LM3S800"},
111 {0x31,"LM3S801"},
112 {0x39,"LM3S808"},
113 {0x32,"LM3S811"},
114 {0x33,"LM3S812"},
115 /*{0x33,"LM3S2616"},*/
116 {0x34,"LM3S815"},
117 {0x36,"LM3S817"},
118 {0x37,"LM3S818"},
119 {0x35,"LM3S828"},
120 {0x39,"LM3S2276"},
121 {0x3A,"LM3S2776"},
122 {0x43,"LM3S3651"},
123 {0x44,"LM3S3739"},
124 {0x45,"LM3S3749"},
125 {0x46,"LM3S3759"},
126 {0x48,"LM3S3768"},
127 {0x49,"LM3S3748"},
128 {0x50,"LM3S2678"},
129 {0x51,"LM3S2110"},
130 {0x52,"LM3S2739"},
131 {0x53,"LM3S2651"},
132 {0x54,"LM3S2939"},
133 {0x55,"LM3S2965"},
134 {0x56,"LM3S2432"},
135 {0x57,"LM3S2620"},
136 {0x58,"LM3S2950"},
137 {0x59,"LM3S2412"},
138 {0x5A,"LM3S2533"},
139 {0x61,"LM3S8630"},
140 {0x62,"LM3S8970"},
141 {0x63,"LM3S8730"},
142 {0x64,"LM3S8530"},
143 {0x65,"LM3S8930"},
144 {0x71,"LM3S6610"},
145 {0x72,"LM3S6950"},
146 {0x73,"LM3S6965"},
147 {0x74,"LM3S6110"},
148 {0x75,"LM3S6432"},
149 {0x76,"LM3S6537"},
150 {0x77,"LM3S6753"},
151 {0x78,"LM3S6952"},
152 {0x80,"LM3S2671"},
153 {0x81,"LM3S5632"},
154 {0x82,"LM3S6422"},
155 {0x83,"LM3S6633"},
156 {0x84,"LM3S2139"},
157 {0x85,"LM3S2637"},
158 {0x86,"LM3S8738"},
159 {0x88,"LM3S8938"},
160 {0x89,"LM3S6938"},
161 {0x8A,"LM3S5652"},
162 {0x8B,"LM3S6637"},
163 {0x8C,"LM3S8933"},
164 {0x8D,"LM3S8733"},
165 {0x8E,"LM3S8538"},
166 {0x8F,"LM3S2948"},
167 {0x91,"LM3S5662"},
168 {0x96,"LM3S5732"},
169 {0x97,"LM3S5737"},
170 {0x99,"LM3S5747"},
171 {0x9A,"LM3S5752"},
172 {0x9B,"LM3S5757"},
173 {0x9C,"LM3S5762"},
174 {0x9D,"LM3S5767"},
175 {0xA0,"LM3S5739"},
176 {0xA1,"LM3S6100"},
177 {0xA2,"LM3S2410"},
178 {0xA3,"LM3S6730"},
179 {0xA4,"LM3S2730"},
180 {0xA5,"LM3S6420"},
181 {0xA6,"LM3S8962"},
182 {0xA7,"LM3S5749"},
183 {0xA8,"LM3S5769"},
184 {0xA9,"LM3S5768"},
185 {0xB3,"LM3S1635"},
186 {0xB4,"LM3S1850"},
187 {0xB5,"LM3S1960"},
188 {0xB7,"LM3S1937"},
189 {0xB8,"LM3S1968"},
190 {0xB9,"LM3S1751"},
191 {0xBA,"LM3S1439"},
192 {0xBB,"LM3S1512"},
193 {0xBC,"LM3S1435"},
194 {0xBD,"LM3S1637"},
195 {0xBE,"LM3S1958"},
196 {0xBF,"LM3S1110"},
197 {0xC0,"LM3S1620"},
198 {0xC1,"LM3S1150"},
199 {0xC2,"LM3S1165"},
200 {0xC3,"LM3S1133"},
201 {0xC4,"LM3S1162"},
202 {0xC5,"LM3S1138"},
203 {0xC6,"LM3S1332"},
204 {0xC7,"LM3S1538"},
205 {0xD0,"LM3S6815"},
206 {0xD1,"LM3S6816"},
207 {0xD2,"LM3S6915"},
208 {0xD3,"LM3S6916"},
209 {0xD4,"LM3S2016"},
210 {0xD5,"LM3S1615"},
211 {0xD6,"LM3S1616"},
212 {0xD7,"LM3S8971"},
213 {0xD8,"LM3S1108"},
214 {0xD9,"LM3S1101"},
215 {0xDA,"LM3S1608"},
216 {0xDB,"LM3S1601"},
217 {0xDC,"LM3S1918"},
218 {0xDD,"LM3S1911"},
219 {0xDE,"LM3S2108"},
220 {0xDF,"LM3S2101"},
221 {0xE0,"LM3S2608"},
222 {0xE1,"LM3S2601"},
223 {0xE2,"LM3S2918"},
224 {0xE3,"LM3S2911"},
225 {0xE4,"LM3S6118"},
226 {0xE5,"LM3S6111"},
227 {0xE6,"LM3S6618"},
228 {0xE7,"LM3S6611"},
229 {0xE8,"LM3S6918"},
230 {0xE9,"LM3S6911"},
231 {0,"Unknown part"}
232 };
233
234 char * StellarisClassname[5] =
235 {
236 "Sandstorm",
237 "Fury",
238 "Unknown",
239 "DustDevil",
240 "Tempest"
241 };
242
243 /***************************************************************************
244 * openocd command interface *
245 ***************************************************************************/
246
247 /* flash_bank stellaris <base> <size> 0 0 <target#>
248 */
249 int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
250 {
251 stellaris_flash_bank_t *stellaris_info;
252
253 if (argc < 6)
254 {
255 LOG_WARNING("incomplete flash_bank stellaris configuration");
256 return ERROR_FLASH_BANK_INVALID;
257 }
258
259 stellaris_info = calloc(sizeof(stellaris_flash_bank_t), 1);
260 bank->base = 0x0;
261 bank->driver_priv = stellaris_info;
262
263 stellaris_info->target_name = "Unknown target";
264
265 /* part wasn't probed for info yet */
266 stellaris_info->did1 = 0;
267
268 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
269 return ERROR_OK;
270 }
271
272 int stellaris_register_commands(struct command_context_s *cmd_ctx)
273 {
274 command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, "stellaris flash specific commands");
275
276 register_command(cmd_ctx, stm32x_cmd, "mass_erase", stellaris_handle_mass_erase_command, COMMAND_EXEC, "mass erase device");
277 return ERROR_OK;
278 }
279
280 int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
281 {
282 int printed, device_class;
283 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
284
285 stellaris_read_part_info(bank);
286
287 if (stellaris_info->did1 == 0)
288 {
289 printed = snprintf(buf, buf_size, "Cannot identify target as a Stellaris\n");
290 buf += printed;
291 buf_size -= printed;
292 return ERROR_FLASH_OPERATION_FAILED;
293 }
294
295 if (DID0_VER(stellaris_info->did0) > 0)
296 {
297 device_class = (stellaris_info->did0>>16) & 0xFF;
298 }
299 else
300 {
301 device_class = 0;
302 }
303 printed = snprintf(buf, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
304 device_class, StellarisClassname[device_class], stellaris_info->target_name,
305 'A' + ((stellaris_info->did0>>8) & 0xFF), (stellaris_info->did0) & 0xFF);
306 buf += printed;
307 buf_size -= printed;
308
309 printed = snprintf(buf, buf_size, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
310 stellaris_info->did1, stellaris_info->did1, "ARMV7M", (1+((stellaris_info->dc0>>16) & 0xFFFF))/4, (1+(stellaris_info->dc0 & 0xFFFF))*2);
311 buf += printed;
312 buf_size -= printed;
313
314 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info->mck_freq / 1000, stellaris_info->rcc);
315 buf += printed;
316 buf_size -= printed;
317
318 if (stellaris_info->num_lockbits>0)
319 {
320 printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", stellaris_info->pagesize, stellaris_info->num_lockbits, stellaris_info->lockbits,stellaris_info->num_pages/stellaris_info->num_lockbits);
321 buf += printed;
322 buf_size -= printed;
323 }
324 return ERROR_OK;
325 }
326
327 /***************************************************************************
328 * chip identification and status *
329 ***************************************************************************/
330
331 u32 stellaris_get_flash_status(flash_bank_t *bank)
332 {
333 target_t *target = bank->target;
334 u32 fmc;
335
336 target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc);
337
338 return fmc;
339 }
340
341 /** Read clock configuration and set stellaris_info->usec_clocks*/
342
343 void stellaris_read_clock_info(flash_bank_t *bank)
344 {
345 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
346 target_t *target = bank->target;
347 u32 rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
348 unsigned long mainfreq;
349
350 target_read_u32(target, SCB_BASE|RCC, &rcc);
351 LOG_DEBUG("Stellaris RCC %x", rcc);
352 target_read_u32(target, SCB_BASE|PLLCFG, &pllcfg);
353 LOG_DEBUG("Stellaris PLLCFG %x", pllcfg);
354 stellaris_info->rcc = rcc;
355
356 sysdiv = (rcc>>23) & 0xF;
357 usesysdiv = (rcc>>22) & 0x1;
358 bypass = (rcc>>11) & 0x1;
359 oscsrc = (rcc>>4) & 0x3;
360 /* xtal = (rcc>>6)&0xF; */
361 switch (oscsrc)
362 {
363 case 0:
364 mainfreq = 6000000; /* Default xtal */
365 break;
366 case 1:
367 mainfreq = 22500000; /* Internal osc. 15 MHz +- 50% */
368 break;
369 case 2:
370 mainfreq = 5625000; /* Internal osc. / 4 */
371 break;
372 case 3:
373 LOG_WARNING("Invalid oscsrc (3) in rcc register");
374 mainfreq = 6000000;
375 break;
376
377 default: /* NOTREACHED */
378 mainfreq = 0;
379 break;
380 }
381
382 if (!bypass)
383 mainfreq = 200000000; /* PLL out frec */
384
385 if (usesysdiv)
386 stellaris_info->mck_freq = mainfreq/(1+sysdiv);
387 else
388 stellaris_info->mck_freq = mainfreq;
389
390 /* Forget old flash timing */
391 stellaris_set_flash_mode(bank, 0);
392 }
393
394 /* Setup the timimg registers */
395 void stellaris_set_flash_mode(flash_bank_t *bank,int mode)
396 {
397 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
398 target_t *target = bank->target;
399
400 u32 usecrl = (stellaris_info->mck_freq/1000000ul-1);
401 LOG_DEBUG("usecrl = %i",usecrl);
402 target_write_u32(target, SCB_BASE|USECRL, usecrl);
403 }
404
405 u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
406 {
407 u32 status;
408
409 /* Stellaris waits for cmdbit to clear */
410 while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0))
411 {
412 LOG_DEBUG("status: 0x%x", status);
413 alive_sleep(1);
414 }
415
416 /* Flash errors are reflected in the FLASH_CRIS register */
417
418 return status;
419 }
420
421 /* Send one command to the flash controller */
422 int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
423 {
424 u32 fmc;
425 target_t *target = bank->target;
426
427 fmc = FMC_WRKEY | cmd;
428 target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc);
429 LOG_DEBUG("Flash command: 0x%x", fmc);
430
431 if (stellaris_wait_status_busy(bank, cmd, 100))
432 {
433 return ERROR_FLASH_OPERATION_FAILED;
434 }
435
436 return ERROR_OK;
437 }
438
439 /* Read device id register, main clock frequency register and fill in driver info structure */
440 int stellaris_read_part_info(struct flash_bank_s *bank)
441 {
442 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
443 target_t *target = bank->target;
444 u32 did0, did1, ver, fam, status;
445 int i;
446
447 /* Read and parse chip identification register */
448 target_read_u32(target, SCB_BASE|DID0, &did0);
449 target_read_u32(target, SCB_BASE|DID1, &did1);
450 target_read_u32(target, SCB_BASE|DC0, &stellaris_info->dc0);
451 target_read_u32(target, SCB_BASE|DC1, &stellaris_info->dc1);
452 LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0, did1, stellaris_info->dc0, stellaris_info->dc1);
453
454 ver = did0 >> 28;
455 if((ver != 0) && (ver != 1))
456 {
457 LOG_WARNING("Unknown did0 version, cannot identify target");
458 return ERROR_FLASH_OPERATION_FAILED;
459 }
460
461 if (did1 == 0)
462 {
463 LOG_WARNING("Cannot identify target as a Stellaris");
464 return ERROR_FLASH_OPERATION_FAILED;
465 }
466
467 ver = did1 >> 28;
468 fam = (did1 >> 24) & 0xF;
469 if(((ver != 0) && (ver != 1)) || (fam != 0))
470 {
471 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
472 }
473
474 for (i = 0; StellarisParts[i].partno; i++)
475 {
476 if (StellarisParts[i].partno == ((did1 >> 16) & 0xFF))
477 break;
478 }
479
480 stellaris_info->target_name = StellarisParts[i].partname;
481
482 stellaris_info->did0 = did0;
483 stellaris_info->did1 = did1;
484
485 stellaris_info->num_lockbits = 1 + (stellaris_info->dc0 & 0xFFFF);
486 stellaris_info->num_pages = 2 *(1+(stellaris_info->dc0 & 0xFFFF));
487 stellaris_info->pagesize = 1024;
488 bank->size = 1024 * stellaris_info->num_pages;
489 stellaris_info->pages_in_lockregion = 2;
490 target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
491
492 /* provide this for the benefit of the higher flash driver layers */
493 bank->num_sectors = stellaris_info->num_pages;
494 bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
495 for (i = 0; i < bank->num_sectors; i++)
496 {
497 bank->sectors[i].offset = i * stellaris_info->pagesize;
498 bank->sectors[i].size = stellaris_info->pagesize;
499 bank->sectors[i].is_erased = -1;
500 bank->sectors[i].is_protected = -1;
501 }
502
503 /* Read main and master clock freqency register */
504 stellaris_read_clock_info(bank);
505
506 status = stellaris_get_flash_status(bank);
507
508 return ERROR_OK;
509 }
510
511 /***************************************************************************
512 * flash operations *
513 ***************************************************************************/
514
515 int stellaris_protect_check(struct flash_bank_s *bank)
516 {
517 u32 status;
518
519 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
520
521 if (bank->target->state != TARGET_HALTED)
522 {
523 LOG_ERROR("Target not halted");
524 return ERROR_TARGET_NOT_HALTED;
525 }
526
527 if (stellaris_info->did1 == 0)
528 {
529 stellaris_read_part_info(bank);
530 }
531
532 if (stellaris_info->did1 == 0)
533 {
534 LOG_WARNING("Cannot identify target as an AT91SAM");
535 return ERROR_FLASH_OPERATION_FAILED;
536 }
537
538 status = stellaris_get_flash_status(bank);
539 stellaris_info->lockbits = status >> 16;
540
541 return ERROR_OK;
542 }
543
544 int stellaris_erase(struct flash_bank_s *bank, int first, int last)
545 {
546 int banknr;
547 u32 flash_fmc, flash_cris;
548 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
549 target_t *target = bank->target;
550
551 if (bank->target->state != TARGET_HALTED)
552 {
553 LOG_ERROR("Target not halted");
554 return ERROR_TARGET_NOT_HALTED;
555 }
556
557 if (stellaris_info->did1 == 0)
558 {
559 stellaris_read_part_info(bank);
560 }
561
562 if (stellaris_info->did1 == 0)
563 {
564 LOG_WARNING("Cannot identify target as Stellaris");
565 return ERROR_FLASH_OPERATION_FAILED;
566 }
567
568 if ((first < 0) || (last < first) || (last >= stellaris_info->num_pages))
569 {
570 return ERROR_FLASH_SECTOR_INVALID;
571 }
572
573 if ((first == 0) && (last == (stellaris_info->num_pages-1)))
574 {
575 return stellaris_mass_erase(bank);
576 }
577
578 /* Configure the flash controller timing */
579 stellaris_read_clock_info(bank);
580 stellaris_set_flash_mode(bank,0);
581
582 /* Clear and disable flash programming interrupts */
583 target_write_u32(target, FLASH_CIM, 0);
584 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
585
586 for (banknr = first; banknr <= last; banknr++)
587 {
588 /* Address is first word in page */
589 target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);
590 /* Write erase command */
591 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);
592 /* Wait until erase complete */
593 do
594 {
595 target_read_u32(target, FLASH_FMC, &flash_fmc);
596 }
597 while(flash_fmc & FMC_ERASE);
598
599 /* Check acess violations */
600 target_read_u32(target, FLASH_CRIS, &flash_cris);
601 if(flash_cris & (AMASK))
602 {
603 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr, flash_cris);
604 target_write_u32(target, FLASH_CRIS, 0);
605 return ERROR_FLASH_OPERATION_FAILED;
606 }
607
608 bank->sectors[banknr].is_erased = 1;
609 }
610
611 return ERROR_OK;
612 }
613
614 int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last)
615 {
616 u32 fmppe, flash_fmc, flash_cris;
617 int lockregion;
618
619 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
620 target_t *target = bank->target;
621
622 if (bank->target->state != TARGET_HALTED)
623 {
624 LOG_ERROR("Target not halted");
625 return ERROR_TARGET_NOT_HALTED;
626 }
627
628 if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits))
629 {
630 return ERROR_FLASH_SECTOR_INVALID;
631 }
632
633 if (stellaris_info->did1 == 0)
634 {
635 stellaris_read_part_info(bank);
636 }
637
638 if (stellaris_info->did1 == 0)
639 {
640 LOG_WARNING("Cannot identify target as an Stellaris MCU");
641 return ERROR_FLASH_OPERATION_FAILED;
642 }
643
644 /* Configure the flash controller timing */
645 stellaris_read_clock_info(bank);
646 stellaris_set_flash_mode(bank, 0);
647
648 fmppe = stellaris_info->lockbits;
649 for (lockregion = first; lockregion <= last; lockregion++)
650 {
651 if (set)
652 fmppe &= ~(1<<lockregion);
653 else
654 fmppe |= (1<<lockregion);
655 }
656
657 /* Clear and disable flash programming interrupts */
658 target_write_u32(target, FLASH_CIM, 0);
659 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
660
661 LOG_DEBUG("fmppe 0x%x",fmppe);
662 target_write_u32(target, SCB_BASE|FMPPE, fmppe);
663 /* Commit FMPPE */
664 target_write_u32(target, FLASH_FMA, 1);
665 /* Write commit command */
666 /* TODO safety check, sice this cannot be undone */
667 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
668 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
669 /* Wait until erase complete */
670 do
671 {
672 target_read_u32(target, FLASH_FMC, &flash_fmc);
673 }
674 while(flash_fmc & FMC_COMT);
675
676 /* Check acess violations */
677 target_read_u32(target, FLASH_CRIS, &flash_cris);
678 if(flash_cris & (AMASK))
679 {
680 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris);
681 target_write_u32(target, FLASH_CRIS, 0);
682 return ERROR_FLASH_OPERATION_FAILED;
683 }
684
685 target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
686
687 return ERROR_OK;
688 }
689
690 u8 stellaris_write_code[] =
691 {
692 /*
693 Call with :
694 r0 = buffer address
695 r1 = destination address
696 r2 = bytecount (in) - endaddr (work)
697
698 Used registers:
699 r3 = pFLASH_CTRL_BASE
700 r4 = FLASHWRITECMD
701 r5 = #1
702 r6 = bytes written
703 r7 = temp reg
704 */
705 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
706 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
707 0x01,0x25, /* movs r5, 1 */
708 0x00,0x26, /* movs r6, #0 */
709 /* mainloop: */
710 0x19,0x60, /* str r1, [r3, #0] */
711 0x87,0x59, /* ldr r7, [r0, r6] */
712 0x5F,0x60, /* str r7, [r3, #4] */
713 0x9C,0x60, /* str r4, [r3, #8] */
714 /* waitloop: */
715 0x9F,0x68, /* ldr r7, [r3, #8] */
716 0x2F,0x42, /* tst r7, r5 */
717 0xFC,0xD1, /* bne waitloop */
718 0x04,0x31, /* adds r1, r1, #4 */
719 0x04,0x36, /* adds r6, r6, #4 */
720 0x96,0x42, /* cmp r6, r2 */
721 0xF4,0xD1, /* bne mainloop */
722 /* exit: */
723 0xFE,0xE7, /* b exit */
724 /* pFLASH_CTRL_BASE: */
725 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
726 /* FLASHWRITECMD: */
727 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
728 };
729
730 int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 wcount)
731 {
732 target_t *target = bank->target;
733 u32 buffer_size = 8192;
734 working_area_t *source;
735 working_area_t *write_algorithm;
736 u32 address = bank->base + offset;
737 reg_param_t reg_params[3];
738 armv7m_algorithm_t armv7m_info;
739 int retval = ERROR_OK;
740
741 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
742 bank, buffer, offset, wcount);
743
744 /* flash write code */
745 if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
746 {
747 LOG_WARNING("no working area available, can't do block memory writes");
748 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
749 };
750
751 target_write_buffer(target, write_algorithm->address, sizeof(stellaris_write_code), stellaris_write_code);
752
753 /* memory buffer */
754 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
755 {
756 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
757 target, buffer_size, source);
758 buffer_size /= 2;
759 if (buffer_size <= 256)
760 {
761 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
762 if (write_algorithm)
763 target_free_working_area(target, write_algorithm);
764
765 LOG_WARNING("no large enough working area available, can't do block memory writes");
766 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
767 }
768 };
769
770 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
771 armv7m_info.core_mode = ARMV7M_MODE_ANY;
772
773 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
774 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
775 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
776
777 while (wcount > 0)
778 {
779 u32 thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
780
781 target_write_buffer(target, source->address, thisrun_count * 4, buffer);
782
783 buf_set_u32(reg_params[0].value, 0, 32, source->address);
784 buf_set_u32(reg_params[1].value, 0, 32, address);
785 buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
786 LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count, address, wcount);
787 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count, address, wcount);
788 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, write_algorithm->address, write_algorithm->address + sizeof(stellaris_write_code)-10, 10000, &armv7m_info)) != ERROR_OK)
789 {
790 LOG_ERROR("error executing stellaris flash write algorithm");
791 retval = ERROR_FLASH_OPERATION_FAILED;
792 break;
793 }
794
795 buffer += thisrun_count * 4;
796 address += thisrun_count * 4;
797 wcount -= thisrun_count;
798 }
799
800 target_free_working_area(target, write_algorithm);
801 target_free_working_area(target, source);
802
803 destroy_reg_param(&reg_params[0]);
804 destroy_reg_param(&reg_params[1]);
805 destroy_reg_param(&reg_params[2]);
806
807 return retval;
808 }
809
810 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
811 {
812 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
813 target_t *target = bank->target;
814 u32 address = offset;
815 u32 flash_cris,flash_fmc;
816 u32 retval;
817
818 if (bank->target->state != TARGET_HALTED)
819 {
820 LOG_ERROR("Target not halted");
821 return ERROR_TARGET_NOT_HALTED;
822 }
823
824 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
825 bank, buffer, offset, count);
826
827 if (stellaris_info->did1 == 0)
828 {
829 stellaris_read_part_info(bank);
830 }
831
832 if (stellaris_info->did1 == 0)
833 {
834 LOG_WARNING("Cannot identify target as a Stellaris processor");
835 return ERROR_FLASH_OPERATION_FAILED;
836 }
837
838 if((offset & 3) || (count & 3))
839 {
840 LOG_WARNING("offset size must be word aligned");
841 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
842 }
843
844 if (offset + count > bank->size)
845 return ERROR_FLASH_DST_OUT_OF_BANK;
846
847 /* Configure the flash controller timing */
848 stellaris_read_clock_info(bank);
849 stellaris_set_flash_mode(bank, 0);
850
851 /* Clear and disable flash programming interrupts */
852 target_write_u32(target, FLASH_CIM, 0);
853 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
854
855 /* multiple words to be programmed? */
856 if (count > 0)
857 {
858 /* try using a block write */
859 if ((retval = stellaris_write_block(bank, buffer, offset, count/4)) != ERROR_OK)
860 {
861 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
862 {
863 /* if block write failed (no sufficient working area),
864 * we use normal (slow) single dword accesses */
865 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
866 }
867 else if (retval == ERROR_FLASH_OPERATION_FAILED)
868 {
869 /* if an error occured, we examine the reason, and quit */
870 target_read_u32(target, FLASH_CRIS, &flash_cris);
871
872 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris);
873 return ERROR_FLASH_OPERATION_FAILED;
874 }
875 }
876 else
877 {
878 buffer += count * 4;
879 address += count * 4;
880 count = 0;
881 }
882 }
883
884 while (count > 0)
885 {
886 if (!(address & 0xff))
887 LOG_DEBUG("0x%x", address);
888
889 /* Program one word */
890 target_write_u32(target, FLASH_FMA, address);
891 target_write_buffer(target, FLASH_FMD, 4, buffer);
892 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
893 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
894 /* Wait until write complete */
895 do
896 {
897 target_read_u32(target, FLASH_FMC, &flash_fmc);
898 }
899 while (flash_fmc & FMC_WRITE);
900 buffer += 4;
901 address += 4;
902 count -= 4;
903 }
904 /* Check acess violations */
905 target_read_u32(target, FLASH_CRIS, &flash_cris);
906 if (flash_cris & (AMASK))
907 {
908 LOG_DEBUG("flash_cris 0x%x", flash_cris);
909 return ERROR_FLASH_OPERATION_FAILED;
910 }
911 return ERROR_OK;
912 }
913
914 int stellaris_probe(struct flash_bank_s *bank)
915 {
916 /* we can't probe on an stellaris
917 * if this is an stellaris, it has the configured flash
918 */
919
920 if (bank->target->state != TARGET_HALTED)
921 {
922 LOG_ERROR("Target not halted");
923 return ERROR_TARGET_NOT_HALTED;
924 }
925
926 /* stellaris_read_part_info() already takes care about error checking and reporting */
927 return stellaris_read_part_info(bank);
928 }
929
930 int stellaris_auto_probe(struct flash_bank_s *bank)
931 {
932 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
933 if (stellaris_info->did1)
934 return ERROR_OK;
935 return stellaris_probe(bank);
936 }
937
938 int stellaris_mass_erase(struct flash_bank_s *bank)
939 {
940 target_t *target = NULL;
941 stellaris_flash_bank_t *stellaris_info = NULL;
942 u32 flash_fmc;
943
944 stellaris_info = bank->driver_priv;
945 target = bank->target;
946
947 if (target->state != TARGET_HALTED)
948 {
949 LOG_ERROR("Target not halted");
950 return ERROR_TARGET_NOT_HALTED;
951 }
952
953 if (stellaris_info->did1 == 0)
954 {
955 stellaris_read_part_info(bank);
956 }
957
958 if (stellaris_info->did1 == 0)
959 {
960 LOG_WARNING("Cannot identify target as Stellaris");
961 return ERROR_FLASH_OPERATION_FAILED;
962 }
963
964 /* Configure the flash controller timing */
965 stellaris_read_clock_info(bank);
966 stellaris_set_flash_mode(bank, 0);
967
968 /* Clear and disable flash programming interrupts */
969 target_write_u32(target, FLASH_CIM, 0);
970 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
971
972 target_write_u32(target, FLASH_FMA, 0);
973 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
974 /* Wait until erase complete */
975 do
976 {
977 target_read_u32(target, FLASH_FMC, &flash_fmc);
978 }
979 while (flash_fmc & FMC_MERASE);
980
981 /* if device has > 128k, then second erase cycle is needed
982 * this is only valid for older devices, but will not hurt */
983 if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
984 {
985 target_write_u32(target, FLASH_FMA, 0x20000);
986 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
987 /* Wait until erase complete */
988 do
989 {
990 target_read_u32(target, FLASH_FMC, &flash_fmc);
991 }
992 while (flash_fmc & FMC_MERASE);
993 }
994
995 return ERROR_OK;
996 }
997
998 int stellaris_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
999 {
1000 flash_bank_t *bank;
1001 int i;
1002
1003 if (argc < 1)
1004 {
1005 command_print(cmd_ctx, "stellaris mass_erase <bank>");
1006 return ERROR_OK;
1007 }
1008
1009 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1010 if (!bank)
1011 {
1012 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1013 return ERROR_OK;
1014 }
1015
1016 if (stellaris_mass_erase(bank) == ERROR_OK)
1017 {
1018 /* set all sectors as erased */
1019 for (i = 0; i < bank->num_sectors; i++)
1020 {
1021 bank->sectors[i].is_erased = 1;
1022 }
1023
1024 command_print(cmd_ctx, "stellaris mass erase complete");
1025 }
1026 else
1027 {
1028 command_print(cmd_ctx, "stellaris mass erase failed");
1029 }
1030
1031 return ERROR_OK;
1032 }

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)