Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: targets/TARGET_Cypress/TARGET_PSOC6/rtc_api.c
- Revision:
- 188:bcfe06ba3d64
- Child:
- 189:f392fc9709a3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/TARGET_Cypress/TARGET_PSOC6/rtc_api.c Thu Nov 08 11:46:34 2018 +0000
@@ -0,0 +1,159 @@
+/*
+ * mbed Microcontroller Library
+ * Copyright (c) 2017-2018 Future Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "device.h"
+#include "rtc_api.h"
+#include "mbed_error.h"
+#include "mbed_mktime.h"
+#include "cy_rtc.h"
+
+
+#if DEVICE_RTC
+
+/*
+ * Since Mbed tests insist on supporting 1970 - 2106 years range
+ * and Cypress h/w supports only 2000 - 2099 years range,
+* two backup registers are used to flag century correction.
+ */
+#define BR_LAST_YEAR_READ 14
+#define BR_CENTURY_CORRECTION 15
+
+static int enabled = 0;
+
+static uint32_t rtc_read_convert_year(uint32_t short_year)
+{
+ uint32_t century = BACKUP->BREG[BR_CENTURY_CORRECTION];
+
+ if (BACKUP->BREG[BR_LAST_YEAR_READ] > short_year) {
+ BACKUP->BREG[BR_CENTURY_CORRECTION] = ++century;
+ }
+ BACKUP->BREG[BR_LAST_YEAR_READ] = short_year;
+
+ return century * 100 + short_year;
+}
+
+static uint32_t rtc_write_convert_year(uint32_t long_year)
+{
+ uint32_t short_year = long_year;
+ uint32_t century = short_year / 100;
+ short_year -= century * 100;
+ BACKUP->BREG[BR_CENTURY_CORRECTION] = century;
+ BACKUP->BREG[BR_LAST_YEAR_READ] = short_year;
+ return short_year;
+}
+
+void rtc_init(void)
+{
+ static cy_stc_rtc_config_t init_val = {
+ /* Time information */
+ .hrFormat = CY_RTC_24_HOURS,
+ .sec = 0,
+ .min = 0,
+ .hour = 0,
+ .dayOfWeek = CY_RTC_SATURDAY,
+ .date = 1,
+ .month = 1,
+ .year = 0 // 2000 - 30 == 1970
+ };
+ cy_stc_rtc_config_t cy_time;
+
+ if (!enabled) {
+ // Setup power management callback.
+ // Setup century interrupt.
+ // Verify RTC time consistency.
+ Cy_RTC_GetDateAndTime(&cy_time);
+ if ( CY_RTC_IS_SEC_VALID(cy_time.sec) &&
+ CY_RTC_IS_MIN_VALID(cy_time.min) &&
+ CY_RTC_IS_HOUR_VALID(cy_time.hour) &&
+ CY_RTC_IS_DOW_VALID(cy_time.dayOfWeek) &&
+ CY_RTC_IS_MONTH_VALID(cy_time.month) &&
+ CY_RTC_IS_YEAR_SHORT_VALID(cy_time.year) &&
+ (cy_time.hrFormat == CY_RTC_24_HOURS)) {
+ enabled = 1;
+ } else {
+ // reinitialize
+ init_val.year = rtc_write_convert_year(1970);
+ if (Cy_RTC_Init(&init_val) == CY_RTC_SUCCESS) {
+ enabled = 1;
+ }
+ }
+ }
+}
+
+void rtc_free(void)
+{
+ // Nothing to do
+}
+
+int rtc_isenabled(void)
+{
+ return enabled;
+}
+
+time_t rtc_read(void)
+{
+ cy_stc_rtc_config_t cy_time;
+ struct tm gmt;
+ time_t timestamp = 0;
+ uint32_t interrupt_state;
+
+ // Since RTC reading function is unreliable when the RTC is busy with previous update
+ // we have to make sure it's not before calling it.
+ while (CY_RTC_BUSY == Cy_RTC_GetSyncStatus()) {}
+
+ interrupt_state = Cy_SysLib_EnterCriticalSection();
+ Cy_RTC_GetDateAndTime(&cy_time);
+ gmt.tm_sec = cy_time.sec;
+ gmt.tm_min = cy_time.min;
+ gmt.tm_hour = cy_time.hour;
+ gmt.tm_mday = cy_time.date;
+ gmt.tm_mon = cy_time.month - 1;
+ gmt.tm_year = rtc_read_convert_year(cy_time.year);
+ gmt.tm_isdst = 0;
+ Cy_SysLib_ExitCriticalSection(interrupt_state);
+
+ _rtc_maketime(&gmt, ×tamp, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
+ return timestamp;
+}
+
+void rtc_write(time_t t)
+{
+ cy_en_rtc_status_t status;
+ struct tm gmt;
+
+ if ( _rtc_localtime(t, &gmt, RTC_4_YEAR_LEAP_YEAR_SUPPORT)) {
+ uint32_t year;
+ uint32_t interrupt_state;
+ // Make sure RTC is not busy and can be updated.
+ while (CY_RTC_BUSY == Cy_RTC_GetSyncStatus()) {}
+
+ interrupt_state = Cy_SysLib_EnterCriticalSection();
+ year = rtc_write_convert_year(gmt.tm_year);
+ status = Cy_RTC_SetDateAndTimeDirect(gmt.tm_sec,
+ gmt.tm_min,
+ gmt.tm_hour,
+ gmt.tm_mday,
+ gmt.tm_mon + 1,
+ year);
+ Cy_SysLib_ExitCriticalSection(interrupt_state);
+ if (status != CY_RTC_SUCCESS) {
+ error("Error 0x%x while setting RTC time.", status);
+ }
+ }
+}
+
+#endif // DEVICE_RTC


