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

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)