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.

TMDSCNCD28M36: Problem with FlashAPI load F28M36 (C28 cpu)

Part Number: TMDSCNCD28M36

Hello,

I am working on a bootloader for the F28M36 device. I am working with the TMDSCNCD28M36 reference design (ControlCard and Docking Station). I am using CCSv8 for firmware development.

The ARM part of the bootloader is fine. I am able to perform communication and save the binary into the Flash, using FAPI.

I am facing some challenges with the C28 cpu. I could implement the IPC communication between both CPUs, using as a reference the example code from ControlSuite. I could also execute successfully the example code for flashAPI for C28 CPU.

When I integrate code into my firmware, the problem arises.

Below there is my complete source code (for now):

/**
 * @file main.c
 * @brief Main file of bootloader firmware for C28 core.
 *
 * @author flavio.alves
 * @date 30/11/2018
 */

#if !defined(_CONCERTO)
   #define _CONCERTO
#endif

#if !defined(_LITTLE_ENDIAN)
    #define _LITTLE_ENDIAN
#endif

#if !defined(_C28X)
    #define _C28X
#endif

#include "F28M36x_Device.h"
#include "F28M36x_GlobalPrototypes.h"
#include <string.h>
#include "flash_programming_c28.h"
#include "F28M36x_Ipc_drivers.h"
#include "F28M36x_Flash.h"                // Flash Error Registers
#include "FlashAPI/Types.h"
#include "FlashAPI/F021.h"

#define C28_CTOM_PASSMSG  0x0003FBF4            // Used by C28 to pass address
                                                // of local variables to perform
                                                // actions on

typedef enum {
    SectorN,
    SectorM,
    SectorL,
    SectorK,
    SectorJ,
    SectorI,
    SectorH,
    SectorG,
    SectorF,
    SectorE,
    SectorD,
    SectorC,
    SectorB,
    SectorA
} FlashSector_e;

typedef struct {
    FlashSector_e sector;
    Uint32 addr_start;
    Uint32 len;
} FlashSector_t;

//RAM Function Linker Section
#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        #define ramFuncSection ".TI.ramfunc"
    #else
        #define ramFuncSection "ramfuncs"
    #endif
#endif

__interrupt void MtoCIPC1IntHandler(void);
__interrupt void MtoCIPC2IntHandler(void);
void JumpApp(void);
void TransferStart(unsigned long ulParam);
void TransferStop(void);
void TransferSendData(void);
void FlashInit(void);
void Error (void);

//*****************************************************************************
// At least 1 volatile global tIpcController instance is required when using
// IPC API Drivers.
//*****************************************************************************
volatile tIpcController g_sIpcController1;
volatile tIpcController g_sIpcController2;

//*****************************************************************************
// Global variable used in this example to track errors
//*****************************************************************************
volatile Uint16 ErrorFlag;
volatile Uint32 FnCallStatus;

//*****************************************************************************
// Global variables used in this example to read/write data passed between
// M3 and C28
//*****************************************************************************
Uint16 usMBuffer[256];

static Uint8 fileTransferStarted = 0;

volatile Fapi_LibraryInfoType oLibInfo;
volatile Fapi_FlashStatusType oFlashStatus;
Fapi_FlashBankSectorsType     oFlashBankSectors;
Fapi_FlashStatusWordType      oFlashStatusWord;

static FlashSector_t sector_list[] = {
        { SectorN, Bzero_SectorN_start, Bzero_16KSector_u32length },
        { SectorM, Bzero_SectorM_start, Bzero_16KSector_u32length },
        { SectorL, Bzero_SectorL_start, Bzero_16KSector_u32length },
        { SectorK, Bzero_SectorK_start, Bzero_16KSector_u32length },
        { SectorJ, Bzero_SectorJ_start, Bzero_64KSector_u32length },
        { SectorI, Bzero_SectorI_start, Bzero_64KSector_u32length },
        { SectorH, Bzero_SectorH_start, Bzero_64KSector_u32length },
        { SectorG, Bzero_SectorG_start, Bzero_64KSector_u32length },
        { SectorF, Bzero_SectorF_start, Bzero_64KSector_u32length },
        { SectorE, Bzero_SectorE_start, Bzero_64KSector_u32length },
        { SectorD, Bzero_SectorD_start, Bzero_16KSector_u32length },
        { SectorC, Bzero_SectorC_start, Bzero_16KSector_u32length },
        { SectorB, Bzero_SectorB_start, Bzero_16KSector_u32length },
        { SectorA, Bzero_SectorA_start, Bzero_16KSector_u32length },
};

