STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_ll_lptim.c 00004 * @author MCD Application Team 00005 * @brief LPTIM LL module driver. 00006 ****************************************************************************** 00007 * @attention 00008 * 00009 * Copyright (c) 2017 STMicroelectronics. 00010 * All rights reserved. 00011 * 00012 * This software is licensed under terms that can be found in the LICENSE file 00013 * in the root directory of this software component. 00014 * If no LICENSE file comes with this software, it is provided AS-IS. 00015 * 00016 ****************************************************************************** 00017 */ 00018 #if defined(USE_FULL_LL_DRIVER) 00019 00020 /* Includes ------------------------------------------------------------------*/ 00021 #include "stm32l4xx_ll_lptim.h" 00022 #include "stm32l4xx_ll_bus.h" 00023 #include "stm32l4xx_ll_rcc.h" 00024 00025 00026 #ifdef USE_FULL_ASSERT 00027 #include "stm32_assert.h" 00028 #else 00029 #define assert_param(expr) ((void)0U) 00030 #endif /* USE_FULL_ASSERT */ 00031 00032 /** @addtogroup STM32L4xx_LL_Driver 00033 * @{ 00034 */ 00035 00036 #if defined (LPTIM1) || defined (LPTIM2) 00037 00038 /** @addtogroup LPTIM_LL 00039 * @{ 00040 */ 00041 00042 /* Private types -------------------------------------------------------------*/ 00043 /* Private variables ---------------------------------------------------------*/ 00044 /* Private constants ---------------------------------------------------------*/ 00045 /* Private macros ------------------------------------------------------------*/ 00046 /** @addtogroup LPTIM_LL_Private_Macros 00047 * @{ 00048 */ 00049 #define IS_LL_LPTIM_CLOCK_SOURCE(__VALUE__) (((__VALUE__) == LL_LPTIM_CLK_SOURCE_INTERNAL) \ 00050 || ((__VALUE__) == LL_LPTIM_CLK_SOURCE_EXTERNAL)) 00051 00052 #define IS_LL_LPTIM_CLOCK_PRESCALER(__VALUE__) (((__VALUE__) == LL_LPTIM_PRESCALER_DIV1) \ 00053 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV2) \ 00054 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV4) \ 00055 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV8) \ 00056 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV16) \ 00057 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV32) \ 00058 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV64) \ 00059 || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV128)) 00060 00061 #define IS_LL_LPTIM_WAVEFORM(__VALUE__) (((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_PWM) \ 00062 || ((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_SETONCE)) 00063 00064 #define IS_LL_LPTIM_OUTPUT_POLARITY(__VALUE__) (((__VALUE__) == LL_LPTIM_OUTPUT_POLARITY_REGULAR) \ 00065 || ((__VALUE__) == LL_LPTIM_OUTPUT_POLARITY_INVERSE)) 00066 /** 00067 * @} 00068 */ 00069 00070 00071 /* Private function prototypes -----------------------------------------------*/ 00072 /* Private functions ---------------------------------------------------------*/ 00073 /** @defgroup LPTIM_Private_Functions LPTIM Private Functions 00074 * @{ 00075 */ 00076 /** 00077 * @} 00078 */ 00079 /* Exported functions --------------------------------------------------------*/ 00080 /** @addtogroup LPTIM_LL_Exported_Functions 00081 * @{ 00082 */ 00083 00084 /** @addtogroup LPTIM_LL_EF_Init 00085 * @{ 00086 */ 00087 00088 /** 00089 * @brief Set LPTIMx registers to their reset values. 00090 * @param LPTIMx LP Timer instance 00091 * @retval An ErrorStatus enumeration value: 00092 * - SUCCESS: LPTIMx registers are de-initialized 00093 * - ERROR: invalid LPTIMx instance 00094 */ 00095 ErrorStatus LL_LPTIM_DeInit(LPTIM_TypeDef *LPTIMx) 00096 { 00097 ErrorStatus result = SUCCESS; 00098 00099 /* Check the parameters */ 00100 assert_param(IS_LPTIM_INSTANCE(LPTIMx)); 00101 00102 if (LPTIMx == LPTIM1) 00103 { 00104 LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_LPTIM1); 00105 LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1); 00106 } 00107 #if defined(LPTIM2) 00108 else if (LPTIMx == LPTIM2) 00109 { 00110 LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_LPTIM2); 00111 LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_LPTIM2); 00112 } 00113 #endif /* LPTIM2 */ 00114 else 00115 { 00116 result = ERROR; 00117 } 00118 00119 return result; 00120 } 00121 00122 /** 00123 * @brief Set each fields of the LPTIM_InitStruct structure to its default 00124 * value. 00125 * @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure 00126 * @retval None 00127 */ 00128 void LL_LPTIM_StructInit(LL_LPTIM_InitTypeDef *LPTIM_InitStruct) 00129 { 00130 /* Set the default configuration */ 00131 LPTIM_InitStruct->ClockSource = LL_LPTIM_CLK_SOURCE_INTERNAL; 00132 LPTIM_InitStruct->Prescaler = LL_LPTIM_PRESCALER_DIV1; 00133 LPTIM_InitStruct->Waveform = LL_LPTIM_OUTPUT_WAVEFORM_PWM; 00134 LPTIM_InitStruct->Polarity = LL_LPTIM_OUTPUT_POLARITY_REGULAR; 00135 } 00136 00137 /** 00138 * @brief Configure the LPTIMx peripheral according to the specified parameters. 00139 * @note LL_LPTIM_Init can only be called when the LPTIM instance is disabled. 00140 * @note LPTIMx can be disabled using unitary function @ref LL_LPTIM_Disable(). 00141 * @param LPTIMx LP Timer Instance 00142 * @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure 00143 * @retval An ErrorStatus enumeration value: 00144 * - SUCCESS: LPTIMx instance has been initialized 00145 * - ERROR: LPTIMx instance hasn't been initialized 00146 */ 00147 ErrorStatus LL_LPTIM_Init(LPTIM_TypeDef *LPTIMx, LL_LPTIM_InitTypeDef *LPTIM_InitStruct) 00148 { 00149 ErrorStatus result = SUCCESS; 00150 /* Check the parameters */ 00151 assert_param(IS_LPTIM_INSTANCE(LPTIMx)); 00152 assert_param(IS_LL_LPTIM_CLOCK_SOURCE(LPTIM_InitStruct->ClockSource)); 00153 assert_param(IS_LL_LPTIM_CLOCK_PRESCALER(LPTIM_InitStruct->Prescaler)); 00154 assert_param(IS_LL_LPTIM_WAVEFORM(LPTIM_InitStruct->Waveform)); 00155 assert_param(IS_LL_LPTIM_OUTPUT_POLARITY(LPTIM_InitStruct->Polarity)); 00156 00157 /* The LPTIMx_CFGR register must only be modified when the LPTIM is disabled 00158 (ENABLE bit is reset to 0). 00159 */ 00160 if (LL_LPTIM_IsEnabled(LPTIMx) == 1UL) 00161 { 00162 result = ERROR; 00163 } 00164 else 00165 { 00166 /* Set CKSEL bitfield according to ClockSource value */ 00167 /* Set PRESC bitfield according to Prescaler value */ 00168 /* Set WAVE bitfield according to Waveform value */ 00169 /* Set WAVEPOL bitfield according to Polarity value */ 00170 MODIFY_REG(LPTIMx->CFGR, 00171 (LPTIM_CFGR_CKSEL | LPTIM_CFGR_PRESC | LPTIM_CFGR_WAVE | LPTIM_CFGR_WAVPOL), 00172 LPTIM_InitStruct->ClockSource | \ 00173 LPTIM_InitStruct->Prescaler | \ 00174 LPTIM_InitStruct->Waveform | \ 00175 LPTIM_InitStruct->Polarity); 00176 } 00177 00178 return result; 00179 } 00180 00181 /** 00182 * @brief Disable the LPTIM instance 00183 * @rmtoll CR ENABLE LL_LPTIM_Disable 00184 * @param LPTIMx Low-Power Timer instance 00185 * @note The following sequence is required to solve LPTIM disable HW limitation. 00186 * Please check Errata Sheet ES0335 for more details under "MCU may remain 00187 * stuck in LPTIM interrupt when entering Stop mode" section. 00188 * @retval None 00189 */ 00190 void LL_LPTIM_Disable(LPTIM_TypeDef *LPTIMx) 00191 { 00192 LL_RCC_ClocksTypeDef rcc_clock; 00193 uint32_t tmpclksource = 0; 00194 uint32_t tmpIER; 00195 uint32_t tmpCFGR; 00196 uint32_t tmpCMP; 00197 uint32_t tmpARR; 00198 uint32_t primask_bit; 00199 uint32_t tmpOR; 00200 #if defined(LPTIM_RCR_REP) 00201 uint32_t tmpRCR; 00202 #endif 00203 00204 /* Check the parameters */ 00205 assert_param(IS_LPTIM_INSTANCE(LPTIMx)); 00206 00207 /* Enter critical section */ 00208 primask_bit = __get_PRIMASK(); 00209 __set_PRIMASK(1) ; 00210 00211 /********** Save LPTIM Config *********/ 00212 /* Save LPTIM source clock */ 00213 switch ((uint32_t)LPTIMx) 00214 { 00215 case LPTIM1_BASE: 00216 tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE); 00217 break; 00218 #if defined(LPTIM2) 00219 case LPTIM2_BASE: 00220 tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE); 00221 break; 00222 #endif /* LPTIM2 */ 00223 default: 00224 break; 00225 } 00226 00227 /* Save LPTIM configuration registers */ 00228 tmpIER = LPTIMx->IER; 00229 tmpCFGR = LPTIMx->CFGR; 00230 tmpCMP = LPTIMx->CMP; 00231 tmpARR = LPTIMx->ARR; 00232 tmpOR = LPTIMx->OR; 00233 #if defined(LPTIM_RCR_REP) 00234 tmpRCR = LPTIMx->RCR; 00235 #endif 00236 00237 /************* Reset LPTIM ************/ 00238 (void)LL_LPTIM_DeInit(LPTIMx); 00239 00240 /********* Restore LPTIM Config *******/ 00241 LL_RCC_GetSystemClocksFreq(&rcc_clock); 00242 00243 #if defined(LPTIM_RCR_REP) 00244 if ((tmpCMP != 0UL) || (tmpARR != 0UL) || (tmpRCR != 0UL)) 00245 #else 00246 if ((tmpCMP != 0UL) || (tmpARR != 0UL)) 00247 #endif 00248 { 00249 /* Force LPTIM source kernel clock from APB */ 00250 switch ((uint32_t)LPTIMx) 00251 { 00252 case LPTIM1_BASE: 00253 LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_PCLK1); 00254 break; 00255 #if defined(LPTIM2) 00256 case LPTIM2_BASE: 00257 LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); 00258 break; 00259 #endif /* LPTIM2 */ 00260 default: 00261 break; 00262 } 00263 00264 if (tmpCMP != 0UL) 00265 { 00266 /* Restore CMP and ARR registers (LPTIM should be enabled first) */ 00267 LPTIMx->CR |= LPTIM_CR_ENABLE; 00268 LPTIMx->CMP = tmpCMP; 00269 00270 /* Polling on CMP write ok status after above restore operation */ 00271 do 00272 { 00273 rcc_clock.SYSCLK_Frequency--; /* Used for timeout */ 00274 } while (((LL_LPTIM_IsActiveFlag_CMPOK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL)); 00275 00276 LL_LPTIM_ClearFlag_CMPOK(LPTIMx); 00277 } 00278 00279 if (tmpARR != 0UL) 00280 { 00281 LPTIMx->CR |= LPTIM_CR_ENABLE; 00282 LPTIMx->ARR = tmpARR; 00283 00284 LL_RCC_GetSystemClocksFreq(&rcc_clock); 00285 /* Polling on ARR write ok status after above restore operation */ 00286 do 00287 { 00288 rcc_clock.SYSCLK_Frequency--; /* Used for timeout */ 00289 } 00290 while (((LL_LPTIM_IsActiveFlag_ARROK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL)); 00291 00292 LL_LPTIM_ClearFlag_ARROK(LPTIMx); 00293 } 00294 00295 #if defined(LPTIM_RCR_REP) 00296 if (tmpRCR != 0UL) 00297 { 00298 LPTIMx->CR |= LPTIM_CR_ENABLE; 00299 LPTIMx->RCR = tmpRCR; 00300 00301 LL_RCC_GetSystemClocksFreq(&rcc_clock); 00302 /* Polling on RCR write ok status after above restore operation */ 00303 do 00304 { 00305 rcc_clock.SYSCLK_Frequency--; /* Used for timeout */ 00306 } while (((LL_LPTIM_IsActiveFlag_REPOK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL)); 00307 00308 LL_LPTIM_ClearFlag_REPOK(LPTIMx); 00309 } 00310 #endif 00311 00312 /* Restore LPTIM source kernel clock */ 00313 LL_RCC_SetLPTIMClockSource(tmpclksource); 00314 } 00315 00316 /* Restore configuration registers (LPTIM should be disabled first) */ 00317 LPTIMx->CR &= ~(LPTIM_CR_ENABLE); 00318 LPTIMx->IER = tmpIER; 00319 LPTIMx->CFGR = tmpCFGR; 00320 LPTIMx->OR = tmpOR; 00321 00322 /* Exit critical section: restore previous priority mask */ 00323 __set_PRIMASK(primask_bit); 00324 } 00325 00326 /** 00327 * @} 00328 */ 00329 00330 /** 00331 * @} 00332 */ 00333 00334 /** 00335 * @} 00336 */ 00337 00338 #endif /* LPTIM1 || LPTIM2 */ 00339 00340 /** 00341 * @} 00342 */ 00343 00344 #endif /* USE_FULL_LL_DRIVER */