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"
36 #define DID0_VER(did0) ((did0 >> 28)&0x07)
38 static int stellaris_read_part_info(struct flash_bank_s
*bank
);
39 static uint32_t stellaris_get_flash_status(flash_bank_t
*bank
);
40 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
41 //static uint32_t stellaris_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
43 static int stellaris_mass_erase(struct flash_bank_s
*bank
);
82 /*{0x33,"LM3S2616"},*/
201 static char * StellarisClassname
[5] =
210 /***************************************************************************
211 * openocd command interface *
212 ***************************************************************************/
214 /* flash_bank stellaris <base> <size> 0 0 <target#>
216 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
218 stellaris_flash_bank_t
*stellaris_info
;
222 LOG_WARNING("incomplete flash_bank stellaris configuration");
223 return ERROR_FLASH_BANK_INVALID
;
226 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
), 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_s
*bank
, char *buf
, int buf_size
)
244 int printed
, device_class
;
245 stellaris_flash_bank_t
*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
", lockbits: %i 0x%4.4" PRIx32
", pages in lock region: %i \n",
305 stellaris_info
->pagesize
,
306 stellaris_info
->num_lockbits
,
307 stellaris_info
->lockbits
,
308 (int)(stellaris_info
->num_pages
/stellaris_info
->num_lockbits
));
315 /***************************************************************************
316 * chip identification and status *
317 ***************************************************************************/
319 static uint32_t stellaris_get_flash_status(flash_bank_t
*bank
)
321 target_t
*target
= bank
->target
;
324 target_read_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, &fmc
);
329 /** Read clock configuration and set stellaris_info->usec_clocks*/
331 static const unsigned rcc_xtal
[32] = {
332 [0x00] = 1000000, /* no pll */
333 [0x01] = 1843200, /* no pll */
334 [0x02] = 2000000, /* no pll */
335 [0x03] = 2457600, /* no pll */
339 [0x06] = 4000000, /* usb */
343 [0x09] = 5000000, /* usb */
345 [0x0b] = 6000000, /* (reset) usb */
349 [0x0e] = 8000000, /* usb */
352 /* parts before DustDevil use just 4 bits for xtal spec */
354 [0x10] = 10000000, /* usb */
355 [0x11] = 12000000, /* usb */
360 [0x15] = 16000000, /* usb */
364 static void stellaris_read_clock_info(flash_bank_t
*bank
)
366 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
367 target_t
*target
= bank
->target
;
368 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
370 unsigned long mainfreq
;
372 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
373 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
375 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
376 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
378 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
379 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
381 stellaris_info
->rcc
= rcc
;
382 stellaris_info
->rcc
= rcc2
;
384 sysdiv
= (rcc
>> 23) & 0xF;
385 usesysdiv
= (rcc
>> 22) & 0x1;
386 bypass
= (rcc
>> 11) & 0x1;
387 oscsrc
= (rcc
>> 4) & 0x3;
388 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
390 /* NOTE: post-Sandstorm parts have RCC2 which may override
391 * parts of RCC ... with more sysdiv options, option for
392 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
393 * as zero, so the "use RCC2" flag is always clear.
395 if (rcc2
& (1 << 31)) {
396 sysdiv
= (rcc2
>> 23) & 0x3F;
397 bypass
= (rcc2
>> 11) & 0x1;
398 oscsrc
= (rcc2
>> 4) & 0x7;
400 /* FIXME Tempest parts have an additional lsb for
401 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
405 stellaris_info
->mck_desc
= "";
410 mainfreq
= rcc_xtal
[xtal
];
413 mainfreq
= stellaris_info
->iosc_freq
;
414 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
417 mainfreq
= stellaris_info
->iosc_freq
/ 4;
418 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
420 case 3: /* lowspeed */
421 /* Sandstorm doesn't have this 30K +/- 30% osc */
423 stellaris_info
->mck_desc
= " (±30%)";
425 case 8: /* hibernation osc */
426 /* not all parts support hibernation */
430 default: /* NOTREACHED */
435 /* PLL is used if it's not bypassed; its output is 200 MHz
436 * even when it runs at 400 MHz (adds divide-by-two stage).
439 mainfreq
= 200000000;
442 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
444 stellaris_info
->mck_freq
= mainfreq
;
446 /* Forget old flash timing */
447 stellaris_set_flash_mode(bank
, 0);
450 /* Setup the timimg registers */
451 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
453 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
454 target_t
*target
= bank
->target
;
456 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
457 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
458 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
462 static uint32_t stellaris_wait_status_busy(flash_bank_t
*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_s
*bank
,uint8_t cmd
,uint16_t pagen
)
482 target_t
*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_s
*bank
)
500 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
501 target_t
*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;
591 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
593 /* provide this for the benefit of the higher flash driver layers */
594 bank
->num_sectors
= stellaris_info
->num_pages
;
595 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
596 for (i
= 0; i
< bank
->num_sectors
; i
++)
598 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
599 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
600 bank
->sectors
[i
].is_erased
= -1;
601 bank
->sectors
[i
].is_protected
= -1;
604 /* Read main and master clock freqency register */
605 stellaris_read_clock_info(bank
);
607 status
= stellaris_get_flash_status(bank
);
612 /***************************************************************************
614 ***************************************************************************/
616 static int stellaris_protect_check(struct flash_bank_s
*bank
)
620 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
622 if (bank
->target
->state
!= TARGET_HALTED
)
624 LOG_ERROR("Target not halted");
625 return ERROR_TARGET_NOT_HALTED
;
628 if (stellaris_info
->did1
== 0)
630 stellaris_read_part_info(bank
);
633 if (stellaris_info
->did1
== 0)
635 LOG_WARNING("Cannot identify target as Stellaris");
636 return ERROR_FLASH_OPERATION_FAILED
;
639 status
= stellaris_get_flash_status(bank
);
640 stellaris_info
->lockbits
= status
>> 16;
645 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
648 uint32_t flash_fmc
, flash_cris
;
649 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
650 target_t
*target
= bank
->target
;
652 if (bank
->target
->state
!= TARGET_HALTED
)
654 LOG_ERROR("Target not halted");
655 return ERROR_TARGET_NOT_HALTED
;
658 if (stellaris_info
->did1
== 0)
660 stellaris_read_part_info(bank
);
663 if (stellaris_info
->did1
== 0)
665 LOG_WARNING("Cannot identify target as Stellaris");
666 return ERROR_FLASH_OPERATION_FAILED
;
669 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
671 return ERROR_FLASH_SECTOR_INVALID
;
674 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
676 return stellaris_mass_erase(bank
);
679 /* Configure the flash controller timing */
680 stellaris_read_clock_info(bank
);
681 stellaris_set_flash_mode(bank
,0);
683 /* Clear and disable flash programming interrupts */
684 target_write_u32(target
, FLASH_CIM
, 0);
685 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
687 for (banknr
= first
; banknr
<= last
; banknr
++)
689 /* Address is first word in page */
690 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
691 /* Write erase command */
692 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
693 /* Wait until erase complete */
696 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
698 while (flash_fmc
& FMC_ERASE
);
700 /* Check acess violations */
701 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
702 if (flash_cris
& (AMASK
))
704 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
705 target_write_u32(target
, FLASH_CRIS
, 0);
706 return ERROR_FLASH_OPERATION_FAILED
;
709 bank
->sectors
[banknr
].is_erased
= 1;
715 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
717 uint32_t fmppe
, flash_fmc
, flash_cris
;
720 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
721 target_t
*target
= bank
->target
;
723 if (bank
->target
->state
!= TARGET_HALTED
)
725 LOG_ERROR("Target not halted");
726 return ERROR_TARGET_NOT_HALTED
;
729 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
731 return ERROR_FLASH_SECTOR_INVALID
;
734 if (stellaris_info
->did1
== 0)
736 stellaris_read_part_info(bank
);
739 if (stellaris_info
->did1
== 0)
741 LOG_WARNING("Cannot identify target as an Stellaris MCU");
742 return ERROR_FLASH_OPERATION_FAILED
;
745 /* Configure the flash controller timing */
746 stellaris_read_clock_info(bank
);
747 stellaris_set_flash_mode(bank
, 0);
749 fmppe
= stellaris_info
->lockbits
;
750 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
753 fmppe
&= ~(1 << lockregion
);
755 fmppe
|= (1 << lockregion
);
758 /* Clear and disable flash programming interrupts */
759 target_write_u32(target
, FLASH_CIM
, 0);
760 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
762 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
763 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
765 target_write_u32(target
, FLASH_FMA
, 1);
766 /* Write commit command */
767 /* TODO safety check, sice this cannot be undone */
768 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
769 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
770 /* Wait until erase complete */
773 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
775 while (flash_fmc
& FMC_COMT
);
777 /* Check acess violations */
778 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
779 if (flash_cris
& (AMASK
))
781 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
782 target_write_u32(target
, FLASH_CRIS
, 0);
783 return ERROR_FLASH_OPERATION_FAILED
;
786 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
791 static uint8_t stellaris_write_code
[] =
796 r1 = destination address
797 r2 = bytecount (in) - endaddr (work)
800 r3 = pFLASH_CTRL_BASE
806 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
807 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
808 0x01,0x25, /* movs r5, 1 */
809 0x00,0x26, /* movs r6, #0 */
811 0x19,0x60, /* str r1, [r3, #0] */
812 0x87,0x59, /* ldr r7, [r0, r6] */
813 0x5F,0x60, /* str r7, [r3, #4] */
814 0x9C,0x60, /* str r4, [r3, #8] */
816 0x9F,0x68, /* ldr r7, [r3, #8] */
817 0x2F,0x42, /* tst r7, r5 */
818 0xFC,0xD1, /* bne waitloop */
819 0x04,0x31, /* adds r1, r1, #4 */
820 0x04,0x36, /* adds r6, r6, #4 */
821 0x96,0x42, /* cmp r6, r2 */
822 0xF4,0xD1, /* bne mainloop */
824 0xFE,0xE7, /* b exit */
825 /* pFLASH_CTRL_BASE: */
826 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
828 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
831 static int stellaris_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
833 target_t
*target
= bank
->target
;
834 uint32_t buffer_size
= 8192;
835 working_area_t
*source
;
836 working_area_t
*write_algorithm
;
837 uint32_t address
= bank
->base
+ offset
;
838 reg_param_t reg_params
[3];
839 armv7m_algorithm_t armv7m_info
;
840 int retval
= ERROR_OK
;
842 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
843 bank
, buffer
, offset
, wcount
);
845 /* flash write code */
846 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
848 LOG_WARNING("no working area available, can't do block memory writes");
849 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
852 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
855 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
857 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
858 target
, buffer_size
, source
);
860 if (buffer_size
<= 256)
862 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
864 target_free_working_area(target
, write_algorithm
);
866 LOG_WARNING("no large enough working area available, can't do block memory writes");
867 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
871 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
872 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
874 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
875 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
876 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
880 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
882 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
884 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
885 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
886 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
887 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
888 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
889 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
)
891 LOG_ERROR("error executing stellaris flash write algorithm");
892 retval
= ERROR_FLASH_OPERATION_FAILED
;
896 buffer
+= thisrun_count
* 4;
897 address
+= thisrun_count
* 4;
898 wcount
-= thisrun_count
;
901 target_free_working_area(target
, write_algorithm
);
902 target_free_working_area(target
, source
);
904 destroy_reg_param(®_params
[0]);
905 destroy_reg_param(®_params
[1]);
906 destroy_reg_param(®_params
[2]);
911 static int stellaris_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
913 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
914 target_t
*target
= bank
->target
;
915 uint32_t address
= offset
;
916 uint32_t flash_cris
, flash_fmc
;
917 uint32_t words_remaining
= (count
/ 4);
918 uint32_t bytes_remaining
= (count
& 0x00000003);
919 uint32_t bytes_written
= 0;
922 if (bank
->target
->state
!= TARGET_HALTED
)
924 LOG_ERROR("Target not halted");
925 return ERROR_TARGET_NOT_HALTED
;
928 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
929 bank
, buffer
, offset
, count
);
931 if (stellaris_info
->did1
== 0)
933 stellaris_read_part_info(bank
);
936 if (stellaris_info
->did1
== 0)
938 LOG_WARNING("Cannot identify target as a Stellaris processor");
939 return ERROR_FLASH_OPERATION_FAILED
;
944 LOG_WARNING("offset size must be word aligned");
945 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
948 if (offset
+ count
> bank
->size
)
949 return ERROR_FLASH_DST_OUT_OF_BANK
;
951 /* Configure the flash controller timing */
952 stellaris_read_clock_info(bank
);
953 stellaris_set_flash_mode(bank
, 0);
955 /* Clear and disable flash programming interrupts */
956 target_write_u32(target
, FLASH_CIM
, 0);
957 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
959 /* multiple words to be programmed? */
960 if (words_remaining
> 0)
962 /* try using a block write */
963 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
965 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
967 /* if block write failed (no sufficient working area),
968 * we use normal (slow) single dword accesses */
969 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
971 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
973 /* if an error occured, we examine the reason, and quit */
974 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
976 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
977 return ERROR_FLASH_OPERATION_FAILED
;
982 buffer
+= words_remaining
* 4;
983 address
+= words_remaining
* 4;
988 while (words_remaining
> 0)
990 if (!(address
& 0xff))
991 LOG_DEBUG("0x%" PRIx32
"", address
);
993 /* Program one word */
994 target_write_u32(target
, FLASH_FMA
, address
);
995 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
996 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
997 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
998 /* Wait until write complete */
1001 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1002 } while (flash_fmc
& FMC_WRITE
);
1009 if (bytes_remaining
)
1011 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1014 while (bytes_remaining
> 0)
1016 last_word
[i
++] = *(buffer
+ bytes_written
);
1021 if (!(address
& 0xff))
1022 LOG_DEBUG("0x%" PRIx32
"", address
);
1024 /* Program one word */
1025 target_write_u32(target
, FLASH_FMA
, address
);
1026 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1027 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1028 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1029 /* Wait until write complete */
1032 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1033 } while (flash_fmc
& FMC_WRITE
);
1036 /* Check access violations */
1037 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1038 if (flash_cris
& (AMASK
))
1040 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1041 return ERROR_FLASH_OPERATION_FAILED
;
1046 static int stellaris_probe(struct flash_bank_s
*bank
)
1048 /* we can't probe on an stellaris
1049 * if this is an stellaris, it has the configured flash
1052 if (bank
->target
->state
!= TARGET_HALTED
)
1054 LOG_ERROR("Target not halted");
1055 return ERROR_TARGET_NOT_HALTED
;
1058 /* stellaris_read_part_info() already takes care about error checking and reporting */
1059 return stellaris_read_part_info(bank
);
1062 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
1064 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
1065 if (stellaris_info
->did1
)
1067 return stellaris_probe(bank
);
1070 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
1072 target_t
*target
= NULL
;
1073 stellaris_flash_bank_t
*stellaris_info
= NULL
;
1076 stellaris_info
= bank
->driver_priv
;
1077 target
= bank
->target
;
1079 if (target
->state
!= TARGET_HALTED
)
1081 LOG_ERROR("Target not halted");
1082 return ERROR_TARGET_NOT_HALTED
;
1085 if (stellaris_info
->did1
== 0)
1087 stellaris_read_part_info(bank
);
1090 if (stellaris_info
->did1
== 0)
1092 LOG_WARNING("Cannot identify target as Stellaris");
1093 return ERROR_FLASH_OPERATION_FAILED
;
1096 /* Configure the flash controller timing */
1097 stellaris_read_clock_info(bank
);
1098 stellaris_set_flash_mode(bank
, 0);
1100 /* Clear and disable flash programming interrupts */
1101 target_write_u32(target
, FLASH_CIM
, 0);
1102 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1104 target_write_u32(target
, FLASH_FMA
, 0);
1105 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1106 /* Wait until erase complete */
1109 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1111 while (flash_fmc
& FMC_MERASE
);
1113 /* if device has > 128k, then second erase cycle is needed
1114 * this is only valid for older devices, but will not hurt */
1115 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1117 target_write_u32(target
, FLASH_FMA
, 0x20000);
1118 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1119 /* Wait until erase complete */
1122 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1124 while (flash_fmc
& FMC_MERASE
);
1130 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1136 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1141 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1142 if (ERROR_OK
!= retval
)
1145 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1147 /* set all sectors as erased */
1148 for (i
= 0; i
< bank
->num_sectors
; i
++)
1150 bank
->sectors
[i
].is_erased
= 1;
1153 command_print(cmd_ctx
, "stellaris mass erase complete");
1157 command_print(cmd_ctx
, "stellaris mass erase failed");
1163 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
1165 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris",
1166 NULL
, COMMAND_ANY
, "stellaris flash specific commands");
1168 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase",
1169 stellaris_handle_mass_erase_command
, COMMAND_EXEC
,
1170 "mass erase device");
1175 flash_driver_t stellaris_flash
= {
1176 .name
= "stellaris",
1177 .register_commands
= &stellaris_register_commands
,
1178 .flash_bank_command
= &stellaris_flash_bank_command
,
1179 .erase
= &stellaris_erase
,
1180 .protect
= &stellaris_protect
,
1181 .write
= &stellaris_write
,
1182 .probe
= &stellaris_probe
,
1183 .auto_probe
= &stellaris_auto_probe
,
1184 .erase_check
= &default_flash_mem_blank_check
,
1185 .protect_check
= &stellaris_protect_check
,
1186 .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)