drv_rtc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. * Copyright (c) 2020, Du Huanpeng <548708880@qq.com>
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2018-01-30 armink the first version
  10. * 2020-06-23 Du Huanpeng based on components/drivers/rtc/soft_rtc.c
  11. */
  12. #include <rthw.h>
  13. #include <rtthread.h>
  14. #include <rtdevice.h>
  15. #include <rtthread.h>
  16. #include "ls2k1000.h"
  17. #ifdef RT_USING_RTC
  18. struct loongson_rtc {
  19. rt_uint32_t sys_toytrim;
  20. rt_uint32_t sys_toywrite0;
  21. rt_uint32_t sys_toywrite1;
  22. rt_uint32_t sys_toyread0;
  23. rt_uint32_t sys_toyread1;
  24. rt_uint32_t sys_toymatch0;
  25. rt_uint32_t sys_toymatch1;
  26. rt_uint32_t sys_toymatch2;
  27. rt_uint32_t sys_rtcctrl;
  28. rt_uint32_t __pad4[3];
  29. rt_uint32_t __pad5[4];
  30. rt_uint32_t sys_rtctrim;
  31. rt_uint32_t sys_rtcwrite0;
  32. rt_uint32_t sys_rtcread0;
  33. rt_uint32_t sys_rtcmatch0;
  34. rt_uint32_t sys_rtcmatch1;
  35. rt_uint32_t sys_rtcmatch2;
  36. };
  37. /* bit field helpers. */
  38. #define __M(n) (~(~0<<(n)))
  39. #define __RBF(number, n) ((number)&__M(n))
  40. #define __BF(number, n, m) __RBF((number>>m), (n-m+1))
  41. #define BF(number, n, m) (m<n ? __BF(number, n, m) : __BF(number, m, n))
  42. struct rtctime {
  43. rt_uint32_t sys_toyread0;
  44. rt_uint32_t sys_toyread1;
  45. rt_uint32_t sys_rtcread0;
  46. };
  47. typedef struct rtctime rtctime_t;
  48. struct tm *localrtctime(const rtctime_t *rtctp)
  49. {
  50. static struct tm time;
  51. int msec;
  52. msec = BF(rtctp->sys_toyread0, 3, 0);
  53. msec *= 100;
  54. time.tm_sec = BF(rtctp->sys_toyread0, 9, 4);
  55. time.tm_min = BF(rtctp->sys_toyread0, 15, 10);
  56. time.tm_hour = BF(rtctp->sys_toyread0, 20, 16);
  57. time.tm_mday = BF(rtctp->sys_toyread0, 21, 25);
  58. time.tm_mon = BF(rtctp->sys_toyread0, 26, 31);
  59. /* struct tm has three more members:
  60. time.tm_isdst
  61. time.tm_wday
  62. time.tm_yday
  63. */
  64. time.tm_mon -= 1;
  65. time.tm_year = rtctp->sys_toyread1;
  66. return &time;
  67. }
  68. rtctime_t mkrtctime(struct tm *tm)
  69. {
  70. rtctime_t rtctm;
  71. struct tm tmptime;
  72. rtctm.sys_toyread0 <<= 31 - 26 + 1;
  73. rtctm.sys_toyread0 |= tm->tm_mon + 1;
  74. rtctm.sys_toyread0 <<= 25 - 21 + 1;
  75. rtctm.sys_toyread0 |= tm->tm_mday;
  76. rtctm.sys_toyread0 <<= 20 - 16 + 1;
  77. rtctm.sys_toyread0 |= tm->tm_hour;
  78. rtctm.sys_toyread0 <<= 15 - 10 + 1;
  79. rtctm.sys_toyread0 |= tm->tm_min;
  80. rtctm.sys_toyread0 <<= 9 - 4 + 1;
  81. rtctm.sys_toyread0 |= tm->tm_sec;
  82. /* Fixme: 0.1 second */
  83. rtctm.sys_toyread0 <<= 3 - 0 + 1;
  84. rtctm.sys_toyread0 |= 0;
  85. rtctm.sys_toyread1 = tm->tm_year;
  86. tmptime = *localrtctime(&rtctm);
  87. return rtctm;
  88. }
  89. static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  90. {
  91. return RT_EOK;
  92. }
  93. static rt_size_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  94. {
  95. return 0;
  96. }
  97. static rt_err_t rt_rtc_ioctl(rt_device_t dev, int cmd, void *args)
  98. {
  99. rt_err_t err = RT_ENOSYS;
  100. static int count = 0;
  101. struct loongson_rtc *hw_rtc;
  102. rtctime_t rtctm;
  103. struct tm time;
  104. struct tm tmptime;
  105. time_t *t;
  106. hw_rtc = dev->user_data;
  107. t = (time_t *)args;
  108. time = *localtime(t);
  109. rtctm.sys_toyread0 = hw_rtc->sys_toyread0;
  110. rtctm.sys_toyread1 = hw_rtc->sys_toyread1;
  111. rtctm.sys_rtcread0 = hw_rtc->sys_rtcread0;
  112. tmptime = *localrtctime(&rtctm);
  113. switch (cmd) {
  114. case RT_DEVICE_CTRL_RTC_GET_TIME:
  115. *t = mktime(&tmptime);
  116. break;
  117. case RT_DEVICE_CTRL_RTC_SET_TIME:
  118. tmptime.tm_hour = time.tm_hour;
  119. tmptime.tm_min = time.tm_min;
  120. tmptime.tm_sec = time.tm_sec;
  121. tmptime.tm_year = time.tm_year;
  122. tmptime.tm_mon = time.tm_mon;
  123. tmptime.tm_mday = time.tm_mday;
  124. rtctm = mkrtctime(&tmptime);
  125. /* write to hw RTC */
  126. hw_rtc->sys_toywrite0 = rtctm.sys_toyread0;
  127. hw_rtc->sys_toywrite1 = rtctm.sys_toyread1;
  128. break;
  129. case RT_DEVICE_CTRL_RTC_GET_ALARM:
  130. break;
  131. case RT_DEVICE_CTRL_RTC_SET_ALARM:
  132. break;
  133. default:
  134. break;
  135. }
  136. return RT_EOK;
  137. }
  138. int rt_hw_rtc_init(void)
  139. {
  140. static struct rt_device rtc = {
  141. .type = RT_Device_Class_RTC,
  142. .init = RT_NULL,
  143. .open = rt_rtc_open,
  144. .close = RT_NULL,
  145. .read = rt_rtc_read,
  146. .write = RT_NULL,
  147. .control = rt_rtc_ioctl,
  148. .user_data = (void *)RTC_BASE,
  149. };
  150. rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  151. }
  152. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  153. #endif /*RT_USING_RTC*/