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 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
,
297 "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
299 StellarisClassname
[device_class
],
300 stellaris_info
->target_name
,
301 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
302 (int)((stellaris_info
->did0
) & 0xFF));
306 printed
= snprintf(buf
,
308 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
", eproc: %s, ramsize:%ik, flashsize: %ik\n",
309 stellaris_info
->did1
,
310 stellaris_info
->did1
,
312 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
313 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
317 printed
= snprintf(buf
,
319 "master clock(estimated): %ikHz, rcc is 0x%" PRIx32
" \n",
320 (int)(stellaris_info
->mck_freq
/ 1000),
321 stellaris_info
->rcc
);
325 if (stellaris_info
->num_lockbits
>0)
327 printed
= snprintf(buf
,
329 "pagesize: %" PRIi32
", lockbits: %i 0x%4.4" PRIx32
", pages in lock region: %i \n",
330 stellaris_info
->pagesize
,
331 stellaris_info
->num_lockbits
,
332 stellaris_info
->lockbits
,
333 (int)(stellaris_info
->num_pages
/stellaris_info
->num_lockbits
));
340 /***************************************************************************
341 * chip identification and status *
342 ***************************************************************************/
344 static uint32_t stellaris_get_flash_status(flash_bank_t
*bank
)
346 target_t
*target
= bank
->target
;
349 target_read_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, &fmc
);
354 /** Read clock configuration and set stellaris_info->usec_clocks*/
356 static void stellaris_read_clock_info(flash_bank_t
*bank
)
358 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
359 target_t
*target
= bank
->target
;
360 uint32_t rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
361 unsigned long mainfreq
;
363 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
364 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
365 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
366 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
367 stellaris_info
->rcc
= rcc
;
369 sysdiv
= (rcc
>> 23) & 0xF;
370 usesysdiv
= (rcc
>> 22) & 0x1;
371 bypass
= (rcc
>> 11) & 0x1;
372 oscsrc
= (rcc
>> 4) & 0x3;
373 /* xtal = (rcc >> 6)&0xF; */
377 mainfreq
= 6000000; /* Default xtal */
380 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
383 mainfreq
= 5625000; /* Internal osc. / 4 */
386 LOG_WARNING("Invalid oscsrc (3) in rcc register");
390 default: /* NOTREACHED */
396 mainfreq
= 200000000; /* PLL out frec */
399 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
401 stellaris_info
->mck_freq
= mainfreq
;
403 /* Forget old flash timing */
404 stellaris_set_flash_mode(bank
, 0);
407 /* Setup the timimg registers */
408 static void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
410 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
411 target_t
*target
= bank
->target
;
413 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
414 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
415 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
419 static uint32_t stellaris_wait_status_busy(flash_bank_t
*bank
, uint32_t waitbits
, int timeout
)
423 /* Stellaris waits for cmdbit to clear */
424 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
426 LOG_DEBUG("status: 0x%x", status
);
430 /* Flash errors are reflected in the FLASH_CRIS register */
435 /* Send one command to the flash controller */
436 static int stellaris_flash_command(struct flash_bank_s
*bank
,uint8_t cmd
,uint16_t pagen
)
439 target_t
*target
= bank
->target
;
441 fmc
= FMC_WRKEY
| cmd
;
442 target_write_u32(target
, FLASH_CONTROL_BASE
| FLASH_FMC
, fmc
);
443 LOG_DEBUG("Flash command: 0x%x", fmc
);
445 if (stellaris_wait_status_busy(bank
, cmd
, 100))
447 return ERROR_FLASH_OPERATION_FAILED
;
454 /* Read device id register, main clock frequency register and fill in driver info structure */
455 static int stellaris_read_part_info(struct flash_bank_s
*bank
)
457 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
458 target_t
*target
= bank
->target
;
459 uint32_t did0
, did1
, ver
, fam
, status
;
462 /* Read and parse chip identification register */
463 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
464 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
465 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
466 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
467 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
468 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
471 if ((ver
!= 0) && (ver
!= 1))
473 LOG_WARNING("Unknown did0 version, cannot identify target");
474 return ERROR_FLASH_OPERATION_FAILED
;
479 LOG_WARNING("Cannot identify target as a Stellaris");
480 return ERROR_FLASH_OPERATION_FAILED
;
484 fam
= (did1
>> 24) & 0xF;
485 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
487 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
490 for (i
= 0; StellarisParts
[i
].partno
; i
++)
492 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
496 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
498 stellaris_info
->did0
= did0
;
499 stellaris_info
->did1
= did1
;
501 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
502 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
503 stellaris_info
->pagesize
= 1024;
504 bank
->size
= 1024 * stellaris_info
->num_pages
;
505 stellaris_info
->pages_in_lockregion
= 2;
506 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
508 /* provide this for the benefit of the higher flash driver layers */
509 bank
->num_sectors
= stellaris_info
->num_pages
;
510 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
511 for (i
= 0; i
< bank
->num_sectors
; i
++)
513 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
514 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
515 bank
->sectors
[i
].is_erased
= -1;
516 bank
->sectors
[i
].is_protected
= -1;
519 /* Read main and master clock freqency register */
520 stellaris_read_clock_info(bank
);
522 status
= stellaris_get_flash_status(bank
);
527 /***************************************************************************
529 ***************************************************************************/
531 static int stellaris_protect_check(struct flash_bank_s
*bank
)
535 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
537 if (bank
->target
->state
!= TARGET_HALTED
)
539 LOG_ERROR("Target not halted");
540 return ERROR_TARGET_NOT_HALTED
;
543 if (stellaris_info
->did1
== 0)
545 stellaris_read_part_info(bank
);
548 if (stellaris_info
->did1
== 0)
550 LOG_WARNING("Cannot identify target as an AT91SAM");
551 return ERROR_FLASH_OPERATION_FAILED
;
554 status
= stellaris_get_flash_status(bank
);
555 stellaris_info
->lockbits
= status
>> 16;
560 static int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
563 uint32_t flash_fmc
, flash_cris
;
564 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
565 target_t
*target
= bank
->target
;
567 if (bank
->target
->state
!= TARGET_HALTED
)
569 LOG_ERROR("Target not halted");
570 return ERROR_TARGET_NOT_HALTED
;
573 if (stellaris_info
->did1
== 0)
575 stellaris_read_part_info(bank
);
578 if (stellaris_info
->did1
== 0)
580 LOG_WARNING("Cannot identify target as Stellaris");
581 return ERROR_FLASH_OPERATION_FAILED
;
584 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
586 return ERROR_FLASH_SECTOR_INVALID
;
589 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
591 return stellaris_mass_erase(bank
);
594 /* Configure the flash controller timing */
595 stellaris_read_clock_info(bank
);
596 stellaris_set_flash_mode(bank
,0);
598 /* Clear and disable flash programming interrupts */
599 target_write_u32(target
, FLASH_CIM
, 0);
600 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
602 for (banknr
= first
; banknr
<= last
; banknr
++)
604 /* Address is first word in page */
605 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
606 /* Write erase command */
607 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
608 /* Wait until erase complete */
611 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
613 while (flash_fmc
& FMC_ERASE
);
615 /* Check acess violations */
616 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
617 if (flash_cris
& (AMASK
))
619 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
620 target_write_u32(target
, FLASH_CRIS
, 0);
621 return ERROR_FLASH_OPERATION_FAILED
;
624 bank
->sectors
[banknr
].is_erased
= 1;
630 static int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
632 uint32_t fmppe
, flash_fmc
, flash_cris
;
635 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
636 target_t
*target
= bank
->target
;
638 if (bank
->target
->state
!= TARGET_HALTED
)
640 LOG_ERROR("Target not halted");
641 return ERROR_TARGET_NOT_HALTED
;
644 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
646 return ERROR_FLASH_SECTOR_INVALID
;
649 if (stellaris_info
->did1
== 0)
651 stellaris_read_part_info(bank
);
654 if (stellaris_info
->did1
== 0)
656 LOG_WARNING("Cannot identify target as an Stellaris MCU");
657 return ERROR_FLASH_OPERATION_FAILED
;
660 /* Configure the flash controller timing */
661 stellaris_read_clock_info(bank
);
662 stellaris_set_flash_mode(bank
, 0);
664 fmppe
= stellaris_info
->lockbits
;
665 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
668 fmppe
&= ~(1 << lockregion
);
670 fmppe
|= (1 << lockregion
);
673 /* Clear and disable flash programming interrupts */
674 target_write_u32(target
, FLASH_CIM
, 0);
675 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
677 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
678 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
680 target_write_u32(target
, FLASH_FMA
, 1);
681 /* Write commit command */
682 /* TODO safety check, sice this cannot be undone */
683 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
684 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
685 /* Wait until erase complete */
688 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
690 while (flash_fmc
& FMC_COMT
);
692 /* Check acess violations */
693 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
694 if (flash_cris
& (AMASK
))
696 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
697 target_write_u32(target
, FLASH_CRIS
, 0);
698 return ERROR_FLASH_OPERATION_FAILED
;
701 target_read_u32(target
, SCB_BASE
| FMPPE
, &stellaris_info
->lockbits
);
706 static uint8_t stellaris_write_code
[] =
711 r1 = destination address
712 r2 = bytecount (in) - endaddr (work)
715 r3 = pFLASH_CTRL_BASE
721 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
722 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
723 0x01,0x25, /* movs r5, 1 */
724 0x00,0x26, /* movs r6, #0 */
726 0x19,0x60, /* str r1, [r3, #0] */
727 0x87,0x59, /* ldr r7, [r0, r6] */
728 0x5F,0x60, /* str r7, [r3, #4] */
729 0x9C,0x60, /* str r4, [r3, #8] */
731 0x9F,0x68, /* ldr r7, [r3, #8] */
732 0x2F,0x42, /* tst r7, r5 */
733 0xFC,0xD1, /* bne waitloop */
734 0x04,0x31, /* adds r1, r1, #4 */
735 0x04,0x36, /* adds r6, r6, #4 */
736 0x96,0x42, /* cmp r6, r2 */
737 0xF4,0xD1, /* bne mainloop */
739 0xFE,0xE7, /* b exit */
740 /* pFLASH_CTRL_BASE: */
741 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
743 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
746 static int stellaris_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
748 target_t
*target
= bank
->target
;
749 uint32_t buffer_size
= 8192;
750 working_area_t
*source
;
751 working_area_t
*write_algorithm
;
752 uint32_t address
= bank
->base
+ offset
;
753 reg_param_t reg_params
[3];
754 armv7m_algorithm_t armv7m_info
;
755 int retval
= ERROR_OK
;
757 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
758 bank
, buffer
, offset
, wcount
);
760 /* flash write code */
761 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
763 LOG_WARNING("no working area available, can't do block memory writes");
764 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
767 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
770 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
772 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
773 target
, buffer_size
, source
);
775 if (buffer_size
<= 256)
777 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
779 target_free_working_area(target
, write_algorithm
);
781 LOG_WARNING("no large enough working area available, can't do block memory writes");
782 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
786 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
787 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
789 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
790 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
791 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
795 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
797 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
799 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
800 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
801 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
802 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, wcount
);
803 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, wcount
);
804 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
)
806 LOG_ERROR("error executing stellaris flash write algorithm");
807 retval
= ERROR_FLASH_OPERATION_FAILED
;
811 buffer
+= thisrun_count
* 4;
812 address
+= thisrun_count
* 4;
813 wcount
-= thisrun_count
;
816 target_free_working_area(target
, write_algorithm
);
817 target_free_working_area(target
, source
);
819 destroy_reg_param(®_params
[0]);
820 destroy_reg_param(®_params
[1]);
821 destroy_reg_param(®_params
[2]);
826 static int stellaris_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
828 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
829 target_t
*target
= bank
->target
;
830 uint32_t address
= offset
;
831 uint32_t flash_cris
, flash_fmc
;
832 uint32_t words_remaining
= (count
/ 4);
833 uint32_t bytes_remaining
= (count
& 0x00000003);
834 uint32_t bytes_written
= 0;
837 if (bank
->target
->state
!= TARGET_HALTED
)
839 LOG_ERROR("Target not halted");
840 return ERROR_TARGET_NOT_HALTED
;
843 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
844 bank
, buffer
, offset
, count
);
846 if (stellaris_info
->did1
== 0)
848 stellaris_read_part_info(bank
);
851 if (stellaris_info
->did1
== 0)
853 LOG_WARNING("Cannot identify target as a Stellaris processor");
854 return ERROR_FLASH_OPERATION_FAILED
;
859 LOG_WARNING("offset size must be word aligned");
860 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
863 if (offset
+ count
> bank
->size
)
864 return ERROR_FLASH_DST_OUT_OF_BANK
;
866 /* Configure the flash controller timing */
867 stellaris_read_clock_info(bank
);
868 stellaris_set_flash_mode(bank
, 0);
870 /* Clear and disable flash programming interrupts */
871 target_write_u32(target
, FLASH_CIM
, 0);
872 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
874 /* multiple words to be programmed? */
875 if (words_remaining
> 0)
877 /* try using a block write */
878 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
880 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
882 /* if block write failed (no sufficient working area),
883 * we use normal (slow) single dword accesses */
884 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
886 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
888 /* if an error occured, we examine the reason, and quit */
889 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
891 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
892 return ERROR_FLASH_OPERATION_FAILED
;
897 buffer
+= words_remaining
* 4;
898 address
+= words_remaining
* 4;
903 while (words_remaining
> 0)
905 if (!(address
& 0xff))
906 LOG_DEBUG("0x%" PRIx32
"", address
);
908 /* Program one word */
909 target_write_u32(target
, FLASH_FMA
, address
);
910 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
911 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
912 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
913 /* Wait until write complete */
916 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
917 } while (flash_fmc
& FMC_WRITE
);
926 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
929 while (bytes_remaining
> 0)
931 last_word
[i
++] = *(buffer
+ bytes_written
);
936 if (!(address
& 0xff))
937 LOG_DEBUG("0x%" PRIx32
"", address
);
939 /* Program one word */
940 target_write_u32(target
, FLASH_FMA
, address
);
941 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
942 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
943 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
944 /* Wait until write complete */
947 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
948 } while (flash_fmc
& FMC_WRITE
);
951 /* Check access violations */
952 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
953 if (flash_cris
& (AMASK
))
955 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
956 return ERROR_FLASH_OPERATION_FAILED
;
961 static int stellaris_probe(struct flash_bank_s
*bank
)
963 /* we can't probe on an stellaris
964 * if this is an stellaris, it has the configured flash
967 if (bank
->target
->state
!= TARGET_HALTED
)
969 LOG_ERROR("Target not halted");
970 return ERROR_TARGET_NOT_HALTED
;
973 /* stellaris_read_part_info() already takes care about error checking and reporting */
974 return stellaris_read_part_info(bank
);
977 static int stellaris_auto_probe(struct flash_bank_s
*bank
)
979 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
980 if (stellaris_info
->did1
)
982 return stellaris_probe(bank
);
985 static int stellaris_mass_erase(struct flash_bank_s
*bank
)
987 target_t
*target
= NULL
;
988 stellaris_flash_bank_t
*stellaris_info
= NULL
;
991 stellaris_info
= bank
->driver_priv
;
992 target
= bank
->target
;
994 if (target
->state
!= TARGET_HALTED
)
996 LOG_ERROR("Target not halted");
997 return ERROR_TARGET_NOT_HALTED
;
1000 if (stellaris_info
->did1
== 0)
1002 stellaris_read_part_info(bank
);
1005 if (stellaris_info
->did1
== 0)
1007 LOG_WARNING("Cannot identify target as Stellaris");
1008 return ERROR_FLASH_OPERATION_FAILED
;
1011 /* Configure the flash controller timing */
1012 stellaris_read_clock_info(bank
);
1013 stellaris_set_flash_mode(bank
, 0);
1015 /* Clear and disable flash programming interrupts */
1016 target_write_u32(target
, FLASH_CIM
, 0);
1017 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1019 target_write_u32(target
, FLASH_FMA
, 0);
1020 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1021 /* Wait until erase complete */
1024 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1026 while (flash_fmc
& FMC_MERASE
);
1028 /* if device has > 128k, then second erase cycle is needed
1029 * this is only valid for older devices, but will not hurt */
1030 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1032 target_write_u32(target
, FLASH_FMA
, 0x20000);
1033 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1034 /* Wait until erase complete */
1037 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1039 while (flash_fmc
& FMC_MERASE
);
1045 static int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1052 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1056 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1059 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1063 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1065 /* set all sectors as erased */
1066 for (i
= 0; i
< bank
->num_sectors
; i
++)
1068 bank
->sectors
[i
].is_erased
= 1;
1071 command_print(cmd_ctx
, "stellaris mass erase complete");
1075 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)