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
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 int stellaris_register_commands(struct command_context_s
*cmd_ctx
);
48 int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
49 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
);
50 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
51 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
52 int stellaris_auto_probe(struct flash_bank_s
*bank
);
53 int stellaris_probe(struct flash_bank_s
*bank
);
54 int stellaris_erase_check(struct flash_bank_s
*bank
);
55 int stellaris_protect_check(struct flash_bank_s
*bank
);
56 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
58 int stellaris_read_part_info(struct flash_bank_s
*bank
);
59 u32
stellaris_get_flash_status(flash_bank_t
*bank
);
60 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
61 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
);
63 int stellaris_read_part_info(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
= stellaris_erase_check
,
76 .protect_check
= stellaris_protect_check
,
77 .info
= stellaris_info
207 char * StellarisClassname
[2] =
213 /***************************************************************************
214 * openocd command interface *
215 ***************************************************************************/
217 /* flash_bank stellaris <base> <size> 0 0 <target#>
219 int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
221 stellaris_flash_bank_t
*stellaris_info
;
225 WARNING("incomplete flash_bank stellaris configuration");
226 return ERROR_FLASH_BANK_INVALID
;
229 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
),1);
231 bank
->driver_priv
= stellaris_info
;
233 stellaris_info
->target_name
= "Unknown target";
235 /* part wasn't probed for info yet */
236 stellaris_info
->did1
= 0;
238 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
242 int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
245 command_t *stellaris_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, NULL);
246 register_command(cmd_ctx, stellaris_cmd, "gpnvm", stellaris_handle_gpnvm_command, COMMAND_EXEC,
247 "stellaris gpnvm <num> <bit> set|clear, set or clear stellaris gpnvm bit");
252 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
254 int printed
, device_class
;
255 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
257 stellaris_read_part_info(bank
);
259 if (stellaris_info
->did1
== 0)
261 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
264 return ERROR_FLASH_OPERATION_FAILED
;
267 if (DID0_VER(stellaris_info
->did0
)>0)
269 device_class
= (stellaris_info
->did0
>>16)&0xFF;
275 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
276 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
277 'A' + (stellaris_info
->did0
>>8)&0xFF, (stellaris_info
->did0
)&0xFF);
281 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
282 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+(stellaris_info
->dc0
>>16)&0xFFFF)/4, (1+stellaris_info
->dc0
&0xFFFF)*2);
286 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
290 if (stellaris_info
->num_lockbits
>0) {
291 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
);
298 /***************************************************************************
299 * chip identification and status *
300 ***************************************************************************/
302 u32
stellaris_get_flash_status(flash_bank_t
*bank
)
304 target_t
*target
= bank
->target
;
307 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
312 /** Read clock configuration and set stellaris_info->usec_clocks*/
314 void stellaris_read_clock_info(flash_bank_t
*bank
)
316 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
317 target_t
*target
= bank
->target
;
318 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
319 unsigned long mainfreq
;
321 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
322 DEBUG("Stellaris RCC %x",rcc
);
323 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
324 DEBUG("Stellaris PLLCFG %x",pllcfg
);
325 stellaris_info
->rcc
= rcc
;
327 sysdiv
= (rcc
>>23)&0xF;
328 usesysdiv
= (rcc
>>22)&0x1;
329 bypass
= (rcc
>>11)&0x1;
330 oscsrc
= (rcc
>>4)&0x3;
331 /* xtal = (rcc>>6)&0xF; */
335 mainfreq
= 6000000; /* Default xtal */
338 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
341 mainfreq
= 5625000; /* Internal osc. / 4 */
344 WARNING("Invalid oscsrc (3) in rcc register");
350 mainfreq
= 200000000; /* PLL out frec */
353 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
355 stellaris_info
->mck_freq
= mainfreq
;
357 /* Forget old flash timing */
358 stellaris_set_flash_mode(bank
,0);
361 /* Setup the timimg registers */
362 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
364 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
365 target_t
*target
= bank
->target
;
367 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
368 DEBUG("usecrl = %i",usecrl
);
369 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
373 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
377 /* Stellaris waits for cmdbit to clear */
378 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
380 DEBUG("status: 0x%x", status
);
384 /* Flash errors are reflected in the FLASH_CRIS register */
390 /* Send one command to the flash controller */
391 int stellaris_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
394 target_t
*target
= bank
->target
;
396 fmc
= FMC_WRKEY
| cmd
;
397 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
398 DEBUG("Flash command: 0x%x", fmc
);
400 if (stellaris_wait_status_busy(bank
, cmd
, 100))
402 return ERROR_FLASH_OPERATION_FAILED
;
408 /* Read device id register, main clock frequency register and fill in driver info structure */
409 int stellaris_read_part_info(struct flash_bank_s
*bank
)
411 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
412 target_t
*target
= bank
->target
;
413 u32 did0
,did1
, ver
, fam
, status
;
416 /* Read and parse chip identification register */
417 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
418 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
419 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
420 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
421 DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x",did0
, did1
, stellaris_info
->dc0
,stellaris_info
->dc1
);
424 if((ver
!= 0) && (ver
!= 1))
426 WARNING("Unknown did0 version, cannot identify target");
427 return ERROR_FLASH_OPERATION_FAILED
;
432 WARNING("Cannot identify target as a Stellaris");
433 return ERROR_FLASH_OPERATION_FAILED
;
437 fam
= (did1
>> 24) & 0xF;
438 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
440 WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
443 for (i
=0;StellarisParts
[i
].partno
;i
++)
445 if (StellarisParts
[i
].partno
==((did1
>>16)&0xFF))
449 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
451 stellaris_info
->did0
= did0
;
452 stellaris_info
->did1
= did1
;
454 stellaris_info
->num_lockbits
= 1+stellaris_info
->dc0
&0xFFFF;
455 stellaris_info
->num_pages
= 2*(1+stellaris_info
->dc0
&0xFFFF);
456 stellaris_info
->pagesize
= 1024;
457 bank
->size
= 1024*stellaris_info
->num_pages
;
458 stellaris_info
->pages_in_lockregion
= 2;
459 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
461 /* Read main and master clock freqency register */
462 stellaris_read_clock_info(bank
);
464 status
= stellaris_get_flash_status(bank
);
469 /***************************************************************************
471 ***************************************************************************/
473 int stellaris_erase_check(struct flash_bank_s
*bank
)
477 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
478 target_t *target = bank->target;
486 int stellaris_protect_check(struct flash_bank_s
*bank
)
490 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
492 if (bank
->target
->state
!= TARGET_HALTED
)
494 return ERROR_TARGET_NOT_HALTED
;
497 if (stellaris_info
->did1
== 0)
499 stellaris_read_part_info(bank
);
502 if (stellaris_info
->did1
== 0)
504 WARNING("Cannot identify target as an AT91SAM");
505 return ERROR_FLASH_OPERATION_FAILED
;
508 status
= stellaris_get_flash_status(bank
);
509 stellaris_info
->lockbits
= status
>> 16;
514 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
517 u32 flash_fmc
, flash_cris
;
518 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
519 target_t
*target
= bank
->target
;
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 WARNING("Cannot identify target as Stellaris");
534 return ERROR_FLASH_OPERATION_FAILED
;
537 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_pages
))
539 return ERROR_FLASH_SECTOR_INVALID
;
542 /* Configure the flash controller timing */
543 stellaris_read_clock_info(bank
);
544 stellaris_set_flash_mode(bank
,0);
546 /* Clear and disable flash programming interrupts */
547 target_write_u32(target
, FLASH_CIM
, 0);
548 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
550 if ((first
== 0) && (last
== (stellaris_info
->num_pages
-1)))
552 target_write_u32(target
, FLASH_FMA
, 0);
553 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
554 /* Wait until erase complete */
557 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
559 while(flash_fmc
& FMC_MERASE
);
561 /* if device has > 128k, then second erase cycle is needed */
562 if(stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
564 target_write_u32(target
, FLASH_FMA
, 0x20000);
565 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
566 /* Wait until erase complete */
569 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
571 while(flash_fmc
& FMC_MERASE
);
577 for (banknr
=first
;banknr
<=last
;banknr
++)
579 /* Address is first word in page */
580 target_write_u32(target
, FLASH_FMA
, banknr
*stellaris_info
->pagesize
);
581 /* Write erase command */
582 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
583 /* Wait until erase complete */
586 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
588 while(flash_fmc
& FMC_ERASE
);
590 /* Check acess violations */
591 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
592 if(flash_cris
& (AMASK
))
594 WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
595 target_write_u32(target
, FLASH_CRIS
, 0);
596 return ERROR_FLASH_OPERATION_FAILED
;
603 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
605 u32 fmppe
, flash_fmc
, flash_cris
;
608 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
609 target_t
*target
= bank
->target
;
611 if (bank
->target
->state
!= TARGET_HALTED
)
613 return ERROR_TARGET_NOT_HALTED
;
616 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
618 return ERROR_FLASH_SECTOR_INVALID
;
621 if (stellaris_info
->did1
== 0)
623 stellaris_read_part_info(bank
);
626 if (stellaris_info
->did1
== 0)
628 WARNING("Cannot identify target as an Stellaris MCU");
629 return ERROR_FLASH_OPERATION_FAILED
;
632 /* Configure the flash controller timing */
633 stellaris_read_clock_info(bank
);
634 stellaris_set_flash_mode(bank
,0);
636 fmppe
= stellaris_info
->lockbits
;
637 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
640 fmppe
&= ~(1<<lockregion
);
642 fmppe
|= (1<<lockregion
);
645 /* Clear and disable flash programming interrupts */
646 target_write_u32(target
, FLASH_CIM
, 0);
647 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
649 DEBUG("fmppe 0x%x",fmppe
);
650 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
652 target_write_u32(target
, FLASH_FMA
, 1);
653 /* Write commit command */
654 /* TODO safety check, sice this cannot be undone */
655 WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
656 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
657 /* Wait until erase complete */
660 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
662 while(flash_fmc
& FMC_COMT
);
664 /* Check acess violations */
665 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
666 if(flash_cris
& (AMASK
))
668 WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
669 target_write_u32(target
, FLASH_CRIS
, 0);
670 return ERROR_FLASH_OPERATION_FAILED
;
673 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
678 u8 stellaris_write_code
[] =
683 r1 = destination address
684 r2 = bytecount (in) - endaddr (work)
687 r3 = pFLASH_CTRL_BASE
693 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
694 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
695 0x01,0x25, /* movs r5, 1 */
696 0x00,0x26, /* movs r6, #0 */
698 0x19,0x60, /* str r1, [r3, #0] */
699 0x87,0x59, /* ldr r7, [r0, r6] */
700 0x5F,0x60, /* str r7, [r3, #4] */
701 0x9C,0x60, /* str r4, [r3, #8] */
703 0x9F,0x68, /* ldr r7, [r3, #8] */
704 0x2F,0x42, /* tst r7, r5 */
705 0xFC,0xD1, /* bne waitloop */
706 0x04,0x31, /* adds r1, r1, #4 */
707 0x04,0x36, /* adds r6, r6, #4 */
708 0x96,0x42, /* cmp r6, r2 */
709 0xF4,0xD1, /* bne mainloop */
710 0x00,0xBE, /* bkpt #0 */
711 /* pFLASH_CTRL_BASE: */
712 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
714 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
717 int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
719 target_t
*target
= bank
->target
;
720 u32 buffer_size
= 8192;
721 working_area_t
*source
;
722 working_area_t
*write_algorithm
;
723 u32 address
= bank
->base
+ offset
;
724 reg_param_t reg_params
[8];
725 armv7m_algorithm_t armv7m_info
;
728 DEBUG("(bank=%08X buffer=%08X offset=%08X wcount=%08X)",
729 (unsigned int)bank
, (unsigned int)buffer
, offset
, wcount
);
731 /* flash write code */
732 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
734 WARNING("no working area available, can't do block memory writes");
735 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
738 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
741 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
743 DEBUG("called target_alloc_working_area(target=%08X buffer_size=%08X source=%08X)",
744 (unsigned int)target
, buffer_size
, (unsigned int)source
);
746 if (buffer_size
<= 256)
748 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
750 target_free_working_area(target
, write_algorithm
);
752 WARNING("no large enough working area available, can't do block memory writes");
753 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
757 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
758 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
759 armv7m_info
.core_state
= ARMV7M_STATE_THUMB
;
761 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
762 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
763 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
764 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
765 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
766 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
767 init_reg_param(®_params
[6], "r6", 32, PARAM_OUT
);
768 init_reg_param(®_params
[7], "r7", 32, PARAM_OUT
);
772 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
774 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
776 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
777 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
778 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
779 WARNING("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
780 DEBUG("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
781 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
)
783 ERROR("error executing stellaris flash write algorithm");
784 target_free_working_area(target
, source
);
785 destroy_reg_param(®_params
[0]);
786 destroy_reg_param(®_params
[1]);
787 destroy_reg_param(®_params
[2]);
788 return ERROR_FLASH_OPERATION_FAILED
;
791 buffer
+= thisrun_count
* 4;
792 address
+= thisrun_count
* 4;
793 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]);
803 destroy_reg_param(®_params
[3]);
804 destroy_reg_param(®_params
[4]);
805 destroy_reg_param(®_params
[5]);
806 destroy_reg_param(®_params
[6]);
807 destroy_reg_param(®_params
[7]);
812 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
814 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
815 target_t
*target
= bank
->target
;
816 u32 address
= offset
;
817 u32 flash_cris
,flash_fmc
;
820 if (bank
->target
->state
!= TARGET_HALTED
)
822 return ERROR_TARGET_NOT_HALTED
;
825 DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)",
826 (unsigned int)bank
, (unsigned int)buffer
, offset
, count
);
828 if (stellaris_info
->did1
== 0)
830 stellaris_read_part_info(bank
);
833 if (stellaris_info
->did1
== 0)
835 WARNING("Cannot identify target as a Stellaris processor");
836 return ERROR_FLASH_OPERATION_FAILED
;
839 if((offset
& 3) || (count
& 3))
841 WARNING("offset size must be word aligned");
842 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
845 if (offset
+ count
> bank
->size
)
846 return ERROR_FLASH_DST_OUT_OF_BANK
;
848 /* Configure the flash controller timing */
849 stellaris_read_clock_info(bank
);
850 stellaris_set_flash_mode(bank
,0);
853 /* Clear and disable flash programming interrupts */
854 target_write_u32(target
, FLASH_CIM
, 0);
855 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
857 /* multiple words to be programmed? */
860 /* try using a block write */
861 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, count
/4)) != ERROR_OK
)
863 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
865 /* if block write failed (no sufficient working area),
866 * we use normal (slow) single dword accesses */
867 WARNING("couldn't use block writes, falling back to single memory accesses");
869 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
871 /* if an error occured, we examine the reason, and quit */
872 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
874 ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
875 return ERROR_FLASH_OPERATION_FAILED
;
881 address
+= count
* 4;
890 if (!(address
&0xff)) DEBUG("0x%x",address
);
891 /* Program one word */
892 target_write_u32(target
, FLASH_FMA
, address
);
893 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
894 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
895 /* DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
896 /* Wait until write complete */
899 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
901 while(flash_fmc
& FMC_WRITE
);
906 /* Check acess violations */
907 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
908 if(flash_cris
& (AMASK
))
910 DEBUG("flash_cris 0x%x", flash_cris
);
911 return ERROR_FLASH_OPERATION_FAILED
;
917 int stellaris_probe(struct flash_bank_s
*bank
)
919 /* we can't probe on an stellaris
920 * if this is an stellaris, it has the configured flash
923 if (bank
->target
->state
!= TARGET_HALTED
)
925 return ERROR_TARGET_NOT_HALTED
;
928 /* stellaris_read_part_info() already takes care about error checking and reporting */
929 return stellaris_read_part_info(bank
);
932 int stellaris_auto_probe(struct flash_bank_s
*bank
)
934 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
935 if (stellaris_info
->did1
)
937 return stellaris_probe(bank
);
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)