/**
 * @brief Main function
 */
void main(void)
{
    // Define Local  Variables
    Uint32 *pulMsgRam;
    Uint16 counter;

    // Step 1. Initialize System Control:
    // Enable Peripheral Clocks
    // This example function is found in the F28M36x_SysCtrl.c file.
    InitSysCtrl();

    ///  Unlock CSM
//
//  If the API functions are going to run in unsecured RAM
//  then the CSM must be unlocked in order for the flash
//  API functions to access the flash.
//  If the flash API functions are executed from secure memory
//  then this step is not required.
    CsmUnlock();

    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F28M36x_PieCtrl.c file.
    DINT;

    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F28M36x_DefaultIsr.c.
    // This function is found in F28M36x_PieVect.c.
    InitPieVectTable();

    // Copy time critical code and Flash setup code to RAM
    // This includes InitFlash(), Flash API functions and any functions that are
    // assigned to ramfuncs section.
    // The  RamfuncsLoadStart, RamfuncsLoadEnd, 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();

    //  Gain pump semaphore
    FlashGainPump();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.MTOCIPC_INT1 = &MtoCIPC1IntHandler;
    PieVectTable.MTOCIPC_INT2 = &MtoCIPC2IntHandler;
    EDIS;    // This is needed to disable write to EALLOW protected registers

    // Step 4. Initialize the Device Peripherals:
    IPCCInitialize (&g_sIpcController1, IPC_INT1, IPC_INT1);
    IPCCInitialize (&g_sIpcController2, IPC_INT2, IPC_INT2);

    // Step 5. User specific code, enable interrupts:

    // Enable CPU INT1 which is connected to MTOCIPC INT1-4:
    IER |= M_INT11;

    // Enable MTOCIPC INTn in the PIE: Group 11 interrupts
    PieCtrlRegs.PIEIER11.bit.INTx1 = 1; // MTOCIPC INT1
    PieCtrlRegs.PIEIER11.bit.INTx2 = 1; // MTOCIPC INT2

    // Enable global Interrupts and higher priority real-time debug events:
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    // Initialize all variables.
    ErrorFlag = 0;
    FnCallStatus = 0;
    for (counter = 0; counter < 256; counter++)
    {
        usMBuffer[counter] = 0;
    }

    // Point array to address in CTOM MSGRAM for passing variable locations
    pulMsgRam = (void *)C28_CTOM_PASSMSG;

    pulMsgRam[0] = (unsigned long)&usMBuffer[0];
    pulMsgRam[1] = (unsigned long)&TransferStart;
    pulMsgRam[2] = (unsigned long)&TransferSendData;
    pulMsgRam[3] = (unsigned long)&TransferStop;
    pulMsgRam[4] = (unsigned long)&JumpApp;
    pulMsgRam[5] = (unsigned long)&FnCallStatus;

    // Flag to M3 that the variables are ready in MSG RAM with CTOM IPC Flag 17
    CtoMIpcRegs.CTOMIPCSET.bit.IPC17 = 1;

    /*
     * Rotina que chamas as funções de inicialização da FlashAPI
     */
    FlashInit();

    for(;;)
    {
        // Flag an Error if an Invalid Command has been received.
        //
        if (ErrorFlag == 1)
        {
            Error();
        }
    }

#if 0
    Uint32 *pulMsgRam;
    Uint16 counter;

    /**
     * Initialize the Control System:
     * Enable peripheral clocks
     * This example function is found in the F28M36x_SysCtrl.c file.
     */
    InitSysCtrl();

    /**
     * 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();

    /**
     * Disable CPU interrupts
     */
    DINT;

    /**
     * Initialize the PIE control registers to their default state.
     * The default state is all PIE interrupts disabled and flags are cleared.
     * This function is found in the F28M36x_PieCtrl.c file.
     */
    InitPieCtrl();

    /**
     * Disable CPU interrupts and clear all CPU interrupt flags:
     */
    IER = 0x0000;
    IFR = 0x0000;

    /**
     * Initialize the PIE vector table with pointers to the shell Interrupt
     * Service Routines (ISR).
     * This will populate the entire table, even if the interrupt
     * is not used in this example.  This is useful for debug purposes.
     * The shell ISR routines are found in F28M36x_DefaultIsr.c.
     * This function is found in F28M36x_PieVect.c.
     */
    InitPieVectTable();


    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
    InitFlash();

    //  Gain pump semaphore
    FlashGainPump();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.MTOCIPC_INT1 = &MtoCIPC1IntHandler;
    PieVectTable.MTOCIPC_INT2 = &MtoCIPC2IntHandler;
    EDIS;    // This is needed to disable write to EALLOW protected registers

    // Step 4. Initialize the Device Peripherals:
    IPCCInitialize (&g_sIpcController1, IPC_INT1, IPC_INT1);
    IPCCInitialize (&g_sIpcController2, IPC_INT2, IPC_INT2);

    // Step 5. User specific code, enable interrupts:

    // Enable CPU INT1 which is connected to MTOCIPC INT1-4:
    IER |= M_INT11;

    // Enable MTOCIPC INTn in the PIE: Group 11 interrupts
    PieCtrlRegs.PIEIER11.bit.INTx1 = 1; // MTOCIPC INT1
    PieCtrlRegs.PIEIER11.bit.INTx2 = 1; // MTOCIPC INT2

    // Enable global Interrupts and higher priority real-time debug events:
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    // Initialize all variables.
    ErrorFlag = 0;
    FnCallStatus = 0;
    usWWord16 = 0;
    ulWWord32 = 0;
    for (counter = 0; counter < 256; counter++)
    {
        usMBuffer[counter] = 0;
    }

    // Point array to address in CTOM MSGRAM for passing variable locations
    pulMsgRam = (void *)C28_CTOM_PASSMSG;

    // Write addresses of variables where words should be written to pulMsgRam
    // array.
    // 0 = Address of 16-bit word to write to.
    // 1 = Address of 32-bit word to write to.
    // 2 = Address of buffer to block write to.
    // 3 = Address of FunctionCall() function to call.
    // 4 = Address of FunctionCallParam() function to call.
    // 5 = Address of 32-bit FnCallStatus variable to check function call
    // executed
    pulMsgRam[0] = (unsigned long)&usWWord16;
    pulMsgRam[1] = (unsigned long)&ulWWord32;
    pulMsgRam[2] = (unsigned long)&usMBuffer[0];
    pulMsgRam[3] = (unsigned long)&TransferStart;
    pulMsgRam[4] = (unsigned long)&TransferStop;
    pulMsgRam[5] = (unsigned long)&FnCallStatus;

    // Flag to M3 that the variables are ready in MSG RAM with CTOM IPC Flag 17
    CtoMIpcRegs.CTOMIPCSET.bit.IPC17 = 1;

    /*
     * Inicialização da flash, chamando funções da FlashAPI
     */
    FlashInit();

    for(;;)
    {
        // Flag an Error if an Invalid Command has been received.
        //
        if (ErrorFlag == 1)
        {
            Error();
        }
    }
#endif
}
#pragma CODE_SECTION(FlashInit,ramFuncSection);
void FlashInit(void) {
    Fapi_StatusType oReturnCheck;

    EALLOW;

    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 150);
    if(oReturnCheck != Fapi_Status_Success) {
        // Check Flash API documentation for possible errors
        Error();
    }

    // Fapi_getLibraryInfo function can be used to get the information specific
    // to the compiled version of the API library
    oLibInfo = Fapi_getLibraryInfo();

    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success) {
        // Check Flash API documentation for possible errors
        Error();
    }

    // Fapi_getBankSectors function returns the bank starting address, number of
    // sectors, sector sizes, and bank technology type
    // Above information is returned in a structure oFlashBankSectors of type
    // Fapi_FlashBankSectorsType
    oReturnCheck = Fapi_getBankSectors(Fapi_FlashBank0,&oFlashBankSectors);
    if(oReturnCheck != Fapi_Status_Success) {
        //Check Flash API documentation for possible errors
        Error();
    }

}

