]> rtime.felk.cvut.cz Git - sysless.git/blob - arch/arm/mach-lpc23xx/libs/hal/hal.c
It is 12 years after C99 standardization - switch to stdint.h and its types.
[sysless.git] / arch / arm / mach-lpc23xx / libs / hal / hal.c
1 #include <system_def.h>
2 #include <hal_ints.h>
3 #include <hal_intr.h>
4 #include <stdint.h>
5  
6 // -------------------------------------------------------------------------
7 // Hardware init
8
9 // -------------------------------------------------------------------------
10 // This routine is called to respond to a hardware interrupt (IRQ).  It
11 // should interrogate the hardware and return the IRQ vector number.
12 int hal_IRQ_handler(void)
13 {
14     uint32_t irq_num, irq_stat;
15
16     irq_stat=VICIRQStatus;
17     for (irq_num = 0; irq_num < 32; irq_num++)
18       if (irq_stat & (1 << irq_num))
19         break;
20     
21     // If not a valid interrrupt source, treat as spurious interrupt    
22     if (irq_num < HAL_ISR_MIN || irq_num > HAL_ISR_MAX)
23       irq_num = HAL_INTERRUPT_NONE;
24     
25     return (irq_num);
26 }
27
28
29 // -------------------------------------------------------------------------
30 // Interrupt control
31 //
32
33 // Block the the interrupt associated with the vector
34 void hal_interrupt_mask(int vector)
35 {
36     VICIntEnClr = 1 << vector;
37 }
38
39 // Unblock the the interrupt associated with the vector
40 void hal_interrupt_unmask(int vector)
41 {
42     VICIntEnable = 1 << vector;
43 }
44
45 // Acknowledge the the interrupt associated with the vector. This
46 // clears the interrupt but may result in another interrupt being
47 // delivered
48 void hal_interrupt_acknowledge(int vector)
49 {
50
51     // External interrupts have to be cleared from the EXTINT register
52     if (vector >= HAL_INTERRUPT_EINT0 &&
53         vector <= HAL_INTERRUPT_EINT3)
54       {
55         // Map int vector to corresponding bit (0..3)
56         vector = 1 << (vector - HAL_INTERRUPT_EINT0);
57                 
58         // Clear the external interrupt
59         EXTINT=vector;
60       }
61     
62     // Acknowledge interrupt in the VIC
63     VICVectAddr=0;
64 }
65
66 // This provides control over how an interrupt signal is detected.
67 // Options are between level or edge sensitive (level) and high/low
68 // level or rising/falling edge triggered (up).
69 //
70 // This should be simple, but unfortunately on some processor revisions,
71 // it trips up on two errata issues (for the LPC2294 Rev.A these are
72 // EXTINT.1 and VPBDIV.1) and so on these devices a somewhat convoluted
73 // sequence in order to work properly. There is nothing in the errata
74 // sequence that won't work on a processor without these issues.
75 void hal_interrupt_configure(int vector, int level, int up)
76 {
77     uint32_t regval;
78
79     // Map int vector to corresponding bit (0..3)
80     vector = 1 << (vector - HAL_INTERRUPT_EINT0);
81     
82     // Read current mode and update for level (0) or edge detection (1)
83     regval=EXTMODE;
84     if (level)
85       regval &= ~vector;
86     else
87       regval |= vector;
88     EXTMODE=regval;
89     
90     // Read current polarity and update for trigger level or edge
91     // level: high (1), low (0) edge: rising (1), falling (0)
92     regval=EXTPOLAR;
93     if (up)
94       regval |= vector;
95     else
96       regval &= ~vector;
97     EXTPOLAR=regval;
98
99     // Clear any spurious interrupt that might have been generated
100     EXTINT=vector;
101 }
102
103 // Change interrupt level. This is a non-operation on the LPC2XXX
104 void hal_interrupt_set_level(int vector, int level)
105 {
106 }
107
108 uint32_t hal_default_isr(int vector, uint32_t data)
109 {
110   return 0;
111 }
112
113 uint32_t hal_interrupt_handlers[HAL_ISR_COUNT]={[0 ... HAL_ISR_COUNT-1]=(uint32_t)hal_default_isr};
114 uint32_t hal_interrupt_data[HAL_ISR_COUNT];
115
116 #if !defined(__thumb__)
117 void irq_handler_resolver(void) __attribute__ ((interrupt));
118 #endif
119 void irq_handler_resolver(void)
120 {
121   int v;
122   uint32_t f,d;
123
124   v=hal_IRQ_handler();
125   if (v==HAL_INTERRUPT_NONE) return;
126   f=hal_interrupt_handlers[v];
127   d=hal_interrupt_data[v];
128   ((hal_isr)f)(v,d);  
129   hal_interrupt_acknowledge(v);
130 }
131
132 int request_irq(unsigned int irqnum, irq_handler_t handler, unsigned long flags,
133                 const char *name, void *context)
134 {
135   HAL_INTERRUPT_ATTACH(irqnum, handler, context);
136   HAL_INTERRUPT_UNMASK(irqnum);
137   return irqnum;
138 }
139
140 void free_irq(unsigned int irqnum,void *ctx)
141 {
142   HAL_INTERRUPT_MASK(irqnum);
143   HAL_INTERRUPT_DETACH(irqnum, NULL);
144 }