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.

TMS320F280049C: FLASH EEPROM EMULATION CONFIGURATION

Part Number: TMS320F280049C
Other Parts Discussed in Thread: C2000WARE

Hello,

I'm currently attempting to utilize an unused sector of the flash bank in my C2000 device for EEPROM emulation. While researching this, I came across a document (SPRAB69A) that outlines a similar implementation for older gen2 devices.

My intention was to adapt this framework using the latest flash API. However, I've encountered a persistent issue when running this code in an application. I keep receiving the error message "can't find the source file at this address."

Furthermore, when I attempt to include the "Fapi_setActiveFlashBank" function in the code, I encounter a different error: "<a href="file:/C:/ti/ccs1220/ccs/tools/compiler/dmed/HTML/10099.html">#10099-D</a> program will not fit into available memory, or the section contains a call site that requires a trampoline that can't be generated for this section. Run placement with alignment/blocking fails for section "GROUP_1" size 0x933 page 0. Available memory ranges:"

For your reference, I have attached my code.

Thank you for your assistance.

Linker code:

MEMORY
{
PAGE 0 :

   RAMM0           	: origin = 0x0000F5, length = 0x00030B

   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

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 20012000
GROUP {      /* GROUP memory ranges for crc/checksum of entire flash */
   #endif
#endif
  /* BEGIN is used for the "boot to Flash" bootloader mode   */

   BEGIN           	: origin = 0x080000, length = 0x000002

   /* Flash sectors */
   /* BANK 0 */
   FLASH_BANK0_SEC0  : origin = 0x080002, length = 0x000FFE	/* on-chip Flash */
   FLASH_BANK0_SEC1  : origin = 0x081000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC2  : origin = 0x082000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC3  : origin = 0x083000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC4  : origin = 0x084000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC5  : origin = 0x085000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC6  : origin = 0x086000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC7  : origin = 0x087000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC8  : origin = 0x088000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC9  : origin = 0x089000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000	/* on-chip Flash */

   /* BANK 1 */
   FLASH_BANK1_SEC0  : origin = 0x090000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC1  : origin = 0x091000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC2  : origin = 0x092000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC3  : origin = 0x093000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC4  : origin = 0x094000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC5  : origin = 0x095000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC6  : origin = 0x096000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC7  : origin = 0x097000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC8  : origin = 0x098000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC9  : origin = 0x099000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0	/* on-chip Flash */
   FLASH_BANK1_SEC15_DO_NOT_USE     : origin = 0x09FFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 20012000
}  crc(_ccs_flash_checksum, algorithm=C28_CHECKSUM_16)
  #endif
#endif

PAGE 1 :

   BOOT_RSVD       : origin = 0x000002, length = 0x0000F3     /* Part of M0, BOOT rom will use this for stack */
   RAMM1           : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */

   RAMLS5      : origin = 0x00A800, length = 0x000800
   RAMLS6      : origin = 0x00B000, length = 0x000800
   RAMLS7      : origin = 0x00B800, length = 0x000800

   RAMGS0      : origin = 0x00C000, length = 0x002000
   RAMGS1      : origin = 0x00E000, length = 0x002000
   RAMGS2      : origin = 0x010000, length = 0x002000
   RAMGS3      : origin = 0x012000, length = 0x002000
}


SECTIONS
{
   codestart        : > BEGIN,     PAGE = 0, ALIGN(4)
   .text            : >>FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3,   PAGE = 0, ALIGN(4)
   .cinit           : > FLASH_BANK0_SEC1,     PAGE = 0, ALIGN(4)
   .pinit           : > FLASH_BANK0_SEC1,     PAGE = 0, ALIGN(4)
   .switch          : > FLASH_BANK0_SEC1,     PAGE = 0, ALIGN(4)
   .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   .stack           : > RAMM1,     PAGE = 1
   .ebss            : > RAMLS5,    PAGE = 1
   .esysmem         : > RAMLS5,    PAGE = 1
   .econst          : > FLASH_BANK0_SEC4,    PAGE = 0, ALIGN(4)

   ramgs0           : > RAMGS0,    PAGE = 1
   ramgs1           : > RAMGS1,    PAGE = 1

   GROUP
   {
	.TI.ramfunc
	{ -l F021_API_F28004x_FPU32.lib}
	}
						 LOAD = FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13,
                         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)

   /* crc/checksum section configured as COPY section to avoid including in executable */
   .TI.memcrc          : type = COPY

}

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

