2025-12-01 11:56 AM
Hi All,
I'm using STM32G4 with TIM1 for motor control. The BKIN hardware protection works correctly - when I pull the BKIN pin (PB10) low, the motor stops, and when high, it runs again with AOE enabled. However, the break interrupt never fires and HAL_TIMEx_BreakCallback is never called. I've verified that TIM1_BRK_TIM15_IRQHandler exists in stm32g4xx_it.c, NVIC is enabled. The break flag never gets set even though BKIN is functioning. What could prevent the break flag from being set while the hardware break feature still works?
I want to print diagnostic using BKIN callback routing but it doesn't work.
I've attached IOC timer configurations.
Best regards
Solved! Go to Solution.
2025-12-03 10:56 AM
Hey all,
I think I understand the problem.
HAL_TIMEx_PWMN_Start_IT function also enables the break interrupt so I think I need to manually enable the break interrupt when using the TIM_PWM_START_IT function.
Best regards
2025-12-01 12:15 PM
Does a breakpoint in TIM1_BRK_TIM15_IRQHandler ever get hit?
2025-12-02 12:36 AM
Hello @batuhanky
Could you please check if the break interrupt (BIE) is enabled in the TIMx_DIER register?
2025-12-02 11:14 AM
Hey @TDK
No it doesn't get hit but there is an interrupt callback.
When I ground the BKIN pin, the motor stops but printf does not work.
2025-12-02 11:22 AM
Hey @Saket_Om ,
No, BIE is not set, but when I manually enable the BIE bit, the callback works. What could be the reason for this?
TIM1->DIER |= (1 << 7);
2025-12-02 11:38 AM
Use HAL_TIMEx_PWMN_Start_IT to start the channel
This would be much easier to diagnose if you showed your full code.
2025-12-03 12:52 AM
Hello @batuhanky
The API that you are using to start the timer is not enabling the break interrupt.
Try to use HAL_TIMEx_PWMN_Start_IT as suggested by @TDK.
2025-12-03 10:28 AM - edited 2025-12-03 10:48 AM
Hey all,
First of all thanks a lot for your helps.
Right now, the code is not well organized, so I haven't had a chance to fully organize it yet, but you're right, I should have shared all the code. Please check my code below. Current configuration is PWM_MODE_3IN. I'm not using complementary output rn.
Best regards
void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef* htim)
{
if(htim->Instance == TIM1)
{
HAL_GPIO_WritePin(USER_LED_BLUE_GPIO_Port, USER_LED_BLUE_Pin, GPIO_PIN_RESET);
DRV_DRV8316_PrintStatus(&drv8316Config);
}
}HAL_StatusTypeDef API_Motor_Init(API_Motor_TypeDef *const motor, DRV_DRV8316_t *drv8316_handle) {
HAL_StatusTypeDef status;
/*
if (motor->pwmTimerHandle == NULL || motor->phaseUADC == NULL || motor->phaseVADC == NULL) {
return HAL_ERROR;
}
*/
motor->drv8316_handle = drv8316_handle;
if (DRV_DRV8316_Init(motor->drv8316_handle) != HAL_OK) {
motor->drv8316_handle = NULL;
return HAL_ERROR;
}
#ifdef PWM_MODE_3IN
// Start PWM generation on all three phases
status = HAL_TIM_PWM_Start_IT(motor->pwmTimerHandle, motor->timerChannelU);
if (status != HAL_OK) return status;
status = HAL_TIM_PWM_Start_IT(motor->pwmTimerHandle, motor->timerChannelV);
if (status != HAL_OK) return status;
status = HAL_TIM_PWM_Start_IT(motor->pwmTimerHandle, motor->timerChannelW);
if (status != HAL_OK) return status;
#endif
#ifdef PWM_MODE_6IN
// Start PWM/PWM_N generation on all three phases
status = HAL_TIM_PWM_Start(motor->pwmTimerHandle, motor->timerChannelU);
if (status != HAL_OK) return status;
status = HAL_TIMEx_PWMN_Start(motor->pwmTimerHandle, motor->timerChannelU);
if (status != HAL_OK) return status;
status = HAL_TIM_PWM_Start(motor->pwmTimerHandle, motor->timerChannelV);
if (status != HAL_OK) return status;
status = HAL_TIMEx_PWMN_Start(motor->pwmTimerHandle, motor->timerChannelV);
if (status != HAL_OK) return status;
status = HAL_TIM_PWM_Start(motor->pwmTimerHandle, motor->timerChannelW);
if (status != HAL_OK) return status;
status = HAL_TIMEx_PWMN_Start(motor->pwmTimerHandle, motor->timerChannelW);
if (status != HAL_OK) return status;
#endif
//Start timer channel 4 for adc sync.
status = HAL_TIM_PWM_Start_IT(motor->pwmTimerHandle, motor->timerChannelADC);
if (status != HAL_OK) return status;
status = HAL_ADCEx_Calibration_Start(motor->phaseUADC, ADC_SINGLE_ENDED);
if (status != HAL_OK) return status;
status = HAL_ADCEx_Calibration_Start(motor->phaseVADC, ADC_SINGLE_ENDED);
if (status != HAL_OK) return status;
// Start ADC injected conversions
// ADC1 is master, ADC2 is slave in dual simultaneous mode
status = HAL_ADCEx_InjectedStart_IT(motor->phaseUADC);
if (status != HAL_OK) return status;
/*
status = HAL_ADCEx_InjectedStart_IT(motor->phaseVADC);
if (status != HAL_OK) return status;
*/
// Set duty cycles to 0 (zero voltage) before enabling
motor->phaseUduty = 0.0f;
motor->phaseVduty = 0.0f;
motor->phaseWduty = 0.0f;
motor->CCR4Duty = 0.9f;
API_Motor_SetDutyCycles(motor);
// Write max duty cycle to CCR4 register to start ADC injected channels
uint16_t ccr4Duty = (uint16_t)(motor->CCR4Duty*(float)(__HAL_TIM_GET_AUTORELOAD(motor->pwmTimerHandle)+1)) - 1;
__HAL_TIM_SET_COMPARE(motor->pwmTimerHandle, TIM_CHANNEL_4, ccr4Duty);
// Initialize GPIO pins
API_Motor_Disable(motor);
return HAL_OK;
}
2025-12-03 10:56 AM
Hey all,
I think I understand the problem.
HAL_TIMEx_PWMN_Start_IT function also enables the break interrupt so I think I need to manually enable the break interrupt when using the TIM_PWM_START_IT function.
Best regards