rtc.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * File : rtc.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-04-26 yi.qiu first version
  13. */
  14. #include <rtthread.h>
  15. #include <time.h>
  16. #include <s3c24x0.h>
  17. #define BCD2BIN(n) (((((n) >> 4) & 0x0F) * 10) + ((n) & 0x0F))
  18. #define BIN2BCD(n) ((((n) / 10) << 4) | ((n) % 10))
  19. /**
  20. * This function get rtc time
  21. */
  22. void rt_hw_rtc_get(struct tm *ti)
  23. {
  24. rt_uint8_t sec, min, hour, mday, wday, mon, year;
  25. /* enable access to RTC registers */
  26. RTCCON |= 0x01;
  27. /* read RTC registers */
  28. do
  29. {
  30. sec = BCDSEC;
  31. min = BCDMIN;
  32. hour = BCDHOUR;
  33. mday = BCDDATE;
  34. wday = BCDDAY;
  35. mon = BCDMON;
  36. year = BCDYEAR;
  37. } while (sec != BCDSEC);
  38. /* disable access to RTC registers */
  39. RTCCON &= ~0x01;
  40. ti->tm_sec = BCD2BIN(sec & 0x7F);
  41. ti->tm_min = BCD2BIN(min & 0x7F);
  42. ti->tm_hour = BCD2BIN(hour & 0x3F);
  43. ti->tm_mday = BCD2BIN(mday & 0x3F);
  44. ti->tm_mon = BCD2BIN(mon & 0x1F);
  45. ti->tm_year = BCD2BIN(year);
  46. ti->tm_wday = BCD2BIN(wday & 0x07);
  47. ti->tm_yday = 0;
  48. ti->tm_isdst = 0;
  49. }
  50. /**
  51. * This function set rtc time
  52. */
  53. void rt_hw_rtc_set(struct tm *ti)
  54. {
  55. rt_uint8_t sec, min, hour, mday, wday, mon, year;
  56. year = BIN2BCD(ti->tm_year);
  57. mon = BIN2BCD(ti->tm_mon);
  58. wday = BIN2BCD(ti->tm_wday);
  59. mday = BIN2BCD(ti->tm_mday);
  60. hour = BIN2BCD(ti->tm_hour);
  61. min = BIN2BCD(ti->tm_min);
  62. sec = BIN2BCD(ti->tm_sec);
  63. /* enable access to RTC registers */
  64. RTCCON |= 0x01;
  65. /* write RTC registers */
  66. BCDSEC = sec;
  67. BCDMIN = min;
  68. BCDHOUR = hour;
  69. BCDDATE = mday;
  70. BCDDAY = wday;
  71. BCDMON = mon;
  72. BCDYEAR = year;
  73. /* disable access to RTC registers */
  74. RTCCON &= ~0x01;
  75. }
  76. /**
  77. * This function reset rtc
  78. */
  79. void rt_hw_rtc_reset (void)
  80. {
  81. RTCCON = (RTCCON & ~0x06) | 0x08;
  82. RTCCON &= ~(0x08|0x01);
  83. }
  84. static struct rt_device rtc;
  85. static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  86. {
  87. return RT_EOK;
  88. }
  89. static rt_size_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  90. {
  91. return 0;
  92. }
  93. static rt_err_t rt_rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  94. {
  95. struct tm* ti;
  96. RT_ASSERT(dev != RT_NULL);
  97. ti = (struct tm*)args;
  98. switch (cmd)
  99. {
  100. case RT_DEVICE_CTRL_RTC_GET_TIME:
  101. /* read device */
  102. rt_hw_rtc_get(ti);
  103. break;
  104. case RT_DEVICE_CTRL_RTC_SET_TIME:
  105. /* write device */
  106. rt_hw_rtc_set(ti);
  107. break;
  108. }
  109. return RT_EOK;
  110. }
  111. void rt_hw_rtc_init(void)
  112. {
  113. rtc.type = RT_Device_Class_RTC;
  114. /* register rtc device */
  115. rtc.init = RT_NULL;
  116. rtc.open = rt_rtc_open;
  117. rtc.close = RT_NULL;
  118. rtc.read = rt_rtc_read;
  119. rtc.write = RT_NULL;
  120. rtc.control = rt_rtc_control;
  121. /* no private */
  122. rtc.private = RT_NULL;
  123. rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  124. return;
  125. }
  126. time_t time(time_t* t)
  127. {
  128. rt_device_t device;
  129. struct tm ti;
  130. time_t time;
  131. device = rt_device_find("rtc");
  132. if (device != RT_NULL)
  133. {
  134. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
  135. if (t != RT_NULL)
  136. {
  137. time = mktime(&ti);
  138. *t = time;
  139. }
  140. }
  141. return time;
  142. }
  143. #ifdef RT_USING_FINSH
  144. #include <finsh.h>
  145. void set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
  146. {
  147. struct tm ti;
  148. rt_device_t device;
  149. device = rt_device_find("rtc");
  150. if (device != RT_NULL)
  151. {
  152. rt_rtc_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
  153. ti.tm_year = year - 1900;
  154. ti.tm_mon = month - 1;
  155. ti.tm_mday = day;
  156. rt_rtc_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &ti);
  157. }
  158. }
  159. FINSH_FUNCTION_EXPORT(set_date, set date)
  160. void set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
  161. {
  162. struct tm ti;
  163. rt_device_t device;
  164. device = rt_device_find("rtc");
  165. if (device != RT_NULL)
  166. {
  167. rt_rtc_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
  168. ti.tm_hour = hour;
  169. ti.tm_min = minute;
  170. ti.tm_sec = second;
  171. rt_rtc_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &ti);
  172. }
  173. }
  174. FINSH_FUNCTION_EXPORT(set_time, set second)
  175. void list_date()
  176. {
  177. time_t now;
  178. time(&now);
  179. rt_kprintf("%s\n", ctime(&now));
  180. }
  181. FINSH_FUNCTION_EXPORT(list_date, set date)
  182. #endif