Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /* mbed Microcontroller Library
marcozecchini 0:9fca2b23d0ba 2 *******************************************************************************
marcozecchini 0:9fca2b23d0ba 3 * Copyright (c) 2016, STMicroelectronics
marcozecchini 0:9fca2b23d0ba 4 * All rights reserved.
marcozecchini 0:9fca2b23d0ba 5 *
marcozecchini 0:9fca2b23d0ba 6 * Redistribution and use in source and binary forms, with or without
marcozecchini 0:9fca2b23d0ba 7 * modification, are permitted provided that the following conditions are met:
marcozecchini 0:9fca2b23d0ba 8 *
marcozecchini 0:9fca2b23d0ba 9 * 1. Redistributions of source code must retain the above copyright notice,
marcozecchini 0:9fca2b23d0ba 10 * this list of conditions and the following disclaimer.
marcozecchini 0:9fca2b23d0ba 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
marcozecchini 0:9fca2b23d0ba 12 * this list of conditions and the following disclaimer in the documentation
marcozecchini 0:9fca2b23d0ba 13 * and/or other materials provided with the distribution.
marcozecchini 0:9fca2b23d0ba 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
marcozecchini 0:9fca2b23d0ba 15 * may be used to endorse or promote products derived from this software
marcozecchini 0:9fca2b23d0ba 16 * without specific prior written permission.
marcozecchini 0:9fca2b23d0ba 17 *
marcozecchini 0:9fca2b23d0ba 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
marcozecchini 0:9fca2b23d0ba 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
marcozecchini 0:9fca2b23d0ba 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
marcozecchini 0:9fca2b23d0ba 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
marcozecchini 0:9fca2b23d0ba 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
marcozecchini 0:9fca2b23d0ba 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
marcozecchini 0:9fca2b23d0ba 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
marcozecchini 0:9fca2b23d0ba 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
marcozecchini 0:9fca2b23d0ba 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
marcozecchini 0:9fca2b23d0ba 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
marcozecchini 0:9fca2b23d0ba 28 *******************************************************************************
marcozecchini 0:9fca2b23d0ba 29 */
marcozecchini 0:9fca2b23d0ba 30 #if DEVICE_RTC
marcozecchini 0:9fca2b23d0ba 31
marcozecchini 0:9fca2b23d0ba 32 #include "rtc_api.h"
marcozecchini 0:9fca2b23d0ba 33 #include "rtc_api_hal.h"
marcozecchini 0:9fca2b23d0ba 34 #include "mbed_error.h"
marcozecchini 0:9fca2b23d0ba 35 #include "mbed_mktime.h"
marcozecchini 0:9fca2b23d0ba 36
marcozecchini 0:9fca2b23d0ba 37 static RTC_HandleTypeDef RtcHandle;
marcozecchini 0:9fca2b23d0ba 38
marcozecchini 0:9fca2b23d0ba 39 #if RTC_LSI
marcozecchini 0:9fca2b23d0ba 40 #define RTC_CLOCK LSI_VALUE
marcozecchini 0:9fca2b23d0ba 41 #else
marcozecchini 0:9fca2b23d0ba 42 #define RTC_CLOCK LSE_VALUE
marcozecchini 0:9fca2b23d0ba 43 #endif
marcozecchini 0:9fca2b23d0ba 44
marcozecchini 0:9fca2b23d0ba 45 #if DEVICE_LOWPOWERTIMER
marcozecchini 0:9fca2b23d0ba 46 #define RTC_ASYNCH_PREDIV ((RTC_CLOCK - 1) / 0x8000)
marcozecchini 0:9fca2b23d0ba 47 #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
marcozecchini 0:9fca2b23d0ba 48 #else
marcozecchini 0:9fca2b23d0ba 49 #define RTC_ASYNCH_PREDIV (0x007F)
marcozecchini 0:9fca2b23d0ba 50 #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
marcozecchini 0:9fca2b23d0ba 51 #endif
marcozecchini 0:9fca2b23d0ba 52
marcozecchini 0:9fca2b23d0ba 53 #if DEVICE_LOWPOWERTIMER
marcozecchini 0:9fca2b23d0ba 54 static void (*irq_handler)(void);
marcozecchini 0:9fca2b23d0ba 55 static void RTC_IRQHandler(void);
marcozecchini 0:9fca2b23d0ba 56 #endif
marcozecchini 0:9fca2b23d0ba 57
marcozecchini 0:9fca2b23d0ba 58 void rtc_init(void)
marcozecchini 0:9fca2b23d0ba 59 {
marcozecchini 0:9fca2b23d0ba 60 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
marcozecchini 0:9fca2b23d0ba 61 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
marcozecchini 0:9fca2b23d0ba 62
marcozecchini 0:9fca2b23d0ba 63 // Enable access to Backup domain
marcozecchini 0:9fca2b23d0ba 64 HAL_PWR_EnableBkUpAccess();
marcozecchini 0:9fca2b23d0ba 65
marcozecchini 0:9fca2b23d0ba 66 RtcHandle.Instance = RTC;
marcozecchini 0:9fca2b23d0ba 67 RtcHandle.State = HAL_RTC_STATE_RESET;
marcozecchini 0:9fca2b23d0ba 68
marcozecchini 0:9fca2b23d0ba 69 #if !RTC_LSI
marcozecchini 0:9fca2b23d0ba 70 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
marcozecchini 0:9fca2b23d0ba 71 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
marcozecchini 0:9fca2b23d0ba 72 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
marcozecchini 0:9fca2b23d0ba 73 RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
marcozecchini 0:9fca2b23d0ba 74
marcozecchini 0:9fca2b23d0ba 75 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) {
marcozecchini 0:9fca2b23d0ba 76 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
marcozecchini 0:9fca2b23d0ba 77 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
marcozecchini 0:9fca2b23d0ba 78 } else {
marcozecchini 0:9fca2b23d0ba 79 error("Cannot initialize RTC with LSE\n");
marcozecchini 0:9fca2b23d0ba 80 }
marcozecchini 0:9fca2b23d0ba 81
marcozecchini 0:9fca2b23d0ba 82 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
marcozecchini 0:9fca2b23d0ba 83 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
marcozecchini 0:9fca2b23d0ba 84 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
marcozecchini 0:9fca2b23d0ba 85 error("PeriphClkInitStruct RTC failed with LSE\n");
marcozecchini 0:9fca2b23d0ba 86 }
marcozecchini 0:9fca2b23d0ba 87 #else /* !RTC_LSI */
marcozecchini 0:9fca2b23d0ba 88 __HAL_RCC_PWR_CLK_ENABLE();
marcozecchini 0:9fca2b23d0ba 89
marcozecchini 0:9fca2b23d0ba 90 // Reset Backup domain
marcozecchini 0:9fca2b23d0ba 91 __HAL_RCC_BACKUPRESET_FORCE();
marcozecchini 0:9fca2b23d0ba 92 __HAL_RCC_BACKUPRESET_RELEASE();
marcozecchini 0:9fca2b23d0ba 93
marcozecchini 0:9fca2b23d0ba 94 // Enable LSI clock
marcozecchini 0:9fca2b23d0ba 95 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
marcozecchini 0:9fca2b23d0ba 96 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
marcozecchini 0:9fca2b23d0ba 97 RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
marcozecchini 0:9fca2b23d0ba 98 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
marcozecchini 0:9fca2b23d0ba 99 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
marcozecchini 0:9fca2b23d0ba 100 error("Cannot initialize RTC with LSI\n");
marcozecchini 0:9fca2b23d0ba 101 }
marcozecchini 0:9fca2b23d0ba 102
marcozecchini 0:9fca2b23d0ba 103 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
marcozecchini 0:9fca2b23d0ba 104 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
marcozecchini 0:9fca2b23d0ba 105
marcozecchini 0:9fca2b23d0ba 106 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
marcozecchini 0:9fca2b23d0ba 107 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
marcozecchini 0:9fca2b23d0ba 108 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
marcozecchini 0:9fca2b23d0ba 109 error("PeriphClkInitStruct RTC failed with LSI\n");
marcozecchini 0:9fca2b23d0ba 110 }
marcozecchini 0:9fca2b23d0ba 111 #endif /* !RTC_LSI */
marcozecchini 0:9fca2b23d0ba 112
marcozecchini 0:9fca2b23d0ba 113 // Enable RTC
marcozecchini 0:9fca2b23d0ba 114 __HAL_RCC_RTC_ENABLE();
marcozecchini 0:9fca2b23d0ba 115
marcozecchini 0:9fca2b23d0ba 116 #if TARGET_STM32F1
marcozecchini 0:9fca2b23d0ba 117 RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
marcozecchini 0:9fca2b23d0ba 118 #else /* TARGET_STM32F1 */
marcozecchini 0:9fca2b23d0ba 119 RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
marcozecchini 0:9fca2b23d0ba 120 RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
marcozecchini 0:9fca2b23d0ba 121 RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
marcozecchini 0:9fca2b23d0ba 122 RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
marcozecchini 0:9fca2b23d0ba 123 RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
marcozecchini 0:9fca2b23d0ba 124 RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
marcozecchini 0:9fca2b23d0ba 125 #endif /* TARGET_STM32F1 */
marcozecchini 0:9fca2b23d0ba 126
marcozecchini 0:9fca2b23d0ba 127 if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
marcozecchini 0:9fca2b23d0ba 128 error("RTC error: RTC initialization failed.");
marcozecchini 0:9fca2b23d0ba 129 }
marcozecchini 0:9fca2b23d0ba 130
marcozecchini 0:9fca2b23d0ba 131 #if DEVICE_LOWPOWERTIMER
marcozecchini 0:9fca2b23d0ba 132
marcozecchini 0:9fca2b23d0ba 133 #if !RTC_LSI
marcozecchini 0:9fca2b23d0ba 134 if (!rtc_isenabled())
marcozecchini 0:9fca2b23d0ba 135 #endif /* !RTC_LSI */
marcozecchini 0:9fca2b23d0ba 136 {
marcozecchini 0:9fca2b23d0ba 137 rtc_write(0);
marcozecchini 0:9fca2b23d0ba 138 }
marcozecchini 0:9fca2b23d0ba 139
marcozecchini 0:9fca2b23d0ba 140 NVIC_ClearPendingIRQ(RTC_WKUP_IRQn);
marcozecchini 0:9fca2b23d0ba 141 NVIC_DisableIRQ(RTC_WKUP_IRQn);
marcozecchini 0:9fca2b23d0ba 142 NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler);
marcozecchini 0:9fca2b23d0ba 143 NVIC_EnableIRQ(RTC_WKUP_IRQn);
marcozecchini 0:9fca2b23d0ba 144
marcozecchini 0:9fca2b23d0ba 145 #endif /* DEVICE_LOWPOWERTIMER */
marcozecchini 0:9fca2b23d0ba 146 }
marcozecchini 0:9fca2b23d0ba 147
marcozecchini 0:9fca2b23d0ba 148 void rtc_free(void)
marcozecchini 0:9fca2b23d0ba 149 {
marcozecchini 0:9fca2b23d0ba 150 #if RTC_LSI
marcozecchini 0:9fca2b23d0ba 151 // Enable Power clock
marcozecchini 0:9fca2b23d0ba 152 __HAL_RCC_PWR_CLK_ENABLE();
marcozecchini 0:9fca2b23d0ba 153
marcozecchini 0:9fca2b23d0ba 154 // Enable access to Backup domain
marcozecchini 0:9fca2b23d0ba 155 HAL_PWR_EnableBkUpAccess();
marcozecchini 0:9fca2b23d0ba 156
marcozecchini 0:9fca2b23d0ba 157 // Reset Backup domain
marcozecchini 0:9fca2b23d0ba 158 __HAL_RCC_BACKUPRESET_FORCE();
marcozecchini 0:9fca2b23d0ba 159 __HAL_RCC_BACKUPRESET_RELEASE();
marcozecchini 0:9fca2b23d0ba 160
marcozecchini 0:9fca2b23d0ba 161 // Disable access to Backup domain
marcozecchini 0:9fca2b23d0ba 162 HAL_PWR_DisableBkUpAccess();
marcozecchini 0:9fca2b23d0ba 163 #endif
marcozecchini 0:9fca2b23d0ba 164
marcozecchini 0:9fca2b23d0ba 165 // Disable LSI and LSE clocks
marcozecchini 0:9fca2b23d0ba 166 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
marcozecchini 0:9fca2b23d0ba 167 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
marcozecchini 0:9fca2b23d0ba 168 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
marcozecchini 0:9fca2b23d0ba 169 RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
marcozecchini 0:9fca2b23d0ba 170 RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
marcozecchini 0:9fca2b23d0ba 171 HAL_RCC_OscConfig(&RCC_OscInitStruct);
marcozecchini 0:9fca2b23d0ba 172 }
marcozecchini 0:9fca2b23d0ba 173
marcozecchini 0:9fca2b23d0ba 174 /*
marcozecchini 0:9fca2b23d0ba 175 ST RTC_DateTypeDef structure
marcozecchini 0:9fca2b23d0ba 176 WeekDay 1=monday, 2=tuesday, ..., 7=sunday
marcozecchini 0:9fca2b23d0ba 177 Month 0x1=january, 0x2=february, ..., 0x12=december
marcozecchini 0:9fca2b23d0ba 178 Date day of the month 1-31
marcozecchini 0:9fca2b23d0ba 179 Year year 0-99
marcozecchini 0:9fca2b23d0ba 180
marcozecchini 0:9fca2b23d0ba 181 ST RTC_TimeTypeDef structure
marcozecchini 0:9fca2b23d0ba 182 Hours 0-12 if the RTC_HourFormat_12 is selected during init
marcozecchini 0:9fca2b23d0ba 183 0-23 if the RTC_HourFormat_24 is selected during init
marcozecchini 0:9fca2b23d0ba 184 Minutes 0-59
marcozecchini 0:9fca2b23d0ba 185 Seconds 0-59
marcozecchini 0:9fca2b23d0ba 186 TimeFormat RTC_HOURFORMAT12_AM/RTC_HOURFORMAT12_PM
marcozecchini 0:9fca2b23d0ba 187 SubSeconds time unit range between [0-1] Second with [1 Sec / SecondFraction +1] granularity
marcozecchini 0:9fca2b23d0ba 188 SecondFraction range or granularity of Sub Second register content corresponding to Synchronous pre-scaler factor value (PREDIV_S)
marcozecchini 0:9fca2b23d0ba 189 DayLightSaving RTC_DAYLIGHTSAVING_SUB1H/RTC_DAYLIGHTSAVING_ADD1H/RTC_DAYLIGHTSAVING_NONE
marcozecchini 0:9fca2b23d0ba 190 StoreOperation RTC_STOREOPERATION_RESET/RTC_STOREOPERATION_SET
marcozecchini 0:9fca2b23d0ba 191
marcozecchini 0:9fca2b23d0ba 192 struct tm
marcozecchini 0:9fca2b23d0ba 193 tm_sec seconds after the minute 0-61
marcozecchini 0:9fca2b23d0ba 194 tm_min minutes after the hour 0-59
marcozecchini 0:9fca2b23d0ba 195 tm_hour hours since midnight 0-23
marcozecchini 0:9fca2b23d0ba 196 tm_mday day of the month 1-31
marcozecchini 0:9fca2b23d0ba 197 tm_mon months since January 0-11
marcozecchini 0:9fca2b23d0ba 198 tm_year years since 1900
marcozecchini 0:9fca2b23d0ba 199 tm_wday days since Sunday 0-6
marcozecchini 0:9fca2b23d0ba 200 tm_yday days since January 1 0-365
marcozecchini 0:9fca2b23d0ba 201 tm_isdst Daylight Saving Time flag
marcozecchini 0:9fca2b23d0ba 202 */
marcozecchini 0:9fca2b23d0ba 203
marcozecchini 0:9fca2b23d0ba 204 /*
marcozecchini 0:9fca2b23d0ba 205 Information about STM32F0, STM32F2, STM32F3, STM32F4, STM32F7, STM32L0, STM32L1, STM32L4:
marcozecchini 0:9fca2b23d0ba 206 BCD format is used to store the date in the RTC. The year is store on 2 * 4 bits.
marcozecchini 0:9fca2b23d0ba 207 Because the first year is reserved to see if the RTC is init, the supposed range is 01-99.
marcozecchini 0:9fca2b23d0ba 208 1st point is to cover the standard range from 1970 to 2038 (limited by the 32 bits of time_t).
marcozecchini 0:9fca2b23d0ba 209 2nd point is to keep the year 1970 and the leap years synchronized.
marcozecchini 0:9fca2b23d0ba 210
marcozecchini 0:9fca2b23d0ba 211 So by moving it 68 years forward from 1970, it become 1969-2067 which include 1970-2038.
marcozecchini 0:9fca2b23d0ba 212 68 is also a multiple of 4 so it let the leap year synchronized.
marcozecchini 0:9fca2b23d0ba 213
marcozecchini 0:9fca2b23d0ba 214 Information about STM32F1:
marcozecchini 0:9fca2b23d0ba 215 32bit register is used (no BCD format) for the seconds and a software structure to store dates.
marcozecchini 0:9fca2b23d0ba 216 It is then not a problem to not use shifts.
marcozecchini 0:9fca2b23d0ba 217 */
marcozecchini 0:9fca2b23d0ba 218
marcozecchini 0:9fca2b23d0ba 219 time_t rtc_read(void)
marcozecchini 0:9fca2b23d0ba 220 {
marcozecchini 0:9fca2b23d0ba 221 RTC_DateTypeDef dateStruct = {0};
marcozecchini 0:9fca2b23d0ba 222 RTC_TimeTypeDef timeStruct = {0};
marcozecchini 0:9fca2b23d0ba 223 struct tm timeinfo;
marcozecchini 0:9fca2b23d0ba 224
marcozecchini 0:9fca2b23d0ba 225 RtcHandle.Instance = RTC;
marcozecchini 0:9fca2b23d0ba 226
marcozecchini 0:9fca2b23d0ba 227 // Read actual date and time
marcozecchini 0:9fca2b23d0ba 228 // Warning: the time must be read first!
marcozecchini 0:9fca2b23d0ba 229 HAL_RTC_GetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN);
marcozecchini 0:9fca2b23d0ba 230 HAL_RTC_GetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN);
marcozecchini 0:9fca2b23d0ba 231
marcozecchini 0:9fca2b23d0ba 232 // Setup a tm structure based on the RTC
marcozecchini 0:9fca2b23d0ba 233 /* tm_wday information is ignored by mktime */
marcozecchini 0:9fca2b23d0ba 234 timeinfo.tm_mon = dateStruct.Month - 1;
marcozecchini 0:9fca2b23d0ba 235 timeinfo.tm_mday = dateStruct.Date;
marcozecchini 0:9fca2b23d0ba 236 timeinfo.tm_year = dateStruct.Year + 68;
marcozecchini 0:9fca2b23d0ba 237 timeinfo.tm_hour = timeStruct.Hours;
marcozecchini 0:9fca2b23d0ba 238 timeinfo.tm_min = timeStruct.Minutes;
marcozecchini 0:9fca2b23d0ba 239 timeinfo.tm_sec = timeStruct.Seconds;
marcozecchini 0:9fca2b23d0ba 240 // Daylight Saving Time information is not available
marcozecchini 0:9fca2b23d0ba 241 timeinfo.tm_isdst = -1;
marcozecchini 0:9fca2b23d0ba 242
marcozecchini 0:9fca2b23d0ba 243 // Convert to timestamp
marcozecchini 0:9fca2b23d0ba 244 time_t t = _rtc_mktime(&timeinfo);
marcozecchini 0:9fca2b23d0ba 245
marcozecchini 0:9fca2b23d0ba 246 return t;
marcozecchini 0:9fca2b23d0ba 247 }
marcozecchini 0:9fca2b23d0ba 248
marcozecchini 0:9fca2b23d0ba 249 void rtc_write(time_t t)
marcozecchini 0:9fca2b23d0ba 250 {
marcozecchini 0:9fca2b23d0ba 251 RTC_DateTypeDef dateStruct = {0};
marcozecchini 0:9fca2b23d0ba 252 RTC_TimeTypeDef timeStruct = {0};
marcozecchini 0:9fca2b23d0ba 253
marcozecchini 0:9fca2b23d0ba 254 RtcHandle.Instance = RTC;
marcozecchini 0:9fca2b23d0ba 255
marcozecchini 0:9fca2b23d0ba 256 // Convert the time into a tm
marcozecchini 0:9fca2b23d0ba 257 struct tm timeinfo;
marcozecchini 0:9fca2b23d0ba 258 if (_rtc_localtime(t, &timeinfo) == false) {
marcozecchini 0:9fca2b23d0ba 259 return;
marcozecchini 0:9fca2b23d0ba 260 }
marcozecchini 0:9fca2b23d0ba 261
marcozecchini 0:9fca2b23d0ba 262 // Fill RTC structures
marcozecchini 0:9fca2b23d0ba 263 if (timeinfo.tm_wday == 0) {
marcozecchini 0:9fca2b23d0ba 264 dateStruct.WeekDay = 7;
marcozecchini 0:9fca2b23d0ba 265 } else {
marcozecchini 0:9fca2b23d0ba 266 dateStruct.WeekDay = timeinfo.tm_wday;
marcozecchini 0:9fca2b23d0ba 267 }
marcozecchini 0:9fca2b23d0ba 268 dateStruct.Month = timeinfo.tm_mon + 1;
marcozecchini 0:9fca2b23d0ba 269 dateStruct.Date = timeinfo.tm_mday;
marcozecchini 0:9fca2b23d0ba 270 dateStruct.Year = timeinfo.tm_year - 68;
marcozecchini 0:9fca2b23d0ba 271 timeStruct.Hours = timeinfo.tm_hour;
marcozecchini 0:9fca2b23d0ba 272 timeStruct.Minutes = timeinfo.tm_min;
marcozecchini 0:9fca2b23d0ba 273 timeStruct.Seconds = timeinfo.tm_sec;
marcozecchini 0:9fca2b23d0ba 274
marcozecchini 0:9fca2b23d0ba 275 #if !(TARGET_STM32F1)
marcozecchini 0:9fca2b23d0ba 276 timeStruct.TimeFormat = RTC_HOURFORMAT_24;
marcozecchini 0:9fca2b23d0ba 277 timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
marcozecchini 0:9fca2b23d0ba 278 timeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
marcozecchini 0:9fca2b23d0ba 279 #endif /* TARGET_STM32F1 */
marcozecchini 0:9fca2b23d0ba 280
marcozecchini 0:9fca2b23d0ba 281 // Change the RTC current date/time
marcozecchini 0:9fca2b23d0ba 282 HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN);
marcozecchini 0:9fca2b23d0ba 283 HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN);
marcozecchini 0:9fca2b23d0ba 284 }
marcozecchini 0:9fca2b23d0ba 285
marcozecchini 0:9fca2b23d0ba 286 int rtc_isenabled(void)
marcozecchini 0:9fca2b23d0ba 287 {
marcozecchini 0:9fca2b23d0ba 288 #if !(TARGET_STM32F1)
marcozecchini 0:9fca2b23d0ba 289 return ( ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) && ((RTC->ISR & RTC_ISR_RSF) == RTC_ISR_RSF) );
marcozecchini 0:9fca2b23d0ba 290 #else /* TARGET_STM32F1 */
marcozecchini 0:9fca2b23d0ba 291 return ((RTC->CRL & RTC_CRL_RSF) == RTC_CRL_RSF);
marcozecchini 0:9fca2b23d0ba 292 #endif /* TARGET_STM32F1 */
marcozecchini 0:9fca2b23d0ba 293 }
marcozecchini 0:9fca2b23d0ba 294
marcozecchini 0:9fca2b23d0ba 295 #if DEVICE_LOWPOWERTIMER
marcozecchini 0:9fca2b23d0ba 296
marcozecchini 0:9fca2b23d0ba 297 static void RTC_IRQHandler(void)
marcozecchini 0:9fca2b23d0ba 298 {
marcozecchini 0:9fca2b23d0ba 299 /* Update HAL state */
marcozecchini 0:9fca2b23d0ba 300 HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle);
marcozecchini 0:9fca2b23d0ba 301 /* In case of registered handler, call it. */
marcozecchini 0:9fca2b23d0ba 302 if (irq_handler) {
marcozecchini 0:9fca2b23d0ba 303 irq_handler();
marcozecchini 0:9fca2b23d0ba 304 }
marcozecchini 0:9fca2b23d0ba 305 }
marcozecchini 0:9fca2b23d0ba 306
marcozecchini 0:9fca2b23d0ba 307 void rtc_set_irq_handler(uint32_t handler)
marcozecchini 0:9fca2b23d0ba 308 {
marcozecchini 0:9fca2b23d0ba 309 irq_handler = (void (*)(void))handler;
marcozecchini 0:9fca2b23d0ba 310 }
marcozecchini 0:9fca2b23d0ba 311
marcozecchini 0:9fca2b23d0ba 312 uint32_t rtc_read_subseconds(void)
marcozecchini 0:9fca2b23d0ba 313 {
marcozecchini 0:9fca2b23d0ba 314 return 1000000.f * ((double)(RTC_SYNCH_PREDIV - RTC->SSR) / (RTC_SYNCH_PREDIV + 1));
marcozecchini 0:9fca2b23d0ba 315 }
marcozecchini 0:9fca2b23d0ba 316
marcozecchini 0:9fca2b23d0ba 317 void rtc_set_wake_up_timer(uint32_t delta)
marcozecchini 0:9fca2b23d0ba 318 {
marcozecchini 0:9fca2b23d0ba 319 uint32_t wake_up_counter = delta / (2000000 / RTC_CLOCK);
marcozecchini 0:9fca2b23d0ba 320
marcozecchini 0:9fca2b23d0ba 321 if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, wake_up_counter,
marcozecchini 0:9fca2b23d0ba 322 RTC_WAKEUPCLOCK_RTCCLK_DIV2) != HAL_OK) {
marcozecchini 0:9fca2b23d0ba 323 error("Set wake up timer failed\n");
marcozecchini 0:9fca2b23d0ba 324 }
marcozecchini 0:9fca2b23d0ba 325 }
marcozecchini 0:9fca2b23d0ba 326
marcozecchini 0:9fca2b23d0ba 327 void rtc_deactivate_wake_up_timer(void)
marcozecchini 0:9fca2b23d0ba 328 {
marcozecchini 0:9fca2b23d0ba 329 HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle);
marcozecchini 0:9fca2b23d0ba 330 }
marcozecchini 0:9fca2b23d0ba 331
marcozecchini 0:9fca2b23d0ba 332 void rtc_synchronize(void)
marcozecchini 0:9fca2b23d0ba 333 {
marcozecchini 0:9fca2b23d0ba 334 HAL_RTC_WaitForSynchro(&RtcHandle);
marcozecchini 0:9fca2b23d0ba 335 }
marcozecchini 0:9fca2b23d0ba 336 #endif /* DEVICE_LOWPOWERTIMER */
marcozecchini 0:9fca2b23d0ba 337
marcozecchini 0:9fca2b23d0ba 338 #endif /* DEVICE_RTC */