mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

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