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.

How can I jump to loaded flash code TMS320x28027?

Other Parts Discussed in Thread: CONTROLSUITE

I am using the TMS320x28027.   I am running the code from the following directory C:\ti\controlSUITE\device_support\f2802x\v230\f2802x_examples_structs\f28027_flash_kernel uisng the Code Composer Studio Version: 6.1.1.00022 debugger.  

I wrote my own serial down loader in visual studio to parse a my applications intel hex file and load it.   When it comes to writing the entryaddr.  I am using the one I found in my applicatoins map file as follows

OUTPUT FILE NAME: <GOI_ACIM.out>
ENTRY POINT SYMBOL: "_c_int00" address: 003f5813

I set a brake point just before  before Exit_Boot.asm returns as shown.  

MOV *SP++,#0
MOV *SP++,#0x0A0B
POP ST1
POP ST0

;------------------------------------------------
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;-----------------------------------------------

LRETR  

While I am stopped in the debugger at the LRETR statement above. I load the GOI_ACIM.out which are the symbols for my application.  I then hit F5 to single step.

The debugger complains about not being able to find the following file Boot28.inc

I found the file here and pointed the debugger at it.

C:\ti\ccsv6\tools\compiler\ti-cgt-c2000_15.9.0.STS\lib\src\Boot28.inc

This allows me to single step to the following code in Boot28.inc

_c_int00: .asmfunc
****************************************************************************
* INITIALIZE STACK POINTER. *
****************************************************************************
MOV SP,#__stack ; set to beginning of stack space

I singe step down to the last line I am showing in the is function.

****************************************************************************
* PROCESS CINIT INITIALIZATION TABLE. TABLE IS IN PROGRAM MEMORY IN THE *
* FOLLOWING FORMAT: *
* *
* .word <length of init data in words> *
* .word or .long <address of variable to initialize> *
* .word <init data> *
* .word ... *
* *
* If the variable's address is greater than 65535 (located in 'far' *
* memory), then the address field of the cinit record will be 32-bits *
* instead of the default 16-bits. The length value is negated to tag *
* cinit records for those variables located in far memory. *
* *
* The init table is terminated with a zero length *
* *
****************************************************************************
MOVL XAR7,#cinit ; point XAR7 at start of table
CLRC TC ; reset TC bit used as far flag
B START, UNC ; jump to start processing
LOOP:
MOVB AH,#0 ; zero out upper addr bits
PREAD AL,*XAR7 ; load address of variable to be inited
ADDB XAR7,#1 ; point to initialization data
B GET_DATA,NTC ; get data if variable is not far
CLRC TC ; reset TC bit used as far flag
PREAD AH,*XAR7 ; otherwise, get hi bits of 22-bit addr
ADDB XAR7,#1
GET_DATA:
MOVL XAR6,ACC ; address
RPT AR1 ; repeat length + 1 times

When I single step past the RPT AR1 line above the debugger says

No source available for "0x3ff5f6" 

I then load the Boot Rom symbols from the the following path.

C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\Release\TMS320x2802x_boot_rom_Gold_v200.out

My code is stopped here inside

C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\source\SelectMode_Boot.c

void WaitBoot(void)
{
WatchDogEnable();
for(;;)
{
// If the emulator stops here
// a) change EMU_KEY to 0x55AA
// b) write the appropriate boot mode to EMU_BMODE
// c) perform a debugger reset, and run
asm(" ESTOP0");
}
}

I add expressions for the following variables and change there values in the debugger.  I then do a CPU reset as the per the instructions in the above WaitBoot code above

EmuKey = 0x55AA

EmuBMode = 0x000B  (Flash Boot)

This takes me to the following code in

C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\source\Init_Boot.asm


; Initalize the stack pointer.

__stack: .usect ".stack",0
MOV SP, #__stack ; Initalize the stack pointer

; Initalize the device for running in C28x mode.

C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
C28MAP ; Set blocks M0/M1 for C28x mode
CLRC PAGE0 ; Always use stack addressing mode
MOVW DP,#0 ; Initialize DP to point to the low 64 K
CLRC OVM

; Set PM shift of 0

SPM 0

