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_F4xx.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 // Enable Power clock 00105 __PWR_CLK_ENABLE(); 00106 00107 // Enable access to Backup domain 00108 HAL_PWR_EnableBkUpAccess(); 00109 00110 // Check backup condition 00111 if ( Check_Rtc_backup_reg() ) { 00112 return; 00113 } 00114 #endif // modify part2 of 4 (End) 00115 #if !DEVICE_RTC_LSI 00116 // Enable LSE Oscillator 00117 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; 00118 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ 00119 RCC_OscInitStruct.LSEState = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */ 00120 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { 00121 // Connect LSE to RTC 00122 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE); 00123 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); 00124 rtc_freq = LSE_VALUE; 00125 } 00126 else { 00127 error("RTC error: LSE clock initialization failed."); 00128 } 00129 #else 00130 // Enable Power clock 00131 __PWR_CLK_ENABLE(); 00132 00133 // Enable access to Backup domain 00134 HAL_PWR_EnableBkUpAccess(); 00135 00136 // Reset Backup domain 00137 __HAL_RCC_BACKUPRESET_FORCE(); 00138 __HAL_RCC_BACKUPRESET_RELEASE(); 00139 00140 // Enable LSI clock 00141 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; 00142 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! 00143 RCC_OscInitStruct.LSEState = RCC_LSE_OFF; 00144 RCC_OscInitStruct.LSIState = RCC_LSI_ON; 00145 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 00146 error("RTC error: LSI clock initialization failed."); 00147 } 00148 // Connect LSI to RTC 00149 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI); 00150 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI); 00151 // [TODO] This value is LSI typical value. To 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 #if DEVICE_RTC_LSI 00202 rtc_inited = 0; 00203 #endif 00204 } 00205 00206 int rtc_isenabled(void) 00207 { 00208 #if DEVICE_RTC_LSI 00209 return rtc_inited; 00210 #else 00211 #if defined(ORIGINAL) // modify part4 of 4 (Start) 00212 if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) return 1; 00213 else return 0; 00214 #else 00215 return Check_Rtc_backup_reg(); 00216 #endif // modify part4 of 4 (End) 00217 #endif 00218 } 00219 00220 /* 00221 RTC Registers 00222 RTC_WeekDay 1=monday, 2=tuesday, ..., 7=sunday 00223 RTC_Month 1=january, 2=february, ..., 12=december 00224 RTC_Date day of the month 1-31 00225 RTC_Year year 0-99 00226 struct tm 00227 tm_sec seconds after the minute 0-61 00228 tm_min minutes after the hour 0-59 00229 tm_hour hours since midnight 0-23 00230 tm_mday day of the month 1-31 00231 tm_mon months since January 0-11 00232 tm_year years since 1900 00233 tm_wday days since Sunday 0-6 00234 tm_yday days since January 1 0-365 00235 tm_isdst Daylight Saving Time flag 00236 */ 00237 time_t rtc_read(void) 00238 { 00239 RTC_DateTypeDef dateStruct; 00240 RTC_TimeTypeDef timeStruct; 00241 struct tm timeinfo; 00242 00243 RtcHandle.Instance = RTC; 00244 00245 // Read actual date and time 00246 // Warning: the time must be read first! 00247 HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN); 00248 HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN); 00249 00250 // Setup a tm structure based on the RTC 00251 timeinfo.tm_wday = dateStruct.WeekDay; 00252 timeinfo.tm_mon = dateStruct.Month - 1; 00253 timeinfo.tm_mday = dateStruct.Date; 00254 timeinfo.tm_year = dateStruct.Year + 100; 00255 timeinfo.tm_hour = timeStruct.Hours; 00256 timeinfo.tm_min = timeStruct.Minutes; 00257 timeinfo.tm_sec = timeStruct.Seconds; 00258 00259 // Convert to timestamp 00260 time_t t = mktime(&timeinfo); 00261 00262 return t; 00263 } 00264 00265 void rtc_write(time_t t) 00266 { 00267 RTC_DateTypeDef dateStruct; 00268 RTC_TimeTypeDef timeStruct; 00269 00270 RtcHandle.Instance = RTC; 00271 00272 // Convert the time into a tm 00273 struct tm *timeinfo = localtime(&t); 00274 00275 // Fill RTC structures 00276 dateStruct.WeekDay = timeinfo->tm_wday; 00277 dateStruct.Month = timeinfo->tm_mon + 1; 00278 dateStruct.Date = timeinfo->tm_mday; 00279 dateStruct.Year = timeinfo->tm_year - 100; 00280 timeStruct.Hours = timeinfo->tm_hour; 00281 timeStruct.Minutes = timeinfo->tm_min; 00282 timeStruct.Seconds = timeinfo->tm_sec; 00283 timeStruct.TimeFormat = RTC_HOURFORMAT12_PM; 00284 timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; 00285 timeStruct.StoreOperation = RTC_STOREOPERATION_RESET; 00286 00287 // Change the RTC current date/time 00288 HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN); 00289 HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN); 00290 } 00291 00292 #endif 00293 #endif 00294
Generated on Tue Jul 12 2022 20:39:04 by 1.7.2