drv_wdt.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-05-24 QT-one first version
  9. */
  10. #include <rtdbg.h>
  11. #include "drv_wdt.h"
  12. #ifdef BSP_USING_WDT
  13. struct ht32_wdt
  14. {
  15. struct rt_watchdog_device ht32_wdt_device;
  16. rt_uint8_t ht32_wdt_start_flag;
  17. };
  18. static struct ht32_wdt ht32_wdt_obj;
  19. /* Initialization functions for wdt */
  20. static rt_err_t ht32_wdt_init(rt_watchdog_t *wdt)
  21. {
  22. return -RT_ERROR;
  23. }
  24. /* Control function for wdt */
  25. static rt_err_t ht32_wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
  26. {
  27. rt_uint16_t wdt_time_val = (*((rt_uint16_t*)arg));
  28. switch(cmd)
  29. {
  30. /* get timeout(in seconds) */
  31. case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
  32. (*((rt_uint16_t*)arg)) = (WDT_GetReloadValue())/250;
  33. break;
  34. /* set timeout(in seconds) */
  35. case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
  36. if(ht32_wdt_obj.ht32_wdt_start_flag)
  37. {
  38. LOG_W("Please stop the WDT device first.");
  39. }
  40. else
  41. {
  42. if(wdt_time_val > 16)
  43. {
  44. LOG_W("Parameter out of settable range.");
  45. }
  46. else
  47. {
  48. /* Disable WDT Protection */
  49. WDT_ProtectCmd(DISABLE);
  50. /* Reset WDT */
  51. WDT_DeInit();
  52. /* Set Prescaler Value, 32K/128 = 250Hz 4ms */
  53. WDT_SetPrescaler(WDT_PRESCALER_128);
  54. /* Set Prescaler Value, 250Hz*wdt_time_val*250 = nms */
  55. WDT_SetReloadValue((wdt_time_val*250));
  56. /* Set Delta Value, 250Hz*wdt_time_val*250 = nms */
  57. WDT_SetDeltaValue((wdt_time_val*250));
  58. /* Enable the WDT Reset when WDT meets underflow or error */
  59. WDT_ResetCmd(ENABLE);
  60. /* Reload Counter as WDTV Value */
  61. WDT_Restart();
  62. }
  63. }
  64. break;
  65. /* get the left time before reboot(in seconds) */
  66. case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
  67. return -RT_ERROR;
  68. /* refresh watchdog */
  69. case RT_DEVICE_CTRL_WDT_KEEPALIVE:
  70. if(ht32_wdt_obj.ht32_wdt_start_flag)
  71. {
  72. /* Enable WDT Restart (Reload WDT Counter) */
  73. WDT_Restart();
  74. }
  75. else
  76. {
  77. LOG_W("WDT device not activated.");
  78. }
  79. break;
  80. /* start watchdog */
  81. case RT_DEVICE_CTRL_WDT_START:
  82. if(ht32_wdt_obj.ht32_wdt_start_flag)
  83. {
  84. LOG_W("The WDT device has been activated.");
  85. }
  86. else
  87. {
  88. /* Enable WDT */
  89. WDT_Cmd(ENABLE);
  90. /* Enable WDT Protection */
  91. WDT_ProtectCmd(ENABLE);
  92. ht32_wdt_obj.ht32_wdt_start_flag = 1;
  93. }
  94. break;
  95. /* stop watchdog */
  96. case RT_DEVICE_CTRL_WDT_STOP:
  97. if(ht32_wdt_obj.ht32_wdt_start_flag)
  98. {
  99. /* Disable WDT Protection */
  100. WDT_ProtectCmd(DISABLE);
  101. /* Disable WDT */
  102. WDT_Cmd(DISABLE);
  103. ht32_wdt_obj.ht32_wdt_start_flag = 0;
  104. }
  105. else
  106. {
  107. LOG_W("WDT is not activated and does not need to be shut down.");
  108. }
  109. break;
  110. default:
  111. LOG_W("This command is not supported.");
  112. return -RT_ERROR;
  113. }
  114. return RT_EOK;
  115. }
  116. static struct rt_watchdog_ops ht32_wdt_ops =
  117. {
  118. .init = ht32_wdt_init,
  119. .control = ht32_wdt_control,
  120. };
  121. static int rt_hw_wdt_init(void)
  122. {
  123. CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
  124. CKCUClock.Bit.WDT = 1;
  125. CKCU_PeripClockConfig(CKCUClock, ENABLE);
  126. /* wdt operator function */
  127. ht32_wdt_obj.ht32_wdt_device.ops = &ht32_wdt_ops;
  128. /* wdt activation flag bit */
  129. ht32_wdt_obj.ht32_wdt_start_flag = 0;
  130. /* register watchdog device */
  131. if (rt_hw_watchdog_register(&ht32_wdt_obj.ht32_wdt_device, BSP_USING_WDT_NAME, RT_DEVICE_FLAG_DEACTIVATE, &ht32_wdt_obj) != RT_EOK)
  132. {
  133. LOG_E("wdt device register failed.");
  134. return -RT_ERROR;
  135. }
  136. LOG_D("wdt device register success.");
  137. return RT_EOK;
  138. }
  139. INIT_BOARD_EXPORT(rt_hw_wdt_init);
  140. #endif