mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
bogdanm
Date:
Mon Aug 05 14:12:34 2013 +0300
Revision:
13:0645d8841f51
Parent:
vendor/Freescale/KL25Z/hal/gpio_irq_api.c@10:3bc89ef62ce7
Child:
35:371630885ad6
Update mbed sources to revision 64

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 10:3bc89ef62ce7 1 /* mbed Microcontroller Library
emilmont 10:3bc89ef62ce7 2 * Copyright (c) 2006-2013 ARM Limited
emilmont 10:3bc89ef62ce7 3 *
emilmont 10:3bc89ef62ce7 4 * Licensed under the Apache License, Version 2.0 (the "License");
emilmont 10:3bc89ef62ce7 5 * you may not use this file except in compliance with the License.
emilmont 10:3bc89ef62ce7 6 * You may obtain a copy of the License at
emilmont 10:3bc89ef62ce7 7 *
emilmont 10:3bc89ef62ce7 8 * http://www.apache.org/licenses/LICENSE-2.0
emilmont 10:3bc89ef62ce7 9 *
emilmont 10:3bc89ef62ce7 10 * Unless required by applicable law or agreed to in writing, software
emilmont 10:3bc89ef62ce7 11 * distributed under the License is distributed on an "AS IS" BASIS,
emilmont 10:3bc89ef62ce7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
emilmont 10:3bc89ef62ce7 13 * See the License for the specific language governing permissions and
emilmont 10:3bc89ef62ce7 14 * limitations under the License.
emilmont 10:3bc89ef62ce7 15 */
emilmont 10:3bc89ef62ce7 16 #include <stddef.h>
emilmont 10:3bc89ef62ce7 17 #include "cmsis.h"
emilmont 10:3bc89ef62ce7 18
emilmont 10:3bc89ef62ce7 19 #include "gpio_irq_api.h"
emilmont 10:3bc89ef62ce7 20 #include "error.h"
emilmont 10:3bc89ef62ce7 21
emilmont 10:3bc89ef62ce7 22 #define CHANNEL_NUM 64
emilmont 10:3bc89ef62ce7 23
emilmont 10:3bc89ef62ce7 24 static uint32_t channel_ids[CHANNEL_NUM] = {0};
emilmont 10:3bc89ef62ce7 25 static gpio_irq_handler irq_handler;
emilmont 10:3bc89ef62ce7 26
emilmont 10:3bc89ef62ce7 27 #define IRQ_DISABLED (0)
emilmont 10:3bc89ef62ce7 28 #define IRQ_RAISING_EDGE PORT_PCR_IRQC(9)
emilmont 10:3bc89ef62ce7 29 #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10)
emilmont 10:3bc89ef62ce7 30 #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11)
emilmont 10:3bc89ef62ce7 31
emilmont 10:3bc89ef62ce7 32 static void handle_interrupt_in(PORT_Type *port, int ch_base) {
emilmont 10:3bc89ef62ce7 33 uint32_t mask = 0, i;
emilmont 10:3bc89ef62ce7 34
emilmont 10:3bc89ef62ce7 35 for (i = 0; i < 32; i++) {
emilmont 10:3bc89ef62ce7 36 uint32_t pmask = (1 << i);
emilmont 10:3bc89ef62ce7 37 if (port->ISFR & pmask) {
emilmont 10:3bc89ef62ce7 38 mask |= pmask;
emilmont 10:3bc89ef62ce7 39 uint32_t id = channel_ids[ch_base + i];
emilmont 10:3bc89ef62ce7 40 if (id == 0) continue;
emilmont 10:3bc89ef62ce7 41
emilmont 10:3bc89ef62ce7 42 FGPIO_Type *gpio;
emilmont 10:3bc89ef62ce7 43 gpio_irq_event event = IRQ_NONE;
emilmont 10:3bc89ef62ce7 44 switch (port->PCR[i] & PORT_PCR_IRQC_MASK) {
emilmont 10:3bc89ef62ce7 45 case IRQ_RAISING_EDGE:
emilmont 10:3bc89ef62ce7 46 event = IRQ_RISE;
emilmont 10:3bc89ef62ce7 47 break;
emilmont 10:3bc89ef62ce7 48
emilmont 10:3bc89ef62ce7 49 case IRQ_FALLING_EDGE:
emilmont 10:3bc89ef62ce7 50 event = IRQ_FALL;
emilmont 10:3bc89ef62ce7 51 break;
emilmont 10:3bc89ef62ce7 52
emilmont 10:3bc89ef62ce7 53 case IRQ_EITHER_EDGE:
emilmont 10:3bc89ef62ce7 54 gpio = (port == PORTA) ? (FPTA) : (FPTD);
emilmont 10:3bc89ef62ce7 55 event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL);
emilmont 10:3bc89ef62ce7 56 break;
emilmont 10:3bc89ef62ce7 57 }
emilmont 10:3bc89ef62ce7 58 if (event != IRQ_NONE)
emilmont 10:3bc89ef62ce7 59 irq_handler(id, event);
emilmont 10:3bc89ef62ce7 60 }
emilmont 10:3bc89ef62ce7 61 }
emilmont 10:3bc89ef62ce7 62 port->ISFR = mask;
emilmont 10:3bc89ef62ce7 63 }
emilmont 10:3bc89ef62ce7 64
emilmont 10:3bc89ef62ce7 65 void gpio_irqA(void) {handle_interrupt_in(PORTA, 0);}
emilmont 10:3bc89ef62ce7 66 void gpio_irqD(void) {handle_interrupt_in(PORTD, 32);}
emilmont 10:3bc89ef62ce7 67
emilmont 10:3bc89ef62ce7 68 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
emilmont 10:3bc89ef62ce7 69 if (pin == NC) return -1;
emilmont 10:3bc89ef62ce7 70
emilmont 10:3bc89ef62ce7 71 irq_handler = handler;
emilmont 10:3bc89ef62ce7 72
emilmont 10:3bc89ef62ce7 73 obj->port = pin >> PORT_SHIFT;
emilmont 10:3bc89ef62ce7 74 obj->pin = (pin & 0x7F) >> 2;
emilmont 10:3bc89ef62ce7 75
emilmont 10:3bc89ef62ce7 76 uint32_t ch_base, vector;
emilmont 10:3bc89ef62ce7 77 IRQn_Type irq_n;
emilmont 10:3bc89ef62ce7 78 switch (obj->port) {
emilmont 10:3bc89ef62ce7 79 case PortA:
emilmont 10:3bc89ef62ce7 80 ch_base = 0; irq_n = PORTA_IRQn; vector = (uint32_t)gpio_irqA;
emilmont 10:3bc89ef62ce7 81 break;
emilmont 10:3bc89ef62ce7 82
emilmont 10:3bc89ef62ce7 83 case PortD:
emilmont 10:3bc89ef62ce7 84 ch_base = 32; irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD;
emilmont 10:3bc89ef62ce7 85 break;
emilmont 10:3bc89ef62ce7 86
emilmont 10:3bc89ef62ce7 87 default:
emilmont 10:3bc89ef62ce7 88 error("gpio_irq only supported on port A and D\n");
emilmont 10:3bc89ef62ce7 89 break;
emilmont 10:3bc89ef62ce7 90 }
emilmont 10:3bc89ef62ce7 91 NVIC_SetVector(irq_n, vector);
emilmont 10:3bc89ef62ce7 92 NVIC_EnableIRQ(irq_n);
emilmont 10:3bc89ef62ce7 93
emilmont 10:3bc89ef62ce7 94 obj->ch = ch_base + obj->pin;
emilmont 10:3bc89ef62ce7 95 channel_ids[obj->ch] = id;
emilmont 10:3bc89ef62ce7 96
emilmont 10:3bc89ef62ce7 97 return 0;
emilmont 10:3bc89ef62ce7 98 }
emilmont 10:3bc89ef62ce7 99
emilmont 10:3bc89ef62ce7 100 void gpio_irq_free(gpio_irq_t *obj) {
emilmont 10:3bc89ef62ce7 101 channel_ids[obj->ch] = 0;
emilmont 10:3bc89ef62ce7 102 }
emilmont 10:3bc89ef62ce7 103
emilmont 10:3bc89ef62ce7 104 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
emilmont 10:3bc89ef62ce7 105 PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port);
emilmont 10:3bc89ef62ce7 106
emilmont 10:3bc89ef62ce7 107 uint32_t irq_settings = IRQ_DISABLED;
emilmont 10:3bc89ef62ce7 108
emilmont 10:3bc89ef62ce7 109 switch (port->PCR[obj->pin] & PORT_PCR_IRQC_MASK) {
emilmont 10:3bc89ef62ce7 110 case IRQ_DISABLED:
emilmont 10:3bc89ef62ce7 111 if (enable) {
emilmont 10:3bc89ef62ce7 112 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_FALLING_EDGE);
emilmont 10:3bc89ef62ce7 113 }
emilmont 10:3bc89ef62ce7 114 break;
emilmont 10:3bc89ef62ce7 115
emilmont 10:3bc89ef62ce7 116 case IRQ_RAISING_EDGE:
emilmont 10:3bc89ef62ce7 117 if (enable) {
emilmont 10:3bc89ef62ce7 118 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_EITHER_EDGE);
emilmont 10:3bc89ef62ce7 119 } else {
emilmont 10:3bc89ef62ce7 120 if (event == IRQ_FALL)
emilmont 10:3bc89ef62ce7 121 irq_settings = IRQ_RAISING_EDGE;
emilmont 10:3bc89ef62ce7 122 }
emilmont 10:3bc89ef62ce7 123 break;
emilmont 10:3bc89ef62ce7 124
emilmont 10:3bc89ef62ce7 125 case IRQ_FALLING_EDGE:
emilmont 10:3bc89ef62ce7 126 if (enable) {
emilmont 10:3bc89ef62ce7 127 irq_settings = (event == IRQ_FALL) ? (IRQ_FALLING_EDGE) : (IRQ_EITHER_EDGE);
emilmont 10:3bc89ef62ce7 128 } else {
emilmont 10:3bc89ef62ce7 129 if (event == IRQ_RISE)
emilmont 10:3bc89ef62ce7 130 irq_settings = IRQ_FALLING_EDGE;
emilmont 10:3bc89ef62ce7 131 }
emilmont 10:3bc89ef62ce7 132 break;
emilmont 10:3bc89ef62ce7 133
emilmont 10:3bc89ef62ce7 134 case IRQ_EITHER_EDGE:
emilmont 10:3bc89ef62ce7 135 if (enable) {
emilmont 10:3bc89ef62ce7 136 irq_settings = IRQ_EITHER_EDGE;
emilmont 10:3bc89ef62ce7 137 } else {
emilmont 10:3bc89ef62ce7 138 irq_settings = (event == IRQ_RISE) ? (IRQ_FALLING_EDGE) : (IRQ_RAISING_EDGE);
emilmont 10:3bc89ef62ce7 139 }
emilmont 10:3bc89ef62ce7 140 break;
emilmont 10:3bc89ef62ce7 141 }
emilmont 10:3bc89ef62ce7 142
emilmont 10:3bc89ef62ce7 143 // Interrupt configuration and clear interrupt
emilmont 10:3bc89ef62ce7 144 port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
emilmont 10:3bc89ef62ce7 145 }