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.

LAUNCHXL-F28027F: Interrupts don't work when boot from flash.

Part Number: LAUNCHXL-F28027F
Other Parts Discussed in Thread: TMS320F28027, TMS320F28027F,

Hello everyone,

with Lori Heustess I managed to save program in flash either for non BIOS and BIOS projects (https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/984757/launchxl-f28027f-can-t-boot-program-from-flash/36431100)

But now I have another odd problem. I wrote simple program in which there is an echo on UART. It works when I am debugging it by CCS but when I run it from flash only timer task works - I can see it by toggled LEDs. It seems that SCI interrupts are not fired. I put  line that toggles LEDs in interrupt handlers and there was not any action. I have no idea what can cause that behaviour - as I wrote, timer handler works and LEDs are toggled in it. Here are files: main.c, app.cfg and TMS320F28027.cmd:

5153.TMS320F28027.txt
/*
 * Copyright (c) 2015-2020, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 *  ======== TMS320F28027.cmd ========
 *  Define the memory block start/length for the F28027
 */

/*
 *  PAGE 0 will be used to organize program sections
 *  PAGE 1 will be used to organize data sections
 *
 *  Notes:
 *        Memory blocks on F2802x are uniform (ie same
 *        physical memory) in both PAGE 0 and PAGE 1.
 *        That is the same memory region should not be
 *        defined for both PAGE 0 and PAGE 1.
 *        Doing so will result in corruption of program
 *        and/or data.
 *
 *        L0 memory blocks are mirrored - that is
 *        they can be accessed in high memory or low memory.
 *        For simplicity only one instance is used in this
 *        linker file.
 */

MEMORY
{
PAGE 0:    /* Program Memory */

    OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */
    FLASH       : origin = 0x3F0000, length = 0x007F80     /* on-chip FLASH */
    CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Program with all 0x0000 when CSM is in use. */
    BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Used for "boot to Flash" bootloader mode. */
    CSM_PWL     : origin = 0x3F7FF8, length = 0x000008     /* CSM password locations in FLASH */

    IQTABLES    : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
    IQTABLES2   : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
    IQTABLES3   : origin = 0x3FEBDC, length = 0x0000AA	   /* IQ Math Tables in Boot ROM */

    ROM         : origin = 0x3FF27C, length = 0x000D44     /* Boot ROM */
    RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
    VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */

PAGE 1 :   /* Data Memory */

    M01SARAM    : origin = 0x000000, length = 0x000800     /* on-chip RAM block M0, M1 */
    PIEVECT     : origin = 0xD00,    length = 0x100
    L0SARAM     : origin = 0x008000, length = 0x001000     /* on-chip RAM block L0 */
}

/*
 *  Allocate sections to memory blocks.
 *  Note:
 *      codestart   user defined section in DSP28_CodeStartBranch.asm
 *                  used to redirect code execution when booting to flash
 *
 *      ramfuncs    user defined section to store functions that will be
 *                  copied from Flash into RAM
 */

