drv_rtc_ch32f20x.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. * 2022-01-21 charlown first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <sys/time.h>
  13. #include "board.h"
  14. #ifdef BSP_USING_RTC
  15. #define LOG_TAG "drv.rtc"
  16. #include "drv_log.h"
  17. #ifndef BKP_DR1
  18. #define BKP_DR1 RT_NULL
  19. #endif
  20. #define BKUP_REG_DATA 0xA5A5
  21. static struct rt_rtc_device rtc;
  22. static void rt_rtc_config(void)
  23. {
  24. /* Allow access to BKP Domain */
  25. PWR_BackupAccessCmd(ENABLE);
  26. #if defined(BSP_USING_RTC_LSI) && defined(LSI_VALUE)
  27. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  28. #else
  29. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  30. #endif
  31. RCC_RTCCLKCmd(ENABLE);
  32. RTC_WaitForLastTask();
  33. RTC_WaitForSynchro();
  34. if (BKP_ReadBackupRegister(BKP_DR1) != BKUP_REG_DATA)
  35. {
  36. LOG_I("RTC hasn't been configured, please use <date> command to config.");
  37. /* Set RTC prescaler: set RTC period to 1sec */
  38. RTC_SetPrescaler(32767);
  39. /* Wait until last write operation on RTC registers has finished */
  40. RTC_WaitForLastTask();
  41. }
  42. }
  43. static rt_err_t ch32f2_rt_rtc_init(void)
  44. {
  45. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  46. PWR_BackupAccessCmd(ENABLE);
  47. #if defined(BSP_USING_RTC_LSI) && defined(LSI_VALUE)
  48. RCC_LSICmd(ENABLE);
  49. while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  50. ;
  51. #else
  52. RCC_LSEConfig(RCC_LSE_ON);
  53. while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  54. ;
  55. #endif
  56. rt_rtc_config();
  57. return RT_EOK;
  58. }
  59. static rt_err_t ch32f2_get_secs(void *args)
  60. {
  61. *(rt_uint32_t *)args = RTC_GetCounter();
  62. LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
  63. return RT_EOK;
  64. }
  65. static rt_err_t ch32f2_set_secs(void *args)
  66. {
  67. /* Set the RTC counter value */
  68. RTC_SetCounter(*(rt_uint32_t *)args);
  69. /* Wait until last write operation on RTC registers has finished */
  70. RTC_WaitForLastTask();
  71. LOG_D("set rtc time.");
  72. BKP_WriteBackupRegister(BKP_DR1, BKUP_REG_DATA);
  73. LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  74. return RT_EOK;
  75. }
  76. const static struct rt_rtc_ops rtc_ops =
  77. {
  78. .init = ch32f2_rt_rtc_init,
  79. .get_secs = ch32f2_get_secs,
  80. .set_secs = ch32f2_set_secs,
  81. .get_alarm = RT_NULL,
  82. .set_alarm = RT_NULL,
  83. .get_timeval = RT_NULL,
  84. .set_timeval = RT_NULL};
  85. int rt_hw_rtc_init(void)
  86. {
  87. rt_err_t result;
  88. rtc.ops = &rtc_ops;
  89. result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
  90. if (result != RT_EOK)
  91. {
  92. LOG_E("rtc register err code: %d", result);
  93. return result;
  94. }
  95. LOG_D("rtc init success");
  96. return RT_EOK;
  97. }
  98. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  99. #endif /* BSP_USING_RTC */