drv_rtc.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /***************************************************************************//**
  2. * @file drv_rtc.c
  3. * @brief RTC driver of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2012, RT-Thread Development Team
  5. * @author Bernard, onelife
  6. * @version 1.0
  7. *******************************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file
  10. * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
  11. *******************************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2009-01-05 Bernard the first version
  15. * 2010-12-27 onelife Modify for EFM32
  16. * 2011-06-16 onelife Modify init function for efm32lib v2 upgrading
  17. * 2011-12-14 onelife Move LFXO enabling routine to driver initialization
  18. * function (board.c)
  19. ******************************************************************************/
  20. /***************************************************************************//**
  21. * @addtogroup efm32
  22. * @{
  23. ******************************************************************************/
  24. /* Includes ------------------------------------------------------------------*/
  25. #include <rtdevice.h>
  26. #include "board.h"
  27. #include "hdl_interrupt.h"
  28. #include "drv_rtc.h"
  29. #if defined(RT_USING_RTC)
  30. /* Private typedef -----------------------------------------------------------*/
  31. /* Private define ------------------------------------------------------------*/
  32. /* Private macro -------------------------------------------------------------*/
  33. #ifdef RT_RTC_DEBUG
  34. #define rtc_debug(format,args...) rt_kprintf(format, ##args)
  35. #else
  36. #define rtc_debug(format,args...)
  37. #endif
  38. /* Private variables ---------------------------------------------------------*/
  39. static struct rt_device rtc;
  40. static rt_uint32_t rtc_time;
  41. /* Private function prototypes -----------------------------------------------*/
  42. /* Private functions ---------------------------------------------------------*/
  43. static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  44. {
  45. if (dev->rx_indicate != RT_NULL)
  46. {
  47. /* Open Interrupt */
  48. }
  49. return RT_EOK;
  50. }
  51. static rt_size_t rt_rtc_read(
  52. rt_device_t dev,
  53. rt_off_t pos,
  54. void* buffer,
  55. rt_size_t size)
  56. {
  57. return 0;
  58. }
  59. /***************************************************************************//**
  60. * @brief
  61. * Configure RTC device
  62. *
  63. * @details
  64. *
  65. * @note
  66. *
  67. * @param[in] dev
  68. * Pointer to device descriptor
  69. *
  70. * @param[in] cmd
  71. * RTC control command
  72. *
  73. * @param[in] args
  74. * Arguments
  75. *
  76. * @return
  77. * Error code
  78. ******************************************************************************/
  79. static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
  80. {
  81. RT_ASSERT(dev != RT_NULL);
  82. switch (cmd)
  83. {
  84. case RT_DEVICE_CTRL_RTC_GET_TIME:
  85. *(rt_uint32_t *)args = rtc_time + RTC_CounterGet();
  86. rtc_debug("RTC: get rtc_time %x + %x\n", rtc_time, RTC_CounterGet());
  87. break;
  88. case RT_DEVICE_CTRL_RTC_SET_TIME:
  89. {
  90. rtc_time = *(rt_uint32_t *)args;
  91. rtc_debug("RTC: set rtc_time %x\n", rtc_time);
  92. /* Reset counter */
  93. RTC_CounterReset();
  94. }
  95. break;
  96. }
  97. return RT_EOK;
  98. }
  99. /***************************************************************************//**
  100. * @brief
  101. * RTC counter overflow interrupt handler
  102. *
  103. * @details
  104. *
  105. * @note
  106. ******************************************************************************/
  107. void rt_hw_rtc_isr(rt_device_t device)
  108. {
  109. if (RTC->IF & RTC_IFC_OF)
  110. {
  111. rtc_time += _RTC_CNT_MASK;
  112. }
  113. RTC->IFC = _RTC_IFC_MASK;
  114. }
  115. /***************************************************************************//**
  116. * @brief
  117. * Initialize all RTC module related hardware and register RTC device to kernel
  118. *
  119. * @details
  120. *
  121. * @note
  122. ******************************************************************************/
  123. void rt_hw_rtc_init(void)
  124. {
  125. rt_uint32_t reset;
  126. reset = RMU_ResetCauseGet();
  127. // TODO: What is the current reset mode?
  128. if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST)
  129. {
  130. RTC_Init_TypeDef rtcInit;
  131. efm32_irq_hook_init_t hook;
  132. rtcInit.enable = true;
  133. rtcInit.debugRun = false;
  134. rtcInit.comp0Top = false;
  135. rtc_time = 0UL;
  136. rt_kprintf("rtc is not configured\n");
  137. rt_kprintf("please configure with set_date and set_time\n");
  138. /* Configuring clock */
  139. CMU_ClockDivSet(cmuClock_RTC,cmuClkDiv_32768);
  140. CMU_ClockEnable(cmuClock_RTC, true);
  141. /* Initialize and enable RTC */
  142. RTC_Reset();
  143. RTC_Init(&rtcInit);
  144. hook.type = efm32_irq_type_rtc;
  145. hook.unit = 0;
  146. hook.cbFunc = rt_hw_rtc_isr;
  147. hook.userPtr = RT_NULL;
  148. efm32_irq_hook_register(&hook);
  149. /* Enabling Interrupt from RTC */
  150. RTC_IntEnable(RTC_IFC_OF);
  151. RTC_IntClear(RTC_IFC_OF);
  152. NVIC_ClearPendingIRQ(RTC_IRQn);
  153. NVIC_SetPriority(RTC_IRQn, EFM32_IRQ_PRI_DEFAULT);
  154. NVIC_EnableIRQ(RTC_IRQn);
  155. }
  156. /* register rtc device */
  157. rtc.type = RT_Device_Class_RTC;
  158. rtc.rx_indicate = RT_NULL;
  159. rtc.tx_complete = RT_NULL;
  160. rtc.init = RT_NULL;
  161. rtc.open = rt_rtc_open;
  162. rtc.close = RT_NULL;
  163. rtc.read = rt_rtc_read;
  164. rtc.write = RT_NULL;
  165. rtc.control = rt_rtc_control;
  166. rtc.user_data = RT_NULL; /* no private */
  167. rt_device_register(&rtc, RT_RTC_NAME, RT_DEVICE_FLAG_RDWR | EFM32_NO_DATA);
  168. }
  169. #endif
  170. /***************************************************************************//**
  171. * @}
  172. ******************************************************************************/