SECTIONS
{
    /* Allocate program areas: */
    .cinit              : > FLASH       PAGE = 0
    .pinit              : > FLASH       PAGE = 0
    .text               : > FLASH       PAGE = 0
    codestart           : > BEGIN       PAGE = 0
    ramfuncs            : LOAD = FLASH      PAGE = 0,
                          RUN  = L0SARAM    PAGE = 1,
                          LOAD_START(_RamfuncsLoadStart),
                          LOAD_SIZE(_RamfuncsLoadSize),
                          LOAD_END(_RamfuncsLoadEnd),
                          RUN_START(_RamfuncsRunStart)

    csmpasswds          : > CSM_PWL     PAGE = 0
    csm_rsvd            : > CSM_RSVD    PAGE = 0

    /* Allocate uninitalized data sections: */
    .stack              : > M01SARAM | L0SARAM      PAGE = 1
    .ebss               : >> M01SARAM | L0SARAM      PAGE = 1
    .data               : > M01SARAM | L0SARAM      PAGE = 1
    .esysmem            : > L0SARAM | M01SARAM      PAGE = 1
    .cio                : > L0SARAM | M01SARAM      PAGE = 1

    /* Initalized sections go in Flash */
    /* For SDFlash to program these, they must be allocated to page 0 */
    .econst             : > FLASH       PAGE = 0
    .switch             : > FLASH       PAGE = 0
    .args               : > FLASH       PAGE = 0

#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc         : {} LOAD = FLASH    PAGE = 0,
                             RUN  = L0SARAM  PAGE = 1,
                             table(BINIT)
#endif
#endif

    /* Allocate IQ math areas: */
    IQmath              : > FLASH       PAGE = 0            /* Math Code */
    IQmathTables        : > IQTABLES    PAGE = 0, TYPE = NOLOAD

    /*
     *  Uncomment the section below if calling the IQNexp() or IQexp()
     *  functions from the IQMath.lib library in order to utilize the
     *  relevant IQ Math table in Boot ROM (This saves space and Boot ROM
     *  is 1 wait-state). If this section is not uncommented, IQmathTables2
     *  will be loaded into other memory (SARAM, Flash, etc.) and will take
     *  up space, but 0 wait-state is possible.
     */
    /*
    IQmathTables2       : > IQTABLES2   PAGE = 0, TYPE = NOLOAD
    {
        IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)
    }
    */

    /*
     *  Uncomment the section below if calling the IQNasin() or IQasin()
     *  functions from the IQMath.lib library in order to utilize the
     *  relevant IQ Math table in Boot ROM (This saves space and Boot ROM
     *  is 1 wait-state). If this section is not uncommented, IQmathTables2
     *  will be loaded into other memory (SARAM, Flash, etc.) and will take
     *  up space, but 0 wait-state is possible.
     */
    /*
    IQmathTables3       : > IQTABLES3   PAGE = 0, TYPE = NOLOAD
    {
        IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)
    }
    */
}

7144.main.c
/*
 *  ======== main.c ========
 */

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/hal/Hwi.h>

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

#include "adc.h"
#include "clk.h"
#include "flash.h"
#include "gpio.h"
#include "pie.h"
#include "pll.h"
#include "sci.h"
//#include "sci_io.h"
#include "timer.h"
#include "wdog.h"
#include "F2802x_SysCtrl.h"            // System Control/Power Modes


//ADC_Handle myAdc;
CLK_Handle myClk;
//FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
SCI_Handle mySci;
//TIMER_Handle myTimer;


/* Counter incremented by timer interrupt */
volatile UInt tickCount = 0;
volatile UInt txCount = 0;
uint16_t rxData = 0;
Void sciConfigTask(UArg a0, UArg a1);
Void gpioConfigTask(UArg arg, UArg a1);
Void sciTxIntFxn(UArg in);
uint16_t buffer[256] = {0};
/*
 *  ======== main ========
 */
Bits16 *OTP_KEY;
Bits16 *OTP_BMODE;
Int main()
{ 
#ifdef _FLASH
 //memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif
    OTP_KEY = (Bits16*)0x3d7bfe;
    OTP_BMODE = (Bits16*)0x3d7bff;
    //CPU_Handle myCpu;
    PLL_Handle myPll;
    //WDOG_Handle myWDog;

    //
    // Initialize all the handles needed for this application
    //
    //myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
    //myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
    //myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
    mySci = SCI_init((void *)SCIA_BASE_ADDR, sizeof(SCI_Obj));
    //myTimer = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
    //myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    //
    // Select the internal oscillator 1 as the clock source
    //
    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

    //
    // Setup the PLL for x12 /2 which will yield 60Mhz = 12Mhz * 10 / 2
    //
    PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);

    /*Task_Handle sciConfigTaskHandle;
    Error_Block ebSci;
    Error_init(&ebSci);
    sciConfigTaskHandle = Task_create(sciConfigTask, NULL, &ebSci);
    if (sciConfigTaskHandle == NULL) {
    //    System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }*/

    /*Task_Handle gpioInitHandle;
    Error_Block ebGpio;
    Error_init(&ebGpio);
    gpioInitHandle = Task_create(gpioConfigTask, NULL, &ebGpio);
    if (gpioInitHandle == NULL) {
    //    System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }*/


    /*Hwi_Handle sciTxIntHandle;
    Error_Block ebSciTx;
    Error_init(&ebSciTx);
    sciTxIntHandle = Hwi_create(97, sciTxIntFxn, NULL, &ebSciTx);
    if (sciTxIntHandle == NULL) {
        //    System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
*/
    //System_printf("BIOS start!");

    BIOS_start();    /* does not return */
    return(0);
}

