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.

TMS320F28379D: Multiple sequential PI Loops using CLA

Part Number: TMS320F28379D


Hi,

I would Like to implement 3 PI loops with CLA. The loops are sequential that is output of 1st loop is input to 2nd and output of 2nd is input to 3rd.

I have created 3 instances of DCL_PI_CLA and initialized all the instances with the values for each loops

Question 1:

Can I call the function "DCL_runPI_L1" 3 times in one Task? or should it be 3 different tasks Task 1, Task 2 and Task 3? I have tried both but either ways I can only see the first loop working with uk1 varying its value depending on change in rk1. uk2 and uk3 are initially zero and then directly jump to 1 (when rk1 is changed) and do not change at all after that. uk1 gradually varies and reaches 1.

uk1 = DCL_runPI_L1(&pi1, rk1, yk1);

uk2 = DCL_runPI_L1(&pi2, rk2, yk2);

uk3 = DCL_runPI_L1(&pi3, rk3, yk3);

Question 2:

I want them to run the CLA at a frequency depending on the EPWM2 module so I have the Trigger source defined as below

CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM2INT);
CLA_setTriggerSource(CLA_TASK_2, CLA_TRIGGER_EPWM2INT);
CLA_setTriggerSource(CLA_TASK_3, CLA_TRIGGER_EPWM2INT);

Is there a way to trigger 2nd loop when 1st loop is completed and similarly trigger 3rd loop when 1st loop has completed?

Question 3:

Even when CLA is computing and I can see uk1 values varying in the watch window, the debug window shows CLA is suspended. Is this how it is supposed to be? 

If I hit the RUN button I get below errors in the console

Question 4:

Is there a diagram for DCL_PI_L1 architecture alone? Some of the variables used in L1 functions code is not found in this diagram, for example i6. I am trying to find the variable that I need to assign the integrator gain which will be multiplied with the previous integrator output.

Integrator output += Gain * Previous Integrator Output

where Previous Integrator Output = Error * KI     (Error = rk - yk)

Could you point me to the variable to which I should assign this "Gain" value ? Is it i6, i10 or something else?

  

Regards,