void JumpApp(void) {
    FnCallStatus = 0;
}

void TransferSendData(void) {
    FnCallStatus = 0;
}

void TransferStart(unsigned long ulParam) {
    FlashSector_e s = SectorC;
    Uint32 *address;
    Uint32 len;
    volatile Fapi_FlashStatusType oFlashStatus;
    Fapi_StatusType oReturnCheck;

    /* Variavel de retorno inicializada com 0 (OK) */
    FnCallStatus = 0;

    /*
     * Sanity check - inicializado
     */
    if (fileTransferStarted) {
        /* Erro */
        FnCallStatus = 1;
        return;
    }

    /* Flavio Alves: por precaução, vou considerar que o firmware
     * fique inicialmente nos setores C e D, por enquanto, até
     * entender melhor como funciona a setorização da memória do C28
     */

    for(s=SectorC;s<=SectorD;s++) {
        address = (Uint32 *)sector_list[s].addr_start;
        len = sector_list[s].len;

        // Issue the command to erase the sector
        oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                                                         (Uint32 *)address);
        // Wait until FSM is done with erase sector operation
        while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
        // Verify that Sector is erased.  The Erase step itself does a verify
        // as it goes.  This verify is a 2nd verification that can be done.
        oReturnCheck = Fapi_doBlankCheck((Uint32 *)address, len, &oFlashStatusWord);
        if(oReturnCheck != Fapi_Status_Success) {
            FnCallStatus = 1;
            return;
        }
    }

    /*
     * Seta a flag de inicio de modo de transmissao, caso tudo tenha
     * corrido bem.
     */
    if (FnCallStatus == 0) {
        fileTransferStarted = 1;
    }

    return;
}