Void gpioConfigTask(UArg arg, UArg a1){
    //
    // Configure GPIO 0-3 as outputs
    // LEDs
    //
    GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_1, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_2, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_3, GPIO_0_Mode_GeneralPurpose);

    GPIO_setDirection(myGpio, GPIO_Number_0, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_1, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Output);

    GPIO_setLow(myGpio, GPIO_Number_0);
    GPIO_setHigh(myGpio, GPIO_Number_1);
    GPIO_setLow(myGpio, GPIO_Number_2);
    GPIO_setHigh(myGpio, GPIO_Number_3);
}

/*
 *  ======== gpioToggle ========
 *  Timer ISR function that toggles GPIOs

 */
Void gpioToggle(UArg arg)
{
    tickCount += 1;    /* increment the counter */

    //
    // Toggle GPIOs
    //
    GPIO_toggle(myGpio, GPIO_Number_0);
    GPIO_toggle(myGpio, GPIO_Number_1);
    GPIO_toggle(myGpio, GPIO_Number_2);
    GPIO_toggle(myGpio, GPIO_Number_3);
}

Void sciConfigTask(UArg a0, UArg a1){
    //
    // Initialize SCIA GPIO
    //
    GPIO_setPullUp(myGpio, GPIO_Number_28, GPIO_PullUp_Enable);
    GPIO_setPullUp(myGpio, GPIO_Number_29, GPIO_PullUp_Disable);
    GPIO_setQualification(myGpio, GPIO_Number_28, GPIO_Qual_ASync);
    GPIO_setMode(myGpio, GPIO_Number_28, GPIO_28_Mode_SCIRXDA);
    GPIO_setMode(myGpio, GPIO_Number_29, GPIO_29_Mode_SCITXDA);

    CLK_enableSciaClock(myClk);

    //
    // 1 stop bit,  No loopback, No parity, 8 char bits, async mode
    // idle-line protocol
    //
    SCI_disableParity(mySci);
    SCI_setNumStopBits(mySci, SCI_NumStopBits_One);
    SCI_setCharLength(mySci, SCI_CharLength_8_Bits);

    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SCI_enableTx(mySci);
    SCI_enableRx(mySci);
    SCI_enableTxInt(mySci);
    SCI_enableRxInt(mySci);
    //SCI_enableTxWake(mySci);
    //SCI_enableLoopBack(mySci);

    //SCI BRR = LSPCLK/(SCI BAUDx8) - 1
    SCI_setBaudRate(mySci, SCI_BaudRate_9_6_kBaud);
    //SCI_setBaudRate(mySci, SCI_BaudRate_9_6_kBaud);
#if (CPU_FRQ_50MHZ)
    SCI_setBaudRate(mySci, SCI_BaudRate_9_6_kBaud);
#elif (CPU_FRQ_40MHZ)
    SCI_setBaudRate(mySci, (SCI_BaudRate_e)129);
#endif

    SCI_enable(mySci);

    return;
}

Void sciRxIntFxn(UArg in){
    //GPIO_toggle(myGpio, GPIO_Number_0);
    //todo: write incoming data into circular buffer
    rxData = SCI_getData(mySci);
    //echo:
    SCI_putDataNonBlocking(mySci, rxData);
    return;
}

Void sciTxIntFxn(UArg in){
    //GPIO_toggle(myGpio, GPIO_Number_1);
    //todo:
    txCount++;
    return;
}

Void idleFxn(){
    return;
}

app_txt.txt
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var Main = xdc.useModule('xdc.runtime.Main');
var Memory = xdc.useModule('xdc.runtime.Memory')
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');

var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');

var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
var Timer = xdc.useModule('ti.sysbios.hal.Timer');
var ti_sysbios_hal_Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var Boot = xdc.useModule('ti.catalog.c2800.init.Boot');

/*
 * Uncomment this line to globally disable Asserts.
 * All modules inherit the default from the 'Defaults' module.  You
 * can override these defaults on a per-module basis using Module.common$. 
 * Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
 */

/*
 * Uncomment this line to keep module names from being loaded on the target.
 * The module name strings are placed in the .const section. Setting this
 * parameter to false will save space in the .const section.  Error and
 * Assert messages will contain an "unknown module" prefix instead
 * of the actual module name.
Defaults.common$.namedModule = false;
 */

