1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
24 /***************************************************************************
25 * STELLARIS is tested on LM3S811, LM3S6965
26 ***************************************************************************/
32 #include "stellaris.h"
33 #include <target/algorithm.h>
34 #include <target/armv7m.h>
37 #define DID0_VER(did0) ((did0 >> 28)&0x07)
39 static void stellaris_read_clock_info(struct flash_bank
*bank
);
40 static int stellaris_mass_erase(struct flash_bank
*bank
);
217 static char * StellarisClassname
[5] =
226 /***************************************************************************
227 * openocd command interface *
228 ***************************************************************************/
230 /* flash_bank stellaris <base> <size> 0 0 <target#>
232 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
234 struct stellaris_flash_bank
*stellaris_info
;
238 LOG_WARNING("incomplete flash_bank stellaris configuration");
239 return ERROR_FLASH_BANK_INVALID
;
242 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
244 bank
->driver_priv
= stellaris_info
;
246 stellaris_info
->target_name
= "Unknown target";
248 /* part wasn't probed for info yet */
249 stellaris_info
->did1
= 0;
251 /* TODO Specify the main crystal speed in kHz using an optional
252 * argument; ditto, the speed of an external oscillator used
253 * instead of a crystal. Avoid programming flash using IOSC.
258 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
260 int printed
, device_class
;
261 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
263 if (stellaris_info
->did1
== 0)
264 return ERROR_FLASH_BANK_NOT_PROBED
;
266 /* Read main and master clock freqency register */
267 stellaris_read_clock_info(bank
);
269 if (DID0_VER(stellaris_info
->did0
) > 0)
271 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
277 printed
= snprintf(buf
,
279 "\nTI/LMI Stellaris information: Chip is "
280 "class %i (%s) %s rev %c%i\n",
282 StellarisClassname
[device_class
],
283 stellaris_info
->target_name
,
284 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
285 (int)((stellaris_info
->did0
) & 0xFF));
289 printed
= snprintf(buf
,
291 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
292 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
293 stellaris_info
->did1
,
294 stellaris_info
->did1
,
296 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
297 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
301 printed
= snprintf(buf
,
303 "master clock: %ikHz%s, "
304 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
305 (int)(stellaris_info
->mck_freq
/ 1000),
306 stellaris_info
->mck_desc
,
308 stellaris_info
->rcc2
);
312 if (stellaris_info
->num_lockbits
> 0)
314 printed
= snprintf(buf
,
316 "pagesize: %" PRIi32
", pages: %d, "
317 "lockbits: %i, pages per lockbit: %i\n",
318 stellaris_info
->pagesize
,
319 (unsigned) stellaris_info
->num_pages
,
320 stellaris_info
->num_lockbits
,
321 (unsigned) stellaris_info
->pages_in_lockregion
);
328 /***************************************************************************
329 * chip identification and status *
330 ***************************************************************************/
332 /* Set the flash timimg register to match current clocking */
333 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
335 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
336 struct target
*target
= bank
->target
;
337 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
339 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
340 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
343 static const unsigned rcc_xtal
[32] = {
344 [0x00] = 1000000, /* no pll */
345 [0x01] = 1843200, /* no pll */
346 [0x02] = 2000000, /* no pll */
347 [0x03] = 2457600, /* no pll */
351 [0x06] = 4000000, /* usb */
355 [0x09] = 5000000, /* usb */
357 [0x0b] = 6000000, /* (reset) usb */
361 [0x0e] = 8000000, /* usb */
364 /* parts before DustDevil use just 4 bits for xtal spec */
366 [0x10] = 10000000, /* usb */
367 [0x11] = 12000000, /* usb */
372 [0x15] = 16000000, /* usb */
376 /** Read clock configuration and set stellaris_info->usec_clocks. */
377 static void stellaris_read_clock_info(struct flash_bank
*bank
)
379 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
380 struct target
*target
= bank
->target
;
381 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
383 unsigned long mainfreq
;
385 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
386 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
388 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
389 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
391 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
392 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
394 stellaris_info
->rcc
= rcc
;
395 stellaris_info
->rcc
= rcc2
;
397 sysdiv
= (rcc
>> 23) & 0xF;
398 usesysdiv
= (rcc
>> 22) & 0x1;
399 bypass
= (rcc
>> 11) & 0x1;
400 oscsrc
= (rcc
>> 4) & 0x3;
401 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
403 /* NOTE: post-Sandstorm parts have RCC2 which may override
404 * parts of RCC ... with more sysdiv options, option for
405 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
406 * as zero, so the "use RCC2" flag is always clear.
408 if (rcc2
& (1 << 31)) {
409 sysdiv
= (rcc2
>> 23) & 0x3F;
410 bypass
= (rcc2
>> 11) & 0x1;
411 oscsrc
= (rcc2
>> 4) & 0x7;
413 /* FIXME Tempest parts have an additional lsb for
414 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
418 stellaris_info
->mck_desc
= "";
423 mainfreq
= rcc_xtal
[xtal
];
426 mainfreq
= stellaris_info
->iosc_freq
;
427 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
430 mainfreq
= stellaris_info
->iosc_freq
/ 4;
431 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
433 case 3: /* lowspeed */
434 /* Sandstorm doesn't have this 30K +/- 30% osc */
436 stellaris_info
->mck_desc
= " (±30%)";
438 case 8: /* hibernation osc */
439 /* not all parts support hibernation */
443 default: /* NOTREACHED */
448 /* PLL is used if it's not bypassed; its output is 200 MHz
449 * even when it runs at 400 MHz (adds divide-by-two stage).
452 mainfreq
= 200000000;
455 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
457 stellaris_info
->mck_freq
= mainfreq
;
460 /* Read device id register, main clock frequency register and fill in driver info structure */
461 static int stellaris_read_part_info(struct flash_bank
*bank
)
463 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
464 struct target
*target
= bank
->target
;
465 uint32_t did0
, did1
, ver
, fam
;
468 /* Read and parse chip identification register */
469 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
470 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
471 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
472 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
473 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
474 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
477 if ((ver
!= 0) && (ver
!= 1))
479 LOG_WARNING("Unknown did0 version, cannot identify target");
480 return ERROR_FLASH_OPERATION_FAILED
;
485 LOG_WARNING("Cannot identify target as a Stellaris");
486 return ERROR_FLASH_OPERATION_FAILED
;
490 fam
= (did1
>> 24) & 0xF;
491 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
493 LOG_WARNING("Unknown did1 version/family.");
494 return ERROR_FLASH_OPERATION_FAILED
;
497 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
498 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
499 * even give _both_ numbers! We'll use current numbers; IOSC is
500 * always approximate.
502 * For Tempest: IOSC is calibrated, 16 MHz
504 stellaris_info
->iosc_freq
= 12000000;
505 stellaris_info
->iosc_desc
= " (±30%)";
506 stellaris_info
->xtal_mask
= 0x0f;
508 switch ((did0
>> 28) & 0x7) {
509 case 0: /* Sandstorm */
511 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
512 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
513 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
515 if (((did0
>> 8) & 0xff) < 2) {
516 stellaris_info
->iosc_freq
= 15000000;
517 stellaris_info
->iosc_desc
= " (±50%)";
521 switch ((did0
>> 16) & 0xff) {
524 case 4: /* Tempest */
525 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
526 stellaris_info
->iosc_desc
= " (±1%)";
528 case 3: /* DustDevil */
529 stellaris_info
->xtal_mask
= 0x1f;
532 LOG_WARNING("Unknown did0 class");
536 LOG_WARNING("Unknown did0 version");
540 for (i
= 0; StellarisParts
[i
].partno
; i
++)
542 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
546 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
548 stellaris_info
->did0
= did0
;
549 stellaris_info
->did1
= did1
;
551 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
552 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
553 stellaris_info
->pagesize
= 1024;
554 stellaris_info
->pages_in_lockregion
= 2;
559 /***************************************************************************
561 ***************************************************************************/
563 static int stellaris_protect_check(struct flash_bank
*bank
)
565 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
566 int status
= ERROR_OK
;
570 if (stellaris
->did1
== 0)
571 return ERROR_FLASH_BANK_NOT_PROBED
;
573 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
574 bank
->sectors
[i
].is_protected
= -1;
576 /* Read each Flash Memory Protection Program Enable (FMPPE) register
577 * to report any pages that we can't write. Ignore the Read Enable
580 for (i
= 0, page
= 0;
581 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
585 status
= target_read_u32(bank
->target
,
586 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
588 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
589 (unsigned) lockbits
, status
);
590 if (status
!= ERROR_OK
)
593 for (unsigned j
= 0; j
< 32; j
++) {
596 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
597 if (page
>= (unsigned) bank
->num_sectors
)
599 bank
->sectors
[page
++].is_protected
=
600 !(lockbits
& (1 << j
));
609 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
612 uint32_t flash_fmc
, flash_cris
;
613 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
614 struct target
*target
= bank
->target
;
616 if (bank
->target
->state
!= TARGET_HALTED
)
618 LOG_ERROR("Target not halted");
619 return ERROR_TARGET_NOT_HALTED
;
622 if (stellaris_info
->did1
== 0)
623 return ERROR_FLASH_BANK_NOT_PROBED
;
625 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
627 return ERROR_FLASH_SECTOR_INVALID
;
630 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
632 return stellaris_mass_erase(bank
);
635 /* Refresh flash controller timing */
636 stellaris_read_clock_info(bank
);
637 stellaris_set_flash_timing(bank
);
639 /* Clear and disable flash programming interrupts */
640 target_write_u32(target
, FLASH_CIM
, 0);
641 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
643 for (banknr
= first
; banknr
<= last
; banknr
++)
645 /* Address is first word in page */
646 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
647 /* Write erase command */
648 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
649 /* Wait until erase complete */
652 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
654 while (flash_fmc
& FMC_ERASE
);
656 /* Check acess violations */
657 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
658 if (flash_cris
& (AMASK
))
660 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
661 target_write_u32(target
, FLASH_CRIS
, 0);
662 return ERROR_FLASH_OPERATION_FAILED
;
665 bank
->sectors
[banknr
].is_erased
= 1;
671 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
673 uint32_t fmppe
, flash_fmc
, flash_cris
;
676 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
677 struct target
*target
= bank
->target
;
679 if (bank
->target
->state
!= TARGET_HALTED
)
681 LOG_ERROR("Target not halted");
682 return ERROR_TARGET_NOT_HALTED
;
687 LOG_ERROR("Can't unprotect write-protected pages.");
688 /* except by the "recover locked device" procedure ... */
689 return ERROR_INVALID_ARGUMENTS
;
692 if (stellaris_info
->did1
== 0)
693 return ERROR_FLASH_BANK_NOT_PROBED
;
695 /* lockregions are 2 pages ... must protect [even..odd] */
696 if ((first
< 0) || (first
& 1)
697 || (last
< first
) || !(last
& 1)
698 || (last
>= 2 * stellaris_info
->num_lockbits
))
700 LOG_ERROR("Can't protect unaligned or out-of-range sectors.");
701 return ERROR_FLASH_SECTOR_INVALID
;
704 /* Refresh flash controller timing */
705 stellaris_read_clock_info(bank
);
706 stellaris_set_flash_timing(bank
);
708 /* convert from pages to lockregions */
712 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
713 * Current parts can be much bigger.
716 LOG_ERROR("No support yet for protection > 64K");
717 return ERROR_FLASH_OPERATION_FAILED
;
720 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
722 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
723 fmppe
&= ~(1 << lockregion
);
725 /* Clear and disable flash programming interrupts */
726 target_write_u32(target
, FLASH_CIM
, 0);
727 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
729 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
730 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
733 target_write_u32(target
, FLASH_FMA
, 1);
735 /* Write commit command */
736 /* REVISIT safety check, since this cannot be undone
737 * except by the "Recover a locked device" procedure.
739 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
740 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
742 /* Wait until erase complete */
745 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
747 while (flash_fmc
& FMC_COMT
);
749 /* Check acess violations */
750 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
751 if (flash_cris
& (AMASK
))
753 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
754 target_write_u32(target
, FLASH_CRIS
, 0);
755 return ERROR_FLASH_OPERATION_FAILED
;
761 static const uint8_t stellaris_write_code
[] =
766 r1 = destination address
767 r2 = bytecount (in) - endaddr (work)
770 r3 = pFLASH_CTRL_BASE
776 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
777 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
778 0x01,0x25, /* movs r5, 1 */
779 0x00,0x26, /* movs r6, #0 */
781 0x19,0x60, /* str r1, [r3, #0] */
782 0x87,0x59, /* ldr r7, [r0, r6] */
783 0x5F,0x60, /* str r7, [r3, #4] */
784 0x9C,0x60, /* str r4, [r3, #8] */
786 0x9F,0x68, /* ldr r7, [r3, #8] */
787 0x2F,0x42, /* tst r7, r5 */
788 0xFC,0xD1, /* bne waitloop */
789 0x04,0x31, /* adds r1, r1, #4 */
790 0x04,0x36, /* adds r6, r6, #4 */
791 0x96,0x42, /* cmp r6, r2 */
792 0xF4,0xD1, /* bne mainloop */
794 0xFE,0xE7, /* b exit */
795 /* pFLASH_CTRL_BASE: */
796 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
798 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
801 static int stellaris_write_block(struct flash_bank
*bank
,
802 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
804 struct target
*target
= bank
->target
;
805 uint32_t buffer_size
= 8192;
806 struct working_area
*source
;
807 struct working_area
*write_algorithm
;
808 uint32_t address
= bank
->base
+ offset
;
809 struct reg_param reg_params
[3];
810 struct armv7m_algorithm armv7m_info
;
811 int retval
= ERROR_OK
;
813 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
814 bank
, buffer
, offset
, wcount
);
816 /* flash write code */
817 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
819 LOG_WARNING("no working area available, can't do block memory writes");
820 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
823 target_write_buffer(target
, write_algorithm
->address
,
824 sizeof(stellaris_write_code
),
825 (uint8_t *) stellaris_write_code
);
828 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
830 LOG_DEBUG("called target_alloc_working_area(target=%p buffer_size=%08" PRIx32
" source=%p)",
831 target
, buffer_size
, source
);
833 if (buffer_size
<= 256)
835 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
837 target_free_working_area(target
, write_algorithm
);
839 LOG_WARNING("no large enough working area available, can't do block memory writes");
840 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
844 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
845 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
847 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
848 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
849 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
853 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
855 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
857 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
858 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
859 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
860 LOG_INFO("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
861 LOG_DEBUG("Algorithm flash write %" PRIi32
" words to 0x%" PRIx32
", %" PRIi32
" remaining", thisrun_count
, address
, (wcount
- thisrun_count
));
862 if ((retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, write_algorithm
->address
, write_algorithm
->address
+ sizeof(stellaris_write_code
)-10, 10000, &armv7m_info
)) != ERROR_OK
)
864 LOG_ERROR("error executing stellaris flash write algorithm");
865 retval
= ERROR_FLASH_OPERATION_FAILED
;
869 buffer
+= thisrun_count
* 4;
870 address
+= thisrun_count
* 4;
871 wcount
-= thisrun_count
;
874 target_free_working_area(target
, write_algorithm
);
875 target_free_working_area(target
, source
);
877 destroy_reg_param(®_params
[0]);
878 destroy_reg_param(®_params
[1]);
879 destroy_reg_param(®_params
[2]);
884 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
886 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
887 struct target
*target
= bank
->target
;
888 uint32_t address
= offset
;
889 uint32_t flash_cris
, flash_fmc
;
890 uint32_t words_remaining
= (count
/ 4);
891 uint32_t bytes_remaining
= (count
& 0x00000003);
892 uint32_t bytes_written
= 0;
895 if (bank
->target
->state
!= TARGET_HALTED
)
897 LOG_ERROR("Target not halted");
898 return ERROR_TARGET_NOT_HALTED
;
901 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
902 bank
, buffer
, offset
, count
);
904 if (stellaris_info
->did1
== 0)
905 return ERROR_FLASH_BANK_NOT_PROBED
;
909 LOG_WARNING("offset size must be word aligned");
910 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
913 if (offset
+ count
> bank
->size
)
914 return ERROR_FLASH_DST_OUT_OF_BANK
;
916 /* Refresh flash controller timing */
917 stellaris_read_clock_info(bank
);
918 stellaris_set_flash_timing(bank
);
920 /* Clear and disable flash programming interrupts */
921 target_write_u32(target
, FLASH_CIM
, 0);
922 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
924 /* multiple words to be programmed? */
925 if (words_remaining
> 0)
927 /* try using a block write */
928 if ((retval
= stellaris_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
930 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
932 /* if block write failed (no sufficient working area),
933 * we use normal (slow) single dword accesses */
934 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
936 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
938 /* if an error occured, we examine the reason, and quit */
939 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
941 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
942 return ERROR_FLASH_OPERATION_FAILED
;
947 buffer
+= words_remaining
* 4;
948 address
+= words_remaining
* 4;
953 while (words_remaining
> 0)
955 if (!(address
& 0xff))
956 LOG_DEBUG("0x%" PRIx32
"", address
);
958 /* Program one word */
959 target_write_u32(target
, FLASH_FMA
, address
);
960 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
961 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
962 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
963 /* Wait until write complete */
966 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
967 } while (flash_fmc
& FMC_WRITE
);
976 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
979 while (bytes_remaining
> 0)
981 last_word
[i
++] = *(buffer
+ bytes_written
);
986 if (!(address
& 0xff))
987 LOG_DEBUG("0x%" PRIx32
"", address
);
989 /* Program one word */
990 target_write_u32(target
, FLASH_FMA
, address
);
991 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
992 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
993 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
994 /* Wait until write complete */
997 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
998 } while (flash_fmc
& FMC_WRITE
);
1001 /* Check access violations */
1002 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1003 if (flash_cris
& (AMASK
))
1005 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1006 return ERROR_FLASH_OPERATION_FAILED
;
1011 static int stellaris_probe(struct flash_bank
*bank
)
1013 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1016 /* If this is a stellaris chip, it has flash; probe() is just
1017 * to figure out how much is present. Only do it once.
1019 if (stellaris_info
->did1
!= 0)
1022 /* stellaris_read_part_info() already handled error checking and
1023 * reporting. Note that it doesn't write, so we don't care about
1024 * whether the target is halted or not.
1026 retval
= stellaris_read_part_info(bank
);
1027 if (retval
!= ERROR_OK
)
1030 /* provide this for the benefit of the NOR flash framework */
1031 bank
->size
= 1024 * stellaris_info
->num_pages
;
1032 bank
->num_sectors
= stellaris_info
->num_pages
;
1033 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
1034 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1036 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
1037 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
1038 bank
->sectors
[i
].is_erased
= -1;
1039 bank
->sectors
[i
].is_protected
= -1;
1045 static int stellaris_mass_erase(struct flash_bank
*bank
)
1047 struct target
*target
= NULL
;
1048 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1051 stellaris_info
= bank
->driver_priv
;
1052 target
= bank
->target
;
1054 if (target
->state
!= TARGET_HALTED
)
1056 LOG_ERROR("Target not halted");
1057 return ERROR_TARGET_NOT_HALTED
;
1060 if (stellaris_info
->did1
== 0)
1061 return ERROR_FLASH_BANK_NOT_PROBED
;
1063 /* Refresh flash controller timing */
1064 stellaris_read_clock_info(bank
);
1065 stellaris_set_flash_timing(bank
);
1067 /* Clear and disable flash programming interrupts */
1068 target_write_u32(target
, FLASH_CIM
, 0);
1069 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1071 target_write_u32(target
, FLASH_FMA
, 0);
1072 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1073 /* Wait until erase complete */
1076 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1078 while (flash_fmc
& FMC_MERASE
);
1080 /* if device has > 128k, then second erase cycle is needed
1081 * this is only valid for older devices, but will not hurt */
1082 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1084 target_write_u32(target
, FLASH_FMA
, 0x20000);
1085 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1086 /* Wait until erase complete */
1089 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1091 while (flash_fmc
& FMC_MERASE
);
1097 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1103 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1107 struct flash_bank
*bank
;
1108 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1109 if (ERROR_OK
!= retval
)
1112 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1114 /* set all sectors as erased */
1115 for (i
= 0; i
< bank
->num_sectors
; i
++)
1117 bank
->sectors
[i
].is_erased
= 1;
1120 command_print(CMD_CTX
, "stellaris mass erase complete");
1124 command_print(CMD_CTX
, "stellaris mass erase failed");
1130 static const struct command_registration stellaris_exec_command_handlers
[] = {
1132 .name
= "mass_erase",
1133 .handler
= &stellaris_handle_mass_erase_command
,
1134 .mode
= COMMAND_EXEC
,
1135 .help
= "erase entire device",
1137 COMMAND_REGISTRATION_DONE
1139 static const struct command_registration stellaris_command_handlers
[] = {
1141 .name
= "stellaris",
1142 .mode
= COMMAND_ANY
,
1143 .help
= "Stellaris flash command group",
1144 .chain
= stellaris_exec_command_handlers
,
1146 COMMAND_REGISTRATION_DONE
1149 struct flash_driver stellaris_flash
= {
1150 .name
= "stellaris",
1151 .commands
= stellaris_command_handlers
,
1152 .flash_bank_command
= stellaris_flash_bank_command
,
1153 .erase
= stellaris_erase
,
1154 .protect
= stellaris_protect
,
1155 .write
= stellaris_write
,
1156 .probe
= stellaris_probe
,
1157 .auto_probe
= stellaris_probe
,
1158 .erase_check
= default_flash_mem_blank_check
,
1159 .protect_check
= stellaris_protect_check
,
1160 .info
= stellaris_info
,
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)