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.

TMS320F2800157-Q1: eCAP ISR problem

Part Number: TMS320F2800157-Q1
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

I need to measure the duty cycle of an external PWM signal from an ABZ+PWM encoder using the F2800157. The system clock frequency is 120 MHz. I’m using GPIO22 as the input to the eCAP module and have confirmed that the external PWM signal is correctly reaching this pin.

I configured the eCAP module as shown below. However, the issue is that the ISR triggers only once, and the variable onTimeCount holds an unexpectedly large value during that single trigger. Could you please help me troubleshoot this issue?

void initECAP1(void)
{
    // Configure GPIO5 as ECAP1 input

    ECAP_selectECAPInput(ECAP1_BASE,ECAP_INPUT_GPIO22);
    // Disable time-stamp counter
    ECAP_disableTimeStampCapture(ECAP1_BASE);

    // Configure eCAP for capture mode
    ECAP_stopCounter(ECAP1_BASE);
    ECAP_enableCaptureMode(ECAP1_BASE);

    // Capture on rising edge first, then falling edge
    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_RISING_EDGE);
    ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_FALLING_EDGE);

    // Reset counter on event 2 (so we can measure high pulse width)
    ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_2);

    // Divide by 1 (no prescaler)
    ECAP_setEventPrescaler(ECAP1_BASE, 0);

    // Stop after capture event 2
    ECAP_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE, ECAP_EVENT_2);

    // Enable sync-in if needed (optional)
    ECAP_disableLoadCounter(ECAP1_BASE);

    // Clear pending interrupts
    ECAP_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_ALL);
    ECAP_clearGlobalInterrupt(ECAP1_BASE);

    // Enable interrupt for event 2
    ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2);

    // Enable counter and timestamp capture
    ECAP_enableTimeStampCapture(ECAP1_BASE);
    ECAP_startCounter(ECAP1_BASE);

    // Arm the first capture
    ECAP_reArm(ECAP1_BASE);
}

