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