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.

TMS320F28379D: TMS320F28379D Flash memory programming: code breaks at ETRAP0 within InitFlash()

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Hi everyone,

I have an issue related to Flash programming. Before being redirected to manuals, I confirm I have gone through the multi-day workshops training, Lab #10 for the flash programming examples, as well as the report SPRA958L.

I can run Lab #10 with no issue.

My current application however is based on the skeleton code provided in Lab #3 from the One-Day-Workshop instead (Control peripherals). Everything runs fine from RAM. I am trying to run this from flash. I have modified the link command file to suit this purpose.
I keep encountering the following: Break at address "0x3fe493" with no debug information available, or outside of program code. In the disassembly window I can see: 3fe493: 7625 ESTOP0

The only answer to this I could find it at the following link: https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/861317/ccs-launchxl-f28379d-break-at-address-0x3fe493-with-no-debug-information-available-or-outside-of-program-code

Still no success going through that suggestion. This should be the most basic example. I added the _FLASH to the properties in order to trigger in SysCtrl() the mempy() and InitFlash() functions. It builds and debugs with no issues. I reset the CPU from Run. Via Scripts I select EMU_BOOT_FLASH. I get back to the Main and if I run, the code breaks at 3fe493 as previously mentioned.

I tried running line by line: the code first breaks at 3fe468: 761B ASP
This is within the InitFlash() function. I am out of the program code in here. I can still run line by line until I arrive at 3fe493. If I keep pressing F5 it CCS will signal that C28xx_CPU1 is suspended, but then sometimes running. In the disassembly window I cannot move past 3fe494 anyway.

I attach two screenshots from CCS. 

Could you please help? What is this issue?

Many thanks,

