Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /**
sahilmgandhi 18:6a4db94011d3 2 ******************************************************************************
sahilmgandhi 18:6a4db94011d3 3 * @file gpio_irq_api.c
sahilmgandhi 18:6a4db94011d3 4 * @brief Implementation of a GPIO irq handlers
sahilmgandhi 18:6a4db94011d3 5 * @internal
sahilmgandhi 18:6a4db94011d3 6 * @author ON Semiconductor
sahilmgandhi 18:6a4db94011d3 7 * $Rev:
sahilmgandhi 18:6a4db94011d3 8 * $Date: 2015-11-04 $
sahilmgandhi 18:6a4db94011d3 9 ******************************************************************************
sahilmgandhi 18:6a4db94011d3 10 * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
sahilmgandhi 18:6a4db94011d3 11 * All rights reserved. This software and/or documentation is licensed by ON Semiconductor
sahilmgandhi 18:6a4db94011d3 12 * under limited terms and conditions. The terms and conditions pertaining to the software
sahilmgandhi 18:6a4db94011d3 13 * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
sahilmgandhi 18:6a4db94011d3 14 * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
sahilmgandhi 18:6a4db94011d3 15 * if applicable the software license agreement. Do not use this software and/or
sahilmgandhi 18:6a4db94011d3 16 * documentation unless you have carefully read and you agree to the limited terms and
sahilmgandhi 18:6a4db94011d3 17 * conditions. By using this software and/or documentation, you agree to the limited
sahilmgandhi 18:6a4db94011d3 18 * terms and conditions.
sahilmgandhi 18:6a4db94011d3 19 *
sahilmgandhi 18:6a4db94011d3 20 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
sahilmgandhi 18:6a4db94011d3 21 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
sahilmgandhi 18:6a4db94011d3 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
sahilmgandhi 18:6a4db94011d3 23 * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
sahilmgandhi 18:6a4db94011d3 24 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
sahilmgandhi 18:6a4db94011d3 25 * @endinternal
sahilmgandhi 18:6a4db94011d3 26 *
sahilmgandhi 18:6a4db94011d3 27 * @ingroup gpio
sahilmgandhi 18:6a4db94011d3 28 *
sahilmgandhi 18:6a4db94011d3 29 * @details
sahilmgandhi 18:6a4db94011d3 30 *
sahilmgandhi 18:6a4db94011d3 31 * @internal
sahilmgandhi 18:6a4db94011d3 32 * <h1> Reference document(s) </h1>
sahilmgandhi 18:6a4db94011d3 33 * <p>
sahilmgandhi 18:6a4db94011d3 34 * Reference document: IPC7203 APB GPIO Design Specification v1.2</a>
sahilmgandhi 18:6a4db94011d3 35 * </p>
sahilmgandhi 18:6a4db94011d3 36 * @endinternal
sahilmgandhi 18:6a4db94011d3 37 *
sahilmgandhi 18:6a4db94011d3 38 * <h1> Functional description (internal) </h1>
sahilmgandhi 18:6a4db94011d3 39 * <p>
sahilmgandhi 18:6a4db94011d3 40 * Each GPIO line can be independently programmed as an input or an output. Separate Set
sahilmgandhi 18:6a4db94011d3 41 * and Clear registers are provided since it is likely that different software tasks may be
sahilmgandhi 18:6a4db94011d3 42 * servicing different I/O signals. Inputs are synchronized to the system clock
sahilmgandhi 18:6a4db94011d3 43 * through a pair of flip-flops. Each input can be programmed
sahilmgandhi 18:6a4db94011d3 44 * to cause an interrupt to be generated. The interrupt can be programmed to be level-sensitive
sahilmgandhi 18:6a4db94011d3 45 * or edge-sensitive and the level (high or low) or edge (rising, falling or either) that causes
sahilmgandhi 18:6a4db94011d3 46 * the interrupt can be selected. Interrupts can be individually enabled or disabled.
sahilmgandhi 18:6a4db94011d3 47 * Level-sensitive interrupts stay asserted until the interrupting condition is cleared.
sahilmgandhi 18:6a4db94011d3 48 * Edge-triggered interrupts are cleared by writing to the GPIO interrupt clear register.
sahilmgandhi 18:6a4db94011d3 49 * </p>
sahilmgandhi 18:6a4db94011d3 50 *
sahilmgandhi 18:6a4db94011d3 51 * <h1> Use of GPIO driver in SW </h1>
sahilmgandhi 18:6a4db94011d3 52 * <p>
sahilmgandhi 18:6a4db94011d3 53 * The user of the GPIO driver should set the pin as GPIO, using crossbar.
sahilmgandhi 18:6a4db94011d3 54 * Init the GPIO and configure the mode and direction.This will return a device pointer. One device controls all GPIO's. It is not
sahilmgandhi 18:6a4db94011d3 55 * needed nor supported to create a device per GPIO.
sahilmgandhi 18:6a4db94011d3 56 * Next, the user should call the fGpioOpen function with the device and options as paramter.
sahilmgandhi 18:6a4db94011d3 57 * </p>
sahilmgandhi 18:6a4db94011d3 58 * <p>
sahilmgandhi 18:6a4db94011d3 59 * Use the device driver fGpioIoctl function to change the behavior of the GPIO's and to register an
sahilmgandhi 18:6a4db94011d3 60 * interrupt handler for each IO that has an interrupt enabled. There is one interrupt for all GPIO's.
sahilmgandhi 18:6a4db94011d3 61 * The GPIO driver will look up what IO caused the interrupt and call the respective interrupt handler.
sahilmgandhi 18:6a4db94011d3 62 * </p>
sahilmgandhi 18:6a4db94011d3 63 */
sahilmgandhi 18:6a4db94011d3 64
sahilmgandhi 18:6a4db94011d3 65
sahilmgandhi 18:6a4db94011d3 66
sahilmgandhi 18:6a4db94011d3 67 #include "gpio.h"
sahilmgandhi 18:6a4db94011d3 68
sahilmgandhi 18:6a4db94011d3 69 /* Include files from the mbed-hal layer */
sahilmgandhi 18:6a4db94011d3 70 #include "gpio_irq_api.h"
sahilmgandhi 18:6a4db94011d3 71
sahilmgandhi 18:6a4db94011d3 72 #include "device.h"
sahilmgandhi 18:6a4db94011d3 73
sahilmgandhi 18:6a4db94011d3 74 #if DEVICE_INTERRUPTIN
sahilmgandhi 18:6a4db94011d3 75
sahilmgandhi 18:6a4db94011d3 76 /* Handler for the GPIO pin */
sahilmgandhi 18:6a4db94011d3 77 static gpio_irq_handler irq_handler;
sahilmgandhi 18:6a4db94011d3 78 static uint32_t gpioIds[NUMBER_OF_GPIO] = {0};
sahilmgandhi 18:6a4db94011d3 79
sahilmgandhi 18:6a4db94011d3 80 /** Main GPIO IRQ handler called from vector table handler
sahilmgandhi 18:6a4db94011d3 81 *
sahilmgandhi 18:6a4db94011d3 82 * @param gpioBase The GPIO register base address
sahilmgandhi 18:6a4db94011d3 83 * @return void
sahilmgandhi 18:6a4db94011d3 84 */
sahilmgandhi 18:6a4db94011d3 85 void fGpioHandler(void)
sahilmgandhi 18:6a4db94011d3 86 {
sahilmgandhi 18:6a4db94011d3 87 uint8_t index;
sahilmgandhi 18:6a4db94011d3 88 uint32_t active_interrupts = 0;
sahilmgandhi 18:6a4db94011d3 89 gpio_irq_event event = IRQ_NONE;
sahilmgandhi 18:6a4db94011d3 90 GpioReg_pt gpioBase;
sahilmgandhi 18:6a4db94011d3 91
sahilmgandhi 18:6a4db94011d3 92 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 93 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 94
sahilmgandhi 18:6a4db94011d3 95 gpioBase = GPIOREG;
sahilmgandhi 18:6a4db94011d3 96
sahilmgandhi 18:6a4db94011d3 97 /** - Store all active interrupts */
sahilmgandhi 18:6a4db94011d3 98 active_interrupts = gpioBase->R_IRQ_W_CLEAR;
sahilmgandhi 18:6a4db94011d3 99
sahilmgandhi 18:6a4db94011d3 100 for (index=0; index < NUMBER_OF_GPIO; index++) {
sahilmgandhi 18:6a4db94011d3 101
sahilmgandhi 18:6a4db94011d3 102 /* Check the pin for which IRQ is raised */
sahilmgandhi 18:6a4db94011d3 103 if ((active_interrupts >> index) & 0x01) {
sahilmgandhi 18:6a4db94011d3 104 /* Check if it is edge triggered and clear the interrupt */
sahilmgandhi 18:6a4db94011d3 105 if ((gpioBase->IRQ_EDGE >> index) & 0x01) {
sahilmgandhi 18:6a4db94011d3 106 if ((gpioBase->IRQ_POLARITY_SET >> index) &0x01) {
sahilmgandhi 18:6a4db94011d3 107 /* Edge triggered high */
sahilmgandhi 18:6a4db94011d3 108 event = IRQ_RISE;
sahilmgandhi 18:6a4db94011d3 109 } else {
sahilmgandhi 18:6a4db94011d3 110 /* Edge triggered low */
sahilmgandhi 18:6a4db94011d3 111 event = IRQ_FALL;
sahilmgandhi 18:6a4db94011d3 112 }
sahilmgandhi 18:6a4db94011d3 113 }
sahilmgandhi 18:6a4db94011d3 114 gpioBase->IRQ_CLEAR = (0x1 << index);
sahilmgandhi 18:6a4db94011d3 115
sahilmgandhi 18:6a4db94011d3 116 /* Call the handler registered to the pin */
sahilmgandhi 18:6a4db94011d3 117 irq_handler(gpioIds[index], event);
sahilmgandhi 18:6a4db94011d3 118 }
sahilmgandhi 18:6a4db94011d3 119
sahilmgandhi 18:6a4db94011d3 120 }
sahilmgandhi 18:6a4db94011d3 121 }
sahilmgandhi 18:6a4db94011d3 122
sahilmgandhi 18:6a4db94011d3 123 /** Initialize the GPIO IRQ pin
sahilmgandhi 18:6a4db94011d3 124 *
sahilmgandhi 18:6a4db94011d3 125 * @param obj The GPIO object to initialize
sahilmgandhi 18:6a4db94011d3 126 * @param pin The GPIO pin name
sahilmgandhi 18:6a4db94011d3 127 * @param handler The handler to be attached to GPIO IRQ
sahilmgandhi 18:6a4db94011d3 128 * @param id The object ID
sahilmgandhi 18:6a4db94011d3 129 * @return -1 if pin is NC, 0 otherwise
sahilmgandhi 18:6a4db94011d3 130 */
sahilmgandhi 18:6a4db94011d3 131 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
sahilmgandhi 18:6a4db94011d3 132 {
sahilmgandhi 18:6a4db94011d3 133 /* If Pin is not connected; then return -1 */
sahilmgandhi 18:6a4db94011d3 134 if (pin == NC) {
sahilmgandhi 18:6a4db94011d3 135 return(-1);
sahilmgandhi 18:6a4db94011d3 136 }
sahilmgandhi 18:6a4db94011d3 137
sahilmgandhi 18:6a4db94011d3 138 /* Store the pin for which handler is registered */
sahilmgandhi 18:6a4db94011d3 139 obj->pin = pin;
sahilmgandhi 18:6a4db94011d3 140 obj->pinMask = (0x1 << pin);
sahilmgandhi 18:6a4db94011d3 141
sahilmgandhi 18:6a4db94011d3 142 /* Store the ID, this is required by registered handler function */
sahilmgandhi 18:6a4db94011d3 143 gpioIds[pin] = id;
sahilmgandhi 18:6a4db94011d3 144
sahilmgandhi 18:6a4db94011d3 145 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 146 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 147
sahilmgandhi 18:6a4db94011d3 148 /* Initialize the GPIO membase */
sahilmgandhi 18:6a4db94011d3 149 obj->GPIOMEMBASE = GPIOREG;
sahilmgandhi 18:6a4db94011d3 150
sahilmgandhi 18:6a4db94011d3 151 /* Set default values for the pin interrupt */
sahilmgandhi 18:6a4db94011d3 152 obj->GPIOMEMBASE->W_IN = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 153 obj->GPIOMEMBASE->IRQ_EDGE = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 154 obj->GPIOMEMBASE->IRQ_POLARITY_SET = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 155
sahilmgandhi 18:6a4db94011d3 156 /* Register the handler for this pin */
sahilmgandhi 18:6a4db94011d3 157 irq_handler = handler;
sahilmgandhi 18:6a4db94011d3 158
sahilmgandhi 18:6a4db94011d3 159 /* Enable interruption associated with the gpio */
sahilmgandhi 18:6a4db94011d3 160 NVIC_ClearPendingIRQ(Gpio_IRQn);
sahilmgandhi 18:6a4db94011d3 161 NVIC_EnableIRQ(Gpio_IRQn);
sahilmgandhi 18:6a4db94011d3 162
sahilmgandhi 18:6a4db94011d3 163 return(0);
sahilmgandhi 18:6a4db94011d3 164 }
sahilmgandhi 18:6a4db94011d3 165
sahilmgandhi 18:6a4db94011d3 166 /** Release the GPIO IRQ PIN
sahilmgandhi 18:6a4db94011d3 167 *
sahilmgandhi 18:6a4db94011d3 168 * @param obj The gpio object
sahilmgandhi 18:6a4db94011d3 169 */
sahilmgandhi 18:6a4db94011d3 170 void gpio_irq_free(gpio_irq_t *obj)
sahilmgandhi 18:6a4db94011d3 171 {
sahilmgandhi 18:6a4db94011d3 172 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 173 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 174
sahilmgandhi 18:6a4db94011d3 175 /* Disable IRQs to indicate that it is now free */
sahilmgandhi 18:6a4db94011d3 176 obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 177 gpioIds[obj->pin] = 0;
sahilmgandhi 18:6a4db94011d3 178 }
sahilmgandhi 18:6a4db94011d3 179
sahilmgandhi 18:6a4db94011d3 180 /** Enable/disable pin IRQ event
sahilmgandhi 18:6a4db94011d3 181 *
sahilmgandhi 18:6a4db94011d3 182 * @param obj The GPIO object
sahilmgandhi 18:6a4db94011d3 183 * @param event The GPIO IRQ event
sahilmgandhi 18:6a4db94011d3 184 * @param enable The enable flag
sahilmgandhi 18:6a4db94011d3 185 */
sahilmgandhi 18:6a4db94011d3 186 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
sahilmgandhi 18:6a4db94011d3 187 {
sahilmgandhi 18:6a4db94011d3 188 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 189 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 190 obj->GPIOMEMBASE->IRQ_EDGE = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 191
sahilmgandhi 18:6a4db94011d3 192 switch(event) {
sahilmgandhi 18:6a4db94011d3 193 case IRQ_RISE:
sahilmgandhi 18:6a4db94011d3 194
sahilmgandhi 18:6a4db94011d3 195 /* Enable rising edge */
sahilmgandhi 18:6a4db94011d3 196 obj->GPIOMEMBASE->IRQ_POLARITY_SET = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 197 break;
sahilmgandhi 18:6a4db94011d3 198
sahilmgandhi 18:6a4db94011d3 199 case IRQ_FALL:
sahilmgandhi 18:6a4db94011d3 200
sahilmgandhi 18:6a4db94011d3 201 /* Enable falling edge */
sahilmgandhi 18:6a4db94011d3 202 obj->GPIOMEMBASE->IRQ_POLARITY_CLEAR = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 203 break;
sahilmgandhi 18:6a4db94011d3 204
sahilmgandhi 18:6a4db94011d3 205 default:
sahilmgandhi 18:6a4db94011d3 206 /* No event is set */
sahilmgandhi 18:6a4db94011d3 207 break;
sahilmgandhi 18:6a4db94011d3 208 }
sahilmgandhi 18:6a4db94011d3 209 /* Enable the IRQ based on enable parameter */
sahilmgandhi 18:6a4db94011d3 210 if (enable) {
sahilmgandhi 18:6a4db94011d3 211
sahilmgandhi 18:6a4db94011d3 212 obj->GPIOMEMBASE->IRQ_ENABLE_SET = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 213 } else {
sahilmgandhi 18:6a4db94011d3 214
sahilmgandhi 18:6a4db94011d3 215 obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 216 }
sahilmgandhi 18:6a4db94011d3 217 }
sahilmgandhi 18:6a4db94011d3 218
sahilmgandhi 18:6a4db94011d3 219 /** Enable GPIO IRQ
sahilmgandhi 18:6a4db94011d3 220 *
sahilmgandhi 18:6a4db94011d3 221 * This is target dependent, as it might enable the entire port or just a pin
sahilmgandhi 18:6a4db94011d3 222 * @param obj The GPIO object
sahilmgandhi 18:6a4db94011d3 223 */
sahilmgandhi 18:6a4db94011d3 224 void gpio_irq_enable(gpio_irq_t *obj)
sahilmgandhi 18:6a4db94011d3 225 {
sahilmgandhi 18:6a4db94011d3 226 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 227 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 228
sahilmgandhi 18:6a4db94011d3 229 obj->GPIOMEMBASE->IRQ_ENABLE_SET = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 230 }
sahilmgandhi 18:6a4db94011d3 231
sahilmgandhi 18:6a4db94011d3 232 /** Disable GPIO IRQ
sahilmgandhi 18:6a4db94011d3 233 *
sahilmgandhi 18:6a4db94011d3 234 * This is target dependent, as it might disable the entire port or just a pin
sahilmgandhi 18:6a4db94011d3 235 * @param obj The GPIO object
sahilmgandhi 18:6a4db94011d3 236 */
sahilmgandhi 18:6a4db94011d3 237 void gpio_irq_disable(gpio_irq_t *obj)
sahilmgandhi 18:6a4db94011d3 238 {
sahilmgandhi 18:6a4db94011d3 239
sahilmgandhi 18:6a4db94011d3 240 /* Enable the GPIO clock which may have been switched off by other drivers */
sahilmgandhi 18:6a4db94011d3 241 CLOCK_ENABLE(CLOCK_GPIO);
sahilmgandhi 18:6a4db94011d3 242
sahilmgandhi 18:6a4db94011d3 243 obj->GPIOMEMBASE->IRQ_ENABLE_CLEAR = obj->pinMask;
sahilmgandhi 18:6a4db94011d3 244 }
sahilmgandhi 18:6a4db94011d3 245
sahilmgandhi 18:6a4db94011d3 246 #endif //DEVICE_INTERRUPTIN