/*
 * Minimize exit handler array in System.  The System module includes
 * an array of functions that are registered with System_atexit() to be
 * called by System_exit().
 */
System.maxAtexitHandlers = 4;       

/* 
 * Uncomment this line to disable the Error print function.  
 * We lose error information when this is disabled since the errors are
 * not printed.  Disabling the raiseHook will save some code space if
 * your app is not using System_printf() since the Error_print() function
 * calls System_printf().
Error.raiseHook = null;
 */

/* 
 * Uncomment this line to keep Error, Assert, and Log strings from being
 * loaded on the target.  These strings are placed in the .const section.
 * Setting this parameter to false will save space in the .const section.
 * Error, Assert and Log message will print raw ids and args instead of
 * a formatted message.
Text.isLoaded = false;
 */

/*
 * Uncomment this line to disable the output of characters by SysMin
 * when the program exits.  SysMin writes characters to a circular buffer.
 * This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
 */

/*
 * The BIOS module will create the default heap for the system.
 * Specify the size of this default heap.
 */
BIOS.heapSize = 0x800;

/*
 * Build a custom SYS/BIOS library from sources.
 */
BIOS.libType = BIOS.LibType_Custom;

/* System stack size (used by ISRs and Swis) */
Program.stack = 0x100;

/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x200;

/* 
 * Create and install logger for the whole system
 */
/*var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 32;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;*/

System.SupportProxy = SysMin;
var timer0Params = new Timer.Params();
timer0Params.instance.name = "null";
timer0Params.period = 500000;
var timer0 = Timer.create(null, "&gpioToggle", timer0Params);
Task.enableIdleTask = true;
var hwi0Params = new Hwi.Params();
hwi0Params.instance.name = "sciRxInt";
hwi0Params.enableAck = true;
Program.global.sciRxInt = Hwi.create(96, "&sciRxIntFxn", hwi0Params);
var hwi1Params = new Hwi.Params();
hwi1Params.instance.name = "sciTxInt";
Program.global.sciTxInt = Hwi.create(97, "&sciTxIntFxn", hwi1Params);
var task0Params = new Task.Params();
task0Params.instance.name = "gpioInit";
Program.global.gpioInit = Task.create("&gpioConfigTask", task0Params);
var task1Params = new Task.Params();
task1Params.instance.name = "sciConfig";
Program.global.sciConfig = Task.create("&sciConfigTask", task1Params);
Boot.bootFromFlash = true;
Boot.configurePll = false;
Boot.pllOSCCLK = 12;
BIOS.cpuFreq.lo = 60000000;
Boot.pllcrDIV = 10;