Header File:

//############################################################################
//
// FILE:   F280xx_EEPROM.h
//
// TITLE:  Function Prototypes, Global Variables, Pointer Initialization
//		   and, Bank/Page Status Definitions  
//
//############################################################################
// Authors: Tim Love / Pradeep Shinde
// Release Date: Sep 2009 
//############################################################################


#include <F021_F28004x_C28x.h>

// Project specific defines
//#define SINGLE_BYTE 1
#define MULTI_BYTE  1

//Just for flash
#define FLASH_SECTOR    0x090000
#define RESET_BANK_POINTER Bank_Pointer = (uint16 *)FLASH_SECTOR	// Sector H
#define RESET_PAGE_POINTER Page_Pointer = (uint16 *)(FLASH_SECTOR+1)
#define END_OF_SECTOR 0x8FFFF;

//Only for ECC
#define ECC_BANK_BUFFER  (uint16*)0x0
#define ECC_PAGE_BUFFER  (uint16*)0x0

//#endif

// Bank/Page Status Definitions
#define EMPTY_BANK   0xFFFF
#define CURRENT_BANK 0xA00A
#define USED_BANK 	 0x0000
#define BLANK_PAGE 	 0xFFFF
#define CURRENT_PAGE 0x00FF
#define USED_PAGE    0x0000		

// Function Prototypes
extern void EEPROM_GetValidBank();
extern void EEPROM_Erase();
extern void EEPROM_Read();
extern void EEPROM_Write();
extern void EEPROM_UpdateBankStatus();
extern void EEPROM_UpdatePageStatus();
extern void EEPROM_GetSinglePointer(uint16 First_Call);
extern void EEPROM_ProgramSingleByte(uint16 data);

// Global Variables
extern uint16 *Bank_Pointer;
extern uint16 *Page_Pointer;
extern uint16 *Sector_End;
extern uint16 Read_Buffer[64];
extern uint16 Write_Buffer[64];

Source File:

//############################################################################
//
// FILE:   F280xx_EEPROM.c
//
// TITLE:  EEPROM Read, Write, and Erase Functions
//
//############################################################################
// Authors: Tim Love / Pradeep Shinde
// Release Date: Sep 2009
//############################################################################


#include "F280xx_EEPROM.h"						// EEPROM Include File

// Global Variables
uint16 Read_Buffer[64];
uint16 Write_Buffer[64];
uint16 Bank_Counter = 0;
uint16 Page_Counter = 0;
uint16 Bank_Status[1] = {0};
uint16 Page_Status[1] = {0};
uint16 *Bank_Pointer;
uint16 *Page_Pointer;
uint16 *Sector_End;

//Fapi_FlashStatusType FlashStatus;
Fapi_FlashStatusType ProgStatus;

// All Flash API functions need to be ran from internal RAM. Place all functions
// that contain Flash API calls in .TI.ramfunc to allow copy from Flash to RAM.
#pragma CODE_SECTION(EEPROM_Erase,".TI.ramfunc");
#pragma CODE_SECTION(EEPROM_Write,".TI.ramfunc");
#pragma CODE_SECTION(EEPROM_UpdateBankStatus,".TI.ramfunc");
#pragma CODE_SECTION(EEPROM_UpdatePageStatus,".TI.ramfunc");
#pragma CODE_SECTION(EEPROM_ProgramSingleByte,".TI.ramfunc");


