frtc.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: frtc.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 09:02:33
  17. * Description:  This files is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. * 1.0 Wangxiaodong 2021/11/5 init
  23. */
  24. #include <string.h>
  25. #include "fgeneric_timer.h"
  26. #include "ftypes.h"
  27. #include "fassert.h"
  28. #include "fdebug.h"
  29. #include "fsleep.h"
  30. #include "frtc.h"
  31. #include "frtc_hw.h"
  32. #define FRTC_DEBUG_TAG "RTC"
  33. #define FRTC_ERROR(format, ...) FT_DEBUG_PRINT_E(FRTC_DEBUG_TAG, format, ##__VA_ARGS__)
  34. #define FRTC_INFO(format, ...) FT_DEBUG_PRINT_I(FRTC_DEBUG_TAG, format, ##__VA_ARGS__)
  35. #define FRTC_DEBUG(format, ...) FT_DEBUG_PRINT_D(FRTC_DEBUG_TAG, format, ##__VA_ARGS__)
  36. #define FRTC_IS_LEAP_YEAR(year) ((((year) % 4 == 0 ) && ((year) %100 != 0))||( (year) % 400 == 0))
  37. /**
  38. * @name: FRtcCheckDateTime
  39. * @msg: check if the date year, month, day, hour, ... is valid
  40. * @return {u32} whether the date is valid
  41. * @param {FRtcDate} *date, pointer to a FRtcDate structure that contains year, month and day
  42. */
  43. static FError FRtcCheckDateTime(const FRtcDateTime *date_time)
  44. {
  45. FASSERT(date_time != NULL);
  46. u8 w_hour = date_time->hour;
  47. u8 w_minute = date_time->minute;
  48. u8 w_second = date_time->second;
  49. u8 w_year = date_time->year;
  50. u8 w_month = date_time->month;
  51. u8 w_day = date_time->mday;
  52. u8 days_of_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* 月份天数表 */
  53. /* 闰年2月+1天 */
  54. if ((w_month == 2) && (FRTC_IS_LEAP_YEAR(w_year)))
  55. days_of_month[w_month - 1] += 1;
  56. /* 判断月份日期是否合法 */
  57. if ((w_month > 12) || (w_month < 1) || (w_day > days_of_month[w_month - 1]) || (w_day < 1))
  58. {
  59. FRTC_ERROR("invalid input date: month: %d, day: %d", w_month, w_day);
  60. return FRTC_ERR_DATE_INVALID;
  61. }
  62. /* 判断时分秒是否合法 */
  63. if ((w_hour > 23) || (w_minute > 59) || (w_second > 59))
  64. {
  65. FRTC_ERROR("invalid input time: hour: %d, minute: %d, second: %d",
  66. w_hour, w_minute, w_second);
  67. return FRTC_ERR_TIME_INVALID;
  68. }
  69. return FRTC_SUCCESS;
  70. }
  71. /**
  72. * @name: FRtcSetDateTime
  73. * @msg: Set current time in FRtcDateTime
  74. * @return {u32} whether the time setting is successful
  75. * @param {FRtcCtrl} *pctrl, pointer to a FRtcCtrl structure that contains
  76. * the configuration information for the specified rtc module.
  77. * @param {FRtcDate} *date, pointer to a FRtcDate structure that contains year, month and day
  78. * @param {FRtcTime} *time, pointer to a FRtcTime structure that contains hour, minute and second
  79. */
  80. FError FRtcSetDateTime(FRtcCtrl *pctrl, const FRtcDateTime *date_time)
  81. {
  82. FASSERT(pctrl != NULL);
  83. FASSERT(date_time != NULL);
  84. uintptr base_addr = pctrl->config.control_base_addr;
  85. struct tm tm;
  86. time_t t;
  87. u32 ret = 0;
  88. ret = FRtcCheckDateTime(date_time);
  89. if (ret != FRTC_SUCCESS)
  90. {
  91. return ret;
  92. }
  93. tm.tm_sec = date_time->second;
  94. tm.tm_min = date_time->minute;
  95. tm.tm_hour = date_time->hour;
  96. /* tm->tm_wday */
  97. tm.tm_mday = date_time->mday;
  98. tm.tm_mon = (date_time->month - 1);
  99. tm.tm_year = (date_time->year - 1900);
  100. t = mktime(&tm);
  101. FRTC_WRITE_AES_SEL(base_addr, FRTC_AES_SEL_COUNTER);
  102. /* write low 32 bit first */
  103. FRTC_WRITE_CLR_LOW(base_addr, 0);
  104. /* write low 32 bit next */
  105. FRTC_WRITE_CLR(base_addr, t);
  106. return FT_SUCCESS;
  107. }
  108. /**
  109. * @name: FRtcGetDateTime
  110. * @msg: Get current time in FRtcDateTime
  111. * @return {*}
  112. * @param {FRtcCtrl} *pctrl
  113. * @param {FRtcDateTime} *date_time
  114. */
  115. FError FRtcGetDateTime(FRtcCtrl *pctrl, FRtcDateTime *date_time)
  116. {
  117. FASSERT(pctrl != NULL);
  118. FASSERT(date_time != NULL);
  119. time_t seconds = 0;
  120. struct tm *time_p;
  121. FRtcReadTimeStamp(pctrl, &seconds, NULL);
  122. time_p = localtime(&seconds);
  123. date_time->year = time_p->tm_year + 1900;
  124. date_time->month = time_p->tm_mon + 1;
  125. date_time->mday = time_p->tm_mday;
  126. date_time->hour = time_p->tm_hour;
  127. date_time->minute = time_p->tm_min;
  128. date_time->second = time_p->tm_sec;
  129. return FRTC_SUCCESS;
  130. }
  131. /**
  132. * @name: FRtcReadTimeStamp
  133. * @msg: Read time stamp in seconds and milliseconds
  134. * @return {*} none
  135. * @param {FRtcCtrl} *pctrl
  136. * @param {time_t} *sec_p
  137. * @param {time_t} *msec_p
  138. */
  139. void FRtcReadTimeStamp(FRtcCtrl *pctrl, time_t *sec_p, time_t *msec_p)
  140. {
  141. FASSERT(pctrl != NULL);
  142. time_t sec = 0;
  143. u32 msec = 0;
  144. u32 tick = 0;
  145. uintptr base_addr = pctrl->config.control_base_addr;
  146. /* tick = 1/32.768k = 0.03ms = 30us, delay more than 4 ticks */
  147. fsleep_microsec(FRTC_COUNTER_DELAY);
  148. /* write AES_SEL register, to read CCVR and CDR register */
  149. FRTC_WRITE_AES_SEL(base_addr, FRTC_AES_SEL_COUNTER);
  150. /* tick = 1/32.768k = 0.03ms = 30us, delay more than 4 ticks */
  151. fsleep_microsec(FRTC_COUNTER_DELAY);
  152. /* read high 32 bit first */
  153. sec = FRTC_READ_CCVR(base_addr);
  154. /* read low 32 bit next, The lower 15 bits are valid */
  155. tick = (FRTC_READ_CDR_LOW(base_addr) & FRTC_COUNTER_LB_MASK);
  156. /* convert 15 bits tick to milliseconds, count by 32.768k */
  157. msec = ((tick * 1000) >> FRTC_COUNTER_HB_OFFSET);
  158. if (sec_p)
  159. *sec_p = sec;
  160. if (msec_p)
  161. *msec_p = msec;
  162. return;
  163. }
  164. /**
  165. * @name: FRtcCfgInitialize
  166. * @msg: Initialize RTC ctrl
  167. * @return {*}
  168. * @param {FRtcCtrl} *instance_p
  169. * @param {FRtcConfig} *input_config_p
  170. */
  171. FError FRtcCfgInitialize(FRtcCtrl *instance_p, const FRtcConfig *input_config_p)
  172. {
  173. FASSERT(instance_p && input_config_p);
  174. uintptr base_addr = instance_p->config.control_base_addr;
  175. instance_p->config = *input_config_p;
  176. instance_p->is_ready = FT_COMPONENT_IS_READY;
  177. return FRTC_SUCCESS;
  178. }
  179. /**
  180. * @name: FRtcCfgDeInitialize
  181. * @msg: DeInitialization function for the device instance
  182. * @param {FRtcCtrl} *instance_p FRTC驱动控制数据
  183. * @return {*}
  184. */
  185. void FRtcCfgDeInitialize(FRtcCtrl *pctrl)
  186. {
  187. FASSERT(pctrl);
  188. pctrl->is_ready = 0;
  189. memset(pctrl, 0, sizeof(*pctrl));
  190. return;
  191. }