This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28388S: Program not loading from flash on power up/reset

Part Number: TMS320F28388S
Other Parts Discussed in Thread: C2000WARE

Tool/software: C2000ware, CCS12, XDS110

I'm working on a custom board with custom software. I am trying to boot the MCU from flash. Everything works as expected when connected to CCS through a debugger (XDS110). However, when power cycling the MCU does not appear to be booting from flash. 

I have checked the boot mode pins against Table 8-16 in the data sheet:

After power cycling the target, reconnecting in the debugger, and resuming execution, the MCU is stuck on the following instruction: 

3FB114: 6F00 SB 0, UNC
 and does not appear to ever jump to code_start. This is the same behavior as seen in this post. 

If I power cycle the target and reconnect the debugger and go to Scripts->EMU Boot Mode Select->EMU_BOOT_FLASH, then resume the target, the MCU jumps to code_start as expected. 

When inspected the memory at 0x080000, the code for the code start section is present, and not overwritten with 0xFFFFFFFF. 

I have not done anything to program the flash peripheral, my thinking being that the defaults should be fine for this first bit of testing. Later I plan on enabling pre-fetch and caching. The only difference here that I can see is that the example projects do enable pre-fetching and caching, but otherwise all the flash settings are set to the hardware defaults. 

The codestart.asm file was pulled from an existing example project: 

WD_DISABLE  .set  1    ;set to 1 to disable WD, else set to 0

    .ref _c_int00
    .global code_start

***********************************************************************
* Function: codestart section
*
* Description: Branch to code starting point
***********************************************************************

    .sect "codestart"
    .retain

code_start:
    .if WD_DISABLE == 1
        LB wd_disable       ;Branch to watchdog disable code
    .else
        LB _c_int00         ;Branch to start of boot._asm in RTS library
    .endif

;end codestart section

***********************************************************************
* Function: wd_disable
*
* Description: Disables the watchdog timer
***********************************************************************
    .if WD_DISABLE == 1

    .text
wd_disable:
    SETC OBJMODE        ;Set OBJMODE for 28x object code
    EALLOW              ;Enable EALLOW protected register access
    MOVZ DP, #7029h>>6  ;Set data page for WDCR register
    MOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WD
    EDIS                ;Disable EALLOW protected register access
    LB _c_int00         ;Branch to start of boot._asm in RTS library

    .endif

;end wd_disable

    .end

And the linker command file is shown below as well (slightly modified to assign some variables to shared CPU1->CM memory). 

