mbed SDK library sources

Fork of mbed-src by mbed official

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:
mbed_official
Date:
Tue Feb 11 15:00:06 2014 +0000
Revision:
89:9655231f5786
Parent:
35:371630885ad6
Synchronized with git revision 17499c34d273f02497e0706d3abc516b12f3fc62

Full URL: https://github.com/mbedmicro/mbed/commit/17499c34d273f02497e0706d3abc516b12f3fc62/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 30:91c1d09ada54 1 /* mbed Microcontroller Library
mbed_official 30:91c1d09ada54 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 30:91c1d09ada54 3 *
mbed_official 30:91c1d09ada54 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 30:91c1d09ada54 5 * you may not use this file except in compliance with the License.
mbed_official 30:91c1d09ada54 6 * You may obtain a copy of the License at
mbed_official 30:91c1d09ada54 7 *
mbed_official 30:91c1d09ada54 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 30:91c1d09ada54 9 *
mbed_official 30:91c1d09ada54 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 30:91c1d09ada54 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 30:91c1d09ada54 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 30:91c1d09ada54 13 * See the License for the specific language governing permissions and
mbed_official 30:91c1d09ada54 14 * limitations under the License.
mbed_official 30:91c1d09ada54 15 */
mbed_official 30:91c1d09ada54 16 #include <stddef.h>
mbed_official 30:91c1d09ada54 17 #include "cmsis.h"
mbed_official 30:91c1d09ada54 18 #include "gpio_irq_api.h"
mbed_official 30:91c1d09ada54 19 #include "error.h"
mbed_official 30:91c1d09ada54 20 #include "gpio_api.h"
mbed_official 30:91c1d09ada54 21
mbed_official 30:91c1d09ada54 22 // The chip is capable of 42 GPIO interrupts.
mbed_official 30:91c1d09ada54 23 // PIO0_0..PIO0_11, PIO1_0..PIO1_11, PIO2_0..PIO2_11, PIO3_0..PIO3_5
mbed_official 30:91c1d09ada54 24 #define CHANNEL_NUM 42
mbed_official 30:91c1d09ada54 25
mbed_official 30:91c1d09ada54 26 static uint32_t channel_ids[CHANNEL_NUM] = {0};
mbed_official 30:91c1d09ada54 27 static gpio_irq_handler irq_handler;
mbed_official 30:91c1d09ada54 28
mbed_official 30:91c1d09ada54 29 static inline int numofbits(uint32_t bits)
mbed_official 30:91c1d09ada54 30 {
mbed_official 30:91c1d09ada54 31 // Count number of bits
mbed_official 30:91c1d09ada54 32 bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
mbed_official 30:91c1d09ada54 33 bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
mbed_official 30:91c1d09ada54 34 bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
mbed_official 30:91c1d09ada54 35 bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
mbed_official 30:91c1d09ada54 36 return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);
mbed_official 30:91c1d09ada54 37 }
mbed_official 30:91c1d09ada54 38
mbed_official 30:91c1d09ada54 39 static inline void handle_interrupt_in(uint32_t port) {
mbed_official 30:91c1d09ada54 40 // Find out whether the interrupt has been triggered by a high or low value...
mbed_official 30:91c1d09ada54 41 // As the LPC1114 doesn't have a specific register for this, we'll just have to read
mbed_official 30:91c1d09ada54 42 // the level of the pin as if it were just a normal input...
mbed_official 30:91c1d09ada54 43
mbed_official 30:91c1d09ada54 44 uint32_t channel;
mbed_official 30:91c1d09ada54 45
mbed_official 30:91c1d09ada54 46 // Get the number of the pin being used and the port typedef
mbed_official 30:91c1d09ada54 47 LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (port * 0x10000)));
mbed_official 30:91c1d09ada54 48
mbed_official 30:91c1d09ada54 49 // Get index of function table from Mask Interrupt Status register
mbed_official 30:91c1d09ada54 50 channel = numofbits(port_reg->MIS - 1);
mbed_official 30:91c1d09ada54 51
mbed_official 30:91c1d09ada54 52 if (port_reg->MIS & port_reg->IBE) {
mbed_official 30:91c1d09ada54 53 // both edge, read the level of pin
mbed_official 30:91c1d09ada54 54 if ((port_reg->DATA & port_reg->MIS) != 0)
mbed_official 30:91c1d09ada54 55 irq_handler(channel_ids[channel], IRQ_RISE);
mbed_official 30:91c1d09ada54 56 else
mbed_official 30:91c1d09ada54 57 irq_handler(channel_ids[channel], IRQ_FALL);
mbed_official 30:91c1d09ada54 58 }
mbed_official 30:91c1d09ada54 59 else if (port_reg->MIS & port_reg->IEV) {
mbed_official 30:91c1d09ada54 60 irq_handler(channel_ids[channel], IRQ_RISE);
mbed_official 30:91c1d09ada54 61 }
mbed_official 30:91c1d09ada54 62 else {
mbed_official 30:91c1d09ada54 63 irq_handler(channel_ids[channel], IRQ_FALL);
mbed_official 30:91c1d09ada54 64 }
mbed_official 30:91c1d09ada54 65
mbed_official 30:91c1d09ada54 66 // Clear the interrupt...
mbed_official 30:91c1d09ada54 67 port_reg->IC = port_reg->MIS;
mbed_official 30:91c1d09ada54 68 }
mbed_official 30:91c1d09ada54 69
mbed_official 30:91c1d09ada54 70 void gpio_irq0(void) {handle_interrupt_in(0);}
mbed_official 30:91c1d09ada54 71 void gpio_irq1(void) {handle_interrupt_in(1);}
mbed_official 30:91c1d09ada54 72 void gpio_irq2(void) {handle_interrupt_in(2);}
mbed_official 30:91c1d09ada54 73 void gpio_irq3(void) {handle_interrupt_in(3);}
mbed_official 30:91c1d09ada54 74
mbed_official 30:91c1d09ada54 75 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
mbed_official 30:91c1d09ada54 76 int channel;
mbed_official 30:91c1d09ada54 77 uint32_t port_num;
mbed_official 30:91c1d09ada54 78
mbed_official 30:91c1d09ada54 79 if (pin == NC) return -1;
mbed_official 30:91c1d09ada54 80
mbed_official 30:91c1d09ada54 81 // Firstly, we'll put some data in *obj so we can keep track of stuff.
mbed_official 30:91c1d09ada54 82 obj->pin = pin;
mbed_official 30:91c1d09ada54 83
mbed_official 30:91c1d09ada54 84 // Set the handler to be the pointer at the top...
mbed_official 30:91c1d09ada54 85 irq_handler = handler;
mbed_official 30:91c1d09ada54 86
mbed_official 30:91c1d09ada54 87 // Which port are we using?
mbed_official 30:91c1d09ada54 88 port_num = ((pin & 0xF000) >> PORT_SHIFT);
mbed_official 30:91c1d09ada54 89
mbed_official 30:91c1d09ada54 90 switch (port_num) {
mbed_official 30:91c1d09ada54 91 case 0:
mbed_official 30:91c1d09ada54 92 NVIC_SetVector(EINT0_IRQn, (uint32_t)gpio_irq0);
mbed_official 30:91c1d09ada54 93 NVIC_EnableIRQ(EINT0_IRQn);
mbed_official 30:91c1d09ada54 94 break;
mbed_official 30:91c1d09ada54 95 case 1:
mbed_official 30:91c1d09ada54 96 NVIC_SetVector(EINT1_IRQn, (uint32_t)gpio_irq1);
mbed_official 30:91c1d09ada54 97 NVIC_EnableIRQ(EINT1_IRQn);
mbed_official 30:91c1d09ada54 98 break;
mbed_official 30:91c1d09ada54 99 case 2:
mbed_official 30:91c1d09ada54 100 NVIC_SetVector(EINT2_IRQn, (uint32_t)gpio_irq2);
mbed_official 30:91c1d09ada54 101 NVIC_EnableIRQ(EINT2_IRQn);
mbed_official 30:91c1d09ada54 102 break;
mbed_official 30:91c1d09ada54 103 case 3:
mbed_official 30:91c1d09ada54 104 NVIC_SetVector(EINT3_IRQn, (uint32_t)gpio_irq3);
mbed_official 30:91c1d09ada54 105 NVIC_EnableIRQ(EINT3_IRQn);
mbed_official 30:91c1d09ada54 106 break;
mbed_official 30:91c1d09ada54 107 default:
mbed_official 30:91c1d09ada54 108 return -1;
mbed_official 30:91c1d09ada54 109 }
mbed_official 30:91c1d09ada54 110
mbed_official 30:91c1d09ada54 111 // Generate index of function pointer table
mbed_official 30:91c1d09ada54 112 // PIO0_0 - PIO0_11 : 0..11
mbed_official 30:91c1d09ada54 113 // PIO1_0 - PIO1_11 : 12..23
mbed_official 30:91c1d09ada54 114 // PIO2_0 - PIO2_11 : 24..35
mbed_official 30:91c1d09ada54 115 // PIO3_0 - PIO3_5 : 36..41
mbed_official 30:91c1d09ada54 116 channel = (port_num * 12) + ((pin & 0x0F00) >> PIN_SHIFT);
mbed_official 30:91c1d09ada54 117
mbed_official 30:91c1d09ada54 118 channel_ids[channel] = id;
mbed_official 30:91c1d09ada54 119 obj->ch = channel;
mbed_official 30:91c1d09ada54 120
mbed_official 30:91c1d09ada54 121 return 0;
mbed_official 30:91c1d09ada54 122 }
mbed_official 30:91c1d09ada54 123
mbed_official 30:91c1d09ada54 124 void gpio_irq_free(gpio_irq_t *obj) {
mbed_official 30:91c1d09ada54 125 channel_ids[obj->ch] = 0;
mbed_official 30:91c1d09ada54 126 }
mbed_official 30:91c1d09ada54 127
mbed_official 30:91c1d09ada54 128 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
mbed_official 30:91c1d09ada54 129 // Firstly, check if there is an existing event stored...
mbed_official 30:91c1d09ada54 130
mbed_official 30:91c1d09ada54 131 LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (((obj->pin & 0xF000) >> PORT_SHIFT) * 0x10000)));
mbed_official 30:91c1d09ada54 132
mbed_official 30:91c1d09ada54 133 // Need to get the pin number of the pin, not the value of the enum
mbed_official 30:91c1d09ada54 134 uint32_t pin_num = (1 << ((obj->pin & 0x0f00) >> PIN_SHIFT));
mbed_official 30:91c1d09ada54 135
mbed_official 30:91c1d09ada54 136 // Clear
mbed_official 30:91c1d09ada54 137 port_reg->IC |= pin_num;
mbed_official 30:91c1d09ada54 138
mbed_official 30:91c1d09ada54 139 // Make it edge sensitive.
mbed_official 30:91c1d09ada54 140 port_reg->IS &= ~pin_num;
mbed_official 30:91c1d09ada54 141
mbed_official 30:91c1d09ada54 142 if ( (port_reg->IE & pin_num) != 0) {
mbed_official 30:91c1d09ada54 143 // We have an event.
mbed_official 30:91c1d09ada54 144 // Enable both edge interrupts.
mbed_official 30:91c1d09ada54 145
mbed_official 30:91c1d09ada54 146 if (enable) {
mbed_official 30:91c1d09ada54 147 port_reg->IBE |= pin_num;
mbed_official 30:91c1d09ada54 148 port_reg->IE |= pin_num;
mbed_official 30:91c1d09ada54 149 }
mbed_official 30:91c1d09ada54 150 else {
mbed_official 30:91c1d09ada54 151 // These all need to be opposite, to reenable the other one.
mbed_official 30:91c1d09ada54 152 port_reg->IBE &= ~pin_num;
mbed_official 30:91c1d09ada54 153
mbed_official 30:91c1d09ada54 154 if (event == IRQ_RISE)
mbed_official 30:91c1d09ada54 155 port_reg->IEV &= ~pin_num;
mbed_official 30:91c1d09ada54 156 else
mbed_official 30:91c1d09ada54 157 port_reg->IEV |= pin_num;
mbed_official 30:91c1d09ada54 158
mbed_official 30:91c1d09ada54 159 port_reg->IE |= pin_num;
mbed_official 30:91c1d09ada54 160 }
mbed_official 30:91c1d09ada54 161 }
mbed_official 30:91c1d09ada54 162 else {
mbed_official 30:91c1d09ada54 163 // One edge
mbed_official 30:91c1d09ada54 164 port_reg->IBE &= ~pin_num;
mbed_official 30:91c1d09ada54 165 // Rising/falling?
mbed_official 30:91c1d09ada54 166 if (event == IRQ_RISE)
mbed_official 30:91c1d09ada54 167 port_reg->IEV |= pin_num;
mbed_official 30:91c1d09ada54 168 else
mbed_official 30:91c1d09ada54 169 port_reg->IEV &= ~pin_num;
mbed_official 30:91c1d09ada54 170
mbed_official 30:91c1d09ada54 171 if (enable) {
mbed_official 30:91c1d09ada54 172 port_reg->IE |= pin_num;
mbed_official 30:91c1d09ada54 173 }
mbed_official 30:91c1d09ada54 174 }
mbed_official 30:91c1d09ada54 175
mbed_official 30:91c1d09ada54 176 }
mbed_official 35:371630885ad6 177
mbed_official 35:371630885ad6 178 void gpio_irq_enable(gpio_irq_t *obj) {
mbed_official 35:371630885ad6 179 uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT);
mbed_official 35:371630885ad6 180 switch (port_num) {
mbed_official 35:371630885ad6 181 case 0:
mbed_official 35:371630885ad6 182 NVIC_EnableIRQ(EINT0_IRQn);
mbed_official 35:371630885ad6 183 break;
mbed_official 35:371630885ad6 184 case 1:
mbed_official 35:371630885ad6 185 NVIC_EnableIRQ(EINT1_IRQn);
mbed_official 35:371630885ad6 186 break;
mbed_official 35:371630885ad6 187 case 2:
mbed_official 35:371630885ad6 188 NVIC_EnableIRQ(EINT2_IRQn);
mbed_official 35:371630885ad6 189 break;
mbed_official 35:371630885ad6 190 case 3:
mbed_official 35:371630885ad6 191 NVIC_EnableIRQ(EINT3_IRQn);
mbed_official 35:371630885ad6 192 break;
mbed_official 35:371630885ad6 193 default:
mbed_official 35:371630885ad6 194 break;
mbed_official 35:371630885ad6 195 }
mbed_official 35:371630885ad6 196 }
mbed_official 35:371630885ad6 197
mbed_official 35:371630885ad6 198 void gpio_irq_disable(gpio_irq_t *obj) {
mbed_official 35:371630885ad6 199 uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT);
mbed_official 35:371630885ad6 200 switch (port_num) {
mbed_official 35:371630885ad6 201 case 0:
mbed_official 35:371630885ad6 202 NVIC_DisableIRQ(EINT0_IRQn);
mbed_official 35:371630885ad6 203 break;
mbed_official 35:371630885ad6 204 case 1:
mbed_official 35:371630885ad6 205 NVIC_DisableIRQ(EINT1_IRQn);
mbed_official 35:371630885ad6 206 break;
mbed_official 35:371630885ad6 207 case 2:
mbed_official 35:371630885ad6 208 NVIC_DisableIRQ(EINT2_IRQn);
mbed_official 35:371630885ad6 209 break;
mbed_official 35:371630885ad6 210 case 3:
mbed_official 35:371630885ad6 211 NVIC_DisableIRQ(EINT3_IRQn);
mbed_official 35:371630885ad6 212 break;
mbed_official 35:371630885ad6 213 default:
mbed_official 35:371630885ad6 214 break;
mbed_official 35:371630885ad6 215 }
mbed_official 35:371630885ad6 216 }