1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
24 /***************************************************************************
25 * STELLARIS is tested on LM3S811, LM3S6965
26 ***************************************************************************/
31 #include "stellaris.h"
33 #include "binarybuffer.h"
34 #include "algorithm.h"
37 #define DID0_VER(did0) ((did0 >> 28)&0x07)
39 static int stellaris_read_part_info(struct flash_bank
*bank
);
40 static uint32_t stellaris_get_flash_status(struct flash_bank
*bank
);
41 static void stellaris_set_flash_mode(struct flash_bank
*bank
,int mode
);
42 //static uint32_t stellaris_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
44 static int stellaris_mass_erase(struct flash_bank
*bank
);
83 /*{0x33,"LM3S2616"},*/
202 static char * StellarisClassname
[5] =
211 /***************************************************************************
212 * openocd command interface *
213 ***************************************************************************/
215 /* flash_bank stellaris <base> <size> 0 0 <target#>
217 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
219 struct stellaris_flash_bank
*stellaris_info
;
223 LOG_WARNING("incomplete flash_bank stellaris configuration");
224 return ERROR_FLASH_BANK_INVALID
;
227 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
229 bank
->driver_priv
= stellaris_info
;
231 stellaris_info
->target_name
= "Unknown target";
233 /* part wasn't probed for info yet */
234 stellaris_info
->did1
= 0;
236 /* TODO Specify the main crystal speed in kHz using an optional
237 * argument; ditto, the speed of an external oscillator used
238 * instead of a crystal. Avoid programming flash using IOSC.
243 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
245 int printed
, device_class
;
246 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
248 stellaris_read_part_info(bank
);
250 if (stellaris_info
->did1
== 0)
252 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
255 return ERROR_FLASH_OPERATION_FAILED
;
258 if (DID0_VER(stellaris_info
->did0
) > 0)
260 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
266 printed
= snprintf(buf
,
268 "\nTI/LMI Stellaris information: Chip is "
269 "class %i (%s) %s rev %c%i\n",
271 StellarisClassname
[device_class
],
272 stellaris_info
->target_name
,
273 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
274 (int)((stellaris_info
->did0
) & 0xFF));
278 printed
= snprintf(buf
,
280 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
281 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
282 stellaris_info
->did1
,
283 stellaris_info
->did1
,
285 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
286 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
290 printed
= snprintf(buf
,
292 "master clock: %ikHz%s, "
293 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
294 (int)(stellaris_info
->mck_freq
/ 1000),
295 stellaris_info
->mck_desc
,
297 stellaris_info
->rcc2
);
301 if (stellaris_info
->num_lockbits
> 0)
303 printed
= snprintf(buf
,
305 "pagesize: %" PRIi32
", lockbits: %i 0x%4.4" PRIx32
", pages in lock region: %i \n",
306 stellaris_info
->pagesize
,
307 stellaris_info
->num_lockbits
,
308 stellaris_info
->lockbits
,
309 (int)(stellaris_info
->num_pages
/stellaris_info
->num_lockbits
));
316 /***************************************************************************
317 * chip identification and status *
318 ***************************************************************************/
320 static uint32_t stellaris_get_flash_status(struct flash_bank
*bank
)
322 struct target
*target
= bank
->target
;
325 target_read_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, &fmc
);
330 /** Read clock configuration and set stellaris_info->usec_clocks*/
332 static const unsigned rcc_xtal
[32] = {
333 [0x00] = 1000000, /* no pll */
334 [0x01] = 1843200, /* no pll */
335 [0x02] = 2000000, /* no pll */
336 [0x03] = 2457600, /* no pll */
340 [0x06] = 4000000, /* usb */
344 [0x09] = 5000000, /* usb */
346 [0x0b] = 6000000, /* (reset) usb */
350 [0x0e] = 8000000, /* usb */
353 /* parts before DustDevil use just 4 bits for xtal spec */
355 [0x10] = 10000000, /* usb */
356 [0x11] = 12000000, /* usb */
361 [0x15] = 16000000, /* usb */
365 static void stellaris_read_clock_info(struct flash_bank
*bank
)
367 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
368 struct target
*target
= bank
->target
;
369 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
371 unsigned long mainfreq
;
373 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
374 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
376 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
377 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
379 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
380 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
382 stellaris_info
->rcc
= rcc
;
383 stellaris_info
->rcc
= rcc2
;
385 sysdiv
= (rcc
>> 23) & 0xF;
386 usesysdiv
= (rcc
>> 22) & 0x1;
387 bypass
= (rcc
>> 11) & 0x1;
388 oscsrc
= (rcc
>> 4) & 0x3;
389 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
391 /* NOTE: post-Sandstorm parts have RCC2 which may override
392 * parts of RCC ... with more sysdiv options, option for
393 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
394 * as zero, so the "use RCC2" flag is always clear.
396 if (rcc2
& (1 << 31)) {
397 sysdiv
= (rcc2
>> 23) & 0x3F;
398 bypass
= (rcc2
>> 11) & 0x1;
399 oscsrc
= (rcc2
>> 4) & 0x7;
401 /* FIXME Tempest parts have an additional lsb for
402 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
406 stellaris_info
->mck_desc
= "";
411 mainfreq
= rcc_xtal
[xtal
];
414 mainfreq
= stellaris_info
->iosc_freq
;
415 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
418 mainfreq
= stellaris_info
->iosc_freq
/ 4;
419 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
421 case 3: /* lowspeed */
422 /* Sandstorm doesn't have this 30K +/- 30% osc */
424 stellaris_info
->mck_desc
= " (±30%)";
426 case 8: /* hibernation osc */
427 /* not all parts support hibernation */
431 default: /* NOTREACHED */
436 /* PLL is used if it's not bypassed; its output is 200 MHz
437 * even when it runs at 400 MHz (adds divide-by-two stage).
440 mainfreq
= 200000000;
443 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
445 stellaris_info
->mck_freq
= mainfreq
;
447 /* Forget old flash timing */
448 stellaris_set_flash_mode(bank
, 0);
451 /* Setup the timimg registers */
452 static void stellaris_set_flash_mode(struct flash_bank
*bank
,int mode
)
454 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
455 struct target
*target
= bank
->target
;
457 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
458 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
459 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
463 static uint32_t stellaris_wait_status_busy(struct flash_bank
*bank
, uint32_t waitbits
, int timeout
)
467 /* Stellaris waits for cmdbit to clear */
468 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
470 LOG_DEBUG("status: 0x%x", status
);
474 /* Flash errors are reflected in the FLASH_CRIS register */
479 /* Send one command to the flash controller */
480 static int stellaris_flash_command(struct flash_bank
*bank
,uint8_t cmd
,uint16_t pagen
)
483 struct target
*target
= bank
->target
;
485 fmc
= FMC_WRKEY
| cmd
;
486 target_write_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, fmc
);
487 LOG_DEBUG("Flash command: 0x%x", fmc
);
489 if (stellaris_wait_status_busy(bank
, cmd
, 100))
491 return ERROR_FLASH_OPERATION_FAILED
;
498 /* Read device id register, main clock frequency register and fill in driver info structure */
499 static int stellaris_read_part_info(struct flash_bank
*bank
)
501 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
502 struct target
*target
= bank
->target
;
503 uint32_t did0
, did1
, ver
, fam
, status
;
506 /* Read and parse chip identification register */
507 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
508 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
509 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
510 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
511 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
512 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
515 if ((ver
!= 0) && (ver
!= 1))
517 LOG_WARNING("Unknown did0 version, cannot identify target");
518 return ERROR_FLASH_OPERATION_FAILED
;
523 LOG_WARNING("Cannot identify target as a Stellaris");
524 return ERROR_FLASH_OPERATION_FAILED
;
528 fam
= (did1
>> 24) & 0xF;
529 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
531 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
534 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
535 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
536 * even give _both_ numbers! We'll use current numbers; IOSC is
537 * always approximate.
539 * For Tempest: IOSC is calibrated, 16 MHz
541 stellaris_info
->iosc_freq
= 12000000;
542 stellaris_info
->iosc_desc
= " (±30%)";
543 stellaris_info
->xtal_mask
= 0x0f;
545 switch ((did0
>> 28) & 0x7) {
546 case 0: /* Sandstorm */
548 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
549 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
550 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
552 if (((did0
>> 8) & 0xff) < 2) {
553 stellaris_info
->iosc_freq
= 15000000;
554 stellaris_info
->iosc_desc
= " (±50%)";
558 switch ((did0
>> 16) & 0xff) {
561 case 4: /* Tempest */
562 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
563 stellaris_info
->iosc_desc
= " (±1%)";
565 case 3: /* DustDevil */
566 stellaris_info
->xtal_mask
= 0x1f;
569 LOG_WARNING("Unknown did0 class");
573 LOG_WARNING("Unknown did0 version");
576 for (i
= 0; StellarisParts
[i
].partno
; i
++)
578 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
582 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
584 stellaris_info
->did0
= did0
;
585 stellaris_info
->did1
= did1
;
587 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
588 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
589 stellaris_info
->pagesize
= 1024;
590 bank
->size
= 1024 * stellaris_info
->num_pages
;
591 stellaris_info
->pages_in_lockregion
= 2;
592 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
594 /* provide this for the benefit of the higher flash driver layers */
595 bank
->num_sectors
= stellaris_info
->num_pages
;
596 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
597 for (i
= 0; i
< bank
->num_sectors
; i
++)
599 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
600 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
601 bank
->sectors
[i
].is_erased
= -1;
602 bank
->sectors
[i
].is_protected
= -1;
605 /* Read main and master clock freqency register */
606 stellaris_read_clock_info(bank
);
608 status
= stellaris_get_flash_status(bank
);
613 /***************************************************************************
615 ***************************************************************************/
617 static int stellaris_protect_check(struct flash_bank
*bank
)
621 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
623 if (bank
->target
->state
!= TARGET_HALTED
)
625 LOG_ERROR("Target not halted");
626 return ERROR_TARGET_NOT_HALTED
;
629 if (stellaris_info
->did1
== 0)
631 stellaris_read_part_info(bank
);
634 if (stellaris_info
->did1
== 0)
636 LOG_WARNING("Cannot identify target as Stellaris");
637 return ERROR_FLASH_OPERATION_FAILED
;
640 status
= stellaris_get_flash_status(bank
);
641 stellaris_info
->lockbits
= status
>> 16;
646 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
649 uint32_t flash_fmc
, flash_cris
;
650 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
651 struct target
*target
= bank
->target
;
653 if (bank
->target
->state
!= TARGET_HALTED
)
655 LOG_ERROR("Target not halted");
656 return ERROR_TARGET_NOT_HALTED
;
659 if (stellaris_info
->did1
== 0)
661 stellaris_read_part_info(bank
);
664 if (stellaris_info
->did1
== 0)
666 LOG_WARNING("Cannot identify target as Stellaris");
667 return ERROR_FLASH_OPERATION_FAILED
;
670 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
672 return ERROR_FLASH_SECTOR_INVALID
;
675 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
677 return stellaris_mass_erase(bank
);
680 /* Configure the flash controller timing */
681 stellaris_read_clock_info(bank
);
682 stellaris_set_flash_mode(bank
,0);
684 /* Clear and disable flash programming interrupts */
685 target_write_u32(target
, FLASH_CIM
, 0);
686 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
688 for (banknr
= first
; banknr
<= last
; banknr
++)
690 /* Address is first word in page */
691 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
692 /* Write erase command */
693 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
694 /* Wait until erase complete */
697 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
699 while (flash_fmc
& FMC_ERASE
);
701 /* Check acess violations */
702 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
703 if (flash_cris
& (AMASK
))
705 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
706 target_write_u32(target
, FLASH_CRIS
, 0);
707 return ERROR_FLASH_OPERATION_FAILED
;
710 bank
->sectors
[banknr
].is_erased
= 1;
716 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
718 uint32_t fmppe
, flash_fmc
, flash_cris
;
721 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
722 struct target
*target
= bank
->target
;
724 if (bank
->target
->state
!= TARGET_HALTED
)
726 LOG_ERROR("Target not halted");
727 return ERROR_TARGET_NOT_HALTED
;
730 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
732 return ERROR_FLASH_SECTOR_INVALID
;
735 if (stellaris_info
->did1
== 0)
737 stellaris_read_part_info(bank
);
740 if (stellaris_info
->did1
== 0)
742 LOG_WARNING("Cannot identify target as an Stellaris MCU");
743 return ERROR_FLASH_OPERATION_FAILED
;
746 /* Configure the flash controller timing */
747 stellaris_read_clock_info(bank
);
748 stellaris_set_flash_mode(bank
, 0);
750 fmppe
= stellaris_info
->lockbits
;
751 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
754 fmppe
&= ~(1 << lockregion
);
756 fmppe
|= (1 << lockregion
);
759 /* Clear and disable flash programming interrupts */
760 target_write_u32(target
, FLASH_CIM
, 0);
761 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
763 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
764 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
766 target_write_u32(target
, FLASH_FMA
, 1);
767 /* Write commit command */
768 /* TODO safety check, sice this cannot be undone */
769 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
770 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
771 /* Wait until erase complete */
774 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
776 while (flash_fmc
& FMC_COMT
);
778 /* Check acess violations */
779 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
780 if (flash_cris
& (AMASK
))
782 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
783 target_write_u32(target
, FLASH_CRIS
, 0);
784 return ERROR_FLASH_OPERATION_FAILED
;
787 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
792 static uint8_t stellaris_write_code
[] =
797 r1 = destination address
798 r2 = bytecount (in) - endaddr (work)
801 r3 = pFLASH_CTRL_BASE
807 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
808 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
809 0x01,0x25, /* movs r5, 1 */
810 0x00,0x26, /* movs r6, #0 */
812 0x19,0x60, /* str r1, [r3, #0] */
813 0x87,0x59, /* ldr r7, [r0, r6] */
814 0x5F,0x60, /* str r7, [r3, #4] */
815 0x9C,0x60, /* str r4, [r3, #8] */
817 0x9F,0x68, /* ldr r7, [r3, #8] */
818 0x2F,0x42, /* tst r7, r5 */
819 0xFC,0xD1, /* bne waitloop */
820 0x04,0x31, /* adds r1, r1, #4 */
821 0x04,0x36, /* adds r6, r6, #4 */
822 0x96,0x42, /* cmp r6, r2 */
823 0xF4,0xD1, /* bne mainloop */
825 0xFE,0xE7, /* b exit */
826 /* pFLASH_CTRL_BASE: */
827 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
829 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
832 static int stellaris_write_block(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
834 struct target
*target
= bank
->target
;
835 uint32_t buffer_size
= 8192;
836 struct working_area
*source
;
837 struct working_area
*write_algorithm
;
838 uint32_t address
= bank
->base
+ offset
;
839 struct reg_param reg_params
[3];
840 struct armv7m_algorithm armv7m_info
;
841 int retval
= ERROR_OK
;
843 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
844 bank
, buffer
, offset
, wcount
);
846 /* flash write code */
847 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
849 LOG_WARNING("no working area available, can't do block memory writes");
850 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
853 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
856 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
858 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
859 target
, buffer_size
, source
);
861 if (buffer_size
<= 256)
863 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
865 target_free_working_area(target
, write_algorithm
);
867 LOG_WARNING("no large enough working area available, can't do block memory writes");
868 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
872 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
873 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
875 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
876 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
877 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
881 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
883 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
885 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
886 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
887 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
888 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
889 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
890 if ((retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, write_algorithm
->address
, write_algorithm
->address
+ sizeof(stellaris_write_code
)-10, 10000, &armv7m_info
)) != ERROR_OK
)
892 LOG_ERROR("error executing stellaris flash write algorithm");
893 retval
= ERROR_FLASH_OPERATION_FAILED
;
897 buffer
+= thisrun_count
* 4;
898 address
+= thisrun_count
* 4;
899 wcount
-= thisrun_count
;
902 target_free_working_area(target
, write_algorithm
);
903 target_free_working_area(target
, source
);
905 destroy_reg_param(®_params
[0]);
906 destroy_reg_param(®_params
[1]);
907 destroy_reg_param(®_params
[2]);
912 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
914 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
915 struct target
*target
= bank
->target
;
916 uint32_t address
= offset
;
917 uint32_t flash_cris
, flash_fmc
;
918 uint32_t words_remaining
= (count
/ 4);
919 uint32_t bytes_remaining
= (count
& 0x00000003);
920 uint32_t bytes_written
= 0;
923 if (bank
->target
->state
!= TARGET_HALTED
)
925 LOG_ERROR("Target not halted");
926 return ERROR_TARGET_NOT_HALTED
;
929 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
930 bank
, buffer
, offset
, count
);
932 if (stellaris_info
->did1
== 0)
934 stellaris_read_part_info(bank
);
937 if (stellaris_info
->did1
== 0)
939 LOG_WARNING("Cannot identify target as a Stellaris processor");
940 return ERROR_FLASH_OPERATION_FAILED
;
945 LOG_WARNING("offset size must be word aligned");
946 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
949 if (offset
+ count
> bank
->size
)
950 return ERROR_FLASH_DST_OUT_OF_BANK
;
952 /* Configure the flash controller timing */
953 stellaris_read_clock_info(bank
);
954 stellaris_set_flash_mode(bank
, 0);
956 /* Clear and disable flash programming interrupts */
957 target_write_u32(target
, FLASH_CIM
, 0);
958 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
960 /* multiple words to be programmed? */
961 if (words_remaining
> 0)
963 /* try using a block write */
964 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
966 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
968 /* if block write failed (no sufficient working area),
969 * we use normal (slow) single dword accesses */
970 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
972 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
974 /* if an error occured, we examine the reason, and quit */
975 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
977 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
978 return ERROR_FLASH_OPERATION_FAILED
;
983 buffer
+= words_remaining
* 4;
984 address
+= words_remaining
* 4;
989 while (words_remaining
> 0)
991 if (!(address
& 0xff))
992 LOG_DEBUG("0x%" PRIx32
"", address
);
994 /* Program one word */
995 target_write_u32(target
, FLASH_FMA
, address
);
996 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
997 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
998 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
999 /* Wait until write complete */
1002 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1003 } while (flash_fmc
& FMC_WRITE
);
1010 if (bytes_remaining
)
1012 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1015 while (bytes_remaining
> 0)
1017 last_word
[i
++] = *(buffer
+ bytes_written
);
1022 if (!(address
& 0xff))
1023 LOG_DEBUG("0x%" PRIx32
"", address
);
1025 /* Program one word */
1026 target_write_u32(target
, FLASH_FMA
, address
);
1027 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1028 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1029 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1030 /* Wait until write complete */
1033 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1034 } while (flash_fmc
& FMC_WRITE
);
1037 /* Check access violations */
1038 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1039 if (flash_cris
& (AMASK
))
1041 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1042 return ERROR_FLASH_OPERATION_FAILED
;
1047 static int stellaris_probe(struct flash_bank
*bank
)
1049 /* we can't probe on an stellaris
1050 * if this is an stellaris, it has the configured flash
1053 if (bank
->target
->state
!= TARGET_HALTED
)
1055 LOG_ERROR("Target not halted");
1056 return ERROR_TARGET_NOT_HALTED
;
1059 /* stellaris_read_part_info() already takes care about error checking and reporting */
1060 return stellaris_read_part_info(bank
);
1063 static int stellaris_auto_probe(struct flash_bank
*bank
)
1065 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1066 if (stellaris_info
->did1
)
1068 return stellaris_probe(bank
);
1071 static int stellaris_mass_erase(struct flash_bank
*bank
)
1073 struct target
*target
= NULL
;
1074 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1077 stellaris_info
= bank
->driver_priv
;
1078 target
= bank
->target
;
1080 if (target
->state
!= TARGET_HALTED
)
1082 LOG_ERROR("Target not halted");
1083 return ERROR_TARGET_NOT_HALTED
;
1086 if (stellaris_info
->did1
== 0)
1088 stellaris_read_part_info(bank
);
1091 if (stellaris_info
->did1
== 0)
1093 LOG_WARNING("Cannot identify target as Stellaris");
1094 return ERROR_FLASH_OPERATION_FAILED
;
1097 /* Configure the flash controller timing */
1098 stellaris_read_clock_info(bank
);
1099 stellaris_set_flash_mode(bank
, 0);
1101 /* Clear and disable flash programming interrupts */
1102 target_write_u32(target
, FLASH_CIM
, 0);
1103 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1105 target_write_u32(target
, FLASH_FMA
, 0);
1106 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1107 /* Wait until erase complete */
1110 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1112 while (flash_fmc
& FMC_MERASE
);
1114 /* if device has > 128k, then second erase cycle is needed
1115 * this is only valid for older devices, but will not hurt */
1116 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1118 target_write_u32(target
, FLASH_FMA
, 0x20000);
1119 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1120 /* Wait until erase complete */
1123 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1125 while (flash_fmc
& FMC_MERASE
);
1131 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1137 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1141 struct flash_bank
*bank
;
1142 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1143 if (ERROR_OK
!= retval
)
1146 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1148 /* set all sectors as erased */
1149 for (i
= 0; i
< bank
->num_sectors
; i
++)
1151 bank
->sectors
[i
].is_erased
= 1;
1154 command_print(CMD_CTX
, "stellaris mass erase complete");
1158 command_print(CMD_CTX
, "stellaris mass erase failed");
1164 static const struct command_registration stellaris_exec_command_handlers
[] = {
1166 .name
= "mass_erase",
1167 .handler
= &stellaris_handle_mass_erase_command
,
1168 .mode
= COMMAND_EXEC
,
1169 .help
= "erase entire device",
1171 COMMAND_REGISTRATION_DONE
1173 static const struct command_registration stellaris_command_handlers
[] = {
1175 .name
= "stellaris",
1176 .mode
= COMMAND_ANY
,
1177 .help
= "Stellaris flash command group",
1178 .chain
= stellaris_exec_command_handlers
,
1180 COMMAND_REGISTRATION_DONE
1183 static int stellaris_register_commands(struct command_context
*cmd_ctx
)
1185 return register_commands(cmd_ctx
, NULL
, stellaris_command_handlers
);
1189 struct flash_driver stellaris_flash
= {
1190 .name
= "stellaris",
1191 .register_commands
= &stellaris_register_commands
,
1192 .flash_bank_command
= &stellaris_flash_bank_command
,
1193 .erase
= &stellaris_erase
,
1194 .protect
= &stellaris_protect
,
1195 .write
= &stellaris_write
,
1196 .probe
= &stellaris_probe
,
1197 .auto_probe
= &stellaris_auto_probe
,
1198 .erase_check
= &default_flash_mem_blank_check
,
1199 .protect_check
= &stellaris_protect_check
,
1200 .info
= &stellaris_info
,
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)