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.

TMS320F28377D: FFT_Twiddles uninitialized section warning and TwiddleFactors not loaded after CPU connection

Part Number: TMS320F28377D

Hello,

I'm facing some problem similar to the following posts:

https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/630603/2339627?tisearch=e2e-sitesearch&keymatch=FPU_initFlash#2339627

https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/940332?tisearch=e2e-sitesearch&keymatch=FPUfftTables

But none of these answers worked well for me.

I use RFFT from TI using Twiddle Factor Tables. When I load program to CPU1 and run, everything works well. However, when I disconnect the CPU1 and reconnect again and run without loading the program, the FFT results are not ok since twiddle Factors are erased.

When I compile ( v18.12.0.LTS and CCS v.9.3.0.00012) I get this warning: #10068-D no matching section in the following line of .cmd:

#if defined(USE_TABLES)
   FFT_Twiddles     : LOAD = FLASHM,
                      RUN  = RAMGS11,
                      RUN_START(_FFTTwiddlesRunStart),
                      LOAD_START(_FFTTwiddlesLoadStart),
                      LOAD_SIZE(_FFTTwiddlesLoadSize),
                      PAGE = 1,
  {
     --library=c28x_fpu_dsp_library.lib<RFFT_f32_twiddleFactors.obj> (.econst)
  }

#endif

This is my .cmd file:

--define RFFT_ALIGNMENT=128
#if !defined(RFFT_ALIGNMENT)
#error define RFFT_ALIGNMENT under C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
#endif

MEMORY
{

PAGE 0 :  /* Program Memory */
	          /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
	          /* BEGIN is used for the "boot to Flash" bootloader mode   */
	
	BEGIN           	: origin = 0x080000, length = 0x000002
	RAMM0           	: origin = 0x000122, length = 0x0002DE 	/* Non-secure EEC-capable block, only CPU has access to it */
	RAMD0           	: origin = 0x00B000, length = 0x000800	/* Secure EEC-capable and acccess-protection feature block, only CPU has access to it */

   RAMLS012345		: origin = 0x008000, length = 0x003000
//   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
//   RAMLS5     	    : origin = 0x00A800, length = 0x000800

	RAMGS9      : origin = 0x015000, length = 0x001000


	RESET           	: origin = 0x3FFFC0, length = 0x000002
	   
	/* Flash sectors */
	MAGIC_CODE       : origin = 0x080002, length = 0x000004
	FLASHA           : origin = 0x080006, length = 0x001FFA	/* on-chip Flash */
	FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
	FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
	FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
	FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
	FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
	FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
	FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
	FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
	FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
	FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
	FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
	FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */

PAGE 1 : /* Data Memory */
	         /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */

	BOOT_RSVD       : origin = 0x000002, length = 0x000120     	/* Part of M0, BOOT rom will use this for stack */
	RAMM1           : origin = 0x000400, length = 0x000400    	/* Non-secure EEC-capable block, only CPU has access to it */
	RAMD1           : origin = 0x00B800, length = 0x000800	 	/* Secure EEC-capable and acccess-protection feature block, only CPU has access to it */

	RAMGS0      : origin = 0x00C000, length = 0x001000
	RAMGS1      : origin = 0x00D000, length = 0x001000
	RAMGS23      : origin = 0x00E000, length = 0x002000
	//RAMGS3      : origin = 0x00F500, length = 0x000B00
	RAMGS4      : origin = 0x010000, length = 0x001000
	RAMGS5      : origin = 0x011000, length = 0x001000
	RAMGS678      : origin = 0x012000, length = 0x003000
	//RAMGS7      : origin = 0x013000, length = 0x001000
	//RAMGS8      : origin = 0x014000, length = 0x001000

	RAMGS10     : origin = 0x016000, length = 0x001000
	RAMGS11     : origin = 0x017000, length = 0x001000		// reserved as CPU1 local RAM
	RAMGS12     : origin = 0x018000, length = 0x001000		// reserved as CPU1 local RAM
	RAMGS13     : origin = 0x019000, length = 0x001000		// reserved as CPU1 local RAM
	RAMGS14     : origin = 0x01A000, length = 0x001000		// reserved as CPU1 local RAM
	RAMGS15     : origin = 0x01B000, length = 0x001000		// reserved as CPU1 local RAM


	FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */

	CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
	CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
}

	

