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