// eCAP ISR
__interrupt void ecap1ISR(void)
{
    uint32_t cap1, cap2;

    // Clear interrupt flags
    ECAP_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2);
    ECAP_clearGlobalInterrupt(ECAP1_BASE);

    // Read captured values
    cap1 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
    cap2 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);

    // Compute ON time (assuming Event1 = rising, Event2 = falling)
    onTimeCount = cap2 - cap1;

    captureDone = true;

    // Re-arm for next capture
    ECAP_reArm(ECAP1_BASE);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}

  • Hi Loganathan,

    I would highly recommend looking at our example code we have within our C2000WARE to compare against the code you have created to see what the initialization routines are. eCAP example 2, demonstrates this.

    I need to measure the duty cycle of an external PWM signal from an ABZ+PWM encoder using the F2800157. The system clock frequency is 120 MHz. I’m using GPIO22 as the input to the eCAP module and have confirmed that the external PWM signal is correctly reaching this pin.

    Okay, verifying the input signal would be the first step.

    Can you ensure GPIO22 is configured an input?

    If this is reaching the pin, then let's take a look at your eCAP configurations. Based on what you've provided, the initialization is slightly different than what we do in SysConfig. myECAP0BASE is ECAP1_BASE.

    //
    	// Disable ,clear all capture flags and interrupts
    	//
    	ECAP_disableInterrupt(myECAP0_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(myECAP0_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));
    	//
    	// Disables time stamp capture.
    	//
    	ECAP_disableTimeStampCapture(myECAP0_BASE);
    	//
    	// Stops Time stamp counter.
    	//
    	ECAP_stopCounter(myECAP0_BASE);
    	//
    	// Sets eCAP in Capture mode.
    	//
    	ECAP_enableCaptureMode(myECAP0_BASE);
    	//
    	// Sets the capture mode.
    	//
    	ECAP_setCaptureMode(myECAP0_BASE,ECAP_CONTINUOUS_CAPTURE_MODE,ECAP_EVENT_2);
    	//
    	// Sets the Capture event prescaler.
    	//
    	ECAP_setEventPrescaler(myECAP0_BASE, 0U);
    	//
    	// Sets the Capture event polarity.
    	//
    	ECAP_setEventPolarity(myECAP0_BASE,ECAP_EVENT_1,ECAP_EVNT_FALLING_EDGE);
    	ECAP_setEventPolarity(myECAP0_BASE,ECAP_EVENT_2,ECAP_EVNT_RISING_EDGE);
    	ECAP_setEventPolarity(myECAP0_BASE,ECAP_EVENT_3,ECAP_EVNT_FALLING_EDGE);
    	ECAP_setEventPolarity(myECAP0_BASE,ECAP_EVENT_4,ECAP_EVNT_RISING_EDGE);
    	//
    	// Configure counter reset on events
    	//
    	ECAP_enableCounterResetOnEvent(myECAP0_BASE,ECAP_EVENT_1);	
    	ECAP_enableCounterResetOnEvent(myECAP0_BASE,ECAP_EVENT_2);	
    	ECAP_disableCounterResetOnEvent(myECAP0_BASE,ECAP_EVENT_3);
    	ECAP_disableCounterResetOnEvent(myECAP0_BASE,ECAP_EVENT_4);
    	//
    	// Select eCAP input.
    	//
    	ECAP_selectECAPInput(myECAP0_BASE,ECAP_INPUT_GPIO22);
    	//
    	// Sets a phase shift value count.
    	//
    	ECAP_setPhaseShiftCount(myECAP0_BASE,0U);
    	//
    	// Enable counter loading with phase shift value.
    	//
    	ECAP_enableLoadCounter(myECAP0_BASE);
    	//
    	// Configures Sync out signal mode.
    	//
    	ECAP_setSyncOutMode(myECAP0_BASE,ECAP_SYNC_OUT_SYNCI);
    	//
    	// Configures emulation mode.
    	//
    	ECAP_setEmulationMode(myECAP0_BASE,ECAP_EMULATION_STOP);
    	//
    	// Set up the source for sync-in pulse..
    	//
    	ECAP_setSyncInPulseSource(myECAP0_BASE,ECAP_SYNC_IN_PULSE_SRC_DISABLE);
    	//
    	// Starts Time stamp counter for myECAP0.
    	//
    	ECAP_startCounter(myECAP0_BASE);
    	//
    	// Enables time stamp capture for myECAP0.
    	//
    	ECAP_enableTimeStampCapture(myECAP0_BASE);
    	//
    	// Re-arms the eCAP module for myECAP0.
    	//
    	ECAP_reArm(myECAP0_BASE);
    	//
    	// Enables interrupt source for myECAP0.
    	//
    	ECAP_enableInterrupt(myECAP0_BASE,(ECAP_ISR_SOURCE_CAPTURE_EVENT_2));

    I configured the eCAP module as shown below. However, the issue is that the ISR triggers only once, and the variable onTimeCount holds an unexpectedly large value during that single trigger. Could you please help me troubleshoot this issue?

    I moved when clearing the interrupt flags at the bottom of the ISR.

    You should be receiving a new ISR trigger after the first one got triggered if the input source is configured properly.

    I see you are correctly clearing the interrupts for the Capture event, and for the global interrupt flag.

    // eCAP ISR
    __interrupt void ecap1ISR(void)
    {
        uint32_t cap1, cap2;

        // Read captured values
        cap1 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
        cap2 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);

        // Compute ON time (assuming Event1 = rising, Event2 = falling)
        onTimeCount = cap2 - cap1;

        captureDone = true;

        // Re-arm for next capture
        ECAP_reArm(ECAP1_BASE);

        // Clear interrupt flags
        ECAP_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2);
        ECAP_clearGlobalInterrupt(ECAP1_BASE);

        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
    }

    Below is a sample project I modified capturing on GPIO22, for eCAP1_BASE. 

    You can modify as needed, but I am unable to replicate the issue of not receiving back to back interrupts for continuously capturing a signal.

    7462.ecap_ex2_capture_pwm.zip

    Best regards,

    Ryan Ma