Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Fri May 26 17:21:04 2017 +0000
Revision:
34:69342782fb68
Parent:
18:6a4db94011d3
Added small reverse turns before the break so that we can stop faster.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /* mbed Microcontroller Library
sahilmgandhi 18:6a4db94011d3 2 * Copyright (c) 2006-2015 ARM Limited
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * Licensed under the Apache License, Version 2.0 (the "License");
sahilmgandhi 18:6a4db94011d3 5 * you may not use this file except in compliance with the License.
sahilmgandhi 18:6a4db94011d3 6 * You may obtain a copy of the License at
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * http://www.apache.org/licenses/LICENSE-2.0
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * Unless required by applicable law or agreed to in writing, software
sahilmgandhi 18:6a4db94011d3 11 * distributed under the License is distributed on an "AS IS" BASIS,
sahilmgandhi 18:6a4db94011d3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sahilmgandhi 18:6a4db94011d3 13 * See the License for the specific language governing permissions and
sahilmgandhi 18:6a4db94011d3 14 * limitations under the License.
sahilmgandhi 18:6a4db94011d3 15 */
sahilmgandhi 18:6a4db94011d3 16 #include <stddef.h>
sahilmgandhi 18:6a4db94011d3 17 #include "cmsis.h"
sahilmgandhi 18:6a4db94011d3 18
sahilmgandhi 18:6a4db94011d3 19 #include "gpio_irq_api.h"
sahilmgandhi 18:6a4db94011d3 20 #include "mbed_error.h"
sahilmgandhi 18:6a4db94011d3 21
sahilmgandhi 18:6a4db94011d3 22 #define CHANNEL_NUM 160
sahilmgandhi 18:6a4db94011d3 23
sahilmgandhi 18:6a4db94011d3 24 static uint32_t channel_ids[CHANNEL_NUM] = {0};
sahilmgandhi 18:6a4db94011d3 25 static gpio_irq_handler irq_handler;
sahilmgandhi 18:6a4db94011d3 26
sahilmgandhi 18:6a4db94011d3 27 #define IRQ_DISABLED (0)
sahilmgandhi 18:6a4db94011d3 28 #define IRQ_RAISING_EDGE PORT_PCR_IRQC(9)
sahilmgandhi 18:6a4db94011d3 29 #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10)
sahilmgandhi 18:6a4db94011d3 30 #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11)
sahilmgandhi 18:6a4db94011d3 31
sahilmgandhi 18:6a4db94011d3 32 static void handle_interrupt_in(PORT_Type *port, int ch_base) {
sahilmgandhi 18:6a4db94011d3 33 uint32_t isfr;
sahilmgandhi 18:6a4db94011d3 34 uint32_t pin;
sahilmgandhi 18:6a4db94011d3 35
sahilmgandhi 18:6a4db94011d3 36 while ((isfr = port->ISFR) != 0) {
sahilmgandhi 18:6a4db94011d3 37 pin = 31 - __CLZ(isfr);
sahilmgandhi 18:6a4db94011d3 38 uint32_t id = channel_ids[ch_base + pin];
sahilmgandhi 18:6a4db94011d3 39 if (id == 0) {
sahilmgandhi 18:6a4db94011d3 40 continue;
sahilmgandhi 18:6a4db94011d3 41 }
sahilmgandhi 18:6a4db94011d3 42
sahilmgandhi 18:6a4db94011d3 43 GPIO_Type *gpio = PTA;
sahilmgandhi 18:6a4db94011d3 44 gpio_irq_event event = IRQ_NONE;
sahilmgandhi 18:6a4db94011d3 45 uint32_t port_num = (port - PORTA) >> 12;
sahilmgandhi 18:6a4db94011d3 46
sahilmgandhi 18:6a4db94011d3 47 switch (port->PCR[pin] & PORT_PCR_IRQC_MASK) {
sahilmgandhi 18:6a4db94011d3 48 case IRQ_RAISING_EDGE:
sahilmgandhi 18:6a4db94011d3 49 event = IRQ_RISE;
sahilmgandhi 18:6a4db94011d3 50 break;
sahilmgandhi 18:6a4db94011d3 51 case IRQ_FALLING_EDGE:
sahilmgandhi 18:6a4db94011d3 52 event = IRQ_FALL;
sahilmgandhi 18:6a4db94011d3 53 break;
sahilmgandhi 18:6a4db94011d3 54 case IRQ_EITHER_EDGE:
sahilmgandhi 18:6a4db94011d3 55 gpio += (port_num * 0x40);
sahilmgandhi 18:6a4db94011d3 56 event = (gpio->PDIR & (1 << pin)) ? (IRQ_RISE) : (IRQ_FALL);
sahilmgandhi 18:6a4db94011d3 57 break;
sahilmgandhi 18:6a4db94011d3 58 }
sahilmgandhi 18:6a4db94011d3 59 if (event != IRQ_NONE) {
sahilmgandhi 18:6a4db94011d3 60 irq_handler(id, event);
sahilmgandhi 18:6a4db94011d3 61 }
sahilmgandhi 18:6a4db94011d3 62 port->ISFR = 1 << pin;
sahilmgandhi 18:6a4db94011d3 63 }
sahilmgandhi 18:6a4db94011d3 64 }
sahilmgandhi 18:6a4db94011d3 65
sahilmgandhi 18:6a4db94011d3 66 void gpio_irqA(void) {
sahilmgandhi 18:6a4db94011d3 67 handle_interrupt_in(PORTA, 0);
sahilmgandhi 18:6a4db94011d3 68 }
sahilmgandhi 18:6a4db94011d3 69
sahilmgandhi 18:6a4db94011d3 70 void gpio_irqB(void)
sahilmgandhi 18:6a4db94011d3 71 {
sahilmgandhi 18:6a4db94011d3 72 handle_interrupt_in(PORTB, 32);
sahilmgandhi 18:6a4db94011d3 73 }
sahilmgandhi 18:6a4db94011d3 74
sahilmgandhi 18:6a4db94011d3 75 void gpio_irqC(void)
sahilmgandhi 18:6a4db94011d3 76 {
sahilmgandhi 18:6a4db94011d3 77 handle_interrupt_in(PORTC, 64);
sahilmgandhi 18:6a4db94011d3 78 }
sahilmgandhi 18:6a4db94011d3 79
sahilmgandhi 18:6a4db94011d3 80 void gpio_irqD(void)
sahilmgandhi 18:6a4db94011d3 81 {
sahilmgandhi 18:6a4db94011d3 82 handle_interrupt_in(PORTD, 96);
sahilmgandhi 18:6a4db94011d3 83 }
sahilmgandhi 18:6a4db94011d3 84
sahilmgandhi 18:6a4db94011d3 85 void gpio_irqE(void)
sahilmgandhi 18:6a4db94011d3 86 {
sahilmgandhi 18:6a4db94011d3 87 handle_interrupt_in(PORTE, 128);
sahilmgandhi 18:6a4db94011d3 88 }
sahilmgandhi 18:6a4db94011d3 89
sahilmgandhi 18:6a4db94011d3 90
sahilmgandhi 18:6a4db94011d3 91 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
sahilmgandhi 18:6a4db94011d3 92 if (pin == NC)
sahilmgandhi 18:6a4db94011d3 93 return -1;
sahilmgandhi 18:6a4db94011d3 94
sahilmgandhi 18:6a4db94011d3 95 irq_handler = handler;
sahilmgandhi 18:6a4db94011d3 96
sahilmgandhi 18:6a4db94011d3 97 obj->port = pin >> PORT_SHIFT;
sahilmgandhi 18:6a4db94011d3 98 obj->pin = (pin & 0x7F) >> 2;
sahilmgandhi 18:6a4db94011d3 99
sahilmgandhi 18:6a4db94011d3 100 uint32_t ch_base, vector;
sahilmgandhi 18:6a4db94011d3 101 IRQn_Type irq_n;
sahilmgandhi 18:6a4db94011d3 102 switch (obj->port) {
sahilmgandhi 18:6a4db94011d3 103 case PortA:
sahilmgandhi 18:6a4db94011d3 104 ch_base = 0;
sahilmgandhi 18:6a4db94011d3 105 irq_n = PORTA_IRQn;
sahilmgandhi 18:6a4db94011d3 106 vector = (uint32_t)gpio_irqA;
sahilmgandhi 18:6a4db94011d3 107 break;
sahilmgandhi 18:6a4db94011d3 108 case PortB:
sahilmgandhi 18:6a4db94011d3 109 ch_base = 32;
sahilmgandhi 18:6a4db94011d3 110 irq_n = PORTB_IRQn;
sahilmgandhi 18:6a4db94011d3 111 vector = (uint32_t)gpio_irqB;
sahilmgandhi 18:6a4db94011d3 112 break;
sahilmgandhi 18:6a4db94011d3 113 case PortC:
sahilmgandhi 18:6a4db94011d3 114 ch_base = 64;
sahilmgandhi 18:6a4db94011d3 115 irq_n = PORTC_IRQn;
sahilmgandhi 18:6a4db94011d3 116 vector = (uint32_t)gpio_irqC;
sahilmgandhi 18:6a4db94011d3 117 break;
sahilmgandhi 18:6a4db94011d3 118 case PortD:
sahilmgandhi 18:6a4db94011d3 119 ch_base = 96;
sahilmgandhi 18:6a4db94011d3 120 irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD;
sahilmgandhi 18:6a4db94011d3 121 break;
sahilmgandhi 18:6a4db94011d3 122 case PortE:
sahilmgandhi 18:6a4db94011d3 123 ch_base = 128;
sahilmgandhi 18:6a4db94011d3 124 irq_n = PORTE_IRQn;
sahilmgandhi 18:6a4db94011d3 125 vector = (uint32_t)gpio_irqE;
sahilmgandhi 18:6a4db94011d3 126 break;
sahilmgandhi 18:6a4db94011d3 127
sahilmgandhi 18:6a4db94011d3 128 default:
sahilmgandhi 18:6a4db94011d3 129 error("gpio_irq only supported on port A-E.");
sahilmgandhi 18:6a4db94011d3 130 break;
sahilmgandhi 18:6a4db94011d3 131 }
sahilmgandhi 18:6a4db94011d3 132 NVIC_SetVector(irq_n, vector);
sahilmgandhi 18:6a4db94011d3 133 NVIC_EnableIRQ(irq_n);
sahilmgandhi 18:6a4db94011d3 134
sahilmgandhi 18:6a4db94011d3 135 obj->ch = ch_base + obj->pin;
sahilmgandhi 18:6a4db94011d3 136 channel_ids[obj->ch] = id;
sahilmgandhi 18:6a4db94011d3 137
sahilmgandhi 18:6a4db94011d3 138 return 0;
sahilmgandhi 18:6a4db94011d3 139 }
sahilmgandhi 18:6a4db94011d3 140
sahilmgandhi 18:6a4db94011d3 141 void gpio_irq_free(gpio_irq_t *obj) {
sahilmgandhi 18:6a4db94011d3 142 channel_ids[obj->ch] = 0;
sahilmgandhi 18:6a4db94011d3 143 }
sahilmgandhi 18:6a4db94011d3 144
sahilmgandhi 18:6a4db94011d3 145 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
sahilmgandhi 18:6a4db94011d3 146 PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port);
sahilmgandhi 18:6a4db94011d3 147
sahilmgandhi 18:6a4db94011d3 148 uint32_t irq_settings = IRQ_DISABLED;
sahilmgandhi 18:6a4db94011d3 149
sahilmgandhi 18:6a4db94011d3 150 switch (port->PCR[obj->pin] & PORT_PCR_IRQC_MASK) {
sahilmgandhi 18:6a4db94011d3 151 case IRQ_DISABLED:
sahilmgandhi 18:6a4db94011d3 152 if (enable)
sahilmgandhi 18:6a4db94011d3 153 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_FALLING_EDGE);
sahilmgandhi 18:6a4db94011d3 154 break;
sahilmgandhi 18:6a4db94011d3 155
sahilmgandhi 18:6a4db94011d3 156 case IRQ_RAISING_EDGE:
sahilmgandhi 18:6a4db94011d3 157 if (enable) {
sahilmgandhi 18:6a4db94011d3 158 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_EITHER_EDGE);
sahilmgandhi 18:6a4db94011d3 159 } else {
sahilmgandhi 18:6a4db94011d3 160 if (event == IRQ_FALL)
sahilmgandhi 18:6a4db94011d3 161 irq_settings = IRQ_RAISING_EDGE;
sahilmgandhi 18:6a4db94011d3 162 }
sahilmgandhi 18:6a4db94011d3 163 break;
sahilmgandhi 18:6a4db94011d3 164
sahilmgandhi 18:6a4db94011d3 165 case IRQ_FALLING_EDGE:
sahilmgandhi 18:6a4db94011d3 166 if (enable) {
sahilmgandhi 18:6a4db94011d3 167 irq_settings = (event == IRQ_FALL) ? (IRQ_FALLING_EDGE) : (IRQ_EITHER_EDGE);
sahilmgandhi 18:6a4db94011d3 168 } else {
sahilmgandhi 18:6a4db94011d3 169 if (event == IRQ_RISE)
sahilmgandhi 18:6a4db94011d3 170 irq_settings = IRQ_FALLING_EDGE;
sahilmgandhi 18:6a4db94011d3 171 }
sahilmgandhi 18:6a4db94011d3 172 break;
sahilmgandhi 18:6a4db94011d3 173
sahilmgandhi 18:6a4db94011d3 174 case IRQ_EITHER_EDGE:
sahilmgandhi 18:6a4db94011d3 175 if (enable) {
sahilmgandhi 18:6a4db94011d3 176 irq_settings = IRQ_EITHER_EDGE;
sahilmgandhi 18:6a4db94011d3 177 } else {
sahilmgandhi 18:6a4db94011d3 178 irq_settings = (event == IRQ_RISE) ? (IRQ_FALLING_EDGE) : (IRQ_RAISING_EDGE);
sahilmgandhi 18:6a4db94011d3 179 }
sahilmgandhi 18:6a4db94011d3 180 break;
sahilmgandhi 18:6a4db94011d3 181 }
sahilmgandhi 18:6a4db94011d3 182
sahilmgandhi 18:6a4db94011d3 183 // Interrupt configuration and clear interrupt
sahilmgandhi 18:6a4db94011d3 184 port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
sahilmgandhi 18:6a4db94011d3 185 }
sahilmgandhi 18:6a4db94011d3 186
sahilmgandhi 18:6a4db94011d3 187 void gpio_irq_enable(gpio_irq_t *obj) {
sahilmgandhi 18:6a4db94011d3 188 switch (obj->port) {
sahilmgandhi 18:6a4db94011d3 189 case PortA:
sahilmgandhi 18:6a4db94011d3 190 NVIC_EnableIRQ(PORTA_IRQn);
sahilmgandhi 18:6a4db94011d3 191 break;
sahilmgandhi 18:6a4db94011d3 192 case PortB:
sahilmgandhi 18:6a4db94011d3 193 NVIC_EnableIRQ(PORTB_IRQn);
sahilmgandhi 18:6a4db94011d3 194 break;
sahilmgandhi 18:6a4db94011d3 195 case PortC:
sahilmgandhi 18:6a4db94011d3 196 NVIC_EnableIRQ(PORTC_IRQn);
sahilmgandhi 18:6a4db94011d3 197 break;
sahilmgandhi 18:6a4db94011d3 198 case PortD:
sahilmgandhi 18:6a4db94011d3 199 NVIC_EnableIRQ(PORTD_IRQn);
sahilmgandhi 18:6a4db94011d3 200 break;
sahilmgandhi 18:6a4db94011d3 201 case PortE:
sahilmgandhi 18:6a4db94011d3 202 NVIC_EnableIRQ(PORTE_IRQn);
sahilmgandhi 18:6a4db94011d3 203 break;
sahilmgandhi 18:6a4db94011d3 204 }
sahilmgandhi 18:6a4db94011d3 205 }
sahilmgandhi 18:6a4db94011d3 206
sahilmgandhi 18:6a4db94011d3 207 void gpio_irq_disable(gpio_irq_t *obj) {
sahilmgandhi 18:6a4db94011d3 208 switch (obj->port) {
sahilmgandhi 18:6a4db94011d3 209 case PortA:
sahilmgandhi 18:6a4db94011d3 210 NVIC_DisableIRQ(PORTA_IRQn);
sahilmgandhi 18:6a4db94011d3 211 break;
sahilmgandhi 18:6a4db94011d3 212 case PortB:
sahilmgandhi 18:6a4db94011d3 213 NVIC_DisableIRQ(PORTB_IRQn);
sahilmgandhi 18:6a4db94011d3 214 break;
sahilmgandhi 18:6a4db94011d3 215 case PortC:
sahilmgandhi 18:6a4db94011d3 216 NVIC_DisableIRQ(PORTC_IRQn);
sahilmgandhi 18:6a4db94011d3 217 break;
sahilmgandhi 18:6a4db94011d3 218 case PortD:
sahilmgandhi 18:6a4db94011d3 219 NVIC_DisableIRQ(PORTD_IRQn);
sahilmgandhi 18:6a4db94011d3 220 break;
sahilmgandhi 18:6a4db94011d3 221 case PortE:
sahilmgandhi 18:6a4db94011d3 222 NVIC_DisableIRQ(PORTE_IRQn);
sahilmgandhi 18:6a4db94011d3 223 break;
sahilmgandhi 18:6a4db94011d3 224 }
sahilmgandhi 18:6a4db94011d3 225 }