This is a RTC additional function. This is only for Nucleo F401RE & F411RE mbed(Added L152RE, F334R8, L476RG & F746xx). If you connected battery backup circuit for internal RTC, you can make a power-off and reset condition. RTC still has proper time and date.
Dependents: Nucleo_rtos_sample PB_Emma_Ethernet
rtc_api_F334.c
00001 #if 0 00002 /* mbed Microcontroller Library 00003 ******************************************************************************* 00004 * Copyright (c) 2014, STMicroelectronics 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright notice, 00011 * this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00024 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00026 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00027 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 ******************************************************************************* 00030 */ 00031 #include "rtc_api.h" 00032 00033 #if DEVICE_RTC 00034 00035 #include "mbed_error.h" 00036 00037 #if DEVICE_RTC_LSI 00038 static int rtc_inited = 0; 00039 #endif 00040 00041 static RTC_HandleTypeDef RtcHandle; 00042 00043 //#define ORIGINAL 00044 #if defined(ORIGINAL) 00045 #warning "You cannot use SetRTC functions" 00046 #else 00047 #warning "You modified mbed-src rtc_api.c for SetRTC functions" 00048 #endif 00049 00050 #if defined(ORIGINAL) // modify part1 of 4 (Start) 00051 #else 00052 #define RTC_DAT0 0x55aa55aa 00053 #define RTC_DAT1 0xaa55aa55 00054 00055 uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) 00056 { 00057 __IO uint32_t tmp = 0; 00058 00059 // Check the parameters 00060 assert_param(IS_RTC_BKP(RTC_BKP_DR)); 00061 tmp = RTC_BASE + 0x50; 00062 tmp += (RTC_BKP_DR * 4); 00063 // Read the specified register 00064 return (*(__IO uint32_t *)tmp); 00065 } 00066 00067 /* Check RTC Backup registers contents */ 00068 uint32_t Check_Rtc_backup_reg( void ) 00069 { 00070 if ( RTC_ReadBackupRegister( RTC_BKP_DR0 ) == RTC_DAT0 ) { 00071 if ( RTC_ReadBackupRegister( RTC_BKP_DR1 ) == RTC_DAT1 ) { 00072 return 1; 00073 } 00074 } 00075 return 0; 00076 } 00077 00078 void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) 00079 { 00080 __IO uint32_t tmp = 0; 00081 00082 // Check the parameters/ 00083 assert_param(IS_RTC_BKP(RTC_BKP_DR)); 00084 tmp = RTC_BASE + 0x50; 00085 tmp += (RTC_BKP_DR * 4); 00086 // Write the specified register/ 00087 *(__IO uint32_t *)tmp = (uint32_t)Data; 00088 } 00089 #endif // modify part1 of 4 (End) 00090 00091 void rtc_init(void) 00092 { 00093 RCC_OscInitTypeDef RCC_OscInitStruct; 00094 uint32_t rtc_freq = 0; 00095 00096 #if DEVICE_RTC_LSI 00097 rtc_inited = 1; 00098 #endif 00099 00100 RtcHandle.Instance = RTC; 00101 00102 #if defined(ORIGINAL) // modify part2 of 4 (Start) 00103 #else 00104 RtcHandle.Instance = RTC; 00105 00106 // Enable Power clock 00107 __PWR_CLK_ENABLE(); 00108 00109 // Enable access to Backup domain 00110 HAL_PWR_EnableBkUpAccess(); 00111 00112 // Check backup condition 00113 if ( Check_Rtc_backup_reg() ) { 00114 return; 00115 } 00116 #endif // modify part2 of 4 (End) 00117 #if !DEVICE_RTC_LSI 00118 // Enable LSE Oscillator 00119 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; 00120 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ 00121 RCC_OscInitStruct.LSEState = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */ 00122 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { 00123 // Connect LSE to RTC 00124 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); 00125 rtc_freq = LSE_VALUE; 00126 } 00127 else { 00128 error("RTC error: LSE clock initialization failed."); 00129 } 00130 #else 00131 // Enable Power clock 00132 __PWR_CLK_ENABLE(); 00133 00134 // Enable access to Backup domain 00135 HAL_PWR_EnableBkUpAccess(); 00136 00137 // Reset Backup domain 00138 __HAL_RCC_BACKUPRESET_FORCE(); 00139 __HAL_RCC_BACKUPRESET_RELEASE(); 00140 00141 // Enable LSI clock 00142 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; 00143 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! 00144 RCC_OscInitStruct.LSEState = RCC_LSE_OFF; 00145 RCC_OscInitStruct.LSIState = RCC_LSI_ON; 00146 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 00147 error("RTC error: LSI clock initialization failed."); 00148 } 00149 // Connect LSI to RTC 00150 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI); 00151 // Note: The LSI clock can be measured precisely using a timer input capture. 00152 rtc_freq = LSI_VALUE; 00153 #endif 00154 00155 // Enable RTC 00156 __HAL_RCC_RTC_ENABLE(); 00157 00158 RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; 00159 RtcHandle.Init.AsynchPrediv = 127; 00160 RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1; 00161 RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; 00162 RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; 00163 RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; 00164 00165 #if defined(ORIGINAL) // modify part3 of 4 (Start) 00166 #else 00167 /* Write backup data into the backup RAM */ 00168 RTC_WriteBackupRegister( RTC_BKP_DR0, RTC_DAT0 ); 00169 RTC_WriteBackupRegister( RTC_BKP_DR1, RTC_DAT1 ); 00170 #endif // modify part3 of 4 (End) 00171 00172 if (HAL_RTC_Init(&RtcHandle) != HAL_OK) { 00173 error("RTC error: RTC initialization failed."); 00174 } 00175 } 00176 00177 void rtc_free(void) 00178 { 00179 #if DEVICE_RTC_LSI 00180 // Enable Power clock 00181 __PWR_CLK_ENABLE(); 00182 00183 // Enable access to Backup domain 00184 HAL_PWR_EnableBkUpAccess(); 00185 00186 // Reset Backup domain 00187 __HAL_RCC_BACKUPRESET_FORCE(); 00188 __HAL_RCC_BACKUPRESET_RELEASE(); 00189 00190 // Disable access to Backup domain 00191 HAL_PWR_DisableBkUpAccess(); 00192 #endif 00193 00194 // Disable LSI and LSE clocks 00195 RCC_OscInitTypeDef RCC_OscInitStruct; 00196 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; 00197 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 00198 RCC_OscInitStruct.LSIState = RCC_LSI_OFF; 00199 RCC_OscInitStruct.LSEState = RCC_LSE_OFF; 00200 HAL_RCC_OscConfig(&RCC_OscInitStruct); 00201 00202 #if DEVICE_RTC_LSI 00203 rtc_inited = 0; 00204 #endif 00205 } 00206 00207 int rtc_isenabled(void) 00208 { 00209 #if DEVICE_RTC_LSI 00210 return rtc_inited; 00211 #else 00212 #if defined(ORIGINAL) // modify part4 of 4 (Start) 00213 if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) return 1; 00214 else return 0; 00215 #else 00216 return Check_Rtc_backup_reg(); 00217 #endif // modify part4 of 4 (End) 00218 #endif 00219 } 00220 00221 /* 00222 RTC Registers 00223 RTC_WeekDay 1=monday, 2=tuesday, ..., 7=sunday 00224 RTC_Month 1=january, 2=february, ..., 12=december 00225 RTC_Date day of the month 1-31 00226 RTC_Year year 0-99 00227 struct tm 00228 tm_sec seconds after the minute 0-61 00229 tm_min minutes after the hour 0-59 00230 tm_hour hours since midnight 0-23 00231 tm_mday day of the month 1-31 00232 tm_mon months since January 0-11 00233 tm_year years since 1900 00234 tm_wday days since Sunday 0-6 00235 tm_yday days since January 1 0-365 00236 tm_isdst Daylight Saving Time flag 00237 */ 00238 time_t rtc_read(void) 00239 { 00240 RTC_DateTypeDef dateStruct; 00241 RTC_TimeTypeDef timeStruct; 00242 struct tm timeinfo; 00243 00244 RtcHandle.Instance = RTC; 00245 00246 // Read actual date and time 00247 // Warning: the time must be read first! 00248 HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN); 00249 HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN); 00250 00251 // Setup a tm structure based on the RTC 00252 timeinfo.tm_wday = dateStruct.WeekDay; 00253 timeinfo.tm_mon = dateStruct.Month - 1; 00254 timeinfo.tm_mday = dateStruct.Date; 00255 timeinfo.tm_year = dateStruct.Year + 100; 00256 timeinfo.tm_hour = timeStruct.Hours; 00257 timeinfo.tm_min = timeStruct.Minutes; 00258 timeinfo.tm_sec = timeStruct.Seconds; 00259 00260 // Convert to timestamp 00261 time_t t = mktime(&timeinfo); 00262 00263 return t; 00264 } 00265 00266 void rtc_write(time_t t) 00267 { 00268 RTC_DateTypeDef dateStruct; 00269 RTC_TimeTypeDef timeStruct; 00270 00271 RtcHandle.Instance = RTC; 00272 00273 // Convert the time into a tm 00274 struct tm *timeinfo = localtime(&t); 00275 00276 // Fill RTC structures 00277 dateStruct.WeekDay = timeinfo->tm_wday; 00278 dateStruct.Month = timeinfo->tm_mon + 1; 00279 dateStruct.Date = timeinfo->tm_mday; 00280 dateStruct.Year = timeinfo->tm_year - 100; 00281 timeStruct.Hours = timeinfo->tm_hour; 00282 timeStruct.Minutes = timeinfo->tm_min; 00283 timeStruct.Seconds = timeinfo->tm_sec; 00284 timeStruct.TimeFormat = RTC_HOURFORMAT12_PM; 00285 timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; 00286 timeStruct.StoreOperation = RTC_STOREOPERATION_RESET; 00287 00288 // Change the RTC current date/time 00289 HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN); 00290 HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN); 00291 } 00292 00293 #endif 00294 #endif
Generated on Tue Jul 12 2022 20:39:04 by 1.7.2