Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Revision:
18:6a4db94011d3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-dev/targets/TARGET_ONSEMI/TARGET_NCS36510/gpio_irq_api.c	Sun May 14 23:18:57 2017 +0000
@@ -0,0 +1,246 @@
+/**
+ ******************************************************************************
+ * @file gpio_irq_api.c
+ * @brief Implementation of a GPIO irq handlers
+ * @internal
+ * @author ON Semiconductor
+ * $Rev:
+ * $Date: 2015-11-04 $
+ ******************************************************************************
+ * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
+ * All rights reserved.  This software and/or documentation is licensed by ON Semiconductor
+ * under limited terms and conditions.  The terms and conditions pertaining to the software
+ * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
+ * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
+ * if applicable the software license agreement.  Do not use this software and/or
+ * documentation unless you have carefully read and you agree to the limited terms and
+ * conditions.  By using this software and/or documentation, you agree to the limited
+ * terms and conditions.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ * @endinternal
+ *
+ * @ingroup gpio
+ *
+ * @details
+ *
+ * @internal
+ * <h1> Reference document(s) </h1>
+ * <p>
+ * Reference document: IPC7203 APB GPIO Design Specification v1.2</a>
+ * </p>
+ * @endinternal
+ *
+ * <h1> Functional description (internal) </h1>
+ * <p>
+ * Each GPIO line can be independently programmed as an input or an output. Separate Set
+ * and Clear registers are provided since it is likely that different software tasks may be
+ * servicing different I/O signals. Inputs are synchronized to the system clock
+ * through a pair of flip-flops.  Each input can be programmed
+ * to cause an interrupt to be generated.  The interrupt can be programmed to be level-sensitive
+ * or edge-sensitive and the level (high or low) or edge (rising, falling or either) that causes
+ * the interrupt can be selected.  Interrupts can be individually enabled or disabled.
+ * Level-sensitive interrupts stay asserted until the interrupting condition is cleared.
+ * Edge-triggered interrupts are cleared by writing to the GPIO interrupt clear register.
+ * </p>
+ *
+ * <h1> Use of GPIO driver in SW </h1>
+ * <p>
+ * The user of the GPIO driver should set the pin as GPIO, using crossbar.
+ * Init the GPIO and configure the mode and direction.This will return a device pointer.  One device controls all GPIO's.  It is not
+ * needed nor supported to create a device per GPIO.
+ * Next, the user should call the fGpioOpen function with the device and options as paramter.
+ * </p>
+ * <p>
+ * Use the device driver fGpioIoctl function to change the behavior of the GPIO's and to register an
+ * interrupt handler for each IO that has an interrupt enabled.  There is one interrupt for all GPIO's.
+ * The GPIO driver will look up what IO caused the interrupt and call the respective interrupt handler.
+ * </p>
+ */
+
+
+
+#include "gpio.h"
+
+/* Include files from the mbed-hal layer */
+#include "gpio_irq_api.h"
+
+#include "device.h"
+
+#if DEVICE_INTERRUPTIN
+
+/* Handler for the GPIO pin */
+static gpio_irq_handler irq_handler;
+static uint32_t gpioIds[NUMBER_OF_GPIO] = {0};
+
+/** Main GPIO IRQ handler called from vector table handler
+ *
+ * @param gpioBase  The GPIO register base address
+ * @return          void
+ */
+void fGpioHandler(void)
+{
+    uint8_t index;
+    uint32_t active_interrupts = 0;
+    gpio_irq_event event = IRQ_NONE;
+    GpioReg_pt gpioBase;
+
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+
+    gpioBase = GPIOREG;
+
+    /** - Store all active interrupts */
+    active_interrupts = gpioBase->R_IRQ_W_CLEAR;
+
+    for (index=0; index < NUMBER_OF_GPIO; index++) {
+
+        /* Check the pin for which IRQ is raised */
+        if ((active_interrupts >> index) & 0x01) {
+            /* Check if it is edge triggered and clear the interrupt */
+            if ((gpioBase->IRQ_EDGE >> index) &  0x01) {
+                if ((gpioBase->IRQ_POLARITY_SET >> index) &0x01)  {
+                    /* Edge triggered high */
+                    event = IRQ_RISE;
+                } else {
+                    /* Edge triggered low */
+                    event = IRQ_FALL;
+                }
+            }
+            gpioBase->IRQ_CLEAR = (0x1 << index);
+
+            /* Call the handler registered to the pin */
+            irq_handler(gpioIds[index], event);
+        }
+
+    }
+}
+
+/** Initialize the GPIO IRQ pin
+ *
+ * @param obj     The GPIO object to initialize
+ * @param pin     The GPIO pin name
+ * @param handler The handler to be attached to GPIO IRQ
+ * @param id      The object ID
+ * @return -1 if pin is NC, 0 otherwise
+ */
+int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
+{
+    /* If Pin is not connected; then return -1 */
+    if (pin == NC) {
+        return(-1);
+    }
+
+    /* Store the pin for which handler is registered */
+    obj->pin = pin;
+    obj->pinMask = (0x1 << pin);
+
+    /* Store the ID, this is required by registered handler function */
+    gpioIds[pin] = id;
+
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+
+    /* Initialize the GPIO membase */
+    obj->GPIOMEMBASE = GPIOREG;
+
+    /* Set default values for the pin interrupt */
+    obj->GPIOMEMBASE->W_IN = obj->pinMask;
+    obj->GPIOMEMBASE->IRQ_EDGE = obj->pinMask;
+    obj->GPIOMEMBASE->IRQ_POLARITY_SET = obj->pinMask;
+
+    /* Register the handler for this pin */
+    irq_handler = handler;
+
+    /* Enable interruption associated with the gpio */
+    NVIC_ClearPendingIRQ(Gpio_IRQn);
+    NVIC_EnableIRQ(Gpio_IRQn);
+
+    return(0);
+}
+
+/** Release the GPIO IRQ PIN
+ *
+ * @param obj The gpio object
+ */
+void gpio_irq_free(gpio_irq_t *obj)
+{
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+
+    /* Disable IRQs to indicate that it is now free */
+    obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
+    gpioIds[obj->pin] = 0;
+}
+
+/** Enable/disable pin IRQ event
+ *
+ * @param obj    The GPIO object
+ * @param event  The GPIO IRQ event
+ * @param enable The enable flag
+ */
+void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
+{
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+    obj->GPIOMEMBASE->IRQ_EDGE = obj->pinMask;
+    
+    switch(event) {
+        case IRQ_RISE: 
+          
+            /* Enable rising edge */
+            obj->GPIOMEMBASE->IRQ_POLARITY_SET = obj->pinMask;
+           break;
+
+        case IRQ_FALL:
+
+            /* Enable falling edge */
+            obj->GPIOMEMBASE->IRQ_POLARITY_CLEAR = obj->pinMask;
+            break;
+
+        default:
+            /* No event is set */
+            break;
+    }
+    /* Enable the IRQ based on enable parameter */
+    if (enable) {
+
+        obj->GPIOMEMBASE->IRQ_ENABLE_SET = obj->pinMask;
+    } else {
+
+        obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
+    }
+}
+
+/** Enable GPIO IRQ
+ *
+ * This is target dependent, as it might enable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_enable(gpio_irq_t *obj)
+{
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+
+    obj->GPIOMEMBASE->IRQ_ENABLE_SET = obj->pinMask;
+}
+
+/** Disable GPIO IRQ
+ *
+ * This is target dependent, as it might disable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_disable(gpio_irq_t *obj)
+{
+
+    /* Enable the GPIO clock which may have been switched off by other drivers */
+    CLOCK_ENABLE(CLOCK_GPIO);
+
+    obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
+}
+
+#endif //DEVICE_INTERRUPTIN