mbed library sources modified for open wear
Dependents: openwear-lifelogger-example
Fork of mbed-src by
Revision 254:181b5e179739, committed 2014-07-10
- Comitter:
- mbed_official
- Date:
- Thu Jul 10 09:00:09 2014 +0100
- Parent:
- 253:fd34e7cf1b98
- Child:
- 255:20b371a9491b
- Commit message:
- Synchronized with git revision ffef32f2bc6fb88a72a992e85a9e9df0982d7eff
Full URL: https://github.com/mbedmicro/mbed/commit/ffef32f2bc6fb88a72a992e85a9e9df0982d7eff/
[KLxxZ] Increased KLxxZs interrupt handling speed
Changed in this revision
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/gpio_irq_api.c Wed Jul 09 11:00:08 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/gpio_irq_api.c Thu Jul 10 09:00:09 2014 +0100 @@ -30,40 +30,45 @@ #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10) #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11) +const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001}; + static void handle_interrupt_in(PORT_Type *port, int ch_base) { - uint32_t mask = 0, i; + uint32_t isfr; + uint8_t location; - for (i = 0; i < 32; i++) { - uint32_t pmask = (1 << i); - if (port->ISFR & pmask) { - mask |= pmask; - uint32_t id = channel_ids[ch_base + i]; - if (id == 0) { - continue; - } + while((isfr = port->ISFR) != 0) { + location = 0; + for (int i = 0; i < 5; i++) { + if (!(isfr & (search_bits[i] << location))) + location += 1 << (4 - i); + } + + uint32_t id = channel_ids[ch_base + location]; + if (id == 0) { + continue; + } - FGPIO_Type *gpio; - gpio_irq_event event = IRQ_NONE; - switch (port->PCR[i] & PORT_PCR_IRQC_MASK) { - case IRQ_RAISING_EDGE: - event = IRQ_RISE; - break; + FGPIO_Type *gpio; + gpio_irq_event event = IRQ_NONE; + switch (port->PCR[location] & PORT_PCR_IRQC_MASK) { + case IRQ_RAISING_EDGE: + event = IRQ_RISE; + break; - case IRQ_FALLING_EDGE: - event = IRQ_FALL; - break; + case IRQ_FALLING_EDGE: + event = IRQ_FALL; + break; - case IRQ_EITHER_EDGE: - gpio = (port == PORTA) ? (FPTA) : (FPTB); - event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL); - break; - } - if (event != IRQ_NONE) { - irq_handler(id, event); - } + case IRQ_EITHER_EDGE: + gpio = (port == PORTA) ? (FPTA) : (FPTB); + event = (gpio->PDIR & (1 << location)) ? (IRQ_RISE) : (IRQ_FALL); + break; } + if (event != IRQ_NONE) { + irq_handler(id, event); + } + port->ISFR = 1 << location; } - port->ISFR = mask; } /* IRQ only on PORTA and PORTB */ @@ -86,21 +91,21 @@ uint32_t ch_base, vector; IRQn_Type irq_n; switch (obj->port) { - case PortA: - ch_base = 0; - irq_n = PORTA_IRQn; - vector = (uint32_t)gpio_irqA; - break; + case PortA: + ch_base = 0; + irq_n = PORTA_IRQn; + vector = (uint32_t)gpio_irqA; + break; - case PortB: - ch_base = 32; - irq_n = PORTB_IRQn; - vector = (uint32_t)gpio_irqB; - break; + case PortB: + ch_base = 32; + irq_n = PORTB_IRQn; + vector = (uint32_t)gpio_irqB; + break; - default: - error("gpio_irq only supported on Port A and B"); - break; + default: + error("gpio_irq only supported on Port A and B"); + break; } NVIC_SetVector(irq_n, vector); NVIC_EnableIRQ(irq_n);
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/gpio_irq_api.c Wed Jul 09 11:00:08 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/gpio_irq_api.c Thu Jul 10 09:00:09 2014 +0100 @@ -30,40 +30,45 @@ #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10) #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11) +const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001}; + static void handle_interrupt_in(PORT_Type *port, int ch_base) { - uint32_t mask = 0, i; + uint32_t isfr; + uint8_t location; - for (i = 0; i < 32; i++) { - uint32_t pmask = (1 << i); - if (port->ISFR & pmask) { - mask |= pmask; - uint32_t id = channel_ids[ch_base + i]; - if (id == 0) { - continue; - } + while((isfr = port->ISFR) != 0) { + location = 0; + for (int i = 0; i < 5; i++) { + if (!(isfr & (search_bits[i] << location))) + location += 1 << (4 - i); + } + + uint32_t id = channel_ids[ch_base + location]; + if (id == 0) { + continue; + } - FGPIO_Type *gpio; - gpio_irq_event event = IRQ_NONE; - switch (port->PCR[i] & PORT_PCR_IRQC_MASK) { - case IRQ_RAISING_EDGE: - event = IRQ_RISE; - break; + FGPIO_Type *gpio; + gpio_irq_event event = IRQ_NONE; + switch (port->PCR[location] & PORT_PCR_IRQC_MASK) { + case IRQ_RAISING_EDGE: + event = IRQ_RISE; + break; - case IRQ_FALLING_EDGE: - event = IRQ_FALL; - break; + case IRQ_FALLING_EDGE: + event = IRQ_FALL; + break; - case IRQ_EITHER_EDGE: - gpio = (port == PORTA) ? (FPTA) : (FPTD); - event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL); - break; - } - if (event != IRQ_NONE) { - irq_handler(id, event); - } + case IRQ_EITHER_EDGE: + gpio = (port == PORTA) ? (FPTA) : (FPTD); + event = (gpio->PDIR & (1 << location)) ? (IRQ_RISE) : (IRQ_FALL); + break; } + if (event != IRQ_NONE) { + irq_handler(id, event); + } + port->ISFR = 1 << location; } - port->ISFR = mask; } void gpio_irqA(void) {handle_interrupt_in(PORTA, 0);}
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c Wed Jul 09 11:00:08 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c Thu Jul 10 09:00:09 2014 +0100 @@ -30,45 +30,51 @@ #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10) #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11) +const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001}; + static void handle_interrupt_in(PORT_Type *port, int ch_base) { - uint32_t mask = 0, i; + uint32_t isfr; + uint8_t location; - for (i = 0; i < 32; i++) { - uint32_t pmask = (1 << i); - if (port->ISFR & pmask) { - mask |= pmask; - uint32_t id = channel_ids[ch_base + i]; - if (id == 0) { - continue; - } - - FGPIO_Type *gpio; - gpio_irq_event event = IRQ_NONE; - switch (port->PCR[i] & PORT_PCR_IRQC_MASK) { - case IRQ_RAISING_EDGE: - event = IRQ_RISE; - break; + while((isfr = port->ISFR) != 0) { + location = 0; + for (int i = 0; i < 5; i++) { + if (!(isfr & (search_bits[i] << location))) + location += 1 << (4 - i); + } + + uint32_t id = channel_ids[ch_base + location]; + if (id == 0) { + continue; + } - case IRQ_FALLING_EDGE: - event = IRQ_FALL; - break; + FGPIO_Type *gpio; + gpio_irq_event event = IRQ_NONE; + switch (port->PCR[location] & PORT_PCR_IRQC_MASK) { + case IRQ_RAISING_EDGE: + event = IRQ_RISE; + break; + + case IRQ_FALLING_EDGE: + event = IRQ_FALL; + break; - case IRQ_EITHER_EDGE: - if (port == PORTA) { - gpio = FPTA; - } else if (port == PORTC) { - gpio = FPTC; - } else { - gpio = FPTD; - } - event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL); - break; - } - if (event != IRQ_NONE) - irq_handler(id, event); + case IRQ_EITHER_EDGE: + if (port == PORTA) { + gpio = FPTA; + } else if (port == PORTC) { + gpio = FPTC; + } else { + gpio = FPTD; + } + event = (gpio->PDIR & (1<<location)) ? (IRQ_RISE) : (IRQ_FALL); + break; } + if (event != IRQ_NONE) { + irq_handler(id, event); + } + port->ISFR = 1 << location; } - port->ISFR = mask; } void gpio_irqA(void) {