//######################### EEPROM_GET_VALID_BANK ############################
void EEPROM_GetValidBank()
{
//Each page holds 64 data words
//Page size = Page_status word + 64W = 65W
//Bank Size = Bank_status word + 8 * Page size = 1 + 8*65 = 521W

	uint16 i;

   	RESET_BANK_POINTER;		// Reset Bank Pointer to enable search for current Bank
   	RESET_PAGE_POINTER;		// Reset Page Pointer to enable search for current Page

	// Find Current Bank 
	for(i=0;i<8;i++)
	{
		Bank_Status[0] = *(Bank_Pointer);		// Read contents of Bank Pointer
		
		if(Bank_Status[0] == EMPTY_BANK)		// Check for Unused Bank  
		{
			Bank_Counter = i;					// Set Bank Counter to number of current page								 	
			return;								// If Bank is Unused, return as EEPROM is empty
		}
	
		if(Bank_Status[0] == CURRENT_BANK)		// Check for In Use Bank 
		{
			Bank_Counter = i;					// Set Bank Counter to number of current bank
			Page_Pointer = Bank_Pointer + 1;	// Set Page Pointer to first page in current bank
			break;								// Break from loop as current bank has been found
		}

		if(Bank_Status[0] == USED_BANK)   		// Check for Used Bank											
			Bank_Pointer += 521; 				// If Bank has been used, set pointer to next bank		
	}

	// Find Current Page
	for(i=0;i<8;i++)
	{
		Page_Status[0] = *(Page_Pointer);		// Read contents of Page Pointer
		
		// Check for Blank Page or Current Page	
		if(Page_Status[0] == BLANK_PAGE || Page_Status[0] == CURRENT_PAGE)
		{
			Page_Counter = i;					// Set Page Counter to number of current page		
			break;								// Break from loop as current page has been found
		}

		if(Page_Status[0] == USED_PAGE)			// Check for Used Page
			Page_Pointer += 65;					// If page has been used, set pointer to next page
	}

	if (Bank_Counter==7 && Page_Counter==7)		// Check for full EEPROM
	{
		EEPROM_Erase();							// Erase flash sector being used as EEPROM
  		RESET_BANK_POINTER; 					// Reset Bank Pointer as EEPROM is empty
   		RESET_PAGE_POINTER;						// Reset Pank Pointer as EEPROM is empty
		asm(" ESTOP0");
	}
}
//######################### EEPROM_GET_VALID_BANK ############################


//############################# EEPROM_ERASE #################################
void EEPROM_Erase()
{
    Fapi_StatusType Status;

	Status = Fapi_issueAsyncCommandWithAddress((Fapi_EraseSector),(uint32 *)FLASH_SECTOR);

	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}

   	if(Status != Fapi_Status_Success) 		// If Erase fails halt program or handle error
   	{
      	asm(" ESTOP0");
   	} 
}
//############################# EEPROM_ERASE #################################


//############################# EEPROM_READ ##################################
void EEPROM_Read()
{
	uint16 i;

	EEPROM_GetValidBank();					// Find In Use Bank and Current Page

	// Transfer contents of Current Page to Read Buffer
	for(i=0;i<64;i++)
		Read_Buffer[i] = *(++Page_Pointer); 	
}
//############################# EEPROM_READ ##################################


//############################ EEPROM_WRITE ##################################
void EEPROM_Write()
{
	// Variables need for Flash API Functions
    Fapi_StatusType Status;
	uint32 Length;
//	Fapi_FlashStatusType ProgStatus;
	//Fapi_setActiveFlashBank(Fapi_FlashBank0);

	EEPROM_GetValidBank();					// Find In Use Bank and Current Page

    EEPROM_UpdatePageStatus();				// Update Page Status of previous page 
	EEPROM_UpdateBankStatus();				// Updage Bank Status of current and previous bank

	// Program data located in Write_Buffer to current page
	Length = 64;							// Set Length for programming
	Status = Fapi_issueProgrammingCommand((uint32 *)(Page_Pointer+1),Write_Buffer,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);
	
	// Modify Page Status from Blank Page to Current Page if flash programming was successful
	if (Status == Fapi_Status_Success)
	{
		Page_Status[0] = CURRENT_PAGE;  	// Set Page Status to Current Page
		Length = 1;							// Set Length for programming status
		Status = Fapi_issueProgrammingCommand((uint32 *)Page_Pointer,Page_Status,Length,ECC_PAGE_BUFFER,Length, Fapi_DataOnly);
	}
}
//############################ EEPROM_WRITE ##################################


