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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [at91/] [var/] [current/] [src/] [at91_misc.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*==========================================================================
2
//
3
//      at91_misc.c
4
//
5
//      HAL misc board support code for Atmel AT91
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, 2003 Free Software Foundation, 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
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    gthomas
43
// Contributors: gthomas, jskov, nickg, tkoeller
44
// Date:         2001-07-12
45
// Purpose:      HAL board support
46
// Description:  Implementations of HAL board interfaces
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/hal.h>
53
 
54
#include <cyg/infra/cyg_type.h>         // base types
55
#include <cyg/infra/cyg_trac.h>         // tracing macros
56
#include <cyg/infra/cyg_ass.h>          // assertion macros
57
 
58
#include <cyg/hal/hal_io.h>             // IO macros
59
#include <cyg/hal/hal_arch.h>           // Register state info
60
#include <cyg/hal/hal_diag.h>
61
#include <cyg/hal/hal_intr.h>           // necessary?
62
#include <cyg/hal/hal_cache.h>
63
#include <cyg/hal/hal_if.h>             // calling interface
64
#include <cyg/hal/hal_misc.h>           // helper functions
65
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
66
#include <cyg/hal/drv_api.h>            // HAL ISR support
67
#endif
68
#include <cyg/hal/var_io.h>             // platform registers
69
 
70
// -------------------------------------------------------------------------
71
// Hardware init
72
 
73
void hal_hardware_init(void)
74
{
75
    unsigned i;
76
 
77
    // Reset all interrupts
78
    HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, 0xFFFFFFFF);
79
 
80
    // Flush internal priority level stack
81
    for (i = 0; i < 8; ++i)
82
        HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
83
 
84
#ifdef HAL_PLF_HARDWARE_INIT
85
    // Perform any platform specific initializations
86
    HAL_PLF_HARDWARE_INIT();
87
#endif
88
 
89
    // Set up eCos/ROM interfaces
90
    hal_if_init();
91
}
92
 
93
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
94
// Decode a system interrupt. Not all systems have all interrupts. So
95
// code will only be generated for those interrupts which have a
96
// defined value.
97
static int sys_irq_handler(void)
98
{
99
  cyg_uint32 sr, mr;
100
 
101
#ifdef CYGNUM_HAL_INTERRUPT_PITC
102
  // Periodic Interrupt Timer Controller
103
  HAL_READ_UINT32((AT91_PITC+AT91_PITC_PISR), sr);
104
  if (sr & AT91_PITC_PISR_PITS) {
105
    return CYGNUM_HAL_INTERRUPT_PITC;
106
  }
107
#endif
108
 
109
#ifdef CYGNUM_HAL_INTERRUPT_DBG
110
  // Debug Unit
111
  HAL_READ_UINT32((AT91_DBG + AT91_DBG_CSR), sr);
112
  HAL_READ_UINT32((AT91_DBG + AT91_DBG_IMR), mr);
113
  if (sr & mr) {
114
    return CYGNUM_HAL_INTERRUPT_DBG;
115
  }
116
#endif
117
 
118
#ifdef CYGNUM_HAL_INTERRUPT_RTTC
119
  /* Real Time Timer. Check the interrupt is enabled, not that just
120
     the status indicates there is an interrupt. It takes a while for
121
     the status bit to clear. */
122
  HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTSR), sr);
123
  HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTMR), mr);
124
  if (((mr & AT91_RTTC_RTMR_ALMIEN) &&
125
       (sr & AT91_RTTC_RTSR_ALMS)) ||
126
      ((mr & AT91_RTTC_RTMR_RTTINCIEN) &&
127
       (sr & AT91_RTTC_RTSR_RTTINC))) {
128
    return CYGNUM_HAL_INTERRUPT_RTTC;
129
  }
130
#endif
131
 
132
#ifdef CYGNUM_HAL_INTERRUPT_PMC
133
  // Power Management Controller
134
  HAL_READ_UINT32((AT91_PMC+AT91_PMC_IMR), mr);
