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 ***************************************************************************/
32 #include "stellaris.h"
33 #include <target/algorithm.h>
34 #include <target/armv7m.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
);
42 static int stellaris_mass_erase(struct flash_bank
*bank
);
81 /*{0x33,"LM3S2616"},*/
201 static char * StellarisClassname
[5] =
210 /***************************************************************************
211 * openocd command interface *
212 ***************************************************************************/
214 /* flash_bank stellaris <base> <size> 0 0 <target#>
216 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
218 struct stellaris_flash_bank
*stellaris_info
;
222 LOG_WARNING("incomplete flash_bank stellaris configuration");
223 return ERROR_FLASH_BANK_INVALID
;
226 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
228 bank
->driver_priv
= stellaris_info
;
230 stellaris_info
->target_name
= "Unknown target";
232 /* part wasn't probed for info yet */
233 stellaris_info
->did1
= 0;
235 /* TODO Specify the main crystal speed in kHz using an optional
236 * argument; ditto, the speed of an external oscillator used
237 * instead of a crystal. Avoid programming flash using IOSC.
242 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
244 int printed
, device_class
;
245 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
247 stellaris_read_part_info(bank
);
249 if (stellaris_info
->did1
== 0)
251 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
254 return ERROR_FLASH_OPERATION_FAILED
;
257 if (DID0_VER(stellaris_info
->did0
) > 0)
259 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
265 printed
= snprintf(buf
,
267 "\nTI/LMI Stellaris information: Chip is "
268 "class %i (%s) %s rev %c%i\n",
270 StellarisClassname
[device_class
],
271 stellaris_info
->target_name
,
272 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
273 (int)((stellaris_info
->did0
) & 0xFF));
277 printed
= snprintf(buf
,
279 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
280 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
281 stellaris_info
->did1
,
282 stellaris_info
->did1
,
284 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
285 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
289 printed
= snprintf(buf
,
291 "master clock: %ikHz%s, "
292 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
293 (int)(stellaris_info
->mck_freq
/ 1000),
294 stellaris_info
->mck_desc
,
296 stellaris_info
->rcc2
);
300 if (stellaris_info
->num_lockbits
> 0)
302 printed
= snprintf(buf
,
304 "pagesize: %" PRIi32
", pages: %d, "
305 "lockbits: %i, pages per lockbit: %i\n",
306 stellaris_info
->pagesize
,
307 (unsigned) stellaris_info
->num_pages
,
308 stellaris_info
->num_lockbits
,
309 (unsigned) stellaris_info
->pages_in_lockregion
);
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 /* Setup the timimg registers */
331 static void stellaris_set_flash_mode(struct flash_bank
*bank
,int mode
)
333 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
334 struct target
*target
= bank
->target
;
335 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
337 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
338 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
341 static const unsigned rcc_xtal
[32] = {
342 [0x00] = 1000000, /* no pll */
343 [0x01] = 1843200, /* no pll */
344 [0x02] = 2000000, /* no pll */
345 [0x03] = 2457600, /* no pll */
349 [0x06] = 4000000, /* usb */
353 [0x09] = 5000000, /* usb */
355 [0x0b] = 6000000, /* (reset) usb */
359 [0x0e] = 8000000, /* usb */
362 /* parts before DustDevil use just 4 bits for xtal spec */
364 [0x10] = 10000000, /* usb */
365 [0x11] = 12000000, /* usb */
370 [0x15] = 16000000, /* usb */
374 /** Read clock configuration and set stellaris_info->usec_clocks. */
375 static void stellaris_read_clock_info(struct flash_bank
*bank
)
377 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
378 struct target
*target
= bank
->target
;
379 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
381 unsigned long mainfreq
;
383 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
384 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
386 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
387 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
389 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
390 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
392 stellaris_info
->rcc
= rcc
;
393 stellaris_info
->rcc
= rcc2
;
395 sysdiv
= (rcc
>> 23) & 0xF;
396 usesysdiv
= (rcc
>> 22) & 0x1;
397 bypass
= (rcc
>> 11) & 0x1;
398 oscsrc
= (rcc
>> 4) & 0x3;
399 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
401 /* NOTE: post-Sandstorm parts have RCC2 which may override
402 * parts of RCC ... with more sysdiv options, option for
403 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
404 * as zero, so the "use RCC2" flag is always clear.
406 if (rcc2
& (1 << 31)) {
407 sysdiv
= (rcc2
>> 23) & 0x3F;
408 bypass
= (rcc2
>> 11) & 0x1;
409 oscsrc
= (rcc2
>> 4) & 0x7;
411 /* FIXME Tempest parts have an additional lsb for
412 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
416 stellaris_info
->mck_desc
= "";
421 mainfreq
= rcc_xtal
[xtal
];
424 mainfreq
= stellaris_info
->iosc_freq
;
425 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
428 mainfreq
= stellaris_info
->iosc_freq
/ 4;
429 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
431 case 3: /* lowspeed */
432 /* Sandstorm doesn't have this 30K +/- 30% osc */
434 stellaris_info
->mck_desc
= " (±30%)";
436 case 8: /* hibernation osc */
437 /* not all parts support hibernation */
441 default: /* NOTREACHED */
446 /* PLL is used if it's not bypassed; its output is 200 MHz
447 * even when it runs at 400 MHz (adds divide-by-two stage).
450 mainfreq
= 200000000;
453 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
455 stellaris_info
->mck_freq
= mainfreq
;
457 /* Forget old flash timing */
458 stellaris_set_flash_mode(bank
, 0);
462 static uint32_t stellaris_wait_status_busy(struct flash_bank
*bank
, uint32_t waitbits
, int timeout
)
466 /* Stellaris waits for cmdbit to clear */
467 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
469 LOG_DEBUG("status: 0x%x", status
);
473 /* Flash errors are reflected in the FLASH_CRIS register */
478 /* Send one command to the flash controller */
479 static int stellaris_flash_command(struct flash_bank
*bank
,uint8_t cmd
,uint16_t pagen
)
482 struct target
*target
= bank
->target
;
484 fmc
= FMC_WRKEY
| cmd
;
485 target_write_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, fmc
);
486 LOG_DEBUG("Flash command: 0x%x", fmc
);
488 if (stellaris_wait_status_busy(bank
, cmd
, 100))
490 return ERROR_FLASH_OPERATION_FAILED
;
497 /* Read device id register, main clock frequency register and fill in driver info structure */
498 static int stellaris_read_part_info(struct flash_bank
*bank
)
500 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
501 struct target
*target
= bank
->target
;
502 uint32_t did0
, did1
, ver
, fam
, status
;
505 /* Read and parse chip identification register */
506 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
507 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
508 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
509 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
510 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
511 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
514 if ((ver
!= 0) && (ver
!= 1))
516 LOG_WARNING("Unknown did0 version, cannot identify target");
517 return ERROR_FLASH_OPERATION_FAILED
;
522 LOG_WARNING("Cannot identify target as a Stellaris");
523 return ERROR_FLASH_OPERATION_FAILED
;
527 fam
= (did1
>> 24) & 0xF;
528 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
530 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
533 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
534 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
535 * even give _both_ numbers! We'll use current numbers; IOSC is
536 * always approximate.
538 * For Tempest: IOSC is calibrated, 16 MHz
540 stellaris_info
->iosc_freq
= 12000000;
541 stellaris_info
->iosc_desc
= " (±30%)";
542 stellaris_info
->xtal_mask
= 0x0f;
544 switch ((did0
>> 28) & 0x7) {
545 case 0: /* Sandstorm */
547 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
548 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
549 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
551 if (((did0
>> 8) & 0xff) < 2) {
552 stellaris_info
->iosc_freq
= 15000000;
553 stellaris_info
->iosc_desc
= " (±50%)";
557 switch ((did0
>> 16) & 0xff) {
560 case 4: /* Tempest */
561 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
562 stellaris_info
->iosc_desc
= " (±1%)";
564 case 3: /* DustDevil */
565 stellaris_info
->xtal_mask
= 0x1f;
568 LOG_WARNING("Unknown did0 class");
572 LOG_WARNING("Unknown did0 version");
575 for (i
= 0; StellarisParts
[i
].partno
; i
++)
577 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
581 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
583 stellaris_info
->did0
= did0
;
584 stellaris_info
->did1
= did1
;
586 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
587 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
588 stellaris_info
->pagesize
= 1024;
589 bank
->size
= 1024 * stellaris_info
->num_pages
;
590 stellaris_info
->pages_in_lockregion
= 2;
592 /* provide this for the benefit of the higher flash driver layers */
593 bank
->num_sectors
= stellaris_info
->num_pages
;
594 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
595 for (i
= 0; i
< bank
->num_sectors
; i
++)
597 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
598 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
599 bank
->sectors
[i
].is_erased
= -1;
600 bank
->sectors
[i
].is_protected
= -1;
603 /* Read main and master clock freqency register */
604 stellaris_read_clock_info(bank
);
606 status
= stellaris_get_flash_status(bank
);
611 /***************************************************************************
613 ***************************************************************************/
615 static int stellaris_protect_check(struct flash_bank
*bank
)
617 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
618 int status
= ERROR_OK
;
622 if (stellaris
->did1
== 0)
624 status
= stellaris_read_part_info(bank
);
629 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
630 bank
->sectors
[i
].is_protected
= -1;
632 /* Read each Flash Memory Protection Program Enable (FMPPE) register
633 * to report any pages that we can't write. Ignore the Read Enable
636 for (i
= 0, page
= 0;
637 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
641 status
= target_read_u32(bank
->target
,
642 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
644 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
, lockbits
, status
);
645 if (status
!= ERROR_OK
)
648 for (unsigned j
= 0; j
< 32; j
++) {
651 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
652 if (page
>= (unsigned) bank
->num_sectors
)
654 bank
->sectors
[page
++].is_protected
=
655 !(lockbits
& (1 << j
));
664 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
667 uint32_t flash_fmc
, flash_cris
;
668 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
669 struct target
*target
= bank
->target
;
671 if (bank
->target
->state
!= TARGET_HALTED
)
673 LOG_ERROR("Target not halted");
674 return ERROR_TARGET_NOT_HALTED
;
677 if (stellaris_info
->did1
== 0)
679 stellaris_read_part_info(bank
);
682 if (stellaris_info
->did1
== 0)
684 LOG_WARNING("Cannot identify target as Stellaris");
685 return ERROR_FLASH_OPERATION_FAILED
;
688 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
690 return ERROR_FLASH_SECTOR_INVALID
;
693 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
695 return stellaris_mass_erase(bank
);
698 /* Configure the flash controller timing */
699 stellaris_read_clock_info(bank
);
700 stellaris_set_flash_mode(bank
,0);
702 /* Clear and disable flash programming interrupts */
703 target_write_u32(target
, FLASH_CIM
, 0);
704 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
706 for (banknr
= first
; banknr
<= last
; banknr
++)
708 /* Address is first word in page */
709 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
710 /* Write erase command */
711 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
712 /* Wait until erase complete */
715 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
717 while (flash_fmc
& FMC_ERASE
);
719 /* Check acess violations */
720 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
721 if (flash_cris
& (AMASK
))
723 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
724 target_write_u32(target
, FLASH_CRIS
, 0);
725 return ERROR_FLASH_OPERATION_FAILED
;
728 bank
->sectors
[banknr
].is_erased
= 1;
734 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
736 uint32_t fmppe
, flash_fmc
, flash_cris
;
739 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
740 struct target
*target
= bank
->target
;
742 if (bank
->target
->state
!= TARGET_HALTED
)
744 LOG_ERROR("Target not halted");
745 return ERROR_TARGET_NOT_HALTED
;
750 LOG_ERROR("Can't unprotect write-protected pages.");
751 /* except by the "recover locked device" procedure ... */
752 return ERROR_INVALID_ARGUMENTS
;
755 /* lockregions are 2 pages ... must protect [even..odd] */
756 if ((first
< 0) || (first
& 1)
757 || (last
< first
) || !(last
& 1)
758 || (last
>= 2 * stellaris_info
->num_lockbits
))
760 LOG_ERROR("Can't protect unaligned or out-of-range sectors.");
761 return ERROR_FLASH_SECTOR_INVALID
;
764 if (stellaris_info
->did1
== 0)
766 stellaris_read_part_info(bank
);
769 if (stellaris_info
->did1
== 0)
771 LOG_WARNING("Cannot identify target as an Stellaris MCU");
772 return ERROR_FLASH_OPERATION_FAILED
;
775 /* Configure the flash controller timing */
776 stellaris_read_clock_info(bank
);
777 stellaris_set_flash_mode(bank
, 0);
779 /* convert from pages to lockregions */
783 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
784 * Current parts can be much bigger.
787 LOG_ERROR("No support yet for protection > 64K");
788 return ERROR_FLASH_OPERATION_FAILED
;
791 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
793 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
794 fmppe
&= ~(1 << lockregion
);
796 /* Clear and disable flash programming interrupts */
797 target_write_u32(target
, FLASH_CIM
, 0);
798 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
800 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
801 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
804 target_write_u32(target
, FLASH_FMA
, 1);
806 /* Write commit command */
807 /* REVISIT safety check, since this cannot be undone
808 * except by the "Recover a locked device" procedure.
810 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
811 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
813 /* Wait until erase complete */
816 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
818 while (flash_fmc
& FMC_COMT
);
820 /* Check acess violations */
821 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
822 if (flash_cris
& (AMASK
))
824 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
825 target_write_u32(target
, FLASH_CRIS
, 0);
826 return ERROR_FLASH_OPERATION_FAILED
;
832 static const uint8_t stellaris_write_code
[] =
837 r1 = destination address
838 r2 = bytecount (in) - endaddr (work)
841 r3 = pFLASH_CTRL_BASE
847 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
848 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
849 0x01,0x25, /* movs r5, 1 */
850 0x00,0x26, /* movs r6, #0 */
852 0x19,0x60, /* str r1, [r3, #0] */
853 0x87,0x59, /* ldr r7, [r0, r6] */
854 0x5F,0x60, /* str r7, [r3, #4] */
855 0x9C,0x60, /* str r4, [r3, #8] */
857 0x9F,0x68, /* ldr r7, [r3, #8] */
858 0x2F,0x42, /* tst r7, r5 */
859 0xFC,0xD1, /* bne waitloop */
860 0x04,0x31, /* adds r1, r1, #4 */
861 0x04,0x36, /* adds r6, r6, #4 */
862 0x96,0x42, /* cmp r6, r2 */
863 0xF4,0xD1, /* bne mainloop */
865 0xFE,0xE7, /* b exit */
866 /* pFLASH_CTRL_BASE: */
867 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
869 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
872 static int stellaris_write_block(struct flash_bank
*bank
,
873 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
875 struct target
*target
= bank
->target
;
876 uint32_t buffer_size
= 8192;
877 struct working_area
*source
;
878 struct working_area
*write_algorithm
;
879 uint32_t address
= bank
->base
+ offset
;
880 struct reg_param reg_params
[3];
881 struct armv7m_algorithm armv7m_info
;
882 int retval
= ERROR_OK
;
884 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
885 bank
, buffer
, offset
, wcount
);
887 /* flash write code */
888 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
890 LOG_WARNING("no working area available, can't do block memory writes");
891 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
894 target_write_buffer(target
, write_algorithm
->address
,
895 sizeof(stellaris_write_code
),
896 (uint8_t *) stellaris_write_code
);
899 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
901 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
902 target
, buffer_size
, source
);
904 if (buffer_size
<= 256)
906 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
908 target_free_working_area(target
, write_algorithm
);
910 LOG_WARNING("no large enough working area available, can't do block memory writes");
911 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
915 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
916 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
918 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
919 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
920 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
924 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
926 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
928 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
929 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
930 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
931 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
932 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
933 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
)
935 LOG_ERROR("error executing stellaris flash write algorithm");
936 retval
= ERROR_FLASH_OPERATION_FAILED
;
940 buffer
+= thisrun_count
* 4;
941 address
+= thisrun_count
* 4;
942 wcount
-= thisrun_count
;
945 target_free_working_area(target
, write_algorithm
);
946 target_free_working_area(target
, source
);
948 destroy_reg_param(®_params
[0]);
949 destroy_reg_param(®_params
[1]);
950 destroy_reg_param(®_params
[2]);
955 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
957 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
958 struct target
*target
= bank
->target
;
959 uint32_t address
= offset
;
960 uint32_t flash_cris
, flash_fmc
;
961 uint32_t words_remaining
= (count
/ 4);
962 uint32_t bytes_remaining
= (count
& 0x00000003);
963 uint32_t bytes_written
= 0;
966 if (bank
->target
->state
!= TARGET_HALTED
)
968 LOG_ERROR("Target not halted");
969 return ERROR_TARGET_NOT_HALTED
;
972 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
973 bank
, buffer
, offset
, count
);
975 if (stellaris_info
->did1
== 0)
977 stellaris_read_part_info(bank
);
980 if (stellaris_info
->did1
== 0)
982 LOG_WARNING("Cannot identify target as a Stellaris processor");
983 return ERROR_FLASH_OPERATION_FAILED
;
988 LOG_WARNING("offset size must be word aligned");
989 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
992 if (offset
+ count
> bank
->size
)
993 return ERROR_FLASH_DST_OUT_OF_BANK
;
995 /* Configure the flash controller timing */
996 stellaris_read_clock_info(bank
);
997 stellaris_set_flash_mode(bank
, 0);
999 /* Clear and disable flash programming interrupts */
1000 target_write_u32(target
, FLASH_CIM
, 0);
1001 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1003 /* multiple words to be programmed? */
1004 if (words_remaining
> 0)
1006 /* try using a block write */
1007 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
1009 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1011 /* if block write failed (no sufficient working area),
1012 * we use normal (slow) single dword accesses */
1013 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
1015 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
1017 /* if an error occured, we examine the reason, and quit */
1018 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1020 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
1021 return ERROR_FLASH_OPERATION_FAILED
;
1026 buffer
+= words_remaining
* 4;
1027 address
+= words_remaining
* 4;
1028 words_remaining
= 0;
1032 while (words_remaining
> 0)
1034 if (!(address
& 0xff))
1035 LOG_DEBUG("0x%" PRIx32
"", address
);
1037 /* Program one word */
1038 target_write_u32(target
, FLASH_FMA
, address
);
1039 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1040 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1041 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1042 /* Wait until write complete */
1045 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1046 } while (flash_fmc
& FMC_WRITE
);
1053 if (bytes_remaining
)
1055 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1058 while (bytes_remaining
> 0)
1060 last_word
[i
++] = *(buffer
+ bytes_written
);
1065 if (!(address
& 0xff))
1066 LOG_DEBUG("0x%" PRIx32
"", address
);
1068 /* Program one word */
1069 target_write_u32(target
, FLASH_FMA
, address
);
1070 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1071 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1072 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1073 /* Wait until write complete */
1076 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1077 } while (flash_fmc
& FMC_WRITE
);
1080 /* Check access violations */
1081 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1082 if (flash_cris
& (AMASK
))
1084 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1085 return ERROR_FLASH_OPERATION_FAILED
;
1090 static int stellaris_probe(struct flash_bank
*bank
)
1092 /* we can't probe on an stellaris
1093 * if this is an stellaris, it has the configured flash
1096 if (bank
->target
->state
!= TARGET_HALTED
)
1098 LOG_ERROR("Target not halted");
1099 return ERROR_TARGET_NOT_HALTED
;
1102 /* stellaris_read_part_info() already takes care about error checking and reporting */
1103 return stellaris_read_part_info(bank
);
1106 static int stellaris_auto_probe(struct flash_bank
*bank
)
1108 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1109 if (stellaris_info
->did1
)
1111 return stellaris_probe(bank
);
1114 static int stellaris_mass_erase(struct flash_bank
*bank
)
1116 struct target
*target
= NULL
;
1117 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1120 stellaris_info
= bank
->driver_priv
;
1121 target
= bank
->target
;
1123 if (target
->state
!= TARGET_HALTED
)
1125 LOG_ERROR("Target not halted");
1126 return ERROR_TARGET_NOT_HALTED
;
1129 if (stellaris_info
->did1
== 0)
1131 stellaris_read_part_info(bank
);
1134 if (stellaris_info
->did1
== 0)
1136 LOG_WARNING("Cannot identify target as Stellaris");
1137 return ERROR_FLASH_OPERATION_FAILED
;
1140 /* Configure the flash controller timing */
1141 stellaris_read_clock_info(bank
);
1142 stellaris_set_flash_mode(bank
, 0);
1144 /* Clear and disable flash programming interrupts */
1145 target_write_u32(target
, FLASH_CIM
, 0);
1146 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1148 target_write_u32(target
, FLASH_FMA
, 0);
1149 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1150 /* Wait until erase complete */
1153 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1155 while (flash_fmc
& FMC_MERASE
);
1157 /* if device has > 128k, then second erase cycle is needed
1158 * this is only valid for older devices, but will not hurt */
1159 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1161 target_write_u32(target
, FLASH_FMA
, 0x20000);
1162 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1163 /* Wait until erase complete */
1166 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1168 while (flash_fmc
& FMC_MERASE
);
1174 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1180 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1184 struct flash_bank
*bank
;
1185 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1186 if (ERROR_OK
!= retval
)
1189 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1191 /* set all sectors as erased */
1192 for (i
= 0; i
< bank
->num_sectors
; i
++)
1194 bank
->sectors
[i
].is_erased
= 1;
1197 command_print(CMD_CTX
, "stellaris mass erase complete");
1201 command_print(CMD_CTX
, "stellaris mass erase failed");
1207 static const struct command_registration stellaris_exec_command_handlers
[] = {
1209 .name
= "mass_erase",
1210 .handler
= &stellaris_handle_mass_erase_command
,
1211 .mode
= COMMAND_EXEC
,
1212 .help
= "erase entire device",
1214 COMMAND_REGISTRATION_DONE
1216 static const struct command_registration stellaris_command_handlers
[] = {
1218 .name
= "stellaris",
1219 .mode
= COMMAND_ANY
,
1220 .help
= "Stellaris flash command group",
1221 .chain
= stellaris_exec_command_handlers
,
1223 COMMAND_REGISTRATION_DONE
1226 struct flash_driver stellaris_flash
= {
1227 .name
= "stellaris",
1228 .commands
= stellaris_command_handlers
,
1229 .flash_bank_command
= stellaris_flash_bank_command
,
1230 .erase
= stellaris_erase
,
1231 .protect
= stellaris_protect
,
1232 .write
= stellaris_write
,
1233 .probe
= stellaris_probe
,
1234 .auto_probe
= stellaris_auto_probe
,
1235 .erase_check
= default_flash_mem_blank_check
,
1236 .protect_check
= stellaris_protect_check
,
1237 .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)