MEMORY
{
   /* BEGIN is used for the "boot to Flash" bootloader mode   */
   BEGIN            : origin = 0x080000, length = 0x000002
   BOOT_RSVD        : origin = 0x000002, length = 0x0001AF     /* Part of M0, BOOT rom will use this for stack */
   RAMM0            : origin = 0x0001B1, length = 0x00024F
   RAMM1            : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
//   RAMM1_RSVD       : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
   RAMD0            : origin = 0x00C000, length = 0x000800
   RAMD1            : origin = 0x00C800, length = 0x000800
   RAMLS0           : origin = 0x008000, length = 0x000800
   RAMLS1           : origin = 0x008800, length = 0x000800
   RAMLS2           : origin = 0x009000, length = 0x000800
   RAMLS3           : origin = 0x009800, length = 0x000800
   RAMLS4           : origin = 0x00A000, length = 0x000800
   RAMLS5           : origin = 0x00A800, length = 0x000800
   RAMLS6           : origin = 0x00B000, length = 0x000800
   RAMLS7           : origin = 0x00B800, length = 0x000800
   RAMGS0           : origin = 0x00D000, length = 0x001000
   RAMGS1           : origin = 0x00E000, length = 0x001000
   RAMGS2           : origin = 0x00F000, length = 0x001000
   RAMGS3           : origin = 0x010000, length = 0x001000
   RAMGS4           : origin = 0x011000, length = 0x001000
   RAMGS5           : origin = 0x012000, length = 0x001000
   RAMGS6           : origin = 0x013000, length = 0x001000
   RAMGS7           : origin = 0x014000, length = 0x001000
   RAMGS8           : origin = 0x015000, length = 0x001000
   RAMGS9           : origin = 0x016000, length = 0x001000
   RAMGS10          : origin = 0x017000, length = 0x001000
   RAMGS11          : origin = 0x018000, length = 0x001000
   RAMGS12          : origin = 0x019000, length = 0x001000
   RAMGS13          : origin = 0x01A000, length = 0x001000
   RAMGS14          : origin = 0x01B000, length = 0x001000
   RAMGS15          : origin = 0x01C000, length = 0x000FF8
//   RAMGS15_RSVD     : origin = 0x01CFF8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

   /* Flash sectors */
   FLASH0           : origin = 0x080002, length = 0x001FFE  /* on-chip Flash */
   FLASH1           : origin = 0x082000, length = 0x002000  /* on-chip Flash */
   FLASH2           : origin = 0x084000, length = 0x002000  /* on-chip Flash */
   FLASH3           : origin = 0x086000, length = 0x002000  /* on-chip Flash */
   FLASH4           : origin = 0x088000, length = 0x008000  /* on-chip Flash */
   FLASH5           : origin = 0x090000, length = 0x008000  /* on-chip Flash */
   FLASH6           : origin = 0x098000, length = 0x008000  /* on-chip Flash */
   FLASH7           : origin = 0x0A0000, length = 0x008000  /* on-chip Flash */
   FLASH8           : origin = 0x0A8000, length = 0x008000  /* on-chip Flash */
   FLASH9           : origin = 0x0B0000, length = 0x008000  /* on-chip Flash */
   FLASH10          : origin = 0x0B8000, length = 0x002000  /* on-chip Flash */
   FLASH11          : origin = 0x0BA000, length = 0x002000  /* on-chip Flash */
   FLASH12          : origin = 0x0BC000, length = 0x002000  /* on-chip Flash */
   FLASH13          : origin = 0x0BE000, length = 0x001FF0  /* on-chip Flash */
//   FLASH13_RSVD     : origin = 0x0BFFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

   CPU1TOCPU2RAM   : origin = 0x03A000, length = 0x000800
   CPU2TOCPU1RAM   : origin = 0x03B000, length = 0x000800
   CPUTOCMRAM      : origin = 0x039000, length = 0x000800
   CMTOCPURAM      : origin = 0x038000, length = 0x000800

   CANA_MSG_RAM     : origin = 0x049000, length = 0x000800
   CANB_MSG_RAM     : origin = 0x04B000, length = 0x000800

   RESET            : origin = 0x3FFFC0, length = 0x000002
}

SECTIONS
{
   codestart           : > BEGIN, ALIGN(8)
   .text               : >> FLASH1 | FLASH2 | FLASH3 | FLASH4, ALIGN(8)
   .cinit              : > FLASH4, ALIGN(8)
   .switch             : > FLASH1, ALIGN(8)
   .reset              : > RESET, TYPE = DSECT /* not used, */
   .stack              : > RAMM1

#if defined(__TI_EABI__)
   .init_array      : > FLASH1, ALIGN(8)
   .bss             : > RAMLS5
   .bss:output      : > RAMLS3
   .bss:cio         : > RAMLS5
   .data            : > RAMLS5
   .sysmem          : > RAMLS5
   /* Initalized sections go in Flash */
   .const           : > FLASH5, ALIGN(8)
#else
   .pinit           : > FLASH1, ALIGN(8)
   .ebss            : > RAMLS5
   .esysmem         : > RAMLS5
   .cio             : > RAMLS5
   /* Initalized sections go in Flash */
   .econst          : >> FLASH4 | FLASH5, ALIGN(8)
#endif

   //ramgs0 : > RAMGS0, type=NOINIT
   //ramgs1 : > RAMGS1, type=NOINIT
   
   //MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
   //MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT
   //MSGRAM_CPU_TO_CM    : > CPUTOCMRAM, type=NOINIT
   //MSGRAM_CM_TO_CPU    : > CMTOCPURAM, type=NOINIT

   /* The following section definition are for SDFM examples */
   //Filter_RegsFile  : > RAMGS0
   //Filter1_RegsFile : > RAMGS1, fill=0x1111
   //Filter2_RegsFile : > RAMGS2, fill=0x2222
   //Filter3_RegsFile : > RAMGS3, fill=0x3333
   //Filter4_RegsFile : > RAMGS4, fill=0x4444
   //Difference_RegsFile : >RAMGS5, fill=0x3333

   #if defined(__TI_EABI__)
       .TI.ramfunc : {} LOAD = FLASH3,
                        RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                        LOAD_START(RamfuncsLoadStart),
                        LOAD_SIZE(RamfuncsLoadSize),
                        LOAD_END(RamfuncsLoadEnd),
                        RUN_START(RamfuncsRunStart),
                        RUN_SIZE(RamfuncsRunSize),
                        RUN_END(RamfuncsRunEnd),
                        ALIGN(8)
   #else
       .TI.ramfunc : {} LOAD = FLASH3,
                        RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                        LOAD_START(_RamfuncsLoadStart),
                        LOAD_SIZE(_RamfuncsLoadSize),
                        LOAD_END(_RamfuncsLoadEnd),
                        RUN_START(_RamfuncsRunStart),
                        RUN_SIZE(_RamfuncsRunSize),
                        RUN_END(_RamfuncsRunEnd),
                        ALIGN(8)
   #endif

   	/* Buffer Data Data Section */
	.buffer_1 :> CPUTOCMRAM
    .tx_buffer1 :> RAMGS0

}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

