TMS570LC4357: Push Button Debounce

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

Hi,

I want to use internal push button on the hdk board. But the button doesnt work stabile. Some times the register's value changes sometime doenst change value while i push the button. That state is unpredictable. How can i write a debounce fonuction? Or are there an examples project ?


 

  • Hi Dobby,

    The instability you're experiencing is a common issue called "button bounce." When you press or release a mechanical button, the contacts don't make or break cleanly - they bounce multiple times over a period of 5-20ms, causing the GPIO register to change unpredictably.

    Unfortunately, i don't have any ready example for this because most of this kind of requirements will be handled by customers themselves, so i never get this kind of issue before.

    We have internal AI and it suggest couple of code flows like below, you can adopt to any of these methods.

    Method-1:

    // Debounce configuration
    #define DEBOUNCE_TIME_MS    20    // Typical debounce time: 10-20ms
    #define BUTTON_PRESSED      0     // Assuming active low with pull-up
    #define BUTTON_RELEASED     1
    
    // Global variables
    static uint32_t lastButtonState = BUTTON_RELEASED;
    static uint32_t buttonStateCounter = 0;
    static uint32_t stableButtonState = BUTTON_RELEASED;
    
    // Call this function periodically (e.g., every 1ms from a timer interrupt)
    uint32_t debounceButton(uint32_t currentButtonState)
    {
        if (currentButtonState != lastButtonState) {
            // Button state changed, reset counter
            buttonStateCounter = 0;
            lastButtonState = currentButtonState;
        } else {
            // Button state is stable, increment counter
            if (buttonStateCounter < DEBOUNCE_TIME_MS) {
                buttonStateCounter++;
            }
            
            // If stable for debounce time, update stable state
            if (buttonStateCounter >= DEBOUNCE_TIME_MS) {
                stableButtonState = currentButtonState;
            }
        }
        
        return stableButtonState;
    }
    
    // Usage in your main loop or timer ISR
    void checkButton(void)
    {
        uint32_t rawButtonState = gioGetBit(gioPORTA, BUTTON_PIN); // Read GPIO
        uint32_t debouncedState = debounceButton(rawButtonState);
        
        if (debouncedState == BUTTON_PRESSED) {
            // Button is pressed (stable)
            // Your action here
        }
    }

    Method-2:

    typedef enum {
        BUTTON_STATE_RELEASED,
        BUTTON_STATE_PRESSED,
        BUTTON_STATE_DEBOUNCING_PRESS,
        BUTTON_STATE_DEBOUNCING_RELEASE
    } ButtonState_t;
    
    ButtonState_t buttonStateMachine(uint32_t rawInput)
    {
        static ButtonState_t state = BUTTON_STATE_RELEASED;
        static uint32_t debounceCounter = 0;
        
        switch(state) {
            case BUTTON_STATE_RELEASED:
                if (rawInput == BUTTON_PRESSED) {
                    state = BUTTON_STATE_DEBOUNCING_PRESS;
                    debounceCounter = 0;
                }
                break;
                
            case BUTTON_STATE_DEBOUNCING_PRESS:
                if (rawInput == BUTTON_PRESSED) {
                    debounceCounter++;
                    if (debounceCounter >= DEBOUNCE_TIME_MS) {
                        state = BUTTON_STATE_PRESSED;
                        // Trigger button press event here
                    }
                } else {
                    state = BUTTON_STATE_RELEASED;
                }
                break;
                
            case BUTTON_STATE_PRESSED:
                if (rawInput == BUTTON_RELEASED) {
                    state = BUTTON_STATE_DEBOUNCING_RELEASE;
                    debounceCounter = 0;
                }
                break;
                
            case BUTTON_STATE_DEBOUNCING_RELEASE:
                if (rawInput == BUTTON_RELEASED) {
                    debounceCounter++;
                    if (debounceCounter >= DEBOUNCE_TIME_MS) {
                        state = BUTTON_STATE_RELEASED;
                        // Trigger button release event here
                    }
                } else {
                    state = BUTTON_STATE_PRESSED;
                }
                break;
        }
        
        return state;
    }

    Hardware Configuration Tips

    1. Enable Internal Pull-up/Pull-down: Configure your GPIO with internal pull-up or pull-down resistors as appropriate for your button circuit

    2. HALCoGen Configuration: Use HALCoGen to configure your GPIO properly:

      • Set the pin as input
      • Enable pull-up if button connects to ground when pressed
      • Enable pull-down if button connects to VCC when pressed

    Timer Setup for Periodic Sampling

    You'll need a timer to call your debounce function periodically (every 1ms is recommended):

    // In HALCoGen, configure RTI (Real-Time Interrupt) for 1ms period
    void rtiNotification(uint32 notification)
    {
        if(notification == rtiNOTIFICATION_COMPARE0) {
            // Call your button check function here
            checkButton();
        }
    }

    --

    Thanks & regards,
    Jagadish.