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.

how to react on long and short button clicks on a TMS570x

Other Parts Discussed in Thread: HALCOGEN

I am looking for a good way to react on short and long buton clicks on a TMS570x, including debounce.
Disclaimer: I have asked a related question on the EEVBlog, but not TMS570x specific

the expected effect should be similar to what a volume control does:

  • a short click should invoke a function, with debounce (say: volume up with one), after button release
  • a long click should invoke a function repeatedly (say: continuous volume increase until button released or max reached), while button down until button release

I'd like to use the HALCoGen api as much as possible.

If you have experience to share I'd like t know.

  • Hello Jan,

    To identify the best way to implement this in your system you would first need to decide if it should be interrupt or polling based.

    If the "volume control" is the only thing going on in the system at the time, you could implement this as a polling feature where you simply detect the GIO assertion for the button then poll to check the state. Debounce could be as simple as detecting the same value repeatedly for 'X' times in a row where 'X' is the appropriate filtering value for your system. While the polled state of the GIO is asserted, you would stay in a loop increasing (or decreasing) the volume until the max or min is reached.

    Similarly, you could set an interrupt up for the GIO that would interrupt on the rising edge of the GIO signal. Inside the ISR you would set a flag that would indicate the action to your main loop and the action in the main loop would check the continued assertion of the GIO for each loop time and react accordingly (i.e., if(BUTTON_FLAG && BUTTON_STATE)). For filtering, you could still look for 'X' GIO assertions or de-assertions in a row to change the flag variable to be de-asserted.

    In generaly, this is not something that is specific to Hercules and really gets back to how you want the GIO assertions and reactions to behave. I would recommend to start with the basic detection and filtering techniques used widely in embedded software and adjust as needed to get the performance and feel you want in your implementation. i.e., experiment and adjust.

  • Thank you!

    I asked the question for the Hercules family to check if there was a prefered way of doing this with the specific combination of available interrupts and timers (RTI, HET).

    Your answer helps me a lot. I'm going to try out both options.

  • I have tested a few options, and for debouncing this was the simplest software solution: sampling every so many (in my case 10 ms) miliseconds and waiting for a number of stable push and release samples.

    Based on 'A Guide to Debouncing'  by Jack G. Ganssle

    I've adapted it for HALCoGen's gio API, and extracted the state storage out of the debounce function so that it can be used for multiple buttons. I've adapted the values inside the function to work with good user experience and reliable debouncing when sampling every 10 ms.

    Parameter 1 and 2 define the pin to be debounced,

    Parameter 3 is the state of the button that needs deboucing/. The variable has to be passed by reference because the function updates it after sampling.

    // Service routine called by a timer interrupt
    // optimized for a call per 10 ms
    boolean DebounceSwitch(gioPORT_t *port, uint32 bit, uint32 *state)
    {
        *state=(*state<<1) | gioGetBit(port, bit) | 0xffffffe0;
        if(*state==0xfffffff0) {
            return TRUE;
        }
        return FALSE;
    }

    As testbed I used a Hercules Launchpad and enabled interrupt on RTI compare 3 (entry  5 in the VIM table)..

    My calling function (the RTI interrupt handler looks like this:

    void rtiNotification(uint32 notification)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
    /* USER CODE BEGIN (9) */


        static uint32 State7 = 0; // Current debounce status of GIOA[7]
        if(notification==rtiNOTIFICATION_COMPARE3) {
            if(DebounceSwitch(gioPORTA, 7, &State7)) {
                iAction=1;
            }
        }
    /* USER CODE END */
    }

    My initialization and state handlong is as follows:

    void main(void)
    {
    /* USER CODE BEGIN (3) */
        gioInit();
        rtiInit();
        rtiEnableNotification(rtiNOTIFICATION_COMPARE3);
        _enable_interrupt_();
        rtiStartCounter(rtiCOUNTER_BLOCK1);

        while(1) {
            switch(iAction) {
            case 1: // button GIOA[7] short down
                gioToggleBit(gioPORTA,2);
                break;
            }
            iAction = 0;
        }
    /* USER CODE END */
    }