Rashmitha

  • Hi Rashmika,

    I apologize for late reply:

    Can I call the function "DCL_runPI_L1" 3 times in one Task?

    Yes you can and this should work. You may need to debug to see why the values are not as expected. Add an mdebugstop instruction between each PI call to have the CLA stop execution so you can inspect and debug the unexpected values.

    CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM2INT);
    CLA_setTriggerSource(CLA_TASK_2, CLA_TRIGGER_EPWM2INT);
    CLA_setTriggerSource(CLA_TASK_3, CLA_TRIGGER_EPWM2INT);

    Is there a way to trigger 2nd loop when 1st loop is completed and similarly trigger 3rd loop when 1st loop has completed?

    Since all 3 loops are being triggered at same time, as per hardware precedence, since priority of task 1 > 2 > 3, task 1 should start executing while task 2 and 3 are pended and task 2 should begin execution after task 1 completes. Similarly task 3 should execute after task 2 completes. The only time this may not happen is if while task 1 is executing it is triggered and becomes pended again in which case task 1 will execute again after task 1 completes.

    Even when CLA is computing and I can see uk1 values varying in the watch window, the debug window shows CLA is suspended.

    Can you check and make sure all the LS RAMs being allocated to CLA are configured correctly in the initialization code and are allocated to CLA for program or data as defined in the the linker command file? Sounds like an LS RAM memory is not initialized as expected.

    Is there a diagram for DCL_PI_L1 architecture alone?

    I will reach out to the DCL expert and let you know.

    Thanks,

    Ashwini

  • Add an mdebugstop instruction between each PI call to have the CLA stop execution so you can inspect and debug the unexpected values.

    1. I can see the program stopping on each mdebugstop statement but the uk2 and uk3 values are not progressing from 0 to 1 like uk1 does.

    Even if I change the order of functions to call uk3 first followed by uk2 and uk1 respectively, I only see uk1 behaving as expected. Other two value jump to 1 directly as if the integrator part of PI controller gets saturated in the first iteration itself. Other problem is that uk1 returns from one to zero on negative feedback. However, that is not the case with uk2 and uk3; once they reach one they never decrement, and are stuck at 1.

    2. As I step through _DCL_runPI_L1 I see in the registers window that MR0, MR1, MR2 are not getting updated at all. Is there an enable statement that blocks these register writes separately? MAR0 and MPC seems to be working fine.

      

    CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM2INT);
    CLA_setTriggerSource(CLA_TASK_2, CLA_TRIGGER_EPWM2INT);
    CLA_setTriggerSource(CLA_TASK_3, CLA_TRIGGER_EPWM2INT);

    3. Could you suggest an alternative to these lines? I would like to trigger task1 with trigger source as EPWM2 INT but for TASK 2 & 3 I would like to mention completion of prior task as the trigger source.

    Can you check and make sure all the LS RAMs being allocated to CLA are configured correctly in the initialization code

    4. Below are the lines in my configClaMemory() function configuring LS4_5 and LS 0 & 1 and I am using 2837xD_FLASH_CLA_lnk_cpu1.cmd C2000 provided CMD file with some additions for missing sector names.

    //
    // Initialize and wait for CLA1ToCPUMsgRAM
    //
    MemCfg_initSections(MEMCFG_SECT_MSGCLA1TOCPU);
    while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCLA1TOCPU))
    {
    }

    //
    // Initialize and wait for CPUToCLA1MsgRAM
    //
    MemCfg_initSections(MEMCFG_SECT_MSGCPUTOCLA1);
    while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCPUTOCLA1))
    {
    }

    //
    // Select LS4RAM to be the programming space for the CLA
    // First configure the CLA to be the master for LS4 and then
    // set the space to be a program block
    //
    MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS4, MEMCFG_LSRAMMASTER_CPU_CLA1);
    MemCfg_setCLAMemType(MEMCFG_SECT_LS4, MEMCFG_CLA_MEM_PROGRAM);
    MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS5, MEMCFG_LSRAMMASTER_CPU_CLA1);
    MemCfg_setCLAMemType(MEMCFG_SECT_LS5, MEMCFG_CLA_MEM_PROGRAM);

    //
    // Next configure LS0RAM and LS1RAM as data spaces for the CLA
    // First configure the CLA to be the master for LS0(1) and then
    // set the spaces to be code blocks
    //
    MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS0, MEMCFG_LSRAMMASTER_CPU_CLA1);
    MemCfg_setCLAMemType(MEMCFG_SECT_LS0, MEMCFG_CLA_MEM_DATA);

    MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS1, MEMCFG_LSRAMMASTER_CPU_CLA1);
    MemCfg_setCLAMemType(MEMCFG_SECT_LS1, MEMCFG_CLA_MEM_DATA);

    I will reach out to the DCL expert and let you know.

    Sure, thanks!

    Regards,

    Rashmitha

  • Rashmitha,

    For question 4 - Figure 9 in the reference guide corresponds to the DCL_PI_L1 controller, not Figure 7.

    Figure 9 matches the asm.

    Thanks,

    Sira

  • Hi ,

    Thank you for pointing me to the right figure. That helps!.

    I have two more questions about this

    Question 1:

    Could you also please confirm if DCL_PI_L4 uses Forward Euler or Backward Euler Integration? I would like to implement Forward Euler for my application.

    Question 2:

    I am trying to find the variable that I need to assign the integrator gain which will be multiplied with the previous integrator output.

    Integrator output += Gain * Previous Integrator Output

    where Previous Integrator Output = Error * KI     (Error = rk - yk)

    Could you point me to the variable to which I should assign this "Gain" value ? Is it i6, i10 or something else?

    Would you be able to help me with this GAIN variable?

    Thanks & Regards,

    Rashmitha

  • Hi Rashmitha,

    Regarding the variables not updating as expected, here are 2 possible reasons:

    1. https://software-dl.ti.com/C2000/docs/cla_software_dev_guide/debugging.html?highlight=single#why-are-the-variables-in-the-cla-code-not-updating-as-expected

    2. While single stepping on CLA (unlike C28), the pipeline moves by 1 cycle for each step. As a result, sometimes you need to perform a few extra steps till the pipeline reaches the execute/write phase and results get updated in the register and get reflected in debugger expressions window. Please can you try stepping 4-5 more times past line 44 where M1 gets loaded with memory (I assume it is some non-zero value) and see if the correct value shows up in debugger window.

    Regarding the compute,

    Can you add the input variables, pi*,rk*, yk* to expressions and confirm that when you halt in CLA task the values of these variables look correct. This way we can eliminate any possibility of the input variables being allocated to memory that is not initialized for CLA access.

    Thanks,
    Ashwini

  • Hi ,

    I have started using DCL_runPI_L4 function and with this I do see MR0-MR3 updating and I also have all 3 loops running.

    The problems now are

    1. DEBUG window still shows CLA suspended.

    2. pi*,rk*, yk* each of them say "unknown line 2: unexpected token:"

    Question 1:

    Could you also please confirm if DCL_PI_L4 uses Forward Euler or Backward Euler Integration? I would like to implement Forward Euler for my application.

    I am also awaiting response on whether PI_L4 uses Forward Euler or Backward Euler.

    Question 2:

    I am trying to find the variable that I need to assign the integrator gain which will be multiplied with the previous integrator output.

    Integrator output += Gain * Previous Integrator Output

    where Previous Integrator Output = Error * KI     (Error = rk - yk)

    Could you point me to the variable to which I should assign this "Gain" value ? Is it i6, i10 or something else?

    Would you be able to help me with this GAIN variable?

    I realized that neither i6 nor i10 can be used to assign the gain multiplier that I would like to introduce to the control loop. So I edited the DCL_runPI_L4 function to introduce the multiplier I need. I have the loops working as expected but I would like to know if there are any other issues that could arise due to editing this default CLA functions.

    Is there another way to introduce additional variables into the PI Loop ?

    Regards,

    Rashmitha

  • Hi Rashmitha,

    DEBUG window still shows CLA suspended.

    Are you seeing that the CLA is suspended even though there are no mdebugstop breakpoints embedded in task code?

    pi*,rk*, yk* each of them say "unknown line 2: unexpected token:"

    Please add the full names of the variables in expressions without the *. (I had added a * in my reply above as a placeholder for  digits 1 and 2 of the variable names)

    Thanks,

    Ashwini

  • Hi ,

    Are you seeing that the CLA is suspended even though there are no mdebugstop breakpoints embedded in task code?

    Yes, CLA shows suspended even when there are no mdebugstop or mnop lines. The PI Controllers are working fine, debug window just says ClaTask1 does not contain frame information.

    Please add the full names of the variables in expressions without the *.

    I can see the variables updating in Expressions window

    I would also like to confirm if the __mnop() instruction is required/mandatory. I have removed them and the code seems to be working fine.

    Regards,

    Rashmitha

  • Rashmitha, please give me a day to look into the 2 questions you had for me.

    Thanks, Sira

  • Hi ,

    Thanks for getting back! Sure, please let me know when you have the answers Slight smile

    Regards,

    Rashmitha

  • Question1: I believe this is the Forward Euler implementation.

    Question2: There are only 2 gain terms, Kp and Ki, the proportional gain and the integrator gain.

    Thanks,

    Sira

  • Hi ,

    I edited the DCL_runPI_L4 function to introduce the multiplier I need. I have the loops working as expected but I would like to know if there are any other issues that could arise due to editing this default CLA functions.

    Is there another way to introduce additional variables into the PI Loop ?

    Could you comment on the above quoted question too?

    Regards,

    Rashmitha

  • I'll reply tomorrow - today is a US holiday.

    (just a request not to reply to this with an acknowledgement/OK as it will artificially modify some internal metrics we keep :)  )

    Thanks, Sira

  • Rashmitha,

    You've added the multiplication factor of 0.000025, correct? In essence, you've just changed Ki. So why not just suitably modify Ki to meet your control loop's needs.

    Thanks,

    Sira

  • Hi ,

    Yes, you are right I have only changed the multiplication factor for now. But if I do change anything else inside the function- would that have any negative impact on the way the CLA uses this function?

    The reason for asking this is, I have a another model which works on a similar PI parallel topology but for the same Kp, Ki values the response speed seems to be slower when I use the CLA, which very much contradicts the very presence of CLA as it is supposed to speed up due to independent computing, please correct me if I am wrong.

    So I would like to modify this function to replicate the same way my old model works, and that would need moving around the variables, changing order of equations and introducing intermediate variables. I would like to know if I can do such modifications to the default functions.

    Regards,

    Rashmitha 

  • Hi Rashmitha,

    1. When you say "but for the same Kp, Ki values the response speed seems to be slower when I use the CLA", you mean "slower" relative to what? If you are comparing performance against the C28x, the architectures are different (e.g. fewer registers on the CLA) so it could have an impact on performance. And if these control loops are running inside an ISR, then whether you run them on the C28x or the CLA, the independent computing aspect is there anyway. 

    2. So it seems like you want to modify DCL_runPI_L4 so that it behaves similarly as your other model. From a control loop standpoint, you can do anything you want to, since you are the designer :), but wouldn't DCL_runPI_L4 modified essentially become the same as your other model, and end up showing the same issues as (1) above? My point is, I think regardless of what you do, it is (1) above that needs to be root-caused.

    Thanks,

    Sira