- Fixed display of sector sizes in flash.c
[openocd.git] / src / flash / stellaris.c
blob970c1d69eea45698468e69f7a249971fcb836f27
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 ***************************************************************************/
21 /***************************************************************************
22 * STELLARIS is tested on LM3S811
26 ***************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
31 #include "replacements.h"
33 #include "stellaris.h"
34 #include "cortex_m3.h"
36 #include "flash.h"
37 #include "target.h"
38 #include "log.h"
39 #include "binarybuffer.h"
40 #include "types.h"
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
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);
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);
62 int stellaris_read_part_info(struct flash_bank_s *bank);
64 flash_driver_t stellaris_flash =
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
79 struct {
80 u32 partno;
81 char *partname;
82 } StellarisParts[] =
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"}
133 char * StellarisClassname[2] =
135 "Sandstorm",
136 "Fury"
139 /***************************************************************************
140 * openocd command interface *
141 ***************************************************************************/
143 /* flash_bank stellaris <base> <size> 0 0 <target#>
145 int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
147 stellaris_flash_bank_t *stellaris_info;
149 if (argc < 6)
151 WARNING("incomplete flash_bank stellaris configuration");
152 return ERROR_FLASH_BANK_INVALID;
155 stellaris_info = calloc(sizeof(stellaris_flash_bank_t),1);
156 bank->base = 0x0;
157 bank->driver_priv = stellaris_info;
159 stellaris_info->target_name = "Unknown target";
161 /* part wasn't probed for info yet */
162 stellaris_info->did1 = 0;
164 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
165 return ERROR_OK;
168 int stellaris_register_commands(struct command_context_s *cmd_ctx)
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");
175 return ERROR_OK;
178 int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
180 int printed, device_class;
181 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
183 stellaris_read_part_info(bank);
185 if (stellaris_info->did1 == 0)
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;
193 if (DID0_VER(stellaris_info->did0)>0)
195 device_class = (stellaris_info->did0>>16)&0xFF;
197 else
199 device_class = 0;
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;
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;
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;
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;
221 return ERROR_OK;
224 /***************************************************************************
225 * chip identification and status *
226 ***************************************************************************/
228 u32 stellaris_get_flash_status(flash_bank_t *bank)
230 target_t *target = bank->target;
231 u32 fmc;
233 target_read_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, &fmc);
235 return fmc;
238 /** Read clock configuration and set stellaris_info->usec_clocks*/
240 void stellaris_read_clock_info(flash_bank_t *bank)
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;
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;
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)
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;
275 if (!bypass)
276 mainfreq = 200000000; /* PLL out frec */
278 if (usesysdiv)
279 stellaris_info->mck_freq = mainfreq/(1+sysdiv);
280 else
281 stellaris_info->mck_freq = mainfreq;
283 /* Forget old flash timing */
284 stellaris_set_flash_mode(bank,0);
287 /* Setup the timimg registers */
288 void stellaris_set_flash_mode(flash_bank_t *bank,int mode)
290 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
291 target_t *target = bank->target;
293 u32 usecrl = (stellaris_info->mck_freq/1000000ul-1);
294 DEBUG("usecrl = %i",usecrl);
295 target_write_u32(target, SCB_BASE|USECRL , usecrl);
299 u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
301 u32 status;
303 /* Stellaris waits for cmdbit to clear */
304 while (((status = stellaris_get_flash_status(bank)) & waitbits) && (timeout-- > 0))
306 DEBUG("status: 0x%x", status);
307 usleep(1000);
310 /* Flash errors are reflected in the FLASH_CRIS register */
312 return status;
316 /* Send one command to the flash controller */
317 int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
319 u32 fmc;
320 // stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
321 target_t *target = bank->target;
323 fmc = FMC_WRKEY | cmd;
324 target_write_u32(target, FLASH_CONTROL_BASE|FLASH_FMC, fmc);
325 DEBUG("Flash command: 0x%x", fmc);
327 if (stellaris_wait_status_busy(bank, cmd, 100))
329 return ERROR_FLASH_OPERATION_FAILED;
332 return ERROR_OK;
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)
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;
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);
350 ver = did0 >> 28;
351 if((ver != 0) && (ver != 1))
353 WARNING("Unknown did0 version, cannot identify target");
354 return ERROR_FLASH_OPERATION_FAILED;
357 ver = did1 >> 28;
358 fam = (did1 >> 24) & 0xF;
359 if(((ver != 0) && (ver != 1)) || (fam != 0))
361 WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
364 if (did1 == 0)
366 WARNING("Cannot identify target as a Stellaris");
367 return ERROR_FLASH_OPERATION_FAILED;
370 for (i=0;StellarisParts[i].partno;i++)
372 if (StellarisParts[i].partno==((did1>>16)&0xFF))
373 break;
376 stellaris_info->target_name = StellarisParts[i].partname;
378 stellaris_info->did0 = did0;
379 stellaris_info->did1 = did1;
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);
388 // Read main and master clock freqency register
389 stellaris_read_clock_info(bank);
391 status = stellaris_get_flash_status(bank);
393 return ERROR_OK;
396 /***************************************************************************
397 * flash operations *
398 ***************************************************************************/
400 int stellaris_erase_check(struct flash_bank_s *bank)
404 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
405 target_t *target = bank->target;
406 int i;
410 return ERROR_OK;
413 int stellaris_protect_check(struct flash_bank_s *bank)
415 u32 status;
417 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
419 if (stellaris_info->did1 == 0)
421 stellaris_read_part_info(bank);
424 if (stellaris_info->did1 == 0)
426 WARNING("Cannot identify target as an AT91SAM");
427 return ERROR_FLASH_OPERATION_FAILED;
430 status = stellaris_get_flash_status(bank);
431 stellaris_info->lockbits = status >> 16;
433 return ERROR_OK;
436 int stellaris_erase(struct flash_bank_s *bank, int first, int last)
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;
443 if (bank->target->state != TARGET_HALTED)
445 return ERROR_TARGET_NOT_HALTED;
448 if (stellaris_info->did1 == 0)
450 stellaris_read_part_info(bank);
453 if (stellaris_info->did1 == 0)
455 WARNING("Cannot identify target as Stellaris");
456 return ERROR_FLASH_OPERATION_FAILED;
459 if ((first < 0) || (last < first) || (last >= stellaris_info->num_pages))
461 return ERROR_FLASH_SECTOR_INVALID;
464 /* Configure the flash controller timing */
465 stellaris_read_clock_info(bank);
466 stellaris_set_flash_mode(bank,0);
468 /* Clear and disable flash programming interrupts */
469 target_write_u32(target, FLASH_CIM, 0);
470 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
472 if ((first == 0) && (last == (stellaris_info->num_pages-1)))
474 target_write_u32(target, FLASH_FMA, 0);
475 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
476 /* Wait until erase complete */
479 target_read_u32(target, FLASH_FMC, &flash_fmc);
481 while(flash_fmc & FMC_MERASE);
483 /* if device has > 128k, then second erase cycle is needed */
484 if(stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
486 target_write_u32(target, FLASH_FMA, 0x20000);
487 target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
488 /* Wait until erase complete */
491 target_read_u32(target, FLASH_FMC, &flash_fmc);
493 while(flash_fmc & FMC_MERASE);
496 return ERROR_OK;
499 for (banknr=first;banknr<=last;banknr++)
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 */
508 target_read_u32(target, FLASH_FMC, &flash_fmc);
510 while(flash_fmc & FMC_ERASE);
512 /* Check acess violations */
513 target_read_u32(target, FLASH_CRIS, &flash_cris);
514 if(flash_cris & (AMASK))
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;
522 return ERROR_OK;
525 int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last)
527 u32 fmppe, flash_fmc, flash_cris;
528 int lockregion;
530 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
531 target_t *target = bank->target;
533 if (bank->target->state != TARGET_HALTED)
535 return ERROR_TARGET_NOT_HALTED;
538 if ((first < 0) || (last < first) || (last >= stellaris_info->num_lockbits))
540 return ERROR_FLASH_SECTOR_INVALID;
543 if (stellaris_info->did1 == 0)
545 stellaris_read_part_info(bank);
548 if (stellaris_info->did1 == 0)
550 WARNING("Cannot identify target as an Stellaris MCU");
551 return ERROR_FLASH_OPERATION_FAILED;
554 /* Configure the flash controller timing */
555 stellaris_read_clock_info(bank);
556 stellaris_set_flash_mode(bank,0);
558 fmppe = stellaris_info->lockbits;
559 for (lockregion=first;lockregion<=last;lockregion++)
561 if (set)
562 fmppe &= ~(1<<lockregion);
563 else
564 fmppe |= (1<<lockregion);
567 /* Clear and disable flash programming interrupts */
568 target_write_u32(target, FLASH_CIM, 0);
569 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
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 */
582 target_read_u32(target, FLASH_FMC, &flash_fmc);
584 while(flash_fmc & FMC_COMT);
586 /* Check acess violations */
587 target_read_u32(target, FLASH_CRIS, &flash_cris);
588 if(flash_cris & (AMASK))
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;
595 target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
597 return ERROR_OK;
600 u8 stellaris_write_code[] =
603 Call with :
604 r0 = buffer address
605 r1 = destination address
606 r2 = bytecount (in) - endaddr (work)
608 Used registers:
609 r3 = pFLASH_CTRL_BASE
610 r4 = FLASHWRITECMD
611 r5 = #1
612 r6 = bytes written
613 r7 = temp reg
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 */
639 int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 wcount)
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;
651 DEBUG("(bank=%08X buffer=%08X offset=%08X wcount=%08X)",
652 (unsigned int)bank, (unsigned int)buffer, offset, wcount);
654 /* flash write code */
655 if (target_alloc_working_area(target, sizeof(stellaris_write_code), &write_algorithm) != ERROR_OK)
657 WARNING("no working area available, can't do block memory writes");
658 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
661 target_write_buffer(target, write_algorithm->address, sizeof(stellaris_write_code), stellaris_write_code);
663 /* memory buffer */
664 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
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)
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);
675 WARNING("no large enough working area available, can't do block memory writes");
676 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
680 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
681 armv7m_info.core_mode = ARMV7M_MODE_ANY;
682 armv7m_info.core_state = ARMV7M_STATE_THUMB;
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);
693 while (wcount > 0)
695 u32 thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
697 target_write_buffer(target, source->address, thisrun_count * 4, buffer);
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)
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;
714 buffer += thisrun_count * 4;
715 address += thisrun_count * 4;
716 wcount -= thisrun_count;
720 target_free_working_area(target, write_algorithm);
721 target_free_working_area(target, source);
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]);
732 return ERROR_OK;
735 int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
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;
743 DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)",
744 (unsigned int)bank, (unsigned int)buffer, offset, count);
746 if (bank->target->state != TARGET_HALTED)
748 return ERROR_TARGET_NOT_HALTED;
751 if (stellaris_info->did1 == 0)
753 stellaris_read_part_info(bank);
756 if (stellaris_info->did1 == 0)
758 WARNING("Cannot identify target as a Stellaris processor");
759 return ERROR_FLASH_OPERATION_FAILED;
762 if((offset & 3) || (count & 3))
764 WARNING("offset size must be word aligned");
765 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
768 if (offset + count > bank->size)
769 return ERROR_FLASH_DST_OUT_OF_BANK;
771 /* Configure the flash controller timing */
772 stellaris_read_clock_info(bank);
773 stellaris_set_flash_mode(bank,0);
776 /* Clear and disable flash programming interrupts */
777 target_write_u32(target, FLASH_CIM, 0);
778 target_write_u32(target, FLASH_MISC, PMISC|AMISC);
780 /* multiple words to be programmed? */
781 if (count > 0)
783 /* try using a block write */
784 if ((retval = stellaris_write_block(bank, buffer, offset, count/4)) != ERROR_OK)
786 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
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");
792 else if (retval == ERROR_FLASH_OPERATION_FAILED)
794 /* if an error occured, we examine the reason, and quit */
795 target_read_u32(target, FLASH_CRIS, &flash_cris);
797 ERROR("flash writing failed with CRIS: 0x%x", flash_cris);
798 return ERROR_FLASH_OPERATION_FAILED;
801 else
803 buffer += count * 4;
804 address += count * 4;
805 count = 0;
811 while(count>0)
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 */
822 target_read_u32(target, FLASH_FMC, &flash_fmc);
824 while(flash_fmc & FMC_WRITE);
825 buffer += 4;
826 address += 4;
827 count -= 4;
829 /* Check acess violations */
830 target_read_u32(target, FLASH_CRIS, &flash_cris);
831 if(flash_cris & (AMASK))
833 DEBUG("flash_cris 0x%x", flash_cris);
834 return ERROR_FLASH_OPERATION_FAILED;
836 return ERROR_OK;
840 int stellaris_probe(struct flash_bank_s *bank)
842 /* we can't probe on an stellaris
843 * if this is an stellaris, it has the configured flash
845 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
847 if (stellaris_info->did1 == 0)
849 stellaris_read_part_info(bank);
852 if (stellaris_info->did1 == 0)
854 WARNING("Cannot identify target as a LMI Stellaris");
855 return ERROR_FLASH_OPERATION_FAILED;
858 return ERROR_OK;