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: influence of ePWM on eCAP modules

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Hello to everyone,

I´m using a LAUNCHXL-F28379D for my project. I need to use different peripherals and, between these, I´m using ePWM and eCAP.

I´m using eCAP in order to measure the frequency of a squared signal. I´m doing it using an interrupt and the eCAP module1 connected to the 11 pin.
I´m using another interrupt (with higher priority) to update ePWMs comparators values (I´m using ePWM 1A,1B,3B).
These two operations work perfectly alone but, as soon the ePWMs values start to be updated, eCAP starts measuring wrong. It seems that the problem is the updating of the ePWM 1A that affects the eCAP.

I´ve tried also with a smaller code with just eCAP and ePWM in which I´ve a single eCAP interrupt and I set the compare value of the ePWM to a fixed value in the main. I also have problems but, in that case, it seems that the eCAP doesn´t work at all.

My question is: Is there some kind of incompatibility of using both (eCAP and ePWM) at the same time? Maybe I´ve missed something in the datasheet were it´s explained.

Attached the simple code used for the only eCAP + ePWM test:

void main(void)
{
    Device_init();
    Device_initGPIO();
    Interrupt_initModule();
    Interrupt_initVectorTable();

    GPIO_setPinConfig(GPIO_11_GPIO11);
    GPIO_setDirectionMode(11, GPIO_DIR_MODE_IN);
    GPIO_setQualificationMode(11, GPIO_QUAL_ASYNC);

    Interrupt_register(INT_ECAP1, &ecap1ISR);

    initECAP();

    tbcpr_pwm=(int)((100000000/(12500))-1);
    init_PWM(tbcpr_pwm);

    cap1Count = 0U;
    cap2Count = 0U;
    cap3Count = 0U;
    cap4Count = 0U;

    Interrupt_enable(INT_ECAP1);
    EINT;
    ERTM;

    Init_SCI();

    uint16_t compA=0;
    compA=(uint16_t)(0.97*(tbcpr_pwm));
    EPWM_setCounterCompareValue(Base_PWMRete_A,Comparatore_PWMRete_A,compA);

    while(1)
    {
        if (flag>0)
        {
            freq_diff_1=(clock/(cap3Count-cap1Count));
            freq_diff_2=(clock/(cap4Count-cap2Count));
            freq_diff=(freq_diff_1+freq_diff_2)/2;

            sprintf(&stampa[0],"%g\r\n",freq_diff);
            len=strlen(&stampa[0]);
            SCI_writeCharArray(SCIA_BASE, (uint16_t*)stampa, len);

            flag=0;
        }
    }
}

void Inizializza_SCI()
{
    GPIO_setMasterCore(43, GPIO_CORE_CPU1);
    GPIO_setPinConfig(GPIO_43_SCIRXDA);
    GPIO_setDirectionMode(43, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(43, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(43, GPIO_QUAL_ASYNC);

    GPIO_setMasterCore(42, GPIO_CORE_CPU1);
    GPIO_setPinConfig(GPIO_42_SCITXDA);
    GPIO_setDirectionMode(42, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(42, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(42, GPIO_QUAL_ASYNC);

    SCI_performSoftwareReset(SCIA_BASE);

    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 |
                                                                   SCI_CONFIG_STOP_ONE |
                                                                   SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIA_BASE);
    SCI_resetRxFIFO(SCIA_BASE);
    SCI_resetTxFIFO(SCIA_BASE);

    SCI_enableInterrupt(SCIA_BASE, (SCI_INT_RXFF));
    SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXERR);

    SCI_enableFIFO(SCIA_BASE);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);
}

void initECAP()
{
    cap1Count = 0U;
    cap2Count = 0U;
    cap3Count = 0U;
    cap4Count = 0U;
    flag=0;

    ECAP_disableInterrupt(ECAP1_BASE,
                          (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                           ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                           ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                           ECAP_ISR_SOURCE_COUNTER_COMPARE));
    ECAP_clearInterrupt(ECAP1_BASE,
                        (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                         ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                         ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                         ECAP_ISR_SOURCE_COUNTER_COMPARE));

    ECAP_disableTimeStampCapture(ECAP1_BASE);

    ECAP_stopCounter(ECAP1_BASE);
    ECAP_enableCaptureMode(ECAP1_BASE);

    ECAP_setEventPrescaler(ECAP1_BASE,0);

    ECAP_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE, ECAP_EVENT_4);

    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);

    ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_4);

    XBAR_setInputPin(XBAR_INPUT7, 11);

    ECAP_enableLoadCounter(ECAP1_BASE);
    ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_DISABLED);
    ECAP_startCounter(ECAP1_BASE);
    ECAP_enableTimeStampCapture(ECAP1_BASE);
    ECAP_reArm(ECAP1_BASE);

    ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
}

