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.

Using ECap for Hall Sensor Capture in Motor control application

Other Parts Discussed in Thread: CONTROLSUITE

Hi 

I have connected the output pulse of a Hall sensor to Gpio24 of my 28335 chip. 

I know the pulse comes in because during the debug session,  I check the pulse with GpioDataRegs.GPADAT.bit.GPIO24 in the watch window and see this bit toggle when I rotate the motor shaft. I also see the pulse coming on the scope and the values match.

Next, I initialize the ECap1 module with this code;

// ECap1 Register setting

ECap1Regs.TSCTR = 0;       // Set Time Stamp Counter to 0
ECap1Regs.CTRPHS = 0;    // Set Time Stamp Counter Phase Register to 0
ECap1Regs.CAP1 = 0;         // Set Capture Register 1 to 0
ECap1Regs.CAP2 = 0;         // Set Capture Register 2 to 0

ECap1Regs.ECCTL1.bit.FREE_SOFT = 2;      // Counter does not stop on emulation suspend
ECap1Regs.ECCTL1.bit.PRESCALE = 0;       // Prescale is set to divide by 1
ECap1Regs.ECCTL1.bit.CTRRST2 = 1;          // Do not reset counter on Capture Event 2
ECap1Regs.ECCTL1.bit.CAP2POL = 1;         // CAP2 Register will capture on falling edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 1;         // Reset Counter after a Capture Event 1
ECap1Regs.ECCTL1.bit.CAP1POL = 0;        // CAP1 Register will capture on rising edge
ECap1Regs.ECCTL1.bit.CAPLDEN = 0;        // Enable CAP1-CAP4 register loads

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
ECap1Regs.ECCTL2.bit.CAP_APWM = 0; // Enable ECap mode
ECap1Regs.ECCTL2.bit.STOP_WRAP = 0; // Wrap after Capture Event 1 in one-shot mode
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // Operate in Continuous mode
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2; // Sync Out signal is disabled
ECap1Regs.ECCTL2.bit.SYNCI_EN = 0; // Sync In is disabled

Then I prepare ECap1 for interrupt using this code;

ECap1Regs.ECEINT.all = 0x0000;     // Disable all interrupts on ECap1
ECap1Regs.ECCLR.all = 0xFFFF;      // Clear all interrupt flags for ECap1
ECap1Regs.ECEINT.bit.CEVT1 = 1;    // Enable interrupt on Rising Edge signal
ECap1Regs.ECEINT.bit.CEVT2 = 1;   // Enable interrupt on Falling Edge Signal

PieCtrlRegs.PIEIER4.bit.INTx1 = 1;     // Enable Corresponding bit in PIEIER for CAP1

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;     // Start Timer Counter

ECap1Regs.ECCTL1.bit.FREE_SOFT = 2;    // Counter is not affected by Emulation mode

PieCtrlRegs.PIEACK.bit.ACK4 = 1;                // Enable Group4.x Interrupts to PIECTRL

In Main() I wait for the ECap interrupt by setting it up like this:

IER = M_INT4;

If I place this line in the code

ECap1Regs.ECFRC.bit.CEVT1 = 1;  // force the interrupt

the interrupt will fire and I will branck to ISR, however, if I simply turn the motor to create the hardware interrupt, I don't branch to the corresponding ISR routine.


Any ideas?


  • Farrokh,

    Your code looks very close to correct. 

    Can you confirm that you are configuring GPIO24 to be an eCAP via the GPAMUX?  Note that this is EALLOW protected. 

    The only other thing I can think of is to make sure that the eCAP1 clock is on, but I don't think the interrupt would fire if it wasn't on (even if forced).


    Thank you,
    Brett

  • Brett,

    Thanks for the reply. I have checked both points you mentioned. GPAMUX is correctly configured. eCAP1 clock is also enabled.

    Nevertheless, I don't get an interrupt. I also initialized CAP1 register with some value and watch it to see if it changes. It does not which means I don't have an interrupt event at the peripheral level.

    The good news is I loaded another project from ControlSuite and got the interrupt to fire. But in that project, there is no VectorTable. The ISR is local to Main().

    I was testing the eCap module to make sure I can make it work and I am comfortable with. I will re-do the project from scratch tomorrow and see how it goes. Perhaps something is broken in another place and I am just not seeing it. Thanks for confirming that the code is good.

    One question: The documentation is not clear about whether there is any dependencies between the ECap1Regs.ECCTL1.bit.CAPLDEN strobing and the interrupt happening? The schematic points to there being no dependency. Although I don't really care about the capture timing, I think I have to keep the timer running ( as I already do ) , but I prefer to get rid of all the extra stuff in the project including the statements such as  ECap1Regs.ECCTL1.bit.CTRRST1 = 1;

    Second Question: Do I need to worry about the modulo 4 counter in the continuous capture mode?

    Thx

  • I did the project again.Here is how I am setting up my ECap registers;

    void InitECapture()
    {
    ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
    ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped

    // Configure peripheral registers
    ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // Continuous
    ECap1Regs.ECCTL2.bit.STOP_WRAP = 0; // Stop at 4 events
    ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge
    ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Rising edge
    ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Falling edge
    ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Rising edge
    ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // Difference operation
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through
    ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units


    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.CEVT1 = 1; // CEVT1 events = interrupt

    }

    This set up is firing the interrupt correctly. 

    Cheers

    Farrokh

  • Hello Brett Larimore,

    can you give a final comment to this post.

    Actually i am facing ISR interrupt problem in eCAP module of measuring Duty cycle.