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