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 "replacements.h"
33 #include "stellaris.h"
34 #include "cortex_m3.h"
39 #include "binarybuffer.h"
46 #define DID0_VER(did0) ((did0>>28)&0x07)
47 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
);
48 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
49 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
);
50 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
51 static int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
52 static int stellaris_auto_probe(struct flash_bank_s
*bank
);
53 static int stellaris_probe(struct flash_bank_s
*bank
);
54 static int stellaris_protect_check(struct flash_bank_s
*bank
);
55 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
57 static int stellaris_read_part_info(struct flash_bank_s
*bank
);
58 static u32
stellaris_get_flash_status(flash_bank_t
*bank
);
59 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
60 //static u32 stellaris_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
62 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 static int stellaris_mass_erase(struct flash_bank_s
*bank
);
65 flash_driver_t stellaris_flash
=
68 .register_commands
= stellaris_register_commands
,
69 .flash_bank_command
= stellaris_flash_bank_command
,
70 .erase
= stellaris_erase
,
71 .protect
= stellaris_protect
,
72 .write
= stellaris_write
,
73 .probe
= stellaris_probe
,
74 .auto_probe
= stellaris_auto_probe
,
75 .erase_check
= default_flash_mem_blank_check
,
76 .protect_check
= stellaris_protect_check
,
77 .info
= stellaris_info
117 /*{0x33,"LM3S2616"},*/
236 static char * StellarisClassname
[5] =
245 /***************************************************************************
246 * openocd command interface *
247 ***************************************************************************/
249 /* flash_bank stellaris <base> <size> 0 0 <target#>
251 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
253 stellaris_flash_bank_t
*stellaris_info
;
257 LOG_WARNING("incomplete flash_bank stellaris configuration");
258 return ERROR_FLASH_BANK_INVALID
;
261 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
), 1);
263 bank
->driver_priv
= stellaris_info
;
265 stellaris_info
->target_name
= "Unknown target";
267 /* part wasn't probed for info yet */
268 stellaris_info
->did1
= 0;
270 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
274 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
276 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris", NULL
, COMMAND_ANY
, "stellaris flash specific commands");
278 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stellaris_handle_mass_erase_command
, COMMAND_EXEC
, "mass erase device");
282 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
284 int printed
, device_class
;
285 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
287 stellaris_read_part_info(bank
);
289 if (stellaris_info
->did1
== 0)
291 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
294 return ERROR_FLASH_OPERATION_FAILED
;
297 if (DID0_VER(stellaris_info
->did0
) > 0)
299 device_class
= (stellaris_info
->did0
>>16) & 0xFF;
305 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
306 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
307 'A' + ((stellaris_info
->did0
>>8) & 0xFF), (stellaris_info
->did0
) & 0xFF);
311 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
312 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+((stellaris_info
->dc0
>>16) & 0xFFFF))/4, (1+(stellaris_info
->dc0
& 0xFFFF))*2);
316 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
320 if (stellaris_info
->num_lockbits
>0)
322 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
);
329 /***************************************************************************
330 * chip identification and status *
331 ***************************************************************************/
333 static u32
stellaris_get_flash_status(flash_bank_t
*bank
)
335 target_t
*target
= bank
->target
;
338 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
343 /** Read clock configuration and set stellaris_info->usec_clocks*/
345 static void stellaris_read_clock_info(flash_bank_t
*bank
)
347 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
348 target_t
*target
= bank
->target
;
349 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
350 unsigned long mainfreq
;
352 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
353 LOG_DEBUG("Stellaris RCC %x", rcc
);
354 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
355 LOG_DEBUG("Stellaris PLLCFG %x", pllcfg
);
356 stellaris_info
->rcc
= rcc
;
358 sysdiv
= (rcc
>>23) & 0xF;
359 usesysdiv
= (rcc
>>22) & 0x1;
360 bypass
= (rcc
>>11) & 0x1;
361 oscsrc
= (rcc
>>4) & 0x3;
362 /* xtal = (rcc>>6)&0xF; */
366 mainfreq
= 6000000; /* Default xtal */
369 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
372 mainfreq
= 5625000; /* Internal osc. / 4 */
375 LOG_WARNING("Invalid oscsrc (3) in rcc register");
379 default: /* NOTREACHED */
385 mainfreq
= 200000000; /* PLL out frec */
388 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
390 stellaris_info
->mck_freq
= mainfreq
;
392 /* Forget old flash timing */
393 stellaris_set_flash_mode(bank
, 0);
396 /* Setup the timimg registers */
397 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
399 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
400 target_t
*target
= bank
->target
;
402 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
403 LOG_DEBUG("usecrl = %i",usecrl
);
404 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
408 static u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
412 /* Stellaris waits for cmdbit to clear */
413 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
415 LOG_DEBUG("status: 0x%x", status
);
419 /* Flash errors are reflected in the FLASH_CRIS register */
424 /* Send one command to the flash controller */
425 static int stellaris_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
428 target_t
*target
= bank
->target
;
430 fmc
= FMC_WRKEY
| cmd
;
431 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
432 LOG_DEBUG("Flash command: 0x%x", fmc
);
434 if (stellaris_wait_status_busy(bank
, cmd
, 100))
436 return ERROR_FLASH_OPERATION_FAILED
;
443 /* Read device id register, main clock frequency register and fill in driver info structure */
444 static int stellaris_read_part_info(struct flash_bank_s
*bank
)
446 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
447 target_t
*target
= bank
->target
;
448 u32 did0
, did1
, ver
, fam
, status
;
451 /* Read and parse chip identification register */
452 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
453 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
454 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
455 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
456 LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
459 if((ver
!= 0) && (ver
!= 1))
461 LOG_WARNING("Unknown did0 version, cannot identify target");
462 return ERROR_FLASH_OPERATION_FAILED
;
467 LOG_WARNING("Cannot identify target as a Stellaris");
468 return ERROR_FLASH_OPERATION_FAILED
;
472 fam
= (did1
>> 24) & 0xF;
473 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
475 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
478 for (i
= 0; StellarisParts
[i
].partno
; i
++)
480 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
484 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
486 stellaris_info
->did0
= did0
;
487 stellaris_info
->did1
= did1
;
489 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
490 stellaris_info
->num_pages
= 2 *(1+(stellaris_info
->dc0
& 0xFFFF));
491 stellaris_info
->pagesize
= 1024;
492 bank
->size
= 1024 * stellaris_info
->num_pages
;
493 stellaris_info
->pages_in_lockregion
= 2;
494 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
496 /* provide this for the benefit of the higher flash driver layers */
497 bank
->num_sectors
= stellaris_info
->num_pages
;
498 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
499 for (i
= 0; i
< bank
->num_sectors
; i
++)
501 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
502 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
503 bank
->sectors
[i
].is_erased
= -1;
504 bank
->sectors
[i
].is_protected
= -1;
507 /* Read main and master clock freqency register */
508 stellaris_read_clock_info(bank
);
510 status
= stellaris_get_flash_status(bank
);
515 /***************************************************************************
517 ***************************************************************************/
519 static int stellaris_protect_check(struct flash_bank_s
*bank
)
523 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
525 if (bank
->target
->state
!= TARGET_HALTED
)
527 LOG_ERROR("Target not halted");
528 return ERROR_TARGET_NOT_HALTED
;
531 if (stellaris_info
->did1
== 0)
533 stellaris_read_part_info(bank
);
536 if (stellaris_info
->did1
== 0)
538 LOG_WARNING("Cannot identify target as an AT91SAM");
539 return ERROR_FLASH_OPERATION_FAILED
;
542 status
= stellaris_get_flash_status(bank
);
543 stellaris_info
->lockbits
= status
>> 16;
548 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
551 u32 flash_fmc
, flash_cris
;
552 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
553 target_t
*target
= bank
->target
;
555 if (bank
->target
->state
!= TARGET_HALTED
)
557 LOG_ERROR("Target not halted");
558 return ERROR_TARGET_NOT_HALTED
;
561 if (stellaris_info
->did1
== 0)
563 stellaris_read_part_info(bank
);
566 if (stellaris_info
->did1
== 0)
568 LOG_WARNING("Cannot identify target as Stellaris");
569 return ERROR_FLASH_OPERATION_FAILED
;
572 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
574 return ERROR_FLASH_SECTOR_INVALID
;
577 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
579 return stellaris_mass_erase(bank
);
582 /* Configure the flash controller timing */
583 stellaris_read_clock_info(bank
);
584 stellaris_set_flash_mode(bank
,0);
586 /* Clear and disable flash programming interrupts */
587 target_write_u32(target
, FLASH_CIM
, 0);
588 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
590 for (banknr
= first
; banknr
<= last
; banknr
++)
592 /* Address is first word in page */
593 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
594 /* Write erase command */
595 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
596 /* Wait until erase complete */
599 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
601 while(flash_fmc
& FMC_ERASE
);
603 /* Check acess violations */
604 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
605 if(flash_cris
& (AMASK
))
607 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
608 target_write_u32(target
, FLASH_CRIS
, 0);
609 return ERROR_FLASH_OPERATION_FAILED
;
612 bank
->sectors
[banknr
].is_erased
= 1;
618 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
620 u32 fmppe
, flash_fmc
, flash_cris
;
623 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
624 target_t
*target
= bank
->target
;
626 if (bank
->target
->state
!= TARGET_HALTED
)
628 LOG_ERROR("Target not halted");
629 return ERROR_TARGET_NOT_HALTED
;
632 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
634 return ERROR_FLASH_SECTOR_INVALID
;
637 if (stellaris_info
->did1
== 0)
639 stellaris_read_part_info(bank
);
642 if (stellaris_info
->did1
== 0)
644 LOG_WARNING("Cannot identify target as an Stellaris MCU");
645 return ERROR_FLASH_OPERATION_FAILED
;
648 /* Configure the flash controller timing */
649 stellaris_read_clock_info(bank
);
650 stellaris_set_flash_mode(bank
, 0);
652 fmppe
= stellaris_info
->lockbits
;
653 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
656 fmppe
&= ~(1<<lockregion
);
658 fmppe
|= (1<<lockregion
);
661 /* Clear and disable flash programming interrupts */
662 target_write_u32(target
, FLASH_CIM
, 0);
663 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
665 LOG_DEBUG("fmppe 0x%x",fmppe
);
666 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
668 target_write_u32(target
, FLASH_FMA
, 1);
669 /* Write commit command */
670 /* TODO safety check, sice this cannot be undone */
671 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
672 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
673 /* Wait until erase complete */
676 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
678 while(flash_fmc
& FMC_COMT
);
680 /* Check acess violations */
681 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
682 if(flash_cris
& (AMASK
))
684 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
685 target_write_u32(target
, FLASH_CRIS
, 0);
686 return ERROR_FLASH_OPERATION_FAILED
;
689 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
694 static u8 stellaris_write_code
[] =
699 r1 = destination address
700 r2 = bytecount (in) - endaddr (work)
703 r3 = pFLASH_CTRL_BASE
709 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
710 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
711 0x01,0x25, /* movs r5, 1 */
712 0x00,0x26, /* movs r6, #0 */
714 0x19,0x60, /* str r1, [r3, #0] */
715 0x87,0x59, /* ldr r7, [r0, r6] */
716 0x5F,0x60, /* str r7, [r3, #4] */
717 0x9C,0x60, /* str r4, [r3, #8] */
719 0x9F,0x68, /* ldr r7, [r3, #8] */
720 0x2F,0x42, /* tst r7, r5 */
721 0xFC,0xD1, /* bne waitloop */
722 0x04,0x31, /* adds r1, r1, #4 */
723 0x04,0x36, /* adds r6, r6, #4 */
724 0x96,0x42, /* cmp r6, r2 */
725 0xF4,0xD1, /* bne mainloop */
727 0xFE,0xE7, /* b exit */
728 /* pFLASH_CTRL_BASE: */
729 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
731 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
734 static int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
736 target_t
*target
= bank
->target
;
737 u32 buffer_size
= 8192;
738 working_area_t
*source
;
739 working_area_t
*write_algorithm
;
740 u32 address
= bank
->base
+ offset
;
741 reg_param_t reg_params
[3];
742 armv7m_algorithm_t armv7m_info
;
743 int retval
= ERROR_OK
;
745 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
746 bank
, buffer
, offset
, wcount
);
748 /* flash write code */
749 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
751 LOG_WARNING("no working area available, can't do block memory writes");
752 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
755 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
758 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
760 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
761 target
, buffer_size
, source
);
763 if (buffer_size
<= 256)
765 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
767 target_free_working_area(target
, write_algorithm
);
769 LOG_WARNING("no large enough working area available, can't do block memory writes");
770 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
774 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
775 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
777 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
778 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
779 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
783 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
785 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
787 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
788 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
789 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
790 LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
791 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
792 if ((retval
= target
->type
->run_algorithm(target
, 0, NULL
, 3, reg_params
, write_algorithm
->address
, write_algorithm
->address
+ sizeof(stellaris_write_code
)-10, 10000, &armv7m_info
)) != ERROR_OK
)
794 LOG_ERROR("error executing stellaris flash write algorithm");
795 retval
= ERROR_FLASH_OPERATION_FAILED
;
799 buffer
+= thisrun_count
* 4;
800 address
+= thisrun_count
* 4;
801 wcount
-= thisrun_count
;
804 target_free_working_area(target
, write_algorithm
);
805 target_free_working_area(target
, source
);
807 destroy_reg_param(®_params
[0]);
808 destroy_reg_param(®_params
[1]);
809 destroy_reg_param(®_params
[2]);
814 static int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
816 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
817 target_t
*target
= bank
->target
;
818 u32 address
= offset
;
819 u32 flash_cris
, flash_fmc
;
820 u32 words_remaining
= (count
/ 4);
821 u32 bytes_remaining
= (count
& 0x00000003);
822 u32 bytes_written
= 0;
825 if (bank
->target
->state
!= TARGET_HALTED
)
827 LOG_ERROR("Target not halted");
828 return ERROR_TARGET_NOT_HALTED
;
831 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
832 bank
, buffer
, offset
, count
);
834 if (stellaris_info
->did1
== 0)
836 stellaris_read_part_info(bank
);
839 if (stellaris_info
->did1
== 0)
841 LOG_WARNING("Cannot identify target as a Stellaris processor");
842 return ERROR_FLASH_OPERATION_FAILED
;
847 LOG_WARNING("offset size must be word aligned");
848 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
851 if (offset
+ count
> bank
->size
)
852 return ERROR_FLASH_DST_OUT_OF_BANK
;
854 /* Configure the flash controller timing */
855 stellaris_read_clock_info(bank
);
856 stellaris_set_flash_mode(bank
, 0);
858 /* Clear and disable flash programming interrupts */
859 target_write_u32(target
, FLASH_CIM
, 0);
860 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
862 /* multiple words to be programmed? */
863 if (words_remaining
> 0)
865 /* try using a block write */
866 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
868 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
870 /* if block write failed (no sufficient working area),
871 * we use normal (slow) single dword accesses */
872 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
874 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
876 /* if an error occured, we examine the reason, and quit */
877 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
879 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
880 return ERROR_FLASH_OPERATION_FAILED
;
885 buffer
+= words_remaining
* 4;
886 address
+= words_remaining
* 4;
891 while (words_remaining
> 0)
893 if (!(address
& 0xff))
894 LOG_DEBUG("0x%x", address
);
896 /* Program one word */
897 target_write_u32(target
, FLASH_FMA
, address
);
898 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
899 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
900 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
901 /* Wait until write complete */
904 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
905 } while (flash_fmc
& FMC_WRITE
);
914 u8 last_word
[4] = {0xff, 0xff, 0xff, 0xff};
917 while(bytes_remaining
> 0)
919 last_word
[i
++] = *(buffer
+ bytes_written
);
924 if (!(address
& 0xff))
925 LOG_DEBUG("0x%x", address
);
927 /* Program one word */
928 target_write_u32(target
, FLASH_FMA
, address
);
929 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
930 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
931 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
932 /* Wait until write complete */
935 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
936 } while (flash_fmc
& FMC_WRITE
);
939 /* Check access violations */
940 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
941 if (flash_cris
& (AMASK
))
943 LOG_DEBUG("flash_cris 0x%x", flash_cris
);
944 return ERROR_FLASH_OPERATION_FAILED
;
949 static int stellaris_probe(struct flash_bank_s
*bank
)
951 /* we can't probe on an stellaris
952 * if this is an stellaris, it has the configured flash
955 if (bank
->target
->state
!= TARGET_HALTED
)
957 LOG_ERROR("Target not halted");
958 return ERROR_TARGET_NOT_HALTED
;
961 /* stellaris_read_part_info() already takes care about error checking and reporting */
962 return stellaris_read_part_info(bank
);
965 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
967 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
968 if (stellaris_info
->did1
)
970 return stellaris_probe(bank
);
973 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
975 target_t
*target
= NULL
;
976 stellaris_flash_bank_t
*stellaris_info
= NULL
;
979 stellaris_info
= bank
->driver_priv
;
980 target
= bank
->target
;
982 if (target
->state
!= TARGET_HALTED
)
984 LOG_ERROR("Target not halted");
985 return ERROR_TARGET_NOT_HALTED
;
988 if (stellaris_info
->did1
== 0)
990 stellaris_read_part_info(bank
);
993 if (stellaris_info
->did1
== 0)
995 LOG_WARNING("Cannot identify target as Stellaris");
996 return ERROR_FLASH_OPERATION_FAILED
;
999 /* Configure the flash controller timing */
1000 stellaris_read_clock_info(bank
);
1001 stellaris_set_flash_mode(bank
, 0);
1003 /* Clear and disable flash programming interrupts */
1004 target_write_u32(target
, FLASH_CIM
, 0);
1005 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
1007 target_write_u32(target
, FLASH_FMA
, 0);
1008 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1009 /* Wait until erase complete */
1012 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1014 while (flash_fmc
& FMC_MERASE
);
1016 /* if device has > 128k, then second erase cycle is needed
1017 * this is only valid for older devices, but will not hurt */
1018 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1020 target_write_u32(target
, FLASH_FMA
, 0x20000);
1021 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1022 /* Wait until erase complete */
1025 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1027 while (flash_fmc
& FMC_MERASE
);
1033 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1040 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1044 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1047 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1051 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1053 /* set all sectors as erased */
1054 for (i
= 0; i
< bank
->num_sectors
; i
++)
1056 bank
->sectors
[i
].is_erased
= 1;
1059 command_print(cmd_ctx
, "stellaris mass erase complete");
1063 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)