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.

TM4C129ENCPDT: Tigger routine for Port H

Part Number: TM4C129ENCPDT


Hi,

We an encoder connected to Port H. The encoder is actually a 3 bits knob such that 2 bits are used to identify if the encoder is rotated clock wise or anti-clock wise and the 3rd Bit working as a push button to toggle between Course and Fine adjustment of power supply output current. The Knob part number is 427-121251AL121.

We are running following two interrupts;

  1. Interrupt 1 on GPIO_PIN_0: Output Current setting interrupt to detect the Knob is clockwise rotated or anti-clock wise. This interrupt is working fine and there are no bouncing effect
    1. as there is a 1kRx0.1uC filter on the signal.

  2. Interrupt 2 on GPIO_PIN_2: Coarse / Fine adjustment interrupt that is used to define the output current to be adjusted with a Coarse resolution or a Fine resolution. This interrupt triggers twice. There is no bouncing effect as there is a 1kRx0.1uC filter on the signal.

The Interrupt 1 works fine. It is set to trigger on Both edges of the pulse. As can be seen in the following code for Pin GPIO_PIN_0 defined as RSW_D0 pin;

void EncoderPulses_interrupt_enable(void)
{

    IntMasterDisable();
    GPIOPinTypeGPIOInput(ENC_PORT, RSW_D0);
    GPIOPinTypeGPIOInput(ENC_PORT, RSW_D1);
    GPIOPadConfigSet(ENC_PORT, RSW_D0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    GPIOPadConfigSet(ENC_PORT, RSW_D1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);  // Enable weak pullup resistor 
    GPIOIntDisable(ENC_PORT, RSW_D0);        // Disable interrupt 
    GPIOIntClear(ENC_PORT, RSW_D0);      // Clear pending interrupts
    GPIOIntRegister(ENC_PORT, Encoder_IntHandler);
    GPIOIntTypeSet(ENC_PORT, RSW_D0, GPIO_BOTH_EDGES);          
    GPIOIntEnable(ENC_PORT, RSW_D0);     // Enable interrupt
    IntMasterEnable();

}

The Interrupt 2 triggers twice each time it is activated. This interrupt is configured to trigger only on Falling edge. Following is the code for configuring the interrupt on Pin GPIO_PIN_2 defined as RSW_D2 pin.

void EncoderMode_interrupt_enable(void)
{

    IntMasterDisable();
    GPIOPinTypeGPIOInput(ENC_PORT, RSW_D2);
    GPIOPadConfigSet(ENC_PORT, RSW_D2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);  // Enable weak pullup resistor
    GPIOIntDisable(ENC_PORT, RSW_D2);        // Disable interrupt
    GPIOIntClear(ENC_PORT, RSW_D2);      // Clear pending interrupts 
    GPIOIntRegister(ENC_PORT, Encoder_IntHandler);
    GPIOIntTypeSet(ENC_PORT, RSW_D2, GPIO_FALLING_EDGE);             // Configure  falling edge trigger
    GPIOIntEnable(ENC_PORT, RSW_D2);     // Enable interrupt
    IntMasterEnable();

}

Following is the Function invoked whenever the interrupt is triggered on either of the two Pins (e.g. GPIO_PIN_2 and/or GPIO_PIN_0)

void Encoder_IntHandler(void) 
{
    SysCtlDelay(1*17000);//Clear the Interrupt after the Delay to avoid multiple Interrupt entries.
    if(GPIOIntStatus(ENC_PORT, false) & RSW_D0) //Check if the Interrupt is for RSW_D0 (GPIO_PIN_0) or RSW_D2 (GPIO_PIN_2)
    {
        uint8_t i,j;
        GPIOIntClear(ENC_PORT, RSW_D0);
        i = GPIOPinRead(ENC_PORT,RSW_D0);
        j = GPIOPinRead(ENC_PORT,RSW_D1);
        if (j==2){j = 1;} // When GPIO_PIN_1 is HIGH it GPIOPinRead() will report 0x2H. Replace it to 0x1H

        //Detect if the Encoder is moved CC or ACC 
        if(i == j){EncoderServiceReqType = EncoderCCW;} //Encoder moved Anti-Clockwise
        else{EncoderServiceReqType = EncoderCW;} //Encoder moved Clockwise


    }
    else
    {
        GPIOIntClear(ENC_PORT, RSW_D2);
        EncoderServiceReqType = EncoderMBtn;
    }

    EncoderServiceReqFlag = 1;

}

The definitions are;

#define ENC_PORT                GPIO_PORTH_BASE

#define RSW_D0                  GPIO_PIN_0 // Interrupt 1 Pin.
#define RSW_D1                  GPIO_PIN_1
#define RSW_D2                  GPIO_PIN_2 //Interrupt 2 Pin. Encoder Push Button to switch between Fine and Coarse adjustment

I thank you all for your help.

Regards,

Sahil

  • Please note, GPIO_PIN_0 needs to be triggered on both edges because it has to detect if the encoder is moved clockwise or anti-clockwise.

    When Interrupt 1 is invoked either on Rising or Falling edge, the interrupt service routine reads GPIO_PIN_1 and depending on HIGH or LOW value it detects the movement is CC or ACC.

    Interrupt 2 on GPIO_PIN_2 should be either on Falling edge or Rising edge.

  • This is a rotary encoder plus momentary pushbutton switch used as a front-panel control?

    Dispense with the idea of using interrupts to note changes, and just poll the three pins on a regular basis.

  • Hi,

    Interrupt 2 on GPIO_PIN_2 should be either on Falling edge or Rising edge.

    I'm a bit confused. In your original post, you said interrupt 2 is only generated on falling edge. Here you said is both edges. Which is one is correct? Per your code snippet, you are configuring for falling edge on interrupt 2 for PH2. 

    How fast are the input signals especially on RSW_D2? Is it possible that while you are serving the interrupt 2 in the ISR for the first falling edge then next falling edge has also come? This means immediately after you exit the ISR for interrupt 2, it will reenter ISR for the next ISR. Another thing to look at is if RSW_D2 and RSW_D0 can come roughly at the same time? If they come roughly at the same time then when you enter the ISR you first check if RSW_D0 is detected and only clear the flag for interrupt 1, not both. The interrupt 2 is missed. 

    I will suggest you don't use the if-else in the ISR but rather two 'if' conditions. One 'if' for interrupt 1 and another 'if' for interrupt 2. This way you won't miss any of them. 

    Is it possible for you to do an experiment that RSW_D0 will never activate? In another word, only RSW_D2 will activate.  Perhaps the easiest way is to simply disable interrupt 1 for experiment purpose. This way you can confirm in the absence of RSW_D0, the RSW_D2 will still trigger twice or only once.

  • Hello Charles,

    GPIO_PIN_2 is configured to trigger only on Falling Edge as you can see in the snippet. However the problem is GPIO_PIN_2 triggers on Falling as well as on Rising edge.

    There is no multiple interrupt generated as I have RC filter to avoid any bouncing effect.

    GPIO_PIN_0 and GPIO_PIN_2 doesn't activate together in fact they will probably never come together. Since it is an encoder Knob to set Power supply output current so the user will either rotate the Knob which will be activating GPIO_PIN_0 only. And GPIO_PIN_2 will be activated when the User will push the Knob inside. We never push the Knob at the same time while rotating. This means the two interrupts dont activate together.

    As you suggested, let me try to replace the IF-ELSE statement with two IF statements and see if it fixes the issue.

  • Hi,

    So I tried the replacing the IF-ELSE statement with two IF statements but it didn't help. However when I changed Interrupt 2 to be activated on LOW_LEVEL (earlier it was configured to activate on Falling edge) solved the problem.

    I can recall similar problem we had when we were dealing with two interrupts both on earlier configured to be activated on Falling edge  and both interrupts were associated with Port D on Pins Pin 2 and Pin 3. When we changed one interrupt to be on Falling and other to be on Rising edge, solved the problem.

  • Hi,

      Glad that you solve the problem. It is still not clear to me why falling edge would trigger two interrupts as it should not. The GPIO must have seen two falling edges either these two edges come very fast before the ISR is exited or there is still glitch on the input. What you can experiment with is to add a software debounce to eliminate any possibility of glitches on the inputs.  Anyway, if you are satisfied with the level interrupt and that solved the problem for you which is also fine. 

  • I have scoped the pins for both interrupts and I am confident to say that there is no glitches/bouncing etc as we are using an RC filter on both of the pins.

    In my opinion it has something to do with the ports that do not provide individual Pin interrupt capability. Something to thing about !

    I thank you for your help and cross-checks. 

    You have a great day.