wm_watchdog.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**
  2. * @file wm_watchdog.c
  3. *
  4. * @brief watchdog Driver Module
  5. *
  6. * @author kevin
  7. *
  8. * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
  9. */
  10. #include "wm_debug.h"
  11. #include "wm_regs.h"
  12. #include "wm_irq.h"
  13. #include "wm_cpu.h"
  14. #include "wm_watchdog.h"
  15. #include "wm_ram_config.h"
  16. #define WDG_LOAD_VALUE_MAX (0xFFFFFFFF / 40)
  17. #define WDG_LOAD_VALUE_DEF (20 * 1000 * 1000)
  18. static volatile u8 wdg_reset = 0;
  19. static volatile u8 wdg_enable = 0;
  20. static volatile u32 wdg_value_us = WDG_LOAD_VALUE_DEF;
  21. static volatile u32 wdg_jumpclear_flag = 0; /*0:donot jump clear, 1: jump clear, 2:close wdg*/
  22. ATTRIBUTE_ISR void WDG_IRQHandler(void)
  23. {
  24. csi_kernel_intrpt_enter();
  25. if (wdg_reset)
  26. {
  27. csi_kernel_intrpt_exit();
  28. return;
  29. }
  30. tls_sys_set_reboot_reason(REBOOT_REASON_WDG_TIMEOUT);
  31. csi_kernel_intrpt_exit();
  32. }
  33. /**
  34. * @brief This function is used to clear watchdog irq in case watchdog reset
  35. *
  36. * @param None
  37. *
  38. * @return None
  39. *
  40. * @note None
  41. */
  42. void tls_watchdog_clr(void)
  43. {
  44. if (0 == wdg_jumpclear_flag)
  45. {
  46. tls_reg_write32(HR_WDG_INT_CLR, 0x01);
  47. }
  48. }
  49. static void __tls_watchdog_init(u32 usec)
  50. {
  51. tls_sys_clk sysclk;
  52. tls_sys_clk_get(&sysclk);
  53. tls_irq_enable(WDG_IRQn);
  54. tls_reg_write32(HR_WDG_LOAD_VALUE, sysclk.apbclk * usec); /* 40M dominant frequency: 40 * 10^6 * (usec / 10^6) */
  55. tls_reg_write32(HR_WDG_CTRL, 0x3); /* enable irq & reset */
  56. }
  57. static void __tls_watchdog_deinit(void)
  58. {
  59. tls_irq_disable(WDG_IRQn);
  60. tls_reg_write32(HR_WDG_CTRL, 0);
  61. tls_reg_write32(HR_WDG_INT_CLR, 0x01);
  62. }
  63. /**
  64. * @brief This function is used to init watchdog
  65. *
  66. * @param[in] usec microseconds
  67. *
  68. * @return None
  69. *
  70. * @note None
  71. */
  72. void tls_watchdog_init(u32 usec)
  73. {
  74. __tls_watchdog_init(usec);
  75. wdg_value_us = usec;
  76. wdg_enable = 1;
  77. }
  78. /**
  79. * @brief This function is used to deinit watchdog
  80. *
  81. * @param[in] None
  82. *
  83. * @return None
  84. *
  85. * @note None
  86. */
  87. void tls_watchdog_deinit(void)
  88. {
  89. __tls_watchdog_deinit();
  90. wdg_value_us = WDG_LOAD_VALUE_DEF;
  91. wdg_enable = 0;
  92. }
  93. /**
  94. * @brief This function is used to start calculating elapsed time.
  95. *
  96. * @param[in] None
  97. *
  98. * @return elapsed time, unit:millisecond
  99. *
  100. * @note None
  101. */
  102. void tls_watchdog_start_cal_elapsed_time(void)
  103. {
  104. if (wdg_enable)
  105. {
  106. wdg_jumpclear_flag = 1;
  107. __tls_watchdog_deinit();
  108. __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
  109. }
  110. else
  111. {
  112. wdg_jumpclear_flag = 2;
  113. __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
  114. }
  115. }
  116. /**
  117. * @brief This function is used to stop calculating & return elapsed time.
  118. *
  119. * @param[in] none
  120. *
  121. * @return elapsed time, unit:millisecond
  122. *
  123. * @note None
  124. */
  125. u32 tls_watchdog_stop_cal_elapsed_time(void)
  126. {
  127. #define RT_TIME_BASE (40)
  128. u32 val = 0;
  129. switch (wdg_jumpclear_flag)
  130. {
  131. case 1:
  132. {
  133. val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
  134. __tls_watchdog_deinit();
  135. __tls_watchdog_init(wdg_value_us);
  136. wdg_jumpclear_flag = 0;
  137. }
  138. break;
  139. case 2:
  140. {
  141. val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
  142. __tls_watchdog_deinit();
  143. wdg_jumpclear_flag = 0;
  144. }
  145. break;
  146. default:
  147. wdg_jumpclear_flag = 0;
  148. break;
  149. }
  150. return val;
  151. }
  152. /**
  153. * @brief This function is used to reset system
  154. *
  155. * @param None
  156. *
  157. * @return None
  158. *
  159. * @note None
  160. */
  161. void tls_sys_reset(void)
  162. {
  163. tls_os_set_critical();
  164. wdg_reset = 1;
  165. __tls_watchdog_deinit();
  166. tls_reg_write32(HR_WDG_LOCK, 0x1ACCE551);
  167. tls_reg_write32(HR_WDG_LOAD_VALUE, 0x100);
  168. tls_reg_write32(HR_WDG_CTRL, 0x3);
  169. tls_reg_write32(HR_WDG_LOCK, 1);
  170. while(1);
  171. }
  172. /**
  173. * @brief This function is used to set reboot reason
  174. *
  175. * @param reason (enum SYS_REBOOT_REASON)
  176. *
  177. * @return None
  178. *
  179. * @note used with tls_sys_reset
  180. */
  181. void tls_sys_set_reboot_reason(u32 reason)
  182. {
  183. tls_reg_write32(SYS_REBOOT_REASON_ADDRESS, reason);
  184. }
  185. /**
  186. * @brief This function is used to get reboot reason
  187. *
  188. * @param None
  189. *
  190. * @return reason (enum SYS_REBOOT_REASON)
  191. *
  192. * @note None
  193. */
  194. int tls_sys_get_reboot_reason(void)
  195. {
  196. u32 rebootval = 0;
  197. rebootval = tls_reg_read32(SYS_REBOOT_REASON_ADDRESS);
  198. if (rebootval >= REBOOT_REASON_MAX)
  199. {
  200. return REBOOT_REASON_POWER_ON;
  201. }
  202. else
  203. {
  204. return rebootval;
  205. }
  206. }