The correct way of filtering interrupts correctly appears to be this way:
When looking at the way interrupt is checked
/* Capture compare 2 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
/* Input capture event */
if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
Two important lines are
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
this indicates that in our code we can never use
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
because interrupt has been already cleared by
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
Why? Looking at __HAL_TIM_GET_FLAG and __HAL_TIM_CLEAR_IT
#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__))
and
#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))
in other words the bit in SR register is cleared already by the time our code reaches the callback function.. in my case the flag is TIM_IT_CC2..
So, the correct way to do it is like this:
/* USER CODE BEGIN 4 */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t flag = 0;
if( htim->Instance == TIM1 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2 )
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET)
{
if (__HAL_TIM_GET_AUTORELOAD(htim) == 25000)
__HAL_TIM_SET_AUTORELOAD(htim, 55000);
else
__HAL_TIM_SET_AUTORELOAD(htim, 25000);
}
}
}
/* USER CODE END 4 */
It is important to use HAL_TIM_ACTIVE_CHANNEL_2 as a flag to detect the interrupt rather than using TIM_IT_CC2 IF in SR.. the weird thing is that __HAL_TIM_GET_IT_SOURCE checks if the interrupt is enabled in TIMx_DIER ..! So, I am not really sure if I should be using if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET) or not..
BTW, answering some of my own questions:
ARR or period in HAL language can be read/set using __HAL_TIM_GET_AUTORELOAD/__HAL_TIM_SET_AUTORELOAD
Pulse can be read/set using __HAL_TIM_GET_COMPARE/__HAL_TIM_SET_COMPARE
but the actual pulse length is (ARR-CCRx) i.e. (period - Pulse)..
I still don't understand why CC1 OC gets fired...