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.

CCS/TMS320F28069: CLA works with JTAG emulator connected, but not in standalone mode

Part Number: TMS320F28069

Tool/software: Code Composer Studio

I realise that there are other posts already regarding this, but none of the bugs mentioned there are present in this case (or not to my knowledge).

I have one of these devices running with two tasks in the CLA.  When the JTAG emulator is connected and I run in debug mode, everything is fine.  However, if I power cycle the target board (emulator still plugged in), the CPU boots properly but the CLA tasks do not run.  If I program the device with release code (no emulation), the CPU runs, but not the CLA. If I setup interrupts to fire after a CLA task finishes, those interrupts run OK, but the CLA has clearly not executed its code properly.  I know this from debugging with various LEDs on the target board.

The clock to the CLA is enabled in the InitSysCtrl() function, enclosed by EALLOW and EDIS:     SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 1;

Are there any special settings required in the project configurations to allow the CLA to run in standalone?  I am at a loss to know what to do, any suggestions would be gratefully appreciated.

Many thanks in advance.

In the linker CMD file:

MEMORY
{
   PAGE 0 :   /* Program Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
   RAML3       : origin = 0x009000, length = 0x001000   /* on-chip RAM block L3. Used for CLA Program RAM. */
   RAML8       : origin = 0x012000, length = 0x002000     /* on-chip RAM block L8. Used for ramfuncs code. */
   FLASHD      : origin = 0x3E8000, length = 0x004000     /* on-chip FLASH. Used for Cla1Prog code. */
.
.
PAGE 1 :   /* Data Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
           /* Registers remain on PAGE1                                                  */
   RAML0       : origin = 0x008000, length = 0x000800     /* on-chip RAM block L0. Used for CLA Data RAM 2. */
   RAML1       : origin = 0x008800, length = 0x000400     /* on-chip RAM block L1. Used for CLA Data RAM 0. */
   RAML2       : origin = 0x008C00, length = 0x000400     /* on-chip RAM block L2. Used for CLA Data RAM 1. */
.
   CLA1_MSGRAMLOW       : origin = 0x001480, length = 0x000080
   CLA1_MSGRAMHIGH      : origin = 0x001500, length = 0x000080
}
SECTIONS
{
   Cla1Prog            : LOAD = FLASHD,
                         RUN = RAML3,
                         LOAD_START(_Cla1funcsLoadStart),
                         LOAD_END(_Cla1funcsLoadEnd),
       RUN_START(_Cla1funcsRunStart),
       LOAD_SIZE(_Cla1funcsLoadSize),
                         PAGE = 0
   Cla1ToCpuMsgRAM     : > CLA1_MSGRAMLOW,   PAGE = 1
   CpuToCla1MsgRAM     : > CLA1_MSGRAMHIGH,  PAGE = 1
   Cla1DataRam0  : > RAML1,    PAGE = 1
   Cla1DataRam1  : > RAML2,    PAGE = 1
   Cla1DataRam2  : > RAML0,    PAGE = 1
   CLAscratch       :
                     { *.obj(CLAscratch)
                     . += CLA_SCRATCHPAD_SIZE;
                     *.obj(CLAscratch_end) } > RAML1,
      PAGE = 1
}
In CLA initialisation file:
    EALLOW;
    /* Compute all CLA task vector offsets (different from 2837x core) */
    Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT2 = (Uint16)((Uint32)&Cla1Task2 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT3 = (Uint16)((Uint32)&Cla1Task3 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT4 = (Uint16)((Uint32)&Cla1Task4 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT5 = (Uint16)((Uint32)&Cla1Task5 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT6 = (Uint16)((Uint32)&Cla1Task6 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT7 = (Uint16)((Uint32)&Cla1Task7 - (Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT8 = (Uint16)((Uint32)&Cla1Task8 - (Uint32)&Cla1Prog_Start);
    asm("   RPT #3 || NOP");
    Cla1Regs.MMEMCFG.all = CLA_PROG_ENABLE | CLARAM0_ENABLE | CLARAM1_ENABLE | CLARAM2_ENABLE;
    asm("   RPT #3 || NOP");
    Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_ADCINT1;
    Cla1Regs.MPISRCSEL1.bit.PERINT2SEL = CLA_INT2_ADCINT2;
    Cla1Regs.MPISRCSEL1.bit.PERINT8SEL = 0b1111;
    Cla1Regs.MCTL.bit.IACKE = 1;
    Cla1Regs.MIER.all = 0x00FF;
    EDIS;
 
In main(), before setting up CLA:
 
    memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);
  • You said the CLA isn't running, but then said the CLA task completion caused an interrupt status to be sent. This makes it seem the CLA was in fact running.

    If you are running from flash, make sure you copy over the CLA program to RAM first at the start of your application.

    Can you provide more detail? I am not sure what the exact problem is because it seems the CLA is running if the interrupt flags are set on task completion.

    sal
  • I have found the answer.  The CLA was indeed running the code correctly, but several constants I had declared in the CLA initialisation code were not being copied in the CLA data RAM.  Consequently, the calculations being performed by the CLA were producing rubbish output values.  It would appear that the debugger can detect that the constants need copying and do it automatically, which is why there was no problem when the debugger was connected.  For anyone reading this in the future, declare CLA constants like this:

    #pragma DATA_SECTION(xCLA_PhaseCurrentConstants,"Cla1DataRam1");
    const struct CLA_PhaseCurrentConstants_t xCLA_PhaseCurrentConstants =
    {
      .fUGain = INVERTER_PHASE_CURRENT_U_GAIN,
      …
    }

    In the CMD file allocate ClaDataRam1 for use with constants:

     Cla1DataRam1        : LOAD = FLASHE, PAGE = 0
                           RUN = RAML2, PAGE = 1
                           LOAD_START(_Cla1constsLoadStart),
                           LOAD_END(_Cla1constsLoadEnd),
                          
    RUN_START(_Cla1constsRunStart),
                           LOAD_SIZE(_Cla1constsLoadSize)

    In an initialisation function, copy the constants into RAM in the same way that the CLA program memory is copied (memcpy).