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_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (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     (+) Start the Complementary Input Capture measurement.
1123     (+) Stop the Complementary Input Capture.
1124     (+) Start the Complementary Input Capture and enable interrupts.
1125     (+) Stop the Complementary Input Capture and disable interrupts.
1126     (+) Start the Complementary Input Capture and enable DMA transfers.
1127     (+) Stop the Complementary Input Capture and disable DMA transfers.
1128     (+) Start the Complementary One Pulse generation.
1129     (+) Stop the Complementary One Pulse.
1130     (+) Start the Complementary One Pulse and enable interrupts.
1131     (+) Stop the Complementary One Pulse and disable interrupts.
1132 
1133 @endverbatim
1134   * @{
1135   */
1136 
1137 /**
1138   * @brief  Starts the PWM signal generation on the complementary output.
1139   * @param  htim TIM handle
1140   * @param  Channel TIM Channel to be enabled
1141   *          This parameter can be one of the following values:
1142   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1143   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1144   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1145   * @retval HAL status
1146   */
HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef * htim,uint32_t Channel)1147 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
1148 {
1149   uint32_t tmpsmcr;
1150 
1151   /* Check the parameters */
1152   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1153 
1154   /* Check the TIM complementary channel state */
1155   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
1156   {
1157     return HAL_ERROR;
1158   }
1159 
1160   /* Set the TIM complementary channel state */
1161   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1162 
1163   /* Enable the complementary PWM output  */
1164   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1165 
1166   /* Enable the Main Output */
1167   __HAL_TIM_MOE_ENABLE(htim);
1168 
1169   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1170   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1171   {
1172     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1173     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1174     {
1175       __HAL_TIM_ENABLE(htim);
1176     }
1177   }
1178   else
1179   {
1180     __HAL_TIM_ENABLE(htim);
1181   }
1182 
1183   /* Return function status */
1184   return HAL_OK;
1185 }
1186 
1187 /**
1188   * @brief  Stops the PWM signal generation on the complementary output.
1189   * @param  htim TIM handle
1190   * @param  Channel TIM Channel to be disabled
1191   *          This parameter can be one of the following values:
1192   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1193   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1194   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1195   * @retval HAL status
1196   */
HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef * htim,uint32_t Channel)1197 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
1198 {
1199   /* Check the parameters */
1200   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1201 
1202   /* Disable the complementary PWM output  */
1203   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1204 
1205   /* Disable the Main Output */
1206   __HAL_TIM_MOE_DISABLE(htim);
1207 
1208   /* Disable the Peripheral */
1209   __HAL_TIM_DISABLE(htim);
1210 
1211   /* Set the TIM complementary channel state */
1212   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1213 
1214   /* Return function status */
1215   return HAL_OK;
1216 }
1217 
1218 /**
1219   * @brief  Starts the PWM signal generation in interrupt mode on the
1220   *         complementary output.
1221   * @param  htim TIM handle
1222   * @param  Channel TIM Channel to be disabled
1223   *          This parameter can be one of the following values:
1224   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1225   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1226   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1227   * @retval HAL status
1228   */
HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef * htim,uint32_t Channel)1229 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
1230 {
1231   HAL_StatusTypeDef status = HAL_OK;
1232   uint32_t tmpsmcr;
1233 
1234   /* Check the parameters */
1235   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1236 
1237   /* Check the TIM complementary channel state */
1238   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
1239   {
1240     return HAL_ERROR;
1241   }
1242 
1243   /* Set the TIM complementary channel state */
1244   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1245 
1246   switch (Channel)
1247   {
1248     case TIM_CHANNEL_1:
1249     {
1250       /* Enable the TIM Capture/Compare 1 interrupt */
1251       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
1252       break;
1253     }
1254 
1255     case TIM_CHANNEL_2:
1256     {
1257       /* Enable the TIM Capture/Compare 2 interrupt */
1258       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
1259       break;
1260     }
1261 
1262     case TIM_CHANNEL_3:
1263     {
1264       /* Enable the TIM Capture/Compare 3 interrupt */
1265       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
1266       break;
1267     }
1268 
1269     default:
1270       status = HAL_ERROR;
1271       break;
1272   }
1273 
1274   if (status == HAL_OK)
1275   {
1276     /* Enable the TIM Break interrupt */
1277     __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
1278 
1279     /* Enable the complementary PWM output  */
1280     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1281 
1282     /* Enable the Main Output */
1283     __HAL_TIM_MOE_ENABLE(htim);
1284 
1285     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1286     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1287     {
1288       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1289       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1290       {
1291         __HAL_TIM_ENABLE(htim);
1292       }
1293     }
1294     else
1295     {
1296       __HAL_TIM_ENABLE(htim);
1297     }
1298   }
1299 
1300   /* Return function status */
1301   return status;
1302 }
1303 
1304 /**
1305   * @brief  Stops the PWM signal generation in interrupt mode on the
1306   *         complementary output.
1307   * @param  htim TIM handle
1308   * @param  Channel TIM Channel to be disabled
1309   *          This parameter can be one of the following values:
1310   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1311   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1312   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1313   * @retval HAL status
1314   */
HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t Channel)1315 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
1316 {
1317   HAL_StatusTypeDef status = HAL_OK;
1318   uint32_t tmpccer;
1319 
1320   /* Check the parameters */
1321   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1322 
1323   switch (Channel)
1324   {
1325     case TIM_CHANNEL_1:
1326     {
1327       /* Disable the TIM Capture/Compare 1 interrupt */
1328       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
1329       break;
1330     }
1331 
1332     case TIM_CHANNEL_2:
1333     {
1334       /* Disable the TIM Capture/Compare 2 interrupt */
1335       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
1336       break;
1337     }
1338 
1339     case TIM_CHANNEL_3:
1340     {
1341       /* Disable the TIM Capture/Compare 3 interrupt */
1342       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
1343       break;
1344     }
1345 
1346     default:
1347       status = HAL_ERROR;
1348       break;
1349   }
1350 
1351   if (status == HAL_OK)
1352   {
1353     /* Disable the complementary PWM output  */
1354     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1355 
1356     /* Disable the TIM Break interrupt (only if no more channel is active) */
1357     tmpccer = htim->Instance->CCER;
1358     if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
1359     {
1360       __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
1361     }
1362 
1363     /* Disable the Main Output */
1364     __HAL_TIM_MOE_DISABLE(htim);
1365 
1366     /* Disable the Peripheral */
1367     __HAL_TIM_DISABLE(htim);
1368 
1369     /* Set the TIM complementary channel state */
1370     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1371   }
1372 
1373   /* Return function status */
1374   return status;
1375 }
1376 
1377 /**
1378   * @brief  Starts the TIM PWM signal generation in DMA mode on the
1379   *         complementary output
1380   * @param  htim TIM handle
1381   * @param  Channel TIM Channel to be enabled
1382   *          This parameter can be one of the following values:
1383   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1384   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1385   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1386   * @param  pData The source Buffer address.
1387   * @param  Length The length of data to be transferred from memory to TIM peripheral
1388   * @retval HAL status
1389   */
HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef * htim,uint32_t Channel,const uint32_t * pData,uint16_t Length)1390 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
1391                                            uint16_t Length)
1392 {
1393   HAL_StatusTypeDef status = HAL_OK;
1394   uint32_t tmpsmcr;
1395 
1396   /* Check the parameters */
1397   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1398 
1399   /* Set the TIM complementary channel state */
1400   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
1401   {
1402     return HAL_BUSY;
1403   }
1404   else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
1405   {
1406     if ((pData == NULL) || (Length == 0U))
1407     {
1408       return HAL_ERROR;
1409     }
1410     else
1411     {
1412       TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
1413     }
1414   }
1415   else
1416   {
1417     return HAL_ERROR;
1418   }
1419 
1420   switch (Channel)
1421   {
1422     case TIM_CHANNEL_1:
1423     {
1424       /* Set the DMA compare callbacks */
1425       htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1426       htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1427 
1428       /* Set the DMA error callback */
1429       htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
1430 
1431       /* Enable the DMA channel */
1432       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
1433                            Length) != HAL_OK)
1434       {
1435         /* Return error status */
1436         return HAL_ERROR;
1437       }
1438       /* Enable the TIM Capture/Compare 1 DMA request */
1439       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
1440       break;
1441     }
1442 
1443     case TIM_CHANNEL_2:
1444     {
1445       /* Set the DMA compare callbacks */
1446       htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1447       htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1448 
1449       /* Set the DMA error callback */
1450       htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
1451 
1452       /* Enable the DMA channel */
1453       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
1454                            Length) != HAL_OK)
1455       {
1456         /* Return error status */
1457         return HAL_ERROR;
1458       }
1459       /* Enable the TIM Capture/Compare 2 DMA request */
1460       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
1461       break;
1462     }
1463 
1464     case TIM_CHANNEL_3:
1465     {
1466       /* Set the DMA compare callbacks */
1467       htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
1468       htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
1469 
1470       /* Set the DMA error callback */
1471       htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
1472 
1473       /* Enable the DMA channel */
1474       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
1475                            Length) != HAL_OK)
1476       {
1477         /* Return error status */
1478         return HAL_ERROR;
1479       }
1480       /* Enable the TIM Capture/Compare 3 DMA request */
1481       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
1482       break;
1483     }
1484 
1485     default:
1486       status = HAL_ERROR;
1487       break;
1488   }
1489 
1490   if (status == HAL_OK)
1491   {
1492     /* Enable the complementary PWM output  */
1493     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
1494 
1495     /* Enable the Main Output */
1496     __HAL_TIM_MOE_ENABLE(htim);
1497 
1498     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
1499     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
1500     {
1501       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
1502       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
1503       {
1504         __HAL_TIM_ENABLE(htim);
1505       }
1506     }
1507     else
1508     {
1509       __HAL_TIM_ENABLE(htim);
1510     }
1511   }
1512 
1513   /* Return function status */
1514   return status;
1515 }
1516 
1517 /**
1518   * @brief  Stops the TIM PWM signal generation in DMA mode on the complementary
1519   *         output
1520   * @param  htim TIM handle
1521   * @param  Channel TIM Channel to be disabled
1522   *          This parameter can be one of the following values:
1523   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1524   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1525   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
1526   * @retval HAL status
1527   */
HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef * htim,uint32_t Channel)1528 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
1529 {
1530   HAL_StatusTypeDef status = HAL_OK;
1531 
1532   /* Check the parameters */
1533   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
1534 
1535   switch (Channel)
1536   {
1537     case TIM_CHANNEL_1:
1538     {
1539       /* Disable the TIM Capture/Compare 1 DMA request */
1540       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
1541       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
1542       break;
1543     }
1544 
1545     case TIM_CHANNEL_2:
1546     {
1547       /* Disable the TIM Capture/Compare 2 DMA request */
1548       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
1549       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
1550       break;
1551     }
1552 
1553     case TIM_CHANNEL_3:
1554     {
1555       /* Disable the TIM Capture/Compare 3 DMA request */
1556       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
1557       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
1558       break;
1559     }
1560 
1561     default:
1562       status = HAL_ERROR;
1563       break;
1564   }
1565 
1566   if (status == HAL_OK)
1567   {
1568     /* Disable the complementary PWM output */
1569     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1570 
1571     /* Disable the Main Output */
1572     __HAL_TIM_MOE_DISABLE(htim);
1573 
1574     /* Disable the Peripheral */
1575     __HAL_TIM_DISABLE(htim);
1576 
1577     /* Set the TIM complementary channel state */
1578     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1579   }
1580 
1581   /* Return function status */
1582   return status;
1583 }
1584 
1585 /**
1586   * @}
1587   */
1588 
1589 /** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
1590   * @brief    Timer Complementary One Pulse functions
1591   *
1592 @verbatim
1593   ==============================================================================
1594                 ##### Timer Complementary One Pulse functions #####
1595   ==============================================================================
1596   [..]
1597     This section provides functions allowing to:
1598     (+) Start the Complementary One Pulse generation.
1599     (+) Stop the Complementary One Pulse.
1600     (+) Start the Complementary One Pulse and enable interrupts.
1601     (+) Stop the Complementary One Pulse and disable interrupts.
1602 
1603 @endverbatim
1604   * @{
1605   */
1606 
1607 /**
1608   * @brief  Starts the TIM One Pulse signal generation on the complementary
1609   *         output.
1610   * @note OutputChannel must match the pulse output channel chosen when calling
1611   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1612   * @param  htim TIM One Pulse handle
1613   * @param  OutputChannel pulse output channel to enable
1614   *          This parameter can be one of the following values:
1615   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1616   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1617   * @retval HAL status
1618   */
HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1619 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1620 {
1621   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1622   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1623   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1624   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1625   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1626 
1627   /* Check the parameters */
1628   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1629 
1630   /* Check the TIM channels state */
1631   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1632       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1633       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1634       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1635   {
1636     return HAL_ERROR;
1637   }
1638 
1639   /* Set the TIM channels state */
1640   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1641   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1642   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1643   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1644 
1645   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1646   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1647   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1648 
1649   /* Enable the Main Output */
1650   __HAL_TIM_MOE_ENABLE(htim);
1651 
1652   /* Return function status */
1653   return HAL_OK;
1654 }
1655 
1656 /**
1657   * @brief  Stops the TIM One Pulse signal generation on the complementary
1658   *         output.
1659   * @note OutputChannel must match the pulse output channel chosen when calling
1660   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1661   * @param  htim TIM One Pulse handle
1662   * @param  OutputChannel pulse output channel to disable
1663   *          This parameter can be one of the following values:
1664   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1665   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1666   * @retval HAL status
1667   */
HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1668 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1669 {
1670   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1671 
1672   /* Check the parameters */
1673   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1674 
1675   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1676   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1677   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1678 
1679   /* Disable the Main Output */
1680   __HAL_TIM_MOE_DISABLE(htim);
1681 
1682   /* Disable the Peripheral */
1683   __HAL_TIM_DISABLE(htim);
1684 
1685   /* Set the TIM  channels state */
1686   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1687   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1688   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1689   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1690 
1691   /* Return function status */
1692   return HAL_OK;
1693 }
1694 
1695 /**
1696   * @brief  Starts the TIM One Pulse signal generation in interrupt mode on the
1697   *         complementary channel.
1698   * @note OutputChannel must match the pulse output channel chosen when calling
1699   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1700   * @param  htim TIM One Pulse handle
1701   * @param  OutputChannel pulse output channel to enable
1702   *          This parameter can be one of the following values:
1703   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1704   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1705   * @retval HAL status
1706   */
HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1707 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1708 {
1709   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1710   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1711   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1712   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1713   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1714 
1715   /* Check the parameters */
1716   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1717 
1718   /* Check the TIM channels state */
1719   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1720       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1721       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1722       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1723   {
1724     return HAL_ERROR;
1725   }
1726 
1727   /* Set the TIM channels state */
1728   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1729   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1730   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1731   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1732 
1733   /* Enable the TIM Capture/Compare 1 interrupt */
1734   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
1735 
1736   /* Enable the TIM Capture/Compare 2 interrupt */
1737   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
1738 
1739   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1740   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1741   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1742 
1743   /* Enable the Main Output */
1744   __HAL_TIM_MOE_ENABLE(htim);
1745 
1746   /* Return function status */
1747   return HAL_OK;
1748 }
1749 
1750 /**
1751   * @brief  Stops the TIM One Pulse signal generation in interrupt mode on the
1752   *         complementary channel.
1753   * @note OutputChannel must match the pulse output channel chosen when calling
1754   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1755   * @param  htim TIM One Pulse handle
1756   * @param  OutputChannel pulse output channel to disable
1757   *          This parameter can be one of the following values:
1758   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1759   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1760   * @retval HAL status
1761   */
HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1762 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1763 {
1764   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1765 
1766   /* Check the parameters */
1767   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1768 
1769   /* Disable the TIM Capture/Compare 1 interrupt */
1770   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
1771 
1772   /* Disable the TIM Capture/Compare 2 interrupt */
1773   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
1774 
1775   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1776   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1777   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1778 
1779   /* Disable the Main Output */
1780   __HAL_TIM_MOE_DISABLE(htim);
1781 
1782   /* Disable the Peripheral */
1783   __HAL_TIM_DISABLE(htim);
1784 
1785   /* Set the TIM  channels state */
1786   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1787   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1788   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1789   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1790 
1791   /* Return function status */
1792   return HAL_OK;
1793 }
1794 
1795 /**
1796   * @}
1797   */
1798 
1799 /** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
1800   * @brief    Peripheral Control functions
1801   *
1802 @verbatim
1803   ==============================================================================
1804                     ##### Peripheral Control functions #####
1805   ==============================================================================
1806   [..]
1807     This section provides functions allowing to:
1808       (+) Configure the commutation event in case of use of the Hall sensor interface.
1809       (+) Configure Output channels for OC and PWM mode.
1810 
1811       (+) Configure Complementary channels, break features and dead time.
1812       (+) Configure Master synchronization.
1813       (+) Configure timer remapping capabilities.
1814       (+) Enable or disable channel grouping.
1815 
1816 @endverbatim
1817   * @{
1818   */
1819 
1820 /**
1821   * @brief  Configure the TIM commutation event sequence.
1822   * @note  This function is mandatory to use the commutation event in order to
1823   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1824   *        the typical use of this feature is with the use of another Timer(interface Timer)
1825   *        configured in Hall sensor interface, this interface Timer will generate the
1826   *        commutation at its TRGO output (connected to Timer used in this function) each time
1827   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1828   * @param  htim TIM handle
1829   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1830   *          This parameter can be one of the following values:
1831   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1832   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1833   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1834   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1835   *            @arg TIM_TS_NONE: No trigger is needed
1836   * @param  CommutationSource the Commutation Event source
1837   *          This parameter can be one of the following values:
1838   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1839   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1840   * @retval HAL status
1841   */
HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1842 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1843                                               uint32_t  CommutationSource)
1844 {
1845   /* Check the parameters */
1846   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1847   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1848 
1849   __HAL_LOCK(htim);
1850 
1851   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1852       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1853   {
1854     /* Select the Input trigger */
1855     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1856     htim->Instance->SMCR |= InputTrigger;
1857   }
1858 
1859   /* Select the Capture Compare preload feature */
1860   htim->Instance->CR2 |= TIM_CR2_CCPC;
1861   /* Select the Commutation event source */
1862   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1863   htim->Instance->CR2 |= CommutationSource;
1864 
1865   /* Disable Commutation Interrupt */
1866   __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
1867 
1868   /* Disable Commutation DMA request */
1869   __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
1870 
1871   __HAL_UNLOCK(htim);
1872 
1873   return HAL_OK;
1874 }
1875 
1876 /**
1877   * @brief  Configure the TIM commutation event sequence with interrupt.
1878   * @note  This function is mandatory to use the commutation event in order to
1879   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1880   *        the typical use of this feature is with the use of another Timer(interface Timer)
1881   *        configured in Hall sensor interface, this interface Timer will generate the
1882   *        commutation at its TRGO output (connected to Timer used in this function) each time
1883   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1884   * @param  htim TIM handle
1885   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1886   *          This parameter can be one of the following values:
1887   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1888   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1889   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1890   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1891   *            @arg TIM_TS_NONE: No trigger is needed
1892   * @param  CommutationSource the Commutation Event source
1893   *          This parameter can be one of the following values:
1894   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1895   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1896   * @retval HAL status
1897   */
HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1898 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1899                                                  uint32_t  CommutationSource)
1900 {
1901   /* Check the parameters */
1902   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1903   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1904 
1905   __HAL_LOCK(htim);
1906 
1907   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1908       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1909   {
1910     /* Select the Input trigger */
1911     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1912     htim->Instance->SMCR |= InputTrigger;
1913   }
1914 
1915   /* Select the Capture Compare preload feature */
1916   htim->Instance->CR2 |= TIM_CR2_CCPC;
1917   /* Select the Commutation event source */
1918   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1919   htim->Instance->CR2 |= CommutationSource;
1920 
1921   /* Disable Commutation DMA request */
1922   __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
1923 
1924   /* Enable the Commutation Interrupt */
1925   __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
1926 
1927   __HAL_UNLOCK(htim);
1928 
1929   return HAL_OK;
1930 }
1931 
1932 /**
1933   * @brief  Configure the TIM commutation event sequence with DMA.
1934   * @note  This function is mandatory to use the commutation event in order to
1935   *        update the configuration at each commutation detection on the TRGI input of the Timer,
1936   *        the typical use of this feature is with the use of another Timer(interface Timer)
1937   *        configured in Hall sensor interface, this interface Timer will generate the
1938   *        commutation at its TRGO output (connected to Timer used in this function) each time
1939   *        the TI1 of the Interface Timer detect a commutation at its input TI1.
1940   * @note  The user should configure the DMA in his own software, in This function only the COMDE bit is set
1941   * @param  htim TIM handle
1942   * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
1943   *          This parameter can be one of the following values:
1944   *            @arg TIM_TS_ITR0: Internal trigger 0 selected
1945   *            @arg TIM_TS_ITR1: Internal trigger 1 selected
1946   *            @arg TIM_TS_ITR2: Internal trigger 2 selected
1947   *            @arg TIM_TS_ITR3: Internal trigger 3 selected
1948   *            @arg TIM_TS_NONE: No trigger is needed
1949   * @param  CommutationSource the Commutation Event source
1950   *          This parameter can be one of the following values:
1951   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1952   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1953   * @retval HAL status
1954   */
HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1955 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1956                                                   uint32_t  CommutationSource)
1957 {
1958   /* Check the parameters */
1959   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1960   assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
1961 
1962   __HAL_LOCK(htim);
1963 
1964   if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
1965       (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
1966   {
1967     /* Select the Input trigger */
1968     htim->Instance->SMCR &= ~TIM_SMCR_TS;
1969     htim->Instance->SMCR |= InputTrigger;
1970   }
1971 
1972   /* Select the Capture Compare preload feature */
1973   htim->Instance->CR2 |= TIM_CR2_CCPC;
1974   /* Select the Commutation event source */
1975   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1976   htim->Instance->CR2 |= CommutationSource;
1977 
1978   /* Enable the Commutation DMA Request */
1979   /* Set the DMA Commutation Callback */
1980   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
1981   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt;
1982   /* Set the DMA error callback */
1983   htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
1984 
1985   /* Disable Commutation Interrupt */
1986   __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
1987 
1988   /* Enable the Commutation DMA Request */
1989   __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
1990 
1991   __HAL_UNLOCK(htim);
1992 
1993   return HAL_OK;
1994 }
1995 
1996 /**
1997   * @brief  Configures the TIM in master mode.
1998   * @param  htim TIM handle.
1999   * @param  sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that
2000   *         contains the selected trigger output (TRGO) and the Master/Slave
2001   *         mode.
2002   * @retval HAL status
2003   */
HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef * htim,const TIM_MasterConfigTypeDef * sMasterConfig)2004 HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
2005                                                         const TIM_MasterConfigTypeDef *sMasterConfig)
2006 {
2007   uint32_t tmpcr2;
2008   uint32_t tmpsmcr;
2009 
2010   /* Check the parameters */
2011   assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
2012   assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
2013   assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
2014 
2015   /* Check input state */
2016   __HAL_LOCK(htim);
2017 
2018   /* Change the handler state */
2019   htim->State = HAL_TIM_STATE_BUSY;
2020 
2021   /* Get the TIMx CR2 register value */
2022   tmpcr2 = htim->Instance->CR2;
2023 
2024   /* Get the TIMx SMCR register value */
2025   tmpsmcr = htim->Instance->SMCR;
2026 
2027   /* If the timer supports ADC synchronization through TRGO2, set the master mode selection 2 */
2028   if (IS_TIM_TRGO2_INSTANCE(htim->Instance))
2029   {
2030     /* Check the parameters */
2031     assert_param(IS_TIM_TRGO2_SOURCE(sMasterConfig->MasterOutputTrigger2));
2032 
2033     /* Clear the MMS2 bits */
2034     tmpcr2 &= ~TIM_CR2_MMS2;
2035     /* Select the TRGO2 source*/
2036     tmpcr2 |= sMasterConfig->MasterOutputTrigger2;
2037   }
2038 
2039   /* Reset the MMS Bits */
2040   tmpcr2 &= ~TIM_CR2_MMS;
2041   /* Select the TRGO source */
2042   tmpcr2 |=  sMasterConfig->MasterOutputTrigger;
2043 
2044   /* Update TIMx CR2 */
2045   htim->Instance->CR2 = tmpcr2;
2046 
2047   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
2048   {
2049     /* Reset the MSM Bit */
2050     tmpsmcr &= ~TIM_SMCR_MSM;
2051     /* Set master mode */
2052     tmpsmcr |= sMasterConfig->MasterSlaveMode;
2053 
2054     /* Update TIMx SMCR */
2055     htim->Instance->SMCR = tmpsmcr;
2056   }
2057 
2058   /* Change the htim state */
2059   htim->State = HAL_TIM_STATE_READY;
2060 
2061   __HAL_UNLOCK(htim);
2062 
2063   return HAL_OK;
2064 }
2065 
2066 /**
2067   * @brief  Configures the Break feature, dead time, Lock level, OSSI/OSSR State
2068   *         and the AOE(automatic output enable).
2069   * @param  htim TIM handle
2070   * @param  sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
2071   *         contains the BDTR Register configuration  information for the TIM peripheral.
2072   * @note   Interrupts can be generated when an active level is detected on the
2073   *         break input, the break 2 input or the system break input. Break
2074   *         interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
2075   * @retval HAL status
2076   */
HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef * htim,const TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig)2077 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
2078                                                 const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
2079 {
2080   /* Keep this variable initialized to 0 as it is used to configure BDTR register */
2081   uint32_t tmpbdtr = 0U;
2082 
2083   /* Check the parameters */
2084   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
2085   assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
2086   assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
2087   assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
2088   assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
2089   assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
2090   assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
2091   assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
2092   assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
2093 
2094   /* Check input state */
2095   __HAL_LOCK(htim);
2096 
2097   /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
2098      the OSSI State, the dead time value and the Automatic Output Enable Bit */
2099 
2100   /* Set the BDTR bits */
2101   MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
2102   MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
2103   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
2104   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
2105   MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
2106   MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
2107   MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
2108   MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));
2109 
2110   if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
2111   {
2112     /* Check the parameters */
2113     assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode));
2114 
2115     /* Set BREAK AF mode */
2116     MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode);
2117   }
2118 
2119   if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
2120   {
2121     /* Check the parameters */
2122     assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
2123     assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
2124     assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));
2125 
2126     /* Set the BREAK2 input related BDTR bits */
2127     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos));
2128     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
2129     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
2130 
2131     if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
2132     {
2133       /* Check the parameters */
2134       assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode));
2135 
2136       /* Set BREAK2 AF mode */
2137       MODIFY_REG(tmpbdtr, TIM_BDTR_BK2BID, sBreakDeadTimeConfig->Break2AFMode);
2138     }
2139   }
2140 
2141   /* Set TIMx_BDTR */
2142   htim->Instance->BDTR = tmpbdtr;
2143 
2144   __HAL_UNLOCK(htim);
2145 
2146   return HAL_OK;
2147 }
2148 
2149 /**
2150   * @brief  Configures the break input source.
2151   * @param  htim TIM handle.
2152   * @param  BreakInput Break input to configure
2153   *          This parameter can be one of the following values:
2154   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2155   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2156   * @param  sBreakInputConfig Break input source configuration
2157   * @retval HAL status
2158   */
HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput,const TIMEx_BreakInputConfigTypeDef * sBreakInputConfig)2159 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim,
2160                                              uint32_t BreakInput,
2161                                              const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
2162 
2163 {
2164   HAL_StatusTypeDef status = HAL_OK;
2165   uint32_t tmporx;
2166   uint32_t bkin_enable_mask;
2167   uint32_t bkin_polarity_mask;
2168   uint32_t bkin_enable_bitpos;
2169   uint32_t bkin_polarity_bitpos;
2170 
2171   /* Check the parameters */
2172   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
2173   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2174   assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source));
2175   assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable));
2176   assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
2177 
2178   /* Check input state */
2179   __HAL_LOCK(htim);
2180 
2181   switch (sBreakInputConfig->Source)
2182   {
2183     case TIM_BREAKINPUTSOURCE_BKIN:
2184     {
2185       bkin_enable_mask = TIM1_AF1_BKINE;
2186       bkin_enable_bitpos = TIM1_AF1_BKINE_Pos;
2187       bkin_polarity_mask = TIM1_AF1_BKINP;
2188       bkin_polarity_bitpos = TIM1_AF1_BKINP_Pos;
2189       break;
2190     }
2191 #if defined(COMP1) && defined(COMP2)
2192     case TIM_BREAKINPUTSOURCE_COMP1:
2193     {
2194       bkin_enable_mask = TIM1_AF1_BKCMP1E;
2195       bkin_enable_bitpos = TIM1_AF1_BKCMP1E_Pos;
2196       bkin_polarity_mask = TIM1_AF1_BKCMP1P;
2197       bkin_polarity_bitpos = TIM1_AF1_BKCMP1P_Pos;
2198       break;
2199     }
2200     case TIM_BREAKINPUTSOURCE_COMP2:
2201     {
2202       bkin_enable_mask = TIM1_AF1_BKCMP2E;
2203       bkin_enable_bitpos = TIM1_AF1_BKCMP2E_Pos;
2204       bkin_polarity_mask = TIM1_AF1_BKCMP2P;
2205       bkin_polarity_bitpos = TIM1_AF1_BKCMP2P_Pos;
2206       break;
2207     }
2208 #endif /* COMP1 && COMP2 */
2209 
2210     default:
2211     {
2212       bkin_enable_mask = 0U;
2213       bkin_polarity_mask = 0U;
2214       bkin_enable_bitpos = 0U;
2215       bkin_polarity_bitpos = 0U;
2216       break;
2217     }
2218   }
2219 
2220   switch (BreakInput)
2221   {
2222     case TIM_BREAKINPUT_BRK:
2223     {
2224       /* Get the TIMx_AF1 register value */
2225       tmporx = htim->Instance->AF1;
2226 
2227       /* Enable the break input */
2228       tmporx &= ~bkin_enable_mask;
2229       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
2230 
2231       /* Set the break input polarity */
2232       tmporx &= ~bkin_polarity_mask;
2233       tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
2234 
2235       /* Set TIMx_AF1 */
2236       htim->Instance->AF1 = tmporx;
2237       break;
2238     }
2239     case TIM_BREAKINPUT_BRK2:
2240     {
2241       /* Get the TIMx_AF2 register value */
2242       tmporx = htim->Instance->AF2;
2243 
2244       /* Enable the break input */
2245       tmporx &= ~bkin_enable_mask;
2246       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
2247 
2248       /* Set the break input polarity */
2249       tmporx &= ~bkin_polarity_mask;
2250       tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
2251 
2252       /* Set TIMx_AF2 */
2253       htim->Instance->AF2 = tmporx;
2254       break;
2255     }
2256     default:
2257       status = HAL_ERROR;
2258       break;
2259   }
2260 
2261   __HAL_UNLOCK(htim);
2262 
2263   return status;
2264 }
2265 
2266 /**
2267   * @brief  Configures the TIMx Remapping input capabilities.
2268   * @param  htim TIM handle.
2269   * @param  Remap specifies the TIM remapping source.
2270   *     For TIM1, the parameter is a combination of 2 fields (field1 | field2):
2271   *
2272   *       field1 can have the following values:
2273   *            @arg TIM_TIM1_ETR_ADC1_GPIO:           TIM1_ETR is connected to I/O
2274   *            @arg TIM_TIM1_ETR_ADC1_AWD1:           TIM1_ETR is connected to ADC1 AWD1
2275   *            @arg TIM_TIM1_ETR_ADC1_AWD2:           TIM1_ETR is connected to ADC1 AWD2 (*)
2276   *            @arg TIM_TIM1_ETR_ADC1_AWD3:           TIM1_ETR is connected to ADC1 AWD3 (*)
2277   *            @arg TIM_TIM1_ETR_COMP1:               TIM1_ETR is connected to COMP1 output (*)
2278   *            @arg TIM_TIM1_ETR_COMP2:               TIM1_ETR is connected to COMP2 output (*)
2279   *       field2 can have the following values:
2280   *            @arg TIM_TIM1_TI1_GPIO:                TIM1 TI1 is connected to I/O
2281   *            @arg TIM_TIM1_TI1_COMP1:               TIM1 TI1 is connected to COMP1 output (*)
2282   *
2283   *        For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
2284   *
2285   *       field1 can have the following values:
2286   *            @arg TIM_TIM2_ITR1_NONE:               No internal trigger on TIM2_ITR1
2287   *            @arg TIM_TIM2_ITR1_USB:                TIM2_ITR1 is connected to USB SOF (*)
2288   *
2289   *       field2 can have the following values:
2290   *            @arg TIM_TIM2_ETR_GPIO:                TIM2_ETR is connected to I/O
2291   *            @arg TIM_TIM2_ETR_LSE:                 TIM2_ETR is connected to LSE
2292   *            @arg TIM_TIM2_ETR_COMP1:               TIM2_ETR is connected to COMP1 output (*)
2293   *            @arg TIM_TIM2_ETR_COMP2:               TIM2_ETR is connected to COMP2 output (*)
2294   *
2295   *       field3 can have the following values:
2296   *            @arg TIM_TIM2_TI4_GPIO:                TIM2 TI4 is connected to I/O
2297   *            @arg TIM_TIM2_TI4_COMP1:               TIM2 TI4 is connected to COMP1 output (*)
2298   *            @arg TIM_TIM2_TI4_COMP2:               TIM2 TI4 is connected to COMP2 output (*)
2299   *            @arg TIM_TIM2_TI4_COMP1_COMP2:         TIM2 TI4 is connected to logical OR between COMP1 and COMP2 output (*)
2300   *
2301   *     For TIM16, the parameter can have the following values:
2302   *            @arg TIM_TIM16_TI1_GPIO:              TIM16 TI1 is connected to I/O
2303   *            @arg TIM_TIM16_TI1_LSI:               TIM16 TI1 is connected to LSI
2304   *            @arg TIM_TIM16_TI1_LSE:               TIM16 TI1 is connected to LSE
2305   *            @arg TIM_TIM16_TI1_RTC:               TIM16 TI1 is connected to RTC wakeup interrupt
2306   *
2307   *     For TIM17, the parameter can have the following values:
2308   *            @arg TIM_TIM17_TI1_GPIO:              TIM17 TI1 is connected to I/O
2309   *            @arg TIM_TIM17_TI1_MSI:               TIM17 TI1 is connected to MSI  (constraint: MSI clock < 1/4 TIM APB clock)
2310   *            @arg TIM_TIM17_TI1_HSE:               TIM17 TI1 is connected to HSE div 32
2311   *            @arg TIM_TIM17_TI1_MCO:               TIM17 TI1 is connected to MCO
2312   *
2313   *         (*)  Value not defined in all devices.
2314   *
2315   * @retval HAL status
2316   */
HAL_TIMEx_RemapConfig(TIM_HandleTypeDef * htim,uint32_t Remap)2317 HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
2318 {
2319   uint32_t tmpor;
2320   uint32_t tmpaf1;
2321 
2322   /* Check parameters */
2323   assert_param(IS_TIM_REMAP(htim->Instance, Remap));
2324 
2325   __HAL_LOCK(htim);
2326 
2327   /* Read TIMx_OR */
2328   tmpor = READ_REG(htim->Instance->OR);
2329 
2330   /* Read TIMx_AF1 */
2331   tmpaf1 = READ_REG(htim->Instance->AF1);
2332 
2333   /* Set ETR_SEL bit field (if required) */
2334   if (IS_TIM_ETRSEL_INSTANCE(htim->Instance))
2335   {
2336     if ((Remap & TIM1_AF1_ETRSEL) != (uint32_t)RESET)
2337     {
2338       /* COMP1 output or COMP2 output connected to ETR input */
2339       MODIFY_REG(tmpaf1, TIM1_AF1_ETRSEL, (Remap & TIM1_AF1_ETRSEL));
2340     }
2341     else
2342     {
2343       /* ETR legacy mode */
2344       MODIFY_REG(tmpaf1, TIM1_AF1_ETRSEL, 0U);
2345     }
2346 
2347     /* Set TIMx_AF1 */
2348     WRITE_REG(htim->Instance->AF1, tmpaf1);
2349   }
2350 
2351   /* Set other remapping capabilities */
2352   MODIFY_REG(tmpor, TIM_GET_OR_MASK(htim->Instance), (Remap & (~TIM1_AF1_ETRSEL)));
2353 
2354   /* Set TIMx_OR */
2355   WRITE_REG(htim->Instance->OR, tmpor);
2356 
2357   __HAL_UNLOCK(htim);
2358 
2359   return HAL_OK;
2360 }
2361 
2362 /**
2363   * @brief  Group channel 5 and channel 1, 2 or 3
2364   * @param  htim TIM handle.
2365   * @param  Channels specifies the reference signal(s) the OC5REF is combined with.
2366   *         This parameter can be any combination of the following values:
2367   *         TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC
2368   *         TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF
2369   *         TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF
2370   *         TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF
2371   * @retval HAL status
2372   */
HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef * htim,uint32_t Channels)2373 HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels)
2374 {
2375   /* Check parameters */
2376   assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance));
2377   assert_param(IS_TIM_GROUPCH5(Channels));
2378 
2379   /* Process Locked */
2380   __HAL_LOCK(htim);
2381 
2382   htim->State = HAL_TIM_STATE_BUSY;
2383 
2384   /* Clear GC5Cx bit fields */
2385   htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1);
2386 
2387   /* Set GC5Cx bit fields */
2388   htim->Instance->CCR5 |= Channels;
2389 
2390   /* Change the htim state */
2391   htim->State = HAL_TIM_STATE_READY;
2392 
2393   __HAL_UNLOCK(htim);
2394 
2395   return HAL_OK;
2396 }
2397 
2398 /**
2399   * @brief  Disarm the designated break input (when it operates in bidirectional mode).
2400   * @param  htim TIM handle.
2401   * @param  BreakInput Break input to disarm
2402   *          This parameter can be one of the following values:
2403   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2404   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2405   * @note  The break input can be disarmed only when it is configured in
2406   *        bidirectional mode and when when MOE is reset.
2407   * @note  Purpose is to be able to have the input voltage back to high-state,
2408   *        whatever the time constant on the output .
2409   * @retval HAL status
2410   */
HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput)2411 HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
2412 {
2413   HAL_StatusTypeDef status = HAL_OK;
2414   uint32_t tmpbdtr;
2415 
2416   /* Check the parameters */
2417   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
2418   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2419 
2420   switch (BreakInput)
2421   {
2422     case TIM_BREAKINPUT_BRK:
2423     {
2424       /* Check initial conditions */
2425       tmpbdtr = READ_REG(htim->Instance->BDTR);
2426       if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) &&
2427           (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
2428       {
2429         /* Break input BRK is disarmed */
2430         SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM);
2431       }
2432       break;
2433     }
2434 
2435     case TIM_BREAKINPUT_BRK2:
2436     {
2437       /* Check initial conditions */
2438       tmpbdtr = READ_REG(htim->Instance->BDTR);
2439       if ((READ_BIT(tmpbdtr, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID) &&
2440           (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
2441       {
2442         /* Break input BRK is disarmed */
2443         SET_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM);
2444       }
2445       break;
2446     }
2447     default:
2448       status = HAL_ERROR;
2449       break;
2450   }
2451 
2452   return status;
2453 }
2454 
2455 /**
2456   * @brief  Arm the designated break input (when it operates in bidirectional mode).
2457   * @param  htim TIM handle.
2458   * @param  BreakInput Break input to arm
2459   *          This parameter can be one of the following values:
2460   *            @arg TIM_BREAKINPUT_BRK: Timer break input
2461   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
2462   * @note  Arming is possible at anytime, even if fault is present.
2463   * @note  Break input is automatically armed as soon as MOE bit is set.
2464   * @retval HAL status
2465   */
HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef * htim,uint32_t BreakInput)2466 HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef *htim, uint32_t BreakInput)
2467 {
2468   HAL_StatusTypeDef status = HAL_OK;
2469   uint32_t tickstart;
2470 
2471   /* Check the parameters */
2472   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
2473   assert_param(IS_TIM_BREAKINPUT(BreakInput));
2474 
2475   switch (BreakInput)
2476   {
2477     case TIM_BREAKINPUT_BRK:
2478     {
2479       /* Check initial conditions */
2480       if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID)
2481       {
2482         /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
2483         /* Init tickstart for timeout management */
2484         tickstart = HAL_GetTick();
2485         while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
2486         {
2487           if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
2488           {
2489             /* New check to avoid false timeout detection in case of preemption */
2490             if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
2491             {
2492               return HAL_TIMEOUT;
2493             }
2494           }
2495         }
2496       }
2497       break;
2498     }
2499 
2500     case TIM_BREAKINPUT_BRK2:
2501     {
2502       /* Check initial conditions */
2503       if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID)
2504       {
2505         /* Break input BRK2 is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
2506         /* Init tickstart for timeout management */
2507         tickstart = HAL_GetTick();
2508         while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
2509         {
2510           if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
2511           {
2512             /* New check to avoid false timeout detection in case of preemption */
2513             if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
2514             {
2515               return HAL_TIMEOUT;
2516             }
2517           }
2518         }
2519       }
2520       break;
2521     }
2522     default:
2523       status = HAL_ERROR;
2524       break;
2525   }
2526 
2527   return status;
2528 }
2529 
2530 /**
2531   * @}
2532   */
2533 
2534 /** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
2535   * @brief    Extended Callbacks functions
2536   *
2537 @verbatim
2538   ==============================================================================
2539                     ##### Extended Callbacks functions #####
2540   ==============================================================================
2541   [..]
2542     This section provides Extended TIM callback functions:
2543     (+) Timer Commutation callback
2544     (+) Timer Break callback
2545 
2546 @endverbatim
2547   * @{
2548   */
2549 
2550 /**
2551   * @brief  Hall commutation changed callback in non-blocking mode
2552   * @param  htim TIM handle
2553   * @retval None
2554   */
HAL_TIMEx_CommutCallback(TIM_HandleTypeDef * htim)2555 __weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
2556 {
2557   /* Prevent unused argument(s) compilation warning */
2558   UNUSED(htim);
2559 
2560   /* NOTE : This function should not be modified, when the callback is needed,
2561             the HAL_TIMEx_CommutCallback could be implemented in the user file
2562    */
2563 }
2564 /**
2565   * @brief  Hall commutation changed half complete callback in non-blocking mode
2566   * @param  htim TIM handle
2567   * @retval None
2568   */
HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef * htim)2569 __weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
2570 {
2571   /* Prevent unused argument(s) compilation warning */
2572   UNUSED(htim);
2573 
2574   /* NOTE : This function should not be modified, when the callback is needed,
2575             the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file
2576    */
2577 }
2578 
2579 /**
2580   * @brief  Hall Break detection callback in non-blocking mode
2581   * @param  htim TIM handle
2582   * @retval None
2583   */
HAL_TIMEx_BreakCallback(TIM_HandleTypeDef * htim)2584 __weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
2585 {
2586   /* Prevent unused argument(s) compilation warning */
2587   UNUSED(htim);
2588 
2589   /* NOTE : This function should not be modified, when the callback is needed,
2590             the HAL_TIMEx_BreakCallback could be implemented in the user file
2591    */
2592 }
2593 
2594 /**
2595   * @brief  Hall Break2 detection callback in non blocking mode
2596   * @param  htim: TIM handle
2597   * @retval None
2598   */
HAL_TIMEx_Break2Callback(TIM_HandleTypeDef * htim)2599 __weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
2600 {
2601   /* Prevent unused argument(s) compilation warning */
2602   UNUSED(htim);
2603 
2604   /* NOTE : This function Should not be modified, when the callback is needed,
2605             the HAL_TIMEx_Break2Callback could be implemented in the user file
2606    */
2607 }
2608 /**
2609   * @}
2610   */
2611 
2612 /** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
2613   * @brief    Extended Peripheral State functions
2614   *
2615 @verbatim
2616   ==============================================================================
2617                 ##### Extended Peripheral State functions #####
2618   ==============================================================================
2619   [..]
2620     This subsection permits to get in run-time the status of the peripheral
2621     and the data flow.
2622 
2623 @endverbatim
2624   * @{
2625   */
2626 
2627 /**
2628   * @brief  Return the TIM Hall Sensor interface handle state.
2629   * @param  htim TIM Hall Sensor handle
2630   * @retval HAL state
2631   */
HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef * htim)2632 HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim)
2633 {
2634   return htim->State;
2635 }
2636 
2637 /**
2638   * @brief  Return actual state of the TIM complementary channel.
2639   * @param  htim TIM handle
2640   * @param  ChannelN TIM Complementary channel
2641   *          This parameter can be one of the following values:
2642   *            @arg TIM_CHANNEL_1: TIM Channel 1
2643   *            @arg TIM_CHANNEL_2: TIM Channel 2
2644   *            @arg TIM_CHANNEL_3: TIM Channel 3
2645   * @retval TIM Complementary channel state
2646   */
HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef * htim,uint32_t ChannelN)2647 HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim,  uint32_t ChannelN)
2648 {
2649   HAL_TIM_ChannelStateTypeDef channel_state;
2650 
2651   /* Check the parameters */
2652   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN));
2653 
2654   channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN);
2655 
2656   return channel_state;
2657 }
2658 /**
2659   * @}
2660   */
2661 
2662 /**
2663   * @}
2664   */
2665 
2666 /* Private functions ---------------------------------------------------------*/
2667 /** @defgroup TIMEx_Private_Functions TIM Extended Private Functions
2668   * @{
2669   */
2670 
2671 /**
2672   * @brief  TIM DMA Commutation callback.
2673   * @param  hdma pointer to DMA handle.
2674   * @retval None
2675   */
TIMEx_DMACommutationCplt(DMA_HandleTypeDef * hdma)2676 void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
2677 {
2678   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2679 
2680   /* Change the htim state */
2681   htim->State = HAL_TIM_STATE_READY;
2682 
2683 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2684   htim->CommutationCallback(htim);
2685 #else
2686   HAL_TIMEx_CommutCallback(htim);
2687 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2688 }
2689 
2690 /**
2691   * @brief  TIM DMA Commutation half complete callback.
2692   * @param  hdma pointer to DMA handle.
2693   * @retval None
2694   */
TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef * hdma)2695 void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
2696 {
2697   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2698 
2699   /* Change the htim state */
2700   htim->State = HAL_TIM_STATE_READY;
2701 
2702 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2703   htim->CommutationHalfCpltCallback(htim);
2704 #else
2705   HAL_TIMEx_CommutHalfCpltCallback(htim);
2706 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2707 }
2708 
2709 
2710 /**
2711   * @brief  TIM DMA Delay Pulse complete callback (complementary channel).
2712   * @param  hdma pointer to DMA handle.
2713   * @retval None
2714   */
TIM_DMADelayPulseNCplt(DMA_HandleTypeDef * hdma)2715 static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma)
2716 {
2717   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2718 
2719   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
2720   {
2721     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
2722 
2723     if (hdma->Init.Mode == DMA_NORMAL)
2724     {
2725       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
2726     }
2727   }
2728   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
2729   {
2730     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
2731 
2732     if (hdma->Init.Mode == DMA_NORMAL)
2733     {
2734       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
2735     }
2736   }
2737   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
2738   {
2739     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
2740 
2741     if (hdma->Init.Mode == DMA_NORMAL)
2742     {
2743       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
2744     }
2745   }
2746   else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
2747   {
2748     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
2749 
2750     if (hdma->Init.Mode == DMA_NORMAL)
2751     {
2752       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
2753     }
2754   }
2755   else
2756   {
2757     /* nothing to do */
2758   }
2759 
2760 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2761   htim->PWM_PulseFinishedCallback(htim);
2762 #else
2763   HAL_TIM_PWM_PulseFinishedCallback(htim);
2764 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2765 
2766   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
2767 }
2768 
2769 /**
2770   * @brief  TIM DMA error callback (complementary channel)
2771   * @param  hdma pointer to DMA handle.
2772   * @retval None
2773   */
TIM_DMAErrorCCxN(DMA_HandleTypeDef * hdma)2774 static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma)
2775 {
2776   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2777 
2778   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
2779   {
2780     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
2781     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
2782   }
2783   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
2784   {
2785     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
2786     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
2787   }
2788   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
2789   {
2790     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
2791     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
2792   }
2793   else
2794   {
2795     /* nothing to do */
2796   }
2797 
2798 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2799   htim->ErrorCallback(htim);
2800 #else
2801   HAL_TIM_ErrorCallback(htim);
2802 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2803 
2804   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
2805 }
2806 
2807 /**
2808   * @brief  Enables or disables the TIM Capture Compare Channel xN.
2809   * @param  TIMx to select the TIM peripheral
2810   * @param  Channel specifies the TIM Channel
2811   *          This parameter can be one of the following values:
2812   *            @arg TIM_CHANNEL_1: TIM Channel 1
2813   *            @arg TIM_CHANNEL_2: TIM Channel 2
2814   *            @arg TIM_CHANNEL_3: TIM Channel 3
2815   * @param  ChannelNState specifies the TIM Channel CCxNE bit new state.
2816   *          This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
2817   * @retval None
2818   */
TIM_CCxNChannelCmd(TIM_TypeDef * TIMx,uint32_t Channel,uint32_t ChannelNState)2819 static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
2820 {
2821   uint32_t tmp;
2822 
2823   tmp = TIM_CCER_CC1NE << (Channel & 0xFU); /* 0xFU = 15 bits max shift */
2824 
2825   /* Reset the CCxNE Bit */
2826   TIMx->CCER &=  ~tmp;
2827 
2828   /* Set or reset the CCxNE Bit */
2829   TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0xFU)); /* 0xFU = 15 bits max shift */
2830 }
2831 /**
2832   * @}
2833   */
2834 
2835 #endif /* HAL_TIM_MODULE_ENABLED */
2836 /**
2837   * @}
2838   */
2839 
2840 /**
2841   * @}
2842   */
2843