135
  HAL_READ_UINT32((AT91_PMC+AT91_PMC_SR), sr);
136
  if ((sr & mr) &
137
      (AT91_PMC_SR_MOSCS   |
138
       AT91_PMC_SR_LOCK    |
139
       AT91_PMC_SR_MCKRDY  |
140
       AT91_PMC_SR_PCK0RDY |
141
       AT91_PMC_SR_PCK1RDY |
142
       AT91_PMC_SR_PCK2RDY |
143
       AT91_PMC_SR_PCK3RDY)) {
144
    return CYGNUM_HAL_INTERRUPT_PMC;
145
  }
146
#endif
147
 
148
#ifdef CYGNUM_HAL_INTERRUPT_MC
149
  // Memory controller
150
  HAL_READ_UINT32((AT91_MC+AT91_MC_FMR), mr);
151
  HAL_READ_UINT32((AT91_MC+AT91_MC_FSR), sr);
152
  if ((sr & mr) &
153
      (AT91_MC_FSR_FRDY  |
154
       AT91_MC_FSR_LOCKE |
155
       AT91_MC_FSR_PROGE)) {
156
    return CYGNUM_HAL_INTERRUPT_MC;
157
  }
158
#endif
159
 
160
#ifdef CYGNUM_HAL_INTERRUPT_WDTC
161
  // Watchdog Timer Controller
162
  HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDSR), sr);
163
  HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDMR), mr);
164
  if ((mr & AT91_WDTC_WDMR_FIEN) &&
165
      sr & (AT91_WDTC_WDSR_UNDER |
166
            AT91_WDTC_WDSR_ERROR)) {
167
    return CYGNUM_HAL_INTERRUPT_WDTC;
168
  }
169
#endif
170
 
171
#ifdef CYGNUM_HAL_INTERRUPT_RSTC
172
  // Reset Controller
173
  HAL_READ_UINT32((AT91_RST + AT91_RST_RSR), sr);
174
  HAL_READ_UINT32((AT91_RST + AT91_RST_RMR), mr);
175
  if (((mr & AT91_RST_RMR_URSTIEN) && (sr & AT91_RST_RSR_USER)) ||
176
      ((mr & AT91_RST_RMR_BODIEN) && (sr & AT91_RST_RSR_BROWN)))
177
    return CYGNUM_HAL_INTERRUPT_RSTC;
178
#endif
179
 
180
  return CYGNUM_HAL_INTERRUPT_NONE;
181
}
182
#endif
183
 
184
// -------------------------------------------------------------------------
185
// This routine is called to respond to a hardware interrupt (IRQ).  It
186
// should interrogate the hardware and return the IRQ vector number.
187
 
188
int hal_IRQ_handler(void)
189
{
190
    cyg_uint32 irq_num;
191
    cyg_uint32 ivr;
192
#ifdef CYGHWR_HAL_ARM_AT91_FIQ
193
    // handle fiq interrupts as irq 
194
    cyg_uint32 ipr,imr;
195
 
196
    HAL_READ_UINT32(AT91_AIC+AT91_AIC_IPR, ipr);
197
    HAL_READ_UINT32(AT91_AIC+AT91_AIC_IMR, imr);
198
 
199
    if (imr & ipr & (1 << CYGNUM_HAL_INTERRUPT_FIQ)) {
200
      HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_ICCR, (1 << CYGNUM_HAL_INTERRUPT_FIQ));
201
      return CYGNUM_HAL_INTERRUPT_FIQ;
202
    }
203
#endif
204
    // Calculate active interrupt (updates ISR)
205
    HAL_READ_UINT32(AT91_AIC+AT91_AIC_IVR, ivr);
206
 
207
    HAL_READ_UINT32(AT91_AIC+AT91_AIC_ISR, irq_num);
208
 
209
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
210
    if (irq_num == CYGNUM_HAL_INTERRUPT_SYS) {
211
      // determine the source of the system interrupt
212
      irq_num = sys_irq_handler();
213
    }
214
#endif
215
    // An invalid interrupt source is treated as a spurious interrupt    