I appreciate any help.
BR,
Dawid.

  • Hi Dawid,

    One possible reason for this could be that wait-states are involved for flash execution, I should suggest that you map all the ISRs to RAM (for execution).

    Best Regards,

    Marlyn

  • I would never come up with this by myself :) Any example how to handle this? I don't know how todo the mapping. Do you mean some changes in cmd file?

  • I found the article: https://software-dl.ti.com/C2000/docs/optimization_guide/phase3/memory.html#flash-vs-ram-comparison

    I placed the attribute:

    and in main:

    Behavour is still odd, no interrupt for sci. Am I missing something or you meant something else than showed in the article?

  • It works when I am debugging it by CCS but when I run it from flash only timer task works

    My first thought would be the interrupt code is not being copied from its load location in Flash to its run location in RAM.  You should see the same issue when debugging the flash-based project in CCS, though.   Are you using the same build configuration with and without CCS attached?

    Another symptom of the above is the PC would likely go into the weeds and the device watchdog would reset it periodically.  You can check the device reset pin and see if this is happening.  

  • I am using build configuration from default template of sys/bios project for TMS320F28027F target. I didn't changed anything but this line of *.cmd file:

        .ebss               : >> M01SARAM | L0SARAM      PAGE = 1

    (I added second '>' sign; it's a solution from my another forum thread), I added '_FLASH' to predefined symbols and I added some paths to use driverlib in project.

    'You should see the same issue when debugging the flash-based project in CCS, though.' - as I wrote in another thread even LaunchPad demo project doesn't boot from flash. In SYS/BIOS project I checked 'boot from flash' checkbox in XGCONF.

  • Dawid,

    Have you tried reproducing the issue with Code Composer Studio connected?  I mentioned some steps to do this in the other thread.  It is difficult to know what is going wrong without CCS attached.  My guess is the ISRs are not being copied from flash to RAM. 

    I will ask someone with more BIOS experience if they have any ideas. 

    Regards

    Lori

  • Hi Lori,

    I didn't try. Frankly, I didn't know that it is possible to attach debugger when device boots from flash. I was trying to add __attribute__(ramfunc) but device act unstable.

    Could you paste here a link to the thread you mentioned? I can't find it but I'll check if I can reproduce and issue with CCS connected.

  • Yes, a device can boot from flash with the debugger connected.  

    In addition to my previous instructions, I should mention that there is a "emulation boot mode" used when CCS is connected.  Refer to the device Technical Reference Manual (TRM).  In code composer studio, under the scripts menu, select emulation boot mode --> flash or RAM as appropriate.

    In CCS use a reset and not a restart.  Reset takes an actual reset and runs through the boot ROM. Whereas a restart tries to be smart about placing the PC at the entry point of an application.  This is normally not an issue, but when trying to debug a boot to flash issue it doesn't exactly replicate a power boot. 

    If you added the attribute, and want the tools to do the copy automatically during initialization then make sure you have added the table(BINIT) in your linker file.  Refer to the assembly tools ref guide www.ti.com/lit/spru513 "placing functions in RAM".  If BINIT is not specified then the application must perform the copy to RAM.  This puts the developer in charge of when the copy occurs. 

    Regards

    Lori

  • Lori,

    take a look on my first post in this thread and check line 122. of TMS320F28027.cmd - there is table(BINIT) added.

  • Before I start trying to connect CCS in flash boot mode - I did a test connection and here is a result:

    [Start: Texas Instruments XDS100v2 USB Debug Probe_0]
    
    Execute the command:
    
    %ccs_base%/common/uscif/dbgjtag -f %boarddatafile% -rv -o -F inform,logfile=yes -S pathlength -S integrity
    
    [Result]
    
    
    -----[Print the board config pathname(s)]------------------------------------
    
    C:\Users\dawid\AppData\Local\TEXASI~1\CCS\
        ccs1020\0\0\BrdDat\testBoard.dat
    
    -----[Print the reset-command software log-file]-----------------------------
    
    This utility has selected a 100- or 510-class product.
    This utility will load the adapter 'jioserdesusb.dll'.
    The library build date was 'Jan  1 2021'.
    The library build time was '11:25:57'.
    The library package version is '9.3.0.00032'.
    The library component version is '35.35.0.0'.
    The controller does not use a programmable FPGA.
    The controller has a version number of '4' (0x00000004).
    The controller has an insertion length of '0' (0x00000000).
    This utility will attempt to reset the controller.
    This utility has successfully reset the controller.
    
    -----[Print the reset-command hardware log-file]-----------------------------
    
    The scan-path will be reset by toggling the JTAG TRST signal.
    The controller is the FTDI FT2232 with USB interface.
    The link from controller to target is direct (without cable).
    The software is configured for FTDI FT2232 features.
    The controller cannot monitor the value on the EMU[0] pin.
    The controller cannot monitor the value on the EMU[1] pin.
    The controller cannot control the timing on output pins.
    The controller cannot control the timing on input pins.
    The scan-path link-delay has been set to exactly '0' (0x0000).
    
    -----[The log-file for the JTAG TCLK output generated from the PLL]----------
    
    There is no hardware for programming the JTAG TCLK frequency.
    
    -----[Measure the source and frequency of the final JTAG TCLKR input]--------
    
    There is no hardware for measuring the JTAG TCLK frequency.
    
    -----[Perform the standard path-length test on the JTAG IR and DR]-----------
    
    This path-length test uses blocks of 64 32-bit words.
    
    The test for the JTAG IR instruction path-length failed.
    The JTAG IR instruction scan-path is stuck-at-ones.
    
    The test for the JTAG DR bypass path-length failed.
    The JTAG DR bypass scan-path is stuck-at-ones.
    
    -----[Perform the Integrity scan-test on the JTAG IR]------------------------
    
    This test will use blocks of 64 32-bit words.
    This test will be applied just once.
    
    Do a test using 0xFFFFFFFF.
    Scan tests: 1, skipped: 0, failed: 0
    Do a test using 0x00000000.
    Test 2 Word 0: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 1: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 2: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 3: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 4: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 5: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 6: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 7: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    The details of the first 8 errors have been provided.
    The utility will now report only the count of failed tests.
    Scan tests: 2, skipped: 0, failed: 1
    Do a test using 0xFE03E0E2.
    Scan tests: 3, skipped: 0, failed: 2
    Do a test using 0x01FC1F1D.
    Scan tests: 4, skipped: 0, failed: 3
    Do a test using 0x5533CCAA.
    Scan tests: 5, skipped: 0, failed: 4
    Do a test using 0xAACC3355.
    Scan tests: 6, skipped: 0, failed: 5
    Some of the values were corrupted - 83.3 percent.
    
    The JTAG IR Integrity scan-test has failed.
    
    -----[Perform the Integrity scan-test on the JTAG DR]------------------------
    
    This test will use blocks of 64 32-bit words.
    This test will be applied just once.
    
    Do a test using 0xFFFFFFFF.
    Scan tests: 1, skipped: 0, failed: 0
    Do a test using 0x00000000.
    Test 2 Word 0: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 1: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 2: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 3: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 4: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 5: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 6: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    Test 2 Word 7: scanned out 0x00000000 and scanned in 0xFFFFFFFF.
    The details of the first 8 errors have been provided.
    The utility will now report only the count of failed tests.
    Scan tests: 2, skipped: 0, failed: 1
    Do a test using 0xFE03E0E2.
    Scan tests: 3, skipped: 0, failed: 2
    Do a test using 0x01FC1F1D.
    Scan tests: 4, skipped: 0, failed: 3
    Do a test using 0x5533CCAA.
    Scan tests: 5, skipped: 0, failed: 4
    Do a test using 0xAACC3355.
    Scan tests: 6, skipped: 0, failed: 5
    Some of the values were corrupted - 83.3 percent.
    
    The JTAG DR Integrity scan-test has failed.
    
    [End: Texas Instruments XDS100v2 USB Debug Probe_0]
    

    Is that result correct with switches set to flash boot mode?

  • Is that result correct with switches set to flash boot mode?

    Dawid,

    When CCS is connected the emulation boot mode is used.  To connect first use WAIT mode, followed by the emulation boot mode.  There is an example procedure in the TRM that I think will help on page 173:

    2.2.9.2 Example 2: You want to connect your emulator, but do not want application code to start executing before the emulator connects.

    Best Regards

    Lori

  • Lori,

    I'am afraid I am doing something wrong but I'm trying. Here's the details:

    Procedure:

    My code:

    All BOOT switches on launchpad are ON to load the program. Loaded program and memory values:

    And now if I switch off the power by disconnecting USB and connect it again the program starts as always: LEDs blinking and interrupts don't work.

    If I don't do power reset but just click CPU Reset (ctrl+shift+R) all stops and I can do nothing more:

    I changed EMU_BMODE value to FLASH_BOOT but it changed nothing in behaviour. Where I am making a mistake?

  • Dawid, 

    I'll add some clarification / additions to the steps. The goal is to get CCS connected with the device operating similar to boot to flash stand-alone.

    1. program the application into the flash of the device with CCS connected
    2. disconnect CCS and power off the device.  This will clear any RAM content that CCS may have populated.
    3. Configure GPIO37 and GPIO34 pins for mode 2, WAIT.    I think you may have skipped this step?
    4. Power the device - initiate a power-on-reset
      1. The boot ROM will detect TRST = 0 and will use the two pins to determine wait boot.
      2. The boot ROM populates EMU_KEY with 0x55AA and EMU_BMODE with WAIT_BOOT.
      3. The boot ROM waits in the wait routine.
    5. Connect the debugger; TRST will go high.  Key here is to just connect.  Don't re-flash the program. 
    6. Modify the EMU_BMODE via the debugger to boot to FLASH or other desired boot mode.  This can be done via the CCS script I mentioned previously.  Scripts -> EMU boot mode select -> flash
    7. Load the symbols only for your project: load -> symbols.  This will allow source code debug for you to try and find the problem
    8. Perform a debugger reset and run.
      1. The boot loader will use the EMU_BMODE and boot to the desired loader or location
  • Lori,

    Ad. 3. -> on the screenshot I showed configuration of GPIO37 and GPIO34 - that's how I understand configuring GPIO37 and GPIO34 for mode 2 ,WAIT. Unless you mean that I need to hardwire these two pins to GND and VCC,

  • The boot ROM reads the state of the pins.  This occurs right after reset and before your application runs.  So yes, the pins should be tied to get into wait mode.  There are boot jumpers or switches on the launchpad if that is the hardware you are using. 

  • Dawid - I think you may find it helpful to read through the workshop archive for this device.  It discusses the boot process as well as other helpful topics.   Unfortunately the tools used (CCS version and hardware) are dated.  The concepts are still valid.

    training.ti.com/c2000-f2802x-microcontroller-workshop

  • In my other thread I faced similar problem at the end of configuration (https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/988696/launchxl-f280049c-sci-interrupts-on-sys-bios/3654832?focus=true)

    I case of LaunchXL-F28027F I took similar steps and here are the results:

    • I made a fix in cmd linker file: 
    • I connected with the debugger to restarted device and I saw RXERR flag so I added some simple error handling in RX ISR routine:
    • I checked ISRs addresses:
      •  we can see that functions are copied to L0SARAM

    In the case from thread  I mentioned it resolved the problem but here SCI is still dead.

    And I noticed another interesting fact - TMS320F280027F should have 16k RAM and 32k FLASH (https://www.ti.com/product/TMS320F28027F#product-details##params):

    Look at my memory allocation diagram:

    I can allocate ca. 2x less than available. Linker file I use is default from new project created. It's a lot and I think it shouldn't be such a difference. I took a look in reference manual and there is what I found:

    When we add L0 SARAM, M0 SARAM and M1 SARAM we'll get 10 k RAM. 

    Another fact - in my cmd file there wasn't declared L0 SARAM from 0x3F 8000. I added it and I tried to place there ramfunc. Program started but when I typed character in terminal program crashed. Where I can find missing part of RAM and FLASH?

  • I can allocate ca. 2x less than available.

    The confusion is that the CCS Memory Allocation view displays the memory usage in terms of 16-bit words, but labels the values as "x out of y bytes used". Where "bytes" is normally taken to be a count of 8-bit units. See CCS/TMS320F280049: CCS memory allocation view unit used for C2000. I.e. believe the Memory Allocation is showing all of the device memory.

  • Chester is correct.  The C28x smallest addressable unit is a 16-bit word so our tools work with this unit.  For some marketing material the bytes are listed to help customers compare memory sizes with other devices.

  • Another fact - in my cmd file there wasn't declared L0 SARAM from 0x3F 8000. I added it and I tried to place there ramfunc.

    If your linker has L0 at 0x8000 then this is the same physical memory block.  Use one or the other in the linker command file, but not both.  If you tell the tools both exist then you will likely write over something allocated to the other block.  

  • Ok, I see. That's clear for me.

    What about SCI issues? I performed all the steps you mentioned and some others from another thread and still something is going wrong. Memory browser looks ok.

  • I added it and I tried to place there ramfunc. Program started but when I typed character in terminal program crashed.

    Dawid,

    • Is this still the case after removing the second mapping for L0 memory? 
    • Is the program that crashed the terminal or the code running on C28x? 
      • Assuming it is the c28x, if you step through the code, can you narrow down where it crashes?  
      • In addition to the ISRs make sure the flash configuration routine is copied to RAM _before_ it is executed.  It has to run from RAM as it changes the flash waitstates.
    • If the program makes it past all the configuration, If you put a breakpoint in the ISR, does the C28x go there and halt?  Can you step through the ISR and see if there are any clues?  Note - you may want to try a hardware breakpoint for this.  A software breakpoint may be overwritten when the code is copied from Flash to RAM. https://software-dl.ti.com/ccs/esd/documents/ccs_breakpoint_watchpoint_c2000.html

    I know you are working with BIOS.  I've asked a colleague if she can look through the post and suggest anything related to BIOS.  

    My understanding is everything works correctly if you run the program strictly from RAM?  (vs load to flash copy to RAM). 

  • Dawid,

    I spoke to my colleague who is more familiar with BIOS and she mentioned recently working with you to resolve similar issues on the F28004x (yay - glad to hear that is working!!).  She said it sounds like you probably have the Hwis setup correctly.  Some more debug is needed to understand where things are failing. 

    Another suggestion is toggling GPIOs in different places in the code to help narrow down where things go wrong.   

    Maybe compare the setup for the SCI on your working F28004x and the F2802x.  You can inspect the registers in view-> registers.  

    -Lori