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.

eCAP CEVT1 and CEVT2 interrupt initialization

Other Parts Discussed in Thread: TMS320F28027

Hello, 

I am trying to configure eCAP module on TMS320F28027 in Rising/Falling edge Delta timing mode in order to calculate the pulse width. 

However, only one of the interrupts (CEVT2 @ ecap2_isr) routine gets triggered and it gets triggered only once. Please refer to the code snippet below. Any thoughts?

interrupt void ecap1_isr(void)
{
    printf("\n\r In ECAP1 ISR\n\r");

    // Read CAP1 time base counter at CEVT1
    cap_t1      = CAP_getCap1(myCap);

    // Clear eCAP Interrupt
    CAP_clearInt(myCap, CAP_Int_Type_CEVT1);
    // Reenable CAP1
    CAP_rearm(myCap);

    printf("\n\r Cleared CEVT1 INT \n\r");
}

interrupt void ecap2_isr(void)
{
    printf("\n\r In ECAP2 ISR\n\r");

    // Read CAP2 time base counter at CEVT2
    cap_t2      = CAP_getCap2(myCap);
    // Calculate pulse width
    cap_period  = cap_t2 - cap_t1;

    printf("%d, ", cap_period);
    printf("%d Hz \n\r", (40000000/cap_period));

    // Clear eCAP Interrupt
    CAP_clearInt(myCap, CAP_Int_Type_CEVT2);
    // Reenable CAP1
    CAP_rearm(myCap);

    // Clear PIE Interrupt
    PIE_clearInt(myPie, PIE_GroupNumber_4);

    printf("\n\r Cleared CEVT2 INT \n\r");
}

void cap_init()
{
    // Register interrupt handlers in the PIE vector table
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap1_isr);
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap2_isr);

    // eCAP1 on GPIO5
    GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Enable);
    GPIO_setQualification(myGpio, GPIO_Number_5, GPIO_Qual_Sync);
    GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_ECAP1);

    CLK_enableEcap1Clock(myClk);
    // Disable all eCAP interrupts
    CAP_disableInt(myCap, CAP_Int_Type_All);
    // Clear all eCAP interupt flags
    CAP_clearInt(myCap, CAP_Int_Type_All);
    // Disable CAP1-CAP4 register loads
    CAP_disableCaptureLoad(myCap);
    // Ensure counter is stopped
    CAP_disableTimestampCounter(myCap);

    // Configure CAPx for Capture mode
    CAP_setModeCap(myCap);
    // Configure peripheral registers
    //CAP_setCapOneShot(myCap);
    CAP_setCapContinuous(myCap);
    // Set MOD4 Stop/Wrap value
    CAP_setStopWrap(myCap, CAP_Stop_Wrap_CEVT2);
    // Rising Edge
    CAP_setCapEvtPolarity(myCap, CAP_Event_1, CAP_Polarity_Rising);
    // Falling Edge
    CAP_setCapEvtPolarity(myCap, CAP_Event_2, CAP_Polarity_Falling);
    // Reset capture event 1
    CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Enable);
    // Reset capture event 2
    CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Enable);

    // Enable sync in
    //CAP_enableSyncIn(myCap);
    // Pass-through
    CAP_setSyncOut(myCap, CAP_SyncOut_Disable);

    // Enable CAP1-CAP4 register loads
    CAP_enableCaptureLoad(myCap);
    // Enable CAP CEVT1 counter
    CAP_enableTimestampCounter(myCap);
    // Arm one-shot
    CAP_rearm(myCap);
    // Enable CAP1-CAP4 register loads
    CAP_enableCaptureLoad(myCap);
    // Enable interrupt on CEVT1
    CAP_enableInt(myCap, CAP_Int_Type_CEVT1);
    // Enable interrupt on CEVT2
    CAP_enableInt(myCap, CAP_Int_Type_CEVT2);
}

  • Hi Mansi,

    Look at where you register/initialize your PIE interrupt handlers.  The group and subgroup values need to be configured such that they match the peripheral that is generating the interrupt.

    Take a look at the "PIE MUXed Peripheral Interrupt Vector Table" figure within the "System Control and Interrupts Guide" for your device. 
    (in the current revision of this document, it is listed as Table 108)

    Hopefully this helps!


    Thank you,
    Brett

  • Hi Brett,

    Yeah, I looked at that already - eCAP1 Interrupt belongs to Group 4 and Sub-group 1 and that is how I initialized the PIE interrupt handler.

    I think I may have found the issue - I have two ISRs, one for each of the CEVTx events, which is incorrect. eCAP has one dedicated interrupt only and hence can only be tried to one ISR.

    Now that the interrupts are resolved, I am running into both CAPx registers reading the same value and hence reading pulse width as 0.
  • Sorry, with an interrupt named ecap2_isr I mistakenly assumed you were on a device that had two eCAPs.  However, on the F2802x family, there is only 1 eCAP.

    Your thought is valid.  You'll probably have one interrupt.  Inside it you'll check flags to differentiate whether the interrupt occurred because of CEVT1 or CEVT2 (and then take appropriate action).


    Thank you,
    Brett

  • My bad. Thanks so much for looking into it!

    I still can't seem to read the expected value in the eCAP counter registers.

    My interrupt routine is as follows:

    interrupt void ecap1_isr(void)
    {
    if(ECap1Regs.ECFLG.bit.CEVT1 == 1)
    {
    // Read CAP1 time base counter at CEVT1
    cap_t1 = CAP_getCap1(myCap);
    printf("%d \t", cap_t1);

    // Clear eCAP Interrupt
    CAP_clearInt(myCap, CAP_Int_Type_CEVT1);
    // Clear eCAP global interrupt
    CAP_clearInt(myCap, CAP_Int_Type_Global);
    // Clear PIE Interrupt
    PIE_clearInt(myPie, PIE_GroupNumber_4);
    // Rearm eCAP
    //CAP_rearm(myCap);
    }
    else if(ECap1Regs.ECFLG.bit.CEVT2==1)
    {
    // Read CAP2 time base counter at CEVT2
    cap_t2 = CAP_getCap2(myCap);
    printf("%d \n\r", cap_t2);

    // Calculate pulse width
    cap_period = cap_t2 - cap_t1;

    printf("%d, ", cap_period);
    //printf("%d Hz \n\r", (40000000/cap_period));

    // Clear eCAP Interrupt
    CAP_clearInt(myCap, CAP_Int_Type_CEVT2);
    // Clear eCAP global interrupt
    CAP_clearInt(myCap, CAP_Int_Type_Global);
    // Clear PIE Interrupt
    PIE_clearInt(myPie, PIE_GroupNumber_4);
    // Rearm eCAP
    CAP_rearm(myCap);
    }
    else
    {
    // Clear eCAP global interrupt
    CAP_clearInt(myCap, CAP_Int_Type_Global);
    // Clear PIE Interrupt
    PIE_clearInt(myPie, PIE_GroupNumber_4);
    }

    eCAP module init functions is the same as in the original post, except that CEVTx event reset is now disabled:
    // Reset capture event 1
    CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Disable);
    // Reset capture event 2
    CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Disable);