The solution that was posted in the similar posting above is unclear to me, I have all optimizations disabled for this project, and the code start section is present in the flash memory when resetting the CPU as far as I can tell. 

Any help getting this booting from flash would be greatly appreciated, I would like to understand what it is I'm doing wrong. 

  • Hi Joseph,

    I'm working on a custom board with custom software. I am trying to boot the MCU from flash.

    To simplify the issue, can you please try flashing an example from the C2000Ware SDK? I would like to check if you experience the same issue with a piece of known software so we can remove an element from the debug.

    Best Regards,

    Marlyn

  • I tried the same process as above using the adc_ex2_soc_epwm example project. It also stops at a similar instruction when connecting after power up (6F00 SB 0, UNC).

  • Hi Joseph,

    Do you have the XRSn pin brought out on your board? If so, can you please monitor this pin to check if there is a toggle happening?

    Best Regards,

    Marlyn

  • No toggling is occurring on the XRSn pin, just the startup transient (checked out to 800ms). Here is a scope shot of the XRSn line with the 1V2 core voltage and 3V3 rails: 

    Note that in the second shot with the 3V3 rail, the noise is not real, the probe wasn't grounded well when measuring. The 3V3 rail is as clean as the 1V2. 

  • I recalled from the data sheet that there is a recommended resistor across the VDD rail. This is currently not populated, but I didn't think this was needed since I'm currently not using LPM. 

    I can also confirm that placing this resistor does not solve the issue, and the same symptoms remain. 

  • (6F00 SB 0, UNC).

    Hi Joseph,

    Are you using the disassembly view to determine that the code is stopping at this instruction? Can you set a breakpoint at code_start and see if the program ever makes it there?

    Best Regards,

    Marlyn

  • That's correct, the disassembly view showed this. A breakpoint at code_start never triggered. I've been able to determine (at least I think) that this was due to normal bootloader operation. When the emulation boot started, it was trapped at the line I detailed above due to an unsupported EMU key. 

    Checking the memory mapped location for EMUBOOTPINCONFIG (0xD00) showed that when connecting the debugger after a reset without using the script (Scripts->EMU Boot Mode Select->EMU_BOOT_FLASH) was basically being set to a random value. And based on the flow diagram, there was no guarantee that the value that appeared in this register was a valid boot mode, and hence triggered the wait boot state which is why the processor stopped at short branch instruction SB, which holds the program execution in place (i.e. adding 0 to the PC and not allowing the PC to increment). 

    This further showed that I was incorrect about my assumption about the boot process when connecting the debugger when the MCU was already running. It was in-fact resetting the CPU and putting it in an emulation mode, rather than allowing it to perform a standalone boot (I'm sure there's a setting somewhere in CCS that would change this, but this wasn't going to help find the problem). 

    After a little more fiddling and making some pins toggle, I was able to determine that the C28 core was in fact booting correctly from flash. However, it was my boot sequence for the CM that was a little bit off, and wasn't allowing the program to continue execution on the C28 core, nor was the CM booting. I compared the sequence I had to the sequence in the API, and while they were almost the same, I was writing to the reset register multiple times to take the CM out of reset which apparently the CM does not like. 

    Long story short, it all seems to be working.