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.

TMS320F2806 SP and PC corrupted in ramfunc .asm module in C app

On the one hand I have a RAM linked piece of test code that executes marvelously.  It sets a usecond timer for some number of milliseconds, sets the ADC up for samples at a predetermined rate and then runs several digital filters on the fly.  I have it down to 3us per sample running 8 DFT's.  I like it.  (RAM based IQmathLib was 18.2us).

On the other hand I have a stub of the working code that is FLASH based and provides a CAN interface to the chip, etc.  My code takes 24us per sample running from FLASH because of the wait states.  I expected this.  Point is, the code WORKS inserted into the FLASH project (which is the minimal part of a larger project that my code will be one command in).

... calling C routine:  

	// sets ADC and switch states, backs up old settings
	PD_SetADCtoPD (sensor);


	// start a count down timer at MeasTime
    InitCpuTimers();
    ConfigCpuTimer(&CpuTimer0, 100, MeasTime);

    NumSamp = asmMeasLoop (ReIm, CSTime, CosSin);

	// stop ADC
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;			// stop

...

Note, I have verified that all clock setups are identical so the 8x slow-down is just the wait states.  Simple solution - change it from .text to .ramfuncs.   This locates my function at 0x8000 in SRAM (verified by examining PC on entry.)  SP is 0xA8 on first line of code, but the first PUSH sends PC to 0x0088 and sends the SP into left field.

;****************************************************************************
FP	.set	XAR2
 .sect "ramfuncs" ;.sect ".text" 	.global	_asmMeasLoop
	.global _CpuTimer0Regs
	.global _AdcRegs
	.global _AdcMirror
;----------------------------------------------------------------------
;  13 | unsigned long int asmMeasLoop (_iq15* ReIm, _iq30* CSTime, _iq30* CosSin)
_asmMeasLoop:
		; CosSin	  *-SP[22] passed on stack
		; unknown     *-SP[20] passed on stack is 0x00008568, probably PC
		PUSH XAR7 ; *-SP[18] save to use as temporary CosSin pointer 		PUSH XAR6   ; *-SP[16] save to use as temp variable
		PUSH XAR5   ; *-SP[14] save incoming pointer to CSTime
		PUSH XAR4   ; *-SP[12] save incoming pointer to ReIm
		PUSH XAR3   ; *-SP[10]  save to use as pointer to AdcRegs.ADCST
		PUSH XAR2   ; *-SP[8]  save to use as pointer to AdcMirror.ADCRESULT0
		ADDB SP,#4	; NumSamp at *-SP[6], i at *-SP[4]
		PUSH DP		; *-SP[2]
		PUSH ST0	; *-SP[1]

        MOV      *-SP[6],#0             ; NumSamp MSW
        MOV      *-SP[5],#0             ; NumSamp LSW
        MOVL	  XAR2,#_AdcMirror		; save cycles
        MOVL	  XAR3,#_AdcRegs+25		; save cycles
        MOVL      XAR7,*-SP[22]         ;  CosSin[0]; assume XAR7 is available
        SPM 	  0						; no shift P

 

The FLASH code is a part of a CCS3.3 project (I am using 5.2), so I have had to hack and hack again while newly learning C2000.  There is a lot of .asm code in there besides mine.  I wiped it down to the least it can do (receive ECHO, VERSION?, REBOOT, and my command on CAN and return results) ad reverted the CMD files to F2806.cmd (default) and DSP280x_Headers_nonBIOS.cmd (examples default).

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 */
   OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */
   FLASHD      : origin = 0x3F0000, length = 0x002000     /* on-chip FLASH */
   FLASHC      : origin = 0x3F2000, length = 0x002000     /* on-chip FLASH */
   FLASHA      : origin = 0x3F6000, length = 0x001F80     /* on-chip FLASH */
   CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
   BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
   CSM_PWL     : origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */
   
   ROM         : origin = 0x3FF000, length = 0x000FC0     /* 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                                                  */

   RAMM0       : origin = 0x000000, length = 0x000400     /* on-chip RAM block M0 */
   BOOT_RSVD   : origin = 0x000400, length = 0x000080     /* Part of M1, BOOT rom will use this for stack */
   RAMM1       : origin = 0x000480, length = 0x000380     /* on-chip RAM block M1 */
   RAML1       : origin = 0x009000, length = 0x001000     /* on-chip RAM block L1 */
   FLASHB      : origin = 0x3F4000, length = 0x002000     /* on-chip FLASH */
}

