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_read_part_info(struct flash_bank_s
*bank
);
63 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 static int stellaris_mass_erase(struct flash_bank_s
*bank
);
66 flash_driver_t stellaris_flash
=
69 .register_commands
= stellaris_register_commands
,
70 .flash_bank_command
= stellaris_flash_bank_command
,
71 .erase
= stellaris_erase
,
72 .protect
= stellaris_protect
,
73 .write
= stellaris_write
,
74 .probe
= stellaris_probe
,
75 .auto_probe
= stellaris_auto_probe
,
76 .erase_check
= default_flash_mem_blank_check
,
77 .protect_check
= stellaris_protect_check
,
78 .info
= stellaris_info
118 /*{0x33,"LM3S2616"},*/
237 static char * StellarisClassname
[5] =
246 /***************************************************************************
247 * openocd command interface *
248 ***************************************************************************/
250 /* flash_bank stellaris <base> <size> 0 0 <target#>
252 static int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
254 stellaris_flash_bank_t
*stellaris_info
;
258 LOG_WARNING("incomplete flash_bank stellaris configuration");
259 return ERROR_FLASH_BANK_INVALID
;
262 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
), 1);
264 bank
->driver_priv
= stellaris_info
;
266 stellaris_info
->target_name
= "Unknown target";
268 /* part wasn't probed for info yet */
269 stellaris_info
->did1
= 0;
271 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
275 static int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
277 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris", NULL
, COMMAND_ANY
, "stellaris flash specific commands");
279 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stellaris_handle_mass_erase_command
, COMMAND_EXEC
, "mass erase device");
283 static int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
285 int printed
, device_class
;
286 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
288 stellaris_read_part_info(bank
);
290 if (stellaris_info
->did1
== 0)
292 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
295 return ERROR_FLASH_OPERATION_FAILED
;
298 if (DID0_VER(stellaris_info
->did0
) > 0)
300 device_class
= (stellaris_info
->did0
>>16) & 0xFF;
306 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
307 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
308 'A' + ((stellaris_info
->did0
>>8) & 0xFF), (stellaris_info
->did0
) & 0xFF);
312 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
313 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+((stellaris_info
->dc0
>>16) & 0xFFFF))/4, (1+(stellaris_info
->dc0
& 0xFFFF))*2);
317 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
321 if (stellaris_info
->num_lockbits
>0)
323 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
);
330 /***************************************************************************
331 * chip identification and status *
332 ***************************************************************************/
334 static u32
stellaris_get_flash_status(flash_bank_t
*bank
)
336 target_t
*target
= bank
->target
;
339 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
344 /** Read clock configuration and set stellaris_info->usec_clocks*/
346 static void stellaris_read_clock_info(flash_bank_t
*bank
)
348 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
349 target_t
*target
= bank
->target
;
350 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
351 unsigned long mainfreq
;
353 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
354 LOG_DEBUG("Stellaris RCC %x", rcc
);
355 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
356 LOG_DEBUG("Stellaris PLLCFG %x", pllcfg
);
357 stellaris_info
->rcc
= rcc
;
359 sysdiv
= (rcc
>>23) & 0xF;
360 usesysdiv
= (rcc
>>22) & 0x1;
361 bypass
= (rcc
>>11) & 0x1;
362 oscsrc
= (rcc
>>4) & 0x3;
363 /* xtal = (rcc>>6)&0xF; */
367 mainfreq
= 6000000; /* Default xtal */
370 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
373 mainfreq
= 5625000; /* Internal osc. / 4 */
376 LOG_WARNING("Invalid oscsrc (3) in rcc register");
380 default: /* NOTREACHED */
386 mainfreq
= 200000000; /* PLL out frec */
389 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
391 stellaris_info
->mck_freq
= mainfreq
;
393 /* Forget old flash timing */
394 stellaris_set_flash_mode(bank
, 0);
397 /* Setup the timimg registers */
398 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
400 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
401 target_t
*target
= bank
->target
;
403 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
404 LOG_DEBUG("usecrl = %i",usecrl
);
405 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
409 static u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
413 /* Stellaris waits for cmdbit to clear */
414 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
416 LOG_DEBUG("status: 0x%x", status
);
420 /* Flash errors are reflected in the FLASH_CRIS register */
425 /* Send one command to the flash controller */
426 static int stellaris_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
429 target_t
*target
= bank
->target
;
431 fmc
= FMC_WRKEY
| cmd
;
432 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
433 LOG_DEBUG("Flash command: 0x%x", fmc
);
435 if (stellaris_wait_status_busy(bank
, cmd
, 100))
437 return ERROR_FLASH_OPERATION_FAILED
;
444 /* Read device id register, main clock frequency register and fill in driver info structure */
445 static int stellaris_read_part_info(struct flash_bank_s
*bank
)
447 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
448 target_t
*target
= bank
->target
;
449 u32 did0
, did1
, ver
, fam
, status
;
452 /* Read and parse chip identification register */
453 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
454 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
455 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
456 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
457 LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
460 if((ver
!= 0) && (ver
!= 1))
462 LOG_WARNING("Unknown did0 version, cannot identify target");
463 return ERROR_FLASH_OPERATION_FAILED
;
468 LOG_WARNING("Cannot identify target as a Stellaris");
469 return ERROR_FLASH_OPERATION_FAILED
;
473 fam
= (did1
>> 24) & 0xF;
474 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
476 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
479 for (i
= 0; StellarisParts
[i
].partno
; i
++)
481 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
485 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
487 stellaris_info
->did0
= did0
;
488 stellaris_info
->did1
= did1
;
490 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
491 stellaris_info
->num_pages
= 2 *(1+(stellaris_info
->dc0
& 0xFFFF));
492 stellaris_info
->pagesize
= 1024;
493 bank
->size
= 1024 * stellaris_info
->num_pages
;
494 stellaris_info
->pages_in_lockregion
= 2;
495 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
497 /* provide this for the benefit of the higher flash driver layers */
498 bank
->num_sectors
= stellaris_info
->num_pages
;
499 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
500 for (i
= 0; i
< bank
->num_sectors
; i
++)
502 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
503 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
504 bank
->sectors
[i
].is_erased
= -1;
505 bank
->sectors
[i
].is_protected
= -1;
508 /* Read main and master clock freqency register */
509 stellaris_read_clock_info(bank
);
511 status
= stellaris_get_flash_status(bank
);
516 /***************************************************************************
518 ***************************************************************************/
520 static int stellaris_protect_check(struct flash_bank_s
*bank
)
524 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
526 if (bank
->target
->state
!= TARGET_HALTED
)
528 LOG_ERROR("Target not halted");
529 return ERROR_TARGET_NOT_HALTED
;
532 if (stellaris_info
->did1
== 0)
534 stellaris_read_part_info(bank
);
537 if (stellaris_info
->did1
== 0)
539 LOG_WARNING("Cannot identify target as an AT91SAM");
540 return ERROR_FLASH_OPERATION_FAILED
;
543 status
= stellaris_get_flash_status(bank
);
544 stellaris_info
->lockbits
= status
>> 16;
549 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
552 u32 flash_fmc
, flash_cris
;
553 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
554 target_t
*target
= bank
->target
;
556 if (bank
->target
->state
!= TARGET_HALTED
)
558 LOG_ERROR("Target not halted");
559 return ERROR_TARGET_NOT_HALTED
;
562 if (stellaris_info
->did1
== 0)
564 stellaris_read_part_info(bank
);
567 if (stellaris_info
->did1
== 0)
569 LOG_WARNING("Cannot identify target as Stellaris");
570 return ERROR_FLASH_OPERATION_FAILED
;
573 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
575 return ERROR_FLASH_SECTOR_INVALID
;
578 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
580 return stellaris_mass_erase(bank
);
583 /* Configure the flash controller timing */
584 stellaris_read_clock_info(bank
);
585 stellaris_set_flash_mode(bank
,0);
587 /* Clear and disable flash programming interrupts */
588 target_write_u32(target
, FLASH_CIM
, 0);
589 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
591 for (banknr
= first
; banknr
<= last
; banknr
++)
593 /* Address is first word in page */
594 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
595 /* Write erase command */
596 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
597 /* Wait until erase complete */
600 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
602 while(flash_fmc
& FMC_ERASE
);
604 /* Check acess violations */
605 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
606 if(flash_cris
& (AMASK
))
608 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
609 target_write_u32(target
, FLASH_CRIS
, 0);
610 return ERROR_FLASH_OPERATION_FAILED
;
613 bank
->sectors
[banknr
].is_erased
= 1;
619 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
621 u32 fmppe
, flash_fmc
, flash_cris
;
624 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
625 target_t
*target
= bank
->target
;
627 if (bank
->target
->state
!= TARGET_HALTED
)
629 LOG_ERROR("Target not halted");
630 return ERROR_TARGET_NOT_HALTED
;
633 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
635 return ERROR_FLASH_SECTOR_INVALID
;
638 if (stellaris_info
->did1
== 0)
640 stellaris_read_part_info(bank
);
643 if (stellaris_info
->did1
== 0)
645 LOG_WARNING("Cannot identify target as an Stellaris MCU");
646 return ERROR_FLASH_OPERATION_FAILED
;
649 /* Configure the flash controller timing */
650 stellaris_read_clock_info(bank
);
651 stellaris_set_flash_mode(bank
, 0);
653 fmppe
= stellaris_info
->lockbits
;
654 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
657 fmppe
&= ~(1<<lockregion
);
659 fmppe
|= (1<<lockregion
);
662 /* Clear and disable flash programming interrupts */
663 target_write_u32(target
, FLASH_CIM
, 0);
664 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
666 LOG_DEBUG("fmppe 0x%x",fmppe
);
667 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
669 target_write_u32(target
, FLASH_FMA
, 1);
670 /* Write commit command */
671 /* TODO safety check, sice this cannot be undone */
672 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
673 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
674 /* Wait until erase complete */
677 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
679 while(flash_fmc
& FMC_COMT
);
681 /* Check acess violations */
682 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
683 if(flash_cris
& (AMASK
))
685 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
686 target_write_u32(target
, FLASH_CRIS
, 0);
687 return ERROR_FLASH_OPERATION_FAILED
;
690 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
695 static u8 stellaris_write_code
[] =
700 r1 = destination address
701 r2 = bytecount (in) - endaddr (work)
704 r3 = pFLASH_CTRL_BASE
710 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
711 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
712 0x01,0x25, /* movs r5, 1 */
713 0x00,0x26, /* movs r6, #0 */
715 0x19,0x60, /* str r1, [r3, #0] */
716 0x87,0x59, /* ldr r7, [r0, r6] */
717 0x5F,0x60, /* str r7, [r3, #4] */
718 0x9C,0x60, /* str r4, [r3, #8] */
720 0x9F,0x68, /* ldr r7, [r3, #8] */
721 0x2F,0x42, /* tst r7, r5 */
722 0xFC,0xD1, /* bne waitloop */
723 0x04,0x31, /* adds r1, r1, #4 */
724 0x04,0x36, /* adds r6, r6, #4 */
725 0x96,0x42, /* cmp r6, r2 */
726 0xF4,0xD1, /* bne mainloop */
728 0xFE,0xE7, /* b exit */
729 /* pFLASH_CTRL_BASE: */
730 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
732 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
735 static int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
737 target_t
*target
= bank
->target
;
738 u32 buffer_size
= 8192;
739 working_area_t
*source
;
740 working_area_t
*write_algorithm
;
741 u32 address
= bank
->base
+ offset
;
742 reg_param_t reg_params
[3];
743 armv7m_algorithm_t armv7m_info
;
744 int retval
= ERROR_OK
;
746 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
747 bank
, buffer
, offset
, wcount
);
749 /* flash write code */
750 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
752 LOG_WARNING("no working area available, can't do block memory writes");
753 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
756 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
759 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
761 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
762 target
, buffer_size
, source
);
764 if (buffer_size
<= 256)
766 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
768 target_free_working_area(target
, write_algorithm
);
770 LOG_WARNING("no large enough working area available, can't do block memory writes");
771 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
775 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
776 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
778 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
779 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
780 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
784 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
786 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
788 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
789 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
790 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
791 LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
792 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
793 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
)
795 LOG_ERROR("error executing stellaris flash write algorithm");
796 retval
= ERROR_FLASH_OPERATION_FAILED
;
800 buffer
+= thisrun_count
* 4;
801 address
+= thisrun_count
* 4;
802 wcount
-= thisrun_count
;
805 target_free_working_area(target
, write_algorithm
);
806 target_free_working_area(target
, source
);
808 destroy_reg_param(®_params
[0]);
809 destroy_reg_param(®_params
[1]);
810 destroy_reg_param(®_params
[2]);
815 static int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
817 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
818 target_t
*target
= bank
->target
;
819 u32 address
= offset
;
820 u32 flash_cris
, flash_fmc
;
821 u32 words_remaining
= (count
/ 4);
822 u32 bytes_remaining
= (count
& 0x00000003);
823 u32 bytes_written
= 0;
826 if (bank
->target
->state
!= TARGET_HALTED
)
828 LOG_ERROR("Target not halted");
829 return ERROR_TARGET_NOT_HALTED
;
832 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
833 bank
, buffer
, offset
, count
);
835 if (stellaris_info
->did1
== 0)
837 stellaris_read_part_info(bank
);
840 if (stellaris_info
->did1
== 0)
842 LOG_WARNING("Cannot identify target as a Stellaris processor");
843 return ERROR_FLASH_OPERATION_FAILED
;
848 LOG_WARNING("offset size must be word aligned");
849 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
852 if (offset
+ count
> bank
->size
)
853 return ERROR_FLASH_DST_OUT_OF_BANK
;
855 /* Configure the flash controller timing */
856 stellaris_read_clock_info(bank
);
857 stellaris_set_flash_mode(bank
, 0);
859 /* Clear and disable flash programming interrupts */
860 target_write_u32(target
, FLASH_CIM
, 0);
861 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
863 /* multiple words to be programmed? */
864 if (words_remaining
> 0)
866 /* try using a block write */
867 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
869 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
871 /* if block write failed (no sufficient working area),
872 * we use normal (slow) single dword accesses */
873 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
875 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
877 /* if an error occured, we examine the reason, and quit */
878 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
880 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
881 return ERROR_FLASH_OPERATION_FAILED
;
886 buffer
+= words_remaining
* 4;
887 address
+= words_remaining
* 4;
892 while (words_remaining
> 0)
894 if (!(address
& 0xff))
895 LOG_DEBUG("0x%x", address
);
897 /* Program one word */
898 target_write_u32(target
, FLASH_FMA
, address
);
899 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
900 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
901 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
902 /* Wait until write complete */
905 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
906 } while (flash_fmc
& FMC_WRITE
);
915 u8 last_word
[4] = {0xff, 0xff, 0xff, 0xff};
918 while(bytes_remaining
> 0)
920 last_word
[i
++] = *(buffer
+ bytes_written
);
925 if (!(address
& 0xff))
926 LOG_DEBUG("0x%x", address
);
928 /* Program one word */
929 target_write_u32(target
, FLASH_FMA
, address
);
930 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
931 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
932 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
933 /* Wait until write complete */
936 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
937 } while (flash_fmc
& FMC_WRITE
);
940 /* Check access violations */
941 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
942 if (flash_cris
& (AMASK
))
944 LOG_DEBUG("flash_cris 0x%x", flash_cris
);
945 return ERROR_FLASH_OPERATION_FAILED
;
950 static int stellaris_probe(struct flash_bank_s
*bank
)
952 /* we can't probe on an stellaris
953 * if this is an stellaris, it has the configured flash
956 if (bank
->target
->state
!= TARGET_HALTED
)
958 LOG_ERROR("Target not halted");
959 return ERROR_TARGET_NOT_HALTED
;
962 /* stellaris_read_part_info() already takes care about error checking and reporting */
963 return stellaris_read_part_info(bank
);
966 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
968 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
969 if (stellaris_info
->did1
)
971 return stellaris_probe(bank
);
974 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
976 target_t
*target
= NULL
;
977 stellaris_flash_bank_t
*stellaris_info
= NULL
;
980 stellaris_info
= bank
->driver_priv
;
981 target
= bank
->target
;
983 if (target
->state
!= TARGET_HALTED
)
985 LOG_ERROR("Target not halted");
986 return ERROR_TARGET_NOT_HALTED
;
989 if (stellaris_info
->did1
== 0)
991 stellaris_read_part_info(bank
);
994 if (stellaris_info
->did1
== 0)
996 LOG_WARNING("Cannot identify target as Stellaris");
997 return ERROR_FLASH_OPERATION_FAILED
;
1000 /* Configure the flash controller timing */
1001 stellaris_read_clock_info(bank
);
1002 stellaris_set_flash_mode(bank
, 0);
1004 /* Clear and disable flash programming interrupts */
1005 target_write_u32(target
, FLASH_CIM
, 0);
1006 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
1008 target_write_u32(target
, FLASH_FMA
, 0);
1009 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1010 /* Wait until erase complete */
1013 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1015 while (flash_fmc
& FMC_MERASE
);
1017 /* if device has > 128k, then second erase cycle is needed
1018 * this is only valid for older devices, but will not hurt */
1019 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1021 target_write_u32(target
, FLASH_FMA
, 0x20000);
1022 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1023 /* Wait until erase complete */
1026 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1028 while (flash_fmc
& FMC_MERASE
);
1034 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1041 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1045 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1048 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1052 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1054 /* set all sectors as erased */
1055 for (i
= 0; i
< bank
->num_sectors
; i
++)
1057 bank
->sectors
[i
].is_erased
= 1;
1060 command_print(cmd_ctx
, "stellaris mass erase complete");
1064 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)