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
);
41 static int stellaris_mass_erase(struct flash_bank
*bank
);
218 static char * StellarisClassname
[5] =
227 /***************************************************************************
228 * openocd command interface *
229 ***************************************************************************/
231 /* flash_bank stellaris <base> <size> 0 0 <target#>
233 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
235 struct stellaris_flash_bank
*stellaris_info
;
239 LOG_WARNING("incomplete flash_bank stellaris configuration");
240 return ERROR_FLASH_BANK_INVALID
;
243 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
245 bank
->driver_priv
= stellaris_info
;
247 stellaris_info
->target_name
= "Unknown target";
249 /* part wasn't probed for info yet */
250 stellaris_info
->did1
= 0;
252 /* TODO Specify the main crystal speed in kHz using an optional
253 * argument; ditto, the speed of an external oscillator used
254 * instead of a crystal. Avoid programming flash using IOSC.
259 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
261 int printed
, device_class
;
262 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
264 stellaris_read_part_info(bank
);
266 if (stellaris_info
->did1
== 0)
268 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
271 return ERROR_FLASH_OPERATION_FAILED
;
274 if (DID0_VER(stellaris_info
->did0
) > 0)
276 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
282 printed
= snprintf(buf
,
284 "\nTI/LMI Stellaris information: Chip is "
285 "class %i (%s) %s rev %c%i\n",
287 StellarisClassname
[device_class
],
288 stellaris_info
->target_name
,
289 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
290 (int)((stellaris_info
->did0
) & 0xFF));
294 printed
= snprintf(buf
,
296 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
297 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
298 stellaris_info
->did1
,
299 stellaris_info
->did1
,
301 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
302 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
306 printed
= snprintf(buf
,
308 "master clock: %ikHz%s, "
309 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
310 (int)(stellaris_info
->mck_freq
/ 1000),
311 stellaris_info
->mck_desc
,
313 stellaris_info
->rcc2
);
317 if (stellaris_info
->num_lockbits
> 0)
319 printed
= snprintf(buf
,
321 "pagesize: %" PRIi32
", pages: %d, "
322 "lockbits: %i, pages per lockbit: %i\n",
323 stellaris_info
->pagesize
,
324 (unsigned) stellaris_info
->num_pages
,
325 stellaris_info
->num_lockbits
,
326 (unsigned) stellaris_info
->pages_in_lockregion
);
333 /***************************************************************************
334 * chip identification and status *
335 ***************************************************************************/
337 /* Set the flash timimg register to match current clocking */
338 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
340 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
341 struct target
*target
= bank
->target
;
342 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
344 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
345 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
348 static const unsigned rcc_xtal
[32] = {
349 [0x00] = 1000000, /* no pll */
350 [0x01] = 1843200, /* no pll */
351 [0x02] = 2000000, /* no pll */
352 [0x03] = 2457600, /* no pll */
356 [0x06] = 4000000, /* usb */
360 [0x09] = 5000000, /* usb */
362 [0x0b] = 6000000, /* (reset) usb */
366 [0x0e] = 8000000, /* usb */
369 /* parts before DustDevil use just 4 bits for xtal spec */
371 [0x10] = 10000000, /* usb */
372 [0x11] = 12000000, /* usb */
377 [0x15] = 16000000, /* usb */
381 /** Read clock configuration and set stellaris_info->usec_clocks. */
382 static void stellaris_read_clock_info(struct flash_bank
*bank
)
384 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
385 struct target
*target
= bank
->target
;
386 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
388 unsigned long mainfreq
;
390 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
391 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
393 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
394 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
396 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
397 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
399 stellaris_info
->rcc
= rcc
;
400 stellaris_info
->rcc
= rcc2
;
402 sysdiv
= (rcc
>> 23) & 0xF;
403 usesysdiv
= (rcc
>> 22) & 0x1;
404 bypass
= (rcc
>> 11) & 0x1;
405 oscsrc
= (rcc
>> 4) & 0x3;
406 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
408 /* NOTE: post-Sandstorm parts have RCC2 which may override
409 * parts of RCC ... with more sysdiv options, option for
410 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
411 * as zero, so the "use RCC2" flag is always clear.
413 if (rcc2
& (1 << 31)) {
414 sysdiv
= (rcc2
>> 23) & 0x3F;
415 bypass
= (rcc2
>> 11) & 0x1;
416 oscsrc
= (rcc2
>> 4) & 0x7;
418 /* FIXME Tempest parts have an additional lsb for
419 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
423 stellaris_info
->mck_desc
= "";
428 mainfreq
= rcc_xtal
[xtal
];
431 mainfreq
= stellaris_info
->iosc_freq
;
432 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
435 mainfreq
= stellaris_info
->iosc_freq
/ 4;
436 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
438 case 3: /* lowspeed */
439 /* Sandstorm doesn't have this 30K +/- 30% osc */
441 stellaris_info
->mck_desc
= " (±30%)";
443 case 8: /* hibernation osc */
444 /* not all parts support hibernation */
448 default: /* NOTREACHED */
453 /* PLL is used if it's not bypassed; its output is 200 MHz
454 * even when it runs at 400 MHz (adds divide-by-two stage).
457 mainfreq
= 200000000;
460 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
462 stellaris_info
->mck_freq
= mainfreq
;
465 /* Read device id register, main clock frequency register and fill in driver info structure */
466 static int stellaris_read_part_info(struct flash_bank
*bank
)
468 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
469 struct target
*target
= bank
->target
;
470 uint32_t did0
, did1
, ver
, fam
;
473 /* Read and parse chip identification register */
474 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
475 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
476 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
477 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
478 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
479 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
482 if ((ver
!= 0) && (ver
!= 1))
484 LOG_WARNING("Unknown did0 version, cannot identify target");
485 return ERROR_FLASH_OPERATION_FAILED
;
490 LOG_WARNING("Cannot identify target as a Stellaris");
491 return ERROR_FLASH_OPERATION_FAILED
;
495 fam
= (did1
>> 24) & 0xF;
496 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
498 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
501 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
502 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
503 * even give _both_ numbers! We'll use current numbers; IOSC is
504 * always approximate.
506 * For Tempest: IOSC is calibrated, 16 MHz
508 stellaris_info
->iosc_freq
= 12000000;
509 stellaris_info
->iosc_desc
= " (±30%)";
510 stellaris_info
->xtal_mask
= 0x0f;
512 switch ((did0
>> 28) & 0x7) {
513 case 0: /* Sandstorm */
515 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
516 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
517 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
519 if (((did0
>> 8) & 0xff) < 2) {
520 stellaris_info
->iosc_freq
= 15000000;
521 stellaris_info
->iosc_desc
= " (±50%)";
525 switch ((did0
>> 16) & 0xff) {
528 case 4: /* Tempest */
529 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
530 stellaris_info
->iosc_desc
= " (±1%)";
532 case 3: /* DustDevil */
533 stellaris_info
->xtal_mask
= 0x1f;
536 LOG_WARNING("Unknown did0 class");
540 LOG_WARNING("Unknown did0 version");
543 for (i
= 0; StellarisParts
[i
].partno
; i
++)
545 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
549 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
551 stellaris_info
->did0
= did0
;
552 stellaris_info
->did1
= did1
;
554 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
555 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
556 stellaris_info
->pagesize
= 1024;
557 bank
->size
= 1024 * stellaris_info
->num_pages
;
558 stellaris_info
->pages_in_lockregion
= 2;
560 /* provide this for the benefit of the higher flash driver layers */
561 bank
->num_sectors
= stellaris_info
->num_pages
;
562 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
563 for (i
= 0; i
< bank
->num_sectors
; i
++)
565 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
566 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
567 bank
->sectors
[i
].is_erased
= -1;
568 bank
->sectors
[i
].is_protected
= -1;
571 /* Read main and master clock freqency register */
572 stellaris_read_clock_info(bank
);
577 /***************************************************************************
579 ***************************************************************************/
581 static int stellaris_protect_check(struct flash_bank
*bank
)
583 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
584 int status
= ERROR_OK
;
588 if (stellaris
->did1
== 0)
590 status
= stellaris_read_part_info(bank
);
595 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
596 bank
->sectors
[i
].is_protected
= -1;
598 /* Read each Flash Memory Protection Program Enable (FMPPE) register
599 * to report any pages that we can't write. Ignore the Read Enable
602 for (i
= 0, page
= 0;
603 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
607 status
= target_read_u32(bank
->target
,
608 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
610 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
611 (unsigned) lockbits
, status
);
612 if (status
!= ERROR_OK
)
615 for (unsigned j
= 0; j
< 32; j
++) {
618 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
619 if (page
>= (unsigned) bank
->num_sectors
)
621 bank
->sectors
[page
++].is_protected
=
622 !(lockbits
& (1 << j
));
631 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
634 uint32_t flash_fmc
, flash_cris
;
635 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
636 struct target
*target
= bank
->target
;
638 if (bank
->target
->state
!= TARGET_HALTED
)
640 LOG_ERROR("Target not halted");
641 return ERROR_TARGET_NOT_HALTED
;
644 if (stellaris_info
->did1
== 0)
646 stellaris_read_part_info(bank
);
649 if (stellaris_info
->did1
== 0)
651 LOG_WARNING("Cannot identify target as Stellaris");
652 return ERROR_FLASH_OPERATION_FAILED
;
655 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
657 return ERROR_FLASH_SECTOR_INVALID
;
660 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
662 return stellaris_mass_erase(bank
);
665 /* Refresh flash controller timing */
666 stellaris_read_clock_info(bank
);
667 stellaris_set_flash_timing(bank
);
669 /* Clear and disable flash programming interrupts */
670 target_write_u32(target
, FLASH_CIM
, 0);
671 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
673 for (banknr
= first
; banknr
<= last
; banknr
++)
675 /* Address is first word in page */
676 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
677 /* Write erase command */
678 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
679 /* Wait until erase complete */
682 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
684 while (flash_fmc
& FMC_ERASE
);
686 /* Check acess violations */
687 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
688 if (flash_cris
& (AMASK
))
690 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
691 target_write_u32(target
, FLASH_CRIS
, 0);
692 return ERROR_FLASH_OPERATION_FAILED
;
695 bank
->sectors
[banknr
].is_erased
= 1;
701 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
703 uint32_t fmppe
, flash_fmc
, flash_cris
;
706 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
707 struct target
*target
= bank
->target
;
709 if (bank
->target
->state
!= TARGET_HALTED
)
711 LOG_ERROR("Target not halted");
712 return ERROR_TARGET_NOT_HALTED
;
717 LOG_ERROR("Can't unprotect write-protected pages.");
718 /* except by the "recover locked device" procedure ... */
719 return ERROR_INVALID_ARGUMENTS
;
722 /* lockregions are 2 pages ... must protect [even..odd] */
723 if ((first
< 0) || (first
& 1)
724 || (last
< first
) || !(last
& 1)
725 || (last
>= 2 * stellaris_info
->num_lockbits
))
727 LOG_ERROR("Can't protect unaligned or out-of-range sectors.");
728 return ERROR_FLASH_SECTOR_INVALID
;
731 if (stellaris_info
->did1
== 0)
733 stellaris_read_part_info(bank
);
736 if (stellaris_info
->did1
== 0)
738 LOG_WARNING("Cannot identify target as an Stellaris MCU");
739 return ERROR_FLASH_OPERATION_FAILED
;
742 /* Refresh flash controller timing */
743 stellaris_read_clock_info(bank
);
744 stellaris_set_flash_timing(bank
);
746 /* convert from pages to lockregions */
750 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
751 * Current parts can be much bigger.
754 LOG_ERROR("No support yet for protection > 64K");
755 return ERROR_FLASH_OPERATION_FAILED
;
758 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
760 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
761 fmppe
&= ~(1 << lockregion
);
763 /* Clear and disable flash programming interrupts */
764 target_write_u32(target
, FLASH_CIM
, 0);
765 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
767 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
768 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
771 target_write_u32(target
, FLASH_FMA
, 1);
773 /* Write commit command */
774 /* REVISIT safety check, since this cannot be undone
775 * except by the "Recover a locked device" procedure.
777 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
778 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
780 /* Wait until erase complete */
783 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
785 while (flash_fmc
& FMC_COMT
);
787 /* Check acess violations */
788 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
789 if (flash_cris
& (AMASK
))
791 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
792 target_write_u32(target
, FLASH_CRIS
, 0);
793 return ERROR_FLASH_OPERATION_FAILED
;
799 static const uint8_t stellaris_write_code
[] =
804 r1 = destination address
805 r2 = bytecount (in) - endaddr (work)
808 r3 = pFLASH_CTRL_BASE
814 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
815 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
816 0x01,0x25, /* movs r5, 1 */
817 0x00,0x26, /* movs r6, #0 */
819 0x19,0x60, /* str r1, [r3, #0] */
820 0x87,0x59, /* ldr r7, [r0, r6] */
821 0x5F,0x60, /* str r7, [r3, #4] */
822 0x9C,0x60, /* str r4, [r3, #8] */
824 0x9F,0x68, /* ldr r7, [r3, #8] */
825 0x2F,0x42, /* tst r7, r5 */
826 0xFC,0xD1, /* bne waitloop */
827 0x04,0x31, /* adds r1, r1, #4 */
828 0x04,0x36, /* adds r6, r6, #4 */
829 0x96,0x42, /* cmp r6, r2 */
830 0xF4,0xD1, /* bne mainloop */
832 0xFE,0xE7, /* b exit */
833 /* pFLASH_CTRL_BASE: */
834 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
836 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
839 static int stellaris_write_block(struct flash_bank
*bank
,
840 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
842 struct target
*target
= bank
->target
;
843 uint32_t buffer_size
= 8192;
844 struct working_area
*source
;
845 struct working_area
*write_algorithm
;
846 uint32_t address
= bank
->base
+ offset
;
847 struct reg_param reg_params
[3];
848 struct armv7m_algorithm armv7m_info
;
849 int retval
= ERROR_OK
;
851 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
852 bank
, buffer
, offset
, wcount
);
854 /* flash write code */
855 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
857 LOG_WARNING("no working area available, can't do block memory writes");
858 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
861 target_write_buffer(target
, write_algorithm
->address
,
862 sizeof(stellaris_write_code
),
863 (uint8_t *) stellaris_write_code
);
866 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
868 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
869 target
, buffer_size
, source
);
871 if (buffer_size
<= 256)
873 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
875 target_free_working_area(target
, write_algorithm
);
877 LOG_WARNING("no large enough working area available, can't do block memory writes");
878 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
882 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
883 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
885 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
886 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
887 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
891 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
893 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
895 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
896 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
897 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
898 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
899 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
900 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
)
902 LOG_ERROR("error executing stellaris flash write algorithm");
903 retval
= ERROR_FLASH_OPERATION_FAILED
;
907 buffer
+= thisrun_count
* 4;
908 address
+= thisrun_count
* 4;
909 wcount
-= thisrun_count
;
912 target_free_working_area(target
, write_algorithm
);
913 target_free_working_area(target
, source
);
915 destroy_reg_param(®_params
[0]);
916 destroy_reg_param(®_params
[1]);
917 destroy_reg_param(®_params
[2]);
922 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
924 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
925 struct target
*target
= bank
->target
;
926 uint32_t address
= offset
;
927 uint32_t flash_cris
, flash_fmc
;
928 uint32_t words_remaining
= (count
/ 4);
929 uint32_t bytes_remaining
= (count
& 0x00000003);
930 uint32_t bytes_written
= 0;
933 if (bank
->target
->state
!= TARGET_HALTED
)
935 LOG_ERROR("Target not halted");
936 return ERROR_TARGET_NOT_HALTED
;
939 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
940 bank
, buffer
, offset
, count
);
942 if (stellaris_info
->did1
== 0)
944 stellaris_read_part_info(bank
);
947 if (stellaris_info
->did1
== 0)
949 LOG_WARNING("Cannot identify target as a Stellaris processor");
950 return ERROR_FLASH_OPERATION_FAILED
;
955 LOG_WARNING("offset size must be word aligned");
956 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
959 if (offset
+ count
> bank
->size
)
960 return ERROR_FLASH_DST_OUT_OF_BANK
;
962 /* Refresh flash controller timing */
963 stellaris_read_clock_info(bank
);
964 stellaris_set_flash_timing(bank
);
966 /* Clear and disable flash programming interrupts */
967 target_write_u32(target
, FLASH_CIM
, 0);
968 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
970 /* multiple words to be programmed? */
971 if (words_remaining
> 0)
973 /* try using a block write */
974 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
976 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
978 /* if block write failed (no sufficient working area),
979 * we use normal (slow) single dword accesses */
980 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
982 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
984 /* if an error occured, we examine the reason, and quit */
985 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
987 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
988 return ERROR_FLASH_OPERATION_FAILED
;
993 buffer
+= words_remaining
* 4;
994 address
+= words_remaining
* 4;
999 while (words_remaining
> 0)
1001 if (!(address
& 0xff))
1002 LOG_DEBUG("0x%" PRIx32
"", address
);
1004 /* Program one word */
1005 target_write_u32(target
, FLASH_FMA
, address
);
1006 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1007 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1008 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1009 /* Wait until write complete */
1012 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1013 } while (flash_fmc
& FMC_WRITE
);
1020 if (bytes_remaining
)
1022 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1025 while (bytes_remaining
> 0)
1027 last_word
[i
++] = *(buffer
+ bytes_written
);
1032 if (!(address
& 0xff))
1033 LOG_DEBUG("0x%" PRIx32
"", address
);
1035 /* Program one word */
1036 target_write_u32(target
, FLASH_FMA
, address
);
1037 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1038 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1039 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1040 /* Wait until write complete */
1043 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1044 } while (flash_fmc
& FMC_WRITE
);
1047 /* Check access violations */
1048 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1049 if (flash_cris
& (AMASK
))
1051 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1052 return ERROR_FLASH_OPERATION_FAILED
;
1057 static int stellaris_probe(struct flash_bank
*bank
)
1059 /* we can't probe on an stellaris
1060 * if this is an stellaris, it has the configured flash
1063 if (bank
->target
->state
!= TARGET_HALTED
)
1065 LOG_ERROR("Target not halted");
1066 return ERROR_TARGET_NOT_HALTED
;
1069 /* stellaris_read_part_info() already takes care about error checking and reporting */
1070 return stellaris_read_part_info(bank
);
1073 static int stellaris_auto_probe(struct flash_bank
*bank
)
1075 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1076 if (stellaris_info
->did1
)
1078 return stellaris_probe(bank
);
1081 static int stellaris_mass_erase(struct flash_bank
*bank
)
1083 struct target
*target
= NULL
;
1084 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1087 stellaris_info
= bank
->driver_priv
;
1088 target
= bank
->target
;
1090 if (target
->state
!= TARGET_HALTED
)
1092 LOG_ERROR("Target not halted");
1093 return ERROR_TARGET_NOT_HALTED
;
1096 if (stellaris_info
->did1
== 0)
1098 stellaris_read_part_info(bank
);
1101 if (stellaris_info
->did1
== 0)
1103 LOG_WARNING("Cannot identify target as Stellaris");
1104 return ERROR_FLASH_OPERATION_FAILED
;
1107 /* Refresh flash controller timing */
1108 stellaris_read_clock_info(bank
);
1109 stellaris_set_flash_timing(bank
);
1111 /* Clear and disable flash programming interrupts */
1112 target_write_u32(target
, FLASH_CIM
, 0);
1113 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1115 target_write_u32(target
, FLASH_FMA
, 0);
1116 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1117 /* Wait until erase complete */
1120 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1122 while (flash_fmc
& FMC_MERASE
);
1124 /* if device has > 128k, then second erase cycle is needed
1125 * this is only valid for older devices, but will not hurt */
1126 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1128 target_write_u32(target
, FLASH_FMA
, 0x20000);
1129 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1130 /* Wait until erase complete */
1133 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1135 while (flash_fmc
& FMC_MERASE
);
1141 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1147 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1151 struct flash_bank
*bank
;
1152 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1153 if (ERROR_OK
!= retval
)
1156 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1158 /* set all sectors as erased */
1159 for (i
= 0; i
< bank
->num_sectors
; i
++)
1161 bank
->sectors
[i
].is_erased
= 1;
1164 command_print(CMD_CTX
, "stellaris mass erase complete");
1168 command_print(CMD_CTX
, "stellaris mass erase failed");
1174 static const struct command_registration stellaris_exec_command_handlers
[] = {
1176 .name
= "mass_erase",
1177 .handler
= &stellaris_handle_mass_erase_command
,
1178 .mode
= COMMAND_EXEC
,
1179 .help
= "erase entire device",
1181 COMMAND_REGISTRATION_DONE
1183 static const struct command_registration stellaris_command_handlers
[] = {
1185 .name
= "stellaris",
1186 .mode
= COMMAND_ANY
,
1187 .help
= "Stellaris flash command group",
1188 .chain
= stellaris_exec_command_handlers
,
1190 COMMAND_REGISTRATION_DONE
1193 struct flash_driver stellaris_flash
= {
1194 .name
= "stellaris",
1195 .commands
= stellaris_command_handlers
,
1196 .flash_bank_command
= stellaris_flash_bank_command
,
1197 .erase
= stellaris_erase
,
1198 .protect
= stellaris_protect
,
1199 .write
= stellaris_write
,
1200 .probe
= stellaris_probe
,
1201 .auto_probe
= stellaris_auto_probe
,
1202 .erase_check
= default_flash_mem_blank_check
,
1203 .protect_check
= stellaris_protect_check
,
1204 .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)