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