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.

CCS/TMS320F28377D: eCap interupt on each capture

Part Number: TMS320F28377D

Tool/software: Code Composer Studio

Hello, 

for a project I need to use the eCap module of a TMS320F28377D to capture the pulse of Hall sensor. I have to measure the value the ecap counter at each edge changing of the sensor. Right now I manage to fire the interupt every 4 changing edge (mod4 ctr of the ecap module).

For my debug, I set the PWM3A on the GPIO19 in input. When the interrupt is fired, I toggle the GPIO16 set in output. Here is the code:

void main(void)
{
   InitSysCtrl();

   InitEPwm3Gpio();
   InitECap1Gpio(19);
   GPIO_SetupPinOptions(19, GPIO_INPUT, GPIO_ASYNC);

   GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 0);
   GPIO_SetupPinOptions(16, GPIO_OUTPUT, GPIO_PUSHPULL);

   DINT;
   InitPieCtrl();

   IER = 0x0000;
   IFR = 0x0000;

   InitPieVectTable();

   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.ECAP1_INT = &ecap1_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

   InitEPwmTimer();    // For this example, only initialize the ePWM Timers
   InitECapture();

   IER |= M_INT4;

   PieCtrlRegs.PIEIER4.bit.INTx1 = 1;

   EINT;   // Enable Global __interrupt INTM
   ERTM;   // Enable Global realtime __interrupt DBGM

   for(;;)
   {
      asm("          NOP");
   }
}

------------------------------------ Configuration eCap ----------------------------------------------

// InitECapture - Initialize ECAP1 configurations
//
void InitECapture()
{
    ECap1Regs.ECEINT.all = 0;                                    // Disable all eCAP interrupts
    ECap1Regs.ECCLR.all = 0xFFFF;                                // Clear all CAP interrupt flags
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0;                            // Disabled loading of capture results
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;                          // Stop the counter
    ECap1Regs.TSCTR = 0;                                         // Clear the counter
    ECap1Regs.CTRPHS = 0;                                        // Clear the counter phase register
    //
    // Configure peripheral registers
    //
    // Capture Control Reg 1
    ECap1Regs.ECCTL1.bit.CAP1POL = EC_RISING;           // 0   Capture Event 1 Polarity select
    ECap1Regs.ECCTL1.bit.CTRRST1 = EC_DELTA_MODE;       // 1   Counter Reset on Capture Event 1
    ECap1Regs.ECCTL1.bit.CAP2POL = EC_FALLING;          // 2   Capture Event 2 Polarity select
    ECap1Regs.ECCTL1.bit.CTRRST2 = EC_DELTA_MODE;       // 3   Counter Reset on Capture Event 2
    ECap1Regs.ECCTL1.bit.CAP3POL = EC_RISING;           // 4   Capture Event 3 Polarity select
    ECap1Regs.ECCTL1.bit.CTRRST3 = EC_DELTA_MODE;       // 5   Counter Reset on Capture Event 3
    ECap1Regs.ECCTL1.bit.CAP4POL = EC_FALLING;          // 6   Capture Event 4 Polarity select
    ECap1Regs.ECCTL1.bit.CTRRST4 = EC_DELTA_MODE;       // 7   Counter Reset on Capture Event 4
    ECap1Regs.ECCTL1.bit.CAPLDEN = EC_ENABLE;           // 8   Enable Loading CAP1-4 regs on a Cap Event
    ECap1Regs.ECCTL1.bit.PRESCALE = EC_DIV1;            // 13:9 Event Filter prescale select - Divide by 1
    ECap1Regs.ECCTL1.bit.FREE_SOFT = 0b10;              // 15:14   Emulation mode - Run Free

    // Capture Control Reg 2
    ECap1Regs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS;       // 0   Continuous or one-shot - Continuous
    ECap1Regs.ECCTL2.bit.STOP_WRAP = 0b11;                  // 2:1 "Stop value for one-shot, Wrap for continuous", Wrap after Capture Event 4
    ECap1Regs.ECCTL2.bit.REARM = 1;                         // 3   One-shot re-arm
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN;                // 4   TSCNT counter start
    ECap1Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE;              // 5   Counter sync-in select
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCIN;             // 7:6 Sync-out mode
    ECap1Regs.ECCTL2.bit.SWSYNC = 1;                        // 8   SW forced counter sync
    ECap1Regs.ECCTL2.bit.CAP_APWM = EC_CAP_MODE;            // 9   CAP/APWM operating mode select
    ECap1Regs.ECCTL2.bit.APWMPOL = 0;                       // 10   APWM output polarity select

    // ECAP interrupt enable
    ECap1Regs.ECEINT.bit.CEVT1 = 0;           // 1   Capture Event 1 Interrupt Enable
    ECap1Regs.ECEINT.bit.CEVT2 = 0;           // 2   Capture Event 2 Interrupt Enable
    ECap1Regs.ECEINT.bit.CEVT3 = 0;           // 3   Capture Event 3 Interrupt Enable
    ECap1Regs.ECEINT.bit.CEVT4 = 1;           // 4   Capture Event 4 Interrupt Enable
    ECap1Regs.ECEINT.bit.CTROVF = 0;          // 5   Counter Overflow Interrupt Enable
    ECap1Regs.ECEINT.bit.CTR_EQ_PRD = 0;      // 6   Period Equal Interrupt Enable
    ECap1Regs.ECEINT.bit.CTR_EQ_CMP = 0;      // 7   Compare Equal Interrupt Enable

    // ECAP interrupt clear
    ECap1Regs.ECCLR.bit.INT = 1;             // 0   Global Flag
    ECap1Regs.ECCLR.bit.CEVT1 = 1;           // 1   Capture Event 1 Interrupt Flag
    ECap1Regs.ECCLR.bit.CEVT2 = 1;           // 2   Capture Event 2 Interrupt Flag
    ECap1Regs.ECCLR.bit.CEVT3 = 1;           // 3   Capture Event 3 Interrupt Flag
    ECap1Regs.ECCLR.bit.CEVT4 = 1;           // 4   Capture Event 4 Interrupt Flag
    ECap1Regs.ECCLR.bit.CTROVF = 1;          // 5   Counter Overflow Interrupt Flag
    ECap1Regs.ECCLR.bit.CTR_PRD = 1;         // 6   Period Equal Interrupt Flag


}

