mbed library sources. Supersedes mbed-src. Fixed broken STM32F1xx RTC on rtc_api.c

Dependents:   Nucleo_F103RB_RTC_battery_bkup_pwr_off_okay

Fork of mbed-dev by mbed official

Committer:
maxxir
Date:
Tue Nov 07 16:46:29 2017 +0000
Revision:
177:619788de047e
Parent:
176:447f873cad2f
To fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..;  Used direct RTC register manipulation for STM32F1xx;  rtc_read() && rtc_write()  (native rtc_init() - works good);  also added stub for non-working on STM32F1xx rtc_read_subseconds().

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 172:7d866c31b3c5 1 /* mbed Microcontroller Library
AnnaBridge 172:7d866c31b3c5 2 * Copyright (c) 2015-2016 Nuvoton
AnnaBridge 172:7d866c31b3c5 3 *
AnnaBridge 172:7d866c31b3c5 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 172:7d866c31b3c5 5 * you may not use this file except in compliance with the License.
AnnaBridge 172:7d866c31b3c5 6 * You may obtain a copy of the License at
AnnaBridge 172:7d866c31b3c5 7 *
AnnaBridge 172:7d866c31b3c5 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 172:7d866c31b3c5 9 *
AnnaBridge 172:7d866c31b3c5 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 172:7d866c31b3c5 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 172:7d866c31b3c5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 172:7d866c31b3c5 13 * See the License for the specific language governing permissions and
AnnaBridge 172:7d866c31b3c5 14 * limitations under the License.
AnnaBridge 172:7d866c31b3c5 15 */
AnnaBridge 172:7d866c31b3c5 16
AnnaBridge 172:7d866c31b3c5 17 #include "rtc_api.h"
AnnaBridge 172:7d866c31b3c5 18
AnnaBridge 172:7d866c31b3c5 19 #if DEVICE_RTC
AnnaBridge 172:7d866c31b3c5 20
AnnaBridge 172:7d866c31b3c5 21 #include "mbed_wait_api.h"
AnnaBridge 172:7d866c31b3c5 22 #include "mbed_error.h"
AnnaBridge 172:7d866c31b3c5 23 #include "nu_modutil.h"
AnnaBridge 172:7d866c31b3c5 24 #include "nu_miscutil.h"
AnnaBridge 176:447f873cad2f 25 #include "mbed_mktime.h"
AnnaBridge 172:7d866c31b3c5 26
AnnaBridge 172:7d866c31b3c5 27 #define YEAR0 1900
AnnaBridge 172:7d866c31b3c5 28 //#define EPOCH_YR 1970
AnnaBridge 172:7d866c31b3c5 29
AnnaBridge 172:7d866c31b3c5 30 static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, 0, 0, 0, RTC_IRQn, NULL};
AnnaBridge 172:7d866c31b3c5 31
AnnaBridge 172:7d866c31b3c5 32 void rtc_init(void)
AnnaBridge 172:7d866c31b3c5 33 {
AnnaBridge 172:7d866c31b3c5 34 if (rtc_isenabled()) {
AnnaBridge 172:7d866c31b3c5 35 return;
AnnaBridge 172:7d866c31b3c5 36 }
AnnaBridge 172:7d866c31b3c5 37
AnnaBridge 172:7d866c31b3c5 38 RTC_Open(NULL);
AnnaBridge 172:7d866c31b3c5 39 }
AnnaBridge 172:7d866c31b3c5 40
AnnaBridge 172:7d866c31b3c5 41 void rtc_free(void)
AnnaBridge 172:7d866c31b3c5 42 {
AnnaBridge 172:7d866c31b3c5 43 // N/A
AnnaBridge 172:7d866c31b3c5 44 }
AnnaBridge 172:7d866c31b3c5 45
AnnaBridge 172:7d866c31b3c5 46 int rtc_isenabled(void)
AnnaBridge 172:7d866c31b3c5 47 {
AnnaBridge 172:7d866c31b3c5 48 // NOTE: To access (RTC) registers, clock must be enabled first.
AnnaBridge 172:7d866c31b3c5 49 if (! (CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk)) {
AnnaBridge 172:7d866c31b3c5 50 // Enable IP clock
AnnaBridge 172:7d866c31b3c5 51 CLK_EnableModuleClock(rtc_modinit.clkidx);
AnnaBridge 172:7d866c31b3c5 52 }
AnnaBridge 172:7d866c31b3c5 53
AnnaBridge 172:7d866c31b3c5 54 // NOTE: Check RTC Init Active flag to support crossing reset cycle.
AnnaBridge 172:7d866c31b3c5 55 return !! (RTC->INIT & RTC_INIT_ACTIVE_Msk);
AnnaBridge 172:7d866c31b3c5 56 }
AnnaBridge 172:7d866c31b3c5 57
AnnaBridge 172:7d866c31b3c5 58 /*
AnnaBridge 172:7d866c31b3c5 59 struct tm
AnnaBridge 172:7d866c31b3c5 60 tm_sec seconds after the minute 0-61
AnnaBridge 172:7d866c31b3c5 61 tm_min minutes after the hour 0-59
AnnaBridge 172:7d866c31b3c5 62 tm_hour hours since midnight 0-23
AnnaBridge 172:7d866c31b3c5 63 tm_mday day of the month 1-31
AnnaBridge 172:7d866c31b3c5 64 tm_mon months since January 0-11
AnnaBridge 172:7d866c31b3c5 65 tm_year years since 1900
AnnaBridge 172:7d866c31b3c5 66 tm_wday days since Sunday 0-6
AnnaBridge 172:7d866c31b3c5 67 tm_yday days since January 1 0-365
AnnaBridge 172:7d866c31b3c5 68 tm_isdst Daylight Saving Time flag
AnnaBridge 172:7d866c31b3c5 69 */
AnnaBridge 172:7d866c31b3c5 70
AnnaBridge 172:7d866c31b3c5 71 time_t rtc_read(void)
AnnaBridge 172:7d866c31b3c5 72 {
AnnaBridge 172:7d866c31b3c5 73 // NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency.
AnnaBridge 172:7d866c31b3c5 74 // RTC time got (through RTC_GetDateAndTime()) in this sec would be last-synced and incorrect.
AnnaBridge 172:7d866c31b3c5 75 // NUC472/M453: Known issue
AnnaBridge 172:7d866c31b3c5 76 // M487: Fixed
AnnaBridge 172:7d866c31b3c5 77 if (! rtc_isenabled()) {
AnnaBridge 172:7d866c31b3c5 78 rtc_init();
AnnaBridge 172:7d866c31b3c5 79 }
AnnaBridge 172:7d866c31b3c5 80
AnnaBridge 172:7d866c31b3c5 81 S_RTC_TIME_DATA_T rtc_datetime;
AnnaBridge 172:7d866c31b3c5 82 RTC_GetDateAndTime(&rtc_datetime);
AnnaBridge 172:7d866c31b3c5 83
AnnaBridge 172:7d866c31b3c5 84 struct tm timeinfo;
AnnaBridge 172:7d866c31b3c5 85
AnnaBridge 172:7d866c31b3c5 86 // Convert struct tm to S_RTC_TIME_DATA_T
AnnaBridge 172:7d866c31b3c5 87 timeinfo.tm_year = rtc_datetime.u32Year - YEAR0;
AnnaBridge 172:7d866c31b3c5 88 timeinfo.tm_mon = rtc_datetime.u32Month - 1;
AnnaBridge 172:7d866c31b3c5 89 timeinfo.tm_mday = rtc_datetime.u32Day;
AnnaBridge 172:7d866c31b3c5 90 timeinfo.tm_wday = rtc_datetime.u32DayOfWeek;
AnnaBridge 172:7d866c31b3c5 91 timeinfo.tm_hour = rtc_datetime.u32Hour;
AnnaBridge 176:447f873cad2f 92 if (rtc_datetime.u32TimeScale == RTC_CLOCK_12 && rtc_datetime.u32AmPm == RTC_PM) {
AnnaBridge 176:447f873cad2f 93 timeinfo.tm_hour += 12;
AnnaBridge 176:447f873cad2f 94 }
AnnaBridge 172:7d866c31b3c5 95 timeinfo.tm_min = rtc_datetime.u32Minute;
AnnaBridge 172:7d866c31b3c5 96 timeinfo.tm_sec = rtc_datetime.u32Second;
AnnaBridge 172:7d866c31b3c5 97
AnnaBridge 172:7d866c31b3c5 98 // Convert to timestamp
AnnaBridge 176:447f873cad2f 99 time_t t = _rtc_mktime(&timeinfo);
AnnaBridge 172:7d866c31b3c5 100
AnnaBridge 172:7d866c31b3c5 101 return t;
AnnaBridge 172:7d866c31b3c5 102 }
AnnaBridge 172:7d866c31b3c5 103
AnnaBridge 172:7d866c31b3c5 104 void rtc_write(time_t t)
AnnaBridge 172:7d866c31b3c5 105 {
AnnaBridge 172:7d866c31b3c5 106 if (! rtc_isenabled()) {
AnnaBridge 172:7d866c31b3c5 107 rtc_init();
AnnaBridge 172:7d866c31b3c5 108 }
AnnaBridge 172:7d866c31b3c5 109
AnnaBridge 172:7d866c31b3c5 110 // Convert timestamp to struct tm
AnnaBridge 176:447f873cad2f 111 struct tm timeinfo;
AnnaBridge 176:447f873cad2f 112 if (_rtc_localtime(t, &timeinfo) == false) {
AnnaBridge 176:447f873cad2f 113 return;
AnnaBridge 176:447f873cad2f 114 }
AnnaBridge 172:7d866c31b3c5 115
AnnaBridge 172:7d866c31b3c5 116 S_RTC_TIME_DATA_T rtc_datetime;
AnnaBridge 172:7d866c31b3c5 117
AnnaBridge 172:7d866c31b3c5 118 // Convert S_RTC_TIME_DATA_T to struct tm
AnnaBridge 176:447f873cad2f 119 rtc_datetime.u32Year = timeinfo.tm_year + YEAR0;
AnnaBridge 176:447f873cad2f 120 rtc_datetime.u32Month = timeinfo.tm_mon + 1;
AnnaBridge 176:447f873cad2f 121 rtc_datetime.u32Day = timeinfo.tm_mday;
AnnaBridge 176:447f873cad2f 122 rtc_datetime.u32DayOfWeek = timeinfo.tm_wday;
AnnaBridge 176:447f873cad2f 123 rtc_datetime.u32Hour = timeinfo.tm_hour;
AnnaBridge 176:447f873cad2f 124 rtc_datetime.u32Minute = timeinfo.tm_min;
AnnaBridge 176:447f873cad2f 125 rtc_datetime.u32Second = timeinfo.tm_sec;
AnnaBridge 172:7d866c31b3c5 126 rtc_datetime.u32TimeScale = RTC_CLOCK_24;
AnnaBridge 172:7d866c31b3c5 127
AnnaBridge 172:7d866c31b3c5 128 // NOTE: Timing issue with write to RTC registers. This delay is empirical, not rational.
AnnaBridge 172:7d866c31b3c5 129 RTC_SetDateAndTime(&rtc_datetime);
AnnaBridge 172:7d866c31b3c5 130 wait_us(100);
AnnaBridge 172:7d866c31b3c5 131 }
AnnaBridge 172:7d866c31b3c5 132
AnnaBridge 172:7d866c31b3c5 133 #endif