drv_rtc.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-11-4 GuEe-GUI first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <sys/time.h>
  13. #include <board.h>
  14. #include "drv_rtc.h"
  15. #ifdef BSP_USING_RTC
  16. #define RTC_DR 0x00 /* data read register */
  17. #define RTC_MR 0x04 /* match register */
  18. #define RTC_LR 0x08 /* data load register */
  19. #define RTC_CR 0x0c /* control register */
  20. #define RTC_IMSC 0x10 /* interrupt mask and set register */
  21. #define RTC_RIS 0x14 /* raw interrupt status register */
  22. #define RTC_MIS 0x18 /* masked interrupt status register */
  23. #define RTC_ICR 0x1c /* interrupt clear register */
  24. #define RTC_CR_OPEN 1
  25. #define RTC_CR_CLOSE 0
  26. static struct hw_rtc_device rtc_device;
  27. static rt_ubase_t pl031_rtc_base = PL031_RTC_BASE;
  28. rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
  29. {
  30. return (*((volatile unsigned int *)(pl031_rtc_base + offset)));
  31. }
  32. rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
  33. {
  34. (*((volatile unsigned int *)(pl031_rtc_base + offset))) = value;
  35. }
  36. static rt_err_t pl031_rtc_init(rt_device_t dev)
  37. {
  38. return RT_EOK;
  39. }
  40. static rt_err_t pl031_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  41. {
  42. pl031_write32(RTC_CR, RTC_CR_OPEN);
  43. return RT_EOK;
  44. }
  45. static rt_err_t pl031_rtc_close(rt_device_t dev)
  46. {
  47. pl031_write32(RTC_CR, RTC_CR_CLOSE);
  48. return RT_EOK;
  49. }
  50. static rt_err_t pl031_rtc_control(rt_device_t dev, int cmd, void *args)
  51. {
  52. RT_ASSERT(dev != RT_NULL);
  53. switch (cmd)
  54. {
  55. case RT_DEVICE_CTRL_RTC_GET_TIME:
  56. *(rt_uint32_t *)args = pl031_read32(RTC_DR);
  57. break;
  58. case RT_DEVICE_CTRL_RTC_SET_TIME:
  59. pl031_write32(RTC_LR, *(time_t *)args);
  60. break;
  61. default:
  62. return -RT_EINVAL;
  63. }
  64. return RT_EOK;
  65. }
  66. static rt_ssize_t pl031_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  67. {
  68. pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
  69. return size;
  70. }
  71. static rt_ssize_t pl031_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  72. {
  73. pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
  74. return size;
  75. }
  76. const static struct rt_device_ops pl031_rtc_ops =
  77. {
  78. .init = pl031_rtc_init,
  79. .open = pl031_rtc_open,
  80. .close = pl031_rtc_close,
  81. .read = pl031_rtc_read,
  82. .write = pl031_rtc_write,
  83. .control = pl031_rtc_control
  84. };
  85. int rt_hw_rtc_init(void)
  86. {
  87. pl031_rtc_base = (rt_size_t)rt_ioremap((void *)pl031_rtc_base, PL031_RTC_SIZE);
  88. rt_memset(&rtc_device, 0, sizeof(rtc_device));
  89. rtc_device.device.type = RT_Device_Class_RTC;
  90. rtc_device.device.rx_indicate = RT_NULL;
  91. rtc_device.device.tx_complete = RT_NULL;
  92. rtc_device.device.ops = &pl031_rtc_ops;
  93. rtc_device.device.user_data = RT_NULL;
  94. /* register a rtc device */
  95. rt_device_register(&rtc_device.device, "rtc0", RT_DEVICE_FLAG_RDWR);
  96. rt_soft_rtc_set_source("rtc0");
  97. return 0;
  98. }
  99. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  100. #endif /* BSP_USING_RTC */