216
    if (irq_num < CYGNUM_HAL_ISR_MIN || irq_num > CYGNUM_HAL_ISR_MAX)
217
      irq_num = CYGNUM_HAL_INTERRUPT_NONE;
218
 
219
    return irq_num;
220
}
221
 
222
// -------------------------------------------------------------------------
223
// Interrupt control
224
//
225
 
226
void hal_interrupt_mask(int vector)
227
{
228
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
229
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
230
 
231
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
232
    if (vector >= 32) {
233
      HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR,
234
                       (1 << CYGINT_HAL_ARM_AT91_SYS_INTERRUPT));
235
      return;
236
    }
237
#endif
238
    HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, (1<<vector));
239
}
240
 
241
void hal_interrupt_unmask(int vector)
242
{
243
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
244
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
245
 
246
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
247
    if (vector >= 32) {
248
      hal_interrupt_configure(CYGINT_HAL_ARM_AT91_SYS_INTERRUPT, true, true);
249
      HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR,
250
                       (1 <<CYGINT_HAL_ARM_AT91_SYS_INTERRUPT));
251
      return;
252
    }
253
#endif
254
    HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, (1<<vector));
255
}
256
 
257
void hal_interrupt_acknowledge(int vector)
258
{
259
    // No check for valid vector here! Spurious interrupts
260
    // must be acknowledged, too.
261
    HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
262
}
263
 
264
void hal_interrupt_configure(int vector, int level, int up)
265
{
266
    cyg_uint32 mode;
267
 
268
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
269
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
270
 
271
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
272
    if (vector >= 32)
273
      return;
274
#endif
275
    if (level) {
276
        if (up) {
277
            mode = AT91_AIC_SMR_LEVEL_HI;
278
        } else {
279
            mode = AT91_AIC_SMR_LEVEL_LOW;
280
        }
281
    } else {
282
        if (up) {
283
            mode = AT91_AIC_SMR_EDGE_POS;
284
        } else {
285
            mode = AT91_AIC_SMR_EDGE_NEG;
286
        }
287
    }
288
    mode |= 7;  // Default priority
289
    HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
290
}
291
 
292
void hal_interrupt_set_level(int vector, int level)
293
{
294
    cyg_uint32 mode;
295
 
296
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
297
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
298
    CYG_ASSERT(level >= 0 && level <= 7, "Invalid level");
299
 
300
#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
301
    if (vector >= 32)
302
      return;
303
#endif
304
 
305
    HAL_READ_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
306
    mode = (mode & ~AT91_AIC_SMR_PRIORITY) | level;
307
    HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
308
}
309
 
310
void hal_show_IRQ(int vector, int data, int handler)
311
{
312
//    UNDEFINED(__FUNCTION__);  // FIXME
313
}
314
 
315
 
316
#ifndef AT91_RST
317
/* Use the watchdog to generate a reset */
318
void hal_at91_reset_cpu(void)
319
{
320
    HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY);
321
    HAL_WRITE_UINT32(AT91_WD + AT91_WD_CMR, AT91_WD_CMR_CKEY);
322
    HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
323
    HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR,
324
                     (AT91_WD_OMR_OKEY |
325
                      AT91_WD_OMR_RSTEN |
326
                      AT91_WD_OMR_EXTEN | // also reset external circuitry
327
                      AT91_WD_OMR_WDEN));
328
    while(1) CYG_EMPTY_STATEMENT;
329
}
330
#else
331
/* Use the Reset Controller to generate a reset */
332
void hal_at91_reset_cpu(void)
333
{
334
  HAL_WRITE_UINT32(AT91_RST + AT91_RST_RCR,
335
                   AT91_RST_RCR_PROCRST |
336
                   AT91_RST_RCR_ICERST  |
337
                   AT91_RST_RCR_PERRST  |
338
                   AT91_RST_RCR_KEY);
339
  while(1) CYG_EMPTY_STATEMENT;
340
}
341
#endif
342
//--------------------------------------------------------------------------
343
// EOF at91_misc.c

powered by: WebSVN 2.1.0

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