summaryrefslogtreecommitdiff
path: root/arch/arm/lpc17xx/Drivers/source/lpc17xx_wdt.c
blob: 1d8b407c8113013bc7b5dcaaf898a89c95d3d554 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/***********************************************************************//**
 * @file		lpc17xx_wdt.c
 * @brief		Contains all functions support for WDT firmware library on LPC17xx
 * @version		2.0
 * @date		21. May. 2010
 * @author		NXP MCU SW Application Team
 **************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **********************************************************************/

/* Peripheral group ----------------------------------------------------------- */
/** @addtogroup WDT
 * @{
 */

/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_wdt.h"
#include "lpc17xx_clkpwr.h"
#include "lpc17xx_pinsel.h"


/* If this source file built with example, the LPC17xx FW library configuration
 * file in each example directory ("lpc17xx_libcfg.h") must be included,
 * otherwise the default FW library configuration file must be included instead
 */
#ifdef __BUILD_WITH_EXAMPLE__
#include "lpc17xx_libcfg.h"
#else
#include "lpc17xx_libcfg_default.h"
#endif /* __BUILD_WITH_EXAMPLE__ */


#ifdef _WDT

/* Private Functions ---------------------------------------------------------- */

static uint8_t WDT_SetTimeOut (uint8_t clk_source, uint32_t timeout);

/********************************************************************//**
 * @brief 		Set WDT time out value and WDT mode
 * @param[in]	clk_source select Clock source for WDT device
 * @param[in]	timeout value of time-out for WDT (us)
 * @return		None
 *********************************************************************/
static uint8_t WDT_SetTimeOut (uint8_t clk_source, uint32_t timeout)
{

	uint32_t pclk_wdt = 0;
	uint32_t tempval = 0;

	switch ((WDT_CLK_OPT) clk_source)
    {
    case WDT_CLKSRC_IRC:
    	pclk_wdt = 4000000;
    	// Calculate TC in WDT
    	tempval  = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4));
    	// Check if it valid
    	if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX))
    	{
    		LPC_WDT->WDTC = tempval;
    		return	SUCCESS;
    	}

    	break;

    case WDT_CLKSRC_PCLK:

    	// Get WDT clock with CCLK divider = 4
		pclk_wdt = SystemCoreClock / 4;
		// Calculate TC in WDT
		tempval  = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4));

		if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX))
		{
			CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_4);
			LPC_WDT->WDTC = (uint32_t) tempval;
			return SUCCESS;
		}

		// Get WDT clock with CCLK divider = 2
		pclk_wdt = SystemCoreClock / 2;
		// Calculate TC in WDT
		tempval  = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4));

		if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX))
		{
			CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_2);
			LPC_WDT->WDTC = (uint32_t) tempval;
			return	SUCCESS;
		}

		// Get WDT clock with CCLK divider = 1
		pclk_wdt = SystemCoreClock;
		// Calculate TC in WDT
		tempval  = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4));

		if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX))
		{
			CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_1);
			LPC_WDT->WDTC = (uint32_t) tempval;
			return	SUCCESS;
		}
		break ;


    case WDT_CLKSRC_RTC:
		pclk_wdt = 32768;
		// Calculate TC in WDT
		tempval  = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4));
		// Check if it valid
		if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX))
		{
			LPC_WDT->WDTC = (uint32_t) tempval;
			return	SUCCESS;
		}

		break;

// Error parameter
		default:
			break;
}

	return ERROR;
}

/* End of Private Functions --------------------------------------------------- */


/* Public Functions ----------------------------------------------------------- */
/** @addtogroup WDT_Public_Functions
 * @{
 */


/*********************************************************************//**
* @brief 		Initial for Watchdog function
* 					Clock source = RTC ,
* @param[in]	ClkSrc  Select clock source, should be:
* 				- WDT_CLKSRC_IRC: Clock source from Internal RC oscillator
* 				- WDT_CLKSRC_PCLK: Selects the APB peripheral clock (PCLK)
* 				- WDT_CLKSRC_RTC: Selects the RTC oscillator
* @param[in]	WDTMode WDT mode, should be:
* 				- WDT_MODE_INT_ONLY: Use WDT to generate interrupt only
* 				- WDT_MODE_RESET: Use WDT to generate interrupt and reset MCU
* @return 		None
 **********************************************************************/
void WDT_Init (WDT_CLK_OPT ClkSrc, WDT_MODE_OPT WDTMode)
{
	CHECK_PARAM(PARAM_WDT_CLK_OPT(ClkSrc));
	CHECK_PARAM(PARAM_WDT_MODE_OPT(WDTMode));
	CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_4);

	//Set clock source
	LPC_WDT->WDCLKSEL &= ~WDT_WDCLKSEL_MASK;
	LPC_WDT->WDCLKSEL |= ClkSrc;
	//Set WDT mode
	if (WDTMode == WDT_MODE_RESET){
		LPC_WDT->WDMOD |= WDT_WDMOD(WDTMode);
	}
}

/*********************************************************************//**
* @brief 		Start WDT activity with given timeout value
* @param[in]	TimeOut WDT reset after timeout if it is not feed
* @return 		None
 **********************************************************************/
void WDT_Start(uint32_t TimeOut)
{
	uint32_t ClkSrc;

	ClkSrc = LPC_WDT->WDCLKSEL;
	ClkSrc &=WDT_WDCLKSEL_MASK;
	WDT_SetTimeOut(ClkSrc,TimeOut);
	//enable watchdog
	LPC_WDT->WDMOD |= WDT_WDMOD_WDEN;
	WDT_Feed();
}

/********************************************************************//**
 * @brief 		Read WDT Time out flag
 * @param[in]	None
 * @return		Time out flag status of WDT
 *********************************************************************/
FlagStatus WDT_ReadTimeOutFlag (void)
{
	return ((FlagStatus)((LPC_WDT->WDMOD & WDT_WDMOD_WDTOF) >>2));
}

/********************************************************************//**
 * @brief 		Clear WDT Time out flag
 * @param[in]	None
 * @return		None
 *********************************************************************/
void WDT_ClrTimeOutFlag (void)
{
	LPC_WDT->WDMOD &=~WDT_WDMOD_WDTOF;
}

/********************************************************************//**
 * @brief 		Update WDT timeout value and feed
 * @param[in]	TimeOut	TimeOut value to be updated
 * @return		None
 *********************************************************************/
void WDT_UpdateTimeOut ( uint32_t TimeOut)
{
	uint32_t ClkSrc;
	ClkSrc = LPC_WDT->WDCLKSEL;
	ClkSrc &=WDT_WDCLKSEL_MASK;
	WDT_SetTimeOut(ClkSrc,TimeOut);
	WDT_Feed();
}


/********************************************************************//**
 * @brief 		After set WDTEN, call this function to start Watchdog
 * 				or reload the Watchdog timer
 * @param[in]	None
 *
 * @return		None
 *********************************************************************/
void WDT_Feed (void)
{
	// Disable irq interrupt
	__disable_irq();
	LPC_WDT->WDFEED = 0xAA;
	LPC_WDT->WDFEED = 0x55;
	// Then enable irq interrupt
	__enable_irq();
}

/********************************************************************//**
 * @brief 		Get the current value of WDT
 * @param[in]	None
 * @return		current value of WDT
 *********************************************************************/
uint32_t WDT_GetCurrentCount(void)
{
	return LPC_WDT->WDTV;
}

/**
 * @}
 */

#endif /* _WDT */

/**
 * @}
 */

/* --------------------------------- End Of File ------------------------------ */