; Decide which boot mode to use
LCR _SelectBootMode

I then single step all the way through SelectBootMode

Uint32 SelectBootMode()
{

Uint32 EntryAddr;
Uint16 BootMode;

WatchDogService();

EALLOW;

// Before waking up the flash
// set the POR to the minimum trip point
// If the device was configured by the factory
// this write will have no effect.

*BORTRIM = 0x0100;

// At reset we are in /4 mode. Change to /1
// Calibrate the ADC and internal OSCs
SysCtrlRegs.PLLSTS.bit.DIVSEL = DIVSEL_BY_1;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
(*Device_cal)();
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0;

// Init two locations used by the flash API with 0x0000
Flash_CPUScaleFactor = 0;
Flash_CallbackPtr = 0;
EDIS;

// Read the password locations - this will unlock the
// CSM only if the passwords are erased. Otherwise it
// will not have an effect.
CsmPwl.PSWD0;
CsmPwl.PSWD1;
CsmPwl.PSWD2;
CsmPwl.PSWD3;
CsmPwl.PSWD4;
CsmPwl.PSWD5;
CsmPwl.PSWD6;
CsmPwl.PSWD7;

// If GPIO37/TSO is connected to JTAG,
// read the EMU_KEY_LOC and EMU_BOOT_LOC
// If the key is invalid, assign WAIT to the
// boot mode.
if(DevEmuRegs.DEVICECNF.bit.TRSTn == 1)
{
if(EmuKey != 0x55AA)
{
BootMode = WAIT_BOOT;
}
else BootMode = EmuBMode;
}
// GPIO37/TSO is not connected to JTAG,
// read the state of GPIO34 and GPIO37 to determine
// the boot mode. Store the mode in the EMU_BOOT_LOC
// and EMU_KEY_LOC for use later when GPIO37/TSO is
// connected to JTAG.
else
{
BootMode = GpioDataRegs.GPBDAT.bit.GPIO37 << 1;
BootMode |= GpioDataRegs.GPBDAT.bit.GPIO34;
EALLOW;
EmuBMode = BootMode;
EmuKey = 0x55AA;
EDIS;
}

if(BootMode == WAIT_BOOT) WaitBoot();

WatchDogDisable();
if(BootMode == GET_BOOT)
{
BootMode = (*Get_mode)();
}

if(BootMode == FLASH_BOOT) EntryAddr = FLASH_ENTRY_POINT;
else if(BootMode == OTP_BOOT) EntryAddr = OTP_ENTRY_POINT;
else if(BootMode == RAM_BOOT) EntryAddr = RAM_ENTRY_POINT;
else if(BootMode == SCI_BOOT) EntryAddr = SCI_Boot();
else if(BootMode == SPI_BOOT) EntryAddr = SPI_Boot();
else if(BootMode == I2C_BOOT) EntryAddr = I2C_Boot();
else if(BootMode == PARALLEL_BOOT) EntryAddr = Parallel_Boot();
else if(DevEmuRegs.DEVICECNF.bit.TRSTn == 0)
{
EntryAddr = FLASH_ENTRY_POINT;
}
else WaitBoot();
WatchDogEnable();
return EntryAddr;

}

When I get to the end of the code above

EntryAddr = 0x003F7FF6

I then  single step again the back into C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\source\Init_Boot.asm all the way to the last statement

LCR _SelectBootMode

; Cleanup and exit. At this point the EntryAddr
; is located in the ACC register
BF _ExitBoot,UNC

;-----------------------------------------------
; _ExitBoot
;-----------------------------------------------
;-----------------------------------------------
;This module cleans up after the boot loader
;
; 1) Make sure the stack is deallocated.
; SP = 0x400 after exiting the boot
; loader
; 2) Push 0 onto the stack so RPC will be
; 0 after using LRETR to jump to the
; entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR - this will also clear the RPC
; register since 0 was on the stack
;-----------------------------------------------

_ExitBoot:

;-----------------------------------------------
; Insure that the stack is deallocated
;-----------------------------------------------

MOV SP,#__stack

;-----------------------------------------------
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;-----------------------------------------------

MOV *SP++,#0
MOV *SP++,#0

