1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 /***************************************************************************
22 * STELLARIS is tested on LM3S811, LM3S6965
23 ***************************************************************************/
28 #include "replacements.h"
30 #include "stellaris.h"
31 #include "cortex_m3.h"
36 #include "binarybuffer.h"
43 #define DID0_VER(did0) ((did0>>28)&0x07)
44 int stellaris_register_commands(struct command_context_s
*cmd_ctx
);
45 int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
46 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
);
47 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
48 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
49 int stellaris_auto_probe(struct flash_bank_s
*bank
);
50 int stellaris_probe(struct flash_bank_s
*bank
);
51 int stellaris_protect_check(struct flash_bank_s
*bank
);
52 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
54 int stellaris_read_part_info(struct flash_bank_s
*bank
);
55 u32
stellaris_get_flash_status(flash_bank_t
*bank
);
56 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
57 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
);
59 int stellaris_read_part_info(struct flash_bank_s
*bank
);
60 int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 int stellaris_mass_erase(struct flash_bank_s
*bank
);
63 flash_driver_t stellaris_flash
=
66 .register_commands
= stellaris_register_commands
,
67 .flash_bank_command
= stellaris_flash_bank_command
,
68 .erase
= stellaris_erase
,
69 .protect
= stellaris_protect
,
70 .write
= stellaris_write
,
71 .probe
= stellaris_probe
,
72 .auto_probe
= stellaris_auto_probe
,
73 .erase_check
= default_flash_mem_blank_check
,
74 .protect_check
= stellaris_protect_check
,
75 .info
= stellaris_info
115 /*{0x33,"LM3S2616"},*/
234 char * StellarisClassname
[5] =
243 /***************************************************************************
244 * openocd command interface *
245 ***************************************************************************/
247 /* flash_bank stellaris <base> <size> 0 0 <target#>
249 int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
251 stellaris_flash_bank_t
*stellaris_info
;
255 LOG_WARNING("incomplete flash_bank stellaris configuration");
256 return ERROR_FLASH_BANK_INVALID
;
259 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
), 1);
261 bank
->driver_priv
= stellaris_info
;
263 stellaris_info
->target_name
= "Unknown target";
265 /* part wasn't probed for info yet */
266 stellaris_info
->did1
= 0;
268 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
272 int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
274 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stellaris", NULL
, COMMAND_ANY
, "stellaris flash specific commands");
276 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stellaris_handle_mass_erase_command
, COMMAND_EXEC
, "mass erase device");
280 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
282 int printed
, device_class
;
283 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
285 stellaris_read_part_info(bank
);
287 if (stellaris_info
->did1
== 0)
289 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
292 return ERROR_FLASH_OPERATION_FAILED
;
295 if (DID0_VER(stellaris_info
->did0
) > 0)
297 device_class
= (stellaris_info
->did0
>>16) & 0xFF;
303 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
304 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
305 'A' + ((stellaris_info
->did0
>>8) & 0xFF), (stellaris_info
->did0
) & 0xFF);
309 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
310 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+((stellaris_info
->dc0
>>16) & 0xFFFF))/4, (1+(stellaris_info
->dc0
& 0xFFFF))*2);
314 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
318 if (stellaris_info
->num_lockbits
>0)
320 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
);
327 /***************************************************************************
328 * chip identification and status *
329 ***************************************************************************/
331 u32
stellaris_get_flash_status(flash_bank_t
*bank
)
333 target_t
*target
= bank
->target
;
336 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
341 /** Read clock configuration and set stellaris_info->usec_clocks*/
343 void stellaris_read_clock_info(flash_bank_t
*bank
)
345 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
346 target_t
*target
= bank
->target
;
347 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
348 unsigned long mainfreq
;
350 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
351 LOG_DEBUG("Stellaris RCC %x", rcc
);
352 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
353 LOG_DEBUG("Stellaris PLLCFG %x", pllcfg
);
354 stellaris_info
->rcc
= rcc
;
356 sysdiv
= (rcc
>>23) & 0xF;
357 usesysdiv
= (rcc
>>22) & 0x1;
358 bypass
= (rcc
>>11) & 0x1;
359 oscsrc
= (rcc
>>4) & 0x3;
360 /* xtal = (rcc>>6)&0xF; */
364 mainfreq
= 6000000; /* Default xtal */
367 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
370 mainfreq
= 5625000; /* Internal osc. / 4 */
373 LOG_WARNING("Invalid oscsrc (3) in rcc register");
377 default: /* NOTREACHED */
383 mainfreq
= 200000000; /* PLL out frec */
386 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
388 stellaris_info
->mck_freq
= mainfreq
;
390 /* Forget old flash timing */
391 stellaris_set_flash_mode(bank
, 0);
394 /* Setup the timimg registers */
395 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
397 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
398 target_t
*target
= bank
->target
;
400 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
401 LOG_DEBUG("usecrl = %i",usecrl
);
402 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
405 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
409 /* Stellaris waits for cmdbit to clear */
410 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
412 LOG_DEBUG("status: 0x%x", status
);
416 /* Flash errors are reflected in the FLASH_CRIS register */
421 /* Send one command to the flash controller */
422 int stellaris_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
425 target_t
*target
= bank
->target
;
427 fmc
= FMC_WRKEY
| cmd
;
428 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
429 LOG_DEBUG("Flash command: 0x%x", fmc
);
431 if (stellaris_wait_status_busy(bank
, cmd
, 100))
433 return ERROR_FLASH_OPERATION_FAILED
;
439 /* Read device id register, main clock frequency register and fill in driver info structure */
440 int stellaris_read_part_info(struct flash_bank_s
*bank
)
442 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
443 target_t
*target
= bank
->target
;
444 u32 did0
, did1
, ver
, fam
, status
;
447 /* Read and parse chip identification register */
448 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
449 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
450 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
451 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
452 LOG_DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x", did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
455 if((ver
!= 0) && (ver
!= 1))
457 LOG_WARNING("Unknown did0 version, cannot identify target");
458 return ERROR_FLASH_OPERATION_FAILED
;
463 LOG_WARNING("Cannot identify target as a Stellaris");
464 return ERROR_FLASH_OPERATION_FAILED
;
468 fam
= (did1
>> 24) & 0xF;
469 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
471 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
474 for (i
= 0; StellarisParts
[i
].partno
; i
++)
476 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFF))
480 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
482 stellaris_info
->did0
= did0
;
483 stellaris_info
->did1
= did1
;
485 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
486 stellaris_info
->num_pages
= 2 *(1+(stellaris_info
->dc0
& 0xFFFF));
487 stellaris_info
->pagesize
= 1024;
488 bank
->size
= 1024 * stellaris_info
->num_pages
;
489 stellaris_info
->pages_in_lockregion
= 2;
490 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
492 /* provide this for the benefit of the higher flash driver layers */
493 bank
->num_sectors
= stellaris_info
->num_pages
;
494 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
495 for (i
= 0; i
< bank
->num_sectors
; i
++)
497 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
498 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
499 bank
->sectors
[i
].is_erased
= -1;
500 bank
->sectors
[i
].is_protected
= -1;
503 /* Read main and master clock freqency register */
504 stellaris_read_clock_info(bank
);
506 status
= stellaris_get_flash_status(bank
);
511 /***************************************************************************
513 ***************************************************************************/
515 int stellaris_protect_check(struct flash_bank_s
*bank
)
519 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
521 if (bank
->target
->state
!= TARGET_HALTED
)
523 return ERROR_TARGET_NOT_HALTED
;
526 if (stellaris_info
->did1
== 0)
528 stellaris_read_part_info(bank
);
531 if (stellaris_info
->did1
== 0)
533 LOG_WARNING("Cannot identify target as an AT91SAM");
534 return ERROR_FLASH_OPERATION_FAILED
;
537 status
= stellaris_get_flash_status(bank
);
538 stellaris_info
->lockbits
= status
>> 16;
543 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
546 u32 flash_fmc
, flash_cris
;
547 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
548 target_t
*target
= bank
->target
;
550 if (bank
->target
->state
!= TARGET_HALTED
)
552 return ERROR_TARGET_NOT_HALTED
;
555 if (stellaris_info
->did1
== 0)
557 stellaris_read_part_info(bank
);
560 if (stellaris_info
->did1
== 0)
562 LOG_WARNING("Cannot identify target as Stellaris");
563 return ERROR_FLASH_OPERATION_FAILED
;
566 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_pages
))
568 return ERROR_FLASH_SECTOR_INVALID
;
571 if ((first
== 0) && (last
== (stellaris_info
->num_pages
-1)))
573 return stellaris_mass_erase(bank
);
576 /* Configure the flash controller timing */
577 stellaris_read_clock_info(bank
);
578 stellaris_set_flash_mode(bank
,0);
580 /* Clear and disable flash programming interrupts */
581 target_write_u32(target
, FLASH_CIM
, 0);
582 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
584 for (banknr
= first
; banknr
<= last
; banknr
++)
586 /* Address is first word in page */
587 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
588 /* Write erase command */
589 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
590 /* Wait until erase complete */
593 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
595 while(flash_fmc
& FMC_ERASE
);
597 /* Check acess violations */
598 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
599 if(flash_cris
& (AMASK
))
601 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
602 target_write_u32(target
, FLASH_CRIS
, 0);
603 return ERROR_FLASH_OPERATION_FAILED
;
606 bank
->sectors
[banknr
].is_erased
= 1;
612 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
614 u32 fmppe
, flash_fmc
, flash_cris
;
617 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
618 target_t
*target
= bank
->target
;
620 if (bank
->target
->state
!= TARGET_HALTED
)
622 return ERROR_TARGET_NOT_HALTED
;
625 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
627 return ERROR_FLASH_SECTOR_INVALID
;
630 if (stellaris_info
->did1
== 0)
632 stellaris_read_part_info(bank
);
635 if (stellaris_info
->did1
== 0)
637 LOG_WARNING("Cannot identify target as an Stellaris MCU");
638 return ERROR_FLASH_OPERATION_FAILED
;
641 /* Configure the flash controller timing */
642 stellaris_read_clock_info(bank
);
643 stellaris_set_flash_mode(bank
, 0);
645 fmppe
= stellaris_info
->lockbits
;
646 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
649 fmppe
&= ~(1<<lockregion
);
651 fmppe
|= (1<<lockregion
);
654 /* Clear and disable flash programming interrupts */
655 target_write_u32(target
, FLASH_CIM
, 0);
656 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
658 LOG_DEBUG("fmppe 0x%x",fmppe
);
659 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
661 target_write_u32(target
, FLASH_FMA
, 1);
662 /* Write commit command */
663 /* TODO safety check, sice this cannot be undone */
664 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
665 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
666 /* Wait until erase complete */
669 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
671 while(flash_fmc
& FMC_COMT
);
673 /* Check acess violations */
674 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
675 if(flash_cris
& (AMASK
))
677 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
678 target_write_u32(target
, FLASH_CRIS
, 0);
679 return ERROR_FLASH_OPERATION_FAILED
;
682 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
687 u8 stellaris_write_code
[] =
692 r1 = destination address
693 r2 = bytecount (in) - endaddr (work)
696 r3 = pFLASH_CTRL_BASE
702 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
703 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
704 0x01,0x25, /* movs r5, 1 */
705 0x00,0x26, /* movs r6, #0 */
707 0x19,0x60, /* str r1, [r3, #0] */
708 0x87,0x59, /* ldr r7, [r0, r6] */
709 0x5F,0x60, /* str r7, [r3, #4] */
710 0x9C,0x60, /* str r4, [r3, #8] */
712 0x9F,0x68, /* ldr r7, [r3, #8] */
713 0x2F,0x42, /* tst r7, r5 */
714 0xFC,0xD1, /* bne waitloop */
715 0x04,0x31, /* adds r1, r1, #4 */
716 0x04,0x36, /* adds r6, r6, #4 */
717 0x96,0x42, /* cmp r6, r2 */
718 0xF4,0xD1, /* bne mainloop */
720 0xFE,0xE7, /* b exit */
721 /* pFLASH_CTRL_BASE: */
722 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
724 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
727 int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
729 target_t
*target
= bank
->target
;
730 u32 buffer_size
= 8192;
731 working_area_t
*source
;
732 working_area_t
*write_algorithm
;
733 u32 address
= bank
->base
+ offset
;
734 reg_param_t reg_params
[3];
735 armv7m_algorithm_t armv7m_info
;
736 int retval
= ERROR_OK
;
738 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
739 bank
, buffer
, offset
, wcount
);
741 /* flash write code */
742 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
744 LOG_WARNING("no working area available, can't do block memory writes");
745 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
748 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
751 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
753 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
754 target
, buffer_size
, source
);
756 if (buffer_size
<= 256)
758 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
760 target_free_working_area(target
, write_algorithm
);
762 LOG_WARNING("no large enough working area available, can't do block memory writes");
763 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
767 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
768 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
770 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
771 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
772 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
776 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
778 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
780 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
781 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
782 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
783 LOG_INFO("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
784 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining", thisrun_count
, address
, wcount
);
785 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
)
787 LOG_ERROR("error executing stellaris flash write algorithm");
788 retval
= ERROR_FLASH_OPERATION_FAILED
;
792 buffer
+= thisrun_count
* 4;
793 address
+= thisrun_count
* 4;
794 wcount
-= thisrun_count
;
797 target_free_working_area(target
, write_algorithm
);
798 target_free_working_area(target
, source
);
800 destroy_reg_param(®_params
[0]);
801 destroy_reg_param(®_params
[1]);
802 destroy_reg_param(®_params
[2]);
807 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
809 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
810 target_t
*target
= bank
->target
;
811 u32 address
= offset
;
812 u32 flash_cris
,flash_fmc
;
815 if (bank
->target
->state
!= TARGET_HALTED
)
817 return ERROR_TARGET_NOT_HALTED
;
820 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
821 bank
, buffer
, offset
, count
);
823 if (stellaris_info
->did1
== 0)
825 stellaris_read_part_info(bank
);
828 if (stellaris_info
->did1
== 0)
830 LOG_WARNING("Cannot identify target as a Stellaris processor");
831 return ERROR_FLASH_OPERATION_FAILED
;
834 if((offset
& 3) || (count
& 3))
836 LOG_WARNING("offset size must be word aligned");
837 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
840 if (offset
+ count
> bank
->size
)
841 return ERROR_FLASH_DST_OUT_OF_BANK
;
843 /* Configure the flash controller timing */
844 stellaris_read_clock_info(bank
);
845 stellaris_set_flash_mode(bank
, 0);
847 /* Clear and disable flash programming interrupts */
848 target_write_u32(target
, FLASH_CIM
, 0);
849 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
851 /* multiple words to be programmed? */
854 /* try using a block write */
855 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, count
/4)) != ERROR_OK
)
857 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
859 /* if block write failed (no sufficient working area),
860 * we use normal (slow) single dword accesses */
861 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
863 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
865 /* if an error occured, we examine the reason, and quit */
866 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
868 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
869 return ERROR_FLASH_OPERATION_FAILED
;
875 address
+= count
* 4;
882 if (!(address
& 0xff))
883 LOG_DEBUG("0x%x", address
);
885 /* Program one word */
886 target_write_u32(target
, FLASH_FMA
, address
);
887 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
888 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
889 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
890 /* Wait until write complete */
893 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
895 while (flash_fmc
& FMC_WRITE
);
900 /* Check acess violations */
901 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
902 if (flash_cris
& (AMASK
))
904 LOG_DEBUG("flash_cris 0x%x", flash_cris
);
905 return ERROR_FLASH_OPERATION_FAILED
;
910 int stellaris_probe(struct flash_bank_s
*bank
)
912 /* we can't probe on an stellaris
913 * if this is an stellaris, it has the configured flash
916 if (bank
->target
->state
!= TARGET_HALTED
)
918 return ERROR_TARGET_NOT_HALTED
;
921 /* stellaris_read_part_info() already takes care about error checking and reporting */
922 return stellaris_read_part_info(bank
);
925 int stellaris_auto_probe(struct flash_bank_s
*bank
)
927 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
928 if (stellaris_info
->did1
)
930 return stellaris_probe(bank
);
933 int stellaris_mass_erase(struct flash_bank_s
*bank
)
935 target_t
*target
= NULL
;
936 stellaris_flash_bank_t
*stellaris_info
= NULL
;
939 stellaris_info
= bank
->driver_priv
;
940 target
= bank
->target
;
942 if (target
->state
!= TARGET_HALTED
)
944 return ERROR_TARGET_NOT_HALTED
;
947 if (stellaris_info
->did1
== 0)
949 stellaris_read_part_info(bank
);
952 if (stellaris_info
->did1
== 0)
954 LOG_WARNING("Cannot identify target as Stellaris");
955 return ERROR_FLASH_OPERATION_FAILED
;
958 /* Configure the flash controller timing */
959 stellaris_read_clock_info(bank
);
960 stellaris_set_flash_mode(bank
, 0);
962 /* Clear and disable flash programming interrupts */
963 target_write_u32(target
, FLASH_CIM
, 0);
964 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
966 target_write_u32(target
, FLASH_FMA
, 0);
967 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
968 /* Wait until erase complete */
971 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
973 while (flash_fmc
& FMC_MERASE
);
975 /* if device has > 128k, then second erase cycle is needed
976 * this is only valid for older devices, but will not hurt */
977 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
979 target_write_u32(target
, FLASH_FMA
, 0x20000);
980 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
981 /* Wait until erase complete */
984 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
986 while (flash_fmc
& FMC_MERASE
);
992 int stellaris_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
999 command_print(cmd_ctx
, "stellaris mass_erase <bank>");
1003 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1006 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1010 stellaris_mass_erase(bank
);
1012 /* set all sectors as erased */
1013 for (i
= 0; i
< bank
->num_sectors
; i
++)
1015 bank
->sectors
[i
].is_erased
= 1;
1018 command_print(cmd_ctx
, "stellaris mass erase complete");
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)