Dual state button algorithm in C
... 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.