AnsweredAssumed Answered

STM32F7xx_hal_tim_ex.c Bug report

Question asked by seongho lee on Jun 14, 2017
Latest reply on Jun 14, 2017 by Amel N

Hi all,

 

i generated the pwm related source code using CubeMX 4.21 but it dit not work.

Target MCU : ST32F746NG

 

The following general PWM code works normally but not with DMA Functions.

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);

 

Inoperative code : 

HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1, (uint32_t *)sendBuff, 16);

 

Other MCU (as STM32F407 Discovery board, TIM4_CH1) was targeted and the code was generated with the smae rule (same method, same programs), it worked normally.

also, when TIM1 was replaced with TIM3 on ST32F746NG, perfectly operation was performed.

 

I debugged these problems and found a small buf.

 

When using the TIM1 timer in Cube MX, HAL_TIMEx_ConfigBreakDeadTime is generated in the 'MX_TIM1_Init(...'

The code to set the Busy flag (htim->State = HAL_TIM_STATE_BUSY;), but it did not exist to reverse the code.

 

So, for functions that do not check the htim-State (READY), it works perfectly fine, but in the htim-state checking code there was a problem.

 

The solution is to add  ' htim->State = HAL_TIM_STATE_READY; ' at the bottom of the 'HAL_TIMEx_ConfigBreakDeadTime' function. However, if you regenerate the code by CubeMX, it will be deleted.

 

Another solution is the enter the code below into the area that is not cleared by CubeMX.

 

in int main(void) ... (main.c)

------------------------------------------------------------------------------

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM1_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
htim1.State = HAL_TIM_STATE_READY; // <<-- avoid bug
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1, (uint32_t *)sendBuff, 16);

-----------------------------------------------------------------------

 

 

The modified stm32f7xx_hal_tim_ex.c file is attached to the lower part of the file.

 

 

regards

Seong ho Lee

Dankook University

 

 

 

 

 

 

 

 

Fixed Codes

-----------------------------------------------------------------------

/**
* @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
* and the AOE(automatic output enable).
* @param htim: pointer to a TIM_HandleTypeDef structure that contains
* the configuration information for TIM module.
* @param sBreakDeadTimeConfig: pointer to a TIM_ConfigBreakDeadConfig_TypeDef structure that
* contains the BDTR Register configuration information for the TIM peripheral.
* @retval HAL status
*/

HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig)
{
uint32_t tmpbdtr = 0;

/* Check the parameters */
assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));

/* Check input state */
__HAL_LOCK(htim);

htim->State = HAL_TIM_STATE_BUSY;
/* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
the OSSI State, the dead time value and the Automatic Output Enable Bit */

/* Set the BDTR bits */
MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, sBreakDeadTimeConfig->AutomaticOutput);
MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << BDTR_BKF_SHIFT));

if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
{
assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));

/* Set the BREAK2 input related BDTR bits */
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << BDTR_BK2F_SHIFT));
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
}

htim->State = HAL_TIM_STATE_READY;

/* Set TIMx_BDTR */
htim->Instance->BDTR = tmpbdtr;

__HAL_UNLOCK(htim);

return HAL_OK;
}

Outcomes