rtc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. * 2010-03-18 Gary Lee add functions such as GregorianDay
  14. * and rtc_time_to_tm
  15. * 2009-03-20 yi.qiu clean up
  16. */
  17. #include <rtthread.h>
  18. #include <time.h>
  19. #include <s3c24x0.h>
  20. // #define RTC_DEBUG
  21. #define RTC_ENABLE RTCCON |= 0x01; /*RTC read and write enable */
  22. #define RTC_DISABLE RTCCON &= ~0x01; /* RTC read and write disable */
  23. #define BCD2BIN(n) (((((n) >> 4) & 0x0F) * 10) + ((n) & 0x0F))
  24. #define BIN2BCD(n) ((((n) / 10) << 4) | ((n) % 10))
  25. /**
  26. * This function get rtc time
  27. */
  28. void rt_hw_rtc_get(struct tm *ti)
  29. {
  30. rt_uint8_t sec, min, hour, mday, wday, mon, year;
  31. /* enable access to RTC registers */
  32. RTCCON |= RTC_ENABLE;
  33. /* read RTC registers */
  34. do
  35. {
  36. sec = BCDSEC;
  37. min = BCDMIN;
  38. hour = BCDHOUR;
  39. mday = BCDDATE;
  40. wday = BCDDAY;
  41. mon = BCDMON;
  42. year = BCDYEAR;
  43. } while (sec != BCDSEC);
  44. #ifdef RTC_DEBUG
  45. rt_kprintf("sec:%x min:%x hour:%x mday:%x wday:%x mon:%x year:%x\n",
  46. sec, min, hour, mday, wday, mon, year);
  47. #endif
  48. /* disable access to RTC registers */
  49. RTC_DISABLE
  50. ti->tm_sec = BCD2BIN(sec & 0x7F);
  51. ti->tm_min = BCD2BIN(min & 0x7F);
  52. ti->tm_hour = BCD2BIN(hour & 0x3F);
  53. ti->tm_mday = BCD2BIN(mday & 0x3F);
  54. ti->tm_mon = BCD2BIN(mon & 0x1F);
  55. ti->tm_year = BCD2BIN(year);
  56. ti->tm_wday = BCD2BIN(wday & 0x07);
  57. ti->tm_yday = 0;
  58. ti->tm_isdst = 0;
  59. }
  60. /**
  61. * This function set rtc time
  62. */
  63. void rt_hw_rtc_set(struct tm *ti)
  64. {
  65. rt_uint8_t sec, min, hour, mday, wday, mon, year;
  66. year = BIN2BCD(ti->tm_year);
  67. mon = BIN2BCD(ti->tm_mon);
  68. wday = BIN2BCD(ti->tm_wday);
  69. mday = BIN2BCD(ti->tm_mday);
  70. hour = BIN2BCD(ti->tm_hour);
  71. min = BIN2BCD(ti->tm_min);
  72. sec = BIN2BCD(ti->tm_sec);
  73. /* enable access to RTC registers */
  74. RTC_ENABLE
  75. do{
  76. /* write RTC registers */
  77. BCDSEC = sec;
  78. BCDMIN = min;
  79. BCDHOUR = hour;
  80. BCDDATE = mday;
  81. BCDDAY = wday;
  82. BCDMON = mon;
  83. BCDYEAR = year;
  84. }while (sec != BCDSEC);
  85. /* disable access to RTC registers */
  86. RTC_DISABLE
  87. }
  88. /**
  89. * This function reset rtc
  90. */
  91. void rt_hw_rtc_reset (void)
  92. {
  93. RTCCON = (RTCCON & ~0x06) | 0x08;
  94. RTCCON &= ~(0x08|0x01);
  95. }
  96. static struct rt_device rtc;
  97. static rt_err_t rtc_open(rt_device_t dev, rt_uint16_t oflag)
  98. {
  99. RTC_ENABLE
  100. return RT_EOK;
  101. }
  102. static rt_err_t rtc_close(rt_device_t dev)
  103. {
  104. RTC_DISABLE
  105. return RT_EOK;
  106. }
  107. static rt_size_t rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  108. {
  109. return RT_EOK;
  110. }
  111. static rt_err_t rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  112. {
  113. struct tm tm, *tm_ptr;
  114. time_t *time;
  115. RT_ASSERT(dev != RT_NULL);
  116. time = (time_t *)args;
  117. switch (cmd)
  118. {
  119. case RT_DEVICE_CTRL_RTC_GET_TIME:
  120. /* read device */
  121. rt_hw_rtc_get(&tm);
  122. *((rt_time_t *)args) = mktime(&tm);
  123. break;
  124. case RT_DEVICE_CTRL_RTC_SET_TIME:
  125. tm_ptr = localtime(time);
  126. /* write device */
  127. rt_hw_rtc_set(tm_ptr);
  128. break;
  129. }
  130. return RT_EOK;
  131. }
  132. void rt_hw_rtc_init(void)
  133. {
  134. rtc.type = RT_Device_Class_RTC;
  135. /* register rtc device */
  136. rtc.init = RT_NULL;
  137. rtc.open = rtc_open;
  138. rtc.close = rtc_close;
  139. rtc.read = rtc_read;
  140. rtc.write = RT_NULL;
  141. rtc.control = rtc_control;
  142. /* no private */
  143. rtc.user_data = RT_NULL;
  144. rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  145. }
  146. #ifdef RT_USING_FINSH
  147. #include <finsh.h>
  148. void list_date()
  149. {
  150. time_t time;
  151. rt_device_t device;
  152. device = rt_device_find("rtc");
  153. if (device != RT_NULL)
  154. {
  155. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
  156. rt_kprintf("%d, %s\n", time, ctime(&time));
  157. }
  158. }
  159. FINSH_FUNCTION_EXPORT(list_date, list date);
  160. #endif