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