1
0

drv_rtc.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
  28. {
  29. return (*((volatile unsigned int *)(PL031_RTC_BASE + offset)));
  30. }
  31. rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
  32. {
  33. (*((volatile unsigned int *)(PL031_RTC_BASE + offset))) = value;
  34. }
  35. static rt_err_t pl031_rtc_init(rt_device_t dev)
  36. {
  37. return RT_EOK;
  38. }
  39. static rt_err_t pl031_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  40. {
  41. pl031_write32(RTC_CR, RTC_CR_OPEN);
  42. return RT_EOK;
  43. }
  44. static rt_err_t pl031_rtc_close(rt_device_t dev)
  45. {
  46. pl031_write32(RTC_CR, RTC_CR_CLOSE);
  47. return RT_EOK;
  48. }
  49. static rt_err_t pl031_rtc_control(rt_device_t dev, int cmd, void *args)
  50. {
  51. RT_ASSERT(dev != RT_NULL);
  52. switch (cmd)
  53. {
  54. case RT_DEVICE_CTRL_RTC_GET_TIME:
  55. *(rt_uint32_t *)args = pl031_read32(RTC_DR);
  56. break;
  57. case RT_DEVICE_CTRL_RTC_SET_TIME:
  58. pl031_write32(RTC_LR, *(time_t *)args);
  59. break;
  60. default:
  61. return RT_EINVAL;
  62. }
  63. return RT_EOK;
  64. }
  65. static rt_size_t pl031_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  66. {
  67. pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
  68. return size;
  69. }
  70. static rt_size_t pl031_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  71. {
  72. pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
  73. return size;
  74. }
  75. const static struct rt_device_ops pl031_rtc_ops =
  76. {
  77. .init = pl031_rtc_init,
  78. .open = pl031_rtc_open,
  79. .close = pl031_rtc_close,
  80. .read = pl031_rtc_read,
  81. .write = pl031_rtc_write,
  82. .control = pl031_rtc_control
  83. };
  84. int rt_hw_rtc_init(void)
  85. {
  86. rt_memset(&rtc_device, 0, sizeof(rtc_device));
  87. rtc_device.device.type = RT_Device_Class_RTC;
  88. rtc_device.device.rx_indicate = RT_NULL;
  89. rtc_device.device.tx_complete = RT_NULL;
  90. rtc_device.device.ops = &pl031_rtc_ops;
  91. rtc_device.device.user_data = RT_NULL;
  92. /* register a rtc device */
  93. rt_device_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR);
  94. return 0;
  95. }
  96. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  97. #endif /* BSP_USING_RTC */