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.

LAUNCHXL-F28379D: Can CLA be used to replace calculations done in EPWM1 interrupt at 180kHz?

Part Number: LAUNCHXL-F28379D


Hi,

I use EPWM1 interrupt at 180kHz for calculating CMPA values for SPWM generation.

Because of such high frequency I see occasional disturbance in SPWM waveform when I have CAN ISR processing incoming messages.

I would like to know if I can move the calculations done in EPWM ISR into some other peripheral like CLA so that the processor can be freed from such a time critical and sensitive work.

Currently I trigger EPWM ISR for TBCTR = 0 and TBCTR = PERIOD, Is it possible to have the CLA be triggered for this scenario?

Please do suggest any other solutions that might be more optimized than triggering EPWM ISR at 180kHz for updating CMPA. (I cannot use DMA as the calculations need real time input from control loops)

Regards,

Rashmitha

  • Hi Rashmitha,

    Let me assign this to a CLA expert that could help you on this topic.

    Best,

    Ryan Ma

  • Hi Rashmitha,

    Yes EPWMxINT can be configured as the trigger source for CLA Task. CLA also has write access to the EPWM registers.

    Regards,

    Veena

  • Hi ,

    Thanks for your reply, I have been able to implement it but the SPWM generated is not having the expected frequency.

    I have below lines for EPWM INT enabling. 

    EPWM_enableInterrupt(EPWM1_BASE);
    EPWM_setInterruptSource(EPWM1_BASE, EPWM_INT_TBCTR_ZERO_OR_PERIOD);
    EPWM_setInterruptEventCount(EPWM1_BASE, 1);

    And below lines for enabling CLA INT based on EPWM 1 as trigger source

        //
        // Configure the vectors for the end-of-task interrupt for all
        // 8 tasks
        //
        Interrupt_register(INT_CLA1_1, &cla1Isr1);
    
        //
        // Enable CLA interrupts at the group and subgroup levels
        //
        Interrupt_enable(INT_CLA1_1);
    
        CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM1INT);
        
    

    Other values for my EPWM generation are as below, 

    TBPRD = 1112;  
    T(TBCLK) = 1/200MHz;  
    F(PWM) = 90kHz

    Before using CLA, my output was 18kHz when measuring 5 samples. 

    Now, even though I am using EPWM1 as trigger source for CLA, the sine shape gets completed in 50 samples as shown below.

    Below is the calculation that I moved from EPWM1 ISR to CLA Task

    FLOAT32 sineTable_x1[10] = { 3.0, 8.0, 10.0, 8.0, 3.0, -3.0, -8.0, -10.0, -8.0,
                                 -3.0 };
    FLOAT32 sineTable_x2[10] = { -3.0, -8.0, -10.0, -8.0, -3.0, 3.0, 8.0, 10.0, 8.0,
                                 3.0 };
        
        
    __interrupt void Cla1Task1(void)
    {
        EPwm1Regs.CMPA.bit.CMPA = (U16) (0.5 * (1112 + 75 * sineTable_x1[index]));
        EPwm2Regs.CMPA.bit.CMPA = (U16) (0.5 * (1112 + 75 * sineTable_x2[index]));
        index = (index + 1) % 10;
    
    }

     It looks like the CLA isn't triggered for every trigger of EPWM1 INT. Please suggest what could be causing this and how it can be resolved.

    When I put an LED toggle in EPWM1 ISR and cla1Isr1(), I see that EPWM ISR's frequency is 180kHz and CLA ISR's frequency is 18kHz.

    Regards,

    Rashmitha

  • Hi Rashmitha,

    Apologies for the late reply.

    Have you tried GPIO toggle inside the Cla1Task1 function for profiling?

    In case the Task takes too long to complete, and the next trigger came in, that might get missed.

    Regards,

    Veena

  • Hi ,

    I added GPIO toggle inside Cla1Isr1(as I couldn't add it in the task), and I probed this Red LED and found that the frequency is 18kHz (where I was expecting 180kHz)

    //
    // cla1Isr1 - CLA1 ISR 1
    //
    
    __interrupt void cla1Isr1()
    {
        GPIO_togglePin(RED_LED);
        //
        // Acknowledge the end-of-task interrupt for task 1
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);
    
        //
        // Uncomment to halt debugger and stop here
        //
        //asm(" ESTOP0");
    }

    Question 1: Is there a maximum frequency limit for the CLA?

    Question 2: My CLA task it very minimal with 2 lines for calculation. Should this be scaled down further by storing all the values in an array and just using it from the array? Would that help in making the task faster? The value 75 is only an example, it ranges from 0 to 100 based on PI controller output.

    __interrupt void Cla1Task1(void)
    {
        EPwm1Regs.CMPA.bit.CMPA = (U16) (0.5 * (1112 + 75 * sineTable_x1[index]));
        EPwm2Regs.CMPA.bit.CMPA = (U16) (0.5 * (1112 + 75 * sineTable_x2[index]));
        index = (index + 1) % 10;
    
    }

    Regards,

    Rashmitha

  • Hi Rashmitha,

    GPIO can be toggled from the CLA Task as well.

    It would be good to measure the time it takes to complete this task just to be sure it is not taking longer than the next trigger.

    CLA runs at the same clock as C28x CPU.

    Regards,

    Veena

  • Hi ,

    I tried adding below lines to SET and CLEAR Gpio from within the CLA Task and the GPIO isnt toggling at all. 

    GpioDataRegs.GPASET.bit.GPIO31 = 1;
    
    GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;

    I tried to add the TI function GPIO_togglePin(31); too. 

    Is there some specific setting to enable CLA write to GPIO registers?

    Regards,

    Rashmitha

  • Hi ,

    I was able to drive the GPIO from CLA task by changing its Master Core to CPU1_CLA1 using

    GPIO_setMasterCore(31, GPIO_CORE_CPU1_CLA1);

    and I see that my computation lines are only taking 280 ns, whereas my EPWM triggers are every 5.5 us.

    But the final EPWM output is still not the way I get while using EPWM interrupts.

    I still have the EPWM 1 ISR defined just to acknowledge the event trigger and interrupt ack. I tried to move these lines to CLA Task and that runs me into some other errors.

    __interrupt void EPWM_1_ISR(void)
    {
        EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    
    }

    Edit:

    Moving those 2 lines of calculation(for CMPA values) into the CLA 1 ISR1 gives me the expected output (like how EPWM ISR gives). Any reason why CLA task and CLA ISR behaves differently? Please see the images below to see how the TASK and ISR give different outputs.

    Question: Does CLA1 ISR1 run independently/parallel to the C28x CPU?

    Output when using CLA Task:

    Output when using CLA ISR:

    Regards,

    Rashmitha

  • Hi ,

    I identified the issue.

    The problem was using % Modulo for computing the index variable inside CLA task.

     index = (index + 1) % 10;

    I changed it to a simple increment and and if loop to reset it to zero on reaching array size and it is giving the expected output.

    index++;
    
    if(index > max_size)
    {
        index = 0;
    }

    Is there an explanation for why a modulo % cannot be used in a CLA Task?

    Regards,

    Rashmitha