SECTIONS
{


	/* Allocate program areas: */
	.cinit              : > FLASHB      PAGE = 0, ALIGN(4)
	.pinit              : > FLASHB,     PAGE = 0, ALIGN(4)
	.text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(4)
	codestart           : > BEGIN       PAGE = 0, ALIGN(4)

	/* Allocate uninitalized data sections: */
	.stack              : > RAMM1       			PAGE = 1
	.ebss               : > RAMGS678    			PAGE = 1
	.esysmem            : > RAMGS15  				PAGE = 1
	.cio                : > RAMGS15					PAGE = 1


	/* Initalized sections go in Flash */
	.econst             : > FLASHM,      PAGE = 1, ALIGN(4)
	.switch             : > FLASHB,      PAGE = 0, ALIGN(4)

	.reset              : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

//	SHARERAMGS0			: > RAMGS0,		PAGE = 1
//	SHARERAMGS1			: > RAMGS1,		PAGE = 1
//	SHARERAMGS2			: > RAMGS2,		PAGE = 1

	SHARERAM_param			: > RAMGS4, 	PAGE = 1	// RAMGS2 CPU1 RW ACCESS
	SHARERAM_paramInfo  	: > RAMGS4, 	PAGE = 1	// RAMGS2 CPU1 RW ACCESS
	SHARERAM_crono			: > RAMGS4, 	PAGE = 1	// RAMGS2 CPU1 RW ACCESS
	SHARERAM_AFQe			: > RAMGS4,		PAGE = 1	// RAMGS2 CPU1 RW ACCESS

	SHARERAM_paramModbus	: > RAMGS1     	PAGE = 1	// RAMGS0 CPU2 RW ACCESS
	SHARERAM_FFT_CAN_Slave 	: > RAMGS1		PAGE = 1	// RAMGS0 CPU2 RW ACCESS

	SHARERAM_FFT_CAN_Master : > RAMGS4		PAGE = 1	// RAMGS0 CPU1 RW ACCESS
	SHARERAM_canalesCPU2	: > RAMGS4		PAGE = 1	// RAMGS0 CPU1 RW ACCESS
	SHARERAM_satura			: > RAMGS4		PAGE = 1	// RAMGS0 CPU1 RW ACCESS
	SHARERAM_terminator		: > RAMGS4		PAGE = 1	// RAMGS0 CPU1 RW ACCESS

	.TI.ramfunc : {} LOAD = FLASHE,
						 RUN = RAMLS012345,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         RUN_SIZE(_RamfuncsRunSize),
                         RUN_END(_RamfuncsRunEnd),
						 PAGE = 0, ALIGN(4)

#if defined(USE_TABLES)
   FFT_Twiddles     : LOAD = FLASHM,
                      RUN  = RAMGS11,
                      RUN_START(_FFTTwiddlesRunStart),
                      LOAD_START(_FFTTwiddlesLoadStart),
                      LOAD_SIZE(_FFTTwiddlesLoadSize),
                      PAGE = 1,
  {
     --library=c28x_fpu_dsp_library.lib<RFFT_f32_twiddleFactors.obj> (.econst)
  }

#endif

	
	 

	/* The following section definitions are required when using the IPC API Drivers */
	GROUP : > CPU1TOCPU2RAM, PAGE = 1
	{
        PUTBUFFER
        PUTWRITEIDX
        GETREADIDX
    }

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

	 /* Allocate IQ math areas: */
	   IQmath			: > FLASHB, PAGE = 0, ALIGN(4)            /* Math Code */
	   IQmathTables		: > FLASHC, PAGE = 0, ALIGN(4)
    
	
	 /* The following section definition are for AFQ application*/
	
	vectores			: > RAMGS23,		PAGE = 1
	dataFFT_Iload		: > RAMGS5, 		PAGE = 1, START(_IloadStart), SIZE(_IloadSize)
	dataFFT_IloadM		: > RAMGS11,			PAGE = 1, START(_IloadMStart)
 	modbus              : > RAMGS9,  		PAGE = 0
	vectors_captura		: > RAMGS10,		PAGE = 1
	
   	magic_word				: > MAGIC_CODE,		PAGE = 0, ALIGN(4)
	
 	RFFTdata1        : > RAMGS12,    PAGE = 1, ALIGN = RFFT_ALIGNMENT
   	RFFTdata2        : > RAMGS13,    PAGE = 1
   	RFFTdata3        : > RAMGS14,    PAGE = 1
   	RFFTdata4        : > RAMGS15,    PAGE = 1

	FPUmathTables    : > RAMGS5,    PAGE = 1
	FPUfftTables: > RAMGS11,	PAGE = 1


	  /* Allocate DMA-accessible RAM sections: */
	 dmaMemBufs         : > RAMGS23,   PAGE = 1
	
}

