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 <helper/binarybuffer.h>
34 #include <target/algorithm.h>
35 #include <target/armv7m.h>
38 #define DID0_VER(did0) ((did0 >> 28)&0x07)
40 static int stellaris_read_part_info(struct flash_bank
*bank
);
41 static uint32_t stellaris_get_flash_status(struct flash_bank
*bank
);
42 static void stellaris_set_flash_mode(struct flash_bank
*bank
,int mode
);
43 //static uint32_t stellaris_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
45 static int stellaris_mass_erase(struct flash_bank
*bank
);
84 /*{0x33,"LM3S2616"},*/
203 static char * StellarisClassname
[5] =
212 /***************************************************************************
213 * openocd command interface *
214 ***************************************************************************/
216 /* flash_bank stellaris <base> <size> 0 0 <target#>
218 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
220 struct stellaris_flash_bank
*stellaris_info
;
224 LOG_WARNING("incomplete flash_bank stellaris configuration");
225 return ERROR_FLASH_BANK_INVALID
;
228 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
230 bank
->driver_priv
= stellaris_info
;
232 stellaris_info
->target_name
= "Unknown target";
234 /* part wasn't probed for info yet */
235 stellaris_info
->did1
= 0;
237 /* TODO Specify the main crystal speed in kHz using an optional
238 * argument; ditto, the speed of an external oscillator used
239 * instead of a crystal. Avoid programming flash using IOSC.
244 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
246 int printed
, device_class
;
247 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
249 stellaris_read_part_info(bank
);
251 if (stellaris_info
->did1
== 0)
253 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
256 return ERROR_FLASH_OPERATION_FAILED
;
259 if (DID0_VER(stellaris_info
->did0
) > 0)
261 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
267 printed
= snprintf(buf
,
269 "\nTI/LMI Stellaris information: Chip is "
270 "class %i (%s) %s rev %c%i\n",
272 StellarisClassname
[device_class
],
273 stellaris_info
->target_name
,
274 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
275 (int)((stellaris_info
->did0
) & 0xFF));
279 printed
= snprintf(buf
,
281 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
282 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
283 stellaris_info
->did1
,
284 stellaris_info
->did1
,
286 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
287 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
291 printed
= snprintf(buf
,
293 "master clock: %ikHz%s, "
294 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
295 (int)(stellaris_info
->mck_freq
/ 1000),
296 stellaris_info
->mck_desc
,
298 stellaris_info
->rcc2
);
302 if (stellaris_info
->num_lockbits
> 0)
304 printed
= snprintf(buf
,
306 "pagesize: %" PRIi32
", lockbits: %i 0x%4.4" PRIx32
", pages in lock region: %i \n",
307 stellaris_info
->pagesize
,
308 stellaris_info
->num_lockbits
,
309 stellaris_info
->lockbits
,
310 (int)(stellaris_info
->num_pages
/stellaris_info
->num_lockbits
));
317 /***************************************************************************
318 * chip identification and status *
319 ***************************************************************************/
321 static uint32_t stellaris_get_flash_status(struct flash_bank
*bank
)
323 struct target
*target
= bank
->target
;
326 target_read_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, &fmc
);
331 /** Read clock configuration and set stellaris_info->usec_clocks*/
333 static const unsigned rcc_xtal
[32] = {
334 [0x00] = 1000000, /* no pll */
335 [0x01] = 1843200, /* no pll */
336 [0x02] = 2000000, /* no pll */
337 [0x03] = 2457600, /* no pll */
341 [0x06] = 4000000, /* usb */
345 [0x09] = 5000000, /* usb */
347 [0x0b] = 6000000, /* (reset) usb */
351 [0x0e] = 8000000, /* usb */
354 /* parts before DustDevil use just 4 bits for xtal spec */
356 [0x10] = 10000000, /* usb */
357 [0x11] = 12000000, /* usb */
362 [0x15] = 16000000, /* usb */
366 static void stellaris_read_clock_info(struct flash_bank
*bank
)
368 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
369 struct target
*target
= bank
->target
;
370 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
372 unsigned long mainfreq
;
374 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
375 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
377 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
378 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
380 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
381 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
383 stellaris_info
->rcc
= rcc
;
384 stellaris_info
->rcc
= rcc2
;
386 sysdiv
= (rcc
>> 23) & 0xF;
387 usesysdiv
= (rcc
>> 22) & 0x1;
388 bypass
= (rcc
>> 11) & 0x1;
389 oscsrc
= (rcc
>> 4) & 0x3;
390 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
392 /* NOTE: post-Sandstorm parts have RCC2 which may override
393 * parts of RCC ... with more sysdiv options, option for
394 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
395 * as zero, so the "use RCC2" flag is always clear.
397 if (rcc2
& (1 << 31)) {
398 sysdiv
= (rcc2
>> 23) & 0x3F;
399 bypass
= (rcc2
>> 11) & 0x1;
400 oscsrc
= (rcc2
>> 4) & 0x7;
402 /* FIXME Tempest parts have an additional lsb for
403 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
407 stellaris_info
->mck_desc
= "";
412 mainfreq
= rcc_xtal
[xtal
];
415 mainfreq
= stellaris_info
->iosc_freq
;
416 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
419 mainfreq
= stellaris_info
->iosc_freq
/ 4;
420 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
422 case 3: /* lowspeed */
423 /* Sandstorm doesn't have this 30K +/- 30% osc */
425 stellaris_info
->mck_desc
= " (±30%)";
427 case 8: /* hibernation osc */
428 /* not all parts support hibernation */
432 default: /* NOTREACHED */
437 /* PLL is used if it's not bypassed; its output is 200 MHz
438 * even when it runs at 400 MHz (adds divide-by-two stage).
441 mainfreq
= 200000000;
444 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
446 stellaris_info
->mck_freq
= mainfreq
;
448 /* Forget old flash timing */
449 stellaris_set_flash_mode(bank
, 0);
452 /* Setup the timimg registers */
453 static void stellaris_set_flash_mode(struct flash_bank
*bank
,int mode
)
455 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
456 struct target
*target
= bank
->target
;
458 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
459 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
460 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
464 static uint32_t stellaris_wait_status_busy(struct flash_bank
*bank
, uint32_t waitbits
, int timeout
)
468 /* Stellaris waits for cmdbit to clear */
469 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
471 LOG_DEBUG("status: 0x%x", status
);
475 /* Flash errors are reflected in the FLASH_CRIS register */
480 /* Send one command to the flash controller */
481 static int stellaris_flash_command(struct flash_bank
*bank
,uint8_t cmd
,uint16_t pagen
)
484 struct target
*target
= bank
->target
;
486 fmc
= FMC_WRKEY
| cmd
;
487 target_write_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, fmc
);
488 LOG_DEBUG("Flash command: 0x%x", fmc
);
490 if (stellaris_wait_status_busy(bank
, cmd
, 100))
492 return ERROR_FLASH_OPERATION_FAILED
;
499 /* Read device id register, main clock frequency register and fill in driver info structure */
500 static int stellaris_read_part_info(struct flash_bank
*bank
)
502 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
503 struct target
*target
= bank
->target
;
504 uint32_t did0
, did1
, ver
, fam
, status
;
507 /* Read and parse chip identification register */
508 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
509 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
510 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
511 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
512 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
513 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
516 if ((ver
!= 0) && (ver
!= 1))
518 LOG_WARNING("Unknown did0 version, cannot identify target");
519 return ERROR_FLASH_OPERATION_FAILED
;
524 LOG_WARNING("Cannot identify target as a Stellaris");
525 return ERROR_FLASH_OPERATION_FAILED
;
529 fam
= (did1
>> 24) & 0xF;
530 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
532 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
535 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
536 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
537 * even give _both_ numbers! We'll use current numbers; IOSC is
538 * always approximate.
540 * For Tempest: IOSC is calibrated, 16 MHz
542 stellaris_info
->iosc_freq
= 12000000;
543 stellaris_info
->iosc_desc
= " (±30%)";
544 stellaris_info
->xtal_mask
= 0x0f;
546 switch ((did0
>> 28) & 0x7) {
547 case 0: /* Sandstorm */
549 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
550 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
551 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
553 if (((did0
>> 8) & 0xff) < 2) {
554 stellaris_info
->iosc_freq
= 15000000;
555 stellaris_info
->iosc_desc
= " (±50%)";
559 switch ((did0
>> 16) & 0xff) {
562 case 4: /* Tempest */
563 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
564 stellaris_info
->iosc_desc
= " (±1%)";
566 case 3: /* DustDevil */
567 stellaris_info
->xtal_mask
= 0x1f;
570 LOG_WARNING("Unknown did0 class");
574 LOG_WARNING("Unknown did0 version");
577 for (i
= 0; StellarisParts
[i
].partno
; i
++)
579 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
583 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
585 stellaris_info
->did0
= did0
;
586 stellaris_info
->did1
= did1
;
588 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
589 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
590 stellaris_info
->pagesize
= 1024;
591 bank
->size
= 1024 * stellaris_info
->num_pages
;
592 stellaris_info
->pages_in_lockregion
= 2;
593 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
595 /* provide this for the benefit of the higher flash driver layers */
596 bank
->num_sectors
= stellaris_info
->num_pages
;
597 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
598 for (i
= 0; i
< bank
->num_sectors
; i
++)
600 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
601 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
602 bank
->sectors
[i
].is_erased
= -1;
603 bank
->sectors
[i
].is_protected
= -1;
606 /* Read main and master clock freqency register */
607 stellaris_read_clock_info(bank
);
609 status
= stellaris_get_flash_status(bank
);
614 /***************************************************************************
616 ***************************************************************************/
618 static int stellaris_protect_check(struct flash_bank
*bank
)
622 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
624 if (bank
->target
->state
!= TARGET_HALTED
)
626 LOG_ERROR("Target not halted");
627 return ERROR_TARGET_NOT_HALTED
;
630 if (stellaris_info
->did1
== 0)
632 stellaris_read_part_info(bank
);
635 if (stellaris_info
->did1
== 0)
637 LOG_WARNING("Cannot identify target as Stellaris");
638 return ERROR_FLASH_OPERATION_FAILED
;
641 status
= stellaris_get_flash_status(bank
);
642 stellaris_info
->lockbits
= status
>> 16;
647 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
650 uint32_t flash_fmc
, flash_cris
;
651 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
652 struct target
*target
= bank
->target
;
654 if (bank
->target
->state
!= TARGET_HALTED
)
656 LOG_ERROR("Target not halted");
657 return ERROR_TARGET_NOT_HALTED
;
660 if (stellaris_info
->did1
== 0)
662 stellaris_read_part_info(bank
);
665 if (stellaris_info
->did1
== 0)
667 LOG_WARNING("Cannot identify target as Stellaris");
668 return ERROR_FLASH_OPERATION_FAILED
;
671 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
673 return ERROR_FLASH_SECTOR_INVALID
;
676 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
678 return stellaris_mass_erase(bank
);
681 /* Configure the flash controller timing */
682 stellaris_read_clock_info(bank
);
683 stellaris_set_flash_mode(bank
,0);
685 /* Clear and disable flash programming interrupts */
686 target_write_u32(target
, FLASH_CIM
, 0);
687 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
689 for (banknr
= first
; banknr
<= last
; banknr
++)
691 /* Address is first word in page */
692 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
693 /* Write erase command */
694 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
695 /* Wait until erase complete */
698 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
700 while (flash_fmc
& FMC_ERASE
);
702 /* Check acess violations */
703 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
704 if (flash_cris
& (AMASK
))
706 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
707 target_write_u32(target
, FLASH_CRIS
, 0);
708 return ERROR_FLASH_OPERATION_FAILED
;
711 bank
->sectors
[banknr
].is_erased
= 1;
717 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
719 uint32_t fmppe
, flash_fmc
, flash_cris
;
722 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
723 struct target
*target
= bank
->target
;
725 if (bank
->target
->state
!= TARGET_HALTED
)
727 LOG_ERROR("Target not halted");
728 return ERROR_TARGET_NOT_HALTED
;
731 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
733 return ERROR_FLASH_SECTOR_INVALID
;
736 if (stellaris_info
->did1
== 0)
738 stellaris_read_part_info(bank
);
741 if (stellaris_info
->did1
== 0)
743 LOG_WARNING("Cannot identify target as an Stellaris MCU");
744 return ERROR_FLASH_OPERATION_FAILED
;
747 /* Configure the flash controller timing */
748 stellaris_read_clock_info(bank
);
749 stellaris_set_flash_mode(bank
, 0);
751 fmppe
= stellaris_info
->lockbits
;
752 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
755 fmppe
&= ~(1 << lockregion
);
757 fmppe
|= (1 << lockregion
);
760 /* Clear and disable flash programming interrupts */
761 target_write_u32(target
, FLASH_CIM
, 0);
762 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
764 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
765 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
767 target_write_u32(target
, FLASH_FMA
, 1);
768 /* Write commit command */
769 /* TODO safety check, sice this cannot be undone */
770 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
771 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
772 /* Wait until erase complete */
775 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
777 while (flash_fmc
& FMC_COMT
);
779 /* Check acess violations */
780 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
781 if (flash_cris
& (AMASK
))
783 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
784 target_write_u32(target
, FLASH_CRIS
, 0);
785 return ERROR_FLASH_OPERATION_FAILED
;
788 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
793 static uint8_t stellaris_write_code
[] =
798 r1 = destination address
799 r2 = bytecount (in) - endaddr (work)
802 r3 = pFLASH_CTRL_BASE
808 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
809 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
810 0x01,0x25, /* movs r5, 1 */
811 0x00,0x26, /* movs r6, #0 */
813 0x19,0x60, /* str r1, [r3, #0] */
814 0x87,0x59, /* ldr r7, [r0, r6] */
815 0x5F,0x60, /* str r7, [r3, #4] */
816 0x9C,0x60, /* str r4, [r3, #8] */
818 0x9F,0x68, /* ldr r7, [r3, #8] */
819 0x2F,0x42, /* tst r7, r5 */
820 0xFC,0xD1, /* bne waitloop */
821 0x04,0x31, /* adds r1, r1, #4 */
822 0x04,0x36, /* adds r6, r6, #4 */
823 0x96,0x42, /* cmp r6, r2 */
824 0xF4,0xD1, /* bne mainloop */
826 0xFE,0xE7, /* b exit */
827 /* pFLASH_CTRL_BASE: */
828 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
830 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
833 static int stellaris_write_block(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
835 struct target
*target
= bank
->target
;
836 uint32_t buffer_size
= 8192;
837 struct working_area
*source
;
838 struct working_area
*write_algorithm
;
839 uint32_t address
= bank
->base
+ offset
;
840 struct reg_param reg_params
[3];
841 struct armv7m_algorithm armv7m_info
;
842 int retval
= ERROR_OK
;
844 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
845 bank
, buffer
, offset
, wcount
);
847 /* flash write code */
848 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
850 LOG_WARNING("no working area available, can't do block memory writes");
851 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
854 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
857 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
859 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
860 target
, buffer_size
, source
);
862 if (buffer_size
<= 256)
864 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
866 target_free_working_area(target
, write_algorithm
);
868 LOG_WARNING("no large enough working area available, can't do block memory writes");
869 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
873 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
874 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
876 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
877 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
878 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
882 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
884 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
886 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
887 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
888 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
889 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
890 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
891 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
)
893 LOG_ERROR("error executing stellaris flash write algorithm");
894 retval
= ERROR_FLASH_OPERATION_FAILED
;
898 buffer
+= thisrun_count
* 4;
899 address
+= thisrun_count
* 4;
900 wcount
-= thisrun_count
;
903 target_free_working_area(target
, write_algorithm
);
904 target_free_working_area(target
, source
);
906 destroy_reg_param(®_params
[0]);
907 destroy_reg_param(®_params
[1]);
908 destroy_reg_param(®_params
[2]);
913 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
915 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
916 struct target
*target
= bank
->target
;
917 uint32_t address
= offset
;
918 uint32_t flash_cris
, flash_fmc
;
919 uint32_t words_remaining
= (count
/ 4);
920 uint32_t bytes_remaining
= (count
& 0x00000003);
921 uint32_t bytes_written
= 0;
924 if (bank
->target
->state
!= TARGET_HALTED
)
926 LOG_ERROR("Target not halted");
927 return ERROR_TARGET_NOT_HALTED
;
930 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
931 bank
, buffer
, offset
, count
);
933 if (stellaris_info
->did1
== 0)
935 stellaris_read_part_info(bank
);
938 if (stellaris_info
->did1
== 0)
940 LOG_WARNING("Cannot identify target as a Stellaris processor");
941 return ERROR_FLASH_OPERATION_FAILED
;
946 LOG_WARNING("offset size must be word aligned");
947 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
950 if (offset
+ count
> bank
->size
)
951 return ERROR_FLASH_DST_OUT_OF_BANK
;
953 /* Configure the flash controller timing */
954 stellaris_read_clock_info(bank
);
955 stellaris_set_flash_mode(bank
, 0);
957 /* Clear and disable flash programming interrupts */
958 target_write_u32(target
, FLASH_CIM
, 0);
959 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
961 /* multiple words to be programmed? */
962 if (words_remaining
> 0)
964 /* try using a block write */
965 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
967 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
969 /* if block write failed (no sufficient working area),
970 * we use normal (slow) single dword accesses */
971 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
973 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
975 /* if an error occured, we examine the reason, and quit */
976 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
978 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
979 return ERROR_FLASH_OPERATION_FAILED
;
984 buffer
+= words_remaining
* 4;
985 address
+= words_remaining
* 4;
990 while (words_remaining
> 0)
992 if (!(address
& 0xff))
993 LOG_DEBUG("0x%" PRIx32
"", address
);
995 /* Program one word */
996 target_write_u32(target
, FLASH_FMA
, address
);
997 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
998 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
999 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1000 /* Wait until write complete */
1003 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1004 } while (flash_fmc
& FMC_WRITE
);
1011 if (bytes_remaining
)
1013 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1016 while (bytes_remaining
> 0)
1018 last_word
[i
++] = *(buffer
+ bytes_written
);
1023 if (!(address
& 0xff))
1024 LOG_DEBUG("0x%" PRIx32
"", address
);
1026 /* Program one word */
1027 target_write_u32(target
, FLASH_FMA
, address
);
1028 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1029 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1030 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1031 /* Wait until write complete */
1034 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1035 } while (flash_fmc
& FMC_WRITE
);
1038 /* Check access violations */
1039 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1040 if (flash_cris
& (AMASK
))
1042 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1043 return ERROR_FLASH_OPERATION_FAILED
;
1048 static int stellaris_probe(struct flash_bank
*bank
)
1050 /* we can't probe on an stellaris
1051 * if this is an stellaris, it has the configured flash
1054 if (bank
->target
->state
!= TARGET_HALTED
)
1056 LOG_ERROR("Target not halted");
1057 return ERROR_TARGET_NOT_HALTED
;
1060 /* stellaris_read_part_info() already takes care about error checking and reporting */
1061 return stellaris_read_part_info(bank
);
1064 static int stellaris_auto_probe(struct flash_bank
*bank
)
1066 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1067 if (stellaris_info
->did1
)
1069 return stellaris_probe(bank
);
1072 static int stellaris_mass_erase(struct flash_bank
*bank
)
1074 struct target
*target
= NULL
;
1075 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1078 stellaris_info
= bank
->driver_priv
;
1079 target
= bank
->target
;
1081 if (target
->state
!= TARGET_HALTED
)
1083 LOG_ERROR("Target not halted");
1084 return ERROR_TARGET_NOT_HALTED
;
1087 if (stellaris_info
->did1
== 0)
1089 stellaris_read_part_info(bank
);
1092 if (stellaris_info
->did1
== 0)
1094 LOG_WARNING("Cannot identify target as Stellaris");
1095 return ERROR_FLASH_OPERATION_FAILED
;
1098 /* Configure the flash controller timing */
1099 stellaris_read_clock_info(bank
);
1100 stellaris_set_flash_mode(bank
, 0);
1102 /* Clear and disable flash programming interrupts */
1103 target_write_u32(target
, FLASH_CIM
, 0);
1104 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1106 target_write_u32(target
, FLASH_FMA
, 0);
1107 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1108 /* Wait until erase complete */
1111 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1113 while (flash_fmc
& FMC_MERASE
);
1115 /* if device has > 128k, then second erase cycle is needed
1116 * this is only valid for older devices, but will not hurt */
1117 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1119 target_write_u32(target
, FLASH_FMA
, 0x20000);
1120 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1121 /* Wait until erase complete */
1124 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1126 while (flash_fmc
& FMC_MERASE
);
1132 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1138 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1142 struct flash_bank
*bank
;
1143 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1144 if (ERROR_OK
!= retval
)
1147 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1149 /* set all sectors as erased */
1150 for (i
= 0; i
< bank
->num_sectors
; i
++)
1152 bank
->sectors
[i
].is_erased
= 1;
1155 command_print(CMD_CTX
, "stellaris mass erase complete");
1159 command_print(CMD_CTX
, "stellaris mass erase failed");
1165 static const struct command_registration stellaris_exec_command_handlers
[] = {
1167 .name
= "mass_erase",
1168 .handler
= &stellaris_handle_mass_erase_command
,
1169 .mode
= COMMAND_EXEC
,
1170 .help
= "erase entire device",
1172 COMMAND_REGISTRATION_DONE
1174 static const struct command_registration stellaris_command_handlers
[] = {
1176 .name
= "stellaris",
1177 .mode
= COMMAND_ANY
,
1178 .help
= "Stellaris flash command group",
1179 .chain
= stellaris_exec_command_handlers
,
1181 COMMAND_REGISTRATION_DONE
1184 struct flash_driver stellaris_flash
= {
1185 .name
= "stellaris",
1186 .commands
= stellaris_command_handlers
,
1187 .flash_bank_command
= &stellaris_flash_bank_command
,
1188 .erase
= &stellaris_erase
,
1189 .protect
= &stellaris_protect
,
1190 .write
= &stellaris_write
,
1191 .probe
= &stellaris_probe
,
1192 .auto_probe
= &stellaris_auto_probe
,
1193 .erase_check
= &default_flash_mem_blank_check
,
1194 .protect_check
= &stellaris_protect_check
,
1195 .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)