void TransferStop(void) {
    FnCallStatus = 0;
#if 0
    if (!fileTransferStarted) {
        FnCallStatus = 1;
    } else {
        FnCallStatus = 0;
    }

    return;
#endif
}

//*****************************************************************************
// Function to Indicate an Error has Occurred (Invalid Command Received).
//*****************************************************************************
void
Error(void)
{
    // An error has occurred (invalid command received). Loop forever.
    for (;;)
    {
    }
}

//*****************************************************************************
// MtoC INT1 Interrupt Handler - Handles Data Word Reads/Writes
//*****************************************************************************
__interrupt void
MtoCIPC1IntHandler (void)
{
    tIpcMessage sMessage;

    // Continue processing messages as long as MtoC GetBuffer1 is full
    while (IpcGet (&g_sIpcController1, &sMessage,
                   DISABLE_BLOCKING)!= STATUS_FAIL)
    {
        switch (sMessage.ulcommand)
        {
        case IPC_SET_BITS:
            IPCMtoCSetBits(&sMessage);
            break;
        case IPC_CLEAR_BITS:
            IPCMtoCClearBits(&sMessage);
            break;
        case IPC_DATA_WRITE:
            IPCMtoCDataWrite(&sMessage);
            break;
        case IPC_DATA_READ:
            IPCMtoCDataRead(&g_sIpcController1, &sMessage, ENABLE_BLOCKING);
            break;
        case IPC_FUNC_CALL:
            IPCMtoCFunctionCall(&sMessage);
            break;
        default:
            ErrorFlag = 1;
            break;
        }
    }

    // Acknowledge IPC INT1 Flag and PIE to receive more interrupts from group
    // 11
    CtoMIpcRegs.MTOCIPCACK.bit.IPC1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP11;
}

//*****************************************************************************
// MtoC INT2 Interrupt Handler - Handles Data Block Reads/Writes
//*****************************************************************************
__interrupt void
MtoCIPC2IntHandler (void)
{
    tIpcMessage sMessage;

    // Continue processing messages as long as MtoC GetBuffer2 is full
    while (IpcGet (&g_sIpcController2, &sMessage,
                   DISABLE_BLOCKING)!= STATUS_FAIL)
    {
        switch (sMessage.ulcommand)
        {
        case IPC_BLOCK_WRITE:
            IPCMtoCBlockWrite(&sMessage);
            break;
        case IPC_BLOCK_READ:
            IPCMtoCBlockRead(&sMessage);
            break;
        default:
            ErrorFlag = 1;
            break;
        }
    }

    // Acknowledge IPC INT2 Flag and PIE to receive more interrupts from group
    // 11
    CtoMIpcRegs.MTOCIPCACK.bit.IPC2 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP11;
}

