drv_wdt.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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-08-09 Your Name The first version for MCXN236
  9. */
  10. #include <rtthread.h>
  11. #include "drv_wdt.h"
  12. #include "fsl_wwdt.h"
  13. #include "fsl_clock.h"
  14. #ifdef RT_USING_WDT
  15. #define WDT_CLK_FREQ CLOCK_GetWdtClkFreq(0)
  16. struct mcx_wdt
  17. {
  18. rt_watchdog_t watchdog;
  19. WWDT_Type *wdt_base;
  20. clock_name_t clock_src;
  21. clock_ip_name_t clock_ip_name;
  22. };
  23. static struct mcx_wdt wdt_dev;
  24. static rt_err_t wdt_init(rt_watchdog_t *wdt)
  25. {
  26. uint32_t wdtFreq;
  27. wwdt_config_t config;
  28. /* The WDT divides the input frequency into it by 4 */
  29. wdtFreq = WDT_CLK_FREQ / 4;
  30. /* Enable FRO 1M clock for WWDT module. */
  31. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK;
  32. WWDT_GetDefaultConfig(&config);
  33. config.timeoutValue = wdtFreq * 1;
  34. config.windowValue = wdtFreq * 1;
  35. /* Configure WWDT to reset on timeout */
  36. config.enableWatchdogReset = true;
  37. /* Setup watchdog clock frequency(Hz). */
  38. config.clockFreq_Hz = WDT_CLK_FREQ;
  39. CLOCK_EnableClock(wdt_dev.clock_ip_name);
  40. CLOCK_SetClkDiv(kCLOCK_DivWdt0Clk, 1U);
  41. WWDT_Init(wdt_dev.wdt_base, &config);
  42. return RT_EOK;
  43. }
  44. static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
  45. {
  46. switch (cmd)
  47. {
  48. case RT_DEVICE_CTRL_WDT_START:
  49. WWDT_Enable(wdt_dev.wdt_base);
  50. return RT_EOK;
  51. case RT_DEVICE_CTRL_WDT_STOP:
  52. WWDT_Disable(wdt_dev.wdt_base);
  53. return RT_EOK;
  54. case RT_DEVICE_CTRL_WDT_KEEPALIVE:
  55. WWDT_Refresh(wdt_dev.wdt_base);
  56. return RT_EOK;
  57. case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
  58. if (arg != RT_NULL)
  59. {
  60. uint32_t timeout = *((uint32_t *)arg);
  61. timeout = timeout * WDT_CLK_FREQ / 4;
  62. WWDT_SetTimeoutValue(wdt_dev.wdt_base, timeout);
  63. return RT_EOK;
  64. }
  65. return -RT_ERROR;
  66. default:
  67. return -RT_ERROR;
  68. }
  69. }
  70. static struct rt_watchdog_ops wdt_ops =
  71. {
  72. wdt_init,
  73. wdt_control,
  74. };
  75. int rt_hw_wdt_init(void)
  76. {
  77. wdt_dev.wdt_base = WWDT0;
  78. wdt_dev.clock_src = kCLOCK_Clk1M;
  79. wdt_dev.clock_ip_name = kCLOCK_Wwdt0;
  80. wdt_dev.watchdog.ops = &wdt_ops;
  81. if (rt_hw_watchdog_register(&wdt_dev.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
  82. {
  83. rt_kprintf("wdt register failed\n");
  84. return -RT_ERROR;
  85. }
  86. return RT_EOK;
  87. }
  88. INIT_BOARD_EXPORT(rt_hw_wdt_init);
  89. #endif /* RT_USING_WDT */