;-----------------------------------------------
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;-----------------------------------------------

PUSH ACC
POP RPC

;-----------------------------------------------
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
; (OBJMODE = 1, AMODE = 0)
;-----------------------------------------------
ZAPA
MOVL XT,ACC
MOVZ AR0,AL
MOVZ AR1,AL
MOVZ AR2,AL
MOVZ AR3,AL
MOVZ AR4,AL
MOVZ AR5,AL
MOVZ AR6,AL
MOVZ AR7,AL
MOVW DP, #0

;------------------------------------------------
; Restore ST0 and ST1. Note OBJMODE is
; the only bit not restored to its reset state.
; OBJMODE is left set for C28x object operating
; mode.
;
; ST0 = 0x0000 ST1 = 0x0A0B
; 15:10 OVC = 0 15:13 ARP = 0
; 9: 7 PM = 0 12 XF = 0
; 6 V = 0 11 M0M1MAP = 1
; 5 N = 0 10 reserved
; 4 Z = 0 9 OBJMODE = 1
; 3 C = 0 8 AMODE = 0
; 2 TC = 0 7 IDLESTAT = 0
; 1 OVM = 0 6 EALLOW = 0
; 0 SXM = 0 5 LOOP = 0
; 4 SPA = 0
; 3 VMAP = 1
; 2 PAGE0 = 0
; 1 DBGM = 1
; 0 INTM = 1
;-----------------------------------------------

MOV *SP++,#0
MOV *SP++,#0x0A0B
POP ST1
POP ST0

;------------------------------------------------
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;-----------------------------------------------

LRETR

;eof ----------

When I get to the last statement above and single step execution  then goes to LB wd_disable in the following code


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

.sect "codestart"

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

When I single step past the LBwd_disable and end up in the following code inside 

 C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\source\ITrapIsr.asm

;-----------------------------------------------
; _ITRAPIsr
;-----------------------------------------------
;-----------------------------------------------
; This is the ITRAP interrupt service routine for
; thet boot ROM CPU vector table. This routine
; would be called should an ITRAP be encoutered
; before the PIE module was initalized and enabled.
;
; This module performs the following actions:
;
; 1) enables the watchdog
; 2) loops forever
;-----------------------------------------------

.sect ".Isr"

_ITRAPIsr:
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, #0028h ;Clear WDDIS bit in WDCR to enable Watchdog
EDIS ;Disable EALLOW protected register access
SB 0,UNC ;Loop forever

;eof ----------

What am doing wrong?  How can I get my loaded application to boot?

  • James,
    try to program the application using CCS and see if it works (try to use the EMUBOOT to BOOT TO FLASH). If that works and the application doesn;t work after programming through serial loader, then try to dump the flash contents between the two programming models (CCS and your serial loader) and see if the flash contents match and debug from there.


    Best Regards
    Santosh Athuru
  • Hi Santosh,

    My application works when I program it using CCS.

    Isn't true that I am doing an EMUBOOT to BOOT TO FLASH in the what I have posted?
    By setting
    EmuKey = 0x55AA

    EmuBMode = 0x000B (Flash Boot)

    and resetting the debugger. Do you mean something else?

    After I do the EMUBOOT to BOOT TO FLASH which is what I think I'm doing in my posted example. I end up at the

    _ITRAPIsr. The comments in the isr say this
    This is the ITRAP interrupt service routine for
    ; thet boot ROM CPU vector table. This routine
    ; would be called should an ITRAP be encoutered
    ; before the PIE module was initalized and enabled.

    Could it be true?
  • James,
    after you program the the application in flash using CCS and do a debug reset, set EMUKEY to 0x55AA and EMUBOOT to 0x000B and run, the program control should hit your main. If it doesn't , put a break point at the flash Entrypoint (this is a fixed address as documented in TRM and boot ROM branches to this address to start customer application, codestart should be linked to this) and put a break point at main().

    You mentioned that you are able to reach the entrypoint in codestart, but LB WD_DISABLE fails? can you single step in dis-assembly and see why? is the code not present or is it programmed wrong or is it wrong opcode?

    Best Regards
    Santosh Athuru