Updated gpio irq hal with max num of irq

- EXTI lines 5 to 9
- EXTI lines 10 to 15
pull/853/head
milangit 2015-01-20 21:40:05 +01:00
parent 8d97833cad
commit b223f83441
2 changed files with 108 additions and 33 deletions

View File

@ -39,62 +39,125 @@
#define EDGE_BOTH (3) #define EDGE_BOTH (3)
#define CHANNEL_NUM (7) #define CHANNEL_NUM (7)
// Max pins for one line (max with EXTI10_15)
#define MAX_PIN_LINE (6)
static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; typedef struct gpio_channel {
static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts
static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance
uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group
} gpio_channel_t;
static gpio_channel_t channels[CHANNEL_NUM] = {
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0}
};
// Used to return the index for channels array.
static uint32_t pin_base_nr[16] = {
// EXTI0
0, // pin 0
// EXTI1
0, // pin 1
// EXTI2
0, // pin 2
// EXTI3
0, // pin 3
// EXTI4
0, // pin 4
// EXTI5_9
0, // pin 5
1, // pin 6
2, // pin 7
3, // pin 8
4, // pin 9
// EXTI10_15
0, // pin 10
1, // pin 11
2, // pin 12
3, // pin 13
4, // pin 14
5 // pin 15
};
static gpio_irq_handler irq_handler; static gpio_irq_handler irq_handler;
static void handle_interrupt_in(uint32_t irq_index) static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line)
{ {
// Retrieve the gpio and pin that generate the irq gpio_channel_t *gpio_channel = &channels[irq_index];
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]); uint32_t gpio_idx;
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
// Clear interrupt flag for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) {
if (EXTI_GetITStatus(pin) != RESET) { uint32_t current_mask = (1 << gpio_idx);
EXTI_ClearITPendingBit(pin);
}
if (channel_ids[irq_index] == 0) return; if (gpio_channel->pin_mask & current_mask) {
// Retrieve the gpio and pin that generate the irq
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]);
uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx]));
// Check which edge has generated the irq // Clear interrupt flag
if ((gpio->IDR & pin) == 0) { if (EXTI_GetITStatus(pin) != RESET) {
irq_handler(channel_ids[irq_index], IRQ_FALL); EXTI_ClearITPendingBit(pin);
} else {
irq_handler(channel_ids[irq_index], IRQ_RISE); if (gpio_channel->channel_ids[gpio_idx] == 0) continue;
// Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) {
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL);
} else {
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE);
}
}
}
} }
} }
// The irq_index is passed to the function // EXTI line 0
static void gpio_irq0(void) static void gpio_irq0(void)
{ {
handle_interrupt_in(0); // EXTI line 0 handle_interrupt_in(0, 1);
} }
// EXTI line 1
static void gpio_irq1(void) static void gpio_irq1(void)
{ {
handle_interrupt_in(1); // EXTI line 1 handle_interrupt_in(1, 1);
} }
// EXTI line 2
static void gpio_irq2(void) static void gpio_irq2(void)
{ {
handle_interrupt_in(2); // EXTI line 2 handle_interrupt_in(2, 1);
} }
// EXTI line 3
static void gpio_irq3(void) static void gpio_irq3(void)
{ {
handle_interrupt_in(3); // EXTI line 3 handle_interrupt_in(3, 1);
} }
// EXTI line 4
static void gpio_irq4(void) static void gpio_irq4(void)
{ {
handle_interrupt_in(4); // EXTI line 4 handle_interrupt_in(4, 1);
} }
// EXTI lines 5 to 9
static void gpio_irq5(void) static void gpio_irq5(void)
{ {
handle_interrupt_in(5); // EXTI lines 5 to 9 handle_interrupt_in(5, 5);
} }
// EXTI lines 10 to 15
static void gpio_irq6(void) static void gpio_irq6(void)
{ {
handle_interrupt_in(6); // EXTI lines 10 to 15 handle_interrupt_in(6, 6);
} }
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
@ -104,6 +167,8 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
IRQn_Type irq_n = (IRQn_Type)0; IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0; uint32_t vector = 0;
uint32_t irq_index; uint32_t irq_index;
gpio_channel_t *gpio_channel;
uint32_t gpio_idx;
if (pin == NC) return -1; if (pin == NC) return -1;
@ -193,9 +258,13 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
obj->irq_n = irq_n; obj->irq_n = irq_n;
obj->irq_index = irq_index; obj->irq_index = irq_index;
obj->event = EDGE_NONE; obj->event = EDGE_NONE;
channel_ids[irq_index] = id;
channel_gpio[irq_index] = gpio_add; gpio_channel = &channels[irq_index];
channel_pin[irq_index] = pin_index; gpio_idx = pin_base_nr[pin_index];
gpio_channel->pin_mask |= (1 << gpio_idx);
gpio_channel->channel_ids[gpio_idx] = id;
gpio_channel->channel_gpio[gpio_idx] = gpio_add;
gpio_channel->channel_pin[gpio_idx] = pin_index;
irq_handler = handler; irq_handler = handler;
@ -204,9 +273,15 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
void gpio_irq_free(gpio_irq_t *obj) void gpio_irq_free(gpio_irq_t *obj)
{ {
channel_ids[obj->irq_index] = 0; gpio_channel_t *gpio_channel = &channels[obj->irq_index];
channel_gpio[obj->irq_index] = 0; uint32_t pin_index = STM_PIN(obj->pin);
channel_pin[obj->irq_index] = 0; uint32_t gpio_idx = pin_base_nr[pin_index];
gpio_channel->pin_mask &= ~(1 << gpio_idx);
gpio_channel->channel_ids[gpio_idx] = 0;
gpio_channel->channel_gpio[gpio_idx] = 0;
gpio_channel->channel_pin[gpio_idx] = 0;
// Disable EXTI line // Disable EXTI line
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure); EXTI_StructInit(&EXTI_InitStructure);
@ -217,8 +292,7 @@ void gpio_irq_free(gpio_irq_t *obj)
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{ {
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
uint32_t pin_index = STM_PIN(obj->pin);
uint32_t pin_index = channel_pin[obj->irq_index];
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

View File

@ -43,6 +43,7 @@ struct gpio_irq_s {
IRQn_Type irq_n; IRQn_Type irq_n;
uint32_t irq_index; uint32_t irq_index;
uint32_t event; uint32_t event;
PinName pin;
}; };
struct port_s { struct port_s {