void config_PWM(uint32_t pin,uint16_t period,uint32_t PIN_config,uint32_t base_PWM,
                   EPWM_CounterCompareModule Comparatore, EPWM_ActionQualifierOutputModule Comp_Qualif,
                   EPWM_ActionQualifierOutputEvent Comp_action)
{
    GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);   
    GPIO_setPinConfig(PIN_config);       

    EPWM_setTimeBasePeriod(base_PWM, period);      
    EPWM_setPhaseShift(base_PWM, 0);                 
    EPWM_setTimeBaseCounter(base_PWM, 0);             

    EPWM_setCounterCompareValue(base_PWM, Comparatore, 0);   

    EPWM_setTimeBaseCounterMode(base_PWM, EPWM_COUNTER_MODE_UP);     
    EPWM_disablePhaseShiftLoad(base_PWM);                            

    EPWM_setClockPrescaler(base_PWM,EPWM_CLOCK_DIVIDER_1,EPWM_HSCLOCK_DIVIDER_1); 

    EPWM_setCounterCompareShadowLoadMode(base_PWM,Comparatore,EPWM_COMP_LOAD_ON_CNTR_ZERO); 

    EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_LOW,Comp_action);

    EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_HIGH,EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
}

void init_PWM(uint16_t tbcpr_pwm)
{
    config_PWM(0,tbcpr_pwm,GPIO_0_EPWM1A, EPWM1_BASE,EPWM_COUNTER_COMPARE_A, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
}

__interrupt void ecap1ISR(void)
{
    cap1Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
    cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
    cap3Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
    cap4Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
    flag=1;

    ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    ECAP_clearGlobalInterrupt(ECAP1_BASE);
    ECAP_reArm(ECAP1_BASE);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}

In the code also SCI is configured in order to check the eCAP out.

(I know it´s not a good code but it´s to verify if the problem was in the bigger project code or in something in the peripherals)

Thank you in advance, Gaetano.

  • Hi Gaetano,

    There's no restriction in terms of using both EPWM and ECAP simultaneously. Infact, we do have a C2000Ware example showcasing the usage as you highlighted in your initial description. I am unable to see the code where you're updating the EPWM compare values.

    For a standalone execution, you can try generating a normal PWM with constant duty cycle fed to the ECAP module. For reference, you can use the C2000Ware_XX\driverlib\f2837xd\examples\cpu1\ecap -- example 2.

    Thanks,

    Aditya

  • Hi Aditya,

    Thanks for your reply.

    I know the example, I´ve started from it in order to understand the eCAP.

    What I´m trying to do with the simple code I´ve posted is a standalone execution but with no-interactions between ePWM and eCAP. That´s why I´m using an external squared signal for the eCAP. In that way I´m reproducing what I´m doing in the project code and keeping the peripherals separated.

    I´ve modified it in order to be more similar to my project then to the example. There is a brief explaination:

    - 4 kinds of peripherals initialized: SCI, Timer, eCAP, ePWM;
    eCAP init function (on pin11):

    void initECAP()
    {
        ECAP_disableInterrupt(ECAP1_BASE,
                              (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                               ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                               ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                               ECAP_ISR_SOURCE_COUNTER_COMPARE));
        ECAP_clearInterrupt(ECAP1_BASE,
                            (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                             ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                             ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                             ECAP_ISR_SOURCE_COUNTER_COMPARE));
    
        ECAP_disableTimeStampCapture(ECAP1_BASE);
    
        ECAP_stopCounter(ECAP1_BASE);
        ECAP_enableCaptureMode(ECAP1_BASE);
    
        ECAP_setEventPrescaler(ECAP1_BASE,0);
    
        ECAP_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE, ECAP_EVENT_4);
    
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);
    
        ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_4);
    
        XBAR_setInputPin(XBAR_INPUT7, 11);
    
        ECAP_enableLoadCounter(ECAP1_BASE);
        ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_DISABLED);
        ECAP_startCounter(ECAP1_BASE);
        ECAP_enableTimeStampCapture(ECAP1_BASE);
        ECAP_reArm(ECAP1_BASE);
    
        ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    }

    ePWM init functions (3 ePWM initialized in order to check if the problem is on all ePWM or just on 1A):
    void init_PWM(uint16_t tbcpr_pwm)
    {
        config_PWM(0,tbcpr_pwm,GPIO_0_EPWM1A, EPWM1_BASE,EPWM_COUNTER_COMPARE_A, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        config_PWM(1,tbcpr_pwm,GPIO_1_EPWM1B, EPWM1_BASE,EPWM_COUNTER_COMPARE_B, EPWM_AQ_OUTPUT_B,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        config_PWM(4,tbcpr_pwm,GPIO_4_EPWM3A, EPWM3_BASE,EPWM_COUNTER_COMPARE_A, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    }
    
    void config_PWM(uint32_t pin,uint16_t period,uint32_t PIN_config,uint32_t base_PWM,
                       EPWM_CounterCompareModule Comparatore, EPWM_ActionQualifierOutputModule Comp_Qualif,
                       EPWM_ActionQualifierOutputEvent Comp_action)
    {
        GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(PIN_config);
    
        EPWM_setTimeBasePeriod(base_PWM, period);
        EPWM_setPhaseShift(base_PWM, 0);
        EPWM_setTimeBaseCounter(base_PWM, 0);
    
        EPWM_setCounterCompareValue(base_PWM, Comparatore, 0);
    
        EPWM_setTimeBaseCounterMode(base_PWM, EPWM_COUNTER_MODE_UP);
        EPWM_disablePhaseShiftLoad(base_PWM);
    
        EPWM_setClockPrescaler(base_PWM,EPWM_CLOCK_DIVIDER_1,EPWM_HSCLOCK_DIVIDER_1);
    
        EPWM_setCounterCompareShadowLoadMode(base_PWM,Comparatore,EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_LOW,Comp_action);
    
        EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_HIGH,EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    }

    - 2 Interrupts: 1 eCap interrupt in which eCap registers are read; 1 Timer Interrupt every second in which the ePWM are updated; 
    eCAP ISR:

    __interrupt void ecap1ISR(void)
    {
        cap1Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
        cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
        cap3Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
        cap4Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
        flag=1;
    
        ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
        ECAP_clearGlobalInterrupt(ECAP1_BASE);
        ECAP_reArm(ECAP1_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
    }

    Timer ISR (updating the compare value of ePWM every 1s with the same value):
    __interrupt void cpuTimer0ISR(void)
    {
        uint16_t compA=0;
        compA=(uint16_t)(0.97*(tbcpr_pwm));
        EPWM_setCounterCompareValue(EPWM1_BASE,EPWM_COUNTER_COMPARE_A,compA);
        //EPWM_setCounterCompareValue(EPWM1_BASE,EPWM_COUNTER_COMPARE_B,compA);
        //EPWM_setCounterCompareValue(EPWM3_BASE,EPWM_COUNTER_COMPARE_A,compA);
    }


    The rest of the code is similar to the first version I´ve attached.

    As you can see, in the Timer ISR, 3 ´EPWM_setCounterCompareValue´ functions are present.
    With only the functions related to the 1B and 3A uncommented the eCAP still works perfectly. When also the function related to the 1A is activated (uncommented) the eCAP starts reading random numbers.
    So I think there is some kind of interactions with ePWM 1A and eCAP that I´m missing.

    I hope I haven't been too confused in the explanation.
    Thanks for your time.
    Gaetano

  • The subject matter expert is out of office today. Please expect a response by Monday.

    Thanks.

  • Hi Gaetano,

    Sorry for the delay in response.

    Thanks for your detailed explanation. This is definitely not expected. I believe after the updates in the TimerISR, your EPWM waveform turns out to be fine as expected. At what rate is your timer being called? Can you try updating in the EPWM ISR instead of timer ISR? We can check if it is really a problem with timer ISR or is it something else?

    Anyways, this should have worked as is. Also, what are the values that you're seeing in the ECAP result registers as compared to what you were expecting?

    Thanks,

    Aditya

  • Hi Aditya,

    Don't worry about the delay, actually, thanks for the reply.

    About your questions:

    At what rate is your timer being called?

    - In my initial project at 80us (12500Hz). But, in this simple code, I´ve tried some values from 1s to 80us and I´ve the problem anyway;

    Can you try updating in the EPWM ISR instead of timer ISR? We can check if it is really a problem with timer ISR or is it something else?

    - I will try but, in the bigger project, the ISR used for the ePWM updating is the ADC1_ISR. So probably the problem will persist;

    Also, what are the values that you're seeing in the ECAP result registers as compared to what you were expecting?

    - Tomorrow I´ll be able to test again everything and I´ll do some snip to the CCS debug windows during that tests.

    I hope I´m not missing something in the eCAP initialization, that in standalone usage doesn´t create problems. Anyway, I´ll send you screenshots tomorrow.

    In the meanwhile, thanks so much and, if you have some other suggestions about what I´ve to test, please let me know. 

    Thanks,
    Gaetano

  • I hope I´m not missing something in the eCAP initialization, that in standalone usage doesn´t create problems. Anyway, I´ll send you screenshots tomorrow.

    There's no real change as compared to the standalong execution as compared to the one with EPWM. ECAP would consider both equally as any external signal coming in the module.

    Please share the details on EPWMCLK frequency vs the ECAP frequency that you've configured. Additionally, please check the PWM output as well on the analyzer, to double check the input.

  • Hi,

    Tomorrow I´ll be able to test again everything and I´ll do some snip to the CCS debug windows during that tests.

    Here some screen of the values read from the registers:
    1) When the ePWM 1A updating is commented:

    2) When the ePWM 1A updating is active (uncommented):

    Considering the cpu clock (200 MHz) the difference between cap1-cap3 and cap2-cap4 should be around 4,000,000 (because of the input squared wave is at 50 Hz). As you can see, in the second case, values are very strange: cap1 is higher then cap2 and cap3 higher then cap4.

    Please share the details on EPWMCLK frequency vs the ECAP frequency that you've configured

    About it the eCAP should be run at the cpu frequency (200 MHz) while the ePWM clock was setted using the following command:

    EPWM_setClockPrescaler(base_PWM,EPWM_CLOCK_DIVIDER_1,EPWM_HSCLOCK_DIVIDER_1);

    Additionally, please check the PWM output as well on the analyzer, to double check the input

    I´ve checked the ePWM output ith an oscilloscope and It has seemed ok. I´ve also tried to acquire some other signals but I´m not able to share it now.

    As soon as possible I´ll share also the oscilloscope screen captures. In the meanwhile, please let me know if you have some other suggestion on other possible troubleshooting tests.

    Thanks for your time,
    Gaetano

  • Hi Aditya,

    today we tried to modify something. I don´t know if could be helpful:

    - We tried all the ePWM on the boarda (from 1A to 6B) and the problem is just with the ePWM 1A;

    - We tried to modify the eCAP module. We used eCAP1, 2 and 6. No differences, still we have the problem when 1A is active;

    - We tried to use a different pin for the eCAP.  We changed from pin 11 (that could be used for ePWM 6B) to the pin 26 (that is not connected to any ePWM). We still have the same problem;

    - We´ve used two different boards, one with ePWM 1A on and the other with ePWM 1A off. In that way we checked if the ePWM has some influence over the generated wave instead of the eCAP. We connected the squared wave obtained from the first board to the second one and it works.

    So, in the end, it seems that the ePWM 1A has some kind of influence on all eCAP modules.

    Hoping these other informations could be useful. Thanks,
    Gaetano 

  • Interesting. Thanks again for the details that you've provided. I'll try running a EPWM1A with the ECAP module functionality on my side and see if I can recreate the issue.

    Couple more questions on this:

    - I believe you're using an external wired connection to connect the EPWM1A to your ECAP output. 

    - One minor enhancement, although may not be the cause behind the issue, but it'll be good to disable the PWM clock before you configure it and enable it back again. You can do that using the code:

    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    I'll be using the first code that you've shared for trying out on my side and recreate.

    Thanks,
    Aditya

  • Hi,

    Thanks for your reply.

    Regarding the external connections I´ve done this simple (and not so beautiful Joy) scheme for easly explain:

    As you can see ePWM and eCAP aren´t connected at all. The eCAP measures an external square (50 Hz).

    About the code maybe you can start from that one that is a bit less confused and in which I´ve inserted also Timer interrupt and 3 ePWM initializations:

    ecap_ex2_capture_pwm.zip

    If you prefer just the code and not the project:

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <ctype.h>
    #include "device.h"
    #include "driverlib.h"
    #include "F28x_Project.h"
    
    uint32_t cap1Count;
    uint32_t cap2Count;
    uint32_t cap3Count;
    uint32_t cap4Count;
    int flag=0;
    
    static char stampa[500];
    int len=0;
    
    double clock=200000000;
    double freq_diff_1=0;
    double freq_diff_2=0;
    double freq_diff=0;
    double f_Hz=50.00000;
    
    uint16_t tbcpr_pwm;
    
    void initECAP(void);
    void Init_SCI();
    void init_PWM(uint16_t tbcpr_pwm);
    void Init_Timer(uint32_t clockCPU);
    __interrupt void ecap1ISR(void);
    __interrupt void cpuTimer0ISR(void);
    
    void main(void)
    {
        Device_init();
        Device_initGPIO();
        Interrupt_initModule();
        Interrupt_initVectorTable();
    
        //Variables for eCAP
        uint32_t clockCPU=0;
        cap1Count = 0U;
        cap2Count = 0U;
        cap3Count = 0U;
        cap4Count = 0U;
        flag=0;
    
        //eCAP pin
        GPIO_setPinConfig(GPIO_11_GPIO11);
        GPIO_setDirectionMode(11, GPIO_DIR_MODE_IN);
        GPIO_setQualificationMode(11, GPIO_QUAL_ASYNC);
    
        //SCI init for reading output frequency
        Init_SCI();
    
        //Timer init
        clockCPU=SysCtl_getClock(10000000);
        Init_Timer(clockCPU);
    
        //eCAP init
        initECAP();
    
        //ePWM init
        tbcpr_pwm=(int)((100000000/(12500))-1);
        init_PWM(tbcpr_pwm);
    
        //Interrupts
        Interrupt_register(INT_ECAP1, &ecap1ISR);
        Interrupt_register(INT_TIMER0, &cpuTimer0ISR);
        Interrupt_enable(INT_ECAP1);
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        EINT;
        ERTM;
    
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        //Loop
        while(1)
        {
            if (flag>0)
            {
                freq_diff_1=(clock/(cap3Count-cap1Count));
                freq_diff_2=(clock/(cap4Count-cap2Count));
                freq_diff=(freq_diff_1+freq_diff_2)/2;
    
                sprintf(&stampa[0],"%g\r\n",freq_diff);
                len=strlen(&stampa[0]);
                SCI_writeCharArray(SCIA_BASE, (uint16_t*)stampa, len);
    
                flag=0;
            }
        }
    }
    
    void Init_SCI()
    {
        GPIO_setMasterCore(43, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_43_SCIRXDA);
        GPIO_setDirectionMode(43, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(43, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(43, GPIO_QUAL_ASYNC);
    
        GPIO_setMasterCore(42, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_42_SCITXDA);
        GPIO_setDirectionMode(42, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(42, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(42, GPIO_QUAL_ASYNC);
    
        SCI_performSoftwareReset(SCIA_BASE);
    
        SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 |
                                                                       SCI_CONFIG_STOP_ONE |
                                                                       SCI_CONFIG_PAR_NONE));
        SCI_resetChannels(SCIA_BASE);
        SCI_resetRxFIFO(SCIA_BASE);
        SCI_resetTxFIFO(SCIA_BASE);
    
        SCI_enableInterrupt(SCIA_BASE, (SCI_INT_RXFF));
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXERR);
    
        SCI_enableFIFO(SCIA_BASE);
        SCI_enableModule(SCIA_BASE);
        SCI_performSoftwareReset(SCIA_BASE);
    }
    
    void Init_Timer(uint32_t clockCPU)
    {
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
        CPUTimer_stopTimer(CPUTIMER0_BASE);
        CPUTimer_setPeriod(CPUTIMER0_BASE, (uint32_t)(clockCPU/1000));//1ms timer interrupt, change divider to change period
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
        CPUTimer_setEmulationMode(CPUTIMER0_BASE, CPUTIMER_EMULATIONMODE_RUNFREE);
    }
    
    void initECAP()
    {
        ECAP_disableInterrupt(ECAP1_BASE,
                              (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                               ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                               ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                               ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                               ECAP_ISR_SOURCE_COUNTER_COMPARE));
        ECAP_clearInterrupt(ECAP1_BASE,
                            (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                             ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                             ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
                             ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                             ECAP_ISR_SOURCE_COUNTER_COMPARE));
    
        ECAP_disableTimeStampCapture(ECAP1_BASE);
    
        ECAP_stopCounter(ECAP1_BASE);
        ECAP_enableCaptureMode(ECAP1_BASE);
    
        ECAP_setEventPrescaler(ECAP1_BASE,0);
    
        ECAP_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE, ECAP_EVENT_4);
    
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);
    
        ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_4);
    
        XBAR_setInputPin(XBAR_INPUT7, 11);
    
        ECAP_enableLoadCounter(ECAP1_BASE);
        ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_DISABLED);
        ECAP_startCounter(ECAP1_BASE);
        ECAP_enableTimeStampCapture(ECAP1_BASE);
        ECAP_reArm(ECAP1_BASE);
    
        ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    }
    
    void config_PWM(uint32_t pin,uint16_t period,uint32_t PIN_config,uint32_t base_PWM,
                       EPWM_CounterCompareModule Comparatore, EPWM_ActionQualifierOutputModule Comp_Qualif,
                       EPWM_ActionQualifierOutputEvent Comp_action)
    {
        GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(PIN_config);
    
        EPWM_setTimeBasePeriod(base_PWM, period);
        EPWM_setPhaseShift(base_PWM, 0);
        EPWM_setTimeBaseCounter(base_PWM, 0);
    
        EPWM_setCounterCompareValue(base_PWM, Comparatore, 0);
    
        EPWM_setTimeBaseCounterMode(base_PWM, EPWM_COUNTER_MODE_UP);
        EPWM_disablePhaseShiftLoad(base_PWM);
    
        EPWM_setClockPrescaler(base_PWM,EPWM_CLOCK_DIVIDER_1,EPWM_HSCLOCK_DIVIDER_1);
    
        EPWM_setCounterCompareShadowLoadMode(base_PWM,Comparatore,EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_LOW,Comp_action);
    
        EPWM_setActionQualifierAction(base_PWM,Comp_Qualif,EPWM_AQ_OUTPUT_HIGH,EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    }
    
    void init_PWM(uint16_t tbcpr_pwm)
    {
        //ePWM 1A,1B an 3A init
        config_PWM(0,tbcpr_pwm,GPIO_0_EPWM1A, EPWM1_BASE,EPWM_COUNTER_COMPARE_A, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        config_PWM(1,tbcpr_pwm,GPIO_1_EPWM1B, EPWM1_BASE,EPWM_COUNTER_COMPARE_B, EPWM_AQ_OUTPUT_B,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        config_PWM(4,tbcpr_pwm,GPIO_4_EPWM3A, EPWM3_BASE,EPWM_COUNTER_COMPARE_A, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    }
    
    __interrupt void cpuTimer0ISR(void)
    {
        uint16_t compA=0;
        compA=(uint16_t)(0.97*(tbcpr_pwm));
    
        /***ePWM updating (with fixed values): comment/uncomment following lines to deactive/active updating***/
    
        //EPWM_setCounterCompareValue(EPWM1_BASE,EPWM_COUNTER_COMPARE_A,compA);
        EPWM_setCounterCompareValue(EPWM1_BASE,EPWM_COUNTER_COMPARE_B,compA);
        EPWM_setCounterCompareValue(EPWM3_BASE,EPWM_COUNTER_COMPARE_A,compA);
    }
    __interrupt void ecap1ISR(void)
    {
        cap1Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
        cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
        cap3Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
        cap4Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
        flag=1;
    
        ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
        ECAP_clearGlobalInterrupt(ECAP1_BASE);
        ECAP_reArm(ECAP1_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
    }
    

    - One minor enhancement, although may not be the cause behind the issue, but it'll be good to disable the PWM clock before you configure it and enable it back again. You can do that using the code:

    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    I´ll try also this.

    Thanks again,
    Gaetano

  • Thanks for the code. Will check it and get back to you. Allow me some time to work on this.

    Aditya

  • Hi,

    Sorry for the delayed response. I was able to test the functionality normally without any errors. Were you able to resolve on your end? EPWM1 works fine with ECAP module.