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.

TMS320F28335: Phase differences between two signals

Genius 9880 points
Part Number: TMS320F28335

Hi Team,

My customer is trying to use two ECAP modules for capturing two signals and they were able to capture signals. Now, they want to findthe phase difference between the two signals. Is the ECAP using the same counter for each? Is it possible? If yest, they want to want to know how to do it.

Thank you.

Regards,
May

  • Is the ECAP using the same counter for each?

    No, but they use the same system clock input so using two ECAPs with the same counter configuration will count in step.

    how to do it

    After synchronizing two or more ECAPs via the SYNCIN signal, the difference between the capture value of the ECAPs will be proportional to the phase difference.

  • Hi Team,

    Customer configured the synchronous selection registers for both ECAP are as follows.
    But still they were not able to find the correct phase difference.

    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 1;
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 0;
    ECap1Regs.ECCTL2.bit.SWSYNC = 1;

    ECap2Regs.ECCTL2.bit.SYNCO_SEL = 2;
    ECap2Regs.ECCTL2.bit.SYNCI_EN = 1;

    Thank you.

    Regards,
    May

  • Can you share full configuration of eCAP1 and eCAP2?

  • Hi Santosh,

    Please see code below.

    code(1).txt
    //###########################################################################
    //
    // FILE:   Example_2833xEPwmUpAQ.c
    //
    // TITLE:  ePWM Action Qualifier Module using Upcount mode Example
    //
    //! \addtogroup f2833x_example_list
    //! <h1>ePWM Action Qualifier Module using Upcount mode (epwm_up_aq)</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 to produce a waveform with
    //! independent modulation on EPWMxA and EPWMxB. The compare values CMPA
    //! and CMPB are modified within the ePWM's ISR. The TB counter is in upmode.
    //!
    //! Monitor the ePWM1 - ePWM3 pins on an oscilloscope.
    //!
    //! \b External \b Connections \n
    //!  - EPWM1A is on GPIO0
    //!  - EPWM1B is on GPIO1
    //!  - EPWM2A is on GPIO2
    //!  - EPWM2B is on GPIO3
    //!  - EPWM3A is on GPIO4
    //!  - EPWM3B is on GPIO5
    //
    //###########################################################################
    // $TI Release: F2833x Support Library v2.00.00.00 $
    // $Release Date: Tue Jun 26 03:14:14 CDT 2018 $
    // $Copyright:
    // Copyright (C) 2009-2018 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    void InitEPwm1Example(void);
    void Gpio_setup1(void);
    void InitECapture(void);
    __interrupt void ecap1_isr(void);
    __interrupt void ecap2_isr(void);
    
    Uint32 TSt1, TSt2, TSt3, TSt4;
    Uint32 Period1, DutyOnTime1, DutyOffTime1;
    
    Uint32 TSt11, TSt21, TSt31, TSt41, theta;
    Uint32 Period11, DutyOnTime11, DutyOffTime11;
    
    Uint16 tbpr=750,phs=750/2;
    
    void main(void)
    {
        // Step 1. Initialize System Control:
        // PLL, WatchDog, enable Peripheral Clocks
        // This example function is found in the DSP2833x_SysCtrl.c file.
           InitSysCtrl();
    
        // Step 2. Initialize GPIO:
        // This example function is found in the DSP2833x_Gpio.c file and
        // illustrates how to set the GPIO to it's default state.
        // InitGpio();  // Skipped for this example
    
           Gpio_setup1();
           InitEPwm1Example();
           InitECap();
           InitECapture();
    
        // Step 3. Clear all interrupts and initialize PIE vector table:
        // Disable CPU interrupts
           DINT;
    
        // Initialize the PIE control registers to their default state.
        // The default state is all PIE interrupts disabled and flags
        // are cleared.
        // This function is found in the DSP2833x_PieCtrl.c file.
           InitPieCtrl();
    
        // Disable CPU interrupts and clear all CPU interrupt flags:
           IER = 0x0000;
           IFR = 0x0000;
    
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        // This will populate the entire table, even if the interrupt
        // is not used in this example.  This is useful for debug purposes.
        // The shell ISR routines are found in DSP2833x_DefaultIsr.c.
        // This function is found in DSP2833x_PieVect.c.
           InitPieVectTable();
    
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
           EALLOW;  // This is needed to write to EALLOW protected registers
           PieVectTable.ECAP1_INT = &ecap1_isr;
           PieVectTable.ECAP2_INT= &ecap2_isr;
           EDIS;    // This is needed to disable write to EALLOW protected registers
    
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in DSP2833x_InitPeripherals.c
        // InitPeripherals();  // Not required for this example
          // InitEPwmTimer();    // For this example, only initialize the ePWM Timers
          // InitECapture();
    
        // Step 5. User specific code, enable interrupts:
    
        // Initialize counters:
    
        // Enable CPU INT4 which is connected to ECAP1-4 INT:
           IER |= M_INT4;
    
        // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
           PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
           PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
    
        // Enable global Interrupts and higher priority real-time debug events:
           EINT;   // Enable Global interrupt INTM
           ERTM;   // Enable Global realtime interrupt DBGM
    
        // Step 6. IDLE loop. Just sit and loop forever (optional):
           for(;;)
           {
               __asm("          NOP");
           }
    }
    
    //
    // epwm1_isr -
    //
    
    //
    
    
    
    void Gpio_setup1(void){
        EALLOW;
        GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;   // Enable pullup on GPIO0
        GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;   // Enable pullup on GPIO1
    
        GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;  // GPIO0 = PWM1A
        GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;  // GPIO1 = PWM1B
        GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  // GPIO1 = PWM2A
        GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;  // GPIO1 = PWM2B
        GpioCtrlRegs.GPAMUX2.bit.GPIO24=1; // GPIO24= ECAP1;
        GpioCtrlRegs.GPADIR.bit.GPIO25=0;
        GpioCtrlRegs.GPAMUX2.bit.GPIO25=1; // GPIO24= ECAP2;
    
        EDIS;
    }
    void InitEPwm1Example()
    {
        //
        // Setup TBCLK
        //
        EPwm1Regs.TBCTL.bit.CTRMODE = 2; // Count up down
        EPwm1Regs.TBPRD = tbpr;       // Set timer period
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
        EPwm1Regs.TBPHS.half.TBPHS = 0x0000;       // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 000;   // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = 000;
        EPwm1Regs.TBCTL.bit.SYNCOSEL=1;
        EPwm1Regs.CMPA.half.CMPA =tbpr/2;    // Set compare A value
        EPwm1Regs.CMPB = tbpr/2;              // Set Compare B value
        EPwm1Regs.DBCTL.bit.OUT_MODE=3;
        EPwm1Regs.DBCTL.bit.POLSEL=2;
        EPwm1Regs.DBCTL.bit.IN_MODE=0;
        EPwm1Regs.DBRED=20;
        EPwm1Regs.DBFED=20;
        EPwm1Regs.AQCTLA.bit.CAU=2;    // Set PWM1A on Zero
        EPwm1Regs.AQCTLA.bit.CAD=1;
        EPwm1Regs.AQCTLB.bit.CBU=2;
        EPwm1Regs.AQCTLB.bit.CBD=1;
    
        EPwm2Regs.TBCTL.bit.CTRMODE = 2; // Count up down
        EPwm2Regs.TBPRD = tbpr;       // Set timer period
        EPwm2Regs.TBCTL.bit.PHSEN = 1;    // Disable phase loading
        EPwm2Regs.TBPHS.half.TBPHS = phs;       // Phase is 0
        EPwm2Regs.TBCTL.bit.PHSDIR=0;
        EPwm2Regs.TBCTR = 0x0000;                  // Clear counter
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = 000;   // Clock ratio to SYSCLKOUT
        EPwm2Regs.TBCTL.bit.CLKDIV = 000;
        EPwm2Regs.TBCTL.bit.SYNCOSEL=0;
        EPwm2Regs.CMPA.half.CMPA =tbpr/2;    // Set compare A value
        EPwm2Regs.CMPB = tbpr/2;              // Set Compare B value
        EPwm2Regs.DBCTL.bit.OUT_MODE=3;
        EPwm2Regs.DBCTL.bit.POLSEL=2;
        EPwm2Regs.DBCTL.bit.IN_MODE=0;
        EPwm2Regs.DBRED=20;
        EPwm2Regs.DBFED=20;
        EPwm2Regs.AQCTLA.bit.CAU=2;    // Set PWM1A on Zero
        EPwm2Regs.AQCTLA.bit.CAD=1;
        EPwm2Regs.AQCTLB.bit.CBU=2;
        EPwm2Regs.AQCTLB.bit.CBD=1;
    
    }
    
    void InitECapture()
    {
        // Initialization Time
        //=======================
        // ECAP module 1 config
    
        ECap1Regs.ECCTL1.bit.CAP1POL = 0;
        ECap1Regs.ECCTL1.bit.CAP2POL = 1;
        ECap1Regs.ECCTL1.bit.CAP3POL = 0;
        ECap1Regs.ECCTL1.bit.CAP4POL = 1;
        ECap1Regs.ECCTL1.bit.CTRRST1 = 0;
        ECap1Regs.ECCTL1.bit.CTRRST2 = 0;
        ECap1Regs.ECCTL1.bit.CTRRST3 = 0;
        ECap1Regs.ECCTL1.bit.CTRRST4 = 0;
        ECap1Regs.ECCTL1.bit.CAPLDEN = 1;
        ECap1Regs.ECCTL1.bit.PRESCALE = 0;
        ECap1Regs.ECCTL2.bit.CAP_APWM = 0;
        ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0;
        ECap1Regs.ECCTL2.bit.SYNCO_SEL = 1;
        ECap1Regs.ECCTL2.bit.SYNCI_EN = 0;
        ECap1Regs.ECCTL2.bit.SWSYNC = 1;
    
        ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
        ECap1Regs.ECCTL2.bit.REARM = 1;            // arm one-shot
        ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
        ECap1Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt
    
        ECap2Regs.ECCTL1.bit.CAP1POL = 0;
        ECap2Regs.ECCTL1.bit.CAP2POL = 1;
        ECap2Regs.ECCTL1.bit.CAP3POL = 0;
        ECap2Regs.ECCTL1.bit.CAP4POL = 1;
        ECap2Regs.ECCTL1.bit.CTRRST1 = 0;
        ECap2Regs.ECCTL1.bit.CTRRST2 = 0;
        ECap2Regs.ECCTL1.bit.CTRRST3 = 0;
        ECap2Regs.ECCTL1.bit.CTRRST4 = 0;
        ECap2Regs.ECCTL1.bit.CAPLDEN = 1;
        ECap2Regs.ECCTL1.bit.PRESCALE = 0;
        ECap2Regs.ECCTL2.bit.CAP_APWM = 0;
        ECap2Regs.ECCTL2.bit.CONT_ONESHT = 0;
        ECap2Regs.ECCTL2.bit.SYNCO_SEL = 2;
        ECap2Regs.ECCTL2.bit.SYNCI_EN = 1;
    
        ECap2Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
        ECap2Regs.ECCTL2.bit.REARM = 1;            // arm one-shot
        ECap2Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
        ECap2Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt
    
    
    }
    __interrupt void ecap1_isr(void)
    {
        EPwm1Regs.TBPRD = tbpr;       // Set timer period
        EPwm1Regs.CMPA.half.CMPA =tbpr/2;    // Set compare A value
        EPwm1Regs.CMPB = tbpr/2;              // Set Compare B value
    
        EPwm2Regs.TBPRD = tbpr;       // Set timer period
        EPwm2Regs.CMPA.half.CMPA =tbpr/2;    // Set compare A value
        EPwm2Regs.CMPB = tbpr/2;              // Set Compare B value
    
        EPwm2Regs.TBPHS.half.TBPHS = phs;       // Phase is 0
    
        TSt1 = ECap1Regs.CAP1; // Fetch Time-Stamp captured at t1
        TSt2 = ECap1Regs.CAP2; // Fetch Time-Stamp captured at t2
        TSt3 = ECap1Regs.CAP3; // Fetch Time-Stamp captured at t3
        TSt4 = ECap1Regs.CAP4; // Fetch Time-Stamp captured at t4
        Period1 = TSt3-TSt1; // Calculate 1st period
        DutyOnTime1 = TSt2-TSt1; // Calculate On time
        DutyOffTime1 = TSt3-TSt2; // Calculate Off time
    
       ECap1Regs.ECCLR.bit.CEVT4 = 1;
       ECap1Regs.ECCLR.bit.INT = 1;
       ECap1Regs.ECCTL2.bit.REARM = 1;
    
    
       // Acknowledge this interrupt to receive more interrupts from group 4
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    }
    
    __interrupt void ecap2_isr(void)
    {
    
        TSt11 = ECap2Regs.CAP1; // Fetch Time-Stamp captured at t1
        TSt21 = ECap2Regs.CAP2; // Fetch Time-Stamp captured at t2
        TSt31 = ECap2Regs.CAP3; // Fetch Time-Stamp captured at t3
        TSt41 = ECap2Regs.CAP4; // Fetch Time-Stamp captured at t4
        Period11 = TSt31-TSt11; // Calculate 1st period
        DutyOnTime11 = TSt21-TSt11; // Calculate On time
        DutyOffTime11 = TSt31-TSt21; // Calculate Off time
        theta=TSt11-TSt1;
    
       ECap2Regs.ECCLR.bit.CEVT4 = 1;
       ECap2Regs.ECCLR.bit.INT = 1;
       ECap2Regs.ECCTL2.bit.REARM = 1;
    
    
       // Acknowledge this interrupt to receive more interrupts from group 4
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    }
    
    
    //
    // InitEPwm2Example -
    //
    
    //
    // End of File
    //
    
    

    Thank you.

    Regards,
    May

  • May,

    I am trying to run it on my setup. I will get back to you Monday/Tuesday.

    Thanks & Regards,

    Santosh

  • Hi Santosh,

    Thank you, we are looking forward for your feedback on this.

    Regards,
    May

  • May,

    You can use timer and two eCAP module to capture the phase difference. Start timer to eCAP1 ISR, and then stop timer at eCAP2 capture. The timer count can be used as phase difference.

    Regards,

    Santosh