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