- Added PKGLIBDIR define to C options. Allows to store
[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
23 *
24 *
25 *
26 ***************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "replacements.h"
32
33 #include "stellaris.h"
34 #include "cortex_m3.h"
35
36 #include "flash.h"
37 #include "target.h"
38 #include "log.h"
39 #include "binarybuffer.h"
40 #include "types.h"
41
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45
46 #define DID0_VER(did0) ((did0>>28)&0x07)
47 int stellaris_register_commands(struct command_context_s *cmd_ctx);
48 int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
49 int stellaris_erase(struct flash_bank_s *bank, int first, int last);
50 int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last);
51 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
52 int stellaris_probe(struct flash_bank_s *bank);
53 int stellaris_erase_check(struct flash_bank_s *bank);
54 int stellaris_protect_check(struct flash_bank_s *bank);
55 int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size);
56
57 int stellaris_read_part_info(struct flash_bank_s *bank);
58 u32 stellaris_get_flash_status(flash_bank_t *bank);
59 void stellaris_set_flash_mode(flash_bank_t *bank,int mode);
60 u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
61
62 int stellaris_read_part_info(struct flash_bank_s *bank);
63
64 flash_driver_t stellaris_flash =
65 {
66 .name = "stellaris",
67 .register_commands = stellaris_register_commands,
68 .flash_bank_command = stellaris_flash_bank_command,
69 .erase = stellaris_erase,
70 .protect = stellaris_protect,
71 .write = stellaris_write,
72 .probe = stellaris_probe,
73 .erase_check = stellaris_erase_check,
74 .protect_check = stellaris_protect_check,
75 .info = stellaris_info
76 };
77
78
79 struct {
80 u32 partno;
81 char *partname;
82 } StellarisParts[] =
83 {
84 {0x01,"LM3S101"},
85 {0x02,"LM3S102"},
86 {0x11,"LM3S301"},
87 {0x12,"LM3S310"},
88 {0x13,"LM3S315"},
89 {0x14,"LM3S316"},
90 {0x15,"LM3S328"},
91 {0x21,"LM3S601"},
92 {0x22,"LM3S610"},
93 {0x23,"LM3S611"},
94 {0x24,"LM3S612"},
95 {0x25,"LM3S613"},
96 {0x26,"LM3S615"},
97 {0x27,"LM3S628"},
98 {0x31,"LM3S801"},
99 {0x32,"LM3S811"},
100 {0x33,"LM3S812"},
101 {0x34,"LM3S815"},
102 {0x35,"LM3S828"},
103 {0x51,"LM3S2110"},
104 {0x84,"LM3S2139"},
105 {0xa2,"LM3S2410"},
106 {0x59,"LM3S2412"},
107 {0x56,"LM3S2432"},
108 {0x5a,"LM3S2533"},
109 {0x57,"LM3S2620"},
110 {0x85,"LM3S2637"},
111 {0x53,"LM3S2651"},
112 {0xa4,"LM3S2730"},
113 {0x52,"LM3S2739"},
114 {0x54,"LM3S2939"},
115 {0x8f,"LM3S2948"},
116 {0x58,"LM3S2950"},
117 {0x55,"LM3S2965"},
118 {0xa1,"LM3S6100"},
119 {0x74,"LM3S6110"},
120 {0xa5,"LM3S6420"},
121 {0x82,"LM3S6422"},
122 {0x75,"LM3S6432"},
123 {0x71,"LM3S6610"},
124 {0x83,"LM3S6633"},
125 {0x8b,"LM3S6637"},
126 {0xa3,"LM3S6730"},
127 {0x89,"LM3S6938"},
128 {0x78,"LM3S6952"},
129 {0x73,"LM3S6965"},
130 {0,"Unknown part"}
131 };
132
133 char * StellarisClassname[2] =
134 {
135 "Sandstorm",
136 "Fury"
137 };
138
139 /***************************************************************************
140 * openocd command interface *
141 ***************************************************************************/
142
143 /* flash_bank stellaris <base> <size> 0 0 <target#>
144 */
145 int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
146 {
147 stellaris_flash_bank_t *stellaris_info;
148
149 if (argc < 6)
150 {
151 WARNING("incomplete flash_bank stellaris configuration");
152 return ERROR_FLASH_BANK_INVALID;
153 }
154
155 stellaris_info = calloc(sizeof(stellaris_flash_bank_t),1);
156 bank->base = 0x0;
157 bank->driver_priv = stellaris_info;
158
159 stellaris_info->target_name = "Unknown target";
160
161 /* part wasn't probed for info yet */
162 stellaris_info->did1 = 0;
163
164 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
165 return ERROR_OK;
166 }
167
168 int stellaris_register_commands(struct command_context_s *cmd_ctx)
169 {
170 /*
171 command_t *stellaris_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, NULL);
172 register_command(cmd_ctx, stellaris_cmd, "gpnvm", stellaris_handle_gpnvm_command, COMMAND_EXEC,
173 "stellaris gpnvm <num> <bit> set|clear, set or clear stellaris gpnvm bit");
174 */
175 return ERROR_OK;
176 }
177
178 int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
179 {
180 int printed, device_class;
181 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
182
183 stellaris_read_part_info(bank);
184
185 if (stellaris_info->did1 == 0)
186 {
187 printed = snprintf(buf, buf_size, "Cannot identify target as a Stellaris\n");
188 buf += printed;
189 buf_size -= printed;
190 return ERROR_FLASH_OPERATION_FAILED;
191 }
192
193 if (DID0_VER(stellaris_info->did0)>0)
194 {
195 device_class = (stellaris_info->did0>>16)&0xFF;
196 }
197 else
198 {
199 device_class = 0;
200 }
201 printed = snprintf(buf, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
202 device_class, StellarisClassname[device_class], stellaris_info->target_name,
203 'A' + (stellaris_info->did0>>8)&0xFF, (stellaris_info->did0)&0xFF);
204 buf += printed;
205 buf_size -= printed;
206
207 printed = snprintf(buf, buf_size, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
208 stellaris_info->did1, stellaris_info->did1, "ARMV7M", (1+(stellaris_info->dc0>>16)&0xFFFF)/4, (1+stellaris_info->dc0&0xFFFF)*2);
209 buf += printed;
210 buf_size -= printed;
211
212 printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info->mck_freq / 1000, stellaris_info->rcc);
213 buf += printed;
214 buf_size -= printed;
215
216 if (stellaris_info->num_lockbits>0) {
217 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);
218 buf += printed;
219 buf_size -= printed;
220 }
221 return ERROR_OK;
222 }
223
224 /***************************************************************************
225 * chip identification and status *
226 ***************************************************************************/
227
228 u32 stellaris_get_flash_status(flash_bank_t *bank)
229 {
230 target_t *target = bank->target;
231 u32 fmc;
232
233 target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc);
234
235 return fmc;
236 }
237
238 /** Read clock configuration and set stellaris_info->usec_clocks*/
239
240 void stellaris_read_clock_info(flash_bank_t *bank)
241 {
242 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
243 target_t *target = bank->target;
244 u32 rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
245 unsigned long mainfreq;
246
247 target_read_u32(target, SCB_BASE|RCC, &rcc);
248 DEBUG("Stellaris RCC %x",rcc);
249 target_read_u32(target, SCB_BASE|PLLCFG, &pllcfg);
250 DEBUG("Stellaris PLLCFG %x",pllcfg);
251 stellaris_info->rcc = rcc;
252
253 sysdiv = (rcc>>23)&0xF;
254 usesysdiv = (rcc>>22)&0x1;
255 bypass = (rcc>>11)&0x1;
256 oscsrc = (rcc>>4)&0x3;
257 /* xtal = (rcc>>6)&0xF; */
258 switch (oscsrc)
259 {
260 case 0:
261 mainfreq = 6000000; /* Default xtal */
262 break;
263 case 1:
264 mainfreq = 22500000; /* Internal osc. 15 MHz +- 50% */
265 break;
266 case 2:
267 mainfreq = 5625000; /* Internal osc. / 4 */
268 break;
269 case 3:
270 WARNING("Invalid oscsrc (3) in rcc register");
271 mainfreq = 6000000;
272 break;
273 }
274
275 if (!bypass)
276 mainfreq = 200000000; /* PLL out frec */
277
278 if (usesysdiv)
279 stellaris_info->mck_freq = mainfreq/(1+sysdiv);
280 else
281 stellaris_info->mck_freq = mainfreq;
282
283 /* Forget old flash timing */
284 stellaris_set_flash_mode(bank,0);
285 }
286
287 /* Setup the timimg registers */
288 void stellaris_set_flash_mode(flash_bank_t *bank,int mode)
289 {
290 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
291 target_t *target = bank->target;
292
293 u32 usecrl = (stellaris_info->mck_freq/1000000ul-1);
294 DEBUG("usecrl = %i",usecrl);
295 target_write_u32(target, SCB_BASE|USECRL , usecrl);
296
297 }
298
299 u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
300 {
301 u32 status;
302
303 /* Stellaris waits for cmdbit to clear */
304 while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0))
305 {
306 DEBUG("status: 0x%x", status);
307 usleep(1000);
308 }
309
310 /* Flash errors are reflected in the FLASH_CRIS register */
311
312 return status;
313 }
314
315
316 /* Send one command to the flash controller */
317 int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
318 {
319 u32 fmc;
320 // stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
321 target_t *target = bank->target;
322
323 fmc = FMC_WRKEY | cmd;
324 target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc);
325 DEBUG("Flash command: 0x%x", fmc);
326
327 if (stellaris_wait_status_busy(bank, cmd, 100))
328 {
329 return ERROR_FLASH_OPERATION_FAILED;
330 }
331
332 return ERROR_OK;
333 }
334
335 /* Read device id register, main clock frequency register and fill in driver info structure */
336 int stellaris_read_part_info(struct flash_bank_s *bank)
337 {
338 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
339 target_t *target = bank->target;
340 u32 did0,did1, ver, fam, status;
341 int i;
342
343 /* Read and parse chip identification register */
344 target_read_u32(target, SCB_BASE|DID0, &did0);
345 target_read_u32(target, SCB_BASE|DID1, &did1);
346 target_read_u32(target, SCB_BASE|DC0, &stellaris_info->dc0);
347 target_read_u32(target, SCB_BASE|DC1, &stellaris_info->dc1);
348 DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x",did0, did1, stellaris_info->dc0,stellaris_info->dc1);
349
350 ver = did0 >> 28;
351 if((ver != 0) && (ver != 1))
352 {
353 WARNING("Unknown did0 version, cannot identify target");
354 return ERROR_FLASH_OPERATION_FAILED;
355 }
356
357 ver = did1 >> 28;
358 fam = (did1 >> 24) & 0xF;
359 if(((ver != 0) && (ver != 1)) || (fam != 0))
360 {
361 WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
362 }
363
364 if (did1 == 0)
365 {
366 WARNING("Cannot identify target as a Stellaris");
367 return ERROR_FLASH_OPERATION_FAILED;
368 }
369
370 for (i=0;StellarisParts[i].partno;i++)
371 {
372 if (StellarisParts[i].partno==((did1>>16)&0xFF))
373 break;
374 }
375
376 stellaris_info->target_name = StellarisParts[i].partname;
377
378 stellaris_info->did0 = did0;
379 stellaris_info->did1 = did1;
380
381 stellaris_info->num_lockbits = 1+stellaris_info->dc0&0xFFFF;
382 stellaris_info->num_pages = 2*(1+stellaris_info->dc0&0xFFFF);
383 stellaris_info->pagesize = 1024;
384 bank->size = 1024*stellaris_info->num_pages;
385 stellaris_info->pages_in_lockregion = 2;
386 target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
387
388 // Read main and master clock freqency register
389 stellaris_read_clock_info(bank);
390
391 status = stellaris_get_flash_status(bank);
392
393 return ERROR_OK;
394 }
395
396 /***************************************************************************
397 * flash operations *
398 ***************************************************************************/
399
400 int stellaris_erase_check(struct flash_bank_s *bank)
401 {
402 /*
403
404 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
405 target_t *target = bank->target;
406 int i;
407
408 */
409
410 return ERROR_OK;
411 }
412
413 int stellaris_protect_check(struct flash_bank_s *bank)
414 {
415 u32 status;
416
417 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
418
419 if (stellaris_info->did1 == 0)
420 {
421 stellaris_read_part_info(bank);
422 }
423
424 if (stellaris_info->did1 == 0)
425 {
426 WARNING("Cannot identify target as an AT91SAM");
427 return ERROR_FLASH_OPERATION_FAILED;
428 }
429
430 status = stellaris_get_flash_status(bank);
431 stellaris_info->lockbits = status >> 16;
432
433 return ERROR_OK;
434 }
435
436 int stellaris_erase(struct flash_bank_s *bank, int first, int last)
437 {
438 int banknr;
439 u32 flash_fmc, flash_cris;
440 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
441 target_t *target = bank->target;
442
443 if (bank->target->state != TARGET_HALTED)
444 {
445 return ERROR_TARGET_NOT_HALTED;
446 }
447
448 if (stellaris_info->did1 == 0)
449 {
450 stellaris_read_part_info(bank);
451 }
452
453 if (stellaris_info->did1 == 0)
454 {
455 WARNING("Cannot identify target as Stellaris");
456 return ERROR_FLASH_OPERATION_FAILED;
457 }
458
459 if ((first < 0) || (last < first) || (last >= stellaris_info->num_pages))
460 {
461 return ERROR_FLASH_SECTOR_INVALID;
462 }
463
464 /* Configure the flash controller timing */
465 stellaris_read_clock_info(bank);
466 stellaris_set_flash_mode(bank,0);
467
468 /* Clear and disable flash programming interrupts */
469 target_write_u32(target, FLASH_CIM, 0);
470 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
471
472 if ((first == 0) && (last == (stellaris_info->num_pages-1)))
473 {
474 target_write_u32(target, FLASH_FMA, 0);
475 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
476 /* Wait until erase complete */
477 do
478 {
479 target_read_u32(target, FLASH_FMC, &flash_fmc);
480 }
481 while(flash_fmc & FMC_MERASE);
482
483 /* if device has > 128k, then second erase cycle is needed */
484 if(stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
485 {
486 target_write_u32(target, FLASH_FMA, 0x20000);
487 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
488 /* Wait until erase complete */
489 do
490 {
491 target_read_u32(target, FLASH_FMC, &flash_fmc);
492 }
493 while(flash_fmc & FMC_MERASE);
494 }
495
496 return ERROR_OK;
497 }
498
499 for (banknr=first;banknr<=last;banknr++)
500 {
501 /* Address is first word in page */
502 target_write_u32(target, FLASH_FMA, banknr*stellaris_info->pagesize);
503 /* Write erase command */
504 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);
505 /* Wait until erase complete */
506 do
507 {
508 target_read_u32(target, FLASH_FMC, &flash_fmc);
509 }
510 while(flash_fmc & FMC_ERASE);
511
512 /* Check acess violations */
513 target_read_u32(target, FLASH_CRIS, &flash_cris);
514 if(flash_cris & (AMASK))
515 {
516 WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr, flash_cris);
517 target_write_u32(target, FLASH_CRIS, 0);
518 return ERROR_FLASH_OPERATION_FAILED;
519 }
520 }
521
522 return ERROR_OK;
523 }
524
525 int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last)
526 {
527 u32 fmppe, flash_fmc, flash_cris;
528 int lockregion;
529
530 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
531 target_t *target = bank->target;
532
533 if (bank->target->state != TARGET_HALTED)
534 {
535 return ERROR_TARGET_NOT_HALTED;
536 }
537
538 if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits))
539 {
540 return ERROR_FLASH_SECTOR_INVALID;
541 }
542
543 if (stellaris_info->did1 == 0)
544 {
545 stellaris_read_part_info(bank);
546 }
547
548 if (stellaris_info->did1 == 0)
549 {
550 WARNING("Cannot identify target as an Stellaris MCU");
551 return ERROR_FLASH_OPERATION_FAILED;
552 }
553
554 /* Configure the flash controller timing */
555 stellaris_read_clock_info(bank);
556 stellaris_set_flash_mode(bank,0);
557
558 fmppe = stellaris_info->lockbits;
559 for (lockregion=first;lockregion<=last;lockregion++)
560 {
561 if (set)
562 fmppe &= ~(1<<lockregion);
563 else
564 fmppe |= (1<<lockregion);
565 }
566
567 /* Clear and disable flash programming interrupts */
568 target_write_u32(target, FLASH_CIM, 0);
569 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
570
571 DEBUG("fmppe 0x%x",fmppe);
572 target_write_u32(target, SCB_BASE|FMPPE, fmppe);
573 /* Commit FMPPE */
574 target_write_u32(target, FLASH_FMA, 1);
575 /* Write commit command */
576 /* TODO safety check, sice this cannot be undone */
577 WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
578 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
579 /* Wait until erase complete */
580 do
581 {
582 target_read_u32(target, FLASH_FMC, &flash_fmc);
583 }
584 while(flash_fmc & FMC_COMT);
585
586 /* Check acess violations */
587 target_read_u32(target, FLASH_CRIS, &flash_cris);
588 if(flash_cris & (AMASK))
589 {
590 WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris);
591 target_write_u32(target, FLASH_CRIS, 0);
592 return ERROR_FLASH_OPERATION_FAILED;
593 }
594
595 target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
596
597 return ERROR_OK;
598 }
599
600 u8 stellaris_write_code[] =
601 {
602 /*
603 Call with :
604 r0 = buffer address
605 r1 = destination address
606 r2 = bytecount (in) - endaddr (work)
607
608 Used registers:
609 r3 = pFLASH_CTRL_BASE
610 r4 = FLASHWRITECMD
611 r5 = #1
612 r6 = bytes written
613 r7 = temp reg
614 */
615 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
616 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
617 0x01,0x25, /* movs r5, 1 */
618 0x00,0x26, /* movs r6, #0 */
619 /* mainloop: */
620 0x19,0x60, /* str r1, [r3, #0] */
621 0x87,0x59, /* ldr r7, [r0, r6] */
622 0x5F,0x60, /* str r7, [r3, #4] */
623 0x9C,0x60, /* str r4, [r3, #8] */
624 /* waitloop: */
625 0x9F,0x68, /* ldr r7, [r3, #8] */
626 0x2F,0x42, /* tst r7, r5 */
627 0xFC,0xD1, /* bne waitloop */
628 0x04,0x31, /* adds r1, r1, #4 */
629 0x04,0x36, /* adds r6, r6, #4 */
630 0x96,0x42, /* cmp r6, r2 */
631 0xF4,0xD1, /* bne mainloop */
632 0x00,0xBE, /* bkpt #0 */
633 /* pFLASH_CTRL_BASE: */
634 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
635 /* FLASHWRITECMD: */
636 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
637 };
638
639 int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 wcount)
640 {
641 // stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
642 target_t *target = bank->target;
643 u32 buffer_size = 8192;
644 working_area_t *source;
645 working_area_t *write_algorithm;
646 u32 address = bank->base + offset;
647 reg_param_t reg_params[8];
648 armv7m_algorithm_t armv7m_info;
649 int retval;
650
651 DEBUG("(bank=%08X buffer=%08X offset=%08X wcount=%08X)",
652 (unsigned int)bank, (unsigned int)buffer, offset, wcount);
653
654 /* flash write code */
655 if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
656 {
657 WARNING("no working area available, can't do block memory writes");
658 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
659 };
660
661 target_write_buffer(target, write_algorithm->address, sizeof(stellaris_write_code), stellaris_write_code);
662
663 /* memory buffer */
664 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
665 {
666 DEBUG("called target_alloc_working_area(target=%08X buffer_size=%08X source=%08X)",
667 (unsigned int)target, buffer_size, (unsigned int)source);
668 buffer_size /= 2;
669 if (buffer_size <= 256)
670 {
671 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
672 if (write_algorithm)
673 target_free_working_area(target, write_algorithm);
674
675 WARNING("no large enough working area available, can't do block memory writes");
676 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
677 }
678 };
679
680 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
681 armv7m_info.core_mode = ARMV7M_MODE_ANY;
682 armv7m_info.core_state = ARMV7M_STATE_THUMB;
683
684 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
685 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
686 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
687 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
688 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
689 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
690 init_reg_param(&reg_params[6], "r6", 32, PARAM_OUT);
691 init_reg_param(&reg_params[7], "r7", 32, PARAM_OUT);
692
693 while (wcount > 0)
694 {
695 u32 thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
696
697 target_write_buffer(target, source->address, thisrun_count * 4, buffer);
698
699 buf_set_u32(reg_params[0].value, 0, 32, source->address);
700 buf_set_u32(reg_params[1].value, 0, 32, address);
701 buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
702 WARNING("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count,address, wcount);
703 DEBUG("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count,address, wcount);
704 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)
705 {
706 ERROR("error executing stellaris flash write algorithm");
707 target_free_working_area(target, source);
708 destroy_reg_param(&reg_params[0]);
709 destroy_reg_param(&reg_params[1]);
710 destroy_reg_param(&reg_params[2]);
711 return ERROR_FLASH_OPERATION_FAILED;
712 }
713
714 buffer += thisrun_count * 4;
715 address += thisrun_count * 4;
716 wcount -= thisrun_count;
717 }
718
719
720 target_free_working_area(target, write_algorithm);
721 target_free_working_area(target, source);
722
723 destroy_reg_param(&reg_params[0]);
724 destroy_reg_param(&reg_params[1]);
725 destroy_reg_param(&reg_params[2]);
726 destroy_reg_param(&reg_params[3]);
727 destroy_reg_param(&reg_params[4]);
728 destroy_reg_param(&reg_params[5]);
729 destroy_reg_param(&reg_params[6]);
730 destroy_reg_param(&reg_params[7]);
731
732 return ERROR_OK;
733 }
734
735 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
736 {
737 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
738 target_t *target = bank->target;
739 u32 address = offset;
740 u32 flash_cris,flash_fmc;
741 u32 retval;
742
743 DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)",
744 (unsigned int)bank, (unsigned int)buffer, offset, count);
745
746 if (bank->target->state != TARGET_HALTED)
747 {
748 return ERROR_TARGET_NOT_HALTED;
749 }
750
751 if (stellaris_info->did1 == 0)
752 {
753 stellaris_read_part_info(bank);
754 }
755
756 if (stellaris_info->did1 == 0)
757 {
758 WARNING("Cannot identify target as a Stellaris processor");
759 return ERROR_FLASH_OPERATION_FAILED;
760 }
761
762 if((offset & 3) || (count & 3))
763 {
764 WARNING("offset size must be word aligned");
765 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
766 }
767
768 if (offset + count > bank->size)
769 return ERROR_FLASH_DST_OUT_OF_BANK;
770
771 /* Configure the flash controller timing */
772 stellaris_read_clock_info(bank);
773 stellaris_set_flash_mode(bank,0);
774
775
776 /* Clear and disable flash programming interrupts */
777 target_write_u32(target, FLASH_CIM, 0);
778 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
779
780 /* multiple words to be programmed? */
781 if (count > 0)
782 {
783 /* try using a block write */
784 if ((retval = stellaris_write_block(bank, buffer, offset, count/4)) != ERROR_OK)
785 {
786 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
787 {
788 /* if block write failed (no sufficient working area),
789 * we use normal (slow) single dword accesses */
790 WARNING("couldn't use block writes, falling back to single memory accesses");
791 }
792 else if (retval == ERROR_FLASH_OPERATION_FAILED)
793 {
794 /* if an error occured, we examine the reason, and quit */
795 target_read_u32(target, FLASH_CRIS, &flash_cris);
796
797 ERROR("flash writing failed with CRIS: 0x%x", flash_cris);
798 return ERROR_FLASH_OPERATION_FAILED;
799 }
800 }
801 else
802 {
803 buffer += count * 4;
804 address += count * 4;
805 count = 0;
806 }
807 }
808
809
810
811 while(count>0)
812 {
813 if (!(address&0xff)) DEBUG("0x%x",address);
814 /* Program one word */
815 target_write_u32(target, FLASH_FMA, address);
816 target_write_buffer(target, FLASH_FMD, 4, buffer);
817 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
818 //DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE);
819 /* Wait until write complete */
820 do
821 {
822 target_read_u32(target, FLASH_FMC, &flash_fmc);
823 }
824 while(flash_fmc & FMC_WRITE);
825 buffer += 4;
826 address += 4;
827 count -= 4;
828 }
829 /* Check acess violations */
830 target_read_u32(target, FLASH_CRIS, &flash_cris);
831 if(flash_cris & (AMASK))
832 {
833 DEBUG("flash_cris 0x%x", flash_cris);
834 return ERROR_FLASH_OPERATION_FAILED;
835 }
836 return ERROR_OK;
837 }
838
839
840 int stellaris_probe(struct flash_bank_s *bank)
841 {
842 /* we can't probe on an stellaris
843 * if this is an stellaris, it has the configured flash
844 */
845 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
846
847 if (stellaris_info->did1 == 0)
848 {
849 stellaris_read_part_info(bank);
850 }
851
852 if (stellaris_info->did1 == 0)
853 {
854 WARNING("Cannot identify target as a LMI Stellaris");
855 return ERROR_FLASH_OPERATION_FAILED;
856 }
857
858 return ERROR_OK;
859 }

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)