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.

TMS320F28375D: CLA1 Issue

Part Number: TMS320F28375D

Dear Veena,

We have faced same issue again with CLA1.

The function we have developed is not working properly. The function contains several equations, in which some part of function is working Ok but other part of function is not working.

I have attached two file here. One file is function written in C and other file is part of disassembly part of CCS debugger.

Kindly take serious Note of this problem.

Regards,

Dushyant RanaSource_File.rar

  • Hello,

    Can you provide more information on how it isn’t working? Have you stepped through the code?

    Thank you

    Lori

  • Hello,

    The project we are working is part of Active Harmonic Filtering using PR controller (reference document is attached).

    We have used transfer function (discrete form) of PR controller for individual harmonic compensation, which is implemented in CLA1. 

    As our core is running at 39.06usec. This transfer function is not working properly with change of memory length of individual function implemented in CLA1.

    I have attached following files for your reference in attached rar files.

    1. cla1_init.c

    2. C1_CPU_CLA.cla

    3. C1_CpuCla_data.h

    4. 2837x_FLASH_lnk_cpu1.cmd

    5. AHF_3800_3LVL_CPU1.map

    6. PRController.pdf

    Thanks For Support,

    Dushyant Rana

    Project-Files.rar

  • Amtech said:
    This transfer function is not working properly with change of memory length of individual function implemented in CLA1.

    Amtech,

    Does this mean when the function gets to a certain size it no longer works?  Is it now crossing RAM physical boundaries? 

    Not all memory on the device is accessible by the CLA. That would be the first thing to check.  In the data sheet there is a memory map the shows all the memory blocks and which the CLA can access.  If it crossed into another RAM block then that block needs to be configured for use by the CLA.  That would be the second thing to check. 

    If the code is running in valid, configured, CLA memory.  Next thing to check is stepping through the CLA code - can you tell if it is reads not happening properly or writes?  That would help us to understand if it is the data memory causing a problem instead of the program memory. 

    For example, Code Security - if the CLA is running in memory that is not secure but it was trying to access secure RAM which is not allowed. CLA can only access secure RAM if CLA is also grabbed by same zone. If this is the case, then either make RAMs unsecure or grab CLA as well from same zone.

    Lori

  • Hello,


    -> Does this mean when the function gets to a certain size it no longer works? Is it now crossing RAM physical boundaries?
    No, function is not crossing RAM physical boundaries.

    -> Not all memory on the device is accessible by the CLA. That would be the first thing to check. In the data sheet there is a memory map the shows all the memory blocks and which the CLA can access.

    In Our project we have used Local memory LS2, LS3 and LS4 as Program memory for CLA1.
    And we have combined LS0 and LS1 for RAM for CLA1.
    For That we done below memory allocation in cmd file of our firmware.
    PAGE 0 :

    /* BEGIN is used for the "boot to Flash" bootloader mode */
    BEGIN : origin = 0x080000, length = 0x000002
    RAMM0 : origin = 0x000122, length = 0x0002DE
    RAMD0 : origin = 0x00B000, length = 0x000800
    RAMLS0 : origin = 0x008000, length = 0x001000
    //RAMLS1 : origin = 0x008800, length = 0x000800
    RAMLS2 : origin = 0x009000, length = 0x000800
    RAMLS3 : origin = 0x009800, length = 0x000800
    RAMLS4 : origin = 0x00A000, length = 0x000800
    RAMGS12 : origin = 0x018000, length = 0x004000

    RESET : origin = 0x3FFFC0, length = 0x000002
    /* Flash sectors */
    FLASHA : origin = 0x080002, length = 0x001FFE /* 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 = 0x030000 /* on-chip Flash */
    FLASHK : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */
    FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
    FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
    FLASHN : origin = 0x0BE000, length = 0x002000 /* on-chip Flash */

    //in section
    Cla1Prog : LOAD = FLASHD,
    RUN = RAMLS2,
    LOAD_START(_Cla1funcsLoadStart),
    LOAD_END(_Cla1funcsLoadEnd),
    RUN_START(_Cla1funcsRunStart),
    LOAD_SIZE(_Cla1funcsLoadSize),
    PAGE = 0, ALIGN(4)
    // DR-20
    Cla1Prog1 : LOAD = FLASHK,
    RUN = RAMLS3,
    LOAD_START(_Cla1funcsLoadStart1),
    LOAD_END(_Cla1funcsLoadEnd1),
    RUN_START(_Cla1funcsRunStart1),
    LOAD_SIZE(_Cla1funcsLoadSize1),
    PAGE = 0, ALIGN(4)
    // DR-20
    Cla1Prog2 : LOAD = FLASHL,
    RUN = RAMLS4,
    LOAD_START(_Cla1funcsLoadStart2),
    LOAD_END(_Cla1funcsLoadEnd2),
    RUN_START(_Cla1funcsRunStart2),
    LOAD_SIZE(_Cla1funcsLoadSize2),
    PAGE = 0, ALIGN(4)

    We have configured CLA as shown in below:
    void CLA_configClaMemory(void)
    {
    extern uint32_t Cla1funcsRunStart, Cla1funcsLoadStart, Cla1funcsLoadSize;
    extern uint32_t Cla1funcsRunStart1, Cla1funcsLoadStart1, Cla1funcsLoadSize1; // DR-20
    extern uint32_t Cla1funcsRunStart2, Cla1funcsLoadStart2, Cla1funcsLoadSize2; // DR-20
    EALLOW;
    #ifdef _FLASH
    // Copy over code from FLASH to RAM
    memcpy((uint32_t *) & Cla1funcsRunStart, (uint32_t *) & Cla1funcsLoadStart, (uint32_t) & Cla1funcsLoadSize);
    memcpy((uint32_t *) & Cla1funcsRunStart1, (uint32_t *) & Cla1funcsLoadStart1, (uint32_t) & Cla1funcsLoadSize1); // DR-20
    memcpy((uint32_t *) & Cla1funcsRunStart2, (uint32_t *) & Cla1funcsLoadStart2, (uint32_t) & Cla1funcsLoadSize2); // DR-20
    #endif //_FLASH
    // Initialize and wait for CLA1ToCPUMsgRAM
    MemCfgRegs.MSGxINIT.bit.INIT_CLA1TOCPU = 1;

    while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU != 1)
    {
    };

    // Initialize and wait for CPUToCLA1MsgRAM
    MemCfgRegs.MSGxINIT.bit.INIT_CPUTOCLA1 = 1;

    while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1 != 1)
    {
    };

    // Select LSxRAM to be the programming space for the CLA
    // First configure the CLA to be the master for LSx and then
    // set the space to be a program block
    MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1; //RAMLS2
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 1;
    MemCfgRegs.LSxMSEL.bit.MSEL_LS3 = 1; //RAMLS3
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS3 = 1;
    MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1; //RAMLS4
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1;

    // Next configure LSxRAM as data spaces for the CLA
    // First configure the CLA to be the master for LSx and then
    // set the spaces to be code blocks
    MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1; //RAMLS0
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0;
    MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1; //RAMLS1
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0;

    EDIS;
    }

    -> If it crossed into another RAM block then that block needs to be configured for use by the CLA. That would be the second thing to check.
    Not any function is crossing into another RAM block. All used blocks are configured as shown above.


    -> If the code is running in valid, configured, CLA memory. Next thing to check is stepping through the CLA code - can you tell if it is reads not happening properly or writes? That would help us to understand if it is the data memory causing a problem instead of the program memory.
    Can you guide me how to check read and write of CLA code?

    -> in Previous reply i have send all files related to CLA1 configuration, can you guide after reviewing those files?

    -> One more thing is that take a look at portion of disassembly code of CLA1 function,
    here you can see ITRAP0 instruction encountered at regular instances. Can this make trouble in executing code?
    009000: 0000 ITRAP0
    009001: 7840 MOV *-SP[0], AR0
    009002: 872A MOVL XT, @0x2a
    009003: 74C0 SUB *+XAR0[0], AL
    24 CPU_and_CLA.R_pr[0].xn2 = CPU_and_CLA.R_pr[0].xn1;
    009004: 84EC7400 XMAC P, *+XAR4[5], *(0x7400)
    25 CPU_and_CLA.R_pr[0].xn1 = CPU_and_CLA.R_pr[0].xn0;
    009006: 84EA7400 XMAC P, *+XAR2[5], *(0x7400)
    26 CPU_and_CLA.R_pr[0].xn0 = CPU_and_CLA.Rin_pr;
    009008: 844C73C0 XMAC P, *-SP[12], *(0x73c0)
    00900a: 84EA74C0 XMAC P, *+XAR2[5], *(0x74c0)
    27 CPU_and_CLA.R_pr[0].yn2 = CPU_and_CLA.R_pr[0].yn1;
    00900c: 84E67400 XMAC P, *+XAR6[4], *(0x7400)
    28 CPU_and_CLA.R_pr[0].yn1 = CPU_and_CLA.R_pr[0].yn0;
    00900e: 84E47400 XMAC P, *+XAR4[4], *(0x7400)
    29 CPU_and_CLA.R_pr[0].yn0 = ((CPU_and_CLA.a0[0] * (CPU_and_CLA.R_pr[0].xn0 - CPU_and_CLA.R_pr[0].xn2))
    009010: 84A473C0 XMAC P, @AR4, *(0x73c0)
    009012: 84E673D0 XMAC P, *+XAR6[4], *(0x73d0)
    009014: 84EA73E0 XMAC P, *+XAR2[5], *(0x73e0)
    009016: 84EE0110 XMAC P, *+XAR6[5], *(0x0110)
    009018: 84642690 XMAC P, *-SP[36], *(0x2690)
    00901a: 0019 INTR INT10
    00901b: 7C00 MOV @0x0, AR4
    00901c: 84C42180 XMAC P, *+XAR4[0], *(0x2180)
    00901e: 84E873D0 XMAC P, *+XAR0[5], *(0x73d0)
    009020: 0004 PUSH RPC
    009021: 7C00 MOV @0x0, AR4
    009022: 84842210 XMAC P, *XAR4++, *(0x2210)
    009024: 0004 PUSH RPC
    009025: 7C00 MOV @0x0, AR4
    009026: 84E474C0 XMAC P, *+XAR4[4], *(0x74c0)
    009028: 0000 ITRAP0
    009029: 7FA0 MOV @AR0, AR7
    00902a: 0000 ITRAP0
    00902b: 7FA0 MOV @AR0, AR7
    32 total_R = total_R + CPU_and_CLA.R_pr[0].yn0;
    00902c: 872A MOVL XT, @0x2a
    00902d: 73C0 ADD *+XAR0[0], AH
    00902e: 84E473D0 XMAC P, *+XAR4[4], *(0x73d0)
    009030: 0004 PUSH RPC
    009031: 7C20 MOV @0x20, AR4
    009032: 872A MOVL XT, @0x2a
    009033: 74C0 SUB *+XAR0[0], AL
    34 CPU_and_CLA.R_pr[1].xn2 = CPU_and_CLA.R_pr[1].xn1;
    009034: 84F87400 XMAC P, *+XAR0[7], *(0x7400)
    35 CPU_and_CLA.R_pr[1].xn1 = CPU_and_CLA.R_pr[1].xn0;
    009036: 84F67400 XMAC P, *+XAR6[6], *(0x7400)
    36 CPU_and_CLA.R_pr[1].xn0 = CPU_and_CLA.Rin_pr;
    009038: 844C73C0 XMAC P, *-SP[12], *(0x73c0)
    00903a: 84F674C0 XMAC P, *+XAR6[6], *(0x74c0)
    37 CPU_and_CLA.R_pr[1].yn2 = CPU_and_CLA.R_pr[1].yn1;
    00903c: 84F27400 XMAC P, *+XAR2[6], *(0x7400)
    38 CPU_and_CLA.R_pr[1].yn1 = CPU_and_CLA.R_pr[1].yn0;
    00903e: 84F07400 XMAC P, *+XAR0[6], *(0x7400)

  • Amtech said:
     Can you guide me how to check read and write of CLA code?

    Amtech,

    We have a CLA workshop which includes a debug section.  Refer to the 'getting started', "workshops" section of the CLA Software Developers guide:

    https://software-dl.ti.com/C2000/docs/cla_software_dev_guide/getting_started.html

    The guide also includes a number of FAQs and debug tips for the CLA.

    Amtech said:
    -> One more thing is that take a look at portion of disassembly code of CLA1 function,
    here you can see ITRAP0 instruction encountered at regular instances. Can this make trouble in executing code?

    Code Composer Studio thinks you are looking at C28x disassembly.  These are all opcodes for C28x.  In the CCS Debug window, first click on the CPU1_CLA1 core, right click and select "connect target".  Now CCS will know you are looking at the CLA environment and then view the disassembly.    This is described in the workshop I mentioned previously.

    Regards

    Lori

  • ello,

    Still the issue is pending.

    During Debugging CLA1 code i observer one thing. I have used RAMLS2, RAMLS3 and RAMLS4 as CLA program memroy and allocated CLA function to these memory as shown below.

    extern uint32_t Cla1funcsRunStart, Cla1funcsLoadStart, Cla1funcsLoadSize;
    extern uint32_t Cla1funcsRunStart1, Cla1funcsLoadStart1, Cla1funcsLoadSize1; // DR-20
    extern uint32_t Cla1funcsRunStart2, Cla1funcsLoadStart2, Cla1funcsLoadSize2; // DR-20
    EALLOW;
    #ifdef _FLASH
    // Copy over code from FLASH to RAM
    memcpy((uint32_t *) & Cla1funcsRunStart, (uint32_t *) & Cla1funcsLoadStart, (uint32_t) & Cla1funcsLoadSize);
    memcpy((uint32_t *) & Cla1funcsRunStart1, (uint32_t *) & Cla1funcsLoadStart1, (uint32_t) & Cla1funcsLoadSize1); // DR-20
    memcpy((uint32_t *) & Cla1funcsRunStart2, (uint32_t *) & Cla1funcsLoadStart2, (uint32_t) & Cla1funcsLoadSize2); // DR-20
    #endif //_FLASH
    // Initialize and wait for CLA1ToCPUMsgRAM
    MemCfgRegs.MSGxINIT.bit.INIT_CLA1TOCPU = 1;

    while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU != 1)
    {
    };

    // Initialize and wait for CPUToCLA1MsgRAM
    MemCfgRegs.MSGxINIT.bit.INIT_CPUTOCLA1 = 1;

    while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1 != 1)
    {
    };

    // Select LSxRAM to be the programming space for the CLA
    // First configure the CLA to be the master for LSx and then
    // set the space to be a program block
    //MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1; //RAMLS2

    //MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 1;

    MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1; //RAMLS2

    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 1;

    MemCfgRegs.LSxMSEL.bit.MSEL_LS3 = 1; //RAMLS3

    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS3 = 1;

    MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1; //RAMLS4

    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1;

    // Next configure LSxRAM as data spaces for the CLA
    // First configure the CLA to be the master for LSx and then
    // set the spaces to be code blocks
    MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1; //RAMLS0

    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0;

    MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1; //RAMLS1

    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0;


    EDIS;

    As with these setting when debugging i observer in Memory Browser with memory Location of 0x9000 (RAMLS2) data get changing as shown below figure. As if this memory is configured as CLA program memory, should this happen? and what could be cause of this?

    With Regards.

    Dushyant Rana

  • Hello,

    Please use the code formatter when inserting code into a post.  It is the </> button.  It makes it a lot easier to read.  In general, however, I will not be able to read through lots of code trying to determine if there is a mistake.

    Amtech said:
    As with these setting when debugging i observer in Memory Browser with memory Location of 0x9000 (RAMLS2) data get changing as shown below figure. As if this memory is configured as CLA program memory, should this happen? and what could be cause of this?

    The best way to check what is assigned to this memory region is to examine the .map file generated by the linker for anything you do not expect to be allocated to this memory.  This file shows every symbol and where it is allocated in memory.   If it is only CLA program then it should only be modified when the C28x is initializing it.

    Note: due to the Holidays in the US next week, my responses will be delayed to the first week of December. 

  • Hello,

    I am using compiler Version 18.1.1 LTS.

    I have studied compiler defects CODEGEN-3676 from below link, 

    http://software-dl.ti.com/codegen/esd/cgt_public_sw/C2000/18.1.1.LTS/Closed_defects.html

    I am facing same issue described in compiler defect. 

    In below code, last line of equation is executed before actual value is being copied to memory.

     CPU_and_CLA.R_pr[1].xn2 = CPU_and_CLA.R_pr[1].xn1;
     CPU_and_CLA.R_pr[1].xn1 = CPU_and_CLA.R_pr[1].xn0;
     CPU_and_CLA.R_pr[1].xn0 = CPU_and_CLA.Rin_pr;
      CPU_and_CLA.R_pr[1].yn2 = CPU_and_CLA.R_pr[1].yn1;
     CPU_and_CLA.R_pr[1].yn1 = CPU_and_CLA.R_pr[1].yn0;
     CPU_and_CLA.R_pr[1].yn0 = ((CPU_and_CLA.a0[1] * (CPU_and_CLA.R_pr[1].xn0 - CPU_and_CLA.R_pr[1].xn2))
      - (CPU_and_CLA.b1[1] * CPU_and_CLA.R_pr[1].yn1) - (CPU_and_CLA.b2[1] * CPU_and_CLA.R_pr[1].yn2)) * CPU_and_CLA.b0[1];
    

    After putting single NOP instruction as shown in below code, Last line of equation is working properly.

     CPU_and_CLA.R_pr[1].xn2 = CPU_and_CLA.R_pr[1].xn1;
     CPU_and_CLA.R_pr[1].xn1 = CPU_and_CLA.R_pr[1].xn0;
     CPU_and_CLA.R_pr[1].xn0 = CPU_and_CLA.Rin_pr;
     CPU_and_CLA.R_pr[1].yn2 = CPU_and_CLA.R_pr[1].yn1;
     CPU_and_CLA.R_pr[1].yn1 = CPU_and_CLA.R_pr[1].yn0;
     __mnop(); __mnop(); __mnop();
     CPU_and_CLA.R_pr[1].yn0 = ((CPU_and_CLA.a0[1] * (CPU_and_CLA.R_pr[1].xn0 - CPU_and_CLA.R_pr[1].xn2))
      - (CPU_and_CLA.b1[1] * CPU_and_CLA.R_pr[1].yn1) - (CPU_and_CLA.b2[1] * CPU_and_CLA.R_pr[1].yn2)) * CPU_and_CLA.b0[1];

    But i have use three NOP instruction as suggested by you in one of the past technical forum as shown in following link.

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/355184#pi320995=1

    Thanks,

    Dushyant Rana

  • Thank you for the additional details, Dushyant.  Due to the Thanksgiving Holiday I will look at this closer after Dec 1st. 

    Regards

    Lori

  • Dushyant,

    Let me check with our compiler team and get back to you.  

    Regards

    Lori

  • Dushyant,

    Without assembly, it's difficult to determine what is doing on.

    However, if your disassembly has use of MMOVD32 instructions, then you may be encountering this bug instead:

    https://sir.ext.ti.com/jira/browse/EXT_EP-9923

    Unfortunately there is no fix for 18.1.x.LTS release.

    Please test with 18.12.7.LTS or 20.2.3.LTS

    If the issue goes away, and your disassembly has MMOVD32 instructions, then I would expect this to be the issue instead of CODEGEN-3676

    Regards

    Greg