Dual state button algorithm in C I wrote code for determining the push button state whether it is long pressed or not. This function is called by timer interrupt routine every 1ms.

But it seems really dumb. How can I make it shorter and more efficient according to both readability and professional rules? What should I add or change to get double Tap pressing information with this  code?

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{   
    /*button pressed and count*/
    if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13))
    {
        usTick++;
    }
    /*not pressed*/
    else
    {
        if( usTick &gt; 1000){
            ButtonState.PressedState = LongPressed;
            HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);       
            usTick = 0;
        }
        else if( usTick &gt;350){
            ButtonState.PressedState = ShortPressed;
            HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);               
            usTick = 0;
        }               
        usTick = 0;
    }
}
... how can I make it shorter and more efficient according to both readability and professional rules?


Calling

usTick = 0;


is superfluous in the else branches sub-conditions. That can be rewritten like:

/*not pressed*/
else
{
    if( usTick &gt; 1000){
        ButtonState.PressedState = LongPressed;
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);       
    }
    else if( usTick &gt;350){
        ButtonState.PressedState = ShortPressed;
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);       
    }          
    // Calling those statements Once is enough here 
    usTick = 0;
}


Checking the minimum limit and reducing the whole sub-conditions with a ternary condition operator (as mentioned in @David Isla's answer), the whole code could be boiled down to a few lines:

/*not pressed*/
else
{
    if( usTick &gt; 350) {
         ButtonState.PressedState = usTick &gt; 1000 ? LongPressed : ShortPressed;
         HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);       
    }
    usTick = 0;
}





  What should I add or change to get double Tap pressing information with this code?


You might consider to put any data updating operations into critical sections (or other non-interruptible code paths):

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{   
    /*button pressed and count*/
    if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13))
    {
        START_CRITCAL_SECTION();
        usTick++;
        END_CRITCAL_SECTION();
    }
    /*not pressed*/
    else {
        START_CRITCAL_SECTION();
        if( usTick &gt; 350) {
             ButtonState.PressedState = usTick &gt; 1000 ? LongPressed : ShortPressed;
             HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);       
        }
        usTick = 0;
        END_CRITCAL_SECTION();
    }
}


where START_CRITCAL_SECTION() disables all interrupts, and END_CRITCAL_SECTION() reenables their former state.

This may help, that any co-routines or threads will always read consistent values for ustick or the GPIO_PIN_5 state.