In my Main.c file:

#ifdef USE_TABLES
extern uint16_t FFTTwiddlesRunStart;
extern uint16_t FFTTwiddlesLoadStart;
extern uint16_t FFTTwiddlesLoadSize;
#endif //USE_TABLES
void main(void)
{
 	InitSysCtrl();

	// Step 2. Clear all interrupts and initialize PIE vector table:
	DINT;

	// Initialize the PIE control registers to their default state.
	// The default state is all PIE interrupts disabled and flags
	// are cleared.
   	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).
	InitPieVectTable();


	 EALLOW;
	 Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0;
	 memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (uint32_t)&RamfuncsLoadSize);

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

#ifdef USE_TABLES
     memcpy(&FFTTwiddlesRunStart, &FFTTwiddlesLoadStart, (uint32_t)&FFTTwiddlesLoadSize );
#endif //USE_TABLES

What could be the problem for this? Is this problem that I'm facing after reconnection related with the warning or are two separate problems?

Thank you very much

Maite

  • Hi

    Have you enabled the USE_TABLES in the project properties -> compiler -> pre-defined symbols?

  • Hi Shanty,

    thanks for your answer. Yes, I enabled USE_TABLES. In fact, everything works ok when I run program after loading it. The problem is wheny I run the program after a disconnect/reconnect sequence without loading again the program.

  • I don't understand the reasoning behind not reloading the program. The twiddle factors are bundled in with the .out. When you reconnect, the memcpy function is not invoked, hence the twiddle factors are not copied to the right location, resulting in the incorrect values. Can you clarify?

  • Hello,

    when I saw this "problem" I was debuggin with my prototype and I had to switch on- switch off a lot of times the device without making changes to firmware. So, in order to go faster, I did'nt want to load the program every time. Can you explain me a little bit more the reason why twiddle factors are not copied, please?

    Thank you!

  • Hi,

    So in the code, you will notice the line:

    #ifdef USE_TABLES
         memcpy(&FFTTwiddlesRunStart, &FFTTwiddlesLoadStart, (uint32_t)&FFTTwiddlesLoadSize );

    You are using the FLASH configuration, so the twiddle factors are stored in flash. They need to be copied to RAM. This copy to RAM happens with this memcpy() function, which is part of the program. This is why it did not work for you. You must load the program every time, as painful as it may be. 

     -Shantanu

  • Hi,

    but the program is already in the DSP when I reconnect after a debugging session, am I right? Because all the the other things work normally, except twiddle factors. For example, ramfuncs are working well and I also use this memcpy function just before twiddle factors memcpy.

    Maite

  • HI

    In emulation mode, disconnecting and reconnecting the JTAG may or may not erase certain memory contents. Consult the Debug Handbook for more information. It is always safer to just reload the program.