]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/watchdog/arm/lpc2xxx/v2_0/src/watchdog_lpc2xxx.cxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / watchdog / arm / lpc2xxx / v2_0 / src / watchdog_lpc2xxx.cxx
1 //==========================================================================
2 //
3 //      devs/watchdog/arm/lpc2xxx/watchdog_lpc2xxx.cxx
4 //
5 //      Watchdog implementation for ARM LPC2XXX CPU
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
13 // Copyright (C) 2004 eCosCentric Limited 
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //==========================================================================
40 //#####DESCRIPTIONBEGIN####
41 //
42 // Author(s):    jani 
43 // Contributors: tkoeller, nickg
44 // Date:         2004-10-05
45 // Purpose:      Watchdog class implementation
46 // Description:  Contains an implementation of the Watchdog class for use
47 //               with the Philips LPC2XXX watchdog timer.
48 //
49 //####DESCRIPTIONEND####
50 //
51 //==========================================================================
52
53 #include <pkgconf/kernel.h>
54 #include <pkgconf/infra.h>
55 #include <pkgconf/kernel.h>
56 #include <pkgconf/watchdog.h>
57 #include <pkgconf/devs_watchdog_arm_lpc2xxx.h>
58
59 #include <cyg/infra/cyg_type.h>
60 #include <cyg/infra/cyg_ass.h>
61 #include <cyg/infra/cyg_trac.h>
62 #include <cyg/hal/hal_io.h>
63 #include <cyg/hal/hal_diag.h>
64
65 #include <cyg/io/watchdog.hxx>
66
67 #include <cyg/hal/hal_var_ints.h>
68 #if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
69 #include <cyg/kernel/intr.hxx>
70 #endif
71
72 //==========================================================================
73
74 #define TICKS (CYG_HAL_ARM_LPC2XXX_PCLK()/4000 * \
75                CYGNUM_DEVS_WATCHDOG_ARM_LPC2XXX_DESIRED_TIMEOUT_MS)
76
77 #define RESOLUTION CYGNUM_DEVS_WATCHDOG_ARM_LPC2XXX_DESIRED_TIMEOUT_MS*1000000
78
79 //==========================================================================
80
81 #if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
82
83 #define MODVAL  (CYGARC_HAL_LPC2XXX_REG_WDMOD_WDEN | \
84                  CYGARC_HAL_LPC2XXX_REG_WDMOD_WDRESET)
85
86 void
87 Cyg_Watchdog::init_hw(void)
88 {
89   CYG_REPORT_FUNCTION();
90   CYG_REPORT_FUNCARGVOID();
91   resolution = RESOLUTION;
92   CYG_REPORT_RETURN();
93 }
94
95 #else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
96
97 //==========================================================================
98
99 #define MODVAL  (CYGARC_HAL_LPC2XXX_REG_WDMOD_WDEN | \
100                  CYGARC_HAL_LPC2XXX_REG_WDMOD_WDINT)
101 #define INT_PRIO    7
102
103 //==========================================================================
104
105 static Cyg_Watchdog *wd;
106
107 //==========================================================================
108
109 static cyg_uint32
110 isr(cyg_vector vector, CYG_ADDRWORD data)
111 {
112   CYG_REPORT_FUNCTION();
113   CYG_REPORT_FUNCARG2XV(vector, data);
114
115   wd->trigger();
116   Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WD);
117   CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
118   return Cyg_Interrupt::HANDLED;
119 }
120
121 //==========================================================================
122
123 static CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_DRIVERS)
124   Cyg_Interrupt wdint(
125     CYGNUM_HAL_INTERRUPT_WD,
126     INT_PRIO,
127     0,
128     isr,
129     NULL
130   );
131
132 //==========================================================================
133
134 void
135 Cyg_Watchdog::init_hw(void)
136 {
137   CYG_REPORT_FUNCTION();
138   CYG_REPORT_FUNCARGVOID();
139
140   wd = this;
141   resolution = RESOLUTION;
142   wdint.attach();
143   wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WD);
144   wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WD);
145   CYG_REPORT_RETURN();
146 }
147
148 #endif  /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
149
150 //==========================================================================
151 /*
152  * Reset watchdog timer. This needs to be called regularly to prevent
153  * the watchdog from firing.
154  */
155
156 void
157 Cyg_Watchdog::reset(void)
158 {
159   CYG_REPORT_FUNCTION();
160   CYG_REPORT_FUNCARGVOID();
161
162   /* Feed magic values to reset the watchdog. */
163   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
164                    CYGARC_HAL_LPC2XXX_REG_WDFEED, 
165                    CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC1);
166   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
167                    CYGARC_HAL_LPC2XXX_REG_WDFEED, 
168                    CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC2);
169   CYG_REPORT_RETURN();
170 }
171
172 //==========================================================================
173 /*
174  * Start watchdog to generate a hardware reset
175  * or interrupt when expiring.
176  */
177
178 void
179 Cyg_Watchdog::start(void)
180 {
181   CYG_REPORT_FUNCTION();
182   CYG_REPORT_FUNCARGVOID();
183   
184   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
185                    CYGARC_HAL_LPC2XXX_REG_WDTC, TICKS);
186   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
187                    CYGARC_HAL_LPC2XXX_REG_WDMOD, MODVAL);
188   /* Feed magic values to reset the watchdog. */
189   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
190                    CYGARC_HAL_LPC2XXX_REG_WDFEED, 
191                    CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC1);
192   HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
193                    CYGARC_HAL_LPC2XXX_REG_WDFEED, 
194                    CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC2);
195   CYG_REPORT_RETURN();
196 }
197
198 //==========================================================================
199 // End of watchdog_lpc2xxx.cxx