cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G4 Timer Break Interrupt Callback Function

batuhanky
Associate III

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

image_2025-12-01_225352148.pngimage_2025-12-01_225402390.pngimage_2025-12-01_225411569.pngimage_2025-12-01_225426620.png

1 ACCEPTED SOLUTION

Accepted Solutions

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

View solution in original post

8 REPLIES 8
TDK
Super User

Does a breakpoint in TIM1_BRK_TIM15_IRQHandler ever get hit?

 

If you feel a post has answered your question, please click "Accept as Solution".
Saket_Om
ST Employee

Hello @batuhanky 

Could you please check if the break interrupt (BIE) is enabled in the TIMx_DIER register? 

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.
Saket_Om

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.

batuhanky_0-1764702763640.png

 

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);

 

TDK
Super User

Use HAL_TIMEx_PWMN_Start_IT to start the channel

This would be much easier to diagnose if you showed your full code.

If you feel a post has answered your question, please click "Accept as Solution".

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

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.
Saket_Om

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;
}

 

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