1 //==========================================================================
5 // HAL misc board support code for Atmel AT91/EB40
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.
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.
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
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.
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.
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.
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####
44 // Contributors: gthomas, jskov
46 // Purpose: HAL board support
47 // Description: Implementations of HAL board interfaces
49 //####DESCRIPTIONEND####
51 //========================================================================*/
53 #include <pkgconf/hal.h>
55 #include <cyg/infra/cyg_type.h> // base types
56 #include <cyg/infra/cyg_trac.h> // tracing macros
57 #include <cyg/infra/cyg_ass.h> // assertion macros
59 #include <cyg/hal/hal_io.h> // IO macros
60 #include <cyg/hal/hal_arch.h> // Register state info
61 #include <cyg/hal/hal_diag.h>
62 #include <cyg/hal/hal_intr.h> // necessary?
63 #include <cyg/hal/hal_cache.h>
64 #include <cyg/hal/hal_if.h> // calling interface
65 #include <cyg/hal/hal_misc.h> // helper functions
66 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
67 #include <cyg/hal/drv_api.h> // HAL ISR support
69 #include <cyg/hal/plf_io.h> // platform registers
71 static cyg_uint32 _period;
73 void hal_clock_initialize(cyg_uint32 period)
75 CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
77 CYG_ASSERT(period < 0x10000, "Invalid clock period");
80 HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
83 HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC
84 AT91_TC_CMR_CLKS_MCK32); // 1 MHz
85 HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
88 HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
90 // Enable timer 0 interrupt
91 HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
94 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
96 CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
99 CYG_ASSERT(period < 0x10000, "Invalid clock period");
101 HAL_READ_UINT32(timer+AT91_TC_SR, sr); // Clear interrupt
102 HAL_INTERRUPT_ACKNOWLEDGE(CYGNUM_HAL_INTERRUPT_RTC);
104 if (period != _period) {
105 hal_clock_initialize(period);
111 void hal_clock_read(cyg_uint32 *pvalue)
113 CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
116 HAL_READ_UINT32(timer+AT91_TC_CV, val);
120 // -------------------------------------------------------------------------
122 // Delay for some number of micro-seconds
123 // Use timer #2 in 1MHz mode
125 void hal_delay_us(cyg_int32 usecs)
127 CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
131 HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
134 HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32); // 1MHz
135 HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
136 HAL_WRITE_UINT32(timer+AT91_TC_RC, usecs);
139 HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
141 // Wait for the compare
143 HAL_READ_UINT32(timer+AT91_TC_SR, stat);
144 } while ((stat & AT91_TC_SR_CPC) == 0);
147 // -------------------------------------------------------------------------
149 void hal_hardware_init(void)
151 // Set up eCos/ROM interfaces
154 // Reset all interrupts
155 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, 0xFFFFFFFF);
157 // Make sure interrupt controller is happy
158 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
162 // This routine is called to respond to a hardware interrupt (IRQ). It
163 // should interrogate the hardware and return the IRQ vector number.
165 int hal_IRQ_handler(void)
170 HAL_READ_UINT32(AT91_AIC+AT91_AIC_IPR, ipr);
171 HAL_READ_UINT32(AT91_AIC+AT91_AIC_IMR, imr);
173 for (irq_num = 0; irq_num < 19; irq_num++) {
174 if (ipr & (1 << irq_num)) {
186 void hal_interrupt_mask(int vector)
188 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
189 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
191 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, (1<<vector));
194 void hal_interrupt_unmask(int vector)
196 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
197 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
199 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, (1<<vector));
202 void hal_interrupt_acknowledge(int vector)
204 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
205 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
207 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_ICCR, (1<<vector));
209 // FIXME - This isn't 100% correct
210 HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
213 void hal_interrupt_configure(int vector, int level, int up)
217 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
218 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
222 mode = AT91_AIC_SMR_LEVEL_HI;
224 mode = AT91_AIC_SMR_LEVEL_LOW;
228 mode = AT91_AIC_SMR_EDGE_POS;
230 mode = AT91_AIC_SMR_EDGE_NEG;
233 mode |= 7; // Default priority
234 HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
237 void hal_interrupt_set_level(int vector, int level)
241 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
242 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
243 CYG_ASSERT(level >= 1 && level <= 7, "Invalid level");
245 HAL_READ_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
246 mode = (mode & ~AT91_AIC_SMR_PRIORITY) | level;
247 HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
250 void hal_show_IRQ(int vector, int data, int handler)
252 // UNDEFINED(__FUNCTION__); // FIXME
256 // Diagnostic LEDs - there are three colored LEDs which can be used
257 // to send a simple diagnostic value (8 bits)
265 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_CODR, 0x06); // DATA+CLOCK LEDs off
266 for (to = 0; to < 0x200000; to++) ;
267 for (i = 0; i < 8; i++) {
268 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_SODR, ((val>>(7-i)) & 0x01)<<2); // DATA LED
269 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_SODR, 0x02); // CLOCK LED on
270 for (to = 0; to < 0x80000; to++) ;
271 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_CODR, 0x02); // CLOCK LED off
272 for (to = 0; to < 0x40000; to++) ;
273 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_CODR, 0x04); // DATA LED off
280 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_CODR, 0x16);
281 HAL_WRITE_UINT32(AT91_PIO+AT91_PIO_SODR, val);
285 //--------------------------------------------------------------------------