//###################### EEPROM_UPDATE_BANK_STATUS ###########################
void EEPROM_UpdateBankStatus()
{
	// Variables needed for Flash API Functions
	uint32 Length;

	Length = 1;								// Set Length for programming

	Bank_Status[0] = *(Bank_Pointer);		// Read Bank Status from Bank Pointer
	Page_Status[0] = *(Page_Pointer);		// Read Page Status from Page Pointer

	// Program Bank Status for Empty EEPROM
	if (Bank_Status[0] == EMPTY_BANK)		
	{	
		Bank_Status[0] = CURRENT_BANK;  	// Set Bank Status to In Use Bank
		
		// Program Bank Status to current bank
		Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);
		Page_Counter =0;
		Page_Pointer = Bank_Pointer + 1;	// Set Page Pointer to first page of current bank
	}	

	// Program Bank Status of full bank and following bank
	if (Bank_Status[0] == CURRENT_BANK && Page_Counter == 7)	
	{	
		Bank_Status[0] = USED_BANK;			// Set Bank Status to Used Bank
		
		// Program Bank Status to full bank			
		Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);
		
		Bank_Pointer +=521;					// Increment Bank Pointer to next bank
	
		Bank_Status[0] = CURRENT_BANK;		// Set Bank Status to In Use Bank
	
		// Program Bank Status to current bank		
		Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);

		Page_Counter = 0;
		Page_Pointer = Bank_Pointer +1;		// Set Page Pointer to first page of current bank
	}
}
//###################### EEPROM_UPDATE_BANK_STATUS ###########################


//###################### EEPROM_UPDATE_PAGE_STATUS ###########################
void EEPROM_UpdatePageStatus()
{
	// Variables needed for Flash API Functions
	uint16 Length;

	Bank_Status[0] = *(Bank_Pointer);		// Read Bank Status from Bank Pointer			
	Page_Status[0] = *(Page_Pointer);		// Read Page Status from Page Pointer

	// Check if Page Status is blank. If so return to EEPROM_WRITE.
	if(Page_Status[0] == BLANK_PAGE)
		return;
	
	// Program previous page's status to Used Page
	else
	{			
		Page_Status[0] = USED_PAGE; 		// Set Page Status to Used Page 	
		Length = 1;							// Set Length for programming 
		Fapi_issueProgrammingCommand((uint32 *)Page_Pointer,Page_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);
		Page_Pointer +=65;					// Increment Page Pointer to next page
	}
}
//###################### EEPROM_UPDATE_PAGE_STATUS ###########################


//###################### EEPROM_GET_SINGLE_POINTER ###########################
void EEPROM_GetSinglePointer(uint16 First_Call)
{
	uint16 *End_Address;

	End_Address = (uint16 *)END_OF_SECTOR;	// Set End_Address for sector

	if(First_Call == 1)						// If this is first call to function, find valid pointer
	{	
		RESET_BANK_POINTER;					// Reset Bank Pointer to beginning of sector
		while(*(Bank_Pointer) != 0xFFFF)	// Test each location for data
			Bank_Pointer++;					// Increment to next location
	}
		
	if(Bank_Pointer >= End_Address)			// Test if sector is full 
	{    
		EEPROM_Erase();						// Erase flash sector being used as EEPROM
  		RESET_BANK_POINTER; 				// Reset Bank Pointer as EEPROM is empty
   		asm(" ESTOP0");
	}
	
}
//###################### EEPROM_GET_SINGLE_POINTER ###########################