//###########################################################################
//
// FILE:    Fapi_UserDefinedFunctions.c
//
//          Contains all user defined functions that the Fapi functions use.
//
// F021 Flash API v1.52
//
//###########################################################################
// $TI Release: F28M36x Support Library v210 $
// $Release Date: Wed Feb 15 16:20:49 CST 2017 $
// $Copyright: Copyright (C) 2012-2017 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

//RAM Function Linker Section
#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        #define ramFuncSection ".TI.ramfunc"
    #else
        #define ramFuncSection "ramfuncs"
    #endif
#endif

#pragma CODE_SECTION(Fapi_serviceWatchdogTimer,ramFuncSection);
Fapi_StatusType Fapi_serviceWatchdogTimer(void)
{
   /* User to add their own watchdog servicing code here */

   return(Fapi_Status_Success);
}

#pragma CODE_SECTION(Fapi_setupEepromSectorEnable,ramFuncSection);
Fapi_StatusType Fapi_setupEepromSectorEnable(void)
{
   Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;   /* Value must be 0xFFFF to enable erase and programming of the EEPROM bank, 0 to disable */
   FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register, 0x0U); /* Enables sectors 32-63 for bank and sector erase */
   FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector1.u32Register, 0x0U); /* Enables sectors 0-31 for bank and sector erase */
   FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector2.u32Register, 0x0U); /* Enables sectors 32-63 for bank and sector erase */

   return(Fapi_Status_Success);
}

#pragma CODE_SECTION(Fapi_setupBankSectorEnable,ramFuncSection);
Fapi_StatusType Fapi_setupBankSectorEnable(void)
{
   Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;                  /* Enable sectors 0-15 for erase and programming */
   FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register, 0x0U);

   return(Fapi_Status_Success);
}

/* End of File */

I can compile and execute this code. It fails on the execution of the InitFlash() function.

Looking at the this thread, I could realize that the InitFlash implementation is not running correctly, probably because the FlashAPI lib may be not been correctly copied to RAM.

I compared the CMD file (linker script) from both projects: mine and from the example. As I am not an expert, I could not find some clue about what I am doing wrong. Below there is my linker script.

/*
//###########################################################################
// FILE:    F28M36H63C2_generic_wshared_C28_FLASH.cmd
// TITLE:   Linker Command File For all F28M36x Devices w/shared RAM
//###########################################################################
// $TI Release: F28M36x Support Library v202 $
// $Release Date: Tue Apr  8 12:36:34 CDT 2014 $
//###########################################################################
*/

/* ======================================================
// For Code Composer Studio V2.2 and later
// ---------------------------------------
// In addition to this memory linker command file,
// add the header linker command file directly to the project.
// The header linker command file is required to link the
// peripheral structures to the proper locations within
// the memory map.
// The header linker files are found in <base>\F28M36x_headers\cmd
// For BIOS applications add:      F28M36x_Headers_BIOS.cmd
// For nonBIOS applications add:   F28M36x_Headers_nonBIOS.cmd
========================================================= */

/* Define the memory block start/length for the F28M36x
   PAGE 0 will be used to organize program sections
   PAGE 1 will be used to organize data sections

   Notes:
         Memory blocks on F28M36x 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.

         Contiguous SARAM memory blocks or flash sectors can be
         be combined if required to create a larger memory block.
*/