/* 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               : > FLASHC      PAGE = 0
   codestart           : > BEGIN       PAGE = 0
   ramfuncs            : LOAD = FLASHD, 
                         RUN = RAML0, 
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0

   csmpasswds          : > CSM_PWL     PAGE = 0
   csm_rsvd            : > CSM_RSVD    PAGE = 0
   
   /* Allocate uninitalized data sections: */
   .stack              : > RAMM0       PAGE = 1
   .ebss               : > RAML1       PAGE = 1
   .esysmem            : > RAML1       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              : > FLASHC      PAGE = 0                  /* Math Code */
   IQmathTables        : > ROM         PAGE = 0, TYPE = NOLOAD   /* Math Tables In ROM */

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

}

The problem is 100% repeatable.  It occurs in debug (XDS510USB) and release (i.e. other commands answer on CAN but this one needs a power cycle).  The RAM based test code and the FLASH based app link to the same files.  Both work if the section for this function is text.

Also, I had to remove DSP280x_usDelay - apparently for the same reason - before I realized this was happening.

I am sure the issue is largely that I took a generic CMD and don't know enough to fix it... If there is an easy answer I am all ears.  if there is a hard answer, I'll put in the work but would appreciate the reading to be as focused as possible.

Thanks!

 

  • OK, the problem occurs 100% of the time but not always on the first PUSH.  I also found that if I put a breakpoint on the entry line and moved PC to LRETL it "returned" to DSP280x_usDelay ...

    It is next in memory.  Do I need to align the linker to even addresses by - e.g. inserting a NOP?  (OK, this is not a PIC14... :)  )

    SECTION ALLOCATION MAP
    
     output                                  attributes/
    section   page    origin      length       input sections
    --------  ----  ----------  ----------   ----------------
    .pinit     0    003f6000    00000000     UNINITIALIZED
    
    ramfuncs   0    003f0000    00000066     RUN ADDR = 00008000
                      003f0000    00000061     PD_asmMeasLoop.obj (ramfuncs)
                      003f0061    00000004     DSP280x_usDelay.obj (ramfuncs)
                      003f0065    00000001     excanInit18.obj (ramfuncs)
    
    .text      0    003f2000    00001074     
                      003f2000    000005ee     main.obj (.text)
                      003f25ee    00000252     commsfuncs.obj (.text)
                      003f2840    0000013d     PD_Scan.obj (.text)
                      003f297d    00000139     PD_ADCsettings.obj (.text)
                      003f2ab6    00000095     tx_data.obj (.text)
                      003f2b4b    00000083     rts2800_ml.lib : fd_mpy.obj (.text)
                      003f2bce    00000083                    : fs_div.obj (.text)
                      003f2c51    00000079     excanInit18.obj (.text)
                      003f2cca    00000075     DSP280x_CpuTimers.obj (.text)
                      003f2d3f    0000005a     rts2800_ml.lib : fs_mpy.obj (.text)
                      003f2d99    00000044                    : boot.obj (.text)
                      003f2ddd    00000042     dspInit.obj (.text)
                      003f2e1f    0000003c     exrxcan13.obj (.text)
                      003f2e5b    0000003b     extxcan14.obj (.text)
                      003f2e96    00000037     TxRxFunc.obj (.text)
                      003f2ecd    00000031     txcan13.obj (.text)
                      003f2efe    0000002d     sendCmd.obj (.text)
                      003f2f2b    0000002a     rts2800_ml.lib : l_div.obj (.text)
                      003f2f55    0000002a     rxcan12.obj (.text)
                      003f2f7f    00000029     rts2800_ml.lib : fs_tol.obj (.text)
                      003f2fa8    00000022                    : i_div.obj (.text)
                      003f2fca    0000001f                    : fd_tol.obj (.text)
                      003f2fe9    0000001c                    : fs_tofd.obj (.text)
                      003f3005    00000019                    : args_main.obj (.text)
                      003f301e    00000019                    : exit.obj (.text)
                      003f3037    00000013                    : ul_tofs.obj (.text)
                      003f304a    00000010                    : u_tofs.obj (.text)
                      003f305a    00000009     checkcan.obj (.text)
                      003f3063    00000009     rts2800_ml.lib : _lock.obj (.text)
                      003f306c    00000008     DSP280x_CodeStartBranch.obj (.text)
    
    IQmath     0    003f3074    000000a3     
                      003f3074    00000042     IQmath.lib : IQ24sqrt.obj (IQmath)
                      003f30b6    00000029                : IQ30sinPU.obj (IQmath)
                      003f30df    00000027                : IQ30cosPU.obj (IQmath)
                      003f3106    00000011                : IQ24mpyI32int.obj (IQmath)
    
    .cinit     0    003f6000    000000b5     
                      003f6000    0000008f     main.obj (.cinit)
                      003f608f    0000000a     rts2800_ml.lib : _lock.obj (.cinit)
                      003f6099    0000000a                    : exit.obj (.cinit)
                      003f60a3    00000008     PD_ADCsettings.obj (.cinit)
                      003f60ab    00000008     commsfuncs.obj (.cinit)
                      003f60b3    00000002     --HOLE-- [fill = 0]
    
    .econst    0    003f60b6    00000032     
                      003f60b6    00000020     PD_Scan.obj (.econst:_$P$T0$1)
                      003f60d6    00000007     main.obj (.econst:_$P$T1$6)
                      003f60dd    00000006     main.obj (.econst:_$P$T0$5)
                      003f60e3    00000001     --HOLE-- [fill = 0]
                      003f60e4    00000004     PD_Scan.obj (.econst)
    
    codestart 
    *          0    003f7ff6    00000002     
                      003f7ff6    00000002     DSP280x_CodeStartBranch.obj (codestart)
    
    IQmathTables 
    *          0    003ff000    00000b50     NOLOAD SECTION
                      003ff000    00000b50     IQmath.lib : IQmathTables.obj (IQmathTables)
    
    .reset     0    003fffc0    00000002     DSECT
                      003fffc0    00000002     rts2800_ml.lib : boot.obj (.reset)
    
    vectors    0    003fffc2    00000000     DSECT
    
    .stack     1    00000000    00000300     UNINITIALIZED
                      00000000    00000300     --HOLE--
    
    

  • Just as a sanity check I converted this project over to 2806_RAM_lnk.cmd.  I had to strip some functions to fit it, but the problem is not present in this configuration.  It is definitely an issue with FLASH & ramfuncs for any ramfuncs code in this app.

     

    Unfortunately this is not a solution - because before I kick this over the wall to the integration team a great deal of hardware testing and algorithm refinement needs be done. 

     (a) my tech cannot use CCS5 and the debugger to do the HW test

     (b) I cannot fit any more code into an all RAM solution

     (c) I cannot run at 8x slowdown in an all FLASH solution to test HW.

     (d) I'd still like to work with the integration team in the future!

  • Just now reading SPRA958L.  I had mistakenly assumed that the runtime initialization loaded the RAM code...

    I do not have these calls:

    //--- Copy all Flash sections that need to run from RAM (use memcpy() from RTS library)
    
    // Section secureRamFuncs contains user defined code that runs from CSM secured RAM
    	memcpy(&secureRamFuncs_runstart, &secureRamFuncs_loadstart, (Uint32)(&secureRamFuncs_loadsize));
    
    //--- Initialize the Flash and OTP
    	InitFlash();						// Initialize the Flash
    

    Instead of wondering why it failed to execute, now I wonder why it even tried...

    Unfortunately not enough time to try it today.

    Any votes that this is the answer?

  • All it needed was a load...

     

    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)(&RamfuncsLoadEnd-&RamfuncsLoadStart));