drv_rtc.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. * Register RTC device
  118. *
  119. * @details
  120. *
  121. * @note
  122. *
  123. * @param[in] device
  124. * Pointer to device descriptor
  125. *
  126. * @param[in] name
  127. * Device name
  128. *
  129. * @param[in] flag
  130. * Configuration flags
  131. *
  132. * @return
  133. * Error code
  134. ******************************************************************************/
  135. rt_err_t rt_hw_rtc_register(
  136. rt_device_t device,
  137. const char *name,
  138. rt_uint32_t flag)
  139. {
  140. RT_ASSERT(device != RT_NULL);
  141. device->type = RT_Device_Class_RTC;
  142. device->rx_indicate = RT_NULL;
  143. device->tx_complete = RT_NULL;
  144. device->init = RT_NULL;
  145. device->open = rt_rtc_open;
  146. device->close = RT_NULL;
  147. device->read = rt_rtc_read;
  148. device->write = RT_NULL;
  149. device->control = rt_rtc_control;
  150. device->user_data = RT_NULL; /* no private */
  151. /* register a character device */
  152. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  153. }
  154. /***************************************************************************//**
  155. * @brief
  156. * Initialize all RTC module related hardware and register RTC device to kernel
  157. *
  158. * @details
  159. *
  160. * @note
  161. ******************************************************************************/
  162. void rt_hw_rtc_init(void)
  163. {
  164. rt_uint32_t reset;
  165. reset = RMU_ResetCauseGet();
  166. // TODO: What is the current reset mode?
  167. if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST)
  168. {
  169. RTC_Init_TypeDef rtcInit;
  170. efm32_irq_hook_init_t hook;
  171. rtcInit.enable = true;
  172. rtcInit.debugRun = false;
  173. rtcInit.comp0Top = false;
  174. rtc_time = 0UL;
  175. rt_kprintf("rtc is not configured\n");
  176. rt_kprintf("please configure with set_date and set_time\n");
  177. /* Configuring clock */
  178. CMU_ClockDivSet(cmuClock_RTC,cmuClkDiv_32768);
  179. CMU_ClockEnable(cmuClock_RTC, true);
  180. /* Initialize and enable RTC */
  181. RTC_Reset();
  182. RTC_Init(&rtcInit);
  183. hook.type = efm32_irq_type_rtc;
  184. hook.unit = 0;
  185. hook.cbFunc = rt_hw_rtc_isr;
  186. hook.userPtr = RT_NULL;
  187. efm32_irq_hook_register(&hook);
  188. /* Enabling Interrupt from RTC */
  189. RTC_IntEnable(RTC_IFC_OF);
  190. RTC_IntClear(RTC_IFC_OF);
  191. NVIC_ClearPendingIRQ(RTC_IRQn);
  192. NVIC_SetPriority(RTC_IRQn, EFM32_IRQ_PRI_DEFAULT);
  193. NVIC_EnableIRQ(RTC_IRQn);
  194. }
  195. /* register rtc device */
  196. rt_hw_rtc_register(&rtc, RT_RTC_NAME, EFM32_NO_DATA);
  197. }
  198. #endif
  199. /***************************************************************************//**
  200. * @}
  201. ******************************************************************************/