MEMORY
{
PAGE 0:    /* Program Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
   RAML0       : origin = 0x008000, length = 0x001000     /* on-chip RAM block L0 */
   RAML1       : origin = 0x009000, length = 0x001000     /* on-chip RAM block L1 */
   //RAML0L1   : origin = 0x008000, length = 0x002000     /* on-chip RAM block L0-L1*/
   
   FLASHN      : origin = 0x100000, length = 0x002000     /* on-chip FLASH */
   FLASHM      : origin = 0x102000, length = 0x002000     /* on-chip FLASH */
   FLASHL      : origin = 0x104000, length = 0x002000     /* on-chip FLASH */
   FLASHK      : origin = 0x106000, length = 0x002000     /* on-chip FLASH */
   FLASHJ      : origin = 0x108000, length = 0x008000     /* on-chip FLASH */
   FLASHI      : origin = 0x110000, length = 0x008000     /* on-chip FLASH */
   FLASHH      : origin = 0x118000, length = 0x008000     /* on-chip FLASH */
   FLASHG      : origin = 0x120000, length = 0x008000     /* on-chip FLASH */
   FLASHF      : origin = 0x128000, length = 0x008000     /* on-chip FLASH */
   FLASHE      : origin = 0x130000, length = 0x008000      /* on-chip FLASH */
   FLASHD      : origin = 0x138000, length = 0x002000      /* on-chip FLASH */
   FLASHC      : origin = 0x13A000, length = 0x002000      /* on-chip FLASH */
   FLASHB      : origin = 0x13C000, length = 0x002000     /* on-chip FLASH */
   //FLASHCB     : origin = 0x13A000, length = 0x004000      /* on-chip FLASH */
   FLASHA      : origin = 0x13E000, length = 0x001F80      /* on-chip FLASH */

   
   CSM_RSVD    : origin = 0x13FF80, length = 0x000070     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
   BEGIN       : origin = 0x13FFF0, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
   FLASH_EXE_ONLY_P0  : origin = 0x13FFF2, length = 0x000002  /* Part of FLASHA.  Flash execute only locations in FLASHA */ 
   ECSL_PWL_P0 : origin = 0x13FFF4, length = 0x000004     /* Part of FLASHA.  ECSL password locations in FLASHA */
   CSM_PWL_P0  : origin = 0x13FFF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */

   FPUTABLES   : origin = 0x3FD21A, length = 0x0006A0     /* FPU Tables in Boot ROM */
   IQTABLES    : origin = 0x3FD8BA, length = 0x000B50     /* IQ Math Tables in Boot ROM */
   IQTABLES2   : origin = 0x3FE40A, length = 0x00008C     /* IQ Math Tables in Boot ROM */
   IQTABLES3   : origin = 0x3FE496, length = 0x0000AA     /* IQ Math Tables in Boot ROM */

   BOOTROM     : origin = 0x3FED6A, length = 0x001200     /* Boot ROM */
   PIEMISHNDLR : origin = 0x3FFFBE, length = 0x000002      /* part of boot ROM  */
   RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
   VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */

PAGE 1 :   /* Data Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
           /* Registers remain on PAGE1                                                  */
   BOOT_RSVD   : origin = 0x000000, length = 0x000050     /* Part of M0, BOOT rom will use this for stack */
   RAMM0       : origin = 0x000080, length = 0x000380     /* on-chip RAM block  */
   RAMM1       : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
   RAML2       : origin = 0x00A000, length = 0x001000     /* on-chip RAM block L2 */
   RAML3       : origin = 0x00B000, length = 0x001000     /* on-chip RAM block L3 */
   RAMS0       : origin = 0x00C000, length = 0x001000     /* on-chip Shared RAM block S0 */
   RAMS1_0     : origin = 0x00D000, length = 0x000800     /* on-chip Shared RAM block S1 - bank 0 */
   RAMS1_1     : origin = 0x00D800, length = 0x000800     /* on-chip Shared RAM block S1 - bank 1 */
   RAMS2       : origin = 0x00E000, length = 0x001000     /* on-chip Shared RAM block S2 */
   RAMS3       : origin = 0x00F000, length = 0x001000     /* on-chip Shared RAM block S3 */
   //RAMS4       : origin = 0x010000, length = 0x001000     /* on-chip Shared RAM block S4 */
   //RAMS5       : origin = 0x011000, length = 0x001000     /* on-chip Shared RAM block S5 */
   //RAMS6       : origin = 0x012000, length = 0x001000     /* on-chip Shared RAM block S6 */
   //RAMS7       : origin = 0x013000, length = 0x001000     /* on-chip Shared RAM block S7 */
   RAMS45      : origin = 0x010000, length = 0x002000     /* on-chip Shared RAM block S4-S5 */
   RAMS67      : origin = 0x012000, length = 0x002000     /* on-chip Shared RAM block S6-S7 */
   

   CTOMRAM     : origin = 0x03F800, length = 0x000380     /* C28 to M3 Message RAM */
   MTOCRAM     : origin = 0x03FC00, length = 0x000380     /* M3 to C28 Message RAM */
   

}

