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.

TMS320F28075: A race condition when reading EcapxRegs.CAPy asynchronously to eCAP interrupts

Part Number: TMS320F28075

Hello,

My customer would like to use a timer ISR function (@1sec) and read the latest EcapxRegs.CAPy value.

We are afraid that a race condition between a CPU read and a EcapxRegs.CAPy update, because the CPU read is not synchronized to Ecap events.

We are afraid to read a wrong or not properly updated value from the register. 

Q1. Could you please advise whether the race condition possible?

Q2. If yes, could you please advise its solution? I wonder that CAPLDEN bit would work.

  • Hi,

    Yes I think there might be a possibility of race condition as there is no synchronization between the incoming signal & CPU ISR. But if the customer is anyway interested in reading just the latest CAPy value in every 1 second then One-shot mode of ECAP could be useful instead of continuous capture mode. So what I suggest is that the one-shot ECAP capture can be triggered inside the Timer ISR function (@1sec) and then the Capture ECAP event can trigger another ISR where the value can be read. The code sequence will something like below :

    //
    // Timer ISR (@1sec)
    //
    __interrupt void timerISR(void)
    {
        //
        // Start eCAP
        //
        ECAP_reArm(ECAP1_BASE);
    
        //
        // If any other code
        //
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 1
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }


    //
    // eCAP 1 ISR
    //
    __interrupt void ecap1ISR(void)
    {
        //
        // Read the captured value
        //
        cap1Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
        cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
    
        //
        // Do any other processing of captured data
        // 
        
        //
        // Clear interrupt flags for more interrupts.
        //
        ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_2);
        ECAP_clearGlobalInterrupt(ECAP1_BASE);
    
        //
        // Acknowledge the group interrupt for more interrupts.
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
    }

    //
    // initECAP - Configure eCAP
    //
    void initECAP()
    {
        //
        // Disable ,clear all capture flags and interrupts
        //
        ECAP_disableInterrupt(ECAP1_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(ECAP1_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));
    
        //
        // Disable CAP1-CAP4 register loads
        //
        ECAP_disableTimeStampCapture(ECAP1_BASE);
    
        //
        // Configure eCAP
        //    Enable capture mode.
        //    One shot mode, stop capture at event 2.
        //    Set polarity of the events to rising, falling edge.
        //    Set capture in time difference mode.
        //    Enable eCAP module.
        //    Enable interrupt.
        //
        ECAP_stopCounter(ECAP1_BASE);
        ECAP_enableCaptureMode(ECAP1_BASE);
    
        ECAP_setCaptureMode(ECAP1_BASE, ECAP_ONE_SHOT_CAPTURE_MODE, ECAP_EVENT_2);
    
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
        ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
        
        ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_2);
        ECAP_enableLoadCounter(ECAP1_BASE);
        
        ECAP_startCounter(ECAP1_BASE);
        ECAP_enableTimeStampCapture(ECAP1_BASE);
        ECAP_reArm(ECAP1_BASE);
    
        ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2);
    }

    Hope this configuration helps to solve the issue. If my reply answers your question please click on "This resolved my issue" button located at the bottom of my post.

    Regards

    Himanshu

  • Himanshu,

    Thank you very much. Very clear.