1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_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 Complementary signal break and dead time configuration
9   *           + Time Master and Slave synchronization configuration
10   *           + Time Output Compare/PWM Channel Configuration (for channels 5 and 6)
11   *           + Time OCRef clear configuration
12   *           + Timer remapping capabilities configuration
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2024 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 
38             ##### How to use this driver #####
39   ==============================================================================
40     [..]
41      (#) Initialize the TIM low level resources by implementing the following functions
42          depending on the selected feature:
43 
44      (#) Activate the TIM peripheral using one of the start functions:
45            (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(),
46                 HAL_TIMEx_OCN_Start_IT()
47            (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(),
48                 HAL_TIMEx_PWMN_Start_IT()
49            (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
50 
51   @endverbatim
52   ******************************************************************************
53   */
54 
55 /* Includes ------------------------------------------------------------------*/
56 #include "stm32wb0x_hal.h"
57 
58 /** @addtogroup STM32WB0x_HAL_Driver
59   * @{
60   */
61 
62 /** @defgroup TIMEx TIMEx
63   * @brief TIM Extended HAL module driver
64   * @{
65   */
66 
67 #ifdef HAL_TIM_MODULE_ENABLED
68 
69 /* Private typedef -----------------------------------------------------------*/
70 /* Private define ------------------------------------------------------------*/
71 #if defined(TIM_BDTR_BKBID)
72 /* Private constants ---------------------------------------------------------*/
73 /** @defgroup TIMEx_Private_Constants TIM Extended Private Constants
74   * @{
75   */
76 /* Timeout for break input rearm */
77 #define TIM_BREAKINPUT_REARM_TIMEOUT    5UL /* 5 milliseconds */
78 /**
79   * @}
80   */
81 /* End of private constants --------------------------------------------------*/
82 
83 #endif /* TIM_BDTR_BKBID */
84 /* Private macros ------------------------------------------------------------*/
85 /* Private variables ---------------------------------------------------------*/
86 /* Private function prototypes -----------------------------------------------*/
87 #if defined(TIM_DMA_SUPPORT)
88 static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma);
89 static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma);
90 #endif /* TIM_DMA_SUPPORT */
91 static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState);
92 
93 /* Exported functions --------------------------------------------------------*/
94 /** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions
95   * @{
96   */
97 /** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions
98   *  @brief   Timer Complementary Output Compare functions
99   *
100 @verbatim
101   ==============================================================================
102               ##### Timer Complementary Output Compare functions #####
103   ==============================================================================
104   [..]
105     This section provides functions allowing to:
106     (+) Start the Complementary Output Compare/PWM.
107     (+) Stop the Complementary Output Compare/PWM.
108     (+) Start the Complementary Output Compare/PWM and enable interrupts.
109     (+) Stop the Complementary Output Compare/PWM and disable interrupts.
110     (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
111     (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
112 
113 @endverbatim
114   * @{
115   */
116 
117 /**
118   * @brief  Starts the TIM Output Compare signal generation on the complementary
119   *         output.
120   * @param  htim TIM Output Compare handle
121   * @param  Channel TIM Channel to be enabled
122   *          This parameter can be one of the following values:
123   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
124   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
125   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
126   * @retval HAL status
127   */
HAL_TIMEx_OCN_Start(TIM_HandleTypeDef * htim,uint32_t Channel)128 HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
129 {
130   uint32_t tmpsmcr;
131 
132   /* Check the parameters */
133   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
134 
135   /* Check the TIM complementary channel state */
136   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
137   {
138     return HAL_ERROR;
139   }
140 
141   /* Set the TIM complementary channel state */
142   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
143 
144   /* Enable the Capture compare channel N */
145   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
146 
147   /* Enable the Main Output */
148   __HAL_TIM_MOE_ENABLE(htim);
149 
150   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
151   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
152   {
153     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
154     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
155     {
156       __HAL_TIM_ENABLE(htim);
157     }
158   }
159   else
160   {
161     __HAL_TIM_ENABLE(htim);
162   }
163 
164   /* Return function status */
165   return HAL_OK;
166 }
167 
168 /**
169   * @brief  Stops the TIM Output Compare signal generation on the complementary
170   *         output.
171   * @param  htim TIM handle
172   * @param  Channel TIM Channel to be disabled
173   *          This parameter can be one of the following values:
174   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
175   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
176   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
177   * @retval HAL status
178   */
HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef * htim,uint32_t Channel)179 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
180 {
181   /* Check the parameters */
182   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
183 
184   /* Disable the Capture compare channel N */
185   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
186 
187   /* Disable the Main Output */
188   __HAL_TIM_MOE_DISABLE(htim);
189 
190   /* Disable the Peripheral */
191   __HAL_TIM_DISABLE(htim);
192 
193   /* Set the TIM complementary channel state */
194   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
195 
196   /* Return function status */
197   return HAL_OK;
198 }
199 
200 /**
201   * @brief  Starts the TIM Output Compare signal generation in interrupt mode
202   *         on the complementary output.
203   * @param  htim TIM OC handle
204   * @param  Channel TIM Channel to be enabled
205   *          This parameter can be one of the following values:
206   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
207   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
208   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
209   * @retval HAL status
210   */
HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef * htim,uint32_t Channel)211 HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
212 {
213   HAL_StatusTypeDef status = HAL_OK;
214   uint32_t tmpsmcr;
215 
216   /* Check the parameters */
217   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
218 
219   /* Check the TIM complementary channel state */
220   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
221   {
222     return HAL_ERROR;
223   }
224 
225   /* Set the TIM complementary channel state */
226   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
227 
228   switch (Channel)
229   {
230     case TIM_CHANNEL_1:
231     {
232       /* Enable the TIM Output Compare interrupt */
233       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
234       break;
235     }
236 
237     case TIM_CHANNEL_2:
238     {
239       /* Enable the TIM Output Compare interrupt */
240       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
241       break;
242     }
243 
244     case TIM_CHANNEL_3:
245     {
246       /* Enable the TIM Output Compare interrupt */
247       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
248       break;
249     }
250 
251 
252     default:
253       status = HAL_ERROR;
254       break;
255   }
256 
257   if (status == HAL_OK)
258   {
259     /* Enable the TIM Break interrupt */
260     __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
261 
262     /* Enable the Capture compare channel N */
263     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
264 
265     /* Enable the Main Output */
266     __HAL_TIM_MOE_ENABLE(htim);
267 
268     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
269     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
270     {
271       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
272       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
273       {
274         __HAL_TIM_ENABLE(htim);
275       }
276     }
277     else
278     {
279       __HAL_TIM_ENABLE(htim);
280     }
281   }
282 
283   /* Return function status */
284   return status;
285 }
286 
287 /**
288   * @brief  Stops the TIM Output Compare signal generation in interrupt mode
289   *         on the complementary output.
290   * @param  htim TIM Output Compare handle
291   * @param  Channel TIM Channel to be disabled
292   *          This parameter can be one of the following values:
293   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
294   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
295   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
296   * @retval HAL status
297   */
HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t Channel)298 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
299 {
300   HAL_StatusTypeDef status = HAL_OK;
301   uint32_t tmpccer;
302 
303   /* Check the parameters */
304   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
305 
306   switch (Channel)
307   {
308     case TIM_CHANNEL_1:
309     {
310       /* Disable the TIM Output Compare interrupt */
311       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
312       break;
313     }
314 
315     case TIM_CHANNEL_2:
316     {
317       /* Disable the TIM Output Compare interrupt */
318       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
319       break;
320     }
321 
322     case TIM_CHANNEL_3:
323     {
324       /* Disable the TIM Output Compare interrupt */
325       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
326       break;
327     }
328 
329     default:
330       status = HAL_ERROR;
331       break;
332   }
333 
334   if (status == HAL_OK)
335   {
336     /* Disable the Capture compare channel N */
337     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
338 
339     /* Disable the TIM Break interrupt (only if no more channel is active) */
340     tmpccer = htim->Instance->CCER;
341     if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET)
342     {
343       __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
344     }
345 
346     /* Disable the Main Output */
347     __HAL_TIM_MOE_DISABLE(htim);
348 
349     /* Disable the Peripheral */
350     __HAL_TIM_DISABLE(htim);
351 
352     /* Set the TIM complementary channel state */
353     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
354   }
355 
356   /* Return function status */
357   return status;
358 }
359 
360 #if defined(TIM_DMA_SUPPORT)
361 /**
362   * @brief  Starts the TIM Output Compare signal generation in DMA mode
363   *         on the complementary output.
364   * @param  htim TIM Output Compare handle
365   * @param  Channel TIM Channel to be enabled
366   *          This parameter can be one of the following values:
367   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
368   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
369   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
370   * @param  pData The source Buffer address.
371   * @param  Length The length of data to be transferred from memory to TIM peripheral
372   * @retval HAL status
373   */
HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef * htim,uint32_t Channel,const uint32_t * pData,uint16_t Length)374 HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
375                                           uint16_t Length)
376 {
377   HAL_StatusTypeDef status = HAL_OK;
378   uint32_t tmpsmcr;
379 
380   /* Check the parameters */
381   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
382 
383   /* Set the TIM complementary channel state */
384   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
385   {
386     return HAL_BUSY;
387   }
388   else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
389   {
390     if ((pData == NULL) || (Length == 0U))
391     {
392       return HAL_ERROR;
393     }
394     else
395     {
396       TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
397     }
398   }
399   else
400   {
401     return HAL_ERROR;
402   }
403 
404   switch (Channel)
405   {
406     case TIM_CHANNEL_1:
407     {
408       /* Set the DMA compare callbacks */
409       htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
410       htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
411 
412       /* Set the DMA error callback */
413       htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
414 
415       /* Enable the DMA channel */
416       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
417                            Length) != HAL_OK)
418       {
419         /* Return error status */
420         return HAL_ERROR;
421       }
422       /* Enable the TIM Output Compare DMA request */
423       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
424       break;
425     }
426 
427     case TIM_CHANNEL_2:
428     {
429       /* Set the DMA compare callbacks */
430       htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
431       htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
432 
433       /* Set the DMA error callback */
434       htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
435 
436       /* Enable the DMA channel */
437       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
438                            Length) != HAL_OK)
439       {
440         /* Return error status */
441         return HAL_ERROR;
442       }
443       /* Enable the TIM Output Compare DMA request */
444       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
445       break;
446     }
447 
448     case TIM_CHANNEL_3:
449     {
450       /* Set the DMA compare callbacks */
451       htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
452       htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
453 
454       /* Set the DMA error callback */
455       htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
456 
457       /* Enable the DMA channel */
458       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
459                            Length) != HAL_OK)
460       {
461         /* Return error status */
462         return HAL_ERROR;
463       }
464       /* Enable the TIM Output Compare DMA request */
465       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
466       break;
467     }
468 
469     default:
470       status = HAL_ERROR;
471       break;
472   }
473 
474   if (status == HAL_OK)
475   {
476     /* Enable the Capture compare channel N */
477     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
478 
479     /* Enable the Main Output */
480     __HAL_TIM_MOE_ENABLE(htim);
481 
482     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
483     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
484     {
485       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
486       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
487       {
488         __HAL_TIM_ENABLE(htim);
489       }
490     }
491     else
492     {
493       __HAL_TIM_ENABLE(htim);
494     }
495   }
496 
497   /* Return function status */
498   return status;
499 }
500 
501 /**
502   * @brief  Stops the TIM Output Compare signal generation in DMA mode
503   *         on the complementary output.
504   * @param  htim TIM Output Compare handle
505   * @param  Channel TIM Channel to be disabled
506   *          This parameter can be one of the following values:
507   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
508   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
509   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
510   * @retval HAL status
511   */
HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef * htim,uint32_t Channel)512 HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
513 {
514   HAL_StatusTypeDef status = HAL_OK;
515 
516   /* Check the parameters */
517   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
518 
519   switch (Channel)
520   {
521     case TIM_CHANNEL_1:
522     {
523       /* Disable the TIM Output Compare DMA request */
524       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
525       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
526       break;
527     }
528 
529     case TIM_CHANNEL_2:
530     {
531       /* Disable the TIM Output Compare DMA request */
532       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
533       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
534       break;
535     }
536 
537     case TIM_CHANNEL_3:
538     {
539       /* Disable the TIM Output Compare DMA request */
540       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
541       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
542       break;
543     }
544 
545     default:
546       status = HAL_ERROR;
547       break;
548   }
549 
550   if (status == HAL_OK)
551   {
552     /* Disable the Capture compare channel N */
553     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
554 
555     /* Disable the Main Output */
556     __HAL_TIM_MOE_DISABLE(htim);
557 
558     /* Disable the Peripheral */
559     __HAL_TIM_DISABLE(htim);
560 
561     /* Set the TIM complementary channel state */
562     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
563   }
564 
565   /* Return function status */
566   return status;
567 }
568 #endif /* TIM_DMA_SUPPORT */
569 
570 /**
571   * @}
572   */
573 
574 /** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions
575   * @brief    Timer Complementary PWM functions
576   *
577 @verbatim
578   ==============================================================================
579                  ##### Timer Complementary PWM functions #####
580   ==============================================================================
581   [..]
582     This section provides functions allowing to:
583     (+) Start the Complementary PWM.
584     (+) Stop the Complementary PWM.
585     (+) Start the Complementary PWM and enable interrupts.
586     (+) Stop the Complementary PWM and disable interrupts.
587     (+) Start the Complementary PWM and enable DMA transfers.
588     (+) Stop the Complementary PWM and disable DMA transfers.
589 @endverbatim
590   * @{
591   */
592 
593 /**
594   * @brief  Starts the PWM signal generation on the complementary output.
595   * @param  htim TIM handle
596   * @param  Channel TIM Channel to be enabled
597   *          This parameter can be one of the following values:
598   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
599   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
600   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
601   * @retval HAL status
602   */
HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef * htim,uint32_t Channel)603 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
604 {
605   uint32_t tmpsmcr;
606 
607   /* Check the parameters */
608   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
609 
610   /* Check the TIM complementary channel state */
611   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
612   {
613     return HAL_ERROR;
614   }
615 
616   /* Set the TIM complementary channel state */
617   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
618 
619   /* Enable the complementary PWM output  */
620   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
621 
622   /* Enable the Main Output */
623   __HAL_TIM_MOE_ENABLE(htim);
624 
625   /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
626   if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
627   {
628     tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
629     if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
630     {
631       __HAL_TIM_ENABLE(htim);
632     }
633   }
634   else
635   {
636     __HAL_TIM_ENABLE(htim);
637   }
638 
639   /* Return function status */
640   return HAL_OK;
641 }
642 
643 /**
644   * @brief  Stops the PWM signal generation on the complementary output.
645   * @param  htim TIM handle
646   * @param  Channel TIM Channel to be disabled
647   *          This parameter can be one of the following values:
648   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
649   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
650   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
651   * @retval HAL status
652   */
HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef * htim,uint32_t Channel)653 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
654 {
655   /* Check the parameters */
656   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
657 
658   /* Disable the complementary PWM output  */
659   TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
660 
661   /* Disable the Main Output */
662   __HAL_TIM_MOE_DISABLE(htim);
663 
664   /* Disable the Peripheral */
665   __HAL_TIM_DISABLE(htim);
666 
667   /* Set the TIM complementary channel state */
668   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
669 
670   /* Return function status */
671   return HAL_OK;
672 }
673 
674 /**
675   * @brief  Starts the PWM signal generation in interrupt mode on the
676   *         complementary output.
677   * @param  htim TIM handle
678   * @param  Channel TIM Channel to be disabled
679   *          This parameter can be one of the following values:
680   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
681   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
682   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
683   * @retval HAL status
684   */
HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef * htim,uint32_t Channel)685 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
686 {
687   HAL_StatusTypeDef status = HAL_OK;
688   uint32_t tmpsmcr;
689 
690   /* Check the parameters */
691   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
692 
693   /* Check the TIM complementary channel state */
694   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
695   {
696     return HAL_ERROR;
697   }
698 
699   /* Set the TIM complementary channel state */
700   TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
701 
702   switch (Channel)
703   {
704     case TIM_CHANNEL_1:
705     {
706       /* Enable the TIM Capture/Compare 1 interrupt */
707       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
708       break;
709     }
710 
711     case TIM_CHANNEL_2:
712     {
713       /* Enable the TIM Capture/Compare 2 interrupt */
714       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
715       break;
716     }
717 
718     case TIM_CHANNEL_3:
719     {
720       /* Enable the TIM Capture/Compare 3 interrupt */
721       __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
722       break;
723     }
724 
725     default:
726       status = HAL_ERROR;
727       break;
728   }
729 
730   if (status == HAL_OK)
731   {
732     /* Enable the TIM Break interrupt */
733     __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
734 
735     /* Enable the complementary PWM output  */
736     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
737 
738     /* Enable the Main Output */
739     __HAL_TIM_MOE_ENABLE(htim);
740 
741     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
742     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
743     {
744       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
745       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
746       {
747         __HAL_TIM_ENABLE(htim);
748       }
749     }
750     else
751     {
752       __HAL_TIM_ENABLE(htim);
753     }
754   }
755 
756   /* Return function status */
757   return status;
758 }
759 
760 /**
761   * @brief  Stops the PWM signal generation in interrupt mode on the
762   *         complementary output.
763   * @param  htim TIM handle
764   * @param  Channel TIM Channel to be disabled
765   *          This parameter can be one of the following values:
766   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
767   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
768   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
769   * @retval HAL status
770   */
HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t Channel)771 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
772 {
773   HAL_StatusTypeDef status = HAL_OK;
774   uint32_t tmpccer;
775 
776   /* Check the parameters */
777   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
778 
779   switch (Channel)
780   {
781     case TIM_CHANNEL_1:
782     {
783       /* Disable the TIM Capture/Compare 1 interrupt */
784       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
785       break;
786     }
787 
788     case TIM_CHANNEL_2:
789     {
790       /* Disable the TIM Capture/Compare 2 interrupt */
791       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
792       break;
793     }
794 
795     case TIM_CHANNEL_3:
796     {
797       /* Disable the TIM Capture/Compare 3 interrupt */
798       __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
799       break;
800     }
801 
802     default:
803       status = HAL_ERROR;
804       break;
805   }
806 
807   if (status == HAL_OK)
808   {
809     /* Disable the complementary PWM output  */
810     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
811 
812     /* Disable the TIM Break interrupt (only if no more channel is active) */
813     tmpccer = htim->Instance->CCER;
814     if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET)
815     {
816       __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
817     }
818 
819     /* Disable the Main Output */
820     __HAL_TIM_MOE_DISABLE(htim);
821 
822     /* Disable the Peripheral */
823     __HAL_TIM_DISABLE(htim);
824 
825     /* Set the TIM complementary channel state */
826     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
827   }
828 
829   /* Return function status */
830   return status;
831 }
832 
833 #if defined(TIM_DMA_SUPPORT)
834 /**
835   * @brief  Starts the TIM PWM signal generation in DMA mode on the
836   *         complementary output
837   * @param  htim TIM handle
838   * @param  Channel TIM Channel to be enabled
839   *          This parameter can be one of the following values:
840   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
841   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
842   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
843   * @param  pData The source Buffer address.
844   * @param  Length The length of data to be transferred from memory to TIM peripheral
845   * @retval HAL status
846   */
HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef * htim,uint32_t Channel,const uint32_t * pData,uint16_t Length)847 HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
848                                            uint16_t Length)
849 {
850   HAL_StatusTypeDef status = HAL_OK;
851   uint32_t tmpsmcr;
852 
853   /* Check the parameters */
854   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
855 
856   /* Set the TIM complementary channel state */
857   if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
858   {
859     return HAL_BUSY;
860   }
861   else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
862   {
863     if ((pData == NULL) || (Length == 0U))
864     {
865       return HAL_ERROR;
866     }
867     else
868     {
869       TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
870     }
871   }
872   else
873   {
874     return HAL_ERROR;
875   }
876 
877   switch (Channel)
878   {
879     case TIM_CHANNEL_1:
880     {
881       /* Set the DMA compare callbacks */
882       htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
883       htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
884 
885       /* Set the DMA error callback */
886       htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
887 
888       /* Enable the DMA channel */
889       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
890                            Length) != HAL_OK)
891       {
892         /* Return error status */
893         return HAL_ERROR;
894       }
895       /* Enable the TIM Capture/Compare 1 DMA request */
896       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
897       break;
898     }
899 
900     case TIM_CHANNEL_2:
901     {
902       /* Set the DMA compare callbacks */
903       htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
904       htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
905 
906       /* Set the DMA error callback */
907       htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
908 
909       /* Enable the DMA channel */
910       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
911                            Length) != HAL_OK)
912       {
913         /* Return error status */
914         return HAL_ERROR;
915       }
916       /* Enable the TIM Capture/Compare 2 DMA request */
917       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
918       break;
919     }
920 
921     case TIM_CHANNEL_3:
922     {
923       /* Set the DMA compare callbacks */
924       htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
925       htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
926 
927       /* Set the DMA error callback */
928       htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
929 
930       /* Enable the DMA channel */
931       if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
932                            Length) != HAL_OK)
933       {
934         /* Return error status */
935         return HAL_ERROR;
936       }
937       /* Enable the TIM Capture/Compare 3 DMA request */
938       __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
939       break;
940     }
941 
942     default:
943       status = HAL_ERROR;
944       break;
945   }
946 
947   if (status == HAL_OK)
948   {
949     /* Enable the complementary PWM output  */
950     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
951 
952     /* Enable the Main Output */
953     __HAL_TIM_MOE_ENABLE(htim);
954 
955     /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
956     if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
957     {
958       tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
959       if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
960       {
961         __HAL_TIM_ENABLE(htim);
962       }
963     }
964     else
965     {
966       __HAL_TIM_ENABLE(htim);
967     }
968   }
969 
970   /* Return function status */
971   return status;
972 }
973 
974 /**
975   * @brief  Stops the TIM PWM signal generation in DMA mode on the complementary
976   *         output
977   * @param  htim TIM handle
978   * @param  Channel TIM Channel to be disabled
979   *          This parameter can be one of the following values:
980   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
981   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
982   *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
983   * @retval HAL status
984   */
HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef * htim,uint32_t Channel)985 HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
986 {
987   HAL_StatusTypeDef status = HAL_OK;
988 
989   /* Check the parameters */
990   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
991 
992   switch (Channel)
993   {
994     case TIM_CHANNEL_1:
995     {
996       /* Disable the TIM Capture/Compare 1 DMA request */
997       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
998       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
999       break;
1000     }
1001 
1002     case TIM_CHANNEL_2:
1003     {
1004       /* Disable the TIM Capture/Compare 2 DMA request */
1005       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
1006       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
1007       break;
1008     }
1009 
1010     case TIM_CHANNEL_3:
1011     {
1012       /* Disable the TIM Capture/Compare 3 DMA request */
1013       __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
1014       (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
1015       break;
1016     }
1017 
1018     default:
1019       status = HAL_ERROR;
1020       break;
1021   }
1022 
1023   if (status == HAL_OK)
1024   {
1025     /* Disable the complementary PWM output */
1026     TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
1027 
1028     /* Disable the Main Output */
1029     __HAL_TIM_MOE_DISABLE(htim);
1030 
1031     /* Disable the Peripheral */
1032     __HAL_TIM_DISABLE(htim);
1033 
1034     /* Set the TIM complementary channel state */
1035     TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
1036   }
1037 
1038   /* Return function status */
1039   return status;
1040 }
1041 #endif /* TIM_DMA_SUPPORT */
1042 
1043 /**
1044   * @}
1045   */
1046 
1047 /** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
1048   * @brief    Timer Complementary One Pulse functions
1049   *
1050 @verbatim
1051   ==============================================================================
1052                 ##### Timer Complementary One Pulse functions #####
1053   ==============================================================================
1054   [..]
1055     This section provides functions allowing to:
1056     (+) Start the Complementary One Pulse generation.
1057     (+) Stop the Complementary One Pulse.
1058     (+) Start the Complementary One Pulse and enable interrupts.
1059     (+) Stop the Complementary One Pulse and disable interrupts.
1060 
1061 @endverbatim
1062   * @{
1063   */
1064 
1065 /**
1066   * @brief  Starts the TIM One Pulse signal generation on the complementary
1067   *         output.
1068   * @note OutputChannel must match the pulse output channel chosen when calling
1069   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1070   * @param  htim TIM One Pulse handle
1071   * @param  OutputChannel pulse output channel to enable
1072   *          This parameter can be one of the following values:
1073   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1074   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1075   * @retval HAL status
1076   */
HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1077 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1078 {
1079   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1080   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1081   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1082   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1083   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1084 
1085   /* Check the parameters */
1086   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1087 
1088   /* Check the TIM channels state */
1089   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1090       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1091       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1092       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1093   {
1094     return HAL_ERROR;
1095   }
1096 
1097   /* Set the TIM channels state */
1098   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1099   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1100   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1101   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1102 
1103   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1104   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1105   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1106 
1107   /* Enable the Main Output */
1108   __HAL_TIM_MOE_ENABLE(htim);
1109 
1110   /* Return function status */
1111   return HAL_OK;
1112 }
1113 
1114 /**
1115   * @brief  Stops the TIM One Pulse signal generation on the complementary
1116   *         output.
1117   * @note OutputChannel must match the pulse output channel chosen when calling
1118   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1119   * @param  htim TIM One Pulse handle
1120   * @param  OutputChannel pulse output channel to disable
1121   *          This parameter can be one of the following values:
1122   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1123   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1124   * @retval HAL status
1125   */
HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1126 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1127 {
1128   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1129 
1130   /* Check the parameters */
1131   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1132 
1133   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1134   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1135   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1136 
1137   /* Disable the Main Output */
1138   __HAL_TIM_MOE_DISABLE(htim);
1139 
1140   /* Disable the Peripheral */
1141   __HAL_TIM_DISABLE(htim);
1142 
1143   /* Set the TIM  channels state */
1144   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1145   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1146   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1147   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1148 
1149   /* Return function status */
1150   return HAL_OK;
1151 }
1152 
1153 /**
1154   * @brief  Starts the TIM One Pulse signal generation in interrupt mode on the
1155   *         complementary channel.
1156   * @note OutputChannel must match the pulse output channel chosen when calling
1157   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1158   * @param  htim TIM One Pulse handle
1159   * @param  OutputChannel pulse output channel to enable
1160   *          This parameter can be one of the following values:
1161   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1162   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1163   * @retval HAL status
1164   */
HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1165 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1166 {
1167   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1168   HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
1169   HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
1170   HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
1171   HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
1172 
1173   /* Check the parameters */
1174   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1175 
1176   /* Check the TIM channels state */
1177   if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1178       || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
1179       || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
1180       || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
1181   {
1182     return HAL_ERROR;
1183   }
1184 
1185   /* Set the TIM channels state */
1186   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1187   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1188   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
1189   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
1190 
1191   /* Enable the TIM Capture/Compare 1 interrupt */
1192   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
1193 
1194   /* Enable the TIM Capture/Compare 2 interrupt */
1195   __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
1196 
1197   /* Enable the complementary One Pulse output channel and the Input Capture channel */
1198   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
1199   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
1200 
1201   /* Enable the Main Output */
1202   __HAL_TIM_MOE_ENABLE(htim);
1203 
1204   /* Return function status */
1205   return HAL_OK;
1206 }
1207 
1208 /**
1209   * @brief  Stops the TIM One Pulse signal generation in interrupt mode on the
1210   *         complementary channel.
1211   * @note OutputChannel must match the pulse output channel chosen when calling
1212   *       @ref HAL_TIM_OnePulse_ConfigChannel().
1213   * @param  htim TIM One Pulse handle
1214   * @param  OutputChannel pulse output channel to disable
1215   *          This parameter can be one of the following values:
1216   *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
1217   *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
1218   * @retval HAL status
1219   */
HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef * htim,uint32_t OutputChannel)1220 HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
1221 {
1222   uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
1223 
1224   /* Check the parameters */
1225   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
1226 
1227   /* Disable the TIM Capture/Compare 1 interrupt */
1228   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
1229 
1230   /* Disable the TIM Capture/Compare 2 interrupt */
1231   __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
1232 
1233   /* Disable the complementary One Pulse output channel and the Input Capture channel */
1234   TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
1235   TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
1236 
1237   /* Disable the Main Output */
1238   __HAL_TIM_MOE_DISABLE(htim);
1239 
1240   /* Disable the Peripheral */
1241   __HAL_TIM_DISABLE(htim);
1242 
1243   /* Set the TIM  channels state */
1244   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1245   TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1246   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1247   TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1248 
1249   /* Return function status */
1250   return HAL_OK;
1251 }
1252 
1253 /**
1254   * @}
1255   */
1256 
1257 /** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
1258   * @brief    Peripheral Control functions
1259   *
1260 @verbatim
1261   ==============================================================================
1262                     ##### Peripheral Control functions #####
1263   ==============================================================================
1264   [..]
1265     This section provides functions allowing to:
1266       (+) Configure the commutation event in case of use of the Hall sensor interface.
1267       (+) Configure Output channels for OC and PWM mode.
1268 
1269       (+) Configure Complementary channels, break features and dead time.
1270       (+) Configure Master synchronization.
1271       (+) Configure timer remapping capabilities.
1272       (+) Enable or disable channel grouping.
1273 
1274 @endverbatim
1275   * @{
1276   */
1277 
1278 /**
1279   * @brief  Configure the TIM commutation event sequence.
1280   * @param  htim TIM handle
1281   * @param  InputTrigger Unused parameter (kept to avoid compatibility break).
1282   * @param  CommutationSource the Commutation Event source
1283   *          This parameter can be one of the following values:
1284   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1285   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1286   * @retval HAL status
1287   */
HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1288 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1289                                               uint32_t  CommutationSource)
1290 {
1291   UNUSED(InputTrigger);
1292 
1293   /* Check the parameters */
1294   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1295 
1296   __HAL_LOCK(htim);
1297 
1298   /* Select the Capture Compare preload feature */
1299   htim->Instance->CR2 |= TIM_CR2_CCPC;
1300   /* Select the Commutation event source */
1301   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1302   htim->Instance->CR2 |= CommutationSource;
1303 
1304   /* Disable Commutation Interrupt */
1305   __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
1306 
1307   __HAL_UNLOCK(htim);
1308 
1309   return HAL_OK;
1310 }
1311 
1312 /**
1313   * @brief  Configure the TIM commutation event sequence with interrupt.
1314   * @param  htim TIM handle
1315   * @param  InputTrigger Unused parameter (kept to avoid compatibility break).
1316   * @param  CommutationSource the Commutation Event source
1317   *          This parameter can be one of the following values:
1318   *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
1319   *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
1320   * @retval HAL status
1321   */
HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef * htim,uint32_t InputTrigger,uint32_t CommutationSource)1322 HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
1323                                                  uint32_t  CommutationSource)
1324 {
1325   UNUSED(InputTrigger);
1326 
1327   /* Check the parameters */
1328   assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
1329 
1330   __HAL_LOCK(htim);
1331 
1332   /* Select the Capture Compare preload feature */
1333   htim->Instance->CR2 |= TIM_CR2_CCPC;
1334   /* Select the Commutation event source */
1335   htim->Instance->CR2 &= ~TIM_CR2_CCUS;
1336   htim->Instance->CR2 |= CommutationSource;
1337 
1338   /* Enable the Commutation Interrupt */
1339   __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
1340 
1341   __HAL_UNLOCK(htim);
1342 
1343   return HAL_OK;
1344 }
1345 
1346 
1347 /**
1348   * @brief  Configures the Break feature, dead time, Lock level, OSSI/OSSR State
1349   *         and the AOE(automatic output enable).
1350   * @param  htim TIM handle
1351   * @param  sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
1352   *         contains the BDTR Register configuration  information for the TIM peripheral.
1353   * @note   Interrupts can be generated when an active level is detected on the
1354   *         break input, the break 2 input or the system break input. Break
1355   *         interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
1356   * @retval HAL status
1357   */
HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef * htim,const TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig)1358 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
1359                                                 const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
1360 {
1361   /* Keep this variable initialized to 0 as it is used to configure BDTR register */
1362   uint32_t tmpbdtr = 0U;
1363 
1364   /* Check the parameters */
1365   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
1366   assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
1367   assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
1368   assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
1369   assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
1370   assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
1371   assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
1372 #if defined(TIM_BDTR_BKF)
1373   assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
1374 #endif /* TIM_BDTR_BKF */
1375   assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
1376 #if defined(TIM_BDTR_BKBID)
1377   assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode));
1378 #endif /* TIM_BDTR_BKBID */
1379 
1380   /* Check input state */
1381   __HAL_LOCK(htim);
1382 
1383   /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
1384      the OSSI State, the dead time value and the Automatic Output Enable Bit */
1385 
1386   /* Set the BDTR bits */
1387   MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
1388   MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
1389   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
1390   MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
1391   MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
1392   MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
1393   MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
1394 #if defined(TIM_BDTR_BKF)
1395   MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));
1396 #endif /* TIM_BDTR_BKF */
1397 #if defined(TIM_BDTR_BKBID)
1398   MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode);
1399 #endif /* TIM_BDTR_BKBID */
1400 
1401 #if defined(TIM_BDTR_BK2E)
1402   if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
1403   {
1404     /* Check the parameters */
1405     assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
1406     assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
1407     assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));
1408 #if defined(TIM_BDTR_BKBID)
1409     assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode));
1410 #endif /* TIM_BDTR_BKBID */
1411 
1412     /* Set the BREAK2 input related BDTR bits */
1413     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos));
1414     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
1415     MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
1416   }
1417 #endif /* TIM_BDTR_BK2E */
1418 
1419   /* Set TIMx_BDTR */
1420   htim->Instance->BDTR = tmpbdtr;
1421 
1422   __HAL_UNLOCK(htim);
1423 
1424   return HAL_OK;
1425 }
1426 
1427 /**
1428   * @brief  Configures the break input source.
1429   * @param  htim TIM handle.
1430   * @param  BreakInput Break input to configure
1431   *          This parameter can be one of the following values:
1432   *            @arg TIM_BREAKINPUT_BRK: Timer break input
1433   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
1434   * @param  sBreakInputConfig Break input source configuration
1435   * @retval HAL status
1436   */
HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput,const TIMEx_BreakInputConfigTypeDef * sBreakInputConfig)1437 HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim,
1438                                              uint32_t BreakInput,
1439                                              const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
1440 {
1441   HAL_StatusTypeDef status = HAL_OK;
1442   uint32_t tmporx;
1443   uint32_t bkin_enable_mask;
1444   uint32_t bkin_polarity_mask;
1445   uint32_t bkin_enable_bitpos;
1446   uint32_t bkin_polarity_bitpos;
1447 
1448   /* Check the parameters */
1449   assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
1450   assert_param(IS_TIM_BREAKINPUT(BreakInput));
1451   assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source));
1452   assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable));
1453   assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
1454 
1455   /* Check input state */
1456   __HAL_LOCK(htim);
1457 
1458   switch (sBreakInputConfig->Source)
1459   {
1460     case TIM_BREAKINPUTSOURCE_BKIN:
1461     {
1462       bkin_enable_mask = TIM_AF1_BKINE;
1463       bkin_enable_bitpos = TIM_AF1_BKINE_Pos;
1464       bkin_polarity_mask = TIM_AF1_BKINP;
1465       bkin_polarity_bitpos = TIM_AF1_BKINP_Pos;
1466       break;
1467     }
1468 
1469     default:
1470     {
1471       bkin_enable_mask = 0U;
1472       bkin_polarity_mask = 0U;
1473       bkin_enable_bitpos = 0U;
1474       bkin_polarity_bitpos = 0U;
1475       break;
1476     }
1477   }
1478 
1479   switch (BreakInput)
1480   {
1481     case TIM_BREAKINPUT_BRK:
1482     {
1483       /* Get the TIMx_AF1 register value */
1484       tmporx = htim->Instance->AF1;
1485 
1486       /* Enable the break input */
1487       tmporx &= ~bkin_enable_mask;
1488       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
1489 
1490       /* Set the break input polarity */
1491       tmporx &= ~bkin_polarity_mask;
1492       tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
1493 
1494       /* Set TIMx_AF1 */
1495       htim->Instance->AF1 = tmporx;
1496       break;
1497     }
1498 #if defined(TIM_BDTR_BK2E)
1499     case TIM_BREAKINPUT_BRK2:
1500     {
1501       /* Get the TIMx_AF2 register value */
1502       tmporx = htim->Instance->AF2;
1503 
1504       /* Enable the break input */
1505       tmporx &= ~bkin_enable_mask;
1506       tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
1507 
1508       /* Set the break input polarity */
1509       tmporx &= ~bkin_polarity_mask;
1510       tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
1511 
1512       /* Set TIMx_AF2 */
1513       htim->Instance->AF2 = tmporx;
1514       break;
1515     }
1516 #endif /* TIM_BDTR_BK2E */
1517     default:
1518       status = HAL_ERROR;
1519       break;
1520   }
1521 
1522   __HAL_UNLOCK(htim);
1523 
1524   return status;
1525 }
1526 
1527 #if defined(TIM17)
1528 /**
1529   * @brief  Configures the TIMx Remapping input capabilities.
1530   * @param  htim TIM handle.
1531   * @param  Remap specifies the TIM remapping source.
1532   *          This parameter can be one of the following values:
1533   *           @arg TIM_TIM17_TI1_GPIO
1534   *           @arg TIM_TIM17_TI1_LCO
1535   *           @arg TIM_TIM17_TI1_MCO
1536   *
1537   * @retval HAL status
1538   */
HAL_TIMEx_RemapConfig(TIM_HandleTypeDef * htim,uint32_t Remap)1539 HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
1540 {
1541 
1542   /* Check parameters */
1543   assert_param(IS_TIM_REMAP(htim->Instance, Remap));
1544 
1545   __HAL_LOCK(htim);
1546 
1547   /* Set the Timer remapping configuration */
1548   WRITE_REG(htim->Instance->OR1, Remap);
1549 
1550   __HAL_UNLOCK(htim);
1551 
1552   return HAL_OK;
1553 }
1554 #endif /* TIM17 */
1555 
1556 #if defined(TIM_CCR5_CCR5)
1557 /**
1558   * @brief  Group channel 5 and channel 1, 2 or 3
1559   * @param  htim TIM handle.
1560   * @param  Channels specifies the reference signal(s) the OC5REF is combined with.
1561   *         This parameter can be any combination of the following values:
1562   *         TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC
1563   *         TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF
1564   *         TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF
1565   *         TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF
1566   * @retval HAL status
1567   */
HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef * htim,uint32_t Channels)1568 HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels)
1569 {
1570   /* Check parameters */
1571   assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance));
1572   assert_param(IS_TIM_GROUPCH5(Channels));
1573 
1574   /* Process Locked */
1575   __HAL_LOCK(htim);
1576 
1577   htim->State = HAL_TIM_STATE_BUSY;
1578 
1579   /* Clear GC5Cx bit fields */
1580   htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1);
1581 
1582   /* Set GC5Cx bit fields */
1583   htim->Instance->CCR5 |= Channels;
1584 
1585   /* Change the htim state */
1586   htim->State = HAL_TIM_STATE_READY;
1587 
1588   __HAL_UNLOCK(htim);
1589 
1590   return HAL_OK;
1591 }
1592 #endif /* TIM_CCR5_CCR5 */
1593 #if defined(TIM_BDTR_BKBID)
1594 
1595 /**
1596   * @brief  Disarm the designated break input (when it operates in bidirectional mode).
1597   * @param  htim TIM handle.
1598   * @param  BreakInput Break input to disarm
1599   *          This parameter can be one of the following values:
1600   *            @arg TIM_BREAKINPUT_BRK: Timer break input
1601   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
1602   * @note  The break input can be disarmed only when it is configured in
1603   *        bidirectional mode and when when MOE is reset.
1604   * @note  Purpose is to be able to have the input voltage back to high-state,
1605   *        whatever the time constant on the output .
1606   * @retval HAL status
1607   */
HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef * htim,uint32_t BreakInput)1608 HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
1609 {
1610   HAL_StatusTypeDef status = HAL_OK;
1611   uint32_t tmpbdtr;
1612 
1613   /* Check the parameters */
1614   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
1615   assert_param(IS_TIM_BREAKINPUT(BreakInput));
1616 
1617   switch (BreakInput)
1618   {
1619     case TIM_BREAKINPUT_BRK:
1620     {
1621       /* Check initial conditions */
1622       tmpbdtr = READ_REG(htim->Instance->BDTR);
1623       if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) &&
1624           (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
1625       {
1626         /* Break input BRK is disarmed */
1627         SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM);
1628       }
1629       break;
1630     }
1631     default:
1632       status = HAL_ERROR;
1633       break;
1634   }
1635 
1636   return status;
1637 }
1638 
1639 /**
1640   * @brief  Arm the designated break input (when it operates in bidirectional mode).
1641   * @param  htim TIM handle.
1642   * @param  BreakInput Break input to arm
1643   *          This parameter can be one of the following values:
1644   *            @arg TIM_BREAKINPUT_BRK: Timer break input
1645   *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
1646   * @note  Arming is possible at anytime, even if fault is present.
1647   * @note  Break input is automatically armed as soon as MOE bit is set.
1648   * @retval HAL status
1649   */
HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef * htim,uint32_t BreakInput)1650 HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef *htim, uint32_t BreakInput)
1651 {
1652   HAL_StatusTypeDef status = HAL_OK;
1653   uint32_t tickstart;
1654 
1655   /* Check the parameters */
1656   assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
1657   assert_param(IS_TIM_BREAKINPUT(BreakInput));
1658 
1659   switch (BreakInput)
1660   {
1661     case TIM_BREAKINPUT_BRK:
1662     {
1663       /* Check initial conditions */
1664       if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID)
1665       {
1666         /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
1667         /* Init tickstart for timeout management */
1668         tickstart = HAL_GetTick();
1669         while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
1670         {
1671           if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
1672           {
1673             /* New check to avoid false timeout detection in case of preemption */
1674             if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
1675             {
1676               return HAL_TIMEOUT;
1677             }
1678           }
1679         }
1680       }
1681       break;
1682     }
1683 
1684     default:
1685       status = HAL_ERROR;
1686       break;
1687   }
1688 
1689   return status;
1690 }
1691 #endif /* TIM_BDTR_BKBID */
1692 
1693 /**
1694   * @}
1695   */
1696 
1697 /** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
1698   * @brief    Extended Callbacks functions
1699   *
1700 @verbatim
1701   ==============================================================================
1702                     ##### Extended Callbacks functions #####
1703   ==============================================================================
1704   [..]
1705     This section provides Extended TIM callback functions:
1706     (+) Timer Commutation callback
1707     (+) Timer Break callback
1708 
1709 @endverbatim
1710   * @{
1711   */
1712 
1713 /**
1714   * @brief  Commutation callback in non-blocking mode
1715   * @param  htim TIM handle
1716   * @retval None
1717   */
HAL_TIMEx_CommutCallback(TIM_HandleTypeDef * htim)1718 __weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
1719 {
1720   /* Prevent unused argument(s) compilation warning */
1721   UNUSED(htim);
1722 
1723   /* NOTE : This function should not be modified, when the callback is needed,
1724             the HAL_TIMEx_CommutCallback could be implemented in the user file
1725    */
1726 }
1727 
1728 /**
1729   * @brief  Break detection callback in non-blocking mode
1730   * @param  htim TIM handle
1731   * @retval None
1732   */
HAL_TIMEx_BreakCallback(TIM_HandleTypeDef * htim)1733 __weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
1734 {
1735   /* Prevent unused argument(s) compilation warning */
1736   UNUSED(htim);
1737 
1738   /* NOTE : This function should not be modified, when the callback is needed,
1739             the HAL_TIMEx_BreakCallback could be implemented in the user file
1740    */
1741 }
1742 
1743 #if defined(TIM_BDTR_BK2E)
1744 /**
1745   * @brief  Break2 detection callback in non blocking mode
1746   * @param  htim: TIM handle
1747   * @retval None
1748   */
HAL_TIMEx_Break2Callback(TIM_HandleTypeDef * htim)1749 __weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
1750 {
1751   /* Prevent unused argument(s) compilation warning */
1752   UNUSED(htim);
1753 
1754   /* NOTE : This function Should not be modified, when the callback is needed,
1755             the HAL_TIMEx_Break2Callback could be implemented in the user file
1756    */
1757 }
1758 #endif /* TIM_BDTR_BK2E */
1759 /**
1760   * @}
1761   */
1762 
1763 /** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
1764   * @brief    Extended Peripheral State functions
1765   *
1766 @verbatim
1767   ==============================================================================
1768                 ##### Extended Peripheral State functions #####
1769   ==============================================================================
1770   [..]
1771     This subsection permits to get in run-time the status of the peripheral
1772     and the data flow.
1773 
1774 @endverbatim
1775   * @{
1776   */
1777 
1778 /**
1779   * @brief  Return actual state of the TIM complementary channel.
1780   * @param  htim TIM handle
1781   * @param  ChannelN TIM Complementary channel
1782   *          This parameter can be one of the following values:
1783   *            @arg TIM_CHANNEL_1: TIM Channel 1
1784   *            @arg TIM_CHANNEL_2: TIM Channel 2
1785   *            @arg TIM_CHANNEL_3: TIM Channel 3
1786   * @retval TIM Complementary channel state
1787   */
HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef * htim,uint32_t ChannelN)1788 HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim,  uint32_t ChannelN)
1789 {
1790   HAL_TIM_ChannelStateTypeDef channel_state;
1791 
1792   /* Check the parameters */
1793   assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN));
1794 
1795   channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN);
1796 
1797   return channel_state;
1798 }
1799 /**
1800   * @}
1801   */
1802 
1803 /**
1804   * @}
1805   */
1806 
1807 /* Private functions ---------------------------------------------------------*/
1808 /** @defgroup TIMEx_Private_Functions TIM Extended Private Functions
1809   * @{
1810   */
1811 
1812 #if defined(TIM_DMA_SUPPORT)
1813 /**
1814   * @brief  TIM DMA Delay Pulse complete callback (complementary channel).
1815   * @param  hdma pointer to DMA handle.
1816   * @retval None
1817   */
TIM_DMADelayPulseNCplt(DMA_HandleTypeDef * hdma)1818 static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma)
1819 {
1820   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1821 
1822   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
1823   {
1824     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
1825 
1826     if (hdma->Init.Mode == DMA_NORMAL)
1827     {
1828       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1829     }
1830   }
1831   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
1832   {
1833     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
1834 
1835     if (hdma->Init.Mode == DMA_NORMAL)
1836     {
1837       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1838     }
1839   }
1840   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
1841   {
1842     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
1843 
1844     if (hdma->Init.Mode == DMA_NORMAL)
1845     {
1846       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
1847     }
1848   }
1849   else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
1850   {
1851     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
1852 
1853     if (hdma->Init.Mode == DMA_NORMAL)
1854     {
1855       TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
1856     }
1857   }
1858   else
1859   {
1860     /* nothing to do */
1861   }
1862 
1863 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
1864   htim->PWM_PulseFinishedCallback(htim);
1865 #else
1866   HAL_TIM_PWM_PulseFinishedCallback(htim);
1867 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
1868 
1869   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
1870 }
1871 
1872 /**
1873   * @brief  TIM DMA error callback (complementary channel)
1874   * @param  hdma pointer to DMA handle.
1875   * @retval None
1876   */
TIM_DMAErrorCCxN(DMA_HandleTypeDef * hdma)1877 static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma)
1878 {
1879   TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1880 
1881   if (hdma == htim->hdma[TIM_DMA_ID_CC1])
1882   {
1883     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
1884     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
1885   }
1886   else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
1887   {
1888     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
1889     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
1890   }
1891   else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
1892   {
1893     htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
1894     TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
1895   }
1896   else
1897   {
1898     /* nothing to do */
1899   }
1900 
1901 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
1902   htim->ErrorCallback(htim);
1903 #else
1904   HAL_TIM_ErrorCallback(htim);
1905 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
1906 
1907   htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
1908 }
1909 #endif /* TIM_DMA_SUPPORT */
1910 
1911 /**
1912   * @brief  Enables or disables the TIM Capture Compare Channel xN.
1913   * @param  TIMx to select the TIM peripheral
1914   * @param  Channel specifies the TIM Channel
1915   *          This parameter can be one of the following values:
1916   *            @arg TIM_CHANNEL_1: TIM Channel 1
1917   *            @arg TIM_CHANNEL_2: TIM Channel 2
1918   *            @arg TIM_CHANNEL_3: TIM Channel 3
1919   * @param  ChannelNState specifies the TIM Channel CCxNE bit new state.
1920   *          This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
1921   * @retval None
1922   */
TIM_CCxNChannelCmd(TIM_TypeDef * TIMx,uint32_t Channel,uint32_t ChannelNState)1923 static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
1924 {
1925   uint32_t tmp;
1926 
1927   tmp = TIM_CCER_CC1NE << (Channel & 0xFU); /* 0xFU = 15 bits max shift */
1928 
1929   /* Reset the CCxNE Bit */
1930   TIMx->CCER &=  ~tmp;
1931 
1932   /* Set or reset the CCxNE Bit */
1933   TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0xFU)); /* 0xFU = 15 bits max shift */
1934 }
1935 /**
1936   * @}
1937   */
1938 
1939 #endif /* HAL_TIM_MODULE_ENABLED */
1940 /**
1941   * @}
1942   */
1943 
1944 /**
1945   * @}
1946   */
1947