1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_tim_ex.c
4   * @author  MCD Application Team
5   * @brief   TIM HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Timer Extended peripheral:
8   *           + Time Hall Sensor Interface Initialization
9   *           + Time Hall Sensor Interface Start
10   *           + Time Complementary signal break and dead time configuration
11   *           + Time Master and Slave synchronization configuration
12   *           + Time Output Compare/PWM Channel Configuration (for channels 5 and 6)
13   *           + Timer remapping capabilities configuration
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2019 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                       ##### TIMER Extended features #####
28   ==============================================================================
29   [..]
30     The Timer Extended features include:
31     (#) Complementary outputs with programmable dead-time for :
32         (++) Output Compare
33         (++) PWM generation (Edge and Center-aligned Mode)
34         (++) One-pulse mode output
35     (#) Synchronization circuit to control the timer with external signals and to
36         interconnect several timers together.
37     (#) Break input to put the timer output signals in reset state or in a known state.
38     (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
39         positioning purposes
40 
41             ##### How to use this driver #####
42   ==============================================================================
43     [..]
44      (#) Initialize the TIM low level resources by implementing the following functions
45          depending on the selected feature:
46            (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
47 
48      (#) Initialize the TIM low level resources :
49         (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
50         (##) TIM pins configuration
51             (+++) Enable the clock for the TIM GPIOs using the following function:
52               __HAL_RCC_GPIOx_CLK_ENABLE();
53             (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
54 
55      (#) The external Clock can be configured, if needed (the default clock is the
56          internal clock from the APBx), using the following function:
57          HAL_TIM_ConfigClockSource, the clock configuration should be done before
58          any start function.
59 
60      (#) Configure the TIM in the desired functioning mode using one of the
61          initialization function of this driver:
62           (++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the
63                Timer Hall Sensor Interface and the commutation event with the corresponding
64                Interrupt and DMA request if needed (Note that One Timer is used to interface
65                with the Hall sensor Interface and another Timer should be used to use
66                the commutation event).
67 
68      (#) Activate the TIM peripheral using one of the start functions:
69            (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(),
70                 HAL_TIMEx_OCN_Start_IT()
71            (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(),
72                 HAL_TIMEx_PWMN_Start_IT()
73            (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
74            (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(),
75                 HAL_TIMEx_HallSensor_Start_IT().
76 
77   @endverbatim
78   ******************************************************************************
79   */
80 
81 /* Includes ------------------------------------------------------------------*/
82 #include "stm32l5xx_hal.h"
83 
84 /** @addtogroup STM32L5xx_HAL_Driver
85   * @{
86   */
87 
88 /** @defgroup TIMEx TIMEx
89   * @brief TIM Extended HAL module driver
90   * @{
91   */
92 
93 #ifdef HAL_TIM_MODULE_ENABLED
94 
95 /* Private typedef -----------------------------------------------------------*/
96 /* Private define ------------------------------------------------------------*/
97 /* Private constants ---------------------------------------------------------*/
98 /** @defgroup TIMEx_Private_Constants TIM Extended Private Constants
99   * @{
100   */
101 /* Timeout for break input rearm */
102 #define TIM_BREAKINPUT_REARM_TIMEOUT    5UL /* 5 milliseconds */
103 /**
104   * @}
105   */
106 /* End of private constants --------------------------------------------------*/
107 
108 /* Private macros ------------------------------------------------------------*/
109 /* Private variables ---------------------------------------------------------*/
110 /* Private function prototypes -----------------------------------------------*/
111 static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma);
112 static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma);
113 static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState);
114 
115 /* Exported functions --------------------------------------------------------*/
116 /** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions
117   * @{
118   */
119 
120 /** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions
121   * @brief    Timer Hall Sensor functions
122   *
123 @verbatim
124   ==============================================================================
125                       ##### Timer Hall Sensor functions #####
126   ==============================================================================
127   [..]
128     This section provides functions allowing to:
129     (+) Initialize and configure TIM HAL Sensor.
130     (+) De-initialize TIM HAL Sensor.
131     (+) Start the Hall Sensor Interface.
132     (+) Stop the Hall Sensor Interface.
133     (+) Start the Hall Sensor Interface and enable interrupts.
134     (+) Stop the Hall Sensor Interface and disable interrupts.
135     (+) Start the Hall Sensor Interface and enable DMA transfers.
136     (+) Stop the Hall Sensor Interface and disable DMA transfers.
137 
138 @endverbatim
139   * @{
140   */
141 /**
142   * @brief  Initializes the TIM Hall Sensor Interface and initialize the associated handle.
143   * @note   When the timer instance is initialized in Hall Sensor Interface mode,
144   *         timer channels 1 and channel 2 are reserved and cannot be used for
145   *         other purpose.
146   * @param  htim TIM Hall Sensor Interface handle
147   * @param  sConfig TIM Hall Sensor configuration structure
148   * @retval HAL status
149   */
HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef * htim,const TIM_HallSensor_InitTypeDef * sConfig)150 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig)
151 {
152   TIM_OC_InitTypeDef OC_Config;
153 
154   /* Check the TIM handle allocation */
155   if (htim == NULL)
156   {
157     return HAL_ERROR;
158   }
159 
160   /* Check the parameters */
161   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
162   assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
163   assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
164   assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
165   assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
166   assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
167   assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
168   assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
169 
170   if (htim->State == HAL_TIM_STATE_RESET)
171   {
172     /* Allocate lock resource and initialize it */
173     htim->Lock = HAL_UNLOCKED;
174 
175 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
176     /* Reset interrupt callbacks to legacy week callbacks */
177     TIM_ResetCallback(htim);
178 
179     if (htim->HallSensor_MspInitCallback == NULL)
180     {
181       htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit;
182     }
183     /* Init the low level hardware : GPIO, CLOCK, NVIC */
184     htim->HallSensor_MspInitCallback(htim);
185 #else
186     /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
187     HAL_TIMEx_HallSensor_MspInit(htim);
188 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
189   }
190 
191   /* Set the TIM state */
192   htim->State = HAL_TIM_STATE_BUSY;
193 
194   /* Configure the Time base in the Encoder Mode */
195   TIM_Base_SetConfig(htim->Instance, &htim->Init);
196 
197   /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the  Hall sensor */
198   TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
199 
200   /* Reset the IC1PSC Bits */
201   htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
202   /* Set the IC1PSC value */
203   htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
204 
205   /* Enable the Hall sensor interface (XOR function of the three inputs) */
206   htim->Instance->CR2 |= TIM_CR2_TI1S;
207 
208   /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
209   htim->Instance->SMCR &= ~TIM_SMCR_TS;
210   htim->Instance->SMCR |= TIM_TS_TI1F_ED;
211 
212   /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
213   htim->Instance->SMCR &= ~TIM_SMCR_SMS;
214   htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
215 
216   /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
217   OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
218   OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
219   OC_Config.OCMode = TIM_OCMODE_PWM2;
220   OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
221   OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
222   OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
223   OC_Config.Pulse = sConfig->Commutation_Delay;
224 
225   TIM_OC2_SetConfig(htim->Instance, &OC_Config);
226 
227   /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
228     register to 101 */
229   htim->Instance->CR2 &= ~TIM_CR2_MMS;
230   htim->Instance->CR2 |= TIM_TRGO_OC2REF;
231 
232   /* Initialize the DMA burst operation state */
233   htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
234 
235   /* Initialize the TIM channels state */
236   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
237   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
238   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
239   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
240 
241   /* Initialize the TIM state*/
242   htim->State = HAL_TIM_STATE_READY;
243 
244   return HAL_OK;
245 }
246 
247 /**
248   * @brief  DeInitializes the TIM Hall Sensor interface
249   * @param  htim TIM Hall Sensor Interface handle
250   * @retval HAL status
251   */
HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef * htim)252 HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
253 {
254   /* Check the parameters */
255   assert_param(IS_TIM_INSTANCE(htim->Instance));
256 
257   htim->State = HAL_TIM_STATE_BUSY;
258 
259   /* Disable the TIM Peripheral Clock */
260   __HAL_TIM_DISABLE(htim);
261 
262 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
263   if (htim->HallSensor_MspDeInitCallback == NULL)
264   {
265     htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit;
266   }
267   /* DeInit the low level hardware */
268   htim->HallSensor_MspDeInitCallback(htim);
269 #else
270   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
271   HAL_TIMEx_HallSensor_MspDeInit(htim);
272 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
273 
274   /* Change the DMA burst operation state */
275   htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
276 
277   /* Change the TIM channels state */
278   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
279   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
280   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
281   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
282 
283   /* Change TIM state */
284   htim->State = HAL_TIM_STATE_RESET;
285 
286   /* Release Lock */
287   __HAL_UNLOCK(htim);
288 
289   return HAL_OK;
290 }
291 
292 /**
293   * @brief  Initializes the TIM Hall Sensor MSP.
294   * @param  htim TIM Hall Sensor Interface handle
295   * @retval None
296   */
HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef * htim)297 __weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
298 {
299   /* Prevent unused argument(s) compilation warning */
300   UNUSED(htim);
301 
302   /* NOTE : This function should not be modified, when the callback is needed,
303             the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
304    */
305 }
306 
307 /**
308   * @brief  DeInitializes TIM Hall Sensor MSP.
309   * @param  htim TIM Hall Sensor Interface handle
310   * @retval None
311   */
HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef * htim)312 __weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
313 {
314   /* Prevent unused argument(s) compilation warning */
315   UNUSED(htim);
316 
317   /* NOTE : This function should not be modified, when the callback is needed,
318             the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
319    */
320 }
321 
322 /**
323   * @brief  Starts the TIM Hall Sensor Interface.
324   * @param  htim TIM Hall Sensor Interface handle
325   * @retval HAL status
326   */
HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef * htim)327 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
328 {
329   uint32_t tmpsmcr;
330   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
331   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
332   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
333   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
334 
335   /* Check the parameters */
336   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
337 
338   /* Check the TIM channels state */
339   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
340       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
341       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
342       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
343   {
344     return HAL_ERROR;
345   }
346 
347   /* Set the TIM channels state */
348   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
349   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
350   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
351   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
352 
353   /* Enable the Input Capture channel 1
354   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
355   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
356   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
357 
358   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
359   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
360   {
361     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
362     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
363     {
364       __HAL_TIM_ENABLE(htim);
365     }
366   }
367   else
368   {
369     __HAL_TIM_ENABLE(htim);
370   }
371 
372   /* Return function status */
373   return HAL_OK;
374 }
375 
376 /**
377   * @brief  Stops the TIM Hall sensor Interface.
378   * @param  htim TIM Hall Sensor Interface handle
379   * @retval HAL status
380   */
HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef * htim)381 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
382 {
383   /* Check the parameters */
384   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
385 
386   /* Disable the Input Capture channels 1, 2 and 3
387   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
388   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
389   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
390 
391   /* Disable the Peripheral */
392   __HAL_TIM_DISABLE(htim);
393 
394   /* Set the TIM channels state */
395   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
396   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
397   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
398   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
399 
400   /* Return function status */
401   return HAL_OK;
402 }
403 
404 /**
405   * @brief  Starts the TIM Hall Sensor Interface in interrupt mode.
406   * @param  htim TIM Hall Sensor Interface handle
407   * @retval HAL status
408   */
HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef * htim)409 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
410 {
411   uint32_t tmpsmcr;
412   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
413   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
414   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
415   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
416 
417   /* Check the parameters */
418   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
419 
420   /* Check the TIM channels state */
421   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
422       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
423       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
424       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
425   {
426     return HAL_ERROR;
427   }
428 
429   /* Set the TIM channels state */
430   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
431   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
432   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
433   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
434 
435   /* Enable the capture compare Interrupts 1 event */
436   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
437 
438   /* Enable the Input Capture channel 1
439   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
440   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
441   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
442 
443   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
444   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
445   {
446     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
447     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
448     {
449       __HAL_TIM_ENABLE(htim);
450     }
451   }
452   else
453   {
454     __HAL_TIM_ENABLE(htim);
455   }
456 
457   /* Return function status */
458   return HAL_OK;
459 }
460 
461 /**
462   * @brief  Stops the TIM Hall Sensor Interface in interrupt mode.
463   * @param  htim TIM Hall Sensor Interface handle
464   * @retval HAL status
465   */
HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef * htim)466 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
467 {
468   /* Check the parameters */
469   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
470 
471   /* Disable the Input Capture channel 1
472   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
473   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
474   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
475 
476   /* Disable the capture compare Interrupts event */
477   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
478 
479   /* Disable the Peripheral */
480   __HAL_TIM_DISABLE(htim);
481 
482   /* Set the TIM channels state */
483   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
484   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
485   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
486   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
487 
488   /* Return function status */
489   return HAL_OK;
490 }
491 
492 /**
493   * @brief  Starts the TIM Hall Sensor Interface in DMA mode.
494   * @param  htim TIM Hall Sensor Interface handle
495   * @param  pData The destination Buffer address.
496   * @param  Length The length of data to be transferred from TIM peripheral to memory.
497   * @retval HAL status
498   */
HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef * htim,uint32_t * pData,uint16_t Length)499 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
500 {
501   uint32_t tmpsmcr;
502   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
503   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
504 
505   /* Check the parameters */
506   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
507 
508   /* Set the TIM channel state */
509   if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
510       || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY))
511   {
512     return HAL_BUSY;
513   }
514   else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
515            && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY))
516   {
517     if ((pData == NULL) || (Length == 0U))
518     {
519       return HAL_ERROR;
520     }
521     else
522     {
523       TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
524       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
525     }
526   }
527   else
528   {
529     return HAL_ERROR;
530   }
531 
532   /* Enable the Input Capture channel 1
533   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
534   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
535   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
536 
537   /* Set the DMA Input Capture 1 Callbacks */
538   htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
539   htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
540   /* Set the DMA error callback */
541   htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
542 
543   /* Enable the DMA channel for Capture 1*/
544   if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK)
545   {
546     /* Return error status */
547     return HAL_ERROR;
548   }
549   /* Enable the capture compare 1 Interrupt */
550   __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
551 
552   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
553   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
554   {
555     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
556     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
557     {
558       __HAL_TIM_ENABLE(htim);
559     }
560   }
561   else
562   {
563     __HAL_TIM_ENABLE(htim);
564   }
565 
566   /* Return function status */
567   return HAL_OK;
568 }
569 
570 /**
571   * @brief  Stops the TIM Hall Sensor Interface in DMA mode.
572   * @param  htim TIM Hall Sensor Interface handle
573   * @retval HAL status
574   */
HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef * htim)575 HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
576 {
577   /* Check the parameters */
578   assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
579 
580   /* Disable the Input Capture channel 1
581   (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
582   TIM_CHANNEL_2 and TIM_CHANNEL_3) */
583   TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
584 
585 
586   /* Disable the capture compare Interrupts 1 event */
587   __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
588 
589   (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
590 
591   /* Disable the Peripheral */
592   __HAL_TIM_DISABLE(htim);
593 
594   /* Set the TIM channel state */
595   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
596   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
597 
598   /* Return function status */
599   return HAL_OK;
600 }
601 
602 /**
603   * @}
604   */
605 
606 /** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions
607   *  @brief   Timer Complementary Output Compare functions
608   *
609 @verbatim
610   ==============================================================================
611               ##### Timer Complementary Output Compare functions #####
612   ==============================================================================
613   [..]
614     This section provides functions allowing to:
615     (+) Start the Complementary Output Compare/PWM.
616     (+) Stop the Complementary Output Compare/PWM.
617     (+) Start the Complementary Output Compare/PWM and enable interrupts.
618     (+) Stop the Complementary Output Compare/PWM and disable interrupts.
619     (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
620     (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
621 
622 @endverbatim
623   * @{
624   */
625 
626 /**
627   * @brief  Starts the TIM Output Compare signal generation on the complementary
628   *         output.
629   * @param  htim TIM Output Compare handle
630   * @param  Channel TIM Channel to be enabled
631   *          This parameter can be one of the following values:
632   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
633   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
634   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
635   * @retval HAL status
636   */
HAL_TIMEx_OCN_Start(TIM_HandleTypeDef * htim,uint32_t Channel)637 HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
638 {
639   uint32_t tmpsmcr;
640 
641   /* Check the parameters */
642   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
643 
644   /* Check the TIM complementary channel state */
645   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
646   {
647     return HAL_ERROR;
648   }
649 
650   /* Set the TIM complementary channel state */
651   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
652 
653   /* Enable the Capture compare channel N */
654   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
655 
656   /* Enable the Main Output */
657   __HAL_TIM_MOE_ENABLE(htim);
658 
659   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
660   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
661   {
662     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
663     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
664     {
665       __HAL_TIM_ENABLE(htim);
666     }
667   }
668   else
669   {
670     __HAL_TIM_ENABLE(htim);
671   }
672 
673   /* Return function status */
674   return HAL_OK;
675 }
676 
677 /**
678   * @brief  Stops the TIM Output Compare signal generation on the complementary
679   *         output.
680   * @param  htim TIM handle
681   * @param  Channel TIM Channel to be disabled
682   *          This parameter can be one of the following values:
683   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
684   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
685   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
686   * @retval HAL status
687   */
HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef * htim,uint32_t Channel)688 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
689 {
690   /* Check the parameters */
691   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
692 
693   /* Disable the Capture compare channel N */
694   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
695 
696   /* Disable the Main Output */
697   __HAL_TIM_MOE_DISABLE(htim);
698 
699   /* Disable the Peripheral */
700   __HAL_TIM_DISABLE(htim);
701 
702   /* Set the TIM complementary channel state */
703   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
704 
705   /* Return function status */
706   return HAL_OK;
707 }
708 
709 /**
710   * @brief  Starts the TIM Output Compare signal generation in interrupt mode
711   *         on the complementary output.
712   * @param  htim TIM OC handle
713   * @param  Channel TIM Channel to be enabled
714   *          This parameter can be one of the following values:
715   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
716   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
717   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
718   * @retval HAL status
719   */
HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef * htim,uint32_t Channel)720 HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
721 {
722   HAL_StatusTypeDef status = HAL_OK;
723   uint32_t tmpsmcr;
724 
725   /* Check the parameters */
726   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
727 
728   /* Check the TIM complementary channel state */
729   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
730   {
731     return HAL_ERROR;
732   }
733 
734   /* Set the TIM complementary channel state */
735   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
736 
737   switch (Channel)
738   {
739     case TIM_CHANNEL_1:
740     {
741       /* Enable the TIM Output Compare interrupt */
742       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
743       break;
744     }
745 
746     case TIM_CHANNEL_2:
747     {
748       /* Enable the TIM Output Compare interrupt */
749       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
750       break;
751     }
752 
753     case TIM_CHANNEL_3:
754     {
755       /* Enable the TIM Output Compare interrupt */
756       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
757       break;
758     }
759 
760 
761     default:
762       status = HAL_ERROR;
763       break;
764   }
765 
766   if (status == HAL_OK)
767   {
768     /* Enable the TIM Break interrupt */
769     __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
770 
771     /* Enable the Capture compare channel N */
772     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
773 
774     /* Enable the Main Output */
775     __HAL_TIM_MOE_ENABLE(htim);
776 
777     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
778     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
779     {
780       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
781       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
782       {
783         __HAL_TIM_ENABLE(htim);
784       }
785     }
786     else
787     {
788       __HAL_TIM_ENABLE(htim);
789     }
790   }
791 
792   /* Return function status */
793   return status;
794 }
795 
796 /**
797   * @brief  Stops the TIM Output Compare signal generation in interrupt mode
798   *         on the complementary output.
799   * @param  htim TIM Output Compare handle
800   * @param  Channel TIM Channel to be disabled
801   *          This parameter can be one of the following values:
802   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
803   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
804   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
805   * @retval HAL status
806   */
HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t Channel)807 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
808 {
809   HAL_StatusTypeDef status = HAL_OK;
810   uint32_t tmpccer;
811 
812   /* Check the parameters */
813   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
814 
815   switch (Channel)
816   {
817     case TIM_CHANNEL_1:
818     {
819       /* Disable the TIM Output Compare interrupt */
820       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
821       break;
822     }
823 
824     case TIM_CHANNEL_2:
825     {
826       /* Disable the TIM Output Compare interrupt */
827       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
828       break;
829     }
830 
831     case TIM_CHANNEL_3:
832     {
833       /* Disable the TIM Output Compare interrupt */
834       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
835       break;
836     }
837 
838     default:
839       status = HAL_ERROR;
840       break;
841   }
842 
843   if (status == HAL_OK)
844   {
845     /* Disable the Capture compare channel N */
846     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
847 
848     /* Disable the TIM Break interrupt (only if no more channel is active) */
849     tmpccer = htim->Instance->CCER;
850     if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
851     {
852       __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
853     }
854 
855     /* Disable the Main Output */
856     __HAL_TIM_MOE_DISABLE(htim);
857 
858     /* Disable the Peripheral */
859     __HAL_TIM_DISABLE(htim);
860 
861     /* Set the TIM complementary channel state */
862     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
863   }
864 
865   /* Return function status */
866   return status;
867 }
868 
869 /**
870   * @brief  Starts the TIM Output Compare signal generation in DMA mode
871   *         on the complementary output.
872   * @param  htim TIM Output Compare handle
873   * @param  Channel TIM Channel to be enabled
874   *          This parameter can be one of the following values:
875   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
876   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
877   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
878   * @param  pData The source Buffer address.
879   * @param  Length The length of data to be transferred from memory to TIM peripheral
880   * @retval HAL status
881   */
HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef * htim,uint32_t Channel,const uint32_t * pData,uint16_t Length)882 HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
883                                           uint16_t Length)
884 {
885   HAL_StatusTypeDef status = HAL_OK;
886   uint32_t tmpsmcr;
887 
888   /* Check the parameters */
889   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
890 
891   /* Set the TIM complementary channel state */
892   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
893   {
894     return HAL_BUSY;
895   }
896   else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
897   {
898     if ((pData == NULL) || (Length == 0U))
899     {
900       return HAL_ERROR;
901     }
902     else
903     {
904       TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
905     }
906   }
907   else
908   {
909     return HAL_ERROR;
910   }
911 
912   switch (Channel)
913   {
914     case TIM_CHANNEL_1:
915     {
916       /* Set the DMA compare callbacks */
917       htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
918       htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
919 
920       /* Set the DMA error callback */
921       htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
922 
923       /* Enable the DMA channel */
924       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
925                            Length) != HAL_OK)
926       {
927         /* Return error status */
928         return HAL_ERROR;
929       }
930       /* Enable the TIM Output Compare DMA request */
931       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
932       break;
933     }
934 
935     case TIM_CHANNEL_2:
936     {
937       /* Set the DMA compare callbacks */
938       htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
939       htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
940 
941       /* Set the DMA error callback */
942       htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
943 
944       /* Enable the DMA channel */
945       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
946                            Length) != HAL_OK)
947       {
948         /* Return error status */
949         return HAL_ERROR;
950       }
951       /* Enable the TIM Output Compare DMA request */
952       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
953       break;
954     }
955 
956     case TIM_CHANNEL_3:
957     {
958       /* Set the DMA compare callbacks */
959       htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
960       htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
961 
962       /* Set the DMA error callback */
963       htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
964 
965       /* Enable the DMA channel */
966       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
967                            Length) != HAL_OK)
968       {
969         /* Return error status */
970         return HAL_ERROR;
971       }
972       /* Enable the TIM Output Compare DMA request */
973       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
974       break;
975     }
976 
977     default:
978       status = HAL_ERROR;
979       break;
980   }
981 
982   if (status == HAL_OK)
983   {
984     /* Enable the Capture compare channel N */
985     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
986 
987     /* Enable the Main Output */
988     __HAL_TIM_MOE_ENABLE(htim);
989 
990     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
991     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
992     {
993       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
994       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
995       {
996         __HAL_TIM_ENABLE(htim);
997       }
998     }
999     else
1000     {
1001       __HAL_TIM_ENABLE(htim);
1002     }
1003   }
1004 
1005   /* Return function status */
1006   return status;
1007 }
1008 
1009 /**
1010   * @brief  Stops the TIM Output Compare signal generation in DMA mode
1011   *         on the complementary output.
1012   * @param  htim TIM Output Compare handle
1013   * @param  Channel TIM Channel to be disabled
1014   *          This parameter can be one of the following values:
1015   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1016   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1017   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1018   * @retval HAL status
1019   */
HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef * htim,uint32_t Channel)1020 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
1021 {
1022   HAL_StatusTypeDef status = HAL_OK;
1023 
1024   /* Check the parameters */
1025   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1026 
1027   switch (Channel)
1028   {
1029     case TIM_CHANNEL_1:
1030     {
1031       /* Disable the TIM Output Compare DMA request */
1032       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
1033       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
1034       break;
1035     }
1036 
1037     case TIM_CHANNEL_2:
1038     {
1039       /* Disable the TIM Output Compare DMA request */
1040       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
1041       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
1042       break;
1043     }
1044 
1045     case TIM_CHANNEL_3:
1046     {
1047       /* Disable the TIM Output Compare DMA request */
1048       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
1049       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
1050       break;
1051     }
1052 
1053     default:
1054       status = HAL_ERROR;
1055       break;
1056   }
1057 
1058   if (status == HAL_OK)
1059   {
1060     /* Disable the Capture compare channel N */
1061     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1062 
1063     /* Disable the Main Output */
1064     __HAL_TIM_MOE_DISABLE(htim);
1065 
1066     /* Disable the Peripheral */
1067     __HAL_TIM_DISABLE(htim);
1068 
1069     /* Set the TIM complementary channel state */
1070     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1071   }
1072 
1073   /* Return function status */
1074   return status;
1075 }
1076 
1077 /**
1078   * @}
1079   */
1080 
1081 /** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions
1082   * @brief    Timer Complementary PWM functions
1083   *
1084 @verbatim
1085   ==============================================================================
1086                  ##### Timer Complementary PWM functions #####
1087   ==============================================================================
1088   [..]
1089     This section provides functions allowing to:
1090     (+) Start the Complementary PWM.
1091     (+) Stop the Complementary PWM.
1092     (+) Start the Complementary PWM and enable interrupts.
1093     (+) Stop the Complementary PWM and disable interrupts.
1094     (+) Start the Complementary PWM and enable DMA transfers.
1095     (+) Stop the Complementary PWM and disable DMA transfers.
1096     (+) Start the Complementary Input Capture measurement.
1097     (+) Stop the Complementary Input Capture.
1098     (+) Start the Complementary Input Capture and enable interrupts.
1099     (+) Stop the Complementary Input Capture and disable interrupts.
1100     (+) Start the Complementary Input Capture and enable DMA transfers.
1101     (+) Stop the Complementary Input Capture and disable DMA transfers.
1102     (+) Start the Complementary One Pulse generation.
1103     (+) Stop the Complementary One Pulse.
1104     (+) Start the Complementary One Pulse and enable interrupts.
1105     (+) Stop the Complementary One Pulse and disable interrupts.
1106 
1107 @endverbatim
1108   * @{
1109   */
1110 
1111 /**
1112   * @brief  Starts the PWM signal generation on the complementary output.
1113   * @param  htim TIM handle
1114   * @param  Channel TIM Channel to be enabled
1115   *          This parameter can be one of the following values:
1116   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1117   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1118   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1119   * @retval HAL status
1120   */
HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef * htim,uint32_t Channel)1121 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
1122 {
1123   uint32_t tmpsmcr;
1124 
1125   /* Check the parameters */
1126   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1127 
1128   /* Check the TIM complementary channel state */
1129   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
1130   {
1131     return HAL_ERROR;
1132   }
1133 
1134   /* Set the TIM complementary channel state */
1135   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1136 
1137   /* Enable the complementary PWM output  */
1138   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1139 
1140   /* Enable the Main Output */
1141   __HAL_TIM_MOE_ENABLE(htim);
1142 
1143   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1144   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1145   {
1146     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1147     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1148     {
1149       __HAL_TIM_ENABLE(htim);
1150     }
1151   }
1152   else
1153   {
1154     __HAL_TIM_ENABLE(htim);
1155   }
1156 
1157   /* Return function status */
1158   return HAL_OK;
1159 }
1160 
1161 /**
1162   * @brief  Stops the PWM signal generation on the complementary output.
1163   * @param  htim TIM handle
1164   * @param  Channel TIM Channel to be disabled
1165   *          This parameter can be one of the following values:
1166   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1167   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1168   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1169   * @retval HAL status
1170   */
HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef * htim,uint32_t Channel)1171 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
1172 {
1173   /* Check the parameters */
1174   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1175 
1176   /* Disable the complementary PWM output  */
1177   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1178 
1179   /* Disable the Main Output */
1180   __HAL_TIM_MOE_DISABLE(htim);
1181 
1182   /* Disable the Peripheral */
1183   __HAL_TIM_DISABLE(htim);
1184 
1185   /* Set the TIM complementary channel state */
1186   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1187 
1188   /* Return function status */
1189   return HAL_OK;
1190 }
1191 
1192 /**
1193   * @brief  Starts the PWM signal generation in interrupt mode on the
1194   *         complementary output.
1195   * @param  htim TIM handle
1196   * @param  Channel TIM Channel to be disabled
1197   *          This parameter can be one of the following values:
1198   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1199   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1200   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1201   * @retval HAL status
1202   */
HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef * htim,uint32_t Channel)1203 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
1204 {
1205   HAL_StatusTypeDef status = HAL_OK;
1206   uint32_t tmpsmcr;
1207 
1208   /* Check the parameters */
1209   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1210 
1211   /* Check the TIM complementary channel state */
1212   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
1213   {
1214     return HAL_ERROR;
1215   }
1216 
1217   /* Set the TIM complementary channel state */
1218   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1219 
1220   switch (Channel)
1221   {
1222     case TIM_CHANNEL_1:
1223     {
1224       /* Enable the TIM Capture/Compare 1 interrupt */
1225       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
1226       break;
1227     }
1228 
1229     case TIM_CHANNEL_2:
1230     {
1231       /* Enable the TIM Capture/Compare 2 interrupt */
1232       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
1233       break;
1234     }
1235 
1236     case TIM_CHANNEL_3:
1237     {
1238       /* Enable the TIM Capture/Compare 3 interrupt */
1239       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
1240       break;
1241     }
1242 
1243     default:
1244       status = HAL_ERROR;
1245       break;
1246   }
1247 
1248   if (status == HAL_OK)
1249   {
1250     /* Enable the TIM Break interrupt */
1251     __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
1252 
1253     /* Enable the complementary PWM output  */
1254     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1255 
1256     /* Enable the Main Output */
1257     __HAL_TIM_MOE_ENABLE(htim);
1258 
1259     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1260     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1261     {
1262       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1263       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1264       {
1265         __HAL_TIM_ENABLE(htim);
1266       }
1267     }
1268     else
1269     {
1270       __HAL_TIM_ENABLE(htim);
1271     }
1272   }
1273 
1274   /* Return function status */
1275   return status;
1276 }
1277 
1278 /**
1279   * @brief  Stops the PWM signal generation in interrupt mode on the
1280   *         complementary output.
1281   * @param  htim TIM handle
1282   * @param  Channel TIM Channel to be disabled
1283   *          This parameter can be one of the following values:
1284   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1285   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1286   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1287   * @retval HAL status
1288   */
HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t Channel)1289 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
1290 {
1291   HAL_StatusTypeDef status = HAL_OK;
1292   uint32_t tmpccer;
1293 
1294   /* Check the parameters */
1295   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1296 
1297   switch (Channel)
1298   {
1299     case TIM_CHANNEL_1:
1300     {
1301       /* Disable the TIM Capture/Compare 1 interrupt */
1302       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
1303       break;
1304     }
1305 
1306     case TIM_CHANNEL_2:
1307     {
1308       /* Disable the TIM Capture/Compare 2 interrupt */
1309       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
1310       break;
1311     }
1312 
1313     case TIM_CHANNEL_3:
1314     {
1315       /* Disable the TIM Capture/Compare 3 interrupt */
1316       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
1317       break;
1318     }
1319 
1320     default:
1321       status = HAL_ERROR;
1322       break;
1323   }
1324 
1325   if (status == HAL_OK)
1326   {
1327     /* Disable the complementary PWM output  */
1328     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1329 
1330     /* Disable the TIM Break interrupt (only if no more channel is active) */
1331     tmpccer = htim->Instance->CCER;
1332     if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
1333     {
1334       __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
1335     }
1336 
1337     /* Disable the Main Output */
1338     __HAL_TIM_MOE_DISABLE(htim);
1339 
1340     /* Disable the Peripheral */
1341     __HAL_TIM_DISABLE(htim);
1342 
1343     /* Set the TIM complementary channel state */
1344     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1345   }
1346 
1347   /* Return function status */
1348   return status;
1349 }
1350 
1351 /**
1352   * @brief  Starts the TIM PWM signal generation in DMA mode on the
1353   *         complementary output
1354   * @param  htim TIM handle
1355   * @param  Channel TIM Channel to be enabled
1356   *          This parameter can be one of the following values:
1357   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1358   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1359   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1360   * @param  pData The source Buffer address.
1361   * @param  Length The length of data to be transferred from memory to TIM peripheral
1362   * @retval HAL status
1363   */
HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef * htim,uint32_t Channel,const uint32_t * pData,uint16_t Length)1364 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
1365                                            uint16_t Length)
1366 {
1367   HAL_StatusTypeDef status = HAL_OK;
1368   uint32_t tmpsmcr;
1369 
1370   /* Check the parameters */
1371   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1372 
1373   /* Set the TIM complementary channel state */
1374   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
1375   {
1376     return HAL_BUSY;
1377   }
1378   else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
1379   {
1380     if ((pData == NULL) || (Length == 0U))
1381     {
1382       return HAL_ERROR;
1383     }
1384     else
1385     {
1386       TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1387     }
1388   }
1389   else
1390   {
1391     return HAL_ERROR;
1392   }
1393 
1394   switch (Channel)
1395   {
1396     case TIM_CHANNEL_1:
1397     {
1398       /* Set the DMA compare callbacks */
1399       htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1400       htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1401 
1402       /* Set the DMA error callback */
1403       htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
1404 
1405       /* Enable the DMA channel */
1406       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
1407                            Length) != HAL_OK)
1408       {
1409         /* Return error status */
1410         return HAL_ERROR;
1411       }
1412       /* Enable the TIM Capture/Compare 1 DMA request */
1413       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
1414       break;
1415     }
1416 
1417     case TIM_CHANNEL_2:
1418     {
1419       /* Set the DMA compare callbacks */
1420       htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1421       htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1422 
1423       /* Set the DMA error callback */
1424       htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
1425 
1426       /* Enable the DMA channel */
1427       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
1428                            Length) != HAL_OK)
1429       {
1430         /* Return error status */
1431         return HAL_ERROR;
1432       }
1433       /* Enable the TIM Capture/Compare 2 DMA request */
1434       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
1435       break;
1436     }
1437 
1438     case TIM_CHANNEL_3:
1439     {
1440       /* Set the DMA compare callbacks */
1441       htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1442       htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1443 
1444       /* Set the DMA error callback */
1445       htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
1446 
1447       /* Enable the DMA channel */
1448       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
1449                            Length) != HAL_OK)
1450       {
1451         /* Return error status */
1452         return HAL_ERROR;
1453       }
1454       /* Enable the TIM Capture/Compare 3 DMA request */
1455       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
1456       break;
1457     }
1458 
1459     default:
1460       status = HAL_ERROR;
1461       break;
1462   }
1463 
1464   if (status == HAL_OK)
1465   {
1466     /* Enable the complementary PWM output  */
1467     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1468 
1469     /* Enable the Main Output */
1470     __HAL_TIM_MOE_ENABLE(htim);
1471 
1472     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1473     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1474     {
1475       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1476       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1477       {
1478         __HAL_TIM_ENABLE(htim);
1479       }
1480     }
1481     else
1482     {
1483       __HAL_TIM_ENABLE(htim);
1484     }
1485   }
1486 
1487   /* Return function status */
1488   return status;
1489 }
1490 
1491 /**
1492   * @brief  Stops the TIM PWM signal generation in DMA mode on the complementary
1493   *         output
1494   * @param  htim TIM handle
1495   * @param  Channel TIM Channel to be disabled
1496   *          This parameter can be one of the following values:
1497   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1498   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1499   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1500   * @retval HAL status
1501   */
HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef * htim,uint32_t Channel)1502 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
1503 {
1504   HAL_StatusTypeDef status = HAL_OK;
1505 
1506   /* Check the parameters */
1507   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1508 
1509   switch (Channel)
1510   {
1511     case TIM_CHANNEL_1:
1512     {
1513       /* Disable the TIM Capture/Compare 1 DMA request */
1514       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
1515       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
1516       break;
1517     }
1518 
1519     case TIM_CHANNEL_2:
1520     {
1521       /* Disable the TIM Capture/Compare 2 DMA request */
1522       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
1523       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
1524       break;
1525     }
1526 
1527     case TIM_CHANNEL_3:
1528     {
1529       /* Disable the TIM Capture/Compare 3 DMA request */
1530       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
1531       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
1532       break;
1533     }
1534 
1535     default:
1536       status = HAL_ERROR;
1537       break;
1538   }
1539 
1540   if (status == HAL_OK)
1541   {
1542     /* Disable the complementary PWM output */
1543     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1544 
1545     /* Disable the Main Output */
1546     __HAL_TIM_MOE_DISABLE(htim);
1547 
1548     /* Disable the Peripheral */
1549     __HAL_TIM_DISABLE(htim);
1550 
1551     /* Set the TIM complementary channel state */
1552     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1553   }
1554 
1555   /* Return function status */
1556   return status;
1557 }
1558 
1559 /**
1560   * @}
1561   */
1562 
1563 /** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
1564   * @brief    Timer Complementary One Pulse functions
1565   *
1566 @verbatim
1567   ==============================================================================
1568                 ##### Timer Complementary One Pulse functions #####
1569   ==============================================================================
1570   [..]
1571     This section provides functions allowing to:
1572     (+) Start the Complementary One Pulse generation.
1573     (+) Stop the Complementary One Pulse.
1574     (+) Start the Complementary One Pulse and enable interrupts.
1575     (+) Stop the Complementary One Pulse and disable interrupts.
1576 
1577 @endverbatim
1578   * @{
1579   */
1580 
1581 /**
1582   * @brief  Starts the TIM One Pulse signal generation on the complementary
1583   *         output.
1584   * @note OutputChannel must match the pulse output channel chosen when calling
1585   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1586   * @param  htim TIM One Pulse handle
1587   * @param  OutputChannel pulse output channel to enable
1588   *          This parameter can be one of the following values:
1589   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1590   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1591   * @retval HAL status
1592   */
HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1593 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1594 {
1595   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1596   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1597   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1598   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1599   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1600 
1601   /* Check the parameters */
1602   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1603 
1604   /* Check the TIM channels state */
1605   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1606       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1607       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1608       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1609   {
1610     return HAL_ERROR;
1611   }
1612 
1613   /* Set the TIM channels state */
1614   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1615   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1616   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1617   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1618 
1619   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1620   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1621   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1622 
1623   /* Enable the Main Output */
1624   __HAL_TIM_MOE_ENABLE(htim);
1625 
1626   /* Return function status */
1627   return HAL_OK;
1628 }
1629 
1630 /**
1631   * @brief  Stops the TIM One Pulse signal generation on the complementary
1632   *         output.
1633   * @note OutputChannel must match the pulse output channel chosen when calling
1634   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1635   * @param  htim TIM One Pulse handle
1636   * @param  OutputChannel pulse output channel to disable
1637   *          This parameter can be one of the following values:
1638   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1639   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1640   * @retval HAL status
1641   */
HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1642 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1643 {
1644   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1645 
1646   /* Check the parameters */
1647   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1648 
1649   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1650   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1651   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1652 
1653   /* Disable the Main Output */
1654   __HAL_TIM_MOE_DISABLE(htim);
1655 
1656   /* Disable the Peripheral */
1657   __HAL_TIM_DISABLE(htim);
1658 
1659   /* Set the TIM  channels state */
1660   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1661   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1662   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1663   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1664 
1665   /* Return function status */
1666   return HAL_OK;
1667 }
1668 
1669 /**
1670   * @brief  Starts the TIM One Pulse signal generation in interrupt mode on the
1671   *         complementary channel.
1672   * @note OutputChannel must match the pulse output channel chosen when calling
1673   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1674   * @param  htim TIM One Pulse handle
1675   * @param  OutputChannel pulse output channel to enable
1676   *          This parameter can be one of the following values:
1677   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1678   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1679   * @retval HAL status
1680   */
HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1681 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1682 {
1683   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1684   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1685   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1686   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1687   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1688 
1689   /* Check the parameters */
1690   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1691 
1692   /* Check the TIM channels state */
1693   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1694       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1695       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1696       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1697   {
1698     return HAL_ERROR;
1699   }
1700 
1701   /* Set the TIM channels state */
1702   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1703   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1704   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1705   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1706 
1707   /* Enable the TIM Capture/Compare 1 interrupt */
1708   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
1709 
1710   /* Enable the TIM Capture/Compare 2 interrupt */
1711   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
1712 
1713   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1714   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1715   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1716 
1717   /* Enable the Main Output */
1718   __HAL_TIM_MOE_ENABLE(htim);
1719 
1720   /* Return function status */
1721   return HAL_OK;
1722 }
1723 
1724 /**
1725   * @brief  Stops the TIM One Pulse signal generation in interrupt mode on the
1726   *         complementary channel.
1727   * @note OutputChannel must match the pulse output channel chosen when calling
1728   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1729   * @param  htim TIM One Pulse handle
1730   * @param  OutputChannel pulse output channel to disable
1731   *          This parameter can be one of the following values:
1732   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1733   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1734   * @retval HAL status
1735   */
HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1736 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1737 {
1738   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1739 
1740   /* Check the parameters */
1741   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1742 
1743   /* Disable the TIM Capture/Compare 1 interrupt */
1744   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
1745 
1746   /* Disable the TIM Capture/Compare 2 interrupt */
1747   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
1748 
1749   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1750   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1751   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1752 
1753   /* Disable the Main Output */
1754   __HAL_TIM_MOE_DISABLE(htim);
1755 
1756   /* Disable the Peripheral */
1757   __HAL_TIM_DISABLE(htim);
1758 
1759   /* Set the TIM  channels state */
1760   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1761   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1762   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1763   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1764 
1765   /* Return function status */
1766   return HAL_OK;
1767 }
1768 
1769 /**
1770   * @}
1771   */
1772 
1773 /** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
1774   * @brief    Peripheral Control functions
1775   *
1776 @verbatim
1777   ==============================================================================
1778                     ##### Peripheral Control functions #####
1779   ==============================================================================
1780   [..]
1781     This section provides functions allowing to:
1782       (+) Configure the commutation event in case of use of the Hall sensor interface.
1783       (+) Configure Output channels for OC and PWM mode.
1784 
1785       (+) Configure Complementary channels, break features and dead time.
1786       (+) Configure Master synchronization.
1787       (+) Configure timer remapping capabilities.
1788       (+) Enable or disable channel grouping.
1789 
1790 @endverbatim
1791   * @{
1792   */
1793 
1794 /**
1795   * @brief  Configure the TIM commutation event sequence.
1796   * @note  This function is mandatory to use the commutation event in order to
1797   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1798   *        the typical use of this feature is with the use of another Timer(interface Timer)
1799   *        configured in Hall sensor interface, this interface Timer will generate the
1800   *        commutation at its TRGO output (connected to Timer used in this function) each time
1801   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1802   * @param  htim TIM handle
1803   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1804   *          This parameter can be one of the following values:
1805   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1806   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1807   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1808   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1809   *            @arg TIM_TS_NONE: No trigger is needed
1810   * @param  CommutationSource the Commutation Event source
1811   *          This parameter can be one of the following values:
1812   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1813   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1814   * @retval HAL status
1815   */
HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1816 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1817                                               uint32_t  CommutationSource)
1818 {
1819   /* Check the parameters */
1820   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1821   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1822 
1823   __HAL_LOCK(htim);
1824 
1825   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1826       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1827   {
1828     /* Select the Input trigger */
1829     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1830     htim->Instance->SMCR |= InputTrigger;
1831   }
1832 
1833   /* Select the Capture Compare preload feature */
1834   htim->Instance->CR2 |= TIM_CR2_CCPC;
1835   /* Select the Commutation event source */
1836   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1837   htim->Instance->CR2 |= CommutationSource;
1838 
1839   /* Disable Commutation Interrupt */
1840   __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
1841 
1842   /* Disable Commutation DMA request */
1843   __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
1844 
1845   __HAL_UNLOCK(htim);
1846 
1847   return HAL_OK;
1848 }
1849 
1850 /**
1851   * @brief  Configure the TIM commutation event sequence with interrupt.
1852   * @note  This function is mandatory to use the commutation event in order to
1853   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1854   *        the typical use of this feature is with the use of another Timer(interface Timer)
1855   *        configured in Hall sensor interface, this interface Timer will generate the
1856   *        commutation at its TRGO output (connected to Timer used in this function) each time
1857   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1858   * @param  htim TIM handle
1859   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1860   *          This parameter can be one of the following values:
1861   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1862   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1863   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1864   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1865   *            @arg TIM_TS_NONE: No trigger is needed
1866   * @param  CommutationSource the Commutation Event source
1867   *          This parameter can be one of the following values:
1868   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1869   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1870   * @retval HAL status
1871   */
HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1872 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1873                                                  uint32_t  CommutationSource)
1874 {
1875   /* Check the parameters */
1876   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1877   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1878 
1879   __HAL_LOCK(htim);
1880 
1881   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1882       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1883   {
1884     /* Select the Input trigger */
1885     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1886     htim->Instance->SMCR |= InputTrigger;
1887   }
1888 
1889   /* Select the Capture Compare preload feature */
1890   htim->Instance->CR2 |= TIM_CR2_CCPC;
1891   /* Select the Commutation event source */
1892   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1893   htim->Instance->CR2 |= CommutationSource;
1894 
1895   /* Disable Commutation DMA request */
1896   __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
1897 
1898   /* Enable the Commutation Interrupt */
1899   __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
1900 
1901   __HAL_UNLOCK(htim);
1902 
1903   return HAL_OK;
1904 }
1905 
1906 /**
1907   * @brief  Configure the TIM commutation event sequence with DMA.
1908   * @note  This function is mandatory to use the commutation event in order to
1909   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1910   *        the typical use of this feature is with the use of another Timer(interface Timer)
1911   *        configured in Hall sensor interface, this interface Timer will generate the
1912   *        commutation at its TRGO output (connected to Timer used in this function) each time
1913   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1914   * @note  The user should configure the DMA in his own software, in This function only the COMDE bit is set
1915   * @param  htim TIM handle
1916   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1917   *          This parameter can be one of the following values:
1918   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1919   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1920   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1921   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1922   *            @arg TIM_TS_NONE: No trigger is needed
1923   * @param  CommutationSource the Commutation Event source
1924   *          This parameter can be one of the following values:
1925   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1926   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1927   * @retval HAL status
1928   */
HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1929 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1930                                                   uint32_t  CommutationSource)
1931 {
1932   /* Check the parameters */
1933   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1934   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1935 
1936   __HAL_LOCK(htim);
1937 
1938   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1939       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1940   {
1941     /* Select the Input trigger */
1942     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1943     htim->Instance->SMCR |= InputTrigger;
1944   }
1945 
1946   /* Select the Capture Compare preload feature */
1947   htim->Instance->CR2 |= TIM_CR2_CCPC;
1948   /* Select the Commutation event source */
1949   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1950   htim->Instance->CR2 |= CommutationSource;
1951 
1952   /* Enable the Commutation DMA Request */
1953   /* Set the DMA Commutation Callback */
1954   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
1955   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt;
1956   /* Set the DMA error callback */
1957   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
1958 
1959   /* Disable Commutation Interrupt */
1960   __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
1961 
1962   /* Enable the Commutation DMA Request */
1963   __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
1964 
1965   __HAL_UNLOCK(htim);
1966 
1967   return HAL_OK;
1968 }
1969 
1970 /**
1971   * @brief  Configures the TIM in master mode.
1972   * @param  htim TIM handle.
1973   * @param  sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that
1974   *         contains the selected trigger output (TRGO) and the Master/Slave
1975   *         mode.
1976   * @retval HAL status
1977   */
HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef * htim,const TIM_MasterConfigTypeDef * sMasterConfig)1978 HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
1979                                                         const TIM_MasterConfigTypeDef *sMasterConfig)
1980 {
1981   uint32_t tmpcr2;
1982   uint32_t tmpsmcr;
1983 
1984   /* Check the parameters */
1985   assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
1986   assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
1987   assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
1988 
1989   /* Check input state */
1990   __HAL_LOCK(htim);
1991 
1992   /* Change the handler state */
1993   htim->State = HAL_TIM_STATE_BUSY;
1994 
1995   /* Get the TIMx CR2 register value */
1996   tmpcr2 = htim->Instance->CR2;
1997 
1998   /* Get the TIMx SMCR register value */
1999   tmpsmcr = htim->Instance->SMCR;
2000 
2001   /* If the timer supports ADC synchronization through TRGO2, set the master mode selection 2 */
2002   if (IS_TIM_TRGO2_INSTANCE(htim->Instance))
2003   {
2004     /* Check the parameters */
2005     assert_param(IS_TIM_TRGO2_SOURCE(sMasterConfig->MasterOutputTrigger2));
2006 
2007     /* Clear the MMS2 bits */
2008     tmpcr2 &= ~TIM_CR2_MMS2;
2009     /* Select the TRGO2 source*/
2010     tmpcr2 |= sMasterConfig->MasterOutputTrigger2;
2011   }
2012 
2013   /* Reset the MMS Bits */
2014   tmpcr2 &= ~TIM_CR2_MMS;
2015   /* Select the TRGO source */
2016   tmpcr2 |=  sMasterConfig->MasterOutputTrigger;
2017 
2018   /* Update TIMx CR2 */
2019   htim->Instance->CR2 = tmpcr2;
2020 
2021   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
2022   {
2023     /* Reset the MSM Bit */
2024     tmpsmcr &= ~TIM_SMCR_MSM;
2025     /* Set master mode */
2026     tmpsmcr |= sMasterConfig->MasterSlaveMode;
2027 
2028     /* Update TIMx SMCR */
2029     htim->Instance->SMCR = tmpsmcr;
2030   }
2031 
2032   /* Change the htim state */
2033   htim->State = HAL_TIM_STATE_READY;
2034 
2035   __HAL_UNLOCK(htim);
2036 
2037   return HAL_OK;
2038 }
2039 
2040 /**
2041   * @brief  Configures the Break feature, dead time, Lock level, OSSI/OSSR State
2042   *         and the AOE(automatic output enable).
2043   * @param  htim TIM handle
2044   * @param  sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
2045   *         contains the BDTR Register configuration  information for the TIM peripheral.
2046   * @note   Interrupts can be generated when an active level is detected on the
2047   *         break input, the break 2 input or the system break input. Break
2048   *         interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
2049   * @retval HAL status
2050   */
HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef * htim,const TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig)2051 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
2052                                                 const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
2053 {
2054   /* Keep this variable initialized to 0 as it is used to configure BDTR register */
2055   uint32_t tmpbdtr = 0U;
2056 
2057   /* Check the parameters */
2058   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
2059   assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
2060   assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
2061   assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
2062   assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
2063   assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
2064   assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
2065   assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
2066   assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
2067 
2068   /* Check input state */
2069   __HAL_LOCK(htim);
2070 
2071   /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
2072      the OSSI State, the dead time value and the Automatic Output Enable Bit */
2073 
2074   /* Set the BDTR bits */
2075   MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
2076   MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
2077   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
2078   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
2079   MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
2080   MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
2081   MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
2082   MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));
2083 
2084   if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
2085   {
2086     /* Check the parameters */
2087     assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode));
2088 
2089     /* Set BREAK AF mode */
2090     MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode);
2091   }
2092 
2093   if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
2094   {
2095     /* Check the parameters */
2096     assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
2097     assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
2098     assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));
2099 
2100     /* Set the BREAK2 input related BDTR bits */
2101     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos));
2102     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
2103     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
2104 
2105     if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
2106     {
2107       /* Check the parameters */
2108       assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode));
2109 
2110       /* Set BREAK2 AF mode */
2111       MODIFY_REG(tmpbdtr, TIM_BDTR_BK2BID, sBreakDeadTimeConfig->Break2AFMode);
2112     }
2113   }
2114 
2115   /* Set TIMx_BDTR */
2116   htim->Instance->BDTR = tmpbdtr;
2117 
2118   __HAL_UNLOCK(htim);
2119 
2120   return HAL_OK;
2121 }
2122 
2123 /**
2124   * @brief  Configures the break input source.
2125   * @param  htim TIM handle.
2126   * @param  BreakInput Break input to configure
2127   *          This parameter can be one of the following values:
2128   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2129   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2130   * @param  sBreakInputConfig Break input source configuration
2131   * @retval HAL status
2132   */
HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput,const TIMEx_BreakInputConfigTypeDef * sBreakInputConfig)2133 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim,
2134                                              uint32_t BreakInput,
2135                                              const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
2136 
2137 {
2138   HAL_StatusTypeDef status = HAL_OK;
2139   uint32_t tmporx;
2140   uint32_t bkin_enable_mask;
2141   uint32_t bkin_polarity_mask;
2142   uint32_t bkin_enable_bitpos;
2143   uint32_t bkin_polarity_bitpos;
2144 
2145   /* Check the parameters */
2146   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
2147   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2148   assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source));
2149   assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable));
2150   if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
2151   {
2152     assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
2153   }
2154 
2155   /* Check input state */
2156   __HAL_LOCK(htim);
2157 
2158   switch (sBreakInputConfig->Source)
2159   {
2160     case TIM_BREAKINPUTSOURCE_BKIN:
2161     {
2162       bkin_enable_mask = TIM1_OR2_BKINE;
2163       bkin_enable_bitpos = TIM1_OR2_BKINE_Pos;
2164       bkin_polarity_mask = TIM1_OR2_BKINP;
2165       bkin_polarity_bitpos = TIM1_OR2_BKINP_Pos;
2166       break;
2167     }
2168     case TIM_BREAKINPUTSOURCE_COMP1:
2169     {
2170       bkin_enable_mask = TIM1_OR2_BKCMP1E;
2171       bkin_enable_bitpos = TIM1_OR2_BKCMP1E_Pos;
2172       bkin_polarity_mask = TIM1_OR2_BKCMP1P;
2173       bkin_polarity_bitpos = TIM1_OR2_BKCMP1P_Pos;
2174       break;
2175     }
2176     case TIM_BREAKINPUTSOURCE_COMP2:
2177     {
2178       bkin_enable_mask = TIM1_OR2_BKCMP2E;
2179       bkin_enable_bitpos = TIM1_OR2_BKCMP2E_Pos;
2180       bkin_polarity_mask = TIM1_OR2_BKCMP2P;
2181       bkin_polarity_bitpos = TIM1_OR2_BKCMP2P_Pos;
2182       break;
2183     }
2184     case TIM_BREAKINPUTSOURCE_DFSDM1:
2185     {
2186       bkin_enable_mask = TIM1_OR2_BKDF1BK0E;
2187       bkin_enable_bitpos = TIM1_OR2_BKDF1BK0E_Pos;
2188       bkin_polarity_mask = 0U;
2189       bkin_polarity_bitpos = 0U;
2190       break;
2191     }
2192 
2193     default:
2194     {
2195       bkin_enable_mask = 0U;
2196       bkin_polarity_mask = 0U;
2197       bkin_enable_bitpos = 0U;
2198       bkin_polarity_bitpos = 0U;
2199       break;
2200     }
2201   }
2202 
2203   switch (BreakInput)
2204   {
2205     case TIM_BREAKINPUT_BRK:
2206     {
2207       /* Get the TIMx_OR2 register value */
2208       tmporx = htim->Instance->OR2;
2209 
2210       /* Enable the break input */
2211       tmporx &= ~bkin_enable_mask;
2212       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
2213 
2214       /* Set the break input polarity */
2215       if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
2216       {
2217         tmporx &= ~bkin_polarity_mask;
2218         tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
2219       }
2220 
2221       /* Set TIMx_OR2 */
2222       htim->Instance->OR2 = tmporx;
2223       break;
2224     }
2225     case TIM_BREAKINPUT_BRK2:
2226     {
2227       /* Get the TIMx_OR3 register value */
2228       tmporx = htim->Instance->OR3;
2229 
2230       /* Enable the break input */
2231       tmporx &= ~bkin_enable_mask;
2232       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
2233 
2234       /* Set the break input polarity */
2235       if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
2236       {
2237         tmporx &= ~bkin_polarity_mask;
2238         tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
2239       }
2240 
2241       /* Set TIMx_OR3 */
2242       htim->Instance->OR3 = tmporx;
2243       break;
2244     }
2245     default:
2246       status = HAL_ERROR;
2247       break;
2248   }
2249 
2250   __HAL_UNLOCK(htim);
2251 
2252   return status;
2253 }
2254 
2255 /**
2256   * @brief  Configures the TIMx Remapping input capabilities.
2257   * @param  htim TIM handle.
2258   * @param  Remap specifies the TIM remapping source.
2259   *         For TIM1, the parameter is a combination of 3 fields (field1 | field2 | field3):
2260   *
2261   *                   field1 can have the following values:
2262   *            @arg TIM_TIM1_ETR_ADC1_NONE:           TIM1_ETR is not connected to any ADC1 AWD (analog watchdog)
2263   *            @arg TIM_TIM1_ETR_ADC1_AWD1:           TIM1_ETR is connected to ADC1 AWD1
2264   *            @arg TIM_TIM1_ETR_ADC1_AWD2:           TIM1_ETR is connected to ADC1 AWD2
2265   *            @arg TIM_TIM1_ETR_ADC1_AWD3:           TIM1_ETR is connected to ADC1 AWD3
2266   *
2267   *                   field2 can have the following values:
2268   *            @arg TIM_TIM1_TI1_GPIO:                TIM1 TI1 is connected to GPIO
2269   *            @arg TIM_TIM1_TI1_COMP1:               TIM1 TI1 is connected to COMP1 output
2270   *
2271   *                   field3 can have the following values:
2272   *            @arg TIM_TIM1_ETR_COMP1:               TIM1_ETR is connected to COMP1 output
2273   *            @arg TIM_TIM1_ETR_COMP2:               TIM1_ETR is connected to COMP2 output
2274   *
2275   *            @note  When field3 is set to TIM_TIM1_ETR_COMP1 or TIM_TIM1_ETR_COMP2 field1 value is not significant
2276   *
2277   *         For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
2278   *
2279   *                   field1 can have the following values:
2280   *            @arg TIM_TIM2_ITR1_NONE:               No internal trigger on TIM2_ITR1
2281   *            @arg TIM_TIM2_ITR1_USB_SOF:            TIM2_ITR1 is connected to USB SOF
2282   *
2283   *                   field2 can have the following values:
2284   *            @arg TIM_TIM2_ETR_GPIO:                TIM2_ETR is connected to GPIO
2285   *            @arg TIM_TIM2_ETR_LSE:                 TIM2_ETR is connected to LSE
2286   *            @arg TIM_TIM2_ETR_COMP1:               TIM2_ETR is connected to COMP1 output
2287   *            @arg TIM_TIM2_ETR_COMP2:               TIM2_ETR is connected to COMP2 output
2288   *
2289   *                   field3 can have the following values:
2290   *            @arg TIM_TIM2_TI4_GPIO:                TIM2 TI4 is connected to GPIO
2291   *            @arg TIM_TIM2_TI4_COMP1:               TIM2 TI4 is connected to COMP1 output
2292   *            @arg TIM_TIM2_TI4_COMP2:               TIM2 TI4 is connected to COMP2 output
2293   *            @arg TIM_TIM2_TI4_COMP1_COMP2:         TIM2 TI4 is connected to logical OR between COMP1 and COMP2 output
2294   *
2295   *         For TIM3, the parameter is a combination 2 fields(field1 | field2):
2296   *
2297   *                   field1 can have the following values:
2298   *            @arg TIM_TIM3_TI1_GPIO:                TIM3 TI1 is connected to GPIO
2299   *            @arg TIM_TIM3_TI1_COMP1:               TIM3 TI1 is connected to COMP1 output
2300   *            @arg TIM_TIM3_TI1_COMP2:               TIM3 TI1 is connected to COMP2 output
2301   *            @arg TIM_TIM3_TI1_COMP1_COMP2:         TIM3 TI1 is connected to logical OR between COMP1 and COMP2 output
2302   *
2303   *                   field2 can have the following values:
2304   *            @arg TIM_TIM3_ETR_GPIO:                TIM3_ETR is connected to GPIO
2305   *            @arg TIM_TIM3_ETR_COMP1:               TIM3_ETR is connected to COMP1 output
2306   *
2307   *         For TIM8, the parameter is a combination of 2 fields (field1 | field2):
2308   *
2309   *                   field1 can have the following values:
2310   *            @arg TIM_TIM8_TI1_GPIO:               TIM8 TI1 is connected to GPIO
2311   *            @arg TIM_TIM8_TI1_COMP2:              TIM8 TI1 is connected to COMP2 output
2312   *
2313   *                   field2 can have the following values:
2314   *            @arg TIM_TIM8_ETR_COMP1:               TIM8_ETR is connected to COMP1 output
2315   *            @arg TIM_TIM8_ETR_COMP2:               TIM8_ETR is connected to COMP2 output
2316   *
2317   *         For TIM15, the parameter is a combination of 2 fields (field1 | field2):
2318   *
2319   *                   field1 can have the following values:
2320   *            @arg TIM_TIM15_TI1_GPIO:              TIM15 TI1 is connected to GPIO
2321   *            @arg TIM_TIM15_TI1_LSE:               TIM15 TI1 is connected to LSE
2322   *
2323   *                   field2 can have the following values:
2324   *            @arg TIM_TIM15_ENCODERMODE_NONE:      No redirection
2325   *            @arg TIM_TIM15_ENCODERMODE_TIM2:      TIM2 IC1 and TIM2 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
2326   *            @arg TIM_TIM15_ENCODERMODE_TIM3:      TIM3 IC1 and TIM3 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
2327   *            @arg TIM_TIM15_ENCODERMODE_TIM4:      TIM4 IC1 and TIM4 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
2328   *
2329   *         For TIM16, the parameter can have the following values:
2330   *            @arg TIM_TIM16_TI1_GPIO:              TIM16 TI1 is connected to GPIO
2331   *            @arg TIM_TIM16_TI1_LSI:               TIM16 TI1 is connected to LSI
2332   *            @arg TIM_TIM16_TI1_LSE:               TIM16 TI1 is connected to LSE
2333   *            @arg TIM_TIM16_TI1_RTC:               TIM16 TI1 is connected to RTC wakeup interrupt
2334   *
2335   *         For TIM17, the parameter can have the following values:
2336   *            @arg TIM_TIM17_TI1_GPIO:              TIM17 TI1 is connected to GPIO
2337   *            @arg TIM_TIM17_TI1_MSI:               TIM17 TI1 is connected to MSI  (constraints: MSI clock < 1/4 TIM APB clock)
2338   *            @arg TIM_TIM17_TI1_HSE_32:            TIM17 TI1 is connected to HSE div 32
2339   *            @arg TIM_TIM17_TI1_MCO:               TIM17 TI1 is connected to MCO
2340   *
2341   * @retval HAL status
2342   */
HAL_TIMEx_RemapConfig(TIM_HandleTypeDef * htim,uint32_t Remap)2343 HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
2344 {
2345   uint32_t tmpor1;
2346   uint32_t tmpor2;
2347 
2348   /* Check parameters */
2349   assert_param(IS_TIM_REMAP(htim->Instance, Remap));
2350 
2351   __HAL_LOCK(htim);
2352 
2353   /* Set ETR_SEL bit field (if required) */
2354   if (IS_TIM_ETRSEL_INSTANCE(htim->Instance))
2355   {
2356     tmpor2 = htim->Instance->OR2;
2357     tmpor2 &= ~TIM1_OR2_ETRSEL_Msk;
2358     tmpor2 |= (Remap & TIM1_OR2_ETRSEL_Msk);
2359 
2360     /* Set TIMx_OR2 */
2361     htim->Instance->OR2 = tmpor2;
2362   }
2363 
2364   /* Set other remapping capabilities */
2365   tmpor1 = Remap;
2366   tmpor1 &= ~TIM1_OR2_ETRSEL_Msk;
2367 
2368   /* Set TIMx_OR1 */
2369   htim->Instance->OR1 = tmpor1;
2370 
2371   __HAL_UNLOCK(htim);
2372 
2373   return HAL_OK;
2374 }
2375 
2376 /**
2377   * @brief  Group channel 5 and channel 1, 2 or 3
2378   * @param  htim TIM handle.
2379   * @param  Channels specifies the reference signal(s) the OC5REF is combined with.
2380   *         This parameter can be any combination of the following values:
2381   *         TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC
2382   *         TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF
2383   *         TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF
2384   *         TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF
2385   * @retval HAL status
2386   */
HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef * htim,uint32_t Channels)2387 HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels)
2388 {
2389   /* Check parameters */
2390   assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance));
2391   assert_param(IS_TIM_GROUPCH5(Channels));
2392 
2393   /* Process Locked */
2394   __HAL_LOCK(htim);
2395 
2396   htim->State = HAL_TIM_STATE_BUSY;
2397 
2398   /* Clear GC5Cx bit fields */
2399   htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1);
2400 
2401   /* Set GC5Cx bit fields */
2402   htim->Instance->CCR5 |= Channels;
2403 
2404   /* Change the htim state */
2405   htim->State = HAL_TIM_STATE_READY;
2406 
2407   __HAL_UNLOCK(htim);
2408 
2409   return HAL_OK;
2410 }
2411 
2412 /**
2413   * @brief  Disarm the designated break input (when it operates in bidirectional mode).
2414   * @param  htim TIM handle.
2415   * @param  BreakInput Break input to disarm
2416   *          This parameter can be one of the following values:
2417   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2418   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2419   * @note  The break input can be disarmed only when it is configured in
2420   *        bidirectional mode and when when MOE is reset.
2421   * @note  Purpose is to be able to have the input voltage back to high-state,
2422   *        whatever the time constant on the output .
2423   * @retval HAL status
2424   */
HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput)2425 HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
2426 {
2427   HAL_StatusTypeDef status = HAL_OK;
2428   uint32_t tmpbdtr;
2429 
2430   /* Check the parameters */
2431   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
2432   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2433 
2434   switch (BreakInput)
2435   {
2436     case TIM_BREAKINPUT_BRK:
2437     {
2438       /* Check initial conditions */
2439       tmpbdtr = READ_REG(htim->Instance->BDTR);
2440       if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) &&
2441           (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
2442       {
2443         /* Break input BRK is disarmed */
2444         SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM);
2445       }
2446       break;
2447     }
2448 
2449     case TIM_BREAKINPUT_BRK2:
2450     {
2451       /* Check initial conditions */
2452       tmpbdtr = READ_REG(htim->Instance->BDTR);
2453       if ((READ_BIT(tmpbdtr, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID) &&
2454           (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
2455       {
2456         /* Break input BRK is disarmed */
2457         SET_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM);
2458       }
2459       break;
2460     }
2461     default:
2462       status = HAL_ERROR;
2463       break;
2464   }
2465 
2466   return status;
2467 }
2468 
2469 /**
2470   * @brief  Arm the designated break input (when it operates in bidirectional mode).
2471   * @param  htim TIM handle.
2472   * @param  BreakInput Break input to arm
2473   *          This parameter can be one of the following values:
2474   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2475   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2476   * @note  Arming is possible at anytime, even if fault is present.
2477   * @note  Break input is automatically armed as soon as MOE bit is set.
2478   * @retval HAL status
2479   */
HAL_TIMEx_ReArmBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput)2480 HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
2481 {
2482   HAL_StatusTypeDef status = HAL_OK;
2483   uint32_t tickstart;
2484 
2485   /* Check the parameters */
2486   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
2487   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2488 
2489   switch (BreakInput)
2490   {
2491     case TIM_BREAKINPUT_BRK:
2492     {
2493       /* Check initial conditions */
2494       if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID)
2495       {
2496         /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
2497         /* Init tickstart for timeout management */
2498         tickstart = HAL_GetTick();
2499         while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
2500         {
2501           if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
2502           {
2503             /* New check to avoid false timeout detection in case of preemption */
2504             if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
2505             {
2506               return HAL_TIMEOUT;
2507             }
2508           }
2509         }
2510       }
2511       break;
2512     }
2513 
2514     case TIM_BREAKINPUT_BRK2:
2515     {
2516       /* Check initial conditions */
2517       if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID)
2518       {
2519         /* Break input BRK2 is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
2520         /* Init tickstart for timeout management */
2521         tickstart = HAL_GetTick();
2522         while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
2523         {
2524           if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
2525           {
2526             /* New check to avoid false timeout detection in case of preemption */
2527             if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
2528             {
2529               return HAL_TIMEOUT;
2530             }
2531           }
2532         }
2533       }
2534       break;
2535     }
2536     default:
2537       status = HAL_ERROR;
2538       break;
2539   }
2540 
2541   return status;
2542 }
2543 
2544 /**
2545   * @}
2546   */
2547 
2548 /** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
2549   * @brief    Extended Callbacks functions
2550   *
2551 @verbatim
2552   ==============================================================================
2553                     ##### Extended Callbacks functions #####
2554   ==============================================================================
2555   [..]
2556     This section provides Extended TIM callback functions:
2557     (+) Timer Commutation callback
2558     (+) Timer Break callback
2559 
2560 @endverbatim
2561   * @{
2562   */
2563 
2564 /**
2565   * @brief  Hall commutation changed callback in non-blocking mode
2566   * @param  htim TIM handle
2567   * @retval None
2568   */
HAL_TIMEx_CommutCallback(TIM_HandleTypeDef * htim)2569 __weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
2570 {
2571   /* Prevent unused argument(s) compilation warning */
2572   UNUSED(htim);
2573 
2574   /* NOTE : This function should not be modified, when the callback is needed,
2575             the HAL_TIMEx_CommutCallback could be implemented in the user file
2576    */
2577 }
2578 /**
2579   * @brief  Hall commutation changed half complete callback in non-blocking mode
2580   * @param  htim TIM handle
2581   * @retval None
2582   */
HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef * htim)2583 __weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
2584 {
2585   /* Prevent unused argument(s) compilation warning */
2586   UNUSED(htim);
2587 
2588   /* NOTE : This function should not be modified, when the callback is needed,
2589             the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file
2590    */
2591 }
2592 
2593 /**
2594   * @brief  Hall Break detection callback in non-blocking mode
2595   * @param  htim TIM handle
2596   * @retval None
2597   */
HAL_TIMEx_BreakCallback(TIM_HandleTypeDef * htim)2598 __weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
2599 {
2600   /* Prevent unused argument(s) compilation warning */
2601   UNUSED(htim);
2602 
2603   /* NOTE : This function should not be modified, when the callback is needed,
2604             the HAL_TIMEx_BreakCallback could be implemented in the user file
2605    */
2606 }
2607 
2608 /**
2609   * @brief  Hall Break2 detection callback in non blocking mode
2610   * @param  htim: TIM handle
2611   * @retval None
2612   */
HAL_TIMEx_Break2Callback(TIM_HandleTypeDef * htim)2613 __weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
2614 {
2615   /* Prevent unused argument(s) compilation warning */
2616   UNUSED(htim);
2617 
2618   /* NOTE : This function Should not be modified, when the callback is needed,
2619             the HAL_TIMEx_Break2Callback could be implemented in the user file
2620    */
2621 }
2622 /**
2623   * @}
2624   */
2625 
2626 /** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
2627   * @brief    Extended Peripheral State functions
2628   *
2629 @verbatim
2630   ==============================================================================
2631                 ##### Extended Peripheral State functions #####
2632   ==============================================================================
2633   [..]
2634     This subsection permits to get in run-time the status of the peripheral
2635     and the data flow.
2636 
2637 @endverbatim
2638   * @{
2639   */
2640 
2641 /**
2642   * @brief  Return the TIM Hall Sensor interface handle state.
2643   * @param  htim TIM Hall Sensor handle
2644   * @retval HAL state
2645   */
HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef * htim)2646 HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim)
2647 {
2648   return htim->State;
2649 }
2650 
2651 /**
2652   * @brief  Return actual state of the TIM complementary channel.
2653   * @param  htim TIM handle
2654   * @param  ChannelN TIM Complementary channel
2655   *          This parameter can be one of the following values:
2656   *            @arg TIM_CHANNEL_1: TIM Channel 1
2657   *            @arg TIM_CHANNEL_2: TIM Channel 2
2658   *            @arg TIM_CHANNEL_3: TIM Channel 3
2659   * @retval TIM Complementary channel state
2660   */
HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef * htim,uint32_t ChannelN)2661 HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim,  uint32_t ChannelN)
2662 {
2663   HAL_TIM_ChannelStateTypeDef channel_state;
2664 
2665   /* Check the parameters */
2666   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN));
2667 
2668   channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN);
2669 
2670   return channel_state;
2671 }
2672 /**
2673   * @}
2674   */
2675 
2676 /**
2677   * @}
2678   */
2679 
2680 /* Private functions ---------------------------------------------------------*/
2681 /** @defgroup TIMEx_Private_Functions TIM Extended Private Functions
2682   * @{
2683   */
2684 
2685 /**
2686   * @brief  TIM DMA Commutation callback.
2687   * @param  hdma pointer to DMA handle.
2688   * @retval None
2689   */
TIMEx_DMACommutationCplt(DMA_HandleTypeDef * hdma)2690 void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
2691 {
2692   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2693 
2694   /* Change the htim state */
2695   htim->State = HAL_TIM_STATE_READY;
2696 
2697 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2698   htim->CommutationCallback(htim);
2699 #else
2700   HAL_TIMEx_CommutCallback(htim);
2701 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2702 }
2703 
2704 /**
2705   * @brief  TIM DMA Commutation half complete callback.
2706   * @param  hdma pointer to DMA handle.
2707   * @retval None
2708   */
TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef * hdma)2709 void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
2710 {
2711   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2712 
2713   /* Change the htim state */
2714   htim->State = HAL_TIM_STATE_READY;
2715 
2716 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2717   htim->CommutationHalfCpltCallback(htim);
2718 #else
2719   HAL_TIMEx_CommutHalfCpltCallback(htim);
2720 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2721 }
2722 
2723 
2724 /**
2725   * @brief  TIM DMA Delay Pulse complete callback (complementary channel).
2726   * @param  hdma pointer to DMA handle.
2727   * @retval None
2728   */
TIM_DMADelayPulseNCplt(DMA_HandleTypeDef * hdma)2729 static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma)
2730 {
2731   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2732 
2733   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
2734   {
2735     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
2736 
2737     if (hdma->Init.Mode == DMA_NORMAL)
2738     {
2739       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
2740     }
2741   }
2742   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
2743   {
2744     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
2745 
2746     if (hdma->Init.Mode == DMA_NORMAL)
2747     {
2748       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
2749     }
2750   }
2751   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
2752   {
2753     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
2754 
2755     if (hdma->Init.Mode == DMA_NORMAL)
2756     {
2757       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
2758     }
2759   }
2760   else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
2761   {
2762     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
2763 
2764     if (hdma->Init.Mode == DMA_NORMAL)
2765     {
2766       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
2767     }
2768   }
2769   else
2770   {
2771     /* nothing to do */
2772   }
2773 
2774 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2775   htim->PWM_PulseFinishedCallback(htim);
2776 #else
2777   HAL_TIM_PWM_PulseFinishedCallback(htim);
2778 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2779 
2780   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
2781 }
2782 
2783 /**
2784   * @brief  TIM DMA error callback (complementary channel)
2785   * @param  hdma pointer to DMA handle.
2786   * @retval None
2787   */
TIM_DMAErrorCCxN(DMA_HandleTypeDef * hdma)2788 static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma)
2789 {
2790   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2791 
2792   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
2793   {
2794     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
2795     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
2796   }
2797   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
2798   {
2799     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
2800     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
2801   }
2802   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
2803   {
2804     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
2805     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
2806   }
2807   else
2808   {
2809     /* nothing to do */
2810   }
2811 
2812 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2813   htim->ErrorCallback(htim);
2814 #else
2815   HAL_TIM_ErrorCallback(htim);
2816 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2817 
2818   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
2819 }
2820 
2821 /**
2822   * @brief  Enables or disables the TIM Capture Compare Channel xN.
2823   * @param  TIMx to select the TIM peripheral
2824   * @param  Channel specifies the TIM Channel
2825   *          This parameter can be one of the following values:
2826   *            @arg TIM_CHANNEL_1: TIM Channel 1
2827   *            @arg TIM_CHANNEL_2: TIM Channel 2
2828   *            @arg TIM_CHANNEL_3: TIM Channel 3
2829   * @param  ChannelNState specifies the TIM Channel CCxNE bit new state.
2830   *          This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
2831   * @retval None
2832   */
TIM_CCxNChannelCmd(TIM_TypeDef * TIMx,uint32_t Channel,uint32_t ChannelNState)2833 static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
2834 {
2835   uint32_t tmp;
2836 
2837   tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
2838 
2839   /* Reset the CCxNE Bit */
2840   TIMx->CCER &=  ~tmp;
2841 
2842   /* Set or reset the CCxNE Bit */
2843   TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
2844 }
2845 /**
2846   * @}
2847   */
2848 
2849 #endif /* HAL_TIM_MODULE_ENABLED */
2850 /**
2851   * @}
2852   */
2853 
2854 /**
2855   * @}
2856   */
2857