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:
mbed_official
Date:
Tue Dec 16 08:15:08 2014 +0000
Revision:
440:8a0b45cd594f
Parent:
285:31249416b6f9
Synchronized with git revision 67fbbf0b635d0c0d93fbe433306c537c2ad206aa

Full URL: https://github.com/mbedmicro/mbed/commit/67fbbf0b635d0c0d93fbe433306c537c2ad206aa/

Targets: nrf51 - updating app_timer.c from Norid'c SDKv7.1.0

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
emilmont 10:3bc89ef62ce7 18 #include "gpio_irq_api.h"
mbed_official 285:31249416b6f9 19 #include "mbed_error.h"
emilmont 10:3bc89ef62ce7 20 #include "cmsis.h"
emilmont 10:3bc89ef62ce7 21
emilmont 10:3bc89ef62ce7 22 #define CHANNEL_NUM 48
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 static void handle_interrupt_in(void) {
emilmont 10:3bc89ef62ce7 28 // Read in all current interrupt registers. We do this once as the
emilmont 10:3bc89ef62ce7 29 // GPIO interrupt registers are on the APB bus, and this is slow.
emilmont 10:3bc89ef62ce7 30 uint32_t rise0 = LPC_GPIOINT->IO0IntStatR;
emilmont 10:3bc89ef62ce7 31 uint32_t fall0 = LPC_GPIOINT->IO0IntStatF;
emilmont 10:3bc89ef62ce7 32 uint32_t rise2 = LPC_GPIOINT->IO2IntStatR;
emilmont 10:3bc89ef62ce7 33 uint32_t fall2 = LPC_GPIOINT->IO2IntStatF;
bogdanm 21:67d3158c7b56 34 uint8_t bitloc;
bogdanm 21:67d3158c7b56 35
bogdanm 21:67d3158c7b56 36 while(rise0 > 0) { //Continue as long as there are interrupts pending
bogdanm 21:67d3158c7b56 37 bitloc = 31 - __CLZ(rise0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
bogdanm 21:67d3158c7b56 38 if (channel_ids[bitloc] != 0)
bogdanm 21:67d3158c7b56 39 irq_handler(channel_ids[bitloc], IRQ_RISE); //Run that interrupt
bogdanm 21:67d3158c7b56 40
bogdanm 21:67d3158c7b56 41 //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
bogdanm 21:67d3158c7b56 42 LPC_GPIOINT->IO0IntClr = 1 << bitloc;
bogdanm 21:67d3158c7b56 43 rise0 -= 1<<bitloc;
bogdanm 21:67d3158c7b56 44 }
bogdanm 21:67d3158c7b56 45
bogdanm 21:67d3158c7b56 46 while(fall0 > 0) { //Continue as long as there are interrupts pending
bogdanm 21:67d3158c7b56 47 bitloc = 31 - __CLZ(fall0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
bogdanm 21:67d3158c7b56 48 if (channel_ids[bitloc] != 0)
bogdanm 21:67d3158c7b56 49 irq_handler(channel_ids[bitloc], IRQ_FALL); //Run that interrupt
bogdanm 21:67d3158c7b56 50
bogdanm 21:67d3158c7b56 51 //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
bogdanm 21:67d3158c7b56 52 LPC_GPIOINT->IO0IntClr = 1 << bitloc;
bogdanm 21:67d3158c7b56 53 fall0 -= 1<<bitloc;
emilmont 10:3bc89ef62ce7 54 }
emilmont 10:3bc89ef62ce7 55
bogdanm 21:67d3158c7b56 56 //Same for port 2, only we need to watch the channel_index
bogdanm 21:67d3158c7b56 57 while(rise2 > 0) { //Continue as long as there are interrupts pending
bogdanm 21:67d3158c7b56 58 bitloc = 31 - __CLZ(rise2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
bogdanm 21:67d3158c7b56 59
bogdanm 21:67d3158c7b56 60 if (bitloc < 16) //Not sure if this is actually needed
bogdanm 21:67d3158c7b56 61 if (channel_ids[bitloc+32] != 0)
bogdanm 21:67d3158c7b56 62 irq_handler(channel_ids[bitloc+32], IRQ_RISE); //Run that interrupt
bogdanm 21:67d3158c7b56 63
bogdanm 21:67d3158c7b56 64 //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
bogdanm 21:67d3158c7b56 65 LPC_GPIOINT->IO2IntClr = 1 << bitloc;
bogdanm 21:67d3158c7b56 66 rise2 -= 1<<bitloc;
emilmont 10:3bc89ef62ce7 67 }
bogdanm 21:67d3158c7b56 68
bogdanm 21:67d3158c7b56 69 while(fall2 > 0) { //Continue as long as there are interrupts pending
bogdanm 21:67d3158c7b56 70 bitloc = 31 - __CLZ(fall2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
bogdanm 21:67d3158c7b56 71
bogdanm 21:67d3158c7b56 72 if (bitloc < 16) //Not sure if this is actually needed
bogdanm 21:67d3158c7b56 73 if (channel_ids[bitloc+32] != 0)
bogdanm 21:67d3158c7b56 74 irq_handler(channel_ids[bitloc+32], IRQ_FALL); //Run that interrupt
bogdanm 21:67d3158c7b56 75
bogdanm 21:67d3158c7b56 76 //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
bogdanm 21:67d3158c7b56 77 LPC_GPIOINT->IO2IntClr = 1 << bitloc;
bogdanm 21:67d3158c7b56 78 fall2 -= 1<<bitloc;
bogdanm 21:67d3158c7b56 79 }
emilmont 10:3bc89ef62ce7 80 }
emilmont 10:3bc89ef62ce7 81
emilmont 10:3bc89ef62ce7 82 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
emilmont 10:3bc89ef62ce7 83 if (pin == NC) return -1;
emilmont 10:3bc89ef62ce7 84
emilmont 10:3bc89ef62ce7 85 irq_handler = handler;
emilmont 10:3bc89ef62ce7 86
emilmont 10:3bc89ef62ce7 87 obj->port = (int)pin & ~0x1F;
emilmont 10:3bc89ef62ce7 88 obj->pin = (int)pin & 0x1F;
emilmont 10:3bc89ef62ce7 89
emilmont 10:3bc89ef62ce7 90 // Interrupts available only on GPIO0 and GPIO2
emilmont 10:3bc89ef62ce7 91 if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) {
mbed_official 158:3121b9889f7b 92 error("pins on this port cannot generate interrupts");
emilmont 10:3bc89ef62ce7 93 }
emilmont 10:3bc89ef62ce7 94
emilmont 10:3bc89ef62ce7 95 // put us in the interrupt table
emilmont 10:3bc89ef62ce7 96 int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32;
emilmont 10:3bc89ef62ce7 97 channel_ids[index] = id;
emilmont 10:3bc89ef62ce7 98 obj->ch = index;
emilmont 10:3bc89ef62ce7 99
emilmont 10:3bc89ef62ce7 100 NVIC_SetVector(EINT3_IRQn, (uint32_t)handle_interrupt_in);
emilmont 10:3bc89ef62ce7 101 NVIC_EnableIRQ(EINT3_IRQn);
emilmont 10:3bc89ef62ce7 102 return 0;
emilmont 10:3bc89ef62ce7 103 }
emilmont 10:3bc89ef62ce7 104
emilmont 10:3bc89ef62ce7 105 void gpio_irq_free(gpio_irq_t *obj) {
emilmont 10:3bc89ef62ce7 106 channel_ids[obj->ch] = 0;
emilmont 10:3bc89ef62ce7 107 }
emilmont 10:3bc89ef62ce7 108
emilmont 10:3bc89ef62ce7 109 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
emilmont 10:3bc89ef62ce7 110 // ensure nothing is pending
emilmont 10:3bc89ef62ce7 111 switch (obj->port) {
emilmont 10:3bc89ef62ce7 112 case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break;
emilmont 10:3bc89ef62ce7 113 case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break;
emilmont 10:3bc89ef62ce7 114 }
emilmont 10:3bc89ef62ce7 115
emilmont 10:3bc89ef62ce7 116 // enable the pin interrupt
emilmont 10:3bc89ef62ce7 117 if (event == IRQ_RISE) {
emilmont 10:3bc89ef62ce7 118 switch (obj->port) {
emilmont 10:3bc89ef62ce7 119 case LPC_GPIO0_BASE:
emilmont 10:3bc89ef62ce7 120 if (enable) {
emilmont 10:3bc89ef62ce7 121 LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin;
emilmont 10:3bc89ef62ce7 122 } else {
emilmont 10:3bc89ef62ce7 123 LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin);
emilmont 10:3bc89ef62ce7 124 }
emilmont 10:3bc89ef62ce7 125 break;
emilmont 10:3bc89ef62ce7 126 case LPC_GPIO2_BASE:
emilmont 10:3bc89ef62ce7 127 if (enable) {
emilmont 10:3bc89ef62ce7 128 LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin;
emilmont 10:3bc89ef62ce7 129 } else {
emilmont 10:3bc89ef62ce7 130 LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin);
emilmont 10:3bc89ef62ce7 131 }
emilmont 10:3bc89ef62ce7 132 break;
emilmont 10:3bc89ef62ce7 133 }
emilmont 10:3bc89ef62ce7 134 } else {
emilmont 10:3bc89ef62ce7 135 switch (obj->port) {
emilmont 10:3bc89ef62ce7 136 case LPC_GPIO0_BASE:
emilmont 10:3bc89ef62ce7 137 if (enable) {
emilmont 10:3bc89ef62ce7 138 LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin;
emilmont 10:3bc89ef62ce7 139 } else {
emilmont 10:3bc89ef62ce7 140 LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin);
emilmont 10:3bc89ef62ce7 141 }
emilmont 10:3bc89ef62ce7 142 break;
emilmont 10:3bc89ef62ce7 143 case LPC_GPIO2_BASE:
emilmont 10:3bc89ef62ce7 144 if (enable) {
emilmont 10:3bc89ef62ce7 145 LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin;
emilmont 10:3bc89ef62ce7 146 } else {
emilmont 10:3bc89ef62ce7 147 LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin);
emilmont 10:3bc89ef62ce7 148 }
emilmont 10:3bc89ef62ce7 149 break;
emilmont 10:3bc89ef62ce7 150 }
emilmont 10:3bc89ef62ce7 151 }
emilmont 10:3bc89ef62ce7 152 }
mbed_official 35:371630885ad6 153
mbed_official 35:371630885ad6 154 void gpio_irq_enable(gpio_irq_t *obj) {
mbed_official 35:371630885ad6 155 NVIC_EnableIRQ(EINT3_IRQn);
mbed_official 35:371630885ad6 156 }
mbed_official 35:371630885ad6 157
mbed_official 35:371630885ad6 158 void gpio_irq_disable(gpio_irq_t *obj) {
mbed_official 35:371630885ad6 159 NVIC_DisableIRQ(EINT3_IRQn);
mbed_official 35:371630885ad6 160 }
mbed_official 35:371630885ad6 161