Skip to content

Commit e43df5e

Browse files
hywingmysterywolf
authored andcommitted
[bsp][nxp][mcxa153] add watch dog driver
1 parent 1a24ae0 commit e43df5e

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
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-11-25 hywing The first version for NXP MCXA153 Board
9+
*/
10+
11+
#include <rtthread.h>
12+
#include "drv_wdt.h"
13+
14+
#include "fsl_wwdt.h"
15+
#include "fsl_clock.h"
16+
17+
#ifdef RT_USING_WDT
18+
19+
#define WDT_CLK_FREQ CLOCK_GetWwdtClkFreq()
20+
#define WWDT WWDT0
21+
#define APP_WDT_IRQn WWDT0_IRQn
22+
#define APP_WDT_IRQ_HANDLER WWDT0_IRQHandler
23+
24+
struct mcx_wdt
25+
{
26+
rt_watchdog_t watchdog;
27+
WWDT_Type *wdt_base;
28+
};
29+
30+
static struct mcx_wdt wdt_dev;
31+
32+
void APP_WDT_IRQ_HANDLER(void)
33+
{
34+
uint32_t wdtStatus = WWDT_GetStatusFlags(WWDT);
35+
36+
//APP_LED_TOGGLE;
37+
38+
/* The chip will reset before this happens */
39+
if (wdtStatus & kWWDT_TimeoutFlag)
40+
{
41+
WWDT_ClearStatusFlags(WWDT, kWWDT_TimeoutFlag);
42+
}
43+
44+
/* Handle warning interrupt */
45+
if (wdtStatus & kWWDT_WarningFlag)
46+
{
47+
/* A watchdog feed didn't occur prior to warning timeout */
48+
WWDT_ClearStatusFlags(WWDT, kWWDT_WarningFlag);
49+
/* User code. User can do urgent case before timeout reset.
50+
* IE. user can backup the ram data or ram log to flash.
51+
* the period is set by config.warningValue, user need to
52+
* check the period between warning interrupt and timeout.
53+
*/
54+
}
55+
SDK_ISR_EXIT_BARRIER;
56+
}
57+
58+
static rt_err_t wdt_init(rt_watchdog_t *wdt)
59+
{
60+
wwdt_config_t config;
61+
uint32_t wdtFreq;
62+
bool timeOutResetEnable;
63+
64+
/* Enable the WWDT time out to reset the CPU. */
65+
timeOutResetEnable = true;
66+
67+
68+
/* The WDT divides the input frequency into it by 4 */
69+
wdtFreq = WDT_CLK_FREQ / 4;
70+
71+
WWDT_GetDefaultConfig(&config);
72+
73+
/*
74+
* Set watchdog feed time constant to approximately 4s
75+
* Set watchdog warning time to 512 ticks after feed time constant
76+
* Set watchdog window time to 1s
77+
*/
78+
config.timeoutValue = wdtFreq * 4;
79+
config.warningValue = 512;
80+
config.windowValue = wdtFreq * 1;
81+
/* Configure WWDT to reset on timeout */
82+
config.enableWatchdogReset = true;
83+
/* Setup watchdog clock frequency(Hz). */
84+
config.clockFreq_Hz = WDT_CLK_FREQ;
85+
86+
WWDT_Init(WWDT, &config);
87+
NVIC_EnableIRQ(APP_WDT_IRQn);
88+
89+
return RT_EOK;
90+
}
91+
92+
void delayWwdtWindow(void)
93+
{
94+
/* For the TV counter register value will decrease after feed watch dog,
95+
* we can use it to as delay. But in user scene, user need feed watch dog
96+
* in the time period after enter Window but before warning intterupt.
97+
*/
98+
while (WWDT->TV > WWDT->WINDOW)
99+
{
100+
__NOP();
101+
}
102+
}
103+
104+
static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
105+
{
106+
switch (cmd)
107+
{
108+
case RT_DEVICE_CTRL_WDT_START:
109+
WWDT_Enable(wdt_dev.wdt_base);
110+
return RT_EOK;
111+
112+
case RT_DEVICE_CTRL_WDT_STOP:
113+
WWDT_Disable(wdt_dev.wdt_base);
114+
return RT_EOK;
115+
116+
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
117+
delayWwdtWindow();
118+
WWDT_Refresh(wdt_dev.wdt_base);
119+
return RT_EOK;
120+
121+
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
122+
if (arg != RT_NULL)
123+
{
124+
uint32_t timeout = *((uint32_t *)arg);
125+
timeout = timeout * WDT_CLK_FREQ / 4;
126+
WWDT_SetTimeoutValue(wdt_dev.wdt_base, timeout);
127+
return RT_EOK;
128+
}
129+
return -RT_ERROR;
130+
131+
default:
132+
return -RT_ERROR;
133+
}
134+
}
135+
136+
static struct rt_watchdog_ops wdt_ops =
137+
{
138+
wdt_init,
139+
wdt_control,
140+
};
141+
142+
int rt_hw_wdt_init(void)
143+
{
144+
wdt_dev.wdt_base = WWDT;
145+
146+
wdt_dev.watchdog.ops = &wdt_ops;
147+
148+
if (rt_hw_watchdog_register(&wdt_dev.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
149+
{
150+
rt_kprintf("wdt register failed\n");
151+
return -RT_ERROR;
152+
}
153+
154+
return RT_EOK;
155+
}
156+
157+
INIT_BOARD_EXPORT(rt_hw_wdt_init);
158+
159+
#endif /* RT_USING_WDT */
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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-11-25 hywing The first version for NXP MCXA153 Board
9+
*/
10+
11+
#ifndef __DRV_WDT_H__
12+
#define __DRV_WDT_H__
13+
14+
#include <rtthread.h>
15+
#include <rtdevice.h>
16+
17+
int rt_hw_wdt_init(void);
18+
19+
#endif /* __DRV_WDT_H__ */

0 commit comments

Comments
 (0)