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