/* 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              : > FLASHA,		PAGE = 0
   .pinit              : > FLASHA,		PAGE = 0
   .text               : > FLASHA,		PAGE = 0
   codestart           : > BEGIN       	PAGE = 0

#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        GROUP
        {
            .TI.ramfunc
            { -l F021_API_C28x_FPU32.lib}

        } LOAD = FLASHD,
          RUN = RAML0,
          LOAD_START(_RamfuncsLoadStart),
          LOAD_SIZE(_RamfuncsLoadSize),
          RUN_START(_RamfuncsRunStart),
          PAGE = 0
    #else
        GROUP
        {
            ramfuncs
            { -l F021_API_C28x_FPU32.lib}

        } LOAD = FLASHD,
          RUN = RAML0,
          LOAD_START(_RamfuncsLoadStart),
          LOAD_SIZE(_RamfuncsLoadSize),
          RUN_START(_RamfuncsRunStart),
          PAGE = 0
    #endif
#endif

   flashexeonly        : > FLASH_EXE_ONLY_P0 PAGE = 0
   ecslpasswds         : > ECSL_PWL_P0 PAGE = 0
   csmpasswds          : > CSM_PWL_P0  PAGE = 0
   csm_rsvd            : > CSM_RSVD    PAGE = 0
   
   /* The following section definitions are required when using the IPC API Drivers */ 
   GROUP : > CTOMRAM, PAGE = 1 
   {
       PUTBUFFER 
       PUTWRITEIDX 
       GETREADIDX 
   }

   GROUP : > MTOCRAM, PAGE = 1
   {
       GETBUFFER :    TYPE = DSECT
       GETWRITEIDX :  TYPE = DSECT
       PUTREADIDX :   TYPE = DSECT
   }

   SHARERAMS0          : > RAMS0,        PAGE = 1
   SHARERAMS1_0        : > RAMS1_0,        PAGE = 1
   SHARERAMS1_1        : > RAMS1_1,        PAGE = 1
   SHARERAMS2          : > RAMS2,        PAGE = 1
   SHARERAMS3          : > RAMS3,        PAGE = 1
   //SHARERAMS4          : > RAMS4,        PAGE = 1
   //SHARERAMS5          : > RAMS5,        PAGE = 1
   //SHARERAMS6          : > RAMS6,        PAGE = 1
   //SHARERAMS7          : > RAMS7,        PAGE = 1
   SHARERAMS45         : > RAMS45,       PAGE = 1
   SHARERAMS67         : > RAMS67,       PAGE = 1
   
   MTOC_MSG_RAM		   : > MTOCRAM,		PAGE = 1
   CTOM_MSG_RAM		   : > CTOMRAM,		PAGE = 1

   /* Allocate uninitalized data sections: */
   .stack              : > RAMM0       PAGE = 1
   .ebss               : > RAML2       PAGE = 1
   .esysmem            : > RAML2       PAGE = 1

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

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

   /* Allocate FPU math areas: */
   FPUmathTables       : > FPUTABLES,  PAGE = 0, TYPE = NOLOAD
   
   DMARAML2           : > RAML2,       PAGE = 1
   DMARAML3           : > RAML3,       PAGE = 1

  /* 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)

    }
    */

   /* .reset is a standard section used by the compiler.  It contains the */
   /* the address of the start of _c_int00 for C Code.   /*
   /* When using the boot ROM this section and the CPU vector */
   /* table is not needed.  Thus the default type is set here to  */
   /* DSECT  */
   .reset              : > RESET,      PAGE = 0, TYPE = DSECT
   vectors             : > VECTORS     PAGE = 0, TYPE = DSECT

}

/*
*/

Can anybody help me to find out what is going wrong?

Best regards,

