wm_watchdog.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. #define WDG_LOAD_VALUE_MAX (0xFFFFFFFF / 40)
  16. #define WDG_LOAD_VALUE_DEF (20 * 1000 * 1000)
  17. static volatile u8 wdg_reset = 0;
  18. static volatile u8 wdg_enable = 0;
  19. static volatile u32 wdg_value_us = WDG_LOAD_VALUE_DEF;
  20. static volatile u32 wdg_jumpclear_flag = 0; /*0:donot jump clear, 1: jump clear, 2:close wdg*/
  21. ATTRIBUTE_ISR void WDG_IRQHandler(void)
  22. {
  23. csi_kernel_intrpt_enter();
  24. if (wdg_reset)
  25. {
  26. csi_kernel_intrpt_exit();
  27. return;
  28. }
  29. csi_kernel_intrpt_exit();
  30. }
  31. /**
  32. * @brief This function is used to clear watchdog irq in case watchdog reset
  33. *
  34. * @param None
  35. *
  36. * @return None
  37. *
  38. * @note None
  39. */
  40. void tls_watchdog_clr(void)
  41. {
  42. if (0 == wdg_jumpclear_flag)
  43. {
  44. tls_reg_write32(HR_WDG_INT_CLR, 0x01);
  45. }
  46. }
  47. static void __tls_watchdog_init(u32 usec)
  48. {
  49. tls_sys_clk sysclk;
  50. tls_sys_clk_get(&sysclk);
  51. tls_irq_enable(WDG_IRQn);
  52. tls_reg_write32(HR_WDG_LOAD_VALUE, sysclk.apbclk * usec); /* 40M dominant frequency: 40 * 10^6 * (usec / 10^6) */
  53. tls_reg_write32(HR_WDG_CTRL, 0x3); /* enable irq & reset */
  54. }
  55. static void __tls_watchdog_deinit(void)
  56. {
  57. tls_irq_disable(WDG_IRQn);
  58. tls_reg_write32(HR_WDG_CTRL, 0);
  59. tls_reg_write32(HR_WDG_INT_CLR, 0x01);
  60. }
  61. /**
  62. * @brief This function is used to init watchdog
  63. *
  64. * @param[in] usec microseconds
  65. *
  66. * @return None
  67. *
  68. * @note None
  69. */
  70. void tls_watchdog_init(u32 usec)
  71. {
  72. __tls_watchdog_init(usec);
  73. wdg_value_us = usec;
  74. wdg_enable = 1;
  75. }
  76. /**
  77. * @brief This function is used to deinit watchdog
  78. *
  79. * @param[in] None
  80. *
  81. * @return None
  82. *
  83. * @note None
  84. */
  85. void tls_watchdog_deinit(void)
  86. {
  87. __tls_watchdog_deinit();
  88. wdg_value_us = WDG_LOAD_VALUE_DEF;
  89. wdg_enable = 0;
  90. }
  91. /**
  92. * @brief This function is used to start calculating elapsed time.
  93. *
  94. * @param[in] None
  95. *
  96. * @return elapsed time, unit:millisecond
  97. *
  98. * @note None
  99. */
  100. void tls_watchdog_start_cal_elapsed_time(void)
  101. {
  102. if (wdg_enable)
  103. {
  104. wdg_jumpclear_flag = 1;
  105. __tls_watchdog_deinit();
  106. __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
  107. }
  108. else
  109. {
  110. wdg_jumpclear_flag = 2;
  111. __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
  112. }
  113. }
  114. /**
  115. * @brief This function is used to stop calculating & return elapsed time.
  116. *
  117. * @param[in] none
  118. *
  119. * @return elapsed time, unit:millisecond
  120. *
  121. * @note None
  122. */
  123. u32 tls_watchdog_stop_cal_elapsed_time(void)
  124. {
  125. #define RT_TIME_BASE (40)
  126. u32 val = 0;
  127. switch (wdg_jumpclear_flag)
  128. {
  129. case 1:
  130. {
  131. val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
  132. __tls_watchdog_deinit();
  133. __tls_watchdog_init(wdg_value_us);
  134. wdg_jumpclear_flag = 0;
  135. }
  136. break;
  137. case 2:
  138. {
  139. val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
  140. __tls_watchdog_deinit();
  141. wdg_jumpclear_flag = 0;
  142. }
  143. break;
  144. default:
  145. wdg_jumpclear_flag = 0;
  146. break;
  147. }
  148. return val;
  149. }
  150. /**
  151. * @brief This function is used to reset system
  152. *
  153. * @param None
  154. *
  155. * @return None
  156. *
  157. * @note None
  158. */
  159. void tls_sys_reset(void)
  160. {
  161. tls_os_set_critical();
  162. wdg_reset = 1;
  163. __tls_watchdog_deinit();
  164. tls_reg_write32(HR_WDG_LOCK, 0x1ACCE551);
  165. tls_reg_write32(HR_WDG_LOAD_VALUE, 0x100);
  166. tls_reg_write32(HR_WDG_CTRL, 0x3);
  167. tls_reg_write32(HR_WDG_LOCK, 1);
  168. while(1);
  169. }