mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Thu Sep 06 13:40:20 2018 +0100
Revision:
187:0387e8f68319
Parent:
186:707f6e361f3e
Child:
188:bcfe06ba3d64
mbed-dev library. Release version 163

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 154:37f96f9d4de2 1 /* mbed Microcontroller Library
<> 154:37f96f9d4de2 2 *******************************************************************************
Anna Bridge 186:707f6e361f3e 3 * Copyright (c) 2018, STMicroelectronics
<> 154:37f96f9d4de2 4 * All rights reserved.
<> 154:37f96f9d4de2 5 *
<> 154:37f96f9d4de2 6 * Redistribution and use in source and binary forms, with or without
<> 154:37f96f9d4de2 7 * modification, are permitted provided that the following conditions are met:
<> 154:37f96f9d4de2 8 *
<> 154:37f96f9d4de2 9 * 1. Redistributions of source code must retain the above copyright notice,
<> 154:37f96f9d4de2 10 * this list of conditions and the following disclaimer.
<> 154:37f96f9d4de2 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
<> 154:37f96f9d4de2 12 * this list of conditions and the following disclaimer in the documentation
<> 154:37f96f9d4de2 13 * and/or other materials provided with the distribution.
<> 154:37f96f9d4de2 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
<> 154:37f96f9d4de2 15 * may be used to endorse or promote products derived from this software
<> 154:37f96f9d4de2 16 * without specific prior written permission.
<> 154:37f96f9d4de2 17 *
<> 154:37f96f9d4de2 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 154:37f96f9d4de2 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 154:37f96f9d4de2 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 154:37f96f9d4de2 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 154:37f96f9d4de2 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 154:37f96f9d4de2 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 154:37f96f9d4de2 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 154:37f96f9d4de2 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 154:37f96f9d4de2 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 154:37f96f9d4de2 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 154:37f96f9d4de2 28 *******************************************************************************
<> 154:37f96f9d4de2 29 */
Anna Bridge 180:96ed750bd169 30
<> 154:37f96f9d4de2 31 #if DEVICE_RTC
<> 154:37f96f9d4de2 32
<> 154:37f96f9d4de2 33 #include "rtc_api_hal.h"
AnnaBridge 167:e84263d55307 34 #include "mbed_mktime.h"
Anna Bridge 186:707f6e361f3e 35 #include "mbed_error.h"
AnnaBridge 187:0387e8f68319 36 #include "mbed_critical.h"
AnnaBridge 187:0387e8f68319 37
AnnaBridge 187:0387e8f68319 38 #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
AnnaBridge 187:0387e8f68319 39 volatile uint32_t LP_continuous_time = 0;
AnnaBridge 187:0387e8f68319 40 volatile uint32_t LP_last_RTC_time = 0;
AnnaBridge 187:0387e8f68319 41 #endif
AnnaBridge 187:0387e8f68319 42
AnnaBridge 187:0387e8f68319 43 static int RTC_inited = 0;
<> 154:37f96f9d4de2 44
<> 154:37f96f9d4de2 45 static RTC_HandleTypeDef RtcHandle;
<> 154:37f96f9d4de2 46
<> 154:37f96f9d4de2 47 void rtc_init(void)
<> 154:37f96f9d4de2 48 {
AnnaBridge 176:447f873cad2f 49 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
AnnaBridge 176:447f873cad2f 50 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
<> 154:37f96f9d4de2 51
AnnaBridge 187:0387e8f68319 52 if (RTC_inited) {
AnnaBridge 187:0387e8f68319 53 return;
AnnaBridge 187:0387e8f68319 54 }
AnnaBridge 187:0387e8f68319 55 RTC_inited = 1;
AnnaBridge 187:0387e8f68319 56
<> 154:37f96f9d4de2 57 // Enable access to Backup domain
Anna Bridge 180:96ed750bd169 58 __HAL_RCC_PWR_CLK_ENABLE();
<> 154:37f96f9d4de2 59 HAL_PWR_EnableBkUpAccess();
<> 154:37f96f9d4de2 60
Anna Bridge 180:96ed750bd169 61 #if MBED_CONF_TARGET_LSE_AVAILABLE
AnnaBridge 184:08ed48f1de7f 62 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
<> 154:37f96f9d4de2 63 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
<> 154:37f96f9d4de2 64 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
<> 154:37f96f9d4de2 65
Anna Bridge 180:96ed750bd169 66 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
<> 154:37f96f9d4de2 67 error("Cannot initialize RTC with LSE\n");
<> 154:37f96f9d4de2 68 }
<> 154:37f96f9d4de2 69
Anna Bridge 180:96ed750bd169 70 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
Anna Bridge 180:96ed750bd169 71 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
Anna Bridge 180:96ed750bd169 72
<> 154:37f96f9d4de2 73 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
<> 154:37f96f9d4de2 74 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
<> 154:37f96f9d4de2 75 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
<> 154:37f96f9d4de2 76 error("PeriphClkInitStruct RTC failed with LSE\n");
<> 154:37f96f9d4de2 77 }
Anna Bridge 180:96ed750bd169 78 #else /* MBED_CONF_TARGET_LSE_AVAILABLE */
<> 154:37f96f9d4de2 79 // Reset Backup domain
<> 154:37f96f9d4de2 80 __HAL_RCC_BACKUPRESET_FORCE();
<> 154:37f96f9d4de2 81 __HAL_RCC_BACKUPRESET_RELEASE();
<> 154:37f96f9d4de2 82
<> 154:37f96f9d4de2 83 // Enable LSI clock
AnnaBridge 184:08ed48f1de7f 84 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
<> 154:37f96f9d4de2 85 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
<> 154:37f96f9d4de2 86 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
<> 154:37f96f9d4de2 87 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
<> 154:37f96f9d4de2 88 error("Cannot initialize RTC with LSI\n");
<> 154:37f96f9d4de2 89 }
<> 154:37f96f9d4de2 90
<> 154:37f96f9d4de2 91 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
<> 154:37f96f9d4de2 92 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
<> 154:37f96f9d4de2 93
<> 154:37f96f9d4de2 94 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
<> 154:37f96f9d4de2 95 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
<> 154:37f96f9d4de2 96 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
<> 154:37f96f9d4de2 97 error("PeriphClkInitStruct RTC failed with LSI\n");
<> 154:37f96f9d4de2 98 }
Anna Bridge 180:96ed750bd169 99 #endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
<> 154:37f96f9d4de2 100
<> 154:37f96f9d4de2 101 // Enable RTC
<> 154:37f96f9d4de2 102 __HAL_RCC_RTC_ENABLE();
<> 154:37f96f9d4de2 103
Anna Bridge 180:96ed750bd169 104 RtcHandle.Instance = RTC;
Anna Bridge 180:96ed750bd169 105 RtcHandle.State = HAL_RTC_STATE_RESET;
Anna Bridge 180:96ed750bd169 106
<> 154:37f96f9d4de2 107 #if TARGET_STM32F1
<> 154:37f96f9d4de2 108 RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
<> 154:37f96f9d4de2 109 #else /* TARGET_STM32F1 */
<> 154:37f96f9d4de2 110 RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
Anna Bridge 186:707f6e361f3e 111 RtcHandle.Init.AsynchPrediv = PREDIV_A_VALUE;
Anna Bridge 186:707f6e361f3e 112 RtcHandle.Init.SynchPrediv = PREDIV_S_VALUE;
<> 154:37f96f9d4de2 113 RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
<> 154:37f96f9d4de2 114 RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
<> 154:37f96f9d4de2 115 RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
<> 154:37f96f9d4de2 116 #endif /* TARGET_STM32F1 */
<> 154:37f96f9d4de2 117
<> 154:37f96f9d4de2 118 if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
Anna Bridge 180:96ed750bd169 119 error("RTC initialization failed");
<> 154:37f96f9d4de2 120 }
<> 154:37f96f9d4de2 121
AnnaBridge 187:0387e8f68319 122 #if !(TARGET_STM32F1) && !(TARGET_STM32F2)
AnnaBridge 187:0387e8f68319 123 /* STM32F1 : there are no shadow registers */
AnnaBridge 187:0387e8f68319 124 /* STM32F2 : shadow registers can not be bypassed */
AnnaBridge 187:0387e8f68319 125 if (HAL_RTCEx_EnableBypassShadow(&RtcHandle) != HAL_OK) {
AnnaBridge 187:0387e8f68319 126 error("EnableBypassShadow error");
<> 154:37f96f9d4de2 127 }
AnnaBridge 187:0387e8f68319 128 #endif /* TARGET_STM32F1 || TARGET_STM32F2 */
<> 154:37f96f9d4de2 129 }
<> 154:37f96f9d4de2 130
<> 154:37f96f9d4de2 131 void rtc_free(void)
<> 154:37f96f9d4de2 132 {
AnnaBridge 187:0387e8f68319 133 /* RTC clock can not be reset */
<> 154:37f96f9d4de2 134 }
<> 154:37f96f9d4de2 135
<> 160:d5399cc887bb 136
<> 160:d5399cc887bb 137 /*
<> 160:d5399cc887bb 138 Information about STM32F0, STM32F2, STM32F3, STM32F4, STM32F7, STM32L0, STM32L1, STM32L4:
<> 160:d5399cc887bb 139 BCD format is used to store the date in the RTC. The year is store on 2 * 4 bits.
<> 160:d5399cc887bb 140 Because the first year is reserved to see if the RTC is init, the supposed range is 01-99.
<> 160:d5399cc887bb 141 1st point is to cover the standard range from 1970 to 2038 (limited by the 32 bits of time_t).
<> 160:d5399cc887bb 142 2nd point is to keep the year 1970 and the leap years synchronized.
<> 160:d5399cc887bb 143
<> 160:d5399cc887bb 144 So by moving it 68 years forward from 1970, it become 1969-2067 which include 1970-2038.
<> 160:d5399cc887bb 145 68 is also a multiple of 4 so it let the leap year synchronized.
<> 160:d5399cc887bb 146
<> 160:d5399cc887bb 147 Information about STM32F1:
AnnaBridge 182:a56a73fd2a6f 148 32bit register is used (no BCD format) for the seconds.
AnnaBridge 182:a56a73fd2a6f 149 For date, there is no specific register, only a software structure.
<> 160:d5399cc887bb 150 It is then not a problem to not use shifts.
<> 160:d5399cc887bb 151 */
AnnaBridge 187:0387e8f68319 152 #if TARGET_STM32F1
<> 154:37f96f9d4de2 153 time_t rtc_read(void)
<> 154:37f96f9d4de2 154 {
AnnaBridge 176:447f873cad2f 155 RTC_DateTypeDef dateStruct = {0};
AnnaBridge 176:447f873cad2f 156 RTC_TimeTypeDef timeStruct = {0};
<> 154:37f96f9d4de2 157 struct tm timeinfo;
<> 154:37f96f9d4de2 158
<> 154:37f96f9d4de2 159 RtcHandle.Instance = RTC;
<> 154:37f96f9d4de2 160
<> 154:37f96f9d4de2 161 // Read actual date and time
<> 154:37f96f9d4de2 162 // Warning: the time must be read first!
<> 160:d5399cc887bb 163 HAL_RTC_GetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN);
<> 160:d5399cc887bb 164 HAL_RTC_GetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN);
<> 154:37f96f9d4de2 165
AnnaBridge 182:a56a73fd2a6f 166 /* date information is null before first write procedure */
AnnaBridge 182:a56a73fd2a6f 167 /* set 01/01/1970 as default values */
AnnaBridge 182:a56a73fd2a6f 168 if (dateStruct.Year == 0) {
AnnaBridge 182:a56a73fd2a6f 169 dateStruct.Year = 2 ;
AnnaBridge 182:a56a73fd2a6f 170 dateStruct.Month = 1 ;
AnnaBridge 182:a56a73fd2a6f 171 dateStruct.Date = 1 ;
AnnaBridge 182:a56a73fd2a6f 172 }
AnnaBridge 182:a56a73fd2a6f 173
<> 154:37f96f9d4de2 174 // Setup a tm structure based on the RTC
AnnaBridge 182:a56a73fd2a6f 175 /* tm_wday information is ignored by _rtc_maketime */
AnnaBridge 182:a56a73fd2a6f 176 /* tm_isdst information is ignored by _rtc_maketime */
<> 154:37f96f9d4de2 177 timeinfo.tm_mon = dateStruct.Month - 1;
<> 154:37f96f9d4de2 178 timeinfo.tm_mday = dateStruct.Date;
<> 154:37f96f9d4de2 179 timeinfo.tm_year = dateStruct.Year + 68;
<> 154:37f96f9d4de2 180 timeinfo.tm_hour = timeStruct.Hours;
<> 154:37f96f9d4de2 181 timeinfo.tm_min = timeStruct.Minutes;
<> 154:37f96f9d4de2 182 timeinfo.tm_sec = timeStruct.Seconds;
<> 154:37f96f9d4de2 183
<> 154:37f96f9d4de2 184 // Convert to timestamp
AnnaBridge 184:08ed48f1de7f 185 time_t t;
AnnaBridge 184:08ed48f1de7f 186 if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
AnnaBridge 184:08ed48f1de7f 187 return 0;
AnnaBridge 184:08ed48f1de7f 188 }
<> 154:37f96f9d4de2 189
<> 154:37f96f9d4de2 190 return t;
<> 154:37f96f9d4de2 191 }
<> 154:37f96f9d4de2 192
AnnaBridge 187:0387e8f68319 193 #else /* TARGET_STM32F1 */
AnnaBridge 187:0387e8f68319 194
AnnaBridge 187:0387e8f68319 195 time_t rtc_read(void)
AnnaBridge 187:0387e8f68319 196 {
AnnaBridge 187:0387e8f68319 197 struct tm timeinfo;
AnnaBridge 187:0387e8f68319 198
AnnaBridge 187:0387e8f68319 199 /* Since the shadow registers are bypassed we have to read the time twice and compare them until both times are the same */
AnnaBridge 187:0387e8f68319 200 uint32_t Read_time = RTC->TR & RTC_TR_RESERVED_MASK;
AnnaBridge 187:0387e8f68319 201 uint32_t Read_date = RTC->DR & RTC_DR_RESERVED_MASK;
AnnaBridge 187:0387e8f68319 202
AnnaBridge 187:0387e8f68319 203 while ((Read_time != (RTC->TR & RTC_TR_RESERVED_MASK)) || (Read_date != (RTC->DR & RTC_DR_RESERVED_MASK))) {
AnnaBridge 187:0387e8f68319 204 Read_time = RTC->TR & RTC_TR_RESERVED_MASK;
AnnaBridge 187:0387e8f68319 205 Read_date = RTC->DR & RTC_DR_RESERVED_MASK;
AnnaBridge 187:0387e8f68319 206 }
AnnaBridge 187:0387e8f68319 207
AnnaBridge 187:0387e8f68319 208 /* Setup a tm structure based on the RTC
AnnaBridge 187:0387e8f68319 209 struct tm :
AnnaBridge 187:0387e8f68319 210 tm_sec seconds after the minute 0-61
AnnaBridge 187:0387e8f68319 211 tm_min minutes after the hour 0-59
AnnaBridge 187:0387e8f68319 212 tm_hour hours since midnight 0-23
AnnaBridge 187:0387e8f68319 213 tm_mday day of the month 1-31
AnnaBridge 187:0387e8f68319 214 tm_mon months since January 0-11
AnnaBridge 187:0387e8f68319 215 tm_year years since 1900
AnnaBridge 187:0387e8f68319 216 tm_yday information is ignored by _rtc_maketime
AnnaBridge 187:0387e8f68319 217 tm_wday information is ignored by _rtc_maketime
AnnaBridge 187:0387e8f68319 218 tm_isdst information is ignored by _rtc_maketime
AnnaBridge 187:0387e8f68319 219 */
AnnaBridge 187:0387e8f68319 220 timeinfo.tm_mday = RTC_Bcd2ToByte((uint8_t)(Read_date & (RTC_DR_DT | RTC_DR_DU)));
AnnaBridge 187:0387e8f68319 221 timeinfo.tm_mon = RTC_Bcd2ToByte((uint8_t)((Read_date & (RTC_DR_MT | RTC_DR_MU)) >> 8)) - 1;
AnnaBridge 187:0387e8f68319 222 timeinfo.tm_year = RTC_Bcd2ToByte((uint8_t)((Read_date & (RTC_DR_YT | RTC_DR_YU)) >> 16)) + 68;
AnnaBridge 187:0387e8f68319 223 timeinfo.tm_hour = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_HT | RTC_TR_HU)) >> 16));
AnnaBridge 187:0387e8f68319 224 timeinfo.tm_min = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_MNT | RTC_TR_MNU)) >> 8));
AnnaBridge 187:0387e8f68319 225 timeinfo.tm_sec = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_ST | RTC_TR_SU)) >> 0));
AnnaBridge 187:0387e8f68319 226
AnnaBridge 187:0387e8f68319 227 // Convert to timestamp
AnnaBridge 187:0387e8f68319 228 time_t t;
AnnaBridge 187:0387e8f68319 229 if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
AnnaBridge 187:0387e8f68319 230 return 0;
AnnaBridge 187:0387e8f68319 231 }
AnnaBridge 187:0387e8f68319 232
AnnaBridge 187:0387e8f68319 233 return t;
AnnaBridge 187:0387e8f68319 234 }
AnnaBridge 187:0387e8f68319 235
AnnaBridge 187:0387e8f68319 236 #endif /* TARGET_STM32F1 */
AnnaBridge 187:0387e8f68319 237
<> 154:37f96f9d4de2 238 void rtc_write(time_t t)
<> 154:37f96f9d4de2 239 {
AnnaBridge 176:447f873cad2f 240 RTC_DateTypeDef dateStruct = {0};
AnnaBridge 176:447f873cad2f 241 RTC_TimeTypeDef timeStruct = {0};
<> 154:37f96f9d4de2 242
AnnaBridge 187:0387e8f68319 243 core_util_critical_section_enter();
<> 154:37f96f9d4de2 244 RtcHandle.Instance = RTC;
<> 154:37f96f9d4de2 245
<> 154:37f96f9d4de2 246 // Convert the time into a tm
AnnaBridge 167:e84263d55307 247 struct tm timeinfo;
AnnaBridge 184:08ed48f1de7f 248 if (_rtc_localtime(t, &timeinfo, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
AnnaBridge 167:e84263d55307 249 return;
AnnaBridge 167:e84263d55307 250 }
<> 154:37f96f9d4de2 251
<> 154:37f96f9d4de2 252 // Fill RTC structures
AnnaBridge 187:0387e8f68319 253 if (timeinfo.tm_wday == 0) { /* Sunday specific case */
AnnaBridge 187:0387e8f68319 254 dateStruct.WeekDay = RTC_WEEKDAY_SUNDAY;
<> 160:d5399cc887bb 255 } else {
AnnaBridge 167:e84263d55307 256 dateStruct.WeekDay = timeinfo.tm_wday;
<> 160:d5399cc887bb 257 }
AnnaBridge 167:e84263d55307 258 dateStruct.Month = timeinfo.tm_mon + 1;
AnnaBridge 167:e84263d55307 259 dateStruct.Date = timeinfo.tm_mday;
AnnaBridge 167:e84263d55307 260 dateStruct.Year = timeinfo.tm_year - 68;
AnnaBridge 167:e84263d55307 261 timeStruct.Hours = timeinfo.tm_hour;
AnnaBridge 167:e84263d55307 262 timeStruct.Minutes = timeinfo.tm_min;
AnnaBridge 167:e84263d55307 263 timeStruct.Seconds = timeinfo.tm_sec;
<> 154:37f96f9d4de2 264
<> 154:37f96f9d4de2 265 #if !(TARGET_STM32F1)
<> 154:37f96f9d4de2 266 timeStruct.TimeFormat = RTC_HOURFORMAT_24;
<> 154:37f96f9d4de2 267 timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
<> 154:37f96f9d4de2 268 timeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
<> 154:37f96f9d4de2 269 #endif /* TARGET_STM32F1 */
<> 154:37f96f9d4de2 270
AnnaBridge 187:0387e8f68319 271 #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
AnnaBridge 187:0387e8f68319 272 /* Need to update LP_continuous_time value before new RTC time */
AnnaBridge 187:0387e8f68319 273 rtc_read_lp();
AnnaBridge 187:0387e8f68319 274
AnnaBridge 187:0387e8f68319 275 /* LP_last_RTC_time value is updated with the new RTC time */
AnnaBridge 187:0387e8f68319 276 LP_last_RTC_time = timeStruct.Seconds + timeStruct.Minutes * 60 + timeStruct.Hours * 60 * 60;
AnnaBridge 187:0387e8f68319 277
AnnaBridge 187:0387e8f68319 278 /* Save current SSR */
AnnaBridge 187:0387e8f68319 279 uint32_t Read_SubSeconds = (uint32_t)(RTC->SSR);
AnnaBridge 187:0387e8f68319 280 #endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
AnnaBridge 187:0387e8f68319 281
<> 154:37f96f9d4de2 282 // Change the RTC current date/time
Anna Bridge 180:96ed750bd169 283 if (HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN) != HAL_OK) {
Anna Bridge 180:96ed750bd169 284 error("HAL_RTC_SetDate error\n");
Anna Bridge 180:96ed750bd169 285 }
Anna Bridge 180:96ed750bd169 286 if (HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN) != HAL_OK) {
Anna Bridge 180:96ed750bd169 287 error("HAL_RTC_SetTime error\n");
Anna Bridge 180:96ed750bd169 288 }
AnnaBridge 187:0387e8f68319 289
AnnaBridge 187:0387e8f68319 290 #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
AnnaBridge 187:0387e8f68319 291 while (Read_SubSeconds != (RTC->SSR)) {
AnnaBridge 187:0387e8f68319 292 }
AnnaBridge 187:0387e8f68319 293 #endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
AnnaBridge 187:0387e8f68319 294
AnnaBridge 187:0387e8f68319 295 core_util_critical_section_exit();
<> 154:37f96f9d4de2 296 }
<> 154:37f96f9d4de2 297
<> 154:37f96f9d4de2 298 int rtc_isenabled(void)
<> 154:37f96f9d4de2 299 {
<> 160:d5399cc887bb 300 #if !(TARGET_STM32F1)
AnnaBridge 187:0387e8f68319 301 return ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS);
<> 160:d5399cc887bb 302 #else /* TARGET_STM32F1 */
<> 160:d5399cc887bb 303 return ((RTC->CRL & RTC_CRL_RSF) == RTC_CRL_RSF);
<> 160:d5399cc887bb 304 #endif /* TARGET_STM32F1 */
<> 154:37f96f9d4de2 305 }
<> 154:37f96f9d4de2 306
Anna Bridge 180:96ed750bd169 307
Anna Bridge 186:707f6e361f3e 308 #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
Anna Bridge 186:707f6e361f3e 309
Anna Bridge 186:707f6e361f3e 310 static void RTC_IRQHandler(void);
Anna Bridge 186:707f6e361f3e 311 static void (*irq_handler)(void);
Anna Bridge 186:707f6e361f3e 312
Anna Bridge 186:707f6e361f3e 313 volatile uint8_t lp_Fired = 0;
<> 154:37f96f9d4de2 314
<> 154:37f96f9d4de2 315 static void RTC_IRQHandler(void)
<> 154:37f96f9d4de2 316 {
AnnaBridge 176:447f873cad2f 317 /* Update HAL state */
Anna Bridge 180:96ed750bd169 318 RtcHandle.Instance = RTC;
AnnaBridge 187:0387e8f68319 319 if (__HAL_RTC_WAKEUPTIMER_GET_IT(&RtcHandle, RTC_IT_WUT)) {
Anna Bridge 186:707f6e361f3e 320 /* Get the status of the Interrupt */
AnnaBridge 187:0387e8f68319 321 if ((uint32_t)(RTC->CR & RTC_IT_WUT) != (uint32_t)RESET) {
Anna Bridge 186:707f6e361f3e 322 /* Clear the WAKEUPTIMER interrupt pending bit */
Anna Bridge 186:707f6e361f3e 323 __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF);
Anna Bridge 186:707f6e361f3e 324
Anna Bridge 186:707f6e361f3e 325 lp_Fired = 0;
Anna Bridge 186:707f6e361f3e 326 if (irq_handler) {
Anna Bridge 186:707f6e361f3e 327 irq_handler();
Anna Bridge 186:707f6e361f3e 328 }
Anna Bridge 186:707f6e361f3e 329 }
<> 154:37f96f9d4de2 330 }
Anna Bridge 186:707f6e361f3e 331
Anna Bridge 186:707f6e361f3e 332 if (lp_Fired) {
Anna Bridge 186:707f6e361f3e 333 lp_Fired = 0;
Anna Bridge 186:707f6e361f3e 334 if (irq_handler) {
Anna Bridge 186:707f6e361f3e 335 irq_handler();
Anna Bridge 186:707f6e361f3e 336 }
Anna Bridge 186:707f6e361f3e 337 }
Anna Bridge 186:707f6e361f3e 338
Anna Bridge 186:707f6e361f3e 339 __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
<> 154:37f96f9d4de2 340 }
<> 154:37f96f9d4de2 341
Anna Bridge 186:707f6e361f3e 342 uint32_t rtc_read_lp(void)
<> 154:37f96f9d4de2 343 {
AnnaBridge 187:0387e8f68319 344 struct tm timeinfo;
AnnaBridge 181:57724642e740 345
AnnaBridge 187:0387e8f68319 346 /* Since the shadow registers are bypassed we have to read the time twice and compare them until both times are the same */
AnnaBridge 187:0387e8f68319 347 /* We don't have to read date as we bypass shadow registers */
AnnaBridge 187:0387e8f68319 348 uint32_t Read_SecondFraction = (uint32_t)(RTC->PRER & RTC_PRER_PREDIV_S);
AnnaBridge 187:0387e8f68319 349 uint32_t Read_time = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
AnnaBridge 187:0387e8f68319 350 uint32_t Read_SubSeconds = (uint32_t)(RTC->SSR);
AnnaBridge 181:57724642e740 351
AnnaBridge 187:0387e8f68319 352 while ((Read_time != (RTC->TR & RTC_TR_RESERVED_MASK)) || (Read_SubSeconds != (RTC->SSR))) {
AnnaBridge 187:0387e8f68319 353 Read_time = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
AnnaBridge 187:0387e8f68319 354 Read_SubSeconds = (uint32_t)(RTC->SSR);
AnnaBridge 187:0387e8f68319 355 }
AnnaBridge 181:57724642e740 356
AnnaBridge 187:0387e8f68319 357 timeinfo.tm_hour = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_HT | RTC_TR_HU)) >> 16));
AnnaBridge 187:0387e8f68319 358 timeinfo.tm_min = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_MNT | RTC_TR_MNU)) >> 8));
AnnaBridge 187:0387e8f68319 359 timeinfo.tm_sec = RTC_Bcd2ToByte((uint8_t)((Read_time & (RTC_TR_ST | RTC_TR_SU)) >> 0));
AnnaBridge 187:0387e8f68319 360
AnnaBridge 187:0387e8f68319 361 uint32_t RTC_time_s = timeinfo.tm_sec + timeinfo.tm_min * 60 + timeinfo.tm_hour * 60 * 60; // Max 0x0001-517F => * 8191 + 8191 = 0x2A2E-AE80
AnnaBridge 181:57724642e740 362
Anna Bridge 186:707f6e361f3e 363 if (LP_last_RTC_time <= RTC_time_s) {
Anna Bridge 186:707f6e361f3e 364 LP_continuous_time += (RTC_time_s - LP_last_RTC_time);
Anna Bridge 186:707f6e361f3e 365 } else {
AnnaBridge 187:0387e8f68319 366 /* Add 24h */
Anna Bridge 186:707f6e361f3e 367 LP_continuous_time += (24 * 60 * 60 + RTC_time_s - LP_last_RTC_time);
Anna Bridge 186:707f6e361f3e 368 }
Anna Bridge 186:707f6e361f3e 369 LP_last_RTC_time = RTC_time_s;
Anna Bridge 186:707f6e361f3e 370
AnnaBridge 187:0387e8f68319 371 return LP_continuous_time * PREDIV_S_VALUE + Read_SecondFraction - Read_SubSeconds;
<> 154:37f96f9d4de2 372 }
<> 154:37f96f9d4de2 373
Anna Bridge 186:707f6e361f3e 374 void rtc_set_wake_up_timer(timestamp_t timestamp)
<> 154:37f96f9d4de2 375 {
Anna Bridge 186:707f6e361f3e 376 uint32_t WakeUpCounter;
Anna Bridge 186:707f6e361f3e 377 uint32_t current_lp_time;
AnnaBridge 184:08ed48f1de7f 378
Anna Bridge 186:707f6e361f3e 379 current_lp_time = rtc_read_lp();
AnnaBridge 184:08ed48f1de7f 380
Anna Bridge 186:707f6e361f3e 381 if (timestamp < current_lp_time) {
Anna Bridge 186:707f6e361f3e 382 WakeUpCounter = 0xFFFFFFFF - current_lp_time + timestamp;
AnnaBridge 184:08ed48f1de7f 383 } else {
Anna Bridge 186:707f6e361f3e 384 WakeUpCounter = timestamp - current_lp_time;
Anna Bridge 186:707f6e361f3e 385 }
Anna Bridge 186:707f6e361f3e 386
Anna Bridge 186:707f6e361f3e 387 if (WakeUpCounter > 0xFFFF) {
Anna Bridge 186:707f6e361f3e 388 WakeUpCounter = 0xFFFF;
Anna Bridge 180:96ed750bd169 389 }
Anna Bridge 180:96ed750bd169 390
Anna Bridge 180:96ed750bd169 391 RtcHandle.Instance = RTC;
Anna Bridge 186:707f6e361f3e 392 if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, WakeUpCounter, RTC_WAKEUPCLOCK_RTCCLK_DIV4) != HAL_OK) {
AnnaBridge 184:08ed48f1de7f 393 error("rtc_set_wake_up_timer init error\n");
<> 154:37f96f9d4de2 394 }
Anna Bridge 186:707f6e361f3e 395
Anna Bridge 186:707f6e361f3e 396 NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler);
Anna Bridge 186:707f6e361f3e 397 irq_handler = (void (*)(void))lp_ticker_irq_handler;
Anna Bridge 186:707f6e361f3e 398 NVIC_EnableIRQ(RTC_WKUP_IRQn);
Anna Bridge 186:707f6e361f3e 399 }
Anna Bridge 186:707f6e361f3e 400
Anna Bridge 186:707f6e361f3e 401 void rtc_fire_interrupt(void)
Anna Bridge 186:707f6e361f3e 402 {
Anna Bridge 186:707f6e361f3e 403 lp_Fired = 1;
Anna Bridge 186:707f6e361f3e 404 NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler);
Anna Bridge 186:707f6e361f3e 405 irq_handler = (void (*)(void))lp_ticker_irq_handler;
Anna Bridge 186:707f6e361f3e 406 NVIC_SetPendingIRQ(RTC_WKUP_IRQn);
Anna Bridge 186:707f6e361f3e 407 NVIC_EnableIRQ(RTC_WKUP_IRQn);
<> 154:37f96f9d4de2 408 }
<> 154:37f96f9d4de2 409
<> 154:37f96f9d4de2 410 void rtc_deactivate_wake_up_timer(void)
<> 154:37f96f9d4de2 411 {
Anna Bridge 180:96ed750bd169 412 RtcHandle.Instance = RTC;
AnnaBridge 187:0387e8f68319 413 __HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);
AnnaBridge 187:0387e8f68319 414 __HAL_RTC_WAKEUPTIMER_DISABLE(&RtcHandle);
AnnaBridge 187:0387e8f68319 415 __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&RtcHandle, RTC_IT_WUT);
AnnaBridge 187:0387e8f68319 416 __HAL_RTC_WRITEPROTECTION_ENABLE(&RtcHandle);
AnnaBridge 187:0387e8f68319 417 NVIC_DisableIRQ(RTC_WKUP_IRQn);
<> 154:37f96f9d4de2 418 }
<> 154:37f96f9d4de2 419
Anna Bridge 186:707f6e361f3e 420 #endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
<> 154:37f96f9d4de2 421
<> 154:37f96f9d4de2 422 #endif /* DEVICE_RTC */