From 48026bb824fd2d9cfb00ecd040db6ef3a416bae9 Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Fri, 22 Jan 2021 21:43:36 -0500
Subject: upload initial port

---
 ChibiOS_20.3.2/os/hal/src/hal_rtc.c | 321 ++++++++++++++++++++++++++++++++++++
 1 file changed, 321 insertions(+)
 create mode 100644 ChibiOS_20.3.2/os/hal/src/hal_rtc.c

(limited to 'ChibiOS_20.3.2/os/hal/src/hal_rtc.c')

diff --git a/ChibiOS_20.3.2/os/hal/src/hal_rtc.c b/ChibiOS_20.3.2/os/hal/src/hal_rtc.c
new file mode 100644
index 0000000..840e2ec
--- /dev/null
+++ b/ChibiOS_20.3.2/os/hal/src/hal_rtc.c
@@ -0,0 +1,321 @@
+/*
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+    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.
+*/
+/*
+   Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+   aka barthess.
+ */
+
+/**
+ * @file    hal_rtc.c
+ * @brief   RTC Driver code.
+ *
+ * @addtogroup RTC
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions.                                                 */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables.                                                */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types.                                         */
+/*===========================================================================*/
+
+/*
+ * Lookup table with months' length
+ */
+static const uint8_t month_len[12] = {
+  31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*===========================================================================*/
+/* Driver local functions.                                                   */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions.                                                */
+/*===========================================================================*/
+
+/**
+ * @brief   RTC Driver initialization.
+ * @note    This function is implicitly invoked by @p halInit(), there is
+ *          no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void rtcInit(void) {
+
+  rtc_lld_init();
+}
+
+/**
+ * @brief   Initializes a generic RTC driver object.
+ * @details The HW dependent part of the initialization has to be performed
+ *          outside, usually in the hardware initialization code.
+ *
+ * @param[out] rtcp     pointer to RTC driver structure
+ *
+ * @init
+ */
+void rtcObjectInit(RTCDriver *rtcp) {
+
+#if RTC_HAS_STORAGE == TRUE
+  rtcp->vmt = &_rtc_lld_vmt;
+#else
+  (void)rtcp;
+#endif
+}
+
+/**
+ * @brief   Set current time.
+ * @note    This function can be called from any context but limitations
+ *          could be imposed by the low level implementation. It is
+ *          guaranteed that the function can be called from thread
+ *          context.
+ * @note    The function can be reentrant or not reentrant depending on
+ *          the low level implementation.
+ *
+ * @param[in] rtcp      pointer to RTC driver structure
+ * @param[in] timespec  pointer to a @p RTCDateTime structure
+ *
+ * @special
+ */
+void rtcSetTime(RTCDriver *rtcp, const RTCDateTime *timespec) {
+
+  osalDbgCheck((rtcp != NULL) && (timespec != NULL));
+
+  rtc_lld_set_time(rtcp, timespec);
+}
+
+/**
+ * @brief   Get current time.
+ * @note    This function can be called from any context but limitations
+ *          could be imposed by the low level implementation. It is
+ *          guaranteed that the function can be called from thread
+ *          context.
+ * @note    The function can be reentrant or not reentrant depending on
+ *          the low level implementation.
+ *
+ * @param[in] rtcp      pointer to RTC driver structure
+ * @param[out] timespec pointer to a @p RTCDateTime structure
+ *
+ * @special
+ */
+void rtcGetTime(RTCDriver *rtcp, RTCDateTime *timespec) {
+
+  osalDbgCheck((rtcp != NULL) && (timespec != NULL));
+
+  rtc_lld_get_time(rtcp, timespec);
+}
+
+#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
+/**
+ * @brief   Set alarm time.
+ * @note    This function can be called from any context but limitations
+ *          could be imposed by the low level implementation. It is
+ *          guaranteed that the function can be called from thread
+ *          context.
+ * @note    The function can be reentrant or not reentrant depending on
+ *          the low level implementation.
+ *
+ * @param[in] rtcp      pointer to RTC driver structure
+ * @param[in] alarm     alarm identifier
+ * @param[in] alarmspec pointer to a @p RTCAlarm structure or @p NULL
+ *
+ * @special
+ */
+void rtcSetAlarm(RTCDriver *rtcp,
+                 rtcalarm_t alarm,
+                 const RTCAlarm *alarmspec) {
+
+  osalDbgCheck((rtcp != NULL) && (alarm < (rtcalarm_t)RTC_ALARMS));
+
+  rtc_lld_set_alarm(rtcp, alarm, alarmspec);
+}
+
+/**
+ * @brief   Get current alarm.
+ * @note    If an alarm has not been set then the returned alarm specification
+ *          is not meaningful.
+ * @note    This function can be called from any context but limitations
+ *          could be imposed by the low level implementation. It is
+ *          guaranteed that the function can be called from thread
+ *          context.
+ * @note    The function can be reentrant or not reentrant depending on
+ *          the low level implementation.
+ *
+ * @param[in] rtcp      pointer to RTC driver structure
+ * @param[in] alarm     alarm identifier
+ * @param[out] alarmspec pointer to a @p RTCAlarm structure
+ *
+ * @special
+ */
+void rtcGetAlarm(RTCDriver *rtcp,
+                 rtcalarm_t alarm,
+                 RTCAlarm *alarmspec) {
+
+  osalDbgCheck((rtcp != NULL) &&
+               (alarm < (rtcalarm_t)RTC_ALARMS) &&
+               (alarmspec != NULL));
+
+  rtc_lld_get_alarm(rtcp, alarm, alarmspec);
+}
+#endif /* RTC_ALARMS > 0 */
+
+#if (RTC_SUPPORTS_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief   Enables or disables RTC callbacks.
+ * @details This function enables or disables the callback, use a @p NULL
+ *          pointer in order to disable it.
+ * @note    This function can be called from any context but limitations
+ *          could be imposed by the low level implementation. It is
+ *          guaranteed that the function can be called from thread
+ *          context.
+ * @note    The function can be reentrant or not reentrant depending on
+ *          the low level implementation.
+ *
+ * @param[in] rtcp      pointer to RTC driver structure
+ * @param[in] callback  callback function pointer or @p NULL
+ *
+ * @special
+ */
+void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback) {
+
+  osalDbgCheck(rtcp != NULL);
+
+  rtc_lld_set_callback(rtcp, callback);
+}
+#endif /* RTC_SUPPORTS_CALLBACKS == TRUE */
+
+/**
+ * @brief   Convert @p RTCDateTime to broken-down time structure.
+ *
+ * @param[in]  timespec   pointer to a @p RTCDateTime structure
+ * @param[out] timp       pointer to a broken-down time structure
+ * @param[out] tv_msec    pointer to milliseconds value or @p NULL
+ *
+ * @api
+ */
+void rtcConvertDateTimeToStructTm(const RTCDateTime *timespec,
+                                  struct tm *timp,
+                                  uint32_t *tv_msec) {
+  int sec;
+
+  timp->tm_year  = (int)timespec->year + (int)(RTC_BASE_YEAR - 1900U);
+  timp->tm_mon   = (int)timespec->month - 1;
+  timp->tm_mday  = (int)timespec->day;
+  timp->tm_isdst = (int)timespec->dstflag;
+  timp->tm_wday  = (int)timespec->dayofweek - 1;
+
+  sec = (int)timespec->millisecond / 1000;
+  timp->tm_hour = sec / 3600;
+  sec %= 3600;
+  timp->tm_min = sec / 60;
+  timp->tm_sec = sec % 60;
+
+  if (NULL != tv_msec) {
+    *tv_msec = (uint32_t)timespec->millisecond % 1000U;
+  }
+}
+
+/**
+ * @brief   Convert broken-down time structure to @p RTCDateTime.
+ *
+ * @param[in] timp        pointer to a broken-down time structure
+ * @param[in] tv_msec     milliseconds value
+ * @param[out] timespec   pointer to a @p RTCDateTime structure
+ *
+ * @api
+ */
+void rtcConvertStructTmToDateTime(const struct tm *timp,
+                                  uint32_t tv_msec,
+                                  RTCDateTime *timespec) {
+
+  /*lint -save -e9034 [10.4] Verified assignments to bit fields.*/
+  timespec->year      = (uint32_t)timp->tm_year - (RTC_BASE_YEAR - 1900U);
+  timespec->month     = (uint32_t)timp->tm_mon + 1U;
+  timespec->day       = (uint32_t)timp->tm_mday;
+  timespec->dayofweek = (uint32_t)timp->tm_wday + 1U;
+  if (-1 == timp->tm_isdst) {
+    timespec->dstflag = 0U;  /* Set zero if dst is unknown.*/
+  }
+  else {
+    timespec->dstflag = (uint32_t)timp->tm_isdst;
+  }
+  /*lint -restore*/
+  /*lint -save -e9033 [10.8] Verified assignments to bit fields.*/
+  timespec->millisecond = tv_msec + (uint32_t)(((timp->tm_hour * 3600) +
+                                                (timp->tm_min * 60) +
+                                                 timp->tm_sec) * 1000);
+  /*lint -restore*/
+}
+
+/**
+ * @brief   Get current time in format suitable for usage in FAT file system.
+ * @note    The information about day of week and DST is lost in DOS
+ *          format, the second field loses its least significant bit.
+ *
+ * @param[out] timespec pointer to a @p RTCDateTime structure
+ * @return              FAT date/time value.
+ *
+ * @api
+ */
+uint32_t rtcConvertDateTimeToFAT(const RTCDateTime *timespec) {
+  uint32_t fattime;
+  uint32_t sec, min, hour, day, month;
+
+  sec   = timespec->millisecond / 1000U;
+  hour  = sec / 3600U;
+  sec  %= 3600U;
+  min   = sec / 60U;
+  sec  %= 60U;
+  day   = timespec->day;
+  month = timespec->month;
+
+  /* Handle DST flag.*/
+  if (1U == timespec->dstflag) {
+    hour += 1U;
+    if (hour == 24U) {
+      hour = 0U;
+      day += 1U;
+      if (day > month_len[month - 1U]) {
+        day = 1U;
+        month += 1U;
+      }
+    }
+  }
+
+  fattime  = sec   >> 1U;
+  fattime |= min   << 5U;
+  fattime |= hour  << 11U;
+  fattime |= day   << 16U;
+  fattime |= month << 21U;
+  fattime |= (uint32_t)timespec->year << 25U;
+
+  return fattime;
+}
+
+#endif /* HAL_USE_RTC == TRUE */
+
+/** @} */
-- 
cgit v1.2.3