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
, u32 offset
, u32 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 u32
stellaris_get_flash_status(flash_bank_t
*bank
);
49 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
50 //static u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 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 Use an optional main oscillator clock rate in kHz from arg[6] */
264 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
266 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris", NULL
, COMMAND_ANY
, "stellaris flash specific commands");
268 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stellaris_handle_mass_erase_command
, COMMAND_EXEC
, "mass erase device");
272 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
274 int printed
, device_class
;
275 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
277 stellaris_read_part_info(bank
);
279 if (stellaris_info
->did1
== 0)
281 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
284 return ERROR_FLASH_OPERATION_FAILED
;
287 if (DID0_VER(stellaris_info
->did0
) > 0)
289 device_class
= (stellaris_info
->did0
>>16) & 0xFF;
295 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
296 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
297 'A' + ((stellaris_info
->did0
>>8) & 0xFF), (stellaris_info
->did0
) & 0xFF);
301 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
302 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+((stellaris_info
->dc0
>>16) & 0xFFFF))/4, (1+(stellaris_info
->dc0
& 0xFFFF))*2);
306 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
310 if (stellaris_info
->num_lockbits
>0)
312 printed
= snprintf(buf
, buf_size
, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", stellaris_info
->pagesize
, stellaris_info
->num_lockbits
, stellaris_info
->lockbits
,stellaris_info
->num_pages
/stellaris_info
->num_lockbits
);
319 /***************************************************************************
320 * chip identification and status *
321 ***************************************************************************/
323 static u32
stellaris_get_flash_status(flash_bank_t
*bank
)
325 target_t
*target
= bank
->target
;
328 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
333 /** Read clock configuration and set stellaris_info->usec_clocks*/
335 static void stellaris_read_clock_info(flash_bank_t
*bank
)
337 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
338 target_t
*target
= bank
->target
;
339 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
340 unsigned long mainfreq
;
342 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
343 LOG_DEBUG("Stellaris RCC %x", rcc
);
344 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
345 LOG_DEBUG("Stellaris PLLCFG %x", pllcfg
);
346 stellaris_info
->rcc
= rcc
;
348 sysdiv
= (rcc
>>23) & 0xF;
349 usesysdiv
= (rcc
>>22) & 0x1;
350 bypass
= (rcc
>>11) & 0x1;
351 oscsrc
= (rcc
>>4) & 0x3;
352 /* xtal = (rcc>>6)&0xF; */
356 mainfreq
= 6000000; /* Default xtal */
359 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
362 mainfreq
= 5625000; /* Internal osc. / 4 */
365 LOG_WARNING("Invalid oscsrc (3) in rcc register");
369 default: /* NOTREACHED */
375 mainfreq
= 200000000; /* PLL out frec */
378 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
380 stellaris_info
->mck_freq
= mainfreq
;
382 /* Forget old flash timing */
383 stellaris_set_flash_mode(bank
, 0);
386 /* Setup the timimg registers */
387 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
389 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
390 target_t
*target
= bank
->target
;
392 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
393 LOG_DEBUG("usecrl = %i",usecrl
);
394 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
398 static u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
402 /* Stellaris waits for cmdbit to clear */
403 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
405 LOG_DEBUG("status: 0x%x", status
);
409 /* Flash errors are reflected in the FLASH_CRIS register */
414 /* Send one command to the flash controller */
415 static int stellaris_flash_command(struct flash_bank_s
*bank
,uint8_t cmd
,u16 pagen
)
418 target_t
*target
= bank
->target
;
420 fmc
= FMC_WRKEY
| cmd
;
421 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
422 LOG_DEBUG("Flash command: 0x%x", fmc
);
424 if (stellaris_wait_status_busy(bank
, cmd
, 100))
426 return ERROR_FLASH_OPERATION_FAILED
;
433 /* Read device id register, main clock frequency register and fill in driver info structure */
434 static int stellaris_read_part_info(struct flash_bank_s
*bank
)
436 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
437 target_t
*target
= bank
->target
;
438 u32 did0
, did1
, ver
, fam
, status
;
441 /* Read and parse chip identification register */
442 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
443 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
444 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
445 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
446 LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
449 if((ver
!= 0) && (ver
!= 1))
451 LOG_WARNING("Unknown did0 version, cannot identify target");
452 return ERROR_FLASH_OPERATION_FAILED
;
457 LOG_WARNING("Cannot identify target as a Stellaris");
458 return ERROR_FLASH_OPERATION_FAILED
;
462 fam
= (did1
>> 24) & 0xF;
463 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
465 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
468 for (i
= 0; StellarisParts
[i
].partno
; i
++)
470 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
474 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
476 stellaris_info
->did0
= did0
;
477 stellaris_info
->did1
= did1
;
479 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
480 stellaris_info
->num_pages
= 2 *(1+(stellaris_info
->dc0
& 0xFFFF));
481 stellaris_info
->pagesize
= 1024;
482 bank
->size
= 1024 * stellaris_info
->num_pages
;
483 stellaris_info
->pages_in_lockregion
= 2;
484 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
486 /* provide this for the benefit of the higher flash driver layers */
487 bank
->num_sectors
= stellaris_info
->num_pages
;
488 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
489 for (i
= 0; i
< bank
->num_sectors
; i
++)
491 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
492 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
493 bank
->sectors
[i
].is_erased
= -1;
494 bank
->sectors
[i
].is_protected
= -1;
497 /* Read main and master clock freqency register */
498 stellaris_read_clock_info(bank
);
500 status
= stellaris_get_flash_status(bank
);
505 /***************************************************************************
507 ***************************************************************************/
509 static int stellaris_protect_check(struct flash_bank_s
*bank
)
513 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
515 if (bank
->target
->state
!= TARGET_HALTED
)
517 LOG_ERROR("Target not halted");
518 return ERROR_TARGET_NOT_HALTED
;
521 if (stellaris_info
->did1
== 0)
523 stellaris_read_part_info(bank
);
526 if (stellaris_info
->did1
== 0)
528 LOG_WARNING("Cannot identify target as an AT91SAM");
529 return ERROR_FLASH_OPERATION_FAILED
;
532 status
= stellaris_get_flash_status(bank
);
533 stellaris_info
->lockbits
= status
>> 16;
538 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
541 u32 flash_fmc
, flash_cris
;
542 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
543 target_t
*target
= bank
->target
;
545 if (bank
->target
->state
!= TARGET_HALTED
)
547 LOG_ERROR("Target not halted");
548 return ERROR_TARGET_NOT_HALTED
;
551 if (stellaris_info
->did1
== 0)
553 stellaris_read_part_info(bank
);
556 if (stellaris_info
->did1
== 0)
558 LOG_WARNING("Cannot identify target as Stellaris");
559 return ERROR_FLASH_OPERATION_FAILED
;
562 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
564 return ERROR_FLASH_SECTOR_INVALID
;
567 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
569 return stellaris_mass_erase(bank
);
572 /* Configure the flash controller timing */
573 stellaris_read_clock_info(bank
);
574 stellaris_set_flash_mode(bank
,0);
576 /* Clear and disable flash programming interrupts */
577 target_write_u32(target
, FLASH_CIM
, 0);
578 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
580 for (banknr
= first
; banknr
<= last
; banknr
++)
582 /* Address is first word in page */
583 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
584 /* Write erase command */
585 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
586 /* Wait until erase complete */
589 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
591 while(flash_fmc
& FMC_ERASE
);
593 /* Check acess violations */
594 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
595 if(flash_cris
& (AMASK
))
597 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
598 target_write_u32(target
, FLASH_CRIS
, 0);
599 return ERROR_FLASH_OPERATION_FAILED
;
602 bank
->sectors
[banknr
].is_erased
= 1;
608 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
610 u32 fmppe
, flash_fmc
, flash_cris
;
613 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
614 target_t
*target
= bank
->target
;
616 if (bank
->target
->state
!= TARGET_HALTED
)
618 LOG_ERROR("Target not halted");
619 return ERROR_TARGET_NOT_HALTED
;
622 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
624 return ERROR_FLASH_SECTOR_INVALID
;
627 if (stellaris_info
->did1
== 0)
629 stellaris_read_part_info(bank
);
632 if (stellaris_info
->did1
== 0)
634 LOG_WARNING("Cannot identify target as an Stellaris MCU");
635 return ERROR_FLASH_OPERATION_FAILED
;
638 /* Configure the flash controller timing */
639 stellaris_read_clock_info(bank
);
640 stellaris_set_flash_mode(bank
, 0);
642 fmppe
= stellaris_info
->lockbits
;
643 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
646 fmppe
&= ~(1<<lockregion
);
648 fmppe
|= (1<<lockregion
);
651 /* Clear and disable flash programming interrupts */
652 target_write_u32(target
, FLASH_CIM
, 0);
653 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
655 LOG_DEBUG("fmppe 0x%x",fmppe
);
656 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
658 target_write_u32(target
, FLASH_FMA
, 1);
659 /* Write commit command */
660 /* TODO safety check, sice this cannot be undone */
661 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
662 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
663 /* Wait until erase complete */
666 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
668 while(flash_fmc
& FMC_COMT
);
670 /* Check acess violations */
671 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
672 if(flash_cris
& (AMASK
))
674 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
675 target_write_u32(target
, FLASH_CRIS
, 0);
676 return ERROR_FLASH_OPERATION_FAILED
;
679 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
684 static uint8_t stellaris_write_code
[] =
689 r1 = destination address
690 r2 = bytecount (in) - endaddr (work)
693 r3 = pFLASH_CTRL_BASE
699 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
700 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
701 0x01,0x25, /* movs r5, 1 */
702 0x00,0x26, /* movs r6, #0 */
704 0x19,0x60, /* str r1, [r3, #0] */
705 0x87,0x59, /* ldr r7, [r0, r6] */
706 0x5F,0x60, /* str r7, [r3, #4] */
707 0x9C,0x60, /* str r4, [r3, #8] */
709 0x9F,0x68, /* ldr r7, [r3, #8] */
710 0x2F,0x42, /* tst r7, r5 */
711 0xFC,0xD1, /* bne waitloop */
712 0x04,0x31, /* adds r1, r1, #4 */
713 0x04,0x36, /* adds r6, r6, #4 */
714 0x96,0x42, /* cmp r6, r2 */
715 0xF4,0xD1, /* bne mainloop */
717 0xFE,0xE7, /* b exit */
718 /* pFLASH_CTRL_BASE: */
719 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
721 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
724 static int stellaris_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, u32 offset
, u32 wcount
)
726 target_t
*target
= bank
->target
;
727 u32 buffer_size
= 8192;
728 working_area_t
*source
;
729 working_area_t
*write_algorithm
;
730 u32 address
= bank
->base
+ offset
;
731 reg_param_t reg_params
[3];
732 armv7m_algorithm_t armv7m_info
;
733 int retval
= ERROR_OK
;
735 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
736 bank
, buffer
, offset
, wcount
);
738 /* flash write code */
739 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
741 LOG_WARNING("no working area available, can't do block memory writes");
742 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
745 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
748 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
750 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
751 target
, buffer_size
, source
);
753 if (buffer_size
<= 256)
755 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
757 target_free_working_area(target
, write_algorithm
);
759 LOG_WARNING("no large enough working area available, can't do block memory writes");
760 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
764 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
765 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
767 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
768 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
769 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
773 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
775 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
777 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
778 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
779 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
780 LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
781 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
782 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
)
784 LOG_ERROR("error executing stellaris flash write algorithm");
785 retval
= ERROR_FLASH_OPERATION_FAILED
;
789 buffer
+= thisrun_count
* 4;
790 address
+= thisrun_count
* 4;
791 wcount
-= thisrun_count
;
794 target_free_working_area(target
, write_algorithm
);
795 target_free_working_area(target
, source
);
797 destroy_reg_param(®_params
[0]);
798 destroy_reg_param(®_params
[1]);
799 destroy_reg_param(®_params
[2]);
804 static int stellaris_write(struct flash_bank_s
*bank
, uint8_t *buffer
, u32 offset
, u32 count
)
806 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
807 target_t
*target
= bank
->target
;
808 u32 address
= offset
;
809 u32 flash_cris
, flash_fmc
;
810 u32 words_remaining
= (count
/ 4);
811 u32 bytes_remaining
= (count
& 0x00000003);
812 u32 bytes_written
= 0;
815 if (bank
->target
->state
!= TARGET_HALTED
)
817 LOG_ERROR("Target not halted");
818 return ERROR_TARGET_NOT_HALTED
;
821 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
822 bank
, buffer
, offset
, count
);
824 if (stellaris_info
->did1
== 0)
826 stellaris_read_part_info(bank
);
829 if (stellaris_info
->did1
== 0)
831 LOG_WARNING("Cannot identify target as a Stellaris processor");
832 return ERROR_FLASH_OPERATION_FAILED
;
837 LOG_WARNING("offset size must be word aligned");
838 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
841 if (offset
+ count
> bank
->size
)
842 return ERROR_FLASH_DST_OUT_OF_BANK
;
844 /* Configure the flash controller timing */
845 stellaris_read_clock_info(bank
);
846 stellaris_set_flash_mode(bank
, 0);
848 /* Clear and disable flash programming interrupts */
849 target_write_u32(target
, FLASH_CIM
, 0);
850 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
852 /* multiple words to be programmed? */
853 if (words_remaining
> 0)
855 /* try using a block write */
856 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
858 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
860 /* if block write failed (no sufficient working area),
861 * we use normal (slow) single dword accesses */
862 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
864 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
866 /* if an error occured, we examine the reason, and quit */
867 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
869 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
870 return ERROR_FLASH_OPERATION_FAILED
;
875 buffer
+= words_remaining
* 4;
876 address
+= words_remaining
* 4;
881 while (words_remaining
> 0)
883 if (!(address
& 0xff))
884 LOG_DEBUG("0x%x", address
);
886 /* Program one word */
887 target_write_u32(target
, FLASH_FMA
, address
);
888 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
889 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
890 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
891 /* Wait until write complete */
894 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
895 } while (flash_fmc
& FMC_WRITE
);
904 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
907 while(bytes_remaining
> 0)
909 last_word
[i
++] = *(buffer
+ bytes_written
);
914 if (!(address
& 0xff))
915 LOG_DEBUG("0x%x", address
);
917 /* Program one word */
918 target_write_u32(target
, FLASH_FMA
, address
);
919 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
920 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
921 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
922 /* Wait until write complete */
925 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
926 } while (flash_fmc
& FMC_WRITE
);
929 /* Check access violations */
930 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
931 if (flash_cris
& (AMASK
))
933 LOG_DEBUG("flash_cris 0x%x", flash_cris
);
934 return ERROR_FLASH_OPERATION_FAILED
;
939 static int stellaris_probe(struct flash_bank_s
*bank
)
941 /* we can't probe on an stellaris
942 * if this is an stellaris, it has the configured flash
945 if (bank
->target
->state
!= TARGET_HALTED
)
947 LOG_ERROR("Target not halted");
948 return ERROR_TARGET_NOT_HALTED
;
951 /* stellaris_read_part_info() already takes care about error checking and reporting */
952 return stellaris_read_part_info(bank
);
955 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
957 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
958 if (stellaris_info
->did1
)
960 return stellaris_probe(bank
);
963 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
965 target_t
*target
= NULL
;
966 stellaris_flash_bank_t
*stellaris_info
= NULL
;
969 stellaris_info
= bank
->driver_priv
;
970 target
= bank
->target
;
972 if (target
->state
!= TARGET_HALTED
)
974 LOG_ERROR("Target not halted");
975 return ERROR_TARGET_NOT_HALTED
;
978 if (stellaris_info
->did1
== 0)
980 stellaris_read_part_info(bank
);
983 if (stellaris_info
->did1
== 0)
985 LOG_WARNING("Cannot identify target as Stellaris");
986 return ERROR_FLASH_OPERATION_FAILED
;
989 /* Configure the flash controller timing */
990 stellaris_read_clock_info(bank
);
991 stellaris_set_flash_mode(bank
, 0);
993 /* Clear and disable flash programming interrupts */
994 target_write_u32(target
, FLASH_CIM
, 0);
995 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
997 target_write_u32(target
, FLASH_FMA
, 0);
998 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
999 /* Wait until erase complete */
1002 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1004 while (flash_fmc
& FMC_MERASE
);
1006 /* if device has > 128k, then second erase cycle is needed
1007 * this is only valid for older devices, but will not hurt */
1008 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1010 target_write_u32(target
, FLASH_FMA
, 0x20000);
1011 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1012 /* Wait until erase complete */
1015 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1017 while (flash_fmc
& FMC_MERASE
);
1023 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1030 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1034 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1037 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1041 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1043 /* set all sectors as erased */
1044 for (i
= 0; i
< bank
->num_sectors
; i
++)
1046 bank
->sectors
[i
].is_erased
= 1;
1049 command_print(cmd_ctx
, "stellaris mass erase complete");
1053 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)