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