mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 188:bcfe06ba3d64 1 /*
AnnaBridge 188:bcfe06ba3d64 2 * mbed Microcontroller Library
AnnaBridge 188:bcfe06ba3d64 3 * Copyright (c) 2017-2018 Future Electronics
AnnaBridge 188:bcfe06ba3d64 4 *
AnnaBridge 188:bcfe06ba3d64 5 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 188:bcfe06ba3d64 6 * you may not use this file except in compliance with the License.
AnnaBridge 188:bcfe06ba3d64 7 * You may obtain a copy of the License at
AnnaBridge 188:bcfe06ba3d64 8 *
AnnaBridge 188:bcfe06ba3d64 9 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 188:bcfe06ba3d64 10 *
AnnaBridge 188:bcfe06ba3d64 11 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 188:bcfe06ba3d64 12 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 188:bcfe06ba3d64 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 188:bcfe06ba3d64 14 * See the License for the specific language governing permissions and
AnnaBridge 188:bcfe06ba3d64 15 * limitations under the License.
AnnaBridge 188:bcfe06ba3d64 16 */
AnnaBridge 188:bcfe06ba3d64 17
AnnaBridge 188:bcfe06ba3d64 18 #include "device.h"
AnnaBridge 188:bcfe06ba3d64 19 #include "rtc_api.h"
AnnaBridge 188:bcfe06ba3d64 20 #include "mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 21 #include "mbed_mktime.h"
AnnaBridge 188:bcfe06ba3d64 22 #include "cy_rtc.h"
AnnaBridge 188:bcfe06ba3d64 23
AnnaBridge 188:bcfe06ba3d64 24
AnnaBridge 188:bcfe06ba3d64 25 #if DEVICE_RTC
AnnaBridge 188:bcfe06ba3d64 26
AnnaBridge 188:bcfe06ba3d64 27 /*
AnnaBridge 188:bcfe06ba3d64 28 * Since Mbed tests insist on supporting 1970 - 2106 years range
AnnaBridge 188:bcfe06ba3d64 29 * and Cypress h/w supports only 2000 - 2099 years range,
AnnaBridge 188:bcfe06ba3d64 30 * two backup registers are used to flag century correction.
AnnaBridge 188:bcfe06ba3d64 31 */
AnnaBridge 188:bcfe06ba3d64 32 #define BR_LAST_YEAR_READ 14
AnnaBridge 188:bcfe06ba3d64 33 #define BR_CENTURY_CORRECTION 15
AnnaBridge 188:bcfe06ba3d64 34
AnnaBridge 188:bcfe06ba3d64 35 static int enabled = 0;
AnnaBridge 188:bcfe06ba3d64 36
AnnaBridge 188:bcfe06ba3d64 37 static uint32_t rtc_read_convert_year(uint32_t short_year)
AnnaBridge 188:bcfe06ba3d64 38 {
AnnaBridge 188:bcfe06ba3d64 39 uint32_t century = BACKUP->BREG[BR_CENTURY_CORRECTION];
AnnaBridge 188:bcfe06ba3d64 40
AnnaBridge 188:bcfe06ba3d64 41 if (BACKUP->BREG[BR_LAST_YEAR_READ] > short_year) {
AnnaBridge 188:bcfe06ba3d64 42 BACKUP->BREG[BR_CENTURY_CORRECTION] = ++century;
AnnaBridge 188:bcfe06ba3d64 43 }
AnnaBridge 188:bcfe06ba3d64 44 BACKUP->BREG[BR_LAST_YEAR_READ] = short_year;
AnnaBridge 188:bcfe06ba3d64 45
AnnaBridge 188:bcfe06ba3d64 46 return century * 100 + short_year;
AnnaBridge 188:bcfe06ba3d64 47 }
AnnaBridge 188:bcfe06ba3d64 48
AnnaBridge 188:bcfe06ba3d64 49 static uint32_t rtc_write_convert_year(uint32_t long_year)
AnnaBridge 188:bcfe06ba3d64 50 {
AnnaBridge 188:bcfe06ba3d64 51 uint32_t short_year = long_year;
AnnaBridge 188:bcfe06ba3d64 52 uint32_t century = short_year / 100;
AnnaBridge 188:bcfe06ba3d64 53 short_year -= century * 100;
AnnaBridge 188:bcfe06ba3d64 54 BACKUP->BREG[BR_CENTURY_CORRECTION] = century;
AnnaBridge 188:bcfe06ba3d64 55 BACKUP->BREG[BR_LAST_YEAR_READ] = short_year;
AnnaBridge 188:bcfe06ba3d64 56 return short_year;
AnnaBridge 188:bcfe06ba3d64 57 }
AnnaBridge 188:bcfe06ba3d64 58
AnnaBridge 188:bcfe06ba3d64 59 void rtc_init(void)
AnnaBridge 188:bcfe06ba3d64 60 {
AnnaBridge 188:bcfe06ba3d64 61 static cy_stc_rtc_config_t init_val = {
AnnaBridge 188:bcfe06ba3d64 62 /* Time information */
AnnaBridge 188:bcfe06ba3d64 63 .hrFormat = CY_RTC_24_HOURS,
AnnaBridge 188:bcfe06ba3d64 64 .sec = 0,
AnnaBridge 188:bcfe06ba3d64 65 .min = 0,
AnnaBridge 188:bcfe06ba3d64 66 .hour = 0,
AnnaBridge 188:bcfe06ba3d64 67 .dayOfWeek = CY_RTC_SATURDAY,
AnnaBridge 188:bcfe06ba3d64 68 .date = 1,
AnnaBridge 188:bcfe06ba3d64 69 .month = 1,
AnnaBridge 188:bcfe06ba3d64 70 .year = 0 // 2000 - 30 == 1970
AnnaBridge 188:bcfe06ba3d64 71 };
AnnaBridge 188:bcfe06ba3d64 72 cy_stc_rtc_config_t cy_time;
AnnaBridge 188:bcfe06ba3d64 73
AnnaBridge 188:bcfe06ba3d64 74 if (!enabled) {
AnnaBridge 188:bcfe06ba3d64 75 // Setup power management callback.
AnnaBridge 188:bcfe06ba3d64 76 // Setup century interrupt.
AnnaBridge 188:bcfe06ba3d64 77 // Verify RTC time consistency.
AnnaBridge 188:bcfe06ba3d64 78 Cy_RTC_GetDateAndTime(&cy_time);
AnnaBridge 188:bcfe06ba3d64 79 if ( CY_RTC_IS_SEC_VALID(cy_time.sec) &&
AnnaBridge 188:bcfe06ba3d64 80 CY_RTC_IS_MIN_VALID(cy_time.min) &&
AnnaBridge 188:bcfe06ba3d64 81 CY_RTC_IS_HOUR_VALID(cy_time.hour) &&
AnnaBridge 188:bcfe06ba3d64 82 CY_RTC_IS_DOW_VALID(cy_time.dayOfWeek) &&
AnnaBridge 188:bcfe06ba3d64 83 CY_RTC_IS_MONTH_VALID(cy_time.month) &&
AnnaBridge 188:bcfe06ba3d64 84 CY_RTC_IS_YEAR_SHORT_VALID(cy_time.year) &&
AnnaBridge 188:bcfe06ba3d64 85 (cy_time.hrFormat == CY_RTC_24_HOURS)) {
AnnaBridge 188:bcfe06ba3d64 86 enabled = 1;
AnnaBridge 188:bcfe06ba3d64 87 } else {
AnnaBridge 188:bcfe06ba3d64 88 // reinitialize
AnnaBridge 188:bcfe06ba3d64 89 init_val.year = rtc_write_convert_year(1970);
AnnaBridge 188:bcfe06ba3d64 90 if (Cy_RTC_Init(&init_val) == CY_RTC_SUCCESS) {
AnnaBridge 188:bcfe06ba3d64 91 enabled = 1;
AnnaBridge 188:bcfe06ba3d64 92 }
AnnaBridge 188:bcfe06ba3d64 93 }
AnnaBridge 188:bcfe06ba3d64 94 }
AnnaBridge 188:bcfe06ba3d64 95 }
AnnaBridge 188:bcfe06ba3d64 96
AnnaBridge 188:bcfe06ba3d64 97 void rtc_free(void)
AnnaBridge 188:bcfe06ba3d64 98 {
AnnaBridge 188:bcfe06ba3d64 99 // Nothing to do
AnnaBridge 188:bcfe06ba3d64 100 }
AnnaBridge 188:bcfe06ba3d64 101
AnnaBridge 188:bcfe06ba3d64 102 int rtc_isenabled(void)
AnnaBridge 188:bcfe06ba3d64 103 {
AnnaBridge 188:bcfe06ba3d64 104 return enabled;
AnnaBridge 188:bcfe06ba3d64 105 }
AnnaBridge 188:bcfe06ba3d64 106
AnnaBridge 188:bcfe06ba3d64 107 time_t rtc_read(void)
AnnaBridge 188:bcfe06ba3d64 108 {
AnnaBridge 188:bcfe06ba3d64 109 cy_stc_rtc_config_t cy_time;
AnnaBridge 188:bcfe06ba3d64 110 struct tm gmt;
AnnaBridge 188:bcfe06ba3d64 111 time_t timestamp = 0;
AnnaBridge 188:bcfe06ba3d64 112 uint32_t interrupt_state;
AnnaBridge 188:bcfe06ba3d64 113
AnnaBridge 188:bcfe06ba3d64 114 // Since RTC reading function is unreliable when the RTC is busy with previous update
AnnaBridge 188:bcfe06ba3d64 115 // we have to make sure it's not before calling it.
AnnaBridge 188:bcfe06ba3d64 116 while (CY_RTC_BUSY == Cy_RTC_GetSyncStatus()) {}
AnnaBridge 188:bcfe06ba3d64 117
AnnaBridge 188:bcfe06ba3d64 118 interrupt_state = Cy_SysLib_EnterCriticalSection();
AnnaBridge 188:bcfe06ba3d64 119 Cy_RTC_GetDateAndTime(&cy_time);
AnnaBridge 188:bcfe06ba3d64 120 gmt.tm_sec = cy_time.sec;
AnnaBridge 188:bcfe06ba3d64 121 gmt.tm_min = cy_time.min;
AnnaBridge 188:bcfe06ba3d64 122 gmt.tm_hour = cy_time.hour;
AnnaBridge 188:bcfe06ba3d64 123 gmt.tm_mday = cy_time.date;
AnnaBridge 188:bcfe06ba3d64 124 gmt.tm_mon = cy_time.month - 1;
AnnaBridge 188:bcfe06ba3d64 125 gmt.tm_year = rtc_read_convert_year(cy_time.year);
AnnaBridge 188:bcfe06ba3d64 126 gmt.tm_isdst = 0;
AnnaBridge 188:bcfe06ba3d64 127 Cy_SysLib_ExitCriticalSection(interrupt_state);
AnnaBridge 188:bcfe06ba3d64 128
AnnaBridge 188:bcfe06ba3d64 129 _rtc_maketime(&gmt, &timestamp, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
AnnaBridge 188:bcfe06ba3d64 130 return timestamp;
AnnaBridge 188:bcfe06ba3d64 131 }
AnnaBridge 188:bcfe06ba3d64 132
AnnaBridge 188:bcfe06ba3d64 133 void rtc_write(time_t t)
AnnaBridge 188:bcfe06ba3d64 134 {
AnnaBridge 188:bcfe06ba3d64 135 cy_en_rtc_status_t status;
AnnaBridge 188:bcfe06ba3d64 136 struct tm gmt;
AnnaBridge 188:bcfe06ba3d64 137
AnnaBridge 188:bcfe06ba3d64 138 if ( _rtc_localtime(t, &gmt, RTC_4_YEAR_LEAP_YEAR_SUPPORT)) {
AnnaBridge 188:bcfe06ba3d64 139 uint32_t year;
AnnaBridge 188:bcfe06ba3d64 140 uint32_t interrupt_state;
AnnaBridge 188:bcfe06ba3d64 141 // Make sure RTC is not busy and can be updated.
AnnaBridge 188:bcfe06ba3d64 142 while (CY_RTC_BUSY == Cy_RTC_GetSyncStatus()) {}
AnnaBridge 188:bcfe06ba3d64 143
AnnaBridge 188:bcfe06ba3d64 144 interrupt_state = Cy_SysLib_EnterCriticalSection();
AnnaBridge 188:bcfe06ba3d64 145 year = rtc_write_convert_year(gmt.tm_year);
AnnaBridge 188:bcfe06ba3d64 146 status = Cy_RTC_SetDateAndTimeDirect(gmt.tm_sec,
AnnaBridge 188:bcfe06ba3d64 147 gmt.tm_min,
AnnaBridge 188:bcfe06ba3d64 148 gmt.tm_hour,
AnnaBridge 188:bcfe06ba3d64 149 gmt.tm_mday,
AnnaBridge 188:bcfe06ba3d64 150 gmt.tm_mon + 1,
AnnaBridge 188:bcfe06ba3d64 151 year);
AnnaBridge 188:bcfe06ba3d64 152 Cy_SysLib_ExitCriticalSection(interrupt_state);
AnnaBridge 188:bcfe06ba3d64 153 if (status != CY_RTC_SUCCESS) {
AnnaBridge 188:bcfe06ba3d64 154 error("Error 0x%x while setting RTC time.", status);
AnnaBridge 188:bcfe06ba3d64 155 }
AnnaBridge 188:bcfe06ba3d64 156 }
AnnaBridge 188:bcfe06ba3d64 157 }
AnnaBridge 188:bcfe06ba3d64 158
AnnaBridge 188:bcfe06ba3d64 159 #endif // DEVICE_RTC