STMicroelectronics / STM32CubeF4

STM32Cube MCU Full Package for the STM32F4 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
Other
871 stars 418 forks source link

Trigger event triggered in MX_TIMx_Init (TIM_Base_SetConfig) causing triggering of slave timers initialised first #157

Open storm345 opened 1 year ago

storm345 commented 1 year ago

The MX_TIMx_Init function generated by codegen causes a trigger event to occur for the timer (Within TIM_Base_SetConfig in hal_tim). This means that if a timer is set to trigger in response to update from another timer then it will prematurely start during the codegen TIMx_Init functions if it was initialised before the master. This essentially means that successful timer synchronization when update is used as the trigger depends on the ordering of the MX_TIMx_Init codegen function calls.

The reason for the trigger event is as follows: Let's say TIM1 is the slave and TIM4 is the master (As in my code):

MX_TIM1_init is called. This sets the slave trigger bit in the register of TIM1 which starts it listening for trigger event from TIM4. TIM1 is not currently enabled (CEN bit of CR1). MX_TIM4_init is called. TIM4_CR2 register is initialized first with MMS bits set to 000, eg. Reset event is being used to send trigger output During MX_Tim4_Init, HAL_TIM_Base_Init is called. During this call the MMS bits is still 000. During HAL_TIM_Base_Init, TIM_Base_SetConfig is called. During this call the MMS bits is still 000. During the final line of TIM_Base_SetConfig there is the following:

/* Generate an update event to reload the Prescaler
and the repetition counter (only for advanced timer) value immediately */
TIMx->EGR = TIM_EGR_UG;

Before "TIMx->EGR = TIM_EGR_UG;" is executed TIM1 has CR1 has CEN bit of 0, eg. not enabled as expected. When "TIMx->EGR = TIM_EGR_UG;" is executed this causes a trigger event as the MMS is set to 000. This causes TIM1, which was initialized first, to detect the trigger event and enable. TIM1's CR1 CEN bit is now 1. As you can see from the above, this issue means timer slave triggering can happen during the initialisation of timers, rather than when they are started (As seems is the expected behaviour), if they are initialized in an unfavourable order. It would be great if this can be fixed in the HAL so that others do not run into the same issue.

A successful workaround is to add the following two lines into TIM_Base_SetConfig before "TIMx->EGR = TIM_EGR_UG;":

/* Reset the MMS Bits */
TIMx->CR2 &= ~TIM_CR2_MMS;
/* Select the TRGO source to one which will not be triggered by updating EGR register */
TIMx->CR2 |= TIM_TRGO_OC1REF;

Hopefully a less hacky solution can be found and implemented so others do not face this issue.

RJMSTM commented 1 year ago

Hello @storm345,

Thank you for this report. We will get back to you as soon as we analyze it further. This may take some time. Thank you for your comprehension.

With regards,

ASELSTM commented 1 year ago

Hi @storm345,

Would you please share the whole project you have used to reproduce the issue in order to allow a better analysis of the problem.

With regards,

storm345 commented 1 year ago

Hi @ASELSTM, unfortunately I cannot as it is not open source. I believe from my original description of the issue reproduction should not be difficult. If you have further specific questions about the circumstances of the bug I'm happy to answer

storm345 commented 1 year ago

Essentially "TIMx->EGR = TIM_EGR_UG;" causes the reset event to trigger when MMS bits are 000. In the initialization of the timers this situation is coded to occur, and thus the reset event causes the premature triggering of slave timers if they are initiailized before the master timer.

KRASTM commented 3 months ago

Hello @storm345,

Sorry for the very late response, regarding your issue,

Could you try to initialize the master before the slave? We suspect that a very similar issue has been reported in other series, and it is related to Cube Mx.

With regards.

storm345 commented 3 months ago

Hi krastm, as mentioned in the original ticket initialising the master before the slave does fix the issue yes. However the problem is that using code gen there is not user control with CubeMX of the order of initialisation of the timers, so codegen will generate code that causes this issue. The issue should be fixed properly in the HAL so initialisation order is not a factor

storm345 commented 3 months ago

If nothing neater can be found, the successful workaround provided in the original ticket would be a functional (though messy) fix to the issue you could use.

KRASTM commented 3 months ago

Hello @storm345,

Our development team is analyzing the 2 solutions, and they will decide which one to implement, either:

I will keep you informed.

With regards,

KRASTM commented 3 months ago

ST Internal Reference: 158271