/** ****************************************************************************** * @file stm32wb0x_hal_tim_ex.c * @author MCD Application Team * @brief TIM HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Timer Extended peripheral: * + Time Complementary signal break and dead time configuration * + Time Master and Slave synchronization configuration * + Time Output Compare/PWM Channel Configuration (for channels 5 and 6) * + Time OCRef clear configuration * + Timer remapping capabilities configuration ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** @verbatim ============================================================================== ##### TIMER Extended features ##### ============================================================================== [..] The Timer Extended features include: (#) Complementary outputs with programmable dead-time for : (++) Output Compare (++) PWM generation (Edge and Center-aligned Mode) (++) One-pulse mode output (#) Synchronization circuit to control the timer with external signals and to interconnect several timers together. (#) Break input to put the timer output signals in reset state or in a known state. ##### How to use this driver ##### ============================================================================== [..] (#) Initialize the TIM low level resources by implementing the following functions depending on the selected feature: (#) Activate the TIM peripheral using one of the start functions: (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OCN_Start_IT() (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT() (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT() @endverbatim ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32wb0x_hal.h" /** @addtogroup STM32WB0x_HAL_Driver * @{ */ /** @defgroup TIMEx TIMEx * @brief TIM Extended HAL module driver * @{ */ #ifdef HAL_TIM_MODULE_ENABLED /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #if defined(TIM_BDTR_BKBID) /* Private constants ---------------------------------------------------------*/ /** @defgroup TIMEx_Private_Constants TIM Extended Private Constants * @{ */ /* Timeout for break input rearm */ #define TIM_BREAKINPUT_REARM_TIMEOUT 5UL /* 5 milliseconds */ /** * @} */ /* End of private constants --------------------------------------------------*/ #endif /* TIM_BDTR_BKBID */ /* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ #if defined(TIM_DMA_SUPPORT) static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma); static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma); #endif /* TIM_DMA_SUPPORT */ static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState); /* Exported functions --------------------------------------------------------*/ /** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions * @{ */ /** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions * @brief Timer Complementary Output Compare functions * @verbatim ============================================================================== ##### Timer Complementary Output Compare functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Start the Complementary Output Compare/PWM. (+) Stop the Complementary Output Compare/PWM. (+) Start the Complementary Output Compare/PWM and enable interrupts. (+) Stop the Complementary Output Compare/PWM and disable interrupts. (+) Start the Complementary Output Compare/PWM and enable DMA transfers. (+) Stop the Complementary Output Compare/PWM and disable DMA transfers. @endverbatim * @{ */ /** * @brief Starts the TIM Output Compare signal generation on the complementary * output. * @param htim TIM Output Compare handle * @param Channel TIM Channel to be enabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) { uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Check the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) { return HAL_ERROR; } /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); /* Enable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } /* Return function status */ return HAL_OK; } /** * @brief Stops the TIM Output Compare signal generation on the complementary * output. * @param htim TIM handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) { /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Disable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); /* Return function status */ return HAL_OK; } /** * @brief Starts the TIM Output Compare signal generation in interrupt mode * on the complementary output. * @param htim TIM OC handle * @param Channel TIM Channel to be enabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Check the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) { return HAL_ERROR; } /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); switch (Channel) { case TIM_CHANNEL_1: { /* Enable the TIM Output Compare interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); break; } case TIM_CHANNEL_2: { /* Enable the TIM Output Compare interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); break; } case TIM_CHANNEL_3: { /* Enable the TIM Output Compare interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Enable the TIM Break interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); /* Enable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } } /* Return function status */ return status; } /** * @brief Stops the TIM Output Compare signal generation in interrupt mode * on the complementary output. * @param htim TIM Output Compare handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpccer; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); switch (Channel) { case TIM_CHANNEL_1: { /* Disable the TIM Output Compare interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); break; } case TIM_CHANNEL_2: { /* Disable the TIM Output Compare interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); break; } case TIM_CHANNEL_3: { /* Disable the TIM Output Compare interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Disable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the TIM Break interrupt (only if no more channel is active) */ tmpccer = htim->Instance->CCER; if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET) { __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); } /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); } /* Return function status */ return status; } #if defined(TIM_DMA_SUPPORT) /** * @brief Starts the TIM Output Compare signal generation in DMA mode * on the complementary output. * @param htim TIM Output Compare handle * @param Channel TIM Channel to be enabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @param pData The source Buffer address. * @param Length The length of data to be transferred from memory to TIM peripheral * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, uint16_t Length) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Set the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) { return HAL_BUSY; } else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) { if ((pData == NULL) || (Length == 0U)) { return HAL_ERROR; } else { TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); } } else { return HAL_ERROR; } switch (Channel) { case TIM_CHANNEL_1: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Output Compare DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); break; } case TIM_CHANNEL_2: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Output Compare DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); break; } case TIM_CHANNEL_3: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Output Compare DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Enable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } } /* Return function status */ return status; } /** * @brief Stops the TIM Output Compare signal generation in DMA mode * on the complementary output. * @param htim TIM Output Compare handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); switch (Channel) { case TIM_CHANNEL_1: { /* Disable the TIM Output Compare DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); break; } case TIM_CHANNEL_2: { /* Disable the TIM Output Compare DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); break; } case TIM_CHANNEL_3: { /* Disable the TIM Output Compare DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Disable the Capture compare channel N */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); } /* Return function status */ return status; } #endif /* TIM_DMA_SUPPORT */ /** * @} */ /** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions * @brief Timer Complementary PWM functions * @verbatim ============================================================================== ##### Timer Complementary PWM functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Start the Complementary PWM. (+) Stop the Complementary PWM. (+) Start the Complementary PWM and enable interrupts. (+) Stop the Complementary PWM and disable interrupts. (+) Start the Complementary PWM and enable DMA transfers. (+) Stop the Complementary PWM and disable DMA transfers. @endverbatim * @{ */ /** * @brief Starts the PWM signal generation on the complementary output. * @param htim TIM handle * @param Channel TIM Channel to be enabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) { uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Check the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) { return HAL_ERROR; } /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); /* Enable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } /* Return function status */ return HAL_OK; } /** * @brief Stops the PWM signal generation on the complementary output. * @param htim TIM handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) { /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Disable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); /* Return function status */ return HAL_OK; } /** * @brief Starts the PWM signal generation in interrupt mode on the * complementary output. * @param htim TIM handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Check the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) { return HAL_ERROR; } /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); switch (Channel) { case TIM_CHANNEL_1: { /* Enable the TIM Capture/Compare 1 interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); break; } case TIM_CHANNEL_2: { /* Enable the TIM Capture/Compare 2 interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); break; } case TIM_CHANNEL_3: { /* Enable the TIM Capture/Compare 3 interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Enable the TIM Break interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); /* Enable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } } /* Return function status */ return status; } /** * @brief Stops the PWM signal generation in interrupt mode on the * complementary output. * @param htim TIM handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpccer; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); switch (Channel) { case TIM_CHANNEL_1: { /* Disable the TIM Capture/Compare 1 interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); break; } case TIM_CHANNEL_2: { /* Disable the TIM Capture/Compare 2 interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); break; } case TIM_CHANNEL_3: { /* Disable the TIM Capture/Compare 3 interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Disable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the TIM Break interrupt (only if no more channel is active) */ tmpccer = htim->Instance->CCER; if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET) { __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); } /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); } /* Return function status */ return status; } #if defined(TIM_DMA_SUPPORT) /** * @brief Starts the TIM PWM signal generation in DMA mode on the * complementary output * @param htim TIM handle * @param Channel TIM Channel to be enabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @param pData The source Buffer address. * @param Length The length of data to be transferred from memory to TIM peripheral * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, uint16_t Length) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpsmcr; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); /* Set the TIM complementary channel state */ if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) { return HAL_BUSY; } else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) { if ((pData == NULL) || (Length == 0U)) { return HAL_ERROR; } else { TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); } } else { return HAL_ERROR; } switch (Channel) { case TIM_CHANNEL_1: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Capture/Compare 1 DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); break; } case TIM_CHANNEL_2: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Capture/Compare 2 DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); break; } case TIM_CHANNEL_3: { /* Set the DMA compare callbacks */ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; /* Set the DMA error callback */ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; /* Enable the DMA channel */ if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) { /* Return error status */ return HAL_ERROR; } /* Enable the TIM Capture/Compare 3 DMA request */ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Enable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { __HAL_TIM_ENABLE(htim); } } else { __HAL_TIM_ENABLE(htim); } } /* Return function status */ return status; } /** * @brief Stops the TIM PWM signal generation in DMA mode on the complementary * output * @param htim TIM handle * @param Channel TIM Channel to be disabled * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); switch (Channel) { case TIM_CHANNEL_1: { /* Disable the TIM Capture/Compare 1 DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); break; } case TIM_CHANNEL_2: { /* Disable the TIM Capture/Compare 2 DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); break; } case TIM_CHANNEL_3: { /* Disable the TIM Capture/Compare 3 DMA request */ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); break; } default: status = HAL_ERROR; break; } if (status == HAL_OK) { /* Disable the complementary PWM output */ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM complementary channel state */ TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); } /* Return function status */ return status; } #endif /* TIM_DMA_SUPPORT */ /** * @} */ /** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions * @brief Timer Complementary One Pulse functions * @verbatim ============================================================================== ##### Timer Complementary One Pulse functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Start the Complementary One Pulse generation. (+) Stop the Complementary One Pulse. (+) Start the Complementary One Pulse and enable interrupts. (+) Stop the Complementary One Pulse and disable interrupts. @endverbatim * @{ */ /** * @brief Starts the TIM One Pulse signal generation on the complementary * output. * @note OutputChannel must match the pulse output channel chosen when calling * @ref HAL_TIM_OnePulse_ConfigChannel(). * @param htim TIM One Pulse handle * @param OutputChannel pulse output channel to enable * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) { uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); /* Check the TIM channels state */ if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) { return HAL_ERROR; } /* Set the TIM channels state */ TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); /* Enable the complementary One Pulse output channel and the Input Capture channel */ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Return function status */ return HAL_OK; } /** * @brief Stops the TIM One Pulse signal generation on the complementary * output. * @note OutputChannel must match the pulse output channel chosen when calling * @ref HAL_TIM_OnePulse_ConfigChannel(). * @param htim TIM One Pulse handle * @param OutputChannel pulse output channel to disable * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) { uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); /* Disable the complementary One Pulse output channel and the Input Capture channel */ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM channels state */ TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); /* Return function status */ return HAL_OK; } /** * @brief Starts the TIM One Pulse signal generation in interrupt mode on the * complementary channel. * @note OutputChannel must match the pulse output channel chosen when calling * @ref HAL_TIM_OnePulse_ConfigChannel(). * @param htim TIM One Pulse handle * @param OutputChannel pulse output channel to enable * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) { uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); /* Check the TIM channels state */ if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) { return HAL_ERROR; } /* Set the TIM channels state */ TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); /* Enable the TIM Capture/Compare 1 interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); /* Enable the TIM Capture/Compare 2 interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); /* Enable the complementary One Pulse output channel and the Input Capture channel */ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); /* Enable the Main Output */ __HAL_TIM_MOE_ENABLE(htim); /* Return function status */ return HAL_OK; } /** * @brief Stops the TIM One Pulse signal generation in interrupt mode on the * complementary channel. * @note OutputChannel must match the pulse output channel chosen when calling * @ref HAL_TIM_OnePulse_ConfigChannel(). * @param htim TIM One Pulse handle * @param OutputChannel pulse output channel to disable * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) { uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); /* Disable the TIM Capture/Compare 1 interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); /* Disable the TIM Capture/Compare 2 interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); /* Disable the complementary One Pulse output channel and the Input Capture channel */ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); /* Disable the Main Output */ __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); /* Set the TIM channels state */ TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); /* Return function status */ return HAL_OK; } /** * @} */ /** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions * @brief Peripheral Control functions * @verbatim ============================================================================== ##### Peripheral Control functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Configure the commutation event in case of use of the Hall sensor interface. (+) Configure Output channels for OC and PWM mode. (+) Configure Complementary channels, break features and dead time. (+) Configure Master synchronization. (+) Configure timer remapping capabilities. (+) Enable or disable channel grouping. @endverbatim * @{ */ /** * @brief Configure the TIM commutation event sequence. * @param htim TIM handle * @param InputTrigger Unused parameter (kept to avoid compatibility break). * @param CommutationSource the Commutation Event source * This parameter can be one of the following values: * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource) { UNUSED(InputTrigger); /* Check the parameters */ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); __HAL_LOCK(htim); /* Select the Capture Compare preload feature */ htim->Instance->CR2 |= TIM_CR2_CCPC; /* Select the Commutation event source */ htim->Instance->CR2 &= ~TIM_CR2_CCUS; htim->Instance->CR2 |= CommutationSource; /* Disable Commutation Interrupt */ __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); __HAL_UNLOCK(htim); return HAL_OK; } /** * @brief Configure the TIM commutation event sequence with interrupt. * @param htim TIM handle * @param InputTrigger Unused parameter (kept to avoid compatibility break). * @param CommutationSource the Commutation Event source * This parameter can be one of the following values: * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource) { UNUSED(InputTrigger); /* Check the parameters */ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); __HAL_LOCK(htim); /* Select the Capture Compare preload feature */ htim->Instance->CR2 |= TIM_CR2_CCPC; /* Select the Commutation event source */ htim->Instance->CR2 &= ~TIM_CR2_CCUS; htim->Instance->CR2 |= CommutationSource; /* Enable the Commutation Interrupt */ __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM); __HAL_UNLOCK(htim); return HAL_OK; } /** * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State * and the AOE(automatic output enable). * @param htim TIM handle * @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that * contains the BDTR Register configuration information for the TIM peripheral. * @note Interrupts can be generated when an active level is detected on the * break input, the break 2 input or the system break input. Break * interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro. * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig) { /* Keep this variable initialized to 0 as it is used to configure BDTR register */ uint32_t tmpbdtr = 0U; /* Check the parameters */ assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode)); assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode)); assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel)); assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime)); assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState)); assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity)); #if defined(TIM_BDTR_BKF) assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter)); #endif /* TIM_BDTR_BKF */ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput)); #if defined(TIM_BDTR_BKBID) assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode)); #endif /* TIM_BDTR_BKBID */ /* Check input state */ __HAL_LOCK(htim); /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, the OSSI State, the dead time value and the Automatic Output Enable Bit */ /* Set the BDTR bits */ MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime); MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel); MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode); MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode); MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState); MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity); MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput); #if defined(TIM_BDTR_BKF) MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos)); #endif /* TIM_BDTR_BKF */ #if defined(TIM_BDTR_BKBID) MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode); #endif /* TIM_BDTR_BKBID */ #if defined(TIM_BDTR_BK2E) if (IS_TIM_BKIN2_INSTANCE(htim->Instance)) { /* Check the parameters */ assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State)); assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity)); assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter)); #if defined(TIM_BDTR_BKBID) assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode)); #endif /* TIM_BDTR_BKBID */ /* Set the BREAK2 input related BDTR bits */ MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos)); MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State); MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity); } #endif /* TIM_BDTR_BK2E */ /* Set TIMx_BDTR */ htim->Instance->BDTR = tmpbdtr; __HAL_UNLOCK(htim); return HAL_OK; } /** * @brief Configures the break input source. * @param htim TIM handle. * @param BreakInput Break input to configure * This parameter can be one of the following values: * @arg TIM_BREAKINPUT_BRK: Timer break input * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input * @param sBreakInputConfig Break input source configuration * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput, const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmporx; uint32_t bkin_enable_mask; uint32_t bkin_polarity_mask; uint32_t bkin_enable_bitpos; uint32_t bkin_polarity_bitpos; /* Check the parameters */ assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); assert_param(IS_TIM_BREAKINPUT(BreakInput)); assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source)); assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable)); assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity)); /* Check input state */ __HAL_LOCK(htim); switch (sBreakInputConfig->Source) { case TIM_BREAKINPUTSOURCE_BKIN: { bkin_enable_mask = TIM_AF1_BKINE; bkin_enable_bitpos = TIM_AF1_BKINE_Pos; bkin_polarity_mask = TIM_AF1_BKINP; bkin_polarity_bitpos = TIM_AF1_BKINP_Pos; break; } default: { bkin_enable_mask = 0U; bkin_polarity_mask = 0U; bkin_enable_bitpos = 0U; bkin_polarity_bitpos = 0U; break; } } switch (BreakInput) { case TIM_BREAKINPUT_BRK: { /* Get the TIMx_AF1 register value */ tmporx = htim->Instance->AF1; /* Enable the break input */ tmporx &= ~bkin_enable_mask; tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask; /* Set the break input polarity */ tmporx &= ~bkin_polarity_mask; tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask; /* Set TIMx_AF1 */ htim->Instance->AF1 = tmporx; break; } #if defined(TIM_BDTR_BK2E) case TIM_BREAKINPUT_BRK2: { /* Get the TIMx_AF2 register value */ tmporx = htim->Instance->AF2; /* Enable the break input */ tmporx &= ~bkin_enable_mask; tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask; /* Set the break input polarity */ tmporx &= ~bkin_polarity_mask; tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask; /* Set TIMx_AF2 */ htim->Instance->AF2 = tmporx; break; } #endif /* TIM_BDTR_BK2E */ default: status = HAL_ERROR; break; } __HAL_UNLOCK(htim); return status; } #if defined(TIM17) /** * @brief Configures the TIMx Remapping input capabilities. * @param htim TIM handle. * @param Remap specifies the TIM remapping source. * This parameter can be one of the following values: * @arg TIM_TIM17_TI1_GPIO * @arg TIM_TIM17_TI1_LCO * @arg TIM_TIM17_TI1_MCO * * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap) { /* Check parameters */ assert_param(IS_TIM_REMAP(htim->Instance, Remap)); __HAL_LOCK(htim); /* Set the Timer remapping configuration */ WRITE_REG(htim->Instance->OR1, Remap); __HAL_UNLOCK(htim); return HAL_OK; } #endif /* TIM17 */ #if defined(TIM_CCR5_CCR5) /** * @brief Group channel 5 and channel 1, 2 or 3 * @param htim TIM handle. * @param Channels specifies the reference signal(s) the OC5REF is combined with. * This parameter can be any combination of the following values: * TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC * TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF * TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF * TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels) { /* Check parameters */ assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance)); assert_param(IS_TIM_GROUPCH5(Channels)); /* Process Locked */ __HAL_LOCK(htim); htim->State = HAL_TIM_STATE_BUSY; /* Clear GC5Cx bit fields */ htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1); /* Set GC5Cx bit fields */ htim->Instance->CCR5 |= Channels; /* Change the htim state */ htim->State = HAL_TIM_STATE_READY; __HAL_UNLOCK(htim); return HAL_OK; } #endif /* TIM_CCR5_CCR5 */ #if defined(TIM_BDTR_BKBID) /** * @brief Disarm the designated break input (when it operates in bidirectional mode). * @param htim TIM handle. * @param BreakInput Break input to disarm * This parameter can be one of the following values: * @arg TIM_BREAKINPUT_BRK: Timer break input * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input * @note The break input can be disarmed only when it is configured in * bidirectional mode and when when MOE is reset. * @note Purpose is to be able to have the input voltage back to high-state, * whatever the time constant on the output . * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput) { HAL_StatusTypeDef status = HAL_OK; uint32_t tmpbdtr; /* Check the parameters */ assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); assert_param(IS_TIM_BREAKINPUT(BreakInput)); switch (BreakInput) { case TIM_BREAKINPUT_BRK: { /* Check initial conditions */ tmpbdtr = READ_REG(htim->Instance->BDTR); if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) && (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U)) { /* Break input BRK is disarmed */ SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM); } break; } default: status = HAL_ERROR; break; } return status; } /** * @brief Arm the designated break input (when it operates in bidirectional mode). * @param htim TIM handle. * @param BreakInput Break input to arm * This parameter can be one of the following values: * @arg TIM_BREAKINPUT_BRK: Timer break input * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input * @note Arming is possible at anytime, even if fault is present. * @note Break input is automatically armed as soon as MOE bit is set. * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef *htim, uint32_t BreakInput) { HAL_StatusTypeDef status = HAL_OK; uint32_t tickstart; /* Check the parameters */ assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); assert_param(IS_TIM_BREAKINPUT(BreakInput)); switch (BreakInput) { case TIM_BREAKINPUT_BRK: { /* Check initial conditions */ if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) { /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */ /* Init tickstart for timeout management */ tickstart = HAL_GetTick(); while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL) { if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT) { /* New check to avoid false timeout detection in case of preemption */ if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL) { return HAL_TIMEOUT; } } } } break; } default: status = HAL_ERROR; break; } return status; } #endif /* TIM_BDTR_BKBID */ /** * @} */ /** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions * @brief Extended Callbacks functions * @verbatim ============================================================================== ##### Extended Callbacks functions ##### ============================================================================== [..] This section provides Extended TIM callback functions: (+) Timer Commutation callback (+) Timer Break callback @endverbatim * @{ */ /** * @brief Commutation callback in non-blocking mode * @param htim TIM handle * @retval None */ __weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim) { /* Prevent unused argument(s) compilation warning */ UNUSED(htim); /* NOTE : This function should not be modified, when the callback is needed, the HAL_TIMEx_CommutCallback could be implemented in the user file */ } /** * @brief Break detection callback in non-blocking mode * @param htim TIM handle * @retval None */ __weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim) { /* Prevent unused argument(s) compilation warning */ UNUSED(htim); /* NOTE : This function should not be modified, when the callback is needed, the HAL_TIMEx_BreakCallback could be implemented in the user file */ } #if defined(TIM_BDTR_BK2E) /** * @brief Break2 detection callback in non blocking mode * @param htim: TIM handle * @retval None */ __weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim) { /* Prevent unused argument(s) compilation warning */ UNUSED(htim); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_TIMEx_Break2Callback could be implemented in the user file */ } #endif /* TIM_BDTR_BK2E */ /** * @} */ /** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions * @brief Extended Peripheral State functions * @verbatim ============================================================================== ##### Extended Peripheral State functions ##### ============================================================================== [..] This subsection permits to get in run-time the status of the peripheral and the data flow. @endverbatim * @{ */ /** * @brief Return actual state of the TIM complementary channel. * @param htim TIM handle * @param ChannelN TIM Complementary channel * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 * @arg TIM_CHANNEL_2: TIM Channel 2 * @arg TIM_CHANNEL_3: TIM Channel 3 * @retval TIM Complementary channel state */ HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN) { HAL_TIM_ChannelStateTypeDef channel_state; /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN)); channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN); return channel_state; } /** * @} */ /** * @} */ /* Private functions ---------------------------------------------------------*/ /** @defgroup TIMEx_Private_Functions TIM Extended Private Functions * @{ */ #if defined(TIM_DMA_SUPPORT) /** * @brief TIM DMA Delay Pulse complete callback (complementary channel). * @param hdma pointer to DMA handle. * @retval None */ static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma) { TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; if (hdma == htim->hdma[TIM_DMA_ID_CC1]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; if (hdma->Init.Mode == DMA_NORMAL) { TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); } } else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; if (hdma->Init.Mode == DMA_NORMAL) { TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); } } else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; if (hdma->Init.Mode == DMA_NORMAL) { TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); } } else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; if (hdma->Init.Mode == DMA_NORMAL) { TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); } } else { /* nothing to do */ } #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) htim->PWM_PulseFinishedCallback(htim); #else HAL_TIM_PWM_PulseFinishedCallback(htim); #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; } /** * @brief TIM DMA error callback (complementary channel) * @param hdma pointer to DMA handle. * @retval None */ static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma) { TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; if (hdma == htim->hdma[TIM_DMA_ID_CC1]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); } else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); } else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) { htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); } else { /* nothing to do */ } #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) htim->ErrorCallback(htim); #else HAL_TIM_ErrorCallback(htim); #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; } #endif /* TIM_DMA_SUPPORT */ /** * @brief Enables or disables the TIM Capture Compare Channel xN. * @param TIMx to select the TIM peripheral * @param Channel specifies the TIM Channel * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 * @arg TIM_CHANNEL_2: TIM Channel 2 * @arg TIM_CHANNEL_3: TIM Channel 3 * @param ChannelNState specifies the TIM Channel CCxNE bit new state. * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable. * @retval None */ static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState) { uint32_t tmp; tmp = TIM_CCER_CC1NE << (Channel & 0xFU); /* 0xFU = 15 bits max shift */ /* Reset the CCxNE Bit */ TIMx->CCER &= ~tmp; /* Set or reset the CCxNE Bit */ TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0xFU)); /* 0xFU = 15 bits max shift */ } /** * @} */ #endif /* HAL_TIM_MODULE_ENABLED */ /** * @} */ /** * @} */