Erik - / mbed-src

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
Sissors
Date:
Fri Jul 25 18:40:53 2014 +0000
Parent:
192:42b1a45e48aa
Commit message:
Working sleep :D

Changed in this revision

targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/gpio_irq_api.c	Thu May 15 17:15:05 2014 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/gpio_irq_api.c	Fri Jul 25 18:40:53 2014 +0000
@@ -30,52 +30,61 @@
 #define IRQ_FALLING_EDGE    PORT_PCR_IRQC(10)
 #define IRQ_EITHER_EDGE     PORT_PCR_IRQC(11)
 
-static void handle_interrupt_in(PORT_Type *port, int ch_base) {
-    uint32_t mask = 0, i;
+const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001};
+
+static void handle_interrupt_in(PORT_Type *port, int ch_base)
+{
+    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 */
-void gpio_irqA(void) {
+void gpio_irqA(void)
+{
     handle_interrupt_in(PORTA, 0);
 }
 
-void gpio_irqB(void) {
+void gpio_irqB(void)
+{
     handle_interrupt_in(PORTB, 32);
 }
 
-int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
+int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
+{
     if (pin == NC) return -1;
 
     irq_handler = handler;
@@ -86,21 +95,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);
@@ -111,11 +120,13 @@
     return 0;
 }
 
-void gpio_irq_free(gpio_irq_t *obj) {
+void gpio_irq_free(gpio_irq_t *obj)
+{
     channel_ids[obj->ch] = 0;
 }
 
-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)
+{
     PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port);
 
     uint32_t irq_settings = IRQ_DISABLED;
@@ -158,7 +169,8 @@
     port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
 }
 
-void gpio_irq_enable(gpio_irq_t *obj) {
+void gpio_irq_enable(gpio_irq_t *obj)
+{
     if (obj->port == PortA) {
         NVIC_EnableIRQ(PORTA_IRQn);
     } else if (obj->port == PortB) {
@@ -166,7 +178,8 @@
     }
 }
 
-void gpio_irq_disable(gpio_irq_t *obj) {
+void gpio_irq_disable(gpio_irq_t *obj)
+{
     if (obj->port == PortA) {
         NVIC_DisableIRQ(PORTA_IRQn);
     } else if (obj->port == PortB) {
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/gpio_irq_api.c	Thu May 15 17:15:05 2014 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/gpio_irq_api.c	Fri Jul 25 18:40:53 2014 +0000
@@ -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	Thu May 15 17:15:05 2014 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c	Fri Jul 25 18:40:53 2014 +0000
@@ -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) {
--- a/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c	Thu May 15 17:15:05 2014 +0100
+++ b/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c	Fri Jul 25 18:40:53 2014 +0000
@@ -18,10 +18,6 @@
 #include "mbed_interface.h"
 
 void sleep(void) {
-#if DEVICE_SEMIHOST
-    // ensure debug is disconnected
-    mbed_interface_disconnect();
-#endif
     
     // PCON[DPDEN] set to sleep
     LPC_PMU->PCON = 0x0;
@@ -33,46 +29,19 @@
     __WFI();
 }
 
-/*
-* The mbed lpc1768 does not support the deepsleep mode
-* as a debugger is connected to it (the mbed interface).
-*
-* As mentionned in an application note from NXP:
-*
-*       http://www.po-star.com/public/uploads/20120319123122_141.pdf
-*
-*       {{{
-*       The user should be aware of certain limitations during debugging.
-*       The most important is that, due to limitations of the Cortex-M3
-*       integration, the LPC17xx cannot wake up in the usual manner from
-*       Deep Sleep and Power-down modes. It is recommended not to use these
-*       modes during debug. Once an application is downloaded via JTAG/SWD
-*       interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example)
-*       should be removed from the target board, and thereafter, power cycle
-*       the LPC17xx to allow wake-up from deep sleep and power-down modes
-*       }}}
-*
-*       As the interface firmware does not reset the target when a
-*       mbed_interface_disconnect() semihosting call is made, the
-*       core cannot wake-up from deepsleep.
-*
-*       We treat a deepsleep() as a normal sleep().
-*/
-
 void deepsleep(void) {
-#if DEVICE_SEMIHOST
-    // ensure debug is disconnected
-    mbed_interface_disconnect();
-#endif
     
     // PCON[DPDEN] set to deepsleep
-    LPC_PMU->PCON = 0x2;
+    LPC_PMU->PCON = 0;
     
     // SRC[SLEEPDEEP] set to 1 = deep sleep
     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
     
+    LPC_SYSCON->PDSLEEPCFG = 0x000018FF;
+    
     // Power up everything after powerdown
     LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800;
+
     
     // wait for interrupt
     __WFI();