STM32F0xx Standard Peripherals Firmware Library
|
STM32F0xx_StdPeriph_Examples/PWR/PWR_Standby/main.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file PWR/PWR_STANDBY/main.c 00004 * @author MCD Application Team 00005 * @version V1.4.0 00006 * @date 24-July-2014 00007 * @brief Main program body 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "main.h" 00030 00031 /** @addtogroup STM32F0xx_StdPeriph_Examples 00032 * @{ 00033 */ 00034 00035 /** @addtogroup PWR_STANDBY 00036 * @{ 00037 */ 00038 00039 /* Private typedef -----------------------------------------------------------*/ 00040 /* Private define ------------------------------------------------------------*/ 00041 /* Private macro -------------------------------------------------------------*/ 00042 /* Private variables ---------------------------------------------------------*/ 00043 extern __IO uint32_t CaptureNumber, PeriodValue; 00044 00045 /* Private function prototypes -----------------------------------------------*/ 00046 static void RTC_Config(void); 00047 static void EnterSTANDBYMode(void); 00048 static uint32_t GetLSIFrequency(void); 00049 void SysTick_Configuration(void); 00050 00051 /* Private functions ---------------------------------------------------------*/ 00052 00053 /** 00054 * @brief Main program. 00055 * @param None 00056 * @retval None 00057 */ 00058 int main(void) 00059 { 00060 /*!< At this stage the microcontroller clock setting is already configured, 00061 this is done through SystemInit() function which is called from startup 00062 file (startup_stm32f0xx.s) before to branch to application main. 00063 To reconfigure the default setting of SystemInit() function, refer to 00064 system_stm32f0xx.c file 00065 */ 00066 00067 /* Configure LED3 */ 00068 STM_EVAL_LEDInit(LED3); 00069 00070 /* Configure Systick */ 00071 SysTick_Configuration(); 00072 00073 /* Turn ON LED3 */ 00074 STM_EVAL_LEDOn(LED3); 00075 00076 /* Configures Tamper button */ 00077 STM_EVAL_PBInit(BUTTON_TAMPER,BUTTON_MODE_GPIO); 00078 00079 /* Configure RTC clock source and prescaler */ 00080 RTC_Config(); 00081 00082 /* Wait till Tamper button is pressed */ 00083 while(STM_EVAL_PBGetState(BUTTON_TAMPER) != RESET); 00084 00085 /* Enter STANDBY mode, RTC Alarm within 3 second or an external RESET will 00086 wake-up the system from STANDBY */ 00087 EnterSTANDBYMode(); 00088 00089 while(1) 00090 {} 00091 } 00092 00093 /** 00094 * @brief Configures the RTC clock source. 00095 * @param None 00096 * @retval None 00097 */ 00098 static void RTC_Config(void) 00099 { 00100 RTC_InitTypeDef RTC_InitStructure; 00101 RTC_TimeTypeDef RTC_TimeStructure; 00102 uint32_t LSIFreq = 0; 00103 00104 /* Enable the PWR clock */ 00105 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 00106 00107 /* Allow access to Backup Domain */ 00108 PWR_BackupAccessCmd(ENABLE); 00109 00110 /* Disable wake-up source(ALARM) to guarantee free access to WUT level-OR input */ 00111 RTC_ITConfig(RTC_IT_ALRA, DISABLE); 00112 00113 /* Clear Wakeup flag */ 00114 PWR_ClearFlag(PWR_FLAG_WU); 00115 00116 /* Enable wake-up source(ALARM) to guarantee free access to WUT level-OR input */ 00117 RTC_ITConfig(RTC_IT_ALRA, ENABLE); 00118 00119 /* Enable the LSI OSC */ 00120 RCC_LSICmd(ENABLE); 00121 00122 /* Wait till LSI is ready */ 00123 while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) 00124 {} 00125 00126 /* Check if the StandBy flag is set */ 00127 if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) 00128 { 00129 /* Clear StandBy flag */ 00130 PWR_ClearFlag(PWR_FLAG_SB); 00131 00132 /* Check if the StandBy flag is cleared */ 00133 if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) 00134 { 00135 while(1); 00136 } 00137 00138 RTC_WaitForSynchro(); 00139 00140 /* No need to configure the RTC as the RTC config(clock source, enable, 00141 prescaler,...) are kept after wake-up from STANDBY */ 00142 } 00143 else 00144 { 00145 /* RTC Configuration ******************************************************/ 00146 /* Reset Backup Domain */ 00147 RCC_BackupResetCmd(ENABLE); 00148 RCC_BackupResetCmd(DISABLE); 00149 00150 /* Select the RTC Clock Source */ 00151 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); 00152 00153 /* Enable the RTC Clock */ 00154 RCC_RTCCLKCmd(ENABLE); 00155 00156 /* Wait for RTC APB registers synchronisation */ 00157 RTC_WaitForSynchro(); 00158 00159 /* Get the LSI frequency: TIM14 is used to measure the LSI frequency */ 00160 LSIFreq = GetLSIFrequency(); 00161 00162 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; 00163 RTC_InitStructure.RTC_AsynchPrediv = 99; 00164 RTC_InitStructure.RTC_SynchPrediv = (LSIFreq/100) - 1; 00165 00166 RTC_Init(&RTC_InitStructure); 00167 00168 /* Set the time to 01h 00mn 00s AM */ 00169 RTC_TimeStructure.RTC_H12 = RTC_H12_AM; 00170 RTC_TimeStructure.RTC_Hours = 0x01; 00171 RTC_TimeStructure.RTC_Minutes = 0x00; 00172 RTC_TimeStructure.RTC_Seconds = 0x00; 00173 00174 RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure); 00175 } 00176 } 00177 00178 /** 00179 * @brief Enters STANDBY mode, RTC Alarm within 3 second or an external RESET 00180 * will wake-up the system from STANDBY 00181 * @param None 00182 * @retval None 00183 */ 00184 static void EnterSTANDBYMode(void) 00185 { 00186 RTC_AlarmTypeDef RTC_AlarmStructure; 00187 RTC_TimeTypeDef RTC_TimeStructure; 00188 00189 /* Disable the Alarm A */ 00190 RTC_AlarmCmd(RTC_Alarm_A, DISABLE); 00191 00192 /* Get the current time */ 00193 RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); 00194 00195 /* Set the alarm to current time + 3s */ 00196 RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_TimeStructure.RTC_H12; 00197 RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = RTC_TimeStructure.RTC_Hours; 00198 RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = RTC_TimeStructure.RTC_Minutes; 00199 RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = (RTC_TimeStructure.RTC_Seconds + 0x3) % 60; 00200 RTC_AlarmStructure.RTC_AlarmDateWeekDay = 31; 00201 RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; 00202 RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes; 00203 RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure); 00204 00205 /* Enable RTC Alarm A Interrupt: this Interrupt will wake-up the system from 00206 STANDBY mode (RTC Alarm IT not enabled in NVIC) */ 00207 RTC_ITConfig(RTC_IT_ALRA, ENABLE); 00208 00209 /* Enable the Alarm A */ 00210 RTC_AlarmCmd(RTC_Alarm_A, ENABLE); 00211 00212 /* Clear RTC Alarm Flag */ 00213 RTC_ClearFlag(RTC_FLAG_ALRAF); 00214 00215 /* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */ 00216 PWR_EnterSTANDBYMode(); 00217 } 00218 00219 /** 00220 * @brief Configures TIM14 to measure the LSI oscillator frequency. 00221 * @param None 00222 * @retval LSI Frequency 00223 */ 00224 static uint32_t GetLSIFrequency(void) 00225 { 00226 NVIC_InitTypeDef NVIC_InitStructure; 00227 TIM_ICInitTypeDef TIM_ICInitStructure; 00228 RCC_ClocksTypeDef RCC_ClockFreq; 00229 00230 /* TIM14 configuration *******************************************************/ 00231 /* Enable TIM14 clock */ 00232 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); 00233 00234 /* Reset TIM14 registers */ 00235 TIM_DeInit(TIM14); 00236 00237 /* Configure TIM14 prescaler */ 00238 TIM_PrescalerConfig(TIM14, 0, TIM_PSCReloadMode_Immediate); 00239 00240 /* Connect internally the TIM14_CH1 to the RTC clock output */ 00241 TIM_RemapConfig(TIM14, TIM14_RTC_CLK); 00242 00243 /* TIM14 configuration: Input Capture mode --------------------- 00244 The reference clock(LSE or external) is connected to TIM14 CH1 00245 The Rising edge is used as active edge, 00246 The TIM14 CCR1 is used to compute the frequency value 00247 ------------------------------------------------------------ */ 00248 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 00249 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 00250 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 00251 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8; 00252 TIM_ICInitStructure.TIM_ICFilter = 0x0; 00253 TIM_ICInit(TIM14, &TIM_ICInitStructure); 00254 00255 /* Enable the TIM14 global Interrupt */ 00256 NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn; 00257 NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 00258 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 00259 NVIC_Init(&NVIC_InitStructure); 00260 00261 /* Enable TIM14 counter */ 00262 TIM_Cmd(TIM14, ENABLE); 00263 00264 /* Reset the flags */ 00265 TIM14->SR = 0; 00266 00267 /* Enable the CC1 Interrupt Request */ 00268 TIM_ITConfig(TIM14, TIM_IT_CC1, ENABLE); 00269 00270 00271 /* Wait until the TIM14 get 2 LSI edges (refer to TIM14_IRQHandler() in 00272 stm32F0xx_it.c file) ******************************************************/ 00273 while(CaptureNumber != 2) 00274 { 00275 } 00276 /* Deinitialize the TIM14 peripheral registers to their default reset values */ 00277 TIM_DeInit(TIM14); 00278 00279 00280 /* Compute the LSI frequency, depending on TIM14 input clock frequency (PCLK1)*/ 00281 /* Get SYSCLK, HCLK and PCLKx frequency */ 00282 RCC_GetClocksFreq(&RCC_ClockFreq); 00283 00284 /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */ 00285 return ((RCC_ClockFreq.PCLK_Frequency / PeriodValue) * 8); 00286 } 00287 00288 /** 00289 * @brief Configures the SysTick to generate an interrupt each 250 ms. 00290 * @param None 00291 * @retval None 00292 */ 00293 void SysTick_Configuration(void) 00294 { 00295 /* SysTick interrupt each 250 ms */ 00296 if (SysTick_Config((SystemCoreClock/8) / 4)) 00297 { 00298 /* Capture error */ 00299 while (1); 00300 } 00301 00302 /* Select AHB clock(HCLK) divided by 8 as SysTick clock source */ 00303 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 00304 00305 /* Set SysTick Preemption Priority to 1 */ 00306 NVIC_SetPriority(SysTick_IRQn, 0x04); 00307 } 00308 00309 #ifdef USE_FULL_ASSERT 00310 00311 /** 00312 * @brief Reports the name of the source file and the source line number 00313 * where the assert_param error has occurred. 00314 * @param file: pointer to the source file name 00315 * @param line: assert_param error line source number 00316 * @retval None 00317 */ 00318 void assert_failed(uint8_t* file, uint32_t line) 00319 { 00320 /* User can add his own implementation to report the file name and line number, 00321 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 00322 00323 /* Infinite loop */ 00324 while (1) 00325 { 00326 } 00327 } 00328 #endif 00329 00330 /** 00331 * @} 00332 */ 00333 00334 /** 00335 * @} 00336 */ 00337 00338 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/