Fixed bug in gpio_irq_api

Test interruptin now works. Fixes #16
pull/17/head
Matthew Else 2013-07-25 10:26:46 +01:00
parent ddf19e9a4d
commit a7ba27618d
1 changed files with 45 additions and 15 deletions

View File

@ -41,10 +41,14 @@ static inline void handle_interrupt_in(uint32_t channel) {
// Rising edge.
irq_handler(channel_ids[channel], IRQ_RISE);
}
else {
else if (trigger_event == 2) {
// Low, therefore falling edge...
irq_handler(channel_ids[channel], IRQ_FALL);
}
else {
// This is supposed to be triggered by both cases...
irq_handler(channel_ids[channel], IRQ_RISE);
}
// Clear the interrupt...
port_reg->IC |= 1 << pin_num;
@ -116,12 +120,50 @@ void gpio_irq_free(gpio_irq_t *obj) {
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
// Firstly, check if there is an existing event stored...
LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (((obj->pin & 0xF000) >> PORT_SHIFT) * 0x10000)));
// Need to get the pin number of the pin, not the value of the enum
uint8_t pin_num = (obj->pin & (0x0f << PIN_SHIFT)) >> PIN_SHIFT;
trigger_events[obj->ch] = event == IRQ_RISE ? 1 : 0;
if (trigger_events[obj->ch] != 0) {
// We have an event.
// Enable both edge interrupts.
if (enable) {
trigger_events[obj->ch] = 3;
port_reg->IBE |= 1 << pin_num;
port_reg->IE |= 1 << pin_num;
}
else {
// These all need to be opposite, to reenable the other one.
trigger_events[obj->ch] = event == IRQ_RISE ? 2 : 1;
port_reg->IBE &= ~(1 << pin_num);
if (event == IRQ_RISE)
port_reg->IEV &= ~(1 << pin_num);
else
port_reg->IEV |= 1 << pin_num;
port_reg->IE |= 1 << pin_num;
}
}
else {
if (enable) {
trigger_events[obj->ch] = event == IRQ_RISE ? 1 : 2;
port_reg->IE |= 1 << pin_num;
}
// One edge
port_reg->IBE &= ~(1 << pin_num);
// Rising/falling?
if (event == IRQ_RISE)
port_reg->IEV |= 1 << pin_num;
else
port_reg->IEV &= ~(1 << pin_num);
}
/*
Firstly, clear the interrupts for this pin,
@ -133,18 +175,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
// Clear
port_reg->IC |= 1 << pin_num;
// Edge
// Make it edge sensitive.
port_reg->IS &= ~(1 << pin_num);
// Enable
if (enable) port_reg->IE |= 1 << pin_num;
else port_reg->IE &= ~(1 << pin_num);
// One edge
port_reg->IBE &= ~(1 << pin_num);
// Rising/falling?
if (event == IRQ_RISE) port_reg->IEV |= 1 << pin_num;
else port_reg->IEV &= ~(1 << pin_num);
}