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)
37 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
);
38 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
39 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
);
40 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
41 static int stellaris_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
42 static int stellaris_auto_probe(struct flash_bank_s
*bank
);
43 static int stellaris_probe(struct flash_bank_s
*bank
);
44 static int stellaris_protect_check(struct flash_bank_s
*bank
);
45 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
47 static int stellaris_read_part_info(struct flash_bank_s
*bank
);
48 static uint32_t stellaris_get_flash_status(flash_bank_t
*bank
);
49 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
50 //static uint32_t stellaris_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
52 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 static int stellaris_mass_erase(struct flash_bank_s
*bank
);
55 flash_driver_t stellaris_flash
=
58 .register_commands
= stellaris_register_commands
,
59 .flash_bank_command
= stellaris_flash_bank_command
,
60 .erase
= stellaris_erase
,
61 .protect
= stellaris_protect
,
62 .write
= stellaris_write
,
63 .probe
= stellaris_probe
,
64 .auto_probe
= stellaris_auto_probe
,
65 .erase_check
= default_flash_mem_blank_check
,
66 .protect_check
= stellaris_protect_check
,
67 .info
= stellaris_info
107 /*{0x33,"LM3S2616"},*/
226 static char * StellarisClassname
[5] =
235 /***************************************************************************
236 * openocd command interface *
237 ***************************************************************************/
239 /* flash_bank stellaris <base> <size> 0 0 <target#>
241 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
243 stellaris_flash_bank_t
*stellaris_info
;
247 LOG_WARNING("incomplete flash_bank stellaris configuration");
248 return ERROR_FLASH_BANK_INVALID
;
251 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
), 1);
253 bank
->driver_priv
= stellaris_info
;
255 stellaris_info
->target_name
= "Unknown target";
257 /* part wasn't probed for info yet */
258 stellaris_info
->did1
= 0;
260 /* TODO Specify the main crystal speed in kHz using an optional
261 * argument; ditto, the speed of an external oscillator used
262 * instead of a crystal. Avoid programming flash using IOSC.
267 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
269 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris", NULL
, COMMAND_ANY
, "stellaris flash specific commands");
271 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stellaris_handle_mass_erase_command
, COMMAND_EXEC
, "mass erase device");
275 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
277 int printed
, device_class
;
278 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
280 stellaris_read_part_info(bank
);
282 if (stellaris_info
->did1
== 0)
284 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
287 return ERROR_FLASH_OPERATION_FAILED
;
290 if (DID0_VER(stellaris_info
->did0
) > 0)
292 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
298 printed
= snprintf(buf
,
300 "\nTI/LMI Stellaris information: Chip is "
301 "class %i (%s) %s rev %c%i\n",
303 StellarisClassname
[device_class
],
304 stellaris_info
->target_name
,
305 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
306 (int)((stellaris_info
->did0
) & 0xFF));
310 printed
= snprintf(buf
,
312 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
313 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
314 stellaris_info
->did1
,
315 stellaris_info
->did1
,
317 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
318 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
322 printed
= snprintf(buf
,
324 "master clock: %ikHz%s, "
325 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
326 (int)(stellaris_info
->mck_freq
/ 1000),
327 stellaris_info
->mck_desc
,
329 stellaris_info
->rcc2
);
333 if (stellaris_info
->num_lockbits
> 0)
335 printed
= snprintf(buf
,
337 "pagesize: %" PRIi32
", lockbits: %i 0x%4.4" PRIx32
", pages in lock region: %i \n",
338 stellaris_info
->pagesize
,
339 stellaris_info
->num_lockbits
,
340 stellaris_info
->lockbits
,
341 (int)(stellaris_info
->num_pages
/stellaris_info
->num_lockbits
));
348 /***************************************************************************
349 * chip identification and status *
350 ***************************************************************************/
352 static uint32_t stellaris_get_flash_status(flash_bank_t
*bank
)
354 target_t
*target
= bank
->target
;
357 target_read_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, &fmc
);
362 /** Read clock configuration and set stellaris_info->usec_clocks*/
364 static const unsigned rcc_xtal
[32] = {
365 [0x00] = 1000000, /* no pll */
366 [0x01] = 1843200, /* no pll */
367 [0x02] = 2000000, /* no pll */
368 [0x03] = 2457600, /* no pll */
372 [0x06] = 4000000, /* usb */
376 [0x09] = 5000000, /* usb */
378 [0x0b] = 6000000, /* (reset) usb */
382 [0x0e] = 8000000, /* usb */
385 /* parts before DustDevil use just 4 bits for xtal spec */
387 [0x10] = 10000000, /* usb */
388 [0x11] = 12000000, /* usb */
393 [0x15] = 16000000, /* usb */
397 static void stellaris_read_clock_info(flash_bank_t
*bank
)
399 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
400 target_t
*target
= bank
->target
;
401 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
403 unsigned long mainfreq
;
405 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
406 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
408 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
409 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
411 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
412 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
414 stellaris_info
->rcc
= rcc
;
415 stellaris_info
->rcc
= rcc2
;
417 sysdiv
= (rcc
>> 23) & 0xF;
418 usesysdiv
= (rcc
>> 22) & 0x1;
419 bypass
= (rcc
>> 11) & 0x1;
420 oscsrc
= (rcc
>> 4) & 0x3;
421 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
423 /* NOTE: post-Sandstorm parts have RCC2 which may override
424 * parts of RCC ... with more sysdiv options, option for
425 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
426 * as zero, so the "use RCC2" flag is always clear.
428 if (rcc2
& (1 << 31)) {
429 sysdiv
= (rcc2
>> 23) & 0x3F;
430 bypass
= (rcc2
>> 11) & 0x1;
431 oscsrc
= (rcc2
>> 4) & 0x7;
433 /* FIXME Tempest parts have an additional lsb for
434 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
438 stellaris_info
->mck_desc
= "";
443 mainfreq
= rcc_xtal
[xtal
];
446 mainfreq
= stellaris_info
->iosc_freq
;
447 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
450 mainfreq
= stellaris_info
->iosc_freq
/ 4;
451 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
453 case 3: /* lowspeed */
454 /* Sandstorm doesn't have this 30K +/- 30% osc */
456 stellaris_info
->mck_desc
= " (±30%)";
458 case 8: /* hibernation osc */
459 /* not all parts support hibernation */
463 default: /* NOTREACHED */
468 /* PLL is used if it's not bypassed; its output is 200 MHz
469 * even when it runs at 400 MHz (adds divide-by-two stage).
472 mainfreq
= 200000000;
475 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
477 stellaris_info
->mck_freq
= mainfreq
;
479 /* Forget old flash timing */
480 stellaris_set_flash_mode(bank
, 0);
483 /* Setup the timimg registers */
484 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
486 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
487 target_t
*target
= bank
->target
;
489 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
490 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
491 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
495 static uint32_t stellaris_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
)
499 /* Stellaris waits for cmdbit to clear */
500 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
502 LOG_DEBUG("status: 0x%x", status
);
506 /* Flash errors are reflected in the FLASH_CRIS register */
511 /* Send one command to the flash controller */
512 static int stellaris_flash_command(struct flash_bank_s
*bank
,uint8_t cmd
,uint16_t pagen
)
515 target_t
*target
= bank
->target
;
517 fmc
= FMC_WRKEY
| cmd
;
518 target_write_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, fmc
);
519 LOG_DEBUG("Flash command: 0x%x", fmc
);
521 if (stellaris_wait_status_busy(bank
, cmd
, 100))
523 return ERROR_FLASH_OPERATION_FAILED
;
530 /* Read device id register, main clock frequency register and fill in driver info structure */
531 static int stellaris_read_part_info(struct flash_bank_s
*bank
)
533 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
534 target_t
*target
= bank
->target
;
535 uint32_t did0
, did1
, ver
, fam
, status
;
538 /* Read and parse chip identification register */
539 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
540 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
541 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
542 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
543 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
544 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
547 if ((ver
!= 0) && (ver
!= 1))
549 LOG_WARNING("Unknown did0 version, cannot identify target");
550 return ERROR_FLASH_OPERATION_FAILED
;
555 LOG_WARNING("Cannot identify target as a Stellaris");
556 return ERROR_FLASH_OPERATION_FAILED
;
560 fam
= (did1
>> 24) & 0xF;
561 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
563 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
566 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
567 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
568 * even give _both_ numbers! We'll use current numbers; IOSC is
569 * always approximate.
571 * For Tempest: IOSC is calibrated, 16 MHz
573 stellaris_info
->iosc_freq
= 12000000;
574 stellaris_info
->iosc_desc
= " (±30%)";
575 stellaris_info
->xtal_mask
= 0x0f;
577 switch ((did0
>> 28) & 0x7) {
578 case 0: /* Sandstorm */
580 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
581 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
582 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
584 if (((did0
>> 8) & 0xff) < 2) {
585 stellaris_info
->iosc_freq
= 15000000;
586 stellaris_info
->iosc_desc
= " (±50%)";
590 switch ((did0
>> 16) & 0xff) {
593 case 4: /* Tempest */
594 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
595 stellaris_info
->iosc_desc
= " (±1%)";
597 case 3: /* DustDevil */
598 stellaris_info
->xtal_mask
= 0x1f;
601 LOG_WARNING("Unknown did0 class");
605 LOG_WARNING("Unknown did0 version");
608 for (i
= 0; StellarisParts
[i
].partno
; i
++)
610 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
614 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
616 stellaris_info
->did0
= did0
;
617 stellaris_info
->did1
= did1
;
619 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
620 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
621 stellaris_info
->pagesize
= 1024;
622 bank
->size
= 1024 * stellaris_info
->num_pages
;
623 stellaris_info
->pages_in_lockregion
= 2;
624 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
626 /* provide this for the benefit of the higher flash driver layers */
627 bank
->num_sectors
= stellaris_info
->num_pages
;
628 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
629 for (i
= 0; i
< bank
->num_sectors
; i
++)
631 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
632 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
633 bank
->sectors
[i
].is_erased
= -1;
634 bank
->sectors
[i
].is_protected
= -1;
637 /* Read main and master clock freqency register */
638 stellaris_read_clock_info(bank
);
640 status
= stellaris_get_flash_status(bank
);
645 /***************************************************************************
647 ***************************************************************************/
649 static int stellaris_protect_check(struct flash_bank_s
*bank
)
653 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
655 if (bank
->target
->state
!= TARGET_HALTED
)
657 LOG_ERROR("Target not halted");
658 return ERROR_TARGET_NOT_HALTED
;
661 if (stellaris_info
->did1
== 0)
663 stellaris_read_part_info(bank
);
666 if (stellaris_info
->did1
== 0)
668 LOG_WARNING("Cannot identify target as Stellaris");
669 return ERROR_FLASH_OPERATION_FAILED
;
672 status
= stellaris_get_flash_status(bank
);
673 stellaris_info
->lockbits
= status
>> 16;
678 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
681 uint32_t flash_fmc
, flash_cris
;
682 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
683 target_t
*target
= bank
->target
;
685 if (bank
->target
->state
!= TARGET_HALTED
)
687 LOG_ERROR("Target not halted");
688 return ERROR_TARGET_NOT_HALTED
;
691 if (stellaris_info
->did1
== 0)
693 stellaris_read_part_info(bank
);
696 if (stellaris_info
->did1
== 0)
698 LOG_WARNING("Cannot identify target as Stellaris");
699 return ERROR_FLASH_OPERATION_FAILED
;
702 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
704 return ERROR_FLASH_SECTOR_INVALID
;
707 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
709 return stellaris_mass_erase(bank
);
712 /* Configure the flash controller timing */
713 stellaris_read_clock_info(bank
);
714 stellaris_set_flash_mode(bank
,0);
716 /* Clear and disable flash programming interrupts */
717 target_write_u32(target
, FLASH_CIM
, 0);
718 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
720 for (banknr
= first
; banknr
<= last
; banknr
++)
722 /* Address is first word in page */
723 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
724 /* Write erase command */
725 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
726 /* Wait until erase complete */
729 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
731 while (flash_fmc
& FMC_ERASE
);
733 /* Check acess violations */
734 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
735 if (flash_cris
& (AMASK
))
737 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
738 target_write_u32(target
, FLASH_CRIS
, 0);
739 return ERROR_FLASH_OPERATION_FAILED
;
742 bank
->sectors
[banknr
].is_erased
= 1;
748 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
750 uint32_t fmppe
, flash_fmc
, flash_cris
;
753 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
754 target_t
*target
= bank
->target
;
756 if (bank
->target
->state
!= TARGET_HALTED
)
758 LOG_ERROR("Target not halted");
759 return ERROR_TARGET_NOT_HALTED
;
762 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
764 return ERROR_FLASH_SECTOR_INVALID
;
767 if (stellaris_info
->did1
== 0)
769 stellaris_read_part_info(bank
);
772 if (stellaris_info
->did1
== 0)
774 LOG_WARNING("Cannot identify target as an Stellaris MCU");
775 return ERROR_FLASH_OPERATION_FAILED
;
778 /* Configure the flash controller timing */
779 stellaris_read_clock_info(bank
);
780 stellaris_set_flash_mode(bank
, 0);
782 fmppe
= stellaris_info
->lockbits
;
783 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
786 fmppe
&= ~(1 << lockregion
);
788 fmppe
|= (1 << lockregion
);
791 /* Clear and disable flash programming interrupts */
792 target_write_u32(target
, FLASH_CIM
, 0);
793 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
795 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
796 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
798 target_write_u32(target
, FLASH_FMA
, 1);
799 /* Write commit command */
800 /* TODO safety check, sice this cannot be undone */
801 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
802 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
803 /* Wait until erase complete */
806 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
808 while (flash_fmc
& FMC_COMT
);
810 /* Check acess violations */
811 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
812 if (flash_cris
& (AMASK
))
814 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
815 target_write_u32(target
, FLASH_CRIS
, 0);
816 return ERROR_FLASH_OPERATION_FAILED
;
819 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
824 static uint8_t stellaris_write_code
[] =
829 r1 = destination address
830 r2 = bytecount (in) - endaddr (work)
833 r3 = pFLASH_CTRL_BASE
839 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
840 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
841 0x01,0x25, /* movs r5, 1 */
842 0x00,0x26, /* movs r6, #0 */
844 0x19,0x60, /* str r1, [r3, #0] */
845 0x87,0x59, /* ldr r7, [r0, r6] */
846 0x5F,0x60, /* str r7, [r3, #4] */
847 0x9C,0x60, /* str r4, [r3, #8] */
849 0x9F,0x68, /* ldr r7, [r3, #8] */
850 0x2F,0x42, /* tst r7, r5 */
851 0xFC,0xD1, /* bne waitloop */
852 0x04,0x31, /* adds r1, r1, #4 */
853 0x04,0x36, /* adds r6, r6, #4 */
854 0x96,0x42, /* cmp r6, r2 */
855 0xF4,0xD1, /* bne mainloop */
857 0xFE,0xE7, /* b exit */
858 /* pFLASH_CTRL_BASE: */
859 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
861 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
864 static int stellaris_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
866 target_t
*target
= bank
->target
;
867 uint32_t buffer_size
= 8192;
868 working_area_t
*source
;
869 working_area_t
*write_algorithm
;
870 uint32_t address
= bank
->base
+ offset
;
871 reg_param_t reg_params
[3];
872 armv7m_algorithm_t armv7m_info
;
873 int retval
= ERROR_OK
;
875 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
876 bank
, buffer
, offset
, wcount
);
878 /* flash write code */
879 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
881 LOG_WARNING("no working area available, can't do block memory writes");
882 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
885 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
888 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
890 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
891 target
, buffer_size
, source
);
893 if (buffer_size
<= 256)
895 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
897 target_free_working_area(target
, write_algorithm
);
899 LOG_WARNING("no large enough working area available, can't do block memory writes");
900 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
904 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
905 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
907 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
908 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
909 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
913 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
915 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
917 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
918 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
919 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
920 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
921 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
922 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
)
924 LOG_ERROR("error executing stellaris flash write algorithm");
925 retval
= ERROR_FLASH_OPERATION_FAILED
;
929 buffer
+= thisrun_count
* 4;
930 address
+= thisrun_count
* 4;
931 wcount
-= thisrun_count
;
934 target_free_working_area(target
, write_algorithm
);
935 target_free_working_area(target
, source
);
937 destroy_reg_param(®_params
[0]);
938 destroy_reg_param(®_params
[1]);
939 destroy_reg_param(®_params
[2]);
944 static int stellaris_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
946 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
947 target_t
*target
= bank
->target
;
948 uint32_t address
= offset
;
949 uint32_t flash_cris
, flash_fmc
;
950 uint32_t words_remaining
= (count
/ 4);
951 uint32_t bytes_remaining
= (count
& 0x00000003);
952 uint32_t bytes_written
= 0;
955 if (bank
->target
->state
!= TARGET_HALTED
)
957 LOG_ERROR("Target not halted");
958 return ERROR_TARGET_NOT_HALTED
;
961 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
962 bank
, buffer
, offset
, count
);
964 if (stellaris_info
->did1
== 0)
966 stellaris_read_part_info(bank
);
969 if (stellaris_info
->did1
== 0)
971 LOG_WARNING("Cannot identify target as a Stellaris processor");
972 return ERROR_FLASH_OPERATION_FAILED
;
977 LOG_WARNING("offset size must be word aligned");
978 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
981 if (offset
+ count
> bank
->size
)
982 return ERROR_FLASH_DST_OUT_OF_BANK
;
984 /* Configure the flash controller timing */
985 stellaris_read_clock_info(bank
);
986 stellaris_set_flash_mode(bank
, 0);
988 /* Clear and disable flash programming interrupts */
989 target_write_u32(target
, FLASH_CIM
, 0);
990 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
992 /* multiple words to be programmed? */
993 if (words_remaining
> 0)
995 /* try using a block write */
996 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
998 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1000 /* if block write failed (no sufficient working area),
1001 * we use normal (slow) single dword accesses */
1002 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
1004 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
1006 /* if an error occured, we examine the reason, and quit */
1007 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1009 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
1010 return ERROR_FLASH_OPERATION_FAILED
;
1015 buffer
+= words_remaining
* 4;
1016 address
+= words_remaining
* 4;
1017 words_remaining
= 0;
1021 while (words_remaining
> 0)
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, buffer
);
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
);
1042 if (bytes_remaining
)
1044 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1047 while (bytes_remaining
> 0)
1049 last_word
[i
++] = *(buffer
+ bytes_written
);
1054 if (!(address
& 0xff))
1055 LOG_DEBUG("0x%" PRIx32
"", address
);
1057 /* Program one word */
1058 target_write_u32(target
, FLASH_FMA
, address
);
1059 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1060 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1061 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1062 /* Wait until write complete */
1065 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1066 } while (flash_fmc
& FMC_WRITE
);
1069 /* Check access violations */
1070 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1071 if (flash_cris
& (AMASK
))
1073 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1074 return ERROR_FLASH_OPERATION_FAILED
;
1079 static int stellaris_probe(struct flash_bank_s
*bank
)
1081 /* we can't probe on an stellaris
1082 * if this is an stellaris, it has the configured flash
1085 if (bank
->target
->state
!= TARGET_HALTED
)
1087 LOG_ERROR("Target not halted");
1088 return ERROR_TARGET_NOT_HALTED
;
1091 /* stellaris_read_part_info() already takes care about error checking and reporting */
1092 return stellaris_read_part_info(bank
);
1095 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
1097 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
1098 if (stellaris_info
->did1
)
1100 return stellaris_probe(bank
);
1103 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
1105 target_t
*target
= NULL
;
1106 stellaris_flash_bank_t
*stellaris_info
= NULL
;
1109 stellaris_info
= bank
->driver_priv
;
1110 target
= bank
->target
;
1112 if (target
->state
!= TARGET_HALTED
)
1114 LOG_ERROR("Target not halted");
1115 return ERROR_TARGET_NOT_HALTED
;
1118 if (stellaris_info
->did1
== 0)
1120 stellaris_read_part_info(bank
);
1123 if (stellaris_info
->did1
== 0)
1125 LOG_WARNING("Cannot identify target as Stellaris");
1126 return ERROR_FLASH_OPERATION_FAILED
;
1129 /* Configure the flash controller timing */
1130 stellaris_read_clock_info(bank
);
1131 stellaris_set_flash_mode(bank
, 0);
1133 /* Clear and disable flash programming interrupts */
1134 target_write_u32(target
, FLASH_CIM
, 0);
1135 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1137 target_write_u32(target
, FLASH_FMA
, 0);
1138 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1139 /* Wait until erase complete */
1142 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1144 while (flash_fmc
& FMC_MERASE
);
1146 /* if device has > 128k, then second erase cycle is needed
1147 * this is only valid for older devices, but will not hurt */
1148 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1150 target_write_u32(target
, FLASH_FMA
, 0x20000);
1151 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1152 /* Wait until erase complete */
1155 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1157 while (flash_fmc
& FMC_MERASE
);
1163 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1169 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1174 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1175 if (ERROR_OK
!= retval
)
1178 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1180 /* set all sectors as erased */
1181 for (i
= 0; i
< bank
->num_sectors
; i
++)
1183 bank
->sectors
[i
].is_erased
= 1;
1186 command_print(cmd_ctx
, "stellaris mass erase complete");
1190 command_print(cmd_ctx
, "stellaris mass erase failed");
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)