2025-03-09 5:18 PM - edited 2025-03-10 8:24 PM
Hello, this is my equipment:
1) MCU STM32G0B1RETx (LQFP64 packaging) on a custom board.
2) STM32CubeIDE Version: 1.17.0.
3) STM32CubeMX Version 6.13.0.
For visual indicators (LEDs flashing) we use the TIM4 CH1 in OC Toggle mode (no output). The timer configuration was created with the MX software.
TIM4 CH1 generates a periodic signal with a frequency of 2 Hz, which requires a CCR1 value of 5000:
CCR1 value = f_TIM4_CNT_CLK / (2 * f_TIM4_CH1) = 10000 Hz/(2 * 1 Hz) = 5000
The relevant source code is listed below. It is loosely based on the ST HAL example 'TIM_OCToggle': Our solution includes two main steps:
* The function TIM4_sequence_start() initiates the timer OC toggle sequence, while
* the function HAL_TIM_OC_DelayElapsedCallback() counts the interrupts and stops the OC toggle sequence after the specified number of interrupts, that is, 2 x LED flashes.
Problem description:
Our solution partially works. The timer OC toggle sequence does not start every time the function TIM4_sequence_start() is called. It seems that timer interrupts are generated the 1st and 3rd time. The 2nd function call does not seem to generate interrupts. There is sufficient time between the sequences (6 seconds), therefore timing is probably not an issue. This behavior is consistent and repeatable:
Question 1:
Are the HAL functions TIM_OC_Start_IT() and TIM_OC_Stop_IT() sufficient for the desired behavior, or is it necessary to clear any register bits and or flags. Is it required to re-enable the interrupt after calling TIM_OC_Stop_IT?
Question 2:
Could the issue be caused by NVIC priorities?
Both TIM3 (10 ms time base) and TIM4 (OC toggle mode) have a higher NVIC priority than Systick, which is used for periodic, unrelated checks. See the below screenshot.
Please advise. Thank you!
HAL_StatusTypeDef TIM4_sequence_start(int16_t sysError)
{
/* Verify that all TIM1 channels are ready (not busy) */
if ( ( TIM_CHANNEL_STATE_GET(&htim4, TIM_CHANNEL_1) ||
TIM_CHANNEL_STATE_GET(&htim4, TIM_CHANNEL_2) ||
TIM_CHANNEL_STATE_GET(&htim4, TIM_CHANNEL_3) ||
TIM_CHANNEL_STATE_GET(&htim4, TIM_CHANNEL_4) ) != HAL_TIM_CHANNEL_STATE_READY)
{
Error_Handler();
}
// Reset the TIM4 interrupt counter
TIM4IrqCount = 0;
/* Start the timer channel in Output Compare mode */
halError = HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1);
if(halError != HAL_OK)
{
Error_Handler();
}
return HAL_OK;
} // TIM4_sequence_start
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
uint16_t autoreload_value;
uint32_t uhCapture = 0;
/* Get configured autoreload value */
autoreload_value = __HAL_TIM_GET_AUTORELOAD(htim);
if (htim == &htim4)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) /* TIM1_CH1 toggle */
{
/* Number of expected OC interrupts = 2 * Beeps/LED flashes */
TIM4IrqCount++;
if (TIM4IrqCount >= 2 * asidError.numErrorBeeps)
{
TIM4IrqCount = 0; // Reset for next error indicator
halError = HAL_TIM_OC_Stop_IT(htim, TIM_CHANNEL_1);
if(halError != HAL_OK)
{
/* Stop Error */
Error_Handler();
}
}
else
{
/* [kmathia] TIM1 time stamp: start time */
uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
/* Set the Capture Compare Register value */
/* If elapsed time CCR1_VALUE has not reached autoreload ('reset'),
* otherwise keep the CCR value within the autoreload time */
if (uhCapture + TIM4_CCR1_VALUE < autoreload_value)
{
__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (uhCapture + TIM4_CCR1_VALUE));
}
else
{
__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (uhCapture + TIM4_CCR1_VALUE) - autoreload_value);
}
}
}
}
switch (sysError)
{
case ERR_LEFTMOTOR: // error, left motor hardware
HAL_GPIO_TogglePin(LED_BAT1_R_GPIO_Port, LED_BAT1_R_Pin);
HAL_GPIO_TogglePin(LED_BAT2_Y_GPIO_Port, LED_BAT2_Y_Pin);
HAL_GPIO_TogglePin(LED_BAT3_Y_GPIO_Port, LED_BAT3_Y_Pin);
HAL_GPIO_TogglePin(HORN_GPIO_Port, HORN_Pin);
break;
default:
Error_Handler();
break;
}
}
}
2025-04-03 7:12 AM
Hello @Kmax18,
Try clearing the interrupt flag is cleared. This can be done using __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); the issue could potentially be caused by NVIC priorities!
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.