Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:09

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_ll_lptim.c
0004   * @author  MCD Application Team
0005   * @brief   LPTIM LL module driver.
0006   ******************************************************************************
0007   * @attention
0008   *
0009   * Copyright (c) 2017 STMicroelectronics.
0010   * All rights reserved.
0011   *
0012   * This software is licensed under terms that can be found in the LICENSE file
0013   * in the root directory of this software component.
0014   * If no LICENSE file comes with this software, it is provided AS-IS.
0015   *
0016   ******************************************************************************
0017   */
0018 #if defined(USE_FULL_LL_DRIVER) || defined(__rtems__)
0019 
0020 /* Includes ------------------------------------------------------------------*/
0021 #include "stm32h7xx_ll_lptim.h"
0022 #include "stm32h7xx_ll_bus.h"
0023 #include "stm32h7xx_ll_rcc.h"
0024 
0025 
0026 #ifdef  USE_FULL_ASSERT
0027 #include "stm32_assert.h"
0028 #else
0029 #define assert_param(expr) ((void)0U)
0030 #endif /* USE_FULL_ASSERT */
0031 
0032 /** @addtogroup STM32H7xx_LL_Driver
0033   * @{
0034   */
0035 
0036 #if defined (LPTIM1) || defined (LPTIM2) || defined (LPTIM3) || defined (LPTIM4) || defined (LPTIM5)
0037 
0038 /** @addtogroup LPTIM_LL
0039   * @{
0040   */
0041 
0042 /* Private types -------------------------------------------------------------*/
0043 /* Private variables ---------------------------------------------------------*/
0044 /* Private constants ---------------------------------------------------------*/
0045 /* Private macros ------------------------------------------------------------*/
0046 /** @addtogroup LPTIM_LL_Private_Macros
0047   * @{
0048   */
0049 #define IS_LL_LPTIM_CLOCK_SOURCE(__VALUE__) (((__VALUE__) == LL_LPTIM_CLK_SOURCE_INTERNAL) \
0050                                              || ((__VALUE__) == LL_LPTIM_CLK_SOURCE_EXTERNAL))
0051 
0052 #define IS_LL_LPTIM_CLOCK_PRESCALER(__VALUE__) (((__VALUE__) == LL_LPTIM_PRESCALER_DIV1)   \
0053                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV2)   \
0054                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV4)   \
0055                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV8)   \
0056                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV16)  \
0057                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV32)  \
0058                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV64)  \
0059                                                 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV128))
0060 
0061 #define IS_LL_LPTIM_WAVEFORM(__VALUE__) (((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_PWM) \
0062                                          || ((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_SETONCE))
0063 
0064 #define IS_LL_LPTIM_OUTPUT_POLARITY(__VALUE__) (((__VALUE__) == LL_LPTIM_OUTPUT_POLARITY_REGULAR) \
0065                                                 || ((__VALUE__) == LL_LPTIM_OUTPUT_POLARITY_INVERSE))
0066 /**
0067   * @}
0068   */
0069 
0070 
0071 /* Private function prototypes -----------------------------------------------*/
0072 /* Private functions ---------------------------------------------------------*/
0073 /** @defgroup LPTIM_Private_Functions LPTIM Private Functions
0074   * @ingroup RTEMSBSPsARMSTM32H7
0075   * @{
0076   */
0077 /**
0078   * @}
0079   */
0080 /* Exported functions --------------------------------------------------------*/
0081 /** @addtogroup LPTIM_LL_Exported_Functions
0082   * @{
0083   */
0084 
0085 /** @addtogroup LPTIM_LL_EF_Init
0086   * @{
0087   */
0088 
0089 /**
0090   * @brief  Set LPTIMx registers to their reset values.
0091   * @param  LPTIMx LP Timer instance
0092   * @retval An ErrorStatus enumeration value:
0093   *          - SUCCESS: LPTIMx registers are de-initialized
0094   *          - ERROR: invalid LPTIMx instance
0095   */
0096 ErrorStatus LL_LPTIM_DeInit(const LPTIM_TypeDef *LPTIMx)
0097 {
0098   ErrorStatus result = SUCCESS;
0099 
0100   /* Check the parameters */
0101   assert_param(IS_LPTIM_INSTANCE(LPTIMx));
0102 
0103   if (LPTIMx == LPTIM1)
0104   {
0105     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_LPTIM1);
0106     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
0107   }
0108   else if (LPTIMx == LPTIM2)
0109   {
0110     LL_APB4_GRP1_ForceReset(LL_APB4_GRP1_PERIPH_LPTIM2);
0111     LL_APB4_GRP1_ReleaseReset(LL_APB4_GRP1_PERIPH_LPTIM2);
0112   }
0113 #if defined(LPTIM3)
0114   else if (LPTIMx == LPTIM3)
0115   {
0116     LL_APB4_GRP1_ForceReset(LL_APB4_GRP1_PERIPH_LPTIM3);
0117     LL_APB4_GRP1_ReleaseReset(LL_APB4_GRP1_PERIPH_LPTIM3);
0118   }
0119 #endif /* LPTIM3 */
0120 #if defined(LPTIM4)
0121   else if (LPTIMx == LPTIM4)
0122   {
0123     LL_APB4_GRP1_ForceReset(LL_APB4_GRP1_PERIPH_LPTIM4);
0124     LL_APB4_GRP1_ReleaseReset(LL_APB4_GRP1_PERIPH_LPTIM4);
0125   }
0126 #endif /* LPTIM4 */
0127 #if defined(LPTIM5)
0128   else if (LPTIMx == LPTIM5)
0129   {
0130     LL_APB4_GRP1_ForceReset(LL_APB4_GRP1_PERIPH_LPTIM5);
0131     LL_APB4_GRP1_ReleaseReset(LL_APB4_GRP1_PERIPH_LPTIM5);
0132   }
0133 #endif /* LPTIM5 */
0134   else
0135   {
0136     result = ERROR;
0137   }
0138 
0139   return result;
0140 }
0141 
0142 /**
0143   * @brief  Set each fields of the LPTIM_InitStruct structure to its default
0144   *         value.
0145   * @param  LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure
0146   * @retval None
0147   */
0148 void LL_LPTIM_StructInit(LL_LPTIM_InitTypeDef *LPTIM_InitStruct)
0149 {
0150   /* Set the default configuration */
0151   LPTIM_InitStruct->ClockSource = LL_LPTIM_CLK_SOURCE_INTERNAL;
0152   LPTIM_InitStruct->Prescaler   = LL_LPTIM_PRESCALER_DIV1;
0153   LPTIM_InitStruct->Waveform    = LL_LPTIM_OUTPUT_WAVEFORM_PWM;
0154   LPTIM_InitStruct->Polarity    = LL_LPTIM_OUTPUT_POLARITY_REGULAR;
0155 }
0156 
0157 /**
0158   * @brief  Configure the LPTIMx peripheral according to the specified parameters.
0159   * @note LL_LPTIM_Init can only be called when the LPTIM instance is disabled.
0160   * @note LPTIMx can be disabled using unitary function @ref LL_LPTIM_Disable().
0161   * @param  LPTIMx LP Timer Instance
0162   * @param  LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure
0163   * @retval An ErrorStatus enumeration value:
0164   *          - SUCCESS: LPTIMx instance has been initialized
0165   *          - ERROR: LPTIMx instance hasn't been initialized
0166   */
0167 ErrorStatus LL_LPTIM_Init(LPTIM_TypeDef *LPTIMx, const LL_LPTIM_InitTypeDef *LPTIM_InitStruct)
0168 {
0169   ErrorStatus result = SUCCESS;
0170   /* Check the parameters */
0171   assert_param(IS_LPTIM_INSTANCE(LPTIMx));
0172   assert_param(IS_LL_LPTIM_CLOCK_SOURCE(LPTIM_InitStruct->ClockSource));
0173   assert_param(IS_LL_LPTIM_CLOCK_PRESCALER(LPTIM_InitStruct->Prescaler));
0174   assert_param(IS_LL_LPTIM_WAVEFORM(LPTIM_InitStruct->Waveform));
0175   assert_param(IS_LL_LPTIM_OUTPUT_POLARITY(LPTIM_InitStruct->Polarity));
0176 
0177   /* The LPTIMx_CFGR register must only be modified when the LPTIM is disabled
0178      (ENABLE bit is reset to 0).
0179   */
0180   if (LL_LPTIM_IsEnabled(LPTIMx) == 1UL)
0181   {
0182     result = ERROR;
0183   }
0184   else
0185   {
0186     /* Set CKSEL bitfield according to ClockSource value */
0187     /* Set PRESC bitfield according to Prescaler value */
0188     /* Set WAVE bitfield according to Waveform value */
0189     /* Set WAVEPOL bitfield according to Polarity value */
0190     MODIFY_REG(LPTIMx->CFGR,
0191                (LPTIM_CFGR_CKSEL | LPTIM_CFGR_PRESC | LPTIM_CFGR_WAVE | LPTIM_CFGR_WAVPOL),
0192                LPTIM_InitStruct->ClockSource | \
0193                LPTIM_InitStruct->Prescaler | \
0194                LPTIM_InitStruct->Waveform | \
0195                LPTIM_InitStruct->Polarity);
0196   }
0197 
0198   return result;
0199 }
0200 
0201 /**
0202   * @brief  Disable the LPTIM instance
0203   * @rmtoll CR           ENABLE        LL_LPTIM_Disable
0204   * @param  LPTIMx Low-Power Timer instance
0205   * @note   The following sequence is required to solve LPTIM disable HW limitation.
0206   *         Please check Errata Sheet ES0335 for more details under "MCU may remain
0207   *         stuck in LPTIM interrupt when entering Stop mode" section.
0208   * @retval None
0209   */
0210 void LL_LPTIM_Disable(LPTIM_TypeDef *LPTIMx)
0211 {
0212   LL_RCC_ClocksTypeDef rcc_clock;
0213   uint32_t tmpclksource = 0;
0214   uint32_t tmpIER;
0215   uint32_t tmpCFGR;
0216   uint32_t tmpCMP;
0217   uint32_t tmpARR;
0218   uint32_t primask_bit;
0219   uint32_t tmpCFGR2;
0220 
0221   /* Check the parameters */
0222   assert_param(IS_LPTIM_INSTANCE(LPTIMx));
0223 
0224   /* Enter critical section */
0225   primask_bit = __get_PRIMASK();
0226   __set_PRIMASK(1) ;
0227 
0228   /********** Save LPTIM Config *********/
0229   /* Save LPTIM source clock */
0230   switch ((uint32_t)LPTIMx)
0231   {
0232     case LPTIM1_BASE:
0233       tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE);
0234       break;
0235     case LPTIM2_BASE:
0236       tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE);
0237       break;
0238 #if defined(LPTIM3)&&defined(LPTIM4)&&defined(LPTIM5)
0239     case LPTIM3_BASE:
0240     case LPTIM4_BASE:
0241     case LPTIM5_BASE:
0242       tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM345_CLKSOURCE);
0243       break;
0244 #elif defined(LPTIM3)
0245     case LPTIM3_BASE:
0246       tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM3_CLKSOURCE);
0247       break;
0248 #endif /* LPTIM3 && LPTIM4 && LPTIM5 */
0249     default:
0250       break;
0251   }
0252 
0253   /* Save LPTIM configuration registers */
0254   tmpIER = LPTIMx->IER;
0255   tmpCFGR = LPTIMx->CFGR;
0256   tmpCMP = LPTIMx->CMP;
0257   tmpARR = LPTIMx->ARR;
0258   tmpCFGR2 = LPTIMx->CFGR2;
0259 
0260   /************* Reset LPTIM ************/
0261   (void)LL_LPTIM_DeInit(LPTIMx);
0262 
0263   /********* Restore LPTIM Config *******/
0264   LL_RCC_GetSystemClocksFreq(&rcc_clock);
0265 
0266   if ((tmpCMP != 0UL) || (tmpARR != 0UL))
0267   {
0268     /* Force LPTIM source kernel clock from APB */
0269     switch ((uint32_t)LPTIMx)
0270     {
0271       case LPTIM1_BASE:
0272         LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_PCLK1);
0273         break;
0274       case LPTIM2_BASE:
0275         LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK4);
0276         break;
0277 #if defined(LPTIM3)&&defined(LPTIM4)&&defined(LPTIM5)
0278       case LPTIM3_BASE:
0279       case LPTIM4_BASE:
0280       case LPTIM5_BASE:
0281         LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM345_CLKSOURCE_PCLK4);
0282         break;
0283 #elif defined(LPTIM3)
0284       case LPTIM3_BASE:
0285         LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM3_CLKSOURCE_PCLK4);
0286         break;
0287 #endif /* LPTIM3 && LPTIM4 && LPTIM5*/
0288       default:
0289         break;
0290     }
0291 
0292     if (tmpCMP != 0UL)
0293     {
0294       /* Restore CMP and ARR registers (LPTIM should be enabled first) */
0295       LPTIMx->CR |= LPTIM_CR_ENABLE;
0296       LPTIMx->CMP = tmpCMP;
0297 
0298       /* Polling on CMP write ok status after above restore operation */
0299       do
0300       {
0301         rcc_clock.SYSCLK_Frequency--; /* Used for timeout */
0302       } while (((LL_LPTIM_IsActiveFlag_CMPOK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL));
0303 
0304       LL_LPTIM_ClearFlag_CMPOK(LPTIMx);
0305     }
0306 
0307     if (tmpARR != 0UL)
0308     {
0309       LPTIMx->CR |= LPTIM_CR_ENABLE;
0310       LPTIMx->ARR = tmpARR;
0311 
0312       LL_RCC_GetSystemClocksFreq(&rcc_clock);
0313       /* Polling on ARR write ok status after above restore operation */
0314       do
0315       {
0316         rcc_clock.SYSCLK_Frequency--; /* Used for timeout */
0317       } while (((LL_LPTIM_IsActiveFlag_ARROK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL));
0318 
0319       LL_LPTIM_ClearFlag_ARROK(LPTIMx);
0320     }
0321 
0322 
0323     /* Restore LPTIM source kernel clock */
0324     LL_RCC_SetLPTIMClockSource(tmpclksource);
0325   }
0326 
0327   /* Restore configuration registers (LPTIM should be disabled first) */
0328   LPTIMx->CR &= ~(LPTIM_CR_ENABLE);
0329   LPTIMx->IER = tmpIER;
0330   LPTIMx->CFGR = tmpCFGR;
0331   LPTIMx->CFGR2 = tmpCFGR2;
0332 
0333   /* Exit critical section: restore previous priority mask */
0334   __set_PRIMASK(primask_bit);
0335 }
0336 
0337 /**
0338   * @}
0339   */
0340 
0341 /**
0342   * @}
0343   */
0344 
0345 /**
0346   * @}
0347   */
0348 
0349 #endif /* LPTIM1 || LPTIM2 ||  LPTIM3 || LPTIM4 || LPTIM5 */
0350 
0351 /**
0352   * @}
0353   */
0354 
0355 #endif /* USE_FULL_LL_DRIVER */