Nicola Chiodetto

  • Nicola,

    Can you share your linker cmd file?  Would like to check how .TI.ramfunc is mapped.  ITRAP is occurring in this case.  

    Also, please share your code where memcpy() is called.

    Please take a look at this FAQ: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/878674/faq-flash---how-to-modify-an-application-from-ram-configuration-to-flash-configuration 

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    I attach the .cmd file. 

    When it comes to the code where memcpy() is called I am using the Sys_Ctrl.c routine source. Attach that for completeness.

    Many thanks,

    Nicola

    /* .cmd file for FLASH implementation of memory allocation withouh CLA operations - just allocation */
    
    /* Set up 512 word scratchpad memory for use by CLA1 */
    /* Needed because CLA has no stack */
    #ifdef CLA_C
    CLA_SCRATCHPAD_SIZE = 0x200;	/* original value = 0x100 */
    --undef_sym=__cla_scratchpad_end
    --undef_sym=__cla_scratchpad_start
    #endif
    
    -heap 0x3000	/* extend esysmem to 12k to accomodate data stores */
    
    
    MEMORY
    {
    PAGE 0 :  /* Program Memory */
              /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
              /* BEGIN is used for the "boot to Flash" bootloader mode   */
    
       BEGIN           	: origin = 0x080000, length = 0x000002
    
       RAMM0           	: origin = 0x000122, length = 0x0002DE
       RAMLS4_5			: origin = 0x00A000, length = 0x001000	/* 4k  RAM for CLA1 */
       // Additionally sections GS0 to GS4 are assigned for program memory too
       RAMGS0_3			: origin = 0x00C000, length = 0x004000	/* 16k (GS0-GS3) for C28x(cpu1) .text */
       RAMGS4      		: origin = 0x010000, length = 0x001000
    
       /*
       RAMM0           	: origin = 0x000122, length = 0x0002DE
       RAMD0           	: origin = 0x00B000, 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
       */
       RESET           	: origin = 0x3FFFC0, length = 0x000002
    
       /* Flash sectors */
       FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
       FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
       FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
       FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
       FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
       FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
       FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
       FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
       FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
       FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
       FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
       FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
       FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
       FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */
    
    PAGE 1 : /* Data Memory */
             /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */
    
       BOOT_RSVD       : origin = 0x000002, length = 0x000120     /* Part of M0, BOOT rom will use this for stack */
       RAMM1           : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
    
       //RAMD1           : origin = 0x00B800, length = 0x000800   /* D0 and D1 are merged as per following line*/
    
       RAMD0_D1		   : origin = 0x00B000, length = 0x001000     /* Expand .ebss for more global variables */
    
       // RAMLS5      : origin = 0x00A800, length = 0x000800
    
       // as mentioned in PAGE 0: the secions from RAMLS0 to RAMLS3 are allocated to this section
    
       RAMLS0			: origin = 0x008000, length = 0x000800
       RAMLS1			: origin = 0x008800, length = 0x000800
       RAMLS2			: origin = 0x009000, length = 0x000800
       RAMLS3			: origin = 0x009800, length = 0x000800
    
       /* as mentioned before from RAMGS0 to RAMGS04 are included in PAGE 0	(for some reasons to explore up to GS8)
       RAMGS0      : origin = 0x00C000, length = 0x001000
       RAMGS1      : origin = 0x00D000, length = 0x001000
       RAMGS2      : origin = 0x00E000, length = 0x001000
       RAMGS3      : origin = 0x00F000, length = 0x001000
       RAMGS4      : origin = 0x010000, length = 0x001000
       RAMGS5      : origin = 0x011000, length = 0x001000
       RAMGS6      : origin = 0x012000, length = 0x001000
       RAMGS7      : origin = 0x013000, length = 0x001000
       RAMGS8      : origin = 0x014000, length = 0x001000
       */
    
       RAMGS9      : origin = 0x015000, length = 0x001000
       // sections 10 to 12 combined
       RAMGS10_12  : origin = 0x016000, length = 0x003000	  /* 12k heap */
       RAMGS13     : origin = 0x019000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
       RAMGS14     : origin = 0x01A000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
       RAMGS15     : origin = 0x01B000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    
       CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
       CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
    
       // Allocation for CLA
       CLA1_MSGRAMLOW	: origin = 0x001480, length = 0x000080
       CLA1_MSGRAMHIGH	: origin = 0x001500, length = 0x000080
    
    }
    
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit              : > FLASHB      PAGE = 0, ALIGN(4)
       .pinit              : > FLASHB,     PAGE = 0, ALIGN(4)
       .text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(4)
       codestart           : > BEGIN       PAGE = 0, ALIGN(4)
       ramfuncs            : LOAD = FLASHD,
                             //RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,  /* this is commented because this section is not allocated for the memory, but the program*/
                             RUN = RAMGS0_3,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             //LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             //RUN_SIZE(_RamfuncsRunSize),
                             //RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(4)
    
       /* Allocate uninitalized data sections: */
       .stack              : > RAMM1        PAGE = 1
       //.ebss               : >> RAMLS5 | RAMGS0 | RAMGS1       PAGE = 1
       .ebss               : > RAMD0_D1       PAGE = 1
       .esysmem            : > RAMGS10_12     PAGE = 1
    
       /* Initalized sections go in Flash */
       .econst             : >> FLASHF | FLASHG | FLASHH      PAGE = 0, ALIGN(4)
       .switch             : > FLASHB      PAGE = 0, ALIGN(4)
    
       .reset              : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
    
    	/* CLA sections */
    	Cla1Prog		: > RAMLS4_5,	PAGE = 0    /* allocation of CLA RAM space for the program*/
    	CLADataLS0		: > RAMLS0,		PAGE = 1
    	CLADataLS1		: > RAMLS1,		PAGE = 1
    
    	Cla1ToCpuMsgRAM	: > CLA1_MSGRAMLOW,		PAGE = 1
    	CpuToCla1MsgRAM	: > CLA1_MSGRAMHIGH,	PAGE = 1
    
    	Cpu1ToCpu2RAM	: > CPU1TOCPU2RAM,	PAGE = 1
    	Cpu2ToCpu1RAM	: >	CPU2TOCPU1RAM,	PAGE = 1
    
       //Filter_RegsFile     : > RAMGS0,	   PAGE = 1
    
       //SHARERAMGS0		: > RAMGS0,		PAGE = 1
       //SHARERAMGS1		: > RAMGS1,		PAGE = 1
       //ramgs0           : > RAMGS0,     PAGE = 1
       //ramgs1           : > RAMGS1,     PAGE = 1
    
    /*
    #ifdef __TI_COMPILER_VERSION__
    	#if __TI_COMPILER_VERSION__ >= 15009000
    	.TI.ramfunc : {} LOAD = FLASHD,
    						 RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
    						 LOAD_START(_RamfuncsLoadStart),
    						 LOAD_SIZE(_RamfuncsLoadSize),
    						 LOAD_END(_RamfuncsLoadEnd),
    						 RUN_START(_RamfuncsRunStart),
    						 RUN_SIZE(_RamfuncsRunSize),
    						 RUN_END(_RamfuncsRunEnd),
    						 PAGE = 0, ALIGN(4)
    	#endif
    #endif
    */
    
       /* The following section definitions are required when using the IPC API Drivers */
        GROUP : > CPU1TOCPU2RAM, PAGE = 1
        {
            PUTBUFFER
            PUTWRITEIDX
            GETREADIDX
        }
    
        GROUP : > CPU2TOCPU1RAM, PAGE = 1
        {
            GETBUFFER :    TYPE = DSECT
            GETWRITEIDX :  TYPE = DSECT
            PUTREADIDX :   TYPE = DSECT
        }
    
    
    	// filters commented
       /* The following section definition are for SDFM examples */
    
       /*
       Filter1_RegsFile : > RAMGS1,	PAGE = 1, fill=0x1111
       Filter2_RegsFile : > RAMGS2,	PAGE = 1, fill=0x2222
       Filter3_RegsFile : > RAMGS3,	PAGE = 1, fill=0x3333
       Filter4_RegsFile : > RAMGS4,	PAGE = 1, fill=0x4444
       Difference_RegsFile : >RAMGS5, 	PAGE = 1, fill=0x3333
    	*/
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    
    //###########################################################################
    //
    // FILE:   F2837xD_SysCtrl.c
    //
    // TITLE:  F2837xD Device System Control Initialization & Support Functions.
    //
    // DESCRIPTION:
    //
    //         Example initialization of system resources.
    //
    //###########################################################################
    // $TI Release: F2837xD Support Library v200 $
    // $Release Date: Tue Jun 21 13:00:02 CDT 2016 $
    // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "F2837xD_device.h"
    #include "F2837xD_Examples.h"
    
    #define STATUS_FAIL          0
    #define STATUS_SUCCESS       1
    
    //
    // Functions that will be run from RAM need to be assigned to a different
    // section.  This section will then be mapped to a load and run address using
    // the linker cmd file.
    //
    //      *IMPORTANT*
    //
    //  IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs"  FROM FLASH
    //  TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING
    //  AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE.
    //
    #ifndef __cplusplus
    #pragma CODE_SECTION(InitFlash, "ramfuncs");
    #pragma CODE_SECTION(FlashOff, "ramfuncs");
    #endif
    
    //
    // InitSysCtrl - Initialization of system resources.
    //
    void InitSysCtrl(void)
    {
        //
        // Disable the watchdog
        //
        DisableDog();
    
    
    #ifdef _FLASH
        //
        // Copy time critical code and Flash setup code to RAM. This includes the
        // following functions: InitFlash()
        //
        // The  RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
        // symbols are created by the linker. Refer to the device .cmd file.
        //
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    
        //
        // Call Flash Initialization to setup flash waitstates. This function must
        // reside in RAM.
        //
        InitFlash();
    #endif
    
        //
        //      *IMPORTANT*
        //
        // The Device_cal function, which copies the ADC & oscillator calibration
        // values from TI reserved OTP into the appropriate trim registers, occurs
        // automatically in the Boot ROM. If the boot ROM code is bypassed during
        // the debug process, the following function MUST be called for the ADC and
        // oscillators to function according to specification. The clocks to the
        // ADC MUST be enabled before calling this function.
        //
        // See the device data manual and/or the ADC Reference Manual for more
        // information.
        //
    #ifdef CPU1
        EALLOW;
    
        //
        // Enable pull-ups on unbonded IOs as soon as possible to reduce power
        // consumption.
        //
        GPIO_EnableUnbondedIOPullups();
    
        CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
    
        //
        // Check if device is trimmed
        //
        if(*((Uint16 *)0x5D1B6) == 0x0000){
            //
            // Device is not trimmed--apply static calibration values
            //
            AnalogSubsysRegs.ANAREFTRIMA.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMB.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMC.all = 31709;
            AnalogSubsysRegs.ANAREFTRIMD.all = 31709;
        }
    
        CpuSysRegs.PCLKCR13.bit.ADC_A = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_B = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_C = 0;
        CpuSysRegs.PCLKCR13.bit.ADC_D = 0;
        EDIS;
    
        //
        // Initialize the PLL control: SYSPLLMULT and SYSCLKDIVSEL.
        //
        // Defined options to be passed as arguments to this function are defined
        // in F2837xD_Examples.h.
        //
        // Note: The internal oscillator CANNOT be used as the PLL source if the
        // PLLSYSCLK is configured to frequencies above 194 MHz.
        //
        //  PLLSYSCLK = (XTAL_OSC) * (IMULT + FMULT) / (PLLSYSCLKDIV)
        //
    #ifdef _LAUNCHXL_F28379D
        InitSysPll(XTAL_OSC,IMULT_40,FMULT_0,PLLCLK_BY_2);
    #else
        InitSysPll(XTAL_OSC, IMULT_20, FMULT_0, PLLCLK_BY_2);
    #endif // _LAUNCHXL_F28379D
    
    #endif // CPU1
    
        //
        // Turn on all peripherals
        //
        InitPeripheralClocks();
    }
    
    //
    // InitPeripheralClocks - Initializes the clocks for the peripherals.
    //
    // Note: In order to reduce power consumption, turn off the clocks to any
    // peripheral that is not specified for your part-number or is not used in the
    // application
    //
    void InitPeripheralClocks(void)
    {
        EALLOW;
    
        CpuSysRegs.PCLKCR0.bit.CLA1 = 1;
        CpuSysRegs.PCLKCR0.bit.DMA = 1;
        CpuSysRegs.PCLKCR0.bit.CPUTIMER0 = 1;
        CpuSysRegs.PCLKCR0.bit.CPUTIMER1 = 1;
        CpuSysRegs.PCLKCR0.bit.CPUTIMER2 = 1;
    
    #ifdef CPU1
        CpuSysRegs.PCLKCR0.bit.HRPWM = 1;
    #endif
    
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    
    #ifdef CPU1
        CpuSysRegs.PCLKCR1.bit.EMIF1 = 1;
        CpuSysRegs.PCLKCR1.bit.EMIF2 = 1;
    #endif
    
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM6 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM7 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM8 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM9 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM10 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM11 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM12 = 1;
    
        CpuSysRegs.PCLKCR3.bit.ECAP1 = 1;
        CpuSysRegs.PCLKCR3.bit.ECAP2 = 1;
        CpuSysRegs.PCLKCR3.bit.ECAP3 = 1;
        CpuSysRegs.PCLKCR3.bit.ECAP4 = 1;
        CpuSysRegs.PCLKCR3.bit.ECAP5 = 1;
        CpuSysRegs.PCLKCR3.bit.ECAP6 = 1;
    
        CpuSysRegs.PCLKCR4.bit.EQEP1 = 1;
        CpuSysRegs.PCLKCR4.bit.EQEP2 = 1;
        CpuSysRegs.PCLKCR4.bit.EQEP3 = 1;
    
        CpuSysRegs.PCLKCR6.bit.SD1 = 1;
        CpuSysRegs.PCLKCR6.bit.SD2 = 1;
    
        CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
        CpuSysRegs.PCLKCR7.bit.SCI_B = 1;
        CpuSysRegs.PCLKCR7.bit.SCI_C = 1;
        CpuSysRegs.PCLKCR7.bit.SCI_D = 1;
    
        CpuSysRegs.PCLKCR8.bit.SPI_A = 1;
        CpuSysRegs.PCLKCR8.bit.SPI_B = 1;
        CpuSysRegs.PCLKCR8.bit.SPI_C = 1;
    
        CpuSysRegs.PCLKCR9.bit.I2C_A = 1;
        CpuSysRegs.PCLKCR9.bit.I2C_B = 1;
    
        CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
        CpuSysRegs.PCLKCR10.bit.CAN_B = 1;
    
        CpuSysRegs.PCLKCR11.bit.McBSP_A = 1;
        CpuSysRegs.PCLKCR11.bit.McBSP_B = 1;
    
    #ifdef CPU1
        CpuSysRegs.PCLKCR11.bit.USB_A = 1;
    
        CpuSysRegs.PCLKCR12.bit.uPP_A = 1;
    #endif
    
        CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
        CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
    
        CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS2 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS3 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS4 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS5 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS6 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS7 = 1;
        CpuSysRegs.PCLKCR14.bit.CMPSS8 = 1;
    
        CpuSysRegs.PCLKCR16.bit.DAC_A = 1;
        CpuSysRegs.PCLKCR16.bit.DAC_B = 1;
        CpuSysRegs.PCLKCR16.bit.DAC_C = 1;
    
        EDIS;
    }
    
    //
    // DisablePeripheralClocks - Gates-off all peripheral clocks.
    //
    void DisablePeripheralClocks(void)
    {
        EALLOW;
    
        CpuSysRegs.PCLKCR0.all = 0;
        CpuSysRegs.PCLKCR1.all = 0;
        CpuSysRegs.PCLKCR2.all = 0;
        CpuSysRegs.PCLKCR3.all = 0;
        CpuSysRegs.PCLKCR4.all = 0;
        CpuSysRegs.PCLKCR6.all = 0;
        CpuSysRegs.PCLKCR7.all = 0;
        CpuSysRegs.PCLKCR8.all = 0;
        CpuSysRegs.PCLKCR9.all = 0;
        CpuSysRegs.PCLKCR10.all = 0;
        CpuSysRegs.PCLKCR11.all = 0;
        CpuSysRegs.PCLKCR12.all = 0;
        CpuSysRegs.PCLKCR13.all = 0;
        CpuSysRegs.PCLKCR14.all = 0;
        CpuSysRegs.PCLKCR16.all = 0;
    
        EDIS;
    }
    
    //
    // InitFlash - This function initializes the Flash Control registers.
    //
    //      *CAUTION*
    // This function MUST be executed out of RAM. Executing it out of OTP/Flash
    // will yield unpredictable results.
    //
    #ifdef __cplusplus
    #pragma CODE_SECTION("ramfuncs");
    #endif
    void InitFlash(void)
    {
        EALLOW;
    
        //
        // Set VREADST to the proper value for the flash banks to power up
        // properly. This sets the bank power up delay.
        //
        Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    
        //
        // At reset bank and pump are in sleep. A Flash access will power up the
        // bank and pump automatically.
        //
        // After a Flash access, bank and pump go to low power mode (configurable
        // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
        //
        // Power up Flash bank and pump. This also sets the fall back mode of
        // flash and pump as active.
        //
        Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
        Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    
        //
        // Disable Cache and prefetch mechanism before changing wait states
        //
        Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
        Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    
        //
        // Set waitstates according to frequency
        //
        //      *CAUTION*
        // Minimum waitstates required for the flash operating at a given CPU rate
        // must be characterized by TI. Refer to the datasheet for the latest
        // information.
        //
        #if CPU_FRQ_200MHZ
        Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
        #endif
    
        #if CPU_FRQ_150MHZ
        Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
        #endif
    
        #if CPU_FRQ_120MHZ
        Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
        #endif
    
        //
        // Enable Cache and prefetch mechanism to improve performance of code
        // executed from Flash.
        //
        Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
        Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    
        //
        // At reset, ECC is enabled. If it is disabled by application software and
        // if application again wants to enable ECC.
        //
        Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    
        EDIS;
    
        //
        // Force a pipeline flush to ensure that the write to the last register
        // configured occurs before returning.
        //
        __asm(" RPT #7 || NOP");
    }
    
    //
    // FlashOff - This function powers down the flash
    //
    //      *CAUTION*
    // This function MUST be executed out of RAM. Executing it out of OTP/Flash
    // will yield unpredictable results. Also you must seize the flash pump in
    // order to power it down.
    //
    #ifdef __cplusplus
    #pragma CODE_SECTION("ramfuncs");
    #endif
    void FlashOff(void)
    {
        EALLOW;
    
        //
        // Set VREADST to the proper value for the flash banks to power up properly
        //
        Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    
        //
        // Power down bank
        //
        Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0;
    
        //
        // Power down pump
        //
        Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0;
    
        EDIS;
    }
    
    //
    // SeizeFlashPump - Wait until the flash pump is available. Then take control
    //                  of it using the flash pump Semaphore.
    //
    void SeizeFlashPump(void)
    {
        EALLOW;
        #ifdef CPU1
            while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
            {
                FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
            }
        #elif defined(CPU2)
            while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
            {
                FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
            }
        #endif
        EDIS;
    }
    
    //
    // ReleaseFlashPump - Release control of the flash pump using the flash pump
    //                    semaphore.
    //
    void ReleaseFlashPump(void)
    {
        EALLOW;
        FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x0;
        EDIS;
    }
    
    //
    // ServiceDog - This function resets the watchdog timer.
    //
    // Enable this function for using ServiceDog in the application.
    //
    void ServiceDog(void)
    {
        EALLOW;
        WdRegs.WDKEY.bit.WDKEY = 0x0055;
        WdRegs.WDKEY.bit.WDKEY = 0x00AA;
        EDIS;
    }
    
    //
    // DisableDog - This function disables the watchdog timer.
    //
    void DisableDog(void)
    {
        volatile Uint16 temp;
    
        //
        // Grab the clock config first so we don't clobber it
        //
        EALLOW;
        temp = WdRegs.WDCR.all & 0x0007;
        WdRegs.WDCR.all = 0x0068 | temp;
        EDIS;
    }
    
    #ifdef CPU1
    //
    // InitSysPll - This function initializes the PLL registers.
    //
    // Note: The internal oscillator CANNOT be used as the PLL source if the
    // PLLSYSCLK is configured to frequencies above 194 MHz.
    //
    // Note: This function uses the Watchdog as a monitor for the PLL. The user
    // watchdog settings will be modified and restored upon completion.
    //
    void InitSysPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
    {
        Uint16 SCSR, WDCR, WDWCR, intStatus;
        if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)    &&
           (imult        == ClkCfgRegs.SYSPLLMULT.bit.IMULT)           &&
           (fmult        == ClkCfgRegs.SYSPLLMULT.bit.FMULT)           &&
           (divsel       == ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV))
        {
            //
            // Everything is set as required, so just return
            //
            return;
        }
    
        if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)
        {
            switch (clock_source)
            {
                case INT_OSC1:
                    SysIntOsc1Sel();
                    break;
    
                case INT_OSC2:
                    SysIntOsc2Sel();
                    break;
    
                case XTAL_OSC:
                    SysXtalOscSel();
                    break;
            }
        }
    
        EALLOW;
        if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT ||
           fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT)
        {
            Uint16 i;
    
            //
            // This bit is reset only by POR
            //
            if(DevCfgRegs.SYSDBGCTL.bit.BIT_0 == 1)
            {
                //
                // The user can optionally insert handler code here. This will only
                // be executed if a watchdog reset occurred after a failed system
                // PLL initialization. See your device user's guide for more
                // information.
                //
                // If the application has a watchdog reset handler, this bit should
                // be checked to determine if the watchdog reset occurred because
                // of the PLL.
                //
                // No action here will continue with retrying the PLL as normal.
                //
            }
    
            //
            // Bypass PLL and set dividers to /1
            //
            ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
            asm(" RPT #20 || NOP");
            ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;
    
            //
            // Lock the PLL five times. This helps ensure a successful start.
            // Five is the minimum recommended number. The user can increase this
            // number according to allotted system initialization time.
            //
            for(i = 0; i < 5; i++)
            {
                //
                // Turn off PLL
                //
                ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
                asm(" RPT #20 || NOP");
    
                //
                // Write multiplier, which automatically turns on the PLL
                //
                ClkCfgRegs.SYSPLLMULT.all = ((fmult << 8U) | imult);
    
                //
                // Wait for the SYSPLL lock counter
                //
                while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)
                {
                    //
                    // Uncomment to service the watchdog
                    //
                    // ServiceDog();
                }
            }
        }
    
        //
        // Set divider to produce slower output frequency to limit current increase
        //
        if(divsel != PLLCLK_BY_126)
        {
             ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel + 1;
        }else
        {
             ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
        }
    
        //
        //      *CAUTION*
        // It is recommended to use the following watchdog code to monitor the PLL
        // startup sequence. If your application has already cleared the watchdog
        // SCRS[WDOVERRIDE] bit this cannot be done. It is recommended not to clear
        // this bit until after the PLL has been initiated.
        //
    
        //
        // Backup User Watchdog
        //
        SCSR = WdRegs.SCSR.all;
        WDCR = WdRegs.WDCR.all;
        WDWCR = WdRegs.WDWCR.all;
    
        //
        // Disable windowed functionality, reset counter
        //
        EALLOW;
        WdRegs.WDWCR.all = 0x0;
        WdRegs.WDKEY.bit.WDKEY = 0x55;
        WdRegs.WDKEY.bit.WDKEY = 0xAA;
    
        //
        // Disable global interrupts
        //
        intStatus = __disable_interrupts();
    
        //
        // Configure for watchdog reset and to run at max frequency
        //
        WdRegs.SCSR.all = 0x0;
        WdRegs.WDCR.all = 0x28;
    
        //
        // This bit is reset only by power-on-reset (POR) and will not be cleared
        // by a WD reset
        //
        DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 1;
    
        //
        // Enable PLLSYSCLK is fed from system PLL clock
        //
        ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
    
        //
        // Delay to ensure system is clocking from PLL prior to clearing status bit
        //
        asm(" RPT #20 || NOP");
    
        //
        // Clear bit
        //
        DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0;
    
        //
        // Restore user watchdog, first resetting counter
        //
        WdRegs.WDKEY.bit.WDKEY = 0x55;
        WdRegs.WDKEY.bit.WDKEY = 0xAA;
    
        WDCR |= 0x28;                     // Setup WD key--KEY bits always read 0
        WdRegs.WDCR.all = WDCR;
        WdRegs.WDWCR.all = WDWCR;
        WdRegs.SCSR.all = SCSR & 0xFFFE;  // Mask write to bit 0 (W1toClr)
    
        //
        // Restore state of ST1[INTM]. This was set by the __disable_interrupts()
        // intrinsic previously.
        //
        if(!(intStatus & 0x1))
        {
            EINT;
        }
    
        //
        // Restore state of ST1[DBGM]. This was set by the __disable_interrupts()
        // intrinsic previously.
        //
        if(!(intStatus & 0x2))
        {
            asm(" CLRC DBGM");
        }
    
        //
        // 200 PLLSYSCLK delay to allow voltage regulator to stabilize prior
        // to increasing entire system clock frequency.
        //
        asm(" RPT #200 || NOP");
    
        //
        // Set the divider to user value
        //
        ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
        EDIS;
    }
    #endif // CPU1
    
    //
    // InitAuxPll - This function initializes the AUXPLL registers.
    //
    // Note: For this function to properly detect PLL startup,
    // SYSCLK >= 2*AUXPLLCLK after the AUXPLL is selected as the clocking source.
    //
    // This function will use CPU Timer 2 to monitor a successful lock of the
    // AUXPLL.
    //
    void InitAuxPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
    {
        Uint16 i;
        Uint16 counter = 0;
        Uint16 started = 0;
        Uint16 t2_tcr, t2_tpr, t2_tprh, t2_src, t2_prescale;
        Uint32 t2_prd;
    
        if((clock_source == ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL) &&
           (imult        == ClkCfgRegs.AUXPLLMULT.bit.IMULT)           &&
           (fmult        == ClkCfgRegs.AUXPLLMULT.bit.FMULT)           &&
           (divsel       == ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV))
        {
            //
            // Everything is set as required, so just return
            //
            return;
        }
    
        switch (clock_source)
        {
            case INT_OSC2:
                AuxIntOsc2Sel();
                break;
    
            case XTAL_OSC:
                AuxXtalOscSel();
                break;
    
            case AUXCLKIN:
                AuxAuxClkSel();
                break;
        }
    
        //
        // Backup Timer 2 settings
        //
        t2_src = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL;
        t2_prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE;
        t2_tcr = CpuTimer2Regs.TCR.all;
        t2_prd = CpuTimer2Regs.PRD.all;
        t2_tpr = CpuTimer2Regs.TPR.all;
        t2_tprh = CpuTimer2Regs.TPRH.all;
    
        //
        // Configure Timer 2 for AUXPLL as source in known configuration
        //
        EALLOW;
        CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x6;
        CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = 0x0;    // Divide by 1
    
        CpuTimer2Regs.TCR.bit.TSS = 1;      // Stop timer
        CpuTimer2Regs.PRD.all = 10;         // Small PRD value to detect overflow
        CpuTimer2Regs.TPR.all = 0;
        CpuTimer2Regs.TPRH.all = 0;
        CpuTimer2Regs.TCR.bit.TIE = 0;      // Disable timer interrupts
    
        //
        // Set AUX Divide by 8 to ensure that AUXPLLCLK <= SYSCLK/2 while using
        // Timer 2
        //
        ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 0x3;
        EDIS;
    
        while((counter < 5) && (started == 0))
        {
            EALLOW;
            ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0;    // Turn off AUXPLL
            asm(" RPT #20 || NOP");                 // Small delay for power down
    
            //
            // Set integer and fractional multiplier, which automatically turns on
            // the PLL
            //
            ClkCfgRegs.AUXPLLMULT.all = ((fmult << 8U) | imult);
    
            //
            // Enable AUXPLL
            //
            ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1;
            EDIS;
    
            //
            // Wait for the AUXPLL lock counter
            //
            while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1)
            {
                //
                // Uncomment to service the watchdog
                //
                // ServiceDog();
            }
    
            //
            // Enable AUXPLLCLK to be fed from AUX PLL
            //
            EALLOW;
            ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
            asm(" RPT #20 || NOP");
    
            //
            // CPU Timer 2 will now be setup to be clocked from AUXPLLCLK. This is
            // used to test that the PLL has successfully started.
            //
            CpuTimer2Regs.TCR.bit.TRB = 1;      // Reload period value
            CpuTimer2Regs.TCR.bit.TSS = 0;      // Start Timer
    
            //
            // Check to see timer is counting properly
            //
            for(i = 0; i < 1000; i++)
            {
                //
                // Check overflow flag
                //
                if(CpuTimer2Regs.TCR.bit.TIF)
                {
                    //
                    // Clear overflow flag
                    //
                    CpuTimer2Regs.TCR.bit.TIF = 1;
    
                    //
                    // Set flag to indicate PLL started and break out of for-loop
                    //
                    started = 1;
                    break;
                }
            }
    
            //
            // Stop timer
            //
            CpuTimer2Regs.TCR.bit.TSS = 1;
            counter++;
            EDIS;
        }
    
        if(started == 0)
        {
            //
            // AUX PLL may not have started. Reset multiplier to 0 (bypass PLL).
            //
            EALLOW;
            ClkCfgRegs.AUXPLLMULT.all = 0;
            EDIS;
    
            //
            // The user should put some handler code here based on how this
            // condition should be handled in their application.
            //
            asm(" ESTOP0");
        }
    
        //
        // Set divider to desired value
        //
        EALLOW;
        ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = divsel;
    
        //
        // Restore Timer 2 configuration
        //
        CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = t2_src;
        CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = t2_prescale;
        CpuTimer2Regs.TCR.all = t2_tcr;
        CpuTimer2Regs.PRD.all = t2_prd;
        CpuTimer2Regs.TPR.all = t2_tpr;
        CpuTimer2Regs.TPRH.all = t2_tprh;
    
        //
        // Reload period value
        //
        CpuTimer2Regs.TCR.bit.TRB = 1;
        EDIS;
    }
    
    //
    // CsmUnlock - This function unlocks the CSM. User must replace 0xFFFF's with
    //             current password for the DSP. Returns 1 if unlock is successful.
    //
    Uint16 CsmUnlock(void)
    {
        volatile Uint16 temp;
    
        //
        // Load the key registers with the current password. The 0xFFFF's are dummy
        // passwords.  User should replace them with the correct password for the
        // DSP.
        //
        EALLOW;
        DcsmZ1Regs.Z1_CSMKEY0 = 0xFFFFFFFF;
        DcsmZ1Regs.Z1_CSMKEY1 = 0xFFFFFFFF;
        DcsmZ1Regs.Z1_CSMKEY2 = 0xFFFFFFFF;
        DcsmZ1Regs.Z1_CSMKEY3 = 0xFFFFFFFF;
    
        DcsmZ2Regs.Z2_CSMKEY0 = 0xFFFFFFFF;
        DcsmZ2Regs.Z2_CSMKEY1 = 0xFFFFFFFF;
        DcsmZ2Regs.Z2_CSMKEY2 = 0xFFFFFFFF;
        DcsmZ2Regs.Z2_CSMKEY3 = 0xFFFFFFFF;
        EDIS;
    
        return(0);
    }
    
    //
    // SysIntOsc1Sel - This function switches to Internal Oscillator 1.
    //
    void SysIntOsc1Sel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2;     // Clk Src = INTOSC1
        EDIS;
    }
    
    //
    // SysIntOsc2Sel - This function switches to Internal oscillator 2.
    //
    void SysIntOsc2Sel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0;         // Turn on INTOSC2
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0;     // Clk Src = INTOSC2
        EDIS;
    }
    
    //
    // SysXtalOscSel - This function switches to External CRYSTAL oscillator.
    //
    void SysXtalOscSel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0;            // Turn on XTALOSC
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1;     // Clk Src = XTAL
        EDIS;
    }
    
    //
    // AuxIntOsc2Sel - This function switches to Internal oscillator 2.
    //
    void AuxIntOsc2Sel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0;         // Turn on INTOSC2
        ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0;  // Clk Src = INTOSC2
        EDIS;
    }
    
    //
    // AuxXtalOscSel - This function switches to External CRYSTAL oscillator.
    //
    void AuxXtalOscSel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0;            // Turn on XTALOSC
        ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1;  // Clk Src = XTAL
        EDIS;
    }
    
    //
    // AuxAUXCLKOscSel - This function switches to AUXCLKIN (from a GPIO).
    //
    void AuxAuxClkSel(void)
    {
        EALLOW;
        ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 2; // Clk Src = XTAL
        EDIS;
    }
    
    //
    // IDLE - Enter IDLE mode (single CPU).
    //
    void IDLE(void)
    {
        EALLOW;
        CpuSysRegs.LPMCR.bit.LPM = LPM_IDLE;
        EDIS;
        asm(" IDLE");
    }
    
    //
    // STANDBY - Enter STANDBY mode (single CPU).
    //
    void STANDBY(void)
    {
        EALLOW;
        CpuSysRegs.LPMCR.bit.LPM = LPM_STANDBY;
        EDIS;
        asm(" IDLE");
    }
    
    //
    // HALT - Enter HALT mode (dual CPU). Puts CPU2 in IDLE mode first.
    //
    void HALT(void)
    {
    #if defined(CPU2)
        IDLE();
    #elif defined(CPU1)
        EALLOW;
        CpuSysRegs.LPMCR.bit.LPM = LPM_HALT;
        EDIS;
    
        while(DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT != 0x1);
    
        EALLOW;
        ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
        ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
        EDIS;
        asm(" IDLE");
    #endif
    }
    
    //
    // HIB - Enter HIB mode (dual CPU). Puts CPU2 in STANDBY first. Alternately,
    //       CPU2 may be in reset.
    void HIB(void)
    {
    #if defined(CPU2)
        STANDBY();
    #elif defined(CPU1)
        EALLOW;
        CpuSysRegs.LPMCR.bit.LPM = LPM_HIB;
        EDIS;
    
        while((DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT == 0x0) &&
              (DevCfgRegs.RSTSTAT.bit.CPU2RES == 1));
    
        DisablePeripheralClocks();
        EALLOW;
        ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
        ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
        EDIS;
        asm(" IDLE");
    #endif
    }
    

  • Nicola,

    Which compiler version are you using?  Based on the compiler version, you may have to use .TI.ramfunc section instead of ramfuncs (you can see this in the linker cmd file as well).

    Why did you comment out LOAD_SIZE, RUN_SIZE and RUN_END in linker cmd file?

    I would suggest you to take a look the flash based linker cmd examples in C2000Ware.

    Thanks and regards,
    Vamsi

  • Hi Vamsi,

    thanks for your response. I was able to sort this out.

    the LOAD and the other comments I think I have seen them across another thread commented and thought it could be the issue. Uncommenting them did not change things.

    I revised the examples in C2000Ware. The memcpy() was copying garbage and I did not have the .cmd building that I shared with you, which is actually correct. Also another issue for my code to work was the absence of the memcpy() for the CLA as well. I needed to have the CLA running too and I could see only the CPU1 performing tasks.

    Now things seem to be working. 

    Thanks,

    Nicola

  • Nicola,

    Glad it is working now. I am closing this post.

    Thanks and regards,
    Vamsi