----------------------------- eCap Esr----------------------------------

__interrupt void ecap1_isr(void)
{
    // Capture Control Reg 1

   GpioDataRegs.GPATOGGLE.bit.GPIO16 = 1 ;


   ECap1Regs.ECCLR.bit.CEVT4 = 1;
   ECap1Regs.ECCLR.bit.INT = 1;
   ECap1Regs.ECCTL2.bit.REARM = 1;

}

I get this profile: 

PWM : Signal PWM set on GPIO 19 in input of the eCap

ECAP1 : GPIO16 toggle every time the IT is fired

When I want an interruption for each edge, the trouble begins. 

I tested several combinations: 

Just using the capture 1 and an interruption on capture 1

Using the 4 captures with an interuption on the 4 capture:

ECap1Regs.ECEINT.bit.CEVT1 = 1;           // 1   Capture Event 1 Interrupt Enable
 ECap1Regs.ECEINT.bit.CEVT2 = 1;           // 2   Capture Event 2 Interrupt Enable
 ECap1Regs.ECEINT.bit.CEVT3 = 1;           // 3   Capture Event 3 Interrupt Enable
 ECap1Regs.ECEINT.bit.CEVT4 = 1;           // 4   Capture Event 4 Interrupt Enable

For every tests I measure the same reaction :

I don't know why the ITis fired this often. The frequency changes sometimes depending on the set up of the registers.

First, is it possible to have an IT on each changing edge on the signal set on the eCap ?
If it's possible, I would like to know how to configure the register to solve this problem.

Thanks for your help,
Clément

  • Hi Clément,

    A few comments:
    1) You should comment out the instruction to rearm the eCAP within the interrupt.  I don't believe this is what you want anymore, and I feel it may be a contributor to what you are seeing.  It's also not really needed when using continuous mode anyway.
    2) I don't think it should cause any issue, but I might recommend disable phase synch (SYNCI_EN)

    Hopefully this helps!


    Thank you,
    Brett

  • Hi Clement,

    In addition to Brett's suggestions, in your InitECapture() function, i don't see EALLOW. ECCTL1, ECCTL2 and ECEINT are EALLOW protected registers.
  • Hi Brett and Frank,

    thank you for your answers, I tried your modifications and it didn't work at first, then I saw I didn't clear the flag of CEVT1, CEVT2 and CEVT3 in the interrupt function. Now it is working fine.
    Ps: It works with and without the SYNCI_EN.

    Regards,
    Clement