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

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)