rtc-ds1302.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-09-23 GuEe-GUI first version
  9. */
  10. #include "rtc_dm.h"
  11. #define DBG_TAG "rtc.ds1302"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #define RTC_CMD_READ 0x81 /* Read command */
  15. #define RTC_CMD_WRITE 0x80 /* Write command */
  16. #define RTC_CMD_WRITE_ENABLE 0x00 /* Write enable */
  17. #define RTC_CMD_WRITE_DISABLE 0x80 /* Write disable */
  18. #define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */
  19. #define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */
  20. #define RTC_CLCK_BURST 0x1F /* Address of clock burst */
  21. #define RTC_CLCK_LEN 0x08 /* Size of clock burst */
  22. #define RTC_ADDR_CTRL 0x07 /* Address of control register */
  23. #define RTC_ADDR_YEAR 0x06 /* Address of year register */
  24. #define RTC_ADDR_DAY 0x05 /* Address of day of week register */
  25. #define RTC_ADDR_MON 0x04 /* Address of month register */
  26. #define RTC_ADDR_DATE 0x03 /* Address of day of month register */
  27. #define RTC_ADDR_HOUR 0x02 /* Address of hour register */
  28. #define RTC_ADDR_MIN 0x01 /* Address of minute register */
  29. #define RTC_ADDR_SEC 0x00 /* Address of second register */
  30. static rt_err_t ds1302_rtc_get_time(struct rt_spi_device *spi_dev, time_t *sec)
  31. {
  32. struct tm tm;
  33. rt_err_t err;
  34. rt_uint8_t addr = RTC_CLCK_BURST << 1 | RTC_CMD_READ, buf[RTC_CLCK_LEN - 1];
  35. err = rt_spi_send_then_recv(spi_dev, &addr, sizeof(addr), buf, sizeof(buf));
  36. if (err)
  37. {
  38. return err;
  39. }
  40. /* Decode the registers */
  41. tm.tm_sec = rt_bcd2bin(buf[RTC_ADDR_SEC]);
  42. tm.tm_min = rt_bcd2bin(buf[RTC_ADDR_MIN]);
  43. tm.tm_hour = rt_bcd2bin(buf[RTC_ADDR_HOUR]);
  44. tm.tm_wday = buf[RTC_ADDR_DAY] - 1;
  45. tm.tm_mday = rt_bcd2bin(buf[RTC_ADDR_DATE]);
  46. tm.tm_mon = rt_bcd2bin(buf[RTC_ADDR_MON]) - 1;
  47. tm.tm_year = rt_bcd2bin(buf[RTC_ADDR_YEAR]) + 100;
  48. *sec = timegm(&tm);
  49. return RT_EOK;
  50. }
  51. static rt_err_t ds1302_rtc_set_time(struct rt_spi_device *spi_dev, time_t *sec)
  52. {
  53. rt_err_t err;
  54. struct tm *tm;
  55. rt_uint8_t buf[1 + RTC_CLCK_LEN], *bp;
  56. tm = localtime(sec);
  57. /* Enable writing */
  58. bp = buf;
  59. *bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
  60. *bp++ = RTC_CMD_WRITE_ENABLE;
  61. err = rt_spi_send_then_recv(spi_dev, buf, 2, RT_NULL, 0);
  62. if (err)
  63. {
  64. return err;
  65. }
  66. /* Write registers starting at the first time/date address. */
  67. bp = buf;
  68. *bp++ = RTC_CLCK_BURST << 1 | RTC_CMD_WRITE;
  69. *bp++ = rt_bin2bcd(tm->tm_sec);
  70. *bp++ = rt_bin2bcd(tm->tm_min);
  71. *bp++ = rt_bin2bcd(tm->tm_hour);
  72. *bp++ = rt_bin2bcd(tm->tm_mday);
  73. *bp++ = rt_bin2bcd(tm->tm_mon + 1);
  74. *bp++ = tm->tm_wday + 1;
  75. *bp++ = rt_bin2bcd(tm->tm_year % 100);
  76. *bp++ = RTC_CMD_WRITE_DISABLE;
  77. return rt_spi_send_then_recv(spi_dev, buf, sizeof(buf), RT_NULL, 0);
  78. }
  79. static rt_err_t ds1302_rtc_control(rt_device_t dev, int cmd, void *args)
  80. {
  81. rt_err_t err = RT_EOK;
  82. struct rt_spi_device *spi_dev = dev->user_data;
  83. if (!args)
  84. {
  85. return -RT_EINVAL;
  86. }
  87. switch (cmd)
  88. {
  89. case RT_DEVICE_CTRL_RTC_GET_TIME:
  90. err = ds1302_rtc_get_time(spi_dev, args);
  91. break;
  92. case RT_DEVICE_CTRL_RTC_SET_TIME:
  93. err = ds1302_rtc_set_time(spi_dev, args);
  94. break;
  95. case RT_DEVICE_CTRL_RTC_GET_TIMEVAL:
  96. err = ds1302_rtc_get_time(spi_dev, (time_t *)&((struct timeval *)args)->tv_sec);
  97. break;
  98. case RT_DEVICE_CTRL_RTC_SET_TIMEVAL:
  99. err = ds1302_rtc_set_time(spi_dev, (time_t *)&((struct timeval *)args)->tv_sec);
  100. break;
  101. case RT_DEVICE_CTRL_RTC_GET_ALARM:
  102. case RT_DEVICE_CTRL_RTC_SET_ALARM:
  103. err = -RT_ENOSYS;
  104. break;
  105. default:
  106. err = -RT_EINVAL;
  107. break;
  108. }
  109. return err;
  110. }
  111. #ifdef RT_USING_DEVICE_OPS
  112. const static struct rt_device_ops ds1302_rtc_ops =
  113. {
  114. .control = ds1302_rtc_control,
  115. };
  116. #endif
  117. static rt_err_t ds1302_rtc_probe(struct rt_spi_device *spi_dev)
  118. {
  119. rt_err_t err = RT_EOK;
  120. const char *dev_name;
  121. rt_uint8_t addr, buf[4];
  122. if (spi_dev->config.max_hz > 2000000)
  123. {
  124. LOG_E("Speed is too high");
  125. return -RT_EINVAL;
  126. }
  127. else if (spi_dev->config.mode & RT_SPI_CPHA)
  128. {
  129. LOG_E("Bad mode");
  130. return -RT_EINVAL;
  131. }
  132. addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
  133. if ((err = rt_spi_send_then_recv(spi_dev, &addr, sizeof(addr), buf, 1)))
  134. {
  135. LOG_E("Control register read error = %s", rt_strerror(err));
  136. return err;
  137. }
  138. if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0)
  139. {
  140. if ((err = rt_spi_send_then_recv(spi_dev, &addr, sizeof(addr), buf, 1)))
  141. {
  142. LOG_E("Control register read error = %s", rt_strerror(err));
  143. return err;
  144. }
  145. if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0)
  146. {
  147. LOG_E("Junk in control register");
  148. return -RT_EIO;
  149. }
  150. }
  151. if (buf[0] == 0)
  152. {
  153. buf[0] = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
  154. buf[1] = RTC_CMD_WRITE_DISABLE;
  155. if ((err = rt_spi_send_then_recv(spi_dev, buf, 2, RT_NULL, 0)))
  156. {
  157. LOG_E("Control register write error = %s", rt_strerror(err));
  158. return err;
  159. }
  160. addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
  161. if ((err = rt_spi_send_then_recv(spi_dev, &addr, sizeof(addr), buf, 1)))
  162. {
  163. LOG_E("Reading control register error = %s", rt_strerror(err));
  164. return err;
  165. }
  166. if (buf[0] != RTC_CMD_WRITE_DISABLE)
  167. {
  168. LOG_E("Failed to detect chip");
  169. return -RT_EIO;
  170. }
  171. }
  172. spi_dev->parent.user_data = spi_dev;
  173. spi_dev->parent.type = RT_Device_Class_RTC;
  174. #ifdef RT_USING_DEVICE_OPS
  175. spi_dev->parent.ops = &ds1302_rtc_ops;
  176. #else
  177. spi_dev->parent.control = ds1302_rtc_control;
  178. #endif
  179. rtc_dev_set_name(&spi_dev->parent);
  180. dev_name = rt_dm_dev_get_name(&spi_dev->parent);
  181. err = rt_device_register(&spi_dev->parent, dev_name, RT_DEVICE_FLAG_RDWR);
  182. return err;
  183. }
  184. static rt_err_t ds1302_rtc_remove(struct rt_spi_device *spi_dev)
  185. {
  186. rt_device_unregister(&spi_dev->parent);
  187. return RT_EOK;
  188. }
  189. static const struct rt_spi_device_id ds1302_rtc_ids[] =
  190. {
  191. { .name = "ds1302" },
  192. { /* sentinel */ },
  193. };
  194. static const struct rt_ofw_node_id ds1302_rtc_ofw_ids[] =
  195. {
  196. { .compatible = "maxim,ds1302" },
  197. { /* sentinel */ },
  198. };
  199. static struct rt_spi_driver ds1302_rtc_driver =
  200. {
  201. .ids = ds1302_rtc_ids,
  202. .ofw_ids = ds1302_rtc_ofw_ids,
  203. .probe = ds1302_rtc_probe,
  204. .remove = ds1302_rtc_remove,
  205. };
  206. RT_SPI_DRIVER_EXPORT(ds1302_rtc_driver);