//##################### EEPROM_PROGRAM_SINGLE_BYTE ###########################
void EEPROM_ProgramSingleByte(uint16 data)
{
	// Variables needed for Flash API Functions
	uint32 Length;

	Write_Buffer[0] = data;					// Prepare data to be programmed
		
	Length = 1;								// Set Length for programming
	Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer++,Write_Buffer,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly);
	EEPROM_GetSinglePointer(0);				// Test for full sector	
}
//##################### EEPROM_PROGRAM_SINGLE_BYTE ###########################

  • Hi Aloba,

    Whenever you step in to the flash API library functions, CCS will show you the "can't find the source file at this address." message since the flash API source is not available for it to show - This is not an issue.  You can ignore this.

    Regarding the linker error:  It is simply saying that the allocated memory for that output section is not enough.  Try merging couple of memory ranges (to be able to fit that section) and map that section to the new big memory range.  

    Also, note that we are planning to release an EEPROM example (for F28P65x device - but you should be able to easily edit it for F28004x) in the upcoming C2000Ware release.

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    Here's the prompt message I get immediately I tried running the code: No source available for "_system_post_cinit() at C:/Users\...\Debug\project.out:{3} 0x3fbd92{4}" 

    The 0x3fbd92{4} address happens to be in the boot rom.

  • Also, the code would build without the "Fapi_setActiveFlashBank" function but with it in the picture it's going to generate the error message described.

    Thanks and regards,

    Aloba.

  • Hi Aloba,

    For the execution error landing in BootROM: As per the TRM's table 4-15. Wait Point Addresses, the address 0x3fbd92 belongs to ITRAP ISR. 

    It means the CPU executed an illegal instruction.  Please check whether or not the memcpy() is executed before calling any functions that are mapped to the .Ti.ramfunc section.

    For the linker error, please follow the suggestion I provided previously.

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    I appreciate your responses. I've tried implementing your suggestion to resolve the linker error, but unfortunately, it still persists.

    Regarding the `memcpy()` function, it isn't executed at any point in my code because I'm unsure of the source or destination.

    Could you please take a look at the command file I shared? Your advice would be really helpful.

    Thanks and best regards,

    Aloba

  • Aloba,

    Please review this FAQ once: 

    How to modify an application from RAM configuration to Flash configuration?: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/878674 

    Also, you can take a look at any C2000Ware example - they should have a flash build configuration (as explained in above FAQ). You can single-step execute and understand the process that is explained in the FAQ.

    Thanks and regards,

    Vamsi

  • And for the linker command file: Can you show what you did in the linker command file (which you said did not help remove the error)?

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    Here's the modification I made on the linker command file:

    From This:

     

       GROUP
       {
    	.TI.ramfunc
    	{ -l F021_API_F28004x_FPU32.lib}
    	}
    						 LOAD = FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13,
                             RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,

    To this: 

       GROUP
       {
    	.TI.ramfunc
    	{ -l F021_API_F28004x_FPU32.lib}
    	}
    						 LOAD = FLASH_BANK0_SEC7 | FLASH_BANK0_SEC8 | FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13,
                             RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,

    Thanks,

    Aloba.

  • Hi Aloba,

    Instead of OR of the memories, can you merge couple of memories in to one memory range and try?

    Example:

    From this:

    FLASH_A: origin = 0x90000, length = 0x1000

    FLASH_B: origin = 0xA0000, length = 0x1000

    To this:

    FLASH_AB: origin = 0x90000, length = 0x2000

    And use the merged memory range.

    Let us know if that helps.

    Thanks and regards,

    Vamsi 

  • Hi Aloba, 

    Since I did not hear back from you, I am closing this post assuming that my last reply helped you to close the issue.

    If you still have further questions, you can open a new post as needed.

    Thanks and regards,

    Vamsi