Flavio
  • Alves,

    In your code, why are you calling InitSysCtrl, memcpy, InitFlash functions in your code. You don't need to call these function twice.

    Regards,
    Manoj
  • Hello Manoj,

    They are not called twice. The second call is blocked by an "#if0" and it is not compiled.

    I am sorry about the confusion. I should have removed this code during the post.

    Anyway, do you have any idea about why flashAPI is not working?

    Best regards,

    Flavio
  • Flavio,

    InitFlash function should be run from RAM not flash. Did you try single stepping through the code and check whether InitFlash is getting executed from flash.

    Also, what is the error message you are getting?

    Regards,
    Manoj
  • Hello Manoj,

    Yes, I did.

    In fact, I thought the memcpy call just before the InitFlash call was used to make the transfer. And the Ramfuncs variables contain the flashAPI code to be transfered to RAM.

    As far as I understood from the CMD file, the flahsAPI was stored on FLASHD and would be transfered to RAML0.

    I don't know if I did something wrong on the linkerscript or on the code in order to verify why it is not working.

    What can I do go get more information for debugging?

    Best regads,

    Flavio

  • Flavio,

    You need to step-into InitFlash function and run instructions of this function one by one to check why this function isn't working correctly.

    -Manoj
  • Hello Manoj,

    The picture below shows the screen before the call of InitFlash()

    And the picture below is the starting point of the function.

    Please take a look at the disassembly screen. Everything is zero and I could not understand why it happens.

    Could you see any problem in my CMD file?

    Best regards,

    Flavio

  • Flavio,

    I didn't find any glaring issues with your cmd file.

    Did you check whether memcpy function copied the Flash API functions correctly? Did you check whether device is locked?

    Regards,
    Manoj
  • Hello Manoj,

    Sorry for the delay on the response.

    I could finally find the problem. I will explain it here.

    I forgot to mention to you another important element of the problem. During the compilation, I had the following warning:

    warning #10247-D: creating output section "ramfuncs" without a SECTIONS specification

    I took some time finding out what was going on.

    In my linkerscript, I have the following instruction:

    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            GROUP
            {
                .TI.ramfunc
                { -l F021_API_C28x_FPU32.lib(.text)}
    
            } LOAD = FLASHD,
              RUN = RAML0,
              LOAD_START(_RamfuncsLoadStart),
              LOAD_SIZE(_RamfuncsLoadSize),
              RUN_START(_RamfuncsRunStart),
              PAGE = 0
        #else
            GROUP
            {
                ramfuncs
                { -l F021_API_C28x_FPU32.lib(.text)}
    
            } LOAD = FLASHD,
              RUN = RAML0,
              LOAD_START(_RamfuncsLoadStart),
              LOAD_SIZE(_RamfuncsLoadSize),
              RUN_START(_RamfuncsRunStart),
              PAGE = 0
        #endif
    #endif

    According to CodeComposer highlight, the compiled section is the first (.TI.ramfunc) and thus no ramfuncs should be created.

    This is protected in my main.c file with the following code:

    //RAM Function Linker Section
    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            #define ramFuncSection ".TI.ramfunc"
        #else
            #define ramFuncSection "ramfuncs"
        #endif
    #endif

    In main.c file, when some function must be executed in RAM, the following line is added to the code:

    #pragma CODE_SECTION(Fapi_setupBankSectorEnable,ramFuncSection);

    With the provided information, everything is fine.

    But,

    I am not using an off-the-shelf ControlSuite installation. I am used an adapted configuration to be used by several projects.

    Searching for other files in the project, I found the following instructions (in my case, file F28M36x_SysCtrl.c):

    #pragma CODE_SECTION(InitFlash, "ramfuncs");
    #pragma CODE_SECTION(SetupFlash, "ramfuncs");
    #pragma CODE_SECTION(FlashGainPump,"ramfuncs");
    #pragma CODE_SECTION(FlashLeavePump,"ramfuncs");
    

    Those instructions were causing the warning (and the problem). There was no ramfuncs section on the linker script. The compiler created one automatically, with empty information. The results was that itraped instructions showed on some post above.

    I replaced "ramfuncs" on the above code to ramFuncSection and added the same #ifdef condition presented on the main.c in the F28M36x_SysCtrl.c file.

    The warning disappeared. And the code started to work on the same way as the example.

    I hope this explanation might be helpful for others.

    Best regards,

    Flavio