Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stm32/timer: Cannot specify timer callbacks using callback(). #9182

Closed
wants to merge 1 commit into from

Conversation

yn386
Copy link
Contributor

@yn386 yn386 commented Sep 1, 2022

This PR fixes issue #8732.

MicroPython Version

v1.19.1

How to reproduce

Execute attached in #8732.
Specified callback is not called.

Detail of changes

Since HAL version 1.17.0, HAL_TIM_IC_Start_IT() checks whether specified channel of timer is busy or not.

+HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
 {
+  uint32_t tmpsmcr;
+  HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel);
+  HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel);
+
   /* Check the parameters */
   assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));

+  /* Check the TIM channel state */
+  if ((channel_state != HAL_TIM_CHANNEL_STATE_READY)
+      || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Set the TIM channel state */
+  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
+  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
+

For more detail of changes, see git diff 540ae5c5 9153dc73 STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c in lib/stm32lib.

timer.c calls HAL_TIM_IC_Start() when callback parameter is not specified.

if (chan->callback == mp_const_none) {
HAL_TIM_IC_Start(&self->tim, TIMER_CHANNEL(chan));
} else {
pyb_timer_channel_callback(MP_OBJ_FROM_PTR(chan), chan->callback);
}

After callback() is called by python, call HAL_TIM_IC_Start_IT() at
case CHANNEL_MODE_IC:
HAL_TIM_IC_Start_IT(&self->timer->tim, TIMER_CHANNEL(self));
break;

but the timer is already running, so HAL_TIM_IC_Start_IT() returns HAL_ERROR and irq of timer is not enabled here.

This issue is not occurred if Timer.channel() is called with paramerter 'callback' because HAL_TIM_IC_Start_IT() is called in pyb_timer_channel_callback() and irq of timer is enabled.

To prevent this error, call HAL_TIM_IC_Stop_IT() before HAL_TIM_IC_Start_IT().
Mode PWM and OC have same issue, so I also fixed those.

@dpgeorge
Copy link
Member

dpgeorge commented Sep 6, 2022

Thank you. Tested on STM32L476DISC and PYBV10 (to check it didn't change behaviour of other MCUs), rebased and merged in 989b8c7

@dpgeorge dpgeorge closed this Sep 6, 2022
@yn386 yn386 deleted the issue_8732 branch September 6, 2022 23:43
@chrismas9
Copy link
Contributor

@yn386 Thanks for the fix. Tested on NUCLEO_L452RE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants