1 #ifndef CYGONCE_HAL_VAR_INTR_H
2 #define CYGONCE_HAL_VAR_INTR_H
4 //==========================================================================
8 // MCF5272 processor variant interrupt, exception and clock support
11 //==========================================================================
12 //####ECOSGPLCOPYRIGHTBEGIN####
13 // -------------------------------------------
14 // This file is part of eCos, the Embedded Configurable Operating System.
15 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
16 // Copyright (C) 2006 eCosCentric Ltd.
18 // eCos is free software; you can redistribute it and/or modify it under
19 // the terms of the GNU General Public License as published by the Free
20 // Software Foundation; either version 2 or (at your option) any later version.
22 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
23 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 // You should have received a copy of the GNU General Public License along
28 // with eCos; if not, write to the Free Software Foundation, Inc.,
29 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
31 // As a special exception, if other files instantiate templates or use macros
32 // or inline functions from this file, or you compile this file and link it
33 // with other works to produce a work based on this file, this file does not
34 // by itself cause the resulting work to be covered by the GNU General Public
35 // License. However the source code for this file must still be made available
36 // in accordance with section (3) of the GNU General Public License.
38 // This exception does not invalidate any other reasons why a work based on
39 // this file might be covered by the GNU General Public License.
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
45 // Author(s): Enrico Piria
46 // Contributors: Wade Jensen
48 // Purpose: Provide interrupt, exception and clock definitions specific
49 // to the MCF5272 processor.
50 // Usage: Included via "hal_intr.h". Do not use directly.
52 //####DESCRIPTIONEND####
53 //========================================================================
55 #include <pkgconf/hal.h>
56 #include <cyg/infra/cyg_type.h>
58 // Include any platform specific interrupt definitions.
59 #include <cyg/hal/plf_intr.h>
61 // Include for the device addresses (MCF5272_DEVS).
62 #include <cyg/hal/var_arch.h>
64 // Include for HAL I/O macros
65 #include <cyg/hal/hal_io.h>
67 // --------------------------------------------------------------------------
68 // Interrupt controller management
70 // This chip has a programmable interrupt vector base which is different
71 // from the vector base register (VBR). All interrupts from the interrupt
72 // controller are offset from the programmable interrupt vector register
73 // (PIVR). However, the only legal value is 64.
75 #define HAL_PROG_INT_VEC_BASE 64
77 // Vector numbers defined by the interrupt controller.
78 // These are all relative to the interrupt vector base number.
79 #define CYGNUM_HAL_INTERRUPT_USR_SPURINT (0 + HAL_PROG_INT_VEC_BASE)
80 #define CYGNUM_HAL_INTERRUPT_EXTINT1 (1 + HAL_PROG_INT_VEC_BASE)
81 #define CYGNUM_HAL_INTERRUPT_EXTINT2 (2 + HAL_PROG_INT_VEC_BASE)
82 #define CYGNUM_HAL_INTERRUPT_EXTINT3 (3 + HAL_PROG_INT_VEC_BASE)
83 #define CYGNUM_HAL_INTERRUPT_EXTINT4 (4 + HAL_PROG_INT_VEC_BASE)
84 #define CYGNUM_HAL_INTERRUPT_TMR0 (5 + HAL_PROG_INT_VEC_BASE)
85 #define CYGNUM_HAL_INTERRUPT_TMR1 (6 + HAL_PROG_INT_VEC_BASE)
86 #define CYGNUM_HAL_INTERRUPT_TMR2 (7 + HAL_PROG_INT_VEC_BASE)
87 #define CYGNUM_HAL_INTERRUPT_TMR3 (8 + HAL_PROG_INT_VEC_BASE)
88 #define CYGNUM_HAL_INTERRUPT_UART1 (9 + HAL_PROG_INT_VEC_BASE)
89 #define CYGNUM_HAL_INTERRUPT_UART2 (10 + HAL_PROG_INT_VEC_BASE)
90 #define CYGNUM_HAL_INTERRUPT_PLIP (11 + HAL_PROG_INT_VEC_BASE)
91 #define CYGNUM_HAL_INTERRUPT_PLIA (12 + HAL_PROG_INT_VEC_BASE)
92 #define CYGNUM_HAL_INTERRUPT_USB0 (13 + HAL_PROG_INT_VEC_BASE)
93 #define CYGNUM_HAL_INTERRUPT_USB1 (14 + HAL_PROG_INT_VEC_BASE)
94 #define CYGNUM_HAL_INTERRUPT_USB2 (15 + HAL_PROG_INT_VEC_BASE)
95 #define CYGNUM_HAL_INTERRUPT_USB3 (16 + HAL_PROG_INT_VEC_BASE)
96 #define CYGNUM_HAL_INTERRUPT_USB4 (17 + HAL_PROG_INT_VEC_BASE)
97 #define CYGNUM_HAL_INTERRUPT_USB5 (18 + HAL_PROG_INT_VEC_BASE)
98 #define CYGNUM_HAL_INTERRUPT_USB6 (19 + HAL_PROG_INT_VEC_BASE)
99 #define CYGNUM_HAL_INTERRUPT_USB7 (20 + HAL_PROG_INT_VEC_BASE)
100 #define CYGNUM_HAL_INTERRUPT_DMA (21 + HAL_PROG_INT_VEC_BASE)
101 #define CYGNUM_HAL_INTERRUPT_ERX (22 + HAL_PROG_INT_VEC_BASE)
102 #define CYGNUM_HAL_INTERRUPT_ETX (23 + HAL_PROG_INT_VEC_BASE)
103 #define CYGNUM_HAL_INTERRUPT_ENTC (24 + HAL_PROG_INT_VEC_BASE)
104 #define CYGNUM_HAL_INTERRUPT_QSPI (25 + HAL_PROG_INT_VEC_BASE)
105 #define CYGNUM_HAL_INTERRUPT_EXTINT5 (26 + HAL_PROG_INT_VEC_BASE)
106 #define CYGNUM_HAL_INTERRUPT_EXTINT6 (27 + HAL_PROG_INT_VEC_BASE)
107 #define CYGNUM_HAL_INTERRUPT_SWTO (28 + HAL_PROG_INT_VEC_BASE)
108 #define CYGNUM_HAL_INTERRUPT_RES1 (29 + HAL_PROG_INT_VEC_BASE)
109 #define CYGNUM_HAL_INTERRUPT_RES2 (30 + HAL_PROG_INT_VEC_BASE)
110 #define CYGNUM_HAL_INTERRUPT_RES3 (31 + HAL_PROG_INT_VEC_BASE)
112 // -------------------------------------------------------------------------
113 // Interrupt and exception vector table definitions. We need to redifine
114 // CYGNUM_HAL_ISR_MIN because the first usable vector is 65
116 #define CYGNUM_HAL_ISR_RANGE_DEFINED
117 #define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_INTERRUPT_EXTINT1
118 #define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_INTERRUPT_RES3
119 #define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
121 // -------------------------------------------------------------------------
122 // Spurious interrupt definition. The MCF5272 returns vector number 64,
123 // instead of 24, for spurious interrupts
125 #define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_INTERRUPT_USR_SPURINT
127 // --------------------------------------------------------------------------
128 // Interrupt controller definitions.
130 // Interrupt priority tables
131 externC volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
132 externC volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
134 externC void hal_interrupt_set_level(int vector, int level);
135 externC void hal_interrupt_mask(int vector);
136 externC void hal_interrupt_unmask(int vector);
138 // Mask the interrupt associated with the given vector.
139 #define HAL_INTERRUPT_MASK( _vector_ ) \
140 hal_interrupt_mask(_vector_)
142 // Unmask the interrupt associated with the given vector.
143 #define HAL_INTERRUPT_UNMASK( _vector_ ) \
144 hal_interrupt_unmask(_vector_)
146 // Set the priority level of an interrupt.
147 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _prilevel_ ) \
148 hal_interrupt_set_level(_vector_, _prilevel_)
150 // Acknowledge the interrupt by writing a 1 to the corresponding
151 // interrupt pending bit. Write 0 to all other interrupt pending bits. Leave
152 // all priority levels unchanged. Disable all interrupts while we access the
153 // hardware registers.
154 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \
156 cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
157 cyg_uint32 _icr = _vec_offset / 8; \
158 cyg_uint32 _icr_msk = 0x80000000 >> ((_vec_offset % 8) * 4); \
159 cyg_uint32 _icr_oldval; \
160 CYG_INTERRUPT_STATE _intr_state; \
162 HAL_DISABLE_INTERRUPTS(_intr_state); \
163 HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[_icr], _icr_oldval); \
164 HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[_icr], \
165 _icr_oldval & (_icr_msk | 0x77777777)); \
166 HAL_RESTORE_INTERRUPTS(_intr_state); \
169 // Set/clear the interrupt transition register bit. Disable all
170 // interrupts while we access the hardware registers.
171 #define HAL_INTERRUPT_CONFIGURE( _vector_, _leveltriggered_, _up_ ) \
173 if (!(_leveltriggered_)) \
175 cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
176 cyg_uint32 _itr_bit = 0x80000000 >> _vec_offset; \
177 cyg_uint32 _pitr_oldval; \
178 CYG_INTERRUPT_STATE _intr_state; \
180 HAL_DISABLE_INTERRUPTS(_intr_state); \
181 HAL_READ_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval); \
184 HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval | _itr_bit); \
188 HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval & (~_itr_bit)); \
190 HAL_RESTORE_INTERRUPTS(_intr_state); \
194 // --------------------------------------------------------------------------
197 // The MCF5272 has 4 timers, numbered 0...3. Define the timer number that we
198 // want to use for the OS clock.
199 #define CYGNUM_HAL_RTC_TIMER_NUM (3)
201 // The vector used by the real-time clock
202 #define CYGNUM_HAL_INTERRUPT_RTC (CYGNUM_HAL_INTERRUPT_TMR3)
204 // Initialize the timer to generate an interrupt every 10 ms. Use the
205 // system clock divided by 16 as the source. Using 10 as the prescaler
206 // gives a 2.4 us counter. When this counter reaches _period_, generate
208 #define HAL_CLOCK_INITIALIZE(_period_) \
210 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr, \
212 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].trr, \
214 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0); \
215 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0003); \
216 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr, \
217 (((10)-1) << MCF5272_TIMER_TMR_PS_BIT) | \
218 (0 << MCF5272_TIMER_TMR_CE_BIT) | \
219 (0 << MCF5272_TIMER_TMR_OM_BIT) | \
220 (1 << MCF5272_TIMER_TMR_ORI_BIT) | \
221 (0 << MCF5272_TIMER_TMR_FRR_BIT) | \
222 (2 << MCF5272_TIMER_TMR_CLK_BIT) | \
223 (1 << MCF5272_TIMER_TMR_RST_BIT)); \
226 // We must clear the bit in the timer event register before we can get
227 // another interrupt.
228 #define HAL_CLOCK_RESET( _vector_, _period_ ) \
230 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0); \
231 HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0002); \
234 // Read the current counter from the timer
235 #define HAL_CLOCK_READ( _pvalue_ ) \
237 HAL_READ_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, \
241 // Measure clock latency
242 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY
243 #define HAL_CLOCK_LATENCY( _pvalue_ ) \
245 register cyg_int32 result; \
246 HAL_CLOCK_READ( &result ); \
247 *_pvalue_ = result - CYGNUM_HAL_RTC_PERIOD; \
251 // ---------------------------------------------------------------------------
253 #endif // ifndef CYGONCE_HAL_VAR_INTR_H