1 #include <system_def.h>
7 // -------------------------------------------------------------------------
10 // Return value of VPBDIV register. According to errata doc
11 // we need to read twice consecutively to get correct value
12 uint32_t lpc_get_vpbdiv(void)
23 // -------------------------------------------------------------------------
24 // This routine is called to respond to a hardware interrupt (IRQ). It
25 // should interrogate the hardware and return the IRQ vector number.
26 int hal_IRQ_handler(void)
28 uint32_t irq_num, irq_stat;
30 irq_stat=VICIRQStatus;
31 for (irq_num = 0; irq_num < 32; irq_num++)
32 if (irq_stat & (1 << irq_num))
35 // If not a valid interrrupt source, treat as spurious interrupt
36 if (irq_num < HAL_ISR_MIN || irq_num > HAL_ISR_MAX)
37 irq_num = HAL_INTERRUPT_NONE;
43 // -------------------------------------------------------------------------
47 // Block the the interrupt associated with the vector
48 void hal_interrupt_mask(int vector)
50 VICIntEnClear = 1 << vector;
53 // Unblock the the interrupt associated with the vector
54 void hal_interrupt_unmask(int vector)
56 VICIntEnable = 1 << vector;
59 // Acknowledge the the interrupt associated with the vector. This
60 // clears the interrupt but may result in another interrupt being
62 void hal_interrupt_acknowledge(int vector)
65 // External interrupts have to be cleared from the EXTINT register
66 if (vector >= HAL_INTERRUPT_EINT0 &&
67 vector <= HAL_INTERRUPT_EINT3)
69 // Map int vector to corresponding bit (0..3)
70 vector = 1 << (vector - HAL_INTERRUPT_EINT0);
72 // Clear the external interrupt
76 // Acknowledge interrupt in the VIC
80 // This provides control over how an interrupt signal is detected.
81 // Options are between level or edge sensitive (level) and high/low
82 // level or rising/falling edge triggered (up).
84 // This should be simple, but unfortunately on some processor revisions,
85 // it trips up on two errata issues (for the LPC2294 Rev.A these are
86 // EXTINT.1 and VPBDIV.1) and so on these devices a somewhat convoluted
87 // sequence in order to work properly. There is nothing in the errata
88 // sequence that won't work on a processor without these issues.
89 void hal_interrupt_configure(int vector, int level, int up)
92 #ifdef HAL_ARM_LPC2XXX_EXTINT_ERRATA
93 uint32_t saved_vpbdiv;
96 // Map int vector to corresponding bit (0..3)
97 vector = 1 << (vector - HAL_INTERRUPT_EINT0);
99 #ifdef HAL_ARM_LPC2XXX_EXTINT_ERRATA
100 // From discussions with the Philips applications engineers on the
101 // Yahoo LPC2000 forum, it appears that in order up change both
102 // EXTMODE and EXTPOLAR, the operations have to be performed in
103 // two passes as follows:
105 // VPBDIV=0, EXTMODE=n, VPBDIV=n, VPBDIV=0, EXTPOLAR=y, VPBDIV=y
108 // Save current VPBDIV register settings
109 saved_vpbdiv = lpc_get_vpbdiv();
111 // Clear VPBDIV register
114 // Read current mode and update for level (0) or edge detection (1)
122 // Set VPBDIV register to same value as mode
125 // Clear VPBDIV register
128 // Read current polarity and update for trigger level or edge
129 // level: high (1), low (0) edge: rising (1), falling (0)
138 // Set VPBDIV register to same value as mode
141 // Restore saved VPBDIV register
144 // Read current mode and update for level (0) or edge detection (1)
152 // Read current polarity and update for trigger level or edge
153 // level: high (1), low (0) edge: rising (1), falling (0)
161 // Clear any spurious interrupt that might have been generated
165 // Change interrupt level. This is a non-operation on the LPC2XXX
166 void hal_interrupt_set_level(int vector, int level)
170 uint32_t hal_default_isr(int vector, uint32_t data)
175 uint32_t hal_interrupt_handlers[HAL_ISR_COUNT]={[0 ... HAL_ISR_COUNT-1]=(uint32_t)hal_default_isr};
176 uint32_t hal_interrupt_data[HAL_ISR_COUNT];
178 #if !defined(__thumb__)
179 void irq_handler_resolver(void) __attribute__ ((interrupt));
181 void irq_handler_resolver(void)
187 if (v==HAL_INTERRUPT_NONE) return;
188 f=hal_interrupt_handlers[v];
189 d=hal_interrupt_data[v];
191 hal_interrupt_acknowledge(v);
194 int request_irq(unsigned int irqnum, irq_handler_t handler, unsigned long flags,
195 const char *name, void *context)
197 HAL_INTERRUPT_ATTACH(irqnum, handler, context);
198 HAL_INTERRUPT_UNMASK(irqnum);
202 void free_irq(unsigned int irqnum,void *ctx)
204 HAL_INTERRUPT_MASK(irqnum);
205 HAL_INTERRUPT_DETACH(irqnum, NULL);