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 // stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
395 target_t
*target
= bank
->target
;
397 fmc
= FMC_WRKEY
| cmd
;
398 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
399 DEBUG("Flash command: 0x%x", fmc
);
401 if (stellaris_wait_status_busy(bank
, cmd
, 100))
403 return ERROR_FLASH_OPERATION_FAILED
;
409 /* Read device id register, main clock frequency register and fill in driver info structure */
410 int stellaris_read_part_info(struct flash_bank_s
*bank
)
412 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
413 target_t
*target
= bank
->target
;
414 u32 did0
,did1
, ver
, fam
, status
;
417 /* Read and parse chip identification register */
418 target_read_u32(target
, SCB_BASE
|DID0
, &did0
);
419 target_read_u32(target
, SCB_BASE
|DID1
, &did1
);
420 target_read_u32(target
, SCB_BASE
|DC0
, &stellaris_info
->dc0
);
421 target_read_u32(target
, SCB_BASE
|DC1
, &stellaris_info
->dc1
);
422 DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x",did0
, did1
, stellaris_info
->dc0
,stellaris_info
->dc1
);
425 if((ver
!= 0) && (ver
!= 1))
427 WARNING("Unknown did0 version, cannot identify target");
428 return ERROR_FLASH_OPERATION_FAILED
;
432 fam
= (did1
>> 24) & 0xF;
433 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
435 WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
440 WARNING("Cannot identify target as a Stellaris");
441 return ERROR_FLASH_OPERATION_FAILED
;
444 for (i
=0;StellarisParts
[i
].partno
;i
++)
446 if (StellarisParts
[i
].partno
==((did1
>>16)&0xFF))
450 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
452 stellaris_info
->did0
= did0
;
453 stellaris_info
->did1
= did1
;
455 stellaris_info
->num_lockbits
= 1+stellaris_info
->dc0
&0xFFFF;
456 stellaris_info
->num_pages
= 2*(1+stellaris_info
->dc0
&0xFFFF);
457 stellaris_info
->pagesize
= 1024;
458 bank
->size
= 1024*stellaris_info
->num_pages
;
459 stellaris_info
->pages_in_lockregion
= 2;
460 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
462 // Read main and master clock freqency register
463 stellaris_read_clock_info(bank
);
465 status
= stellaris_get_flash_status(bank
);
470 /***************************************************************************
472 ***************************************************************************/
474 int stellaris_erase_check(struct flash_bank_s
*bank
)
478 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
479 target_t *target = bank->target;
487 int stellaris_protect_check(struct flash_bank_s
*bank
)
491 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
493 if (stellaris_info
->did1
== 0)
495 stellaris_read_part_info(bank
);
498 if (stellaris_info
->did1
== 0)
500 WARNING("Cannot identify target as an AT91SAM");
501 return ERROR_FLASH_OPERATION_FAILED
;
504 status
= stellaris_get_flash_status(bank
);
505 stellaris_info
->lockbits
= status
>> 16;
510 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
513 u32 flash_fmc
, flash_cris
;
514 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
515 target_t
*target
= bank
->target
;
517 if (stellaris_info
->did1
== 0)
519 stellaris_read_part_info(bank
);
522 if (stellaris_info
->did1
== 0)
524 WARNING("Cannot identify target as Stellaris");
525 return ERROR_FLASH_OPERATION_FAILED
;
528 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_pages
))
530 return ERROR_FLASH_SECTOR_INVALID
;
533 /* Configure the flash controller timing */
534 stellaris_read_clock_info(bank
);
535 stellaris_set_flash_mode(bank
,0);
537 /* Clear and disable flash programming interrupts */
538 target_write_u32(target
, FLASH_CIM
, 0);
539 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
541 if ((first
== 0) && (last
== (stellaris_info
->num_pages
-1)))
543 target_write_u32(target
, FLASH_FMA
, 0);
544 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
545 /* Wait until erase complete */
548 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
550 while(flash_fmc
& FMC_MERASE
);
552 /* if device has > 128k, then second erase cycle is needed */
553 if(stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
555 target_write_u32(target
, FLASH_FMA
, 0x20000);
556 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
557 /* Wait until erase complete */
560 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
562 while(flash_fmc
& FMC_MERASE
);
568 for (banknr
=first
;banknr
<=last
;banknr
++)
570 /* Address is first word in page */
571 target_write_u32(target
, FLASH_FMA
, banknr
*stellaris_info
->pagesize
);
572 /* Write erase command */
573 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
574 /* Wait until erase complete */
577 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
579 while(flash_fmc
& FMC_ERASE
);
581 /* Check acess violations */
582 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
583 if(flash_cris
& (AMASK
))
585 WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
586 target_write_u32(target
, FLASH_CRIS
, 0);
587 return ERROR_FLASH_OPERATION_FAILED
;
594 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
596 u32 fmppe
, flash_fmc
, flash_cris
;
599 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
600 target_t
*target
= bank
->target
;
602 if (bank
->target
->state
!= TARGET_HALTED
)
604 return ERROR_TARGET_NOT_HALTED
;
607 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
609 return ERROR_FLASH_SECTOR_INVALID
;
612 if (stellaris_info
->did1
== 0)
614 stellaris_read_part_info(bank
);
617 if (stellaris_info
->did1
== 0)
619 WARNING("Cannot identify target as an Stellaris MCU");
620 return ERROR_FLASH_OPERATION_FAILED
;
623 /* Configure the flash controller timing */
624 stellaris_read_clock_info(bank
);
625 stellaris_set_flash_mode(bank
,0);
627 fmppe
= stellaris_info
->lockbits
;
628 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
631 fmppe
&= ~(1<<lockregion
);
633 fmppe
|= (1<<lockregion
);
636 /* Clear and disable flash programming interrupts */
637 target_write_u32(target
, FLASH_CIM
, 0);
638 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
640 DEBUG("fmppe 0x%x",fmppe
);
641 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
643 target_write_u32(target
, FLASH_FMA
, 1);
644 /* Write commit command */
645 /* TODO safety check, sice this cannot be undone */
646 WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
647 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
648 /* Wait until erase complete */
651 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
653 while(flash_fmc
& FMC_COMT
);
655 /* Check acess violations */
656 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
657 if(flash_cris
& (AMASK
))
659 WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
660 target_write_u32(target
, FLASH_CRIS
, 0);
661 return ERROR_FLASH_OPERATION_FAILED
;
664 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
669 u8 stellaris_write_code
[] =
674 r1 = destination address
675 r2 = bytecount (in) - endaddr (work)
678 r3 = pFLASH_CTRL_BASE
684 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
685 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
686 0x01,0x25, /* movs r5, 1 */
687 0x00,0x26, /* movs r6, #0 */
689 0x19,0x60, /* str r1, [r3, #0] */
690 0x87,0x59, /* ldr r7, [r0, r6] */
691 0x5F,0x60, /* str r7, [r3, #4] */
692 0x9C,0x60, /* str r4, [r3, #8] */
694 0x9F,0x68, /* ldr r7, [r3, #8] */
695 0x2F,0x42, /* tst r7, r5 */
696 0xFC,0xD1, /* bne waitloop */
697 0x04,0x31, /* adds r1, r1, #4 */
698 0x04,0x36, /* adds r6, r6, #4 */
699 0x96,0x42, /* cmp r6, r2 */
700 0xF4,0xD1, /* bne mainloop */
701 0x00,0xBE, /* bkpt #0 */
702 /* pFLASH_CTRL_BASE: */
703 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
705 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
708 int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
710 // stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
711 target_t
*target
= bank
->target
;
712 u32 buffer_size
= 8192;
713 working_area_t
*source
;
714 working_area_t
*write_algorithm
;
715 u32 address
= bank
->base
+ offset
;
716 reg_param_t reg_params
[8];
717 armv7m_algorithm_t armv7m_info
;
720 DEBUG("(bank=%08X buffer=%08X offset=%08X wcount=%08X)",
721 (unsigned int)bank
, (unsigned int)buffer
, offset
, wcount
);
723 /* flash write code */
724 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
726 WARNING("no working area available, can't do block memory writes");
727 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
730 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
733 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
735 DEBUG("called target_alloc_working_area(target=%08X buffer_size=%08X source=%08X)",
736 (unsigned int)target
, buffer_size
, (unsigned int)source
);
738 if (buffer_size
<= 256)
740 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
742 target_free_working_area(target
, write_algorithm
);
744 WARNING("no large enough working area available, can't do block memory writes");
745 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
749 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
750 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
751 armv7m_info
.core_state
= ARMV7M_STATE_THUMB
;
753 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
754 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
755 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
756 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
757 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
758 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
759 init_reg_param(®_params
[6], "r6", 32, PARAM_OUT
);
760 init_reg_param(®_params
[7], "r7", 32, PARAM_OUT
);
764 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
766 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
768 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
769 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
770 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
771 WARNING("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
772 DEBUG("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
773 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
)
775 ERROR("error executing stellaris flash write algorithm");
776 target_free_working_area(target
, source
);
777 destroy_reg_param(®_params
[0]);
778 destroy_reg_param(®_params
[1]);
779 destroy_reg_param(®_params
[2]);
780 return ERROR_FLASH_OPERATION_FAILED
;
783 buffer
+= thisrun_count
* 4;
784 address
+= thisrun_count
* 4;
785 wcount
-= thisrun_count
;
789 target_free_working_area(target
, write_algorithm
);
790 target_free_working_area(target
, source
);
792 destroy_reg_param(®_params
[0]);
793 destroy_reg_param(®_params
[1]);
794 destroy_reg_param(®_params
[2]);
795 destroy_reg_param(®_params
[3]);
796 destroy_reg_param(®_params
[4]);
797 destroy_reg_param(®_params
[5]);
798 destroy_reg_param(®_params
[6]);
799 destroy_reg_param(®_params
[7]);
804 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
806 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
807 target_t
*target
= bank
->target
;
808 u32 address
= offset
;
809 u32 flash_cris
,flash_fmc
;
812 DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)",
813 (unsigned int)bank
, (unsigned int)buffer
, offset
, count
);
815 if (stellaris_info
->did1
== 0)
817 stellaris_read_part_info(bank
);
820 if (stellaris_info
->did1
== 0)
822 WARNING("Cannot identify target as a Stellaris processor");
823 return ERROR_FLASH_OPERATION_FAILED
;
826 if((offset
& 3) || (count
& 3))
828 WARNING("offset size must be word aligned");
829 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
832 if (offset
+ count
> bank
->size
)
833 return ERROR_FLASH_DST_OUT_OF_BANK
;
835 /* Configure the flash controller timing */
836 stellaris_read_clock_info(bank
);
837 stellaris_set_flash_mode(bank
,0);
840 /* Clear and disable flash programming interrupts */
841 target_write_u32(target
, FLASH_CIM
, 0);
842 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
844 /* multiple words to be programmed? */
847 /* try using a block write */
848 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, count
/4)) != ERROR_OK
)
850 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
852 /* if block write failed (no sufficient working area),
853 * we use normal (slow) single dword accesses */
854 WARNING("couldn't use block writes, falling back to single memory accesses");
856 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
858 /* if an error occured, we examine the reason, and quit */
859 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
861 ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
862 return ERROR_FLASH_OPERATION_FAILED
;
868 address
+= count
* 4;
877 if (!(address
&0xff)) DEBUG("0x%x",address
);
878 /* Program one word */
879 target_write_u32(target
, FLASH_FMA
, address
);
880 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
881 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
882 //DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE);
883 /* Wait until write complete */
886 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
888 while(flash_fmc
& FMC_WRITE
);
893 /* Check acess violations */
894 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
895 if(flash_cris
& (AMASK
))
897 DEBUG("flash_cris 0x%x", flash_cris
);
898 return ERROR_FLASH_OPERATION_FAILED
;
904 int stellaris_probe(struct flash_bank_s
*bank
)
906 /* we can't probe on an stellaris
907 * if this is an stellaris, it has the configured flash
909 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
911 stellaris_info
->probed
= 0;
913 if (stellaris_info
->did1
== 0)
915 stellaris_read_part_info(bank
);
918 if (stellaris_info
->did1
== 0)
920 WARNING("Cannot identify target as a LMI Stellaris");
921 return ERROR_FLASH_OPERATION_FAILED
;
924 stellaris_info
->probed
= 1;
929 int stellaris_auto_probe(struct flash_bank_s
*bank
)
931 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
932 if (stellaris_info
->probed
)
934 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)