OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [watchdog/] [arm/] [at91/] [v2_0/] [src/] [watchdog_at91.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      devs/watchdog/arm/at91/watchdog_at91.cxx
4
//
5
//      Watchdog implementation for ARM AT91 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
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    tkoeller
44
// Contributors: tkoeller
45
// Date:         2002-05-05
46
// Purpose:      Watchdog class implementation
47
// Description:  Contains an implementation of the Watchdog class for use
48
//               with the ATMEL AT91 watchdog timer.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include <pkgconf/kernel.h>
55
#include <pkgconf/infra.h>
56
#include <pkgconf/kernel.h>
57
#include <pkgconf/watchdog.h>
58
#include <pkgconf/devs_watchdog_arm_at91.h>
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/plf_io.h>
64
#include <cyg/hal/hal_diag.h>
65
#include <cyg/io/watchdog.hxx>
66
#if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
67
#include <cyg/hal/hal_platform_ints.h>
68
#include <cyg/kernel/intr.hxx>
69
#endif
70
 
71
#define MCLK_FREQUENCY_KHZ  32768
72
#define MAX_TICKS           0x0000ffff
73
#define BASE_TICKS          (MCLK_FREQUENCY_KHZ * CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TMEOUT_MS)
74
 
75
#if   BASE_TICKS / 8 <= MAX_TICKS
76
#define DIVIDER 0
77
#define DIV_FACTOR 8
78
#elif BASE_TICKS / 32 <= MAX_TICKS
79
#define DIVIDER 1
80
#define DIV_FACTOR 32
81
#elif BASE_TICKS / 128 <= MAX_TICKS
82
#define DIVIDER 2
83
#define DIV_FACTOR 128
84
#elif BASE_TICKS / 1024 <= MAX_TICKS
85
#define DIVIDER 3
86
#define DIV_FACTOR 1024
87
#else
88
#error Desired resolution beyond hardware capabilities
89
#endif
90
 
91
#define TICKS       ((BASE_TICKS / DIV_FACTOR) | 0xfff)
92
#define RESOLUTION  ((cyg_uint64) (TICKS * DIV_FACTOR ) * 1000000 / MCLK_FREQUENCY_KHZ)
93
 
94
 
95
 
96
#if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
97
 
98
#define OMRVAL  (AT91_WD_OMR_OKEY | AT91_WD_OMR_RSTEN | AT91_WD_OMR_WDEN)
99
 
100
void
101
Cyg_Watchdog::init_hw(void)
102
{
103
  CYG_REPORT_FUNCTION();
104
  CYG_REPORT_FUNCARGVOID();
105
  resolution = RESOLUTION;
106
  CYG_REPORT_RETURN();
107
}
108
 
109
#else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
110
 
111
#define OMRVAL  (AT91_WD_OMR_OKEY | AT91_WD_OMR_IRQEN | AT91_WD_OMR_WDEN)
112
#define INT_PRIO    7
113
 
114
 
115
static void *
116
operator new(size_t size)
117
{
118
  static cyg_uint8 buf[sizeof (Cyg_Interrupt)];
119
  CYG_REPORT_FUNCTION();
120
  CYG_REPORT_FUNCARG1XV(size);
121
  CYG_ASSERTC(size == sizeof buf);
122
  CYG_REPORT_RETVAL(buf);
123
  return buf;
124
}
125
 
126
static cyg_uint32
127
isr(cyg_vector vector, CYG_ADDRWORD data)
128
{
129
  Cyg_Watchdog &wd = *(Cyg_Watchdog *) data;
130
 
131
  CYG_REPORT_FUNCTION();
132
  CYG_REPORT_FUNCARG2XV(vector, data);
133
 
134
  wd.trigger();
135
  Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
136
  CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
137
  return Cyg_Interrupt::HANDLED;
138
}
139
 
140
static Cyg_Interrupt * wdint;
141
 
142
void
143
Cyg_Watchdog::init_hw(void)
144
{
145
  CYG_REPORT_FUNCTION();
146
  CYG_REPORT_FUNCARGVOID();
147
 
148
  resolution = RESOLUTION;
149
  wdint = new Cyg_Interrupt(
150
    CYGNUM_HAL_INTERRUPT_WATCHDOG,
151
    INT_PRIO,
152
    (CYG_ADDRWORD) this,
153
    isr,
154
    NULL
155
  );
156
  wdint->configure_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG, false, true);
157
  wdint->attach();
158
  wdint->acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
159
  wdint->unmask_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
160
  CYG_REPORT_RETURN();
161
}
162
 
163
#endif  /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
164
 
165
 
166
 
167
/*
168
 * Reset watchdog timer. This needs to be called regularly to prevent
169
 * the watchdog from firing.
170
 */
171
void
172
Cyg_Watchdog::reset(void)
173
{
174
  CYG_REPORT_FUNCTION();
175
  CYG_REPORT_FUNCARGVOID();
176
 
177
  /* Write magic code to reset the watchdog. */
178
  HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
179
  CYG_REPORT_RETURN();
180
}
181
 
182
/*
183
 * Start watchdog to generate a hardware reset
184
 * or interrupt when expiring.
185
 */
186
void
187
Cyg_Watchdog::start(void)
188
{
189
  CYG_REPORT_FUNCTION();
190
  CYG_REPORT_FUNCARGVOID();
191
 
192
  HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY);
193
  HAL_WRITE_UINT32(
194
    AT91_WD + AT91_WD_CMR,
195
    AT91_WD_CMR_CKEY | ((TICKS >> 10) & AT91_WD_CMR_HPCV) | DIVIDER
196
  );
197
  HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
198
  HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, OMRVAL);
199
  CYG_REPORT_RETURN();
200
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.