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
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_erase_check(struct flash_bank_s
*bank
);
52 int stellaris_protect_check(struct flash_bank_s
*bank
);
53 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
55 int stellaris_read_part_info(struct flash_bank_s
*bank
);
56 u32
stellaris_get_flash_status(flash_bank_t
*bank
);
57 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
);
58 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
);
60 int stellaris_read_part_info(struct flash_bank_s
*bank
);
62 flash_driver_t stellaris_flash
=
65 .register_commands
= stellaris_register_commands
,
66 .flash_bank_command
= stellaris_flash_bank_command
,
67 .erase
= stellaris_erase
,
68 .protect
= stellaris_protect
,
69 .write
= stellaris_write
,
70 .probe
= stellaris_probe
,
71 .auto_probe
= stellaris_auto_probe
,
72 .erase_check
= stellaris_erase_check
,
73 .protect_check
= stellaris_protect_check
,
74 .info
= stellaris_info
204 char * StellarisClassname
[2] =
210 /***************************************************************************
211 * openocd command interface *
212 ***************************************************************************/
214 /* flash_bank stellaris <base> <size> 0 0 <target#>
216 int stellaris_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
218 stellaris_flash_bank_t
*stellaris_info
;
222 LOG_WARNING("incomplete flash_bank stellaris configuration");
223 return ERROR_FLASH_BANK_INVALID
;
226 stellaris_info
= calloc(sizeof(stellaris_flash_bank_t
),1);
228 bank
->driver_priv
= stellaris_info
;
230 stellaris_info
->target_name
= "Unknown target";
232 /* part wasn't probed for info yet */
233 stellaris_info
->did1
= 0;
235 /* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
239 int stellaris_register_commands(struct command_context_s
*cmd_ctx
)
242 command_t *stellaris_cmd = register_command(cmd_ctx, NULL, "stellaris", NULL, COMMAND_ANY, NULL);
243 register_command(cmd_ctx, stellaris_cmd, "gpnvm", stellaris_handle_gpnvm_command, COMMAND_EXEC,
244 "stellaris gpnvm <num> <bit> set|clear, set or clear stellaris gpnvm bit");
249 int stellaris_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
251 int printed
, device_class
;
252 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
254 stellaris_read_part_info(bank
);
256 if (stellaris_info
->did1
== 0)
258 printed
= snprintf(buf
, buf_size
, "Cannot identify target as a Stellaris\n");
261 return ERROR_FLASH_OPERATION_FAILED
;
264 if (DID0_VER(stellaris_info
->did0
)>0)
266 device_class
= (stellaris_info
->did0
>>16)&0xFF;
272 printed
= snprintf(buf
, buf_size
, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
273 device_class
, StellarisClassname
[device_class
], stellaris_info
->target_name
,
274 'A' + ((stellaris_info
->did0
>>8)&0xFF), (stellaris_info
->did0
)&0xFF);
278 printed
= snprintf(buf
, buf_size
, "did1: 0x%8.8x, arch: 0x%4.4x, eproc: %s, ramsize:%ik, flashsize: %ik\n",
279 stellaris_info
->did1
, stellaris_info
->did1
, "ARMV7M", (1+((stellaris_info
->dc0
>>16)&0xFFFF))/4, (1+(stellaris_info
->dc0
&0xFFFF))*2);
283 printed
= snprintf(buf
, buf_size
, "master clock(estimated): %ikHz, rcc is 0x%x \n", stellaris_info
->mck_freq
/ 1000, stellaris_info
->rcc
);
287 if (stellaris_info
->num_lockbits
>0) {
288 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
);
295 /***************************************************************************
296 * chip identification and status *
297 ***************************************************************************/
299 u32
stellaris_get_flash_status(flash_bank_t
*bank
)
301 target_t
*target
= bank
->target
;
304 target_read_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, &fmc
);
309 /** Read clock configuration and set stellaris_info->usec_clocks*/
311 void stellaris_read_clock_info(flash_bank_t
*bank
)
313 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
314 target_t
*target
= bank
->target
;
315 u32 rcc
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
316 unsigned long mainfreq
;
318 target_read_u32(target
, SCB_BASE
|RCC
, &rcc
);
319 LOG_DEBUG("Stellaris RCC %x",rcc
);
320 target_read_u32(target
, SCB_BASE
|PLLCFG
, &pllcfg
);
321 LOG_DEBUG("Stellaris PLLCFG %x",pllcfg
);
322 stellaris_info
->rcc
= rcc
;
324 sysdiv
= (rcc
>>23)&0xF;
325 usesysdiv
= (rcc
>>22)&0x1;
326 bypass
= (rcc
>>11)&0x1;
327 oscsrc
= (rcc
>>4)&0x3;
328 /* xtal = (rcc>>6)&0xF; */
332 mainfreq
= 6000000; /* Default xtal */
335 mainfreq
= 22500000; /* Internal osc. 15 MHz +- 50% */
338 mainfreq
= 5625000; /* Internal osc. / 4 */
341 LOG_WARNING("Invalid oscsrc (3) in rcc register");
345 default: /* NOTREACHED */
351 mainfreq
= 200000000; /* PLL out frec */
354 stellaris_info
->mck_freq
= mainfreq
/(1+sysdiv
);
356 stellaris_info
->mck_freq
= mainfreq
;
358 /* Forget old flash timing */
359 stellaris_set_flash_mode(bank
,0);
362 /* Setup the timimg registers */
363 void stellaris_set_flash_mode(flash_bank_t
*bank
,int mode
)
365 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
366 target_t
*target
= bank
->target
;
368 u32 usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
369 LOG_DEBUG("usecrl = %i",usecrl
);
370 target_write_u32(target
, SCB_BASE
|USECRL
, usecrl
);
374 u32
stellaris_wait_status_busy(flash_bank_t
*bank
, u32 waitbits
, int timeout
)
378 /* Stellaris waits for cmdbit to clear */
379 while (((status
= stellaris_get_flash_status(bank
)) & waitbits
) && (timeout
-- > 0))
381 LOG_DEBUG("status: 0x%x", status
);
385 /* Flash errors are reflected in the FLASH_CRIS register */
391 /* Send one command to the flash controller */
392 int stellaris_flash_command(struct flash_bank_s
*bank
,u8 cmd
,u16 pagen
)
395 target_t
*target
= bank
->target
;
397 fmc
= FMC_WRKEY
| cmd
;
398 target_write_u32(target
, FLASH_CONTROL_BASE
|FLASH_FMC
, fmc
);
399 LOG_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 LOG_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 LOG_WARNING("Unknown did0 version, cannot identify target");
428 return ERROR_FLASH_OPERATION_FAILED
;
433 LOG_WARNING("Cannot identify target as a Stellaris");
434 return ERROR_FLASH_OPERATION_FAILED
;
438 fam
= (did1
>> 24) & 0xF;
439 if(((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
441 LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
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 /* provide this for the benefit of the higher flash driver layers */
463 bank
->num_sectors
= stellaris_info
->num_pages
;
464 bank
->sectors
= malloc(sizeof(flash_sector_t
) * bank
->num_sectors
);
465 for (i
= 0; i
< bank
->num_sectors
; i
++)
467 bank
->sectors
[i
].offset
= i
*stellaris_info
->pagesize
;
468 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
469 bank
->sectors
[i
].is_erased
= -1;
470 bank
->sectors
[i
].is_protected
= -1;
473 /* Read main and master clock freqency register */
474 stellaris_read_clock_info(bank
);
476 status
= stellaris_get_flash_status(bank
);
481 /***************************************************************************
483 ***************************************************************************/
485 int stellaris_erase_check(struct flash_bank_s
*bank
)
489 stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
490 target_t *target = bank->target;
498 int stellaris_protect_check(struct flash_bank_s
*bank
)
502 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
504 if (bank
->target
->state
!= TARGET_HALTED
)
506 return ERROR_TARGET_NOT_HALTED
;
509 if (stellaris_info
->did1
== 0)
511 stellaris_read_part_info(bank
);
514 if (stellaris_info
->did1
== 0)
516 LOG_WARNING("Cannot identify target as an AT91SAM");
517 return ERROR_FLASH_OPERATION_FAILED
;
520 status
= stellaris_get_flash_status(bank
);
521 stellaris_info
->lockbits
= status
>> 16;
526 int stellaris_erase(struct flash_bank_s
*bank
, int first
, int last
)
529 u32 flash_fmc
, flash_cris
;
530 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
531 target_t
*target
= bank
->target
;
533 if (bank
->target
->state
!= TARGET_HALTED
)
535 return ERROR_TARGET_NOT_HALTED
;
538 if (stellaris_info
->did1
== 0)
540 stellaris_read_part_info(bank
);
543 if (stellaris_info
->did1
== 0)
545 LOG_WARNING("Cannot identify target as Stellaris");
546 return ERROR_FLASH_OPERATION_FAILED
;
549 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_pages
))
551 return ERROR_FLASH_SECTOR_INVALID
;
554 /* Configure the flash controller timing */
555 stellaris_read_clock_info(bank
);
556 stellaris_set_flash_mode(bank
,0);
558 /* Clear and disable flash programming interrupts */
559 target_write_u32(target
, FLASH_CIM
, 0);
560 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
562 if ((first
== 0) && (last
== (stellaris_info
->num_pages
-1)))
564 target_write_u32(target
, FLASH_FMA
, 0);
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
);
573 /* if device has > 128k, then second erase cycle is needed */
574 if(stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
576 target_write_u32(target
, FLASH_FMA
, 0x20000);
577 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
578 /* Wait until erase complete */
581 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
583 while(flash_fmc
& FMC_MERASE
);
589 for (banknr
=first
;banknr
<=last
;banknr
++)
591 /* Address is first word in page */
592 target_write_u32(target
, FLASH_FMA
, banknr
*stellaris_info
->pagesize
);
593 /* Write erase command */
594 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
595 /* Wait until erase complete */
598 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
600 while(flash_fmc
& FMC_ERASE
);
602 /* Check acess violations */
603 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
604 if(flash_cris
& (AMASK
))
606 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%x", banknr
, flash_cris
);
607 target_write_u32(target
, FLASH_CRIS
, 0);
608 return ERROR_FLASH_OPERATION_FAILED
;
611 bank
->sectors
[banknr
].is_erased
= 1;
617 int stellaris_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
619 u32 fmppe
, flash_fmc
, flash_cris
;
622 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
623 target_t
*target
= bank
->target
;
625 if (bank
->target
->state
!= TARGET_HALTED
)
627 return ERROR_TARGET_NOT_HALTED
;
630 if ((first
< 0) || (last
< first
) || (last
>= stellaris_info
->num_lockbits
))
632 return ERROR_FLASH_SECTOR_INVALID
;
635 if (stellaris_info
->did1
== 0)
637 stellaris_read_part_info(bank
);
640 if (stellaris_info
->did1
== 0)
642 LOG_WARNING("Cannot identify target as an Stellaris MCU");
643 return ERROR_FLASH_OPERATION_FAILED
;
646 /* Configure the flash controller timing */
647 stellaris_read_clock_info(bank
);
648 stellaris_set_flash_mode(bank
,0);
650 fmppe
= stellaris_info
->lockbits
;
651 for (lockregion
=first
;lockregion
<=last
;lockregion
++)
654 fmppe
&= ~(1<<lockregion
);
656 fmppe
|= (1<<lockregion
);
659 /* Clear and disable flash programming interrupts */
660 target_write_u32(target
, FLASH_CIM
, 0);
661 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
663 LOG_DEBUG("fmppe 0x%x",fmppe
);
664 target_write_u32(target
, SCB_BASE
|FMPPE
, fmppe
);
666 target_write_u32(target
, FLASH_FMA
, 1);
667 /* Write commit command */
668 /* TODO safety check, sice this cannot be undone */
669 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
670 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
671 /* Wait until erase complete */
674 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
676 while(flash_fmc
& FMC_COMT
);
678 /* Check acess violations */
679 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
680 if(flash_cris
& (AMASK
))
682 LOG_WARNING("Error setting flash page protection, flash_cris 0x%x", flash_cris
);
683 target_write_u32(target
, FLASH_CRIS
, 0);
684 return ERROR_FLASH_OPERATION_FAILED
;
687 target_read_u32(target
, SCB_BASE
|FMPPE
, &stellaris_info
->lockbits
);
692 u8 stellaris_write_code
[] =
697 r1 = destination address
698 r2 = bytecount (in) - endaddr (work)
701 r3 = pFLASH_CTRL_BASE
707 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
708 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
709 0x01,0x25, /* movs r5, 1 */
710 0x00,0x26, /* movs r6, #0 */
712 0x19,0x60, /* str r1, [r3, #0] */
713 0x87,0x59, /* ldr r7, [r0, r6] */
714 0x5F,0x60, /* str r7, [r3, #4] */
715 0x9C,0x60, /* str r4, [r3, #8] */
717 0x9F,0x68, /* ldr r7, [r3, #8] */
718 0x2F,0x42, /* tst r7, r5 */
719 0xFC,0xD1, /* bne waitloop */
720 0x04,0x31, /* adds r1, r1, #4 */
721 0x04,0x36, /* adds r6, r6, #4 */
722 0x96,0x42, /* cmp r6, r2 */
723 0xF4,0xD1, /* bne mainloop */
724 0x00,0xBE, /* bkpt #0 */
725 /* pFLASH_CTRL_BASE: */
726 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
728 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
731 int stellaris_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 wcount
)
733 target_t
*target
= bank
->target
;
734 u32 buffer_size
= 8192;
735 working_area_t
*source
;
736 working_area_t
*write_algorithm
;
737 u32 address
= bank
->base
+ offset
;
738 reg_param_t reg_params
[8];
739 armv7m_algorithm_t armv7m_info
;
742 LOG_DEBUG("(bank=%p buffer=%p offset=%08X wcount=%08X)",
743 bank
, buffer
, offset
, wcount
);
745 /* flash write code */
746 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
748 LOG_WARNING("no working area available, can't do block memory writes");
749 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
752 target_write_buffer(target
, write_algorithm
->address
, sizeof(stellaris_write_code
), stellaris_write_code
);
755 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
757 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08X source=%p)",
758 target
, buffer_size
, source
);
760 if (buffer_size
<= 256)
762 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
764 target_free_working_area(target
, write_algorithm
);
766 LOG_WARNING("no large enough working area available, can't do block memory writes");
767 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
771 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
772 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
774 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
775 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
776 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
777 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
778 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
779 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
780 init_reg_param(®_params
[6], "r6", 32, PARAM_OUT
);
781 init_reg_param(®_params
[7], "r7", 32, PARAM_OUT
);
785 u32 thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
787 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
789 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
790 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
791 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
792 LOG_WARNING("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
793 LOG_DEBUG("Algorithm flash write %i words to 0x%x, %i remaining",thisrun_count
,address
, wcount
);
794 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
)
796 LOG_ERROR("error executing stellaris flash write algorithm");
797 target_free_working_area(target
, source
);
798 destroy_reg_param(®_params
[0]);
799 destroy_reg_param(®_params
[1]);
800 destroy_reg_param(®_params
[2]);
801 return ERROR_FLASH_OPERATION_FAILED
;
804 buffer
+= thisrun_count
* 4;
805 address
+= thisrun_count
* 4;
806 wcount
-= thisrun_count
;
810 target_free_working_area(target
, write_algorithm
);
811 target_free_working_area(target
, source
);
813 destroy_reg_param(®_params
[0]);
814 destroy_reg_param(®_params
[1]);
815 destroy_reg_param(®_params
[2]);
816 destroy_reg_param(®_params
[3]);
817 destroy_reg_param(®_params
[4]);
818 destroy_reg_param(®_params
[5]);
819 destroy_reg_param(®_params
[6]);
820 destroy_reg_param(®_params
[7]);
825 int stellaris_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
827 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
828 target_t
*target
= bank
->target
;
829 u32 address
= offset
;
830 u32 flash_cris
,flash_fmc
;
833 if (bank
->target
->state
!= TARGET_HALTED
)
835 return ERROR_TARGET_NOT_HALTED
;
838 LOG_DEBUG("(bank=%p buffer=%p offset=%08X count=%08X)",
839 bank
, buffer
, offset
, count
);
841 if (stellaris_info
->did1
== 0)
843 stellaris_read_part_info(bank
);
846 if (stellaris_info
->did1
== 0)
848 LOG_WARNING("Cannot identify target as a Stellaris processor");
849 return ERROR_FLASH_OPERATION_FAILED
;
852 if((offset
& 3) || (count
& 3))
854 LOG_WARNING("offset size must be word aligned");
855 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
858 if (offset
+ count
> bank
->size
)
859 return ERROR_FLASH_DST_OUT_OF_BANK
;
861 /* Configure the flash controller timing */
862 stellaris_read_clock_info(bank
);
863 stellaris_set_flash_mode(bank
,0);
866 /* Clear and disable flash programming interrupts */
867 target_write_u32(target
, FLASH_CIM
, 0);
868 target_write_u32(target
, FLASH_MISC
, PMISC
|AMISC
);
870 /* multiple words to be programmed? */
873 /* try using a block write */
874 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, count
/4)) != ERROR_OK
)
876 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
878 /* if block write failed (no sufficient working area),
879 * we use normal (slow) single dword accesses */
880 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
882 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
884 /* if an error occured, we examine the reason, and quit */
885 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
887 LOG_ERROR("flash writing failed with CRIS: 0x%x", flash_cris
);
888 return ERROR_FLASH_OPERATION_FAILED
;
894 address
+= count
* 4;
903 if (!(address
&0xff)) LOG_DEBUG("0x%x",address
);
904 /* Program one word */
905 target_write_u32(target
, FLASH_FMA
, address
);
906 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
907 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
908 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
909 /* Wait until write complete */
912 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
914 while(flash_fmc
& FMC_WRITE
);
919 /* Check acess violations */
920 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
921 if(flash_cris
& (AMASK
))
923 LOG_DEBUG("flash_cris 0x%x", flash_cris
);
924 return ERROR_FLASH_OPERATION_FAILED
;
930 int stellaris_probe(struct flash_bank_s
*bank
)
932 /* we can't probe on an stellaris
933 * if this is an stellaris, it has the configured flash
936 if (bank
->target
->state
!= TARGET_HALTED
)
938 return ERROR_TARGET_NOT_HALTED
;
941 /* stellaris_read_part_info() already takes care about error checking and reporting */
942 return stellaris_read_part_info(bank
);
945 int stellaris_auto_probe(struct flash_bank_s
*bank
)
947 stellaris_flash_bank_t
*stellaris_info
= bank
->driver_priv
;
948 if (stellaris_info
->did1
)
950 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)