fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088
Fork of mbed-src by
gpio_irq_api.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include <stddef.h> 00017 00018 #include "gpio_irq_api.h" 00019 #include "error.h" 00020 #include "cmsis.h" 00021 00022 #define CHANNEL_NUM 48 00023 00024 static uint32_t channel_ids[CHANNEL_NUM] = {0}; 00025 static gpio_irq_handler irq_handler; 00026 00027 static void handle_interrupt_in(void) { 00028 // Read in all current interrupt registers. We do this once as the 00029 // GPIO interrupt registers are on the APB bus, and this is slow. 00030 uint32_t rise0 = LPC_GPIOINT->IO0IntStatR; 00031 uint32_t fall0 = LPC_GPIOINT->IO0IntStatF; 00032 uint32_t rise2 = LPC_GPIOINT->IO2IntStatR; 00033 uint32_t fall2 = LPC_GPIOINT->IO2IntStatF; 00034 uint32_t mask0 = 0; 00035 uint32_t mask2 = 0; 00036 int i; 00037 00038 // P0.0-0.31 00039 for (i = 0; i < 32; i++) { 00040 uint32_t pmask = (1 << i); 00041 if (rise0 & pmask) { 00042 mask0 |= pmask; 00043 if (channel_ids[i] != 0) 00044 irq_handler(channel_ids[i], IRQ_RISE); 00045 } 00046 if (fall0 & pmask) { 00047 mask0 |= pmask; 00048 if (channel_ids[i] != 0) 00049 irq_handler(channel_ids[i], IRQ_FALL); 00050 } 00051 } 00052 00053 // P2.0-2.15 00054 for (i = 0; i < 16; i++) { 00055 uint32_t pmask = (1 << i); 00056 int channel_index = i + 32; 00057 if (rise2 & pmask) { 00058 mask2 |= pmask; 00059 if (channel_ids[channel_index] != 0) 00060 irq_handler(channel_ids[channel_index], IRQ_RISE); 00061 } 00062 if (fall2 & pmask) { 00063 mask2 |= pmask; 00064 if (channel_ids[channel_index] != 0) 00065 irq_handler(channel_ids[channel_index], IRQ_FALL); 00066 } 00067 } 00068 00069 // Clear the interrupts we just handled 00070 LPC_GPIOINT->IO0IntClr = mask0; 00071 LPC_GPIOINT->IO2IntClr = mask2; 00072 } 00073 00074 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { 00075 if (pin == NC) return -1; 00076 00077 irq_handler = handler; 00078 00079 obj->port = (int)pin & ~0x1F; 00080 obj->pin = (int)pin & 0x1F; 00081 00082 // Interrupts available only on GPIO0 and GPIO2 00083 if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) { 00084 error("pins on this port cannot generate interrupts\n"); 00085 } 00086 00087 // put us in the interrupt table 00088 int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32; 00089 channel_ids[index] = id; 00090 obj->ch = index; 00091 00092 NVIC_SetVector(EINT3_IRQn , (uint32_t)handle_interrupt_in); 00093 NVIC_EnableIRQ(EINT3_IRQn ); 00094 return 0; 00095 } 00096 00097 void gpio_irq_free(gpio_irq_t *obj) { 00098 channel_ids[obj->ch] = 0; 00099 } 00100 00101 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { 00102 // ensure nothing is pending 00103 switch (obj->port) { 00104 case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break; 00105 case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break; 00106 } 00107 00108 // enable the pin interrupt 00109 if (event == IRQ_RISE) { 00110 switch (obj->port) { 00111 case LPC_GPIO0_BASE: 00112 if (enable) { 00113 LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin; 00114 } else { 00115 LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin); 00116 } 00117 break; 00118 case LPC_GPIO2_BASE: 00119 if (enable) { 00120 LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin; 00121 } else { 00122 LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin); 00123 } 00124 break; 00125 } 00126 } else { 00127 switch (obj->port) { 00128 case LPC_GPIO0_BASE: 00129 if (enable) { 00130 LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin; 00131 } else { 00132 LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin); 00133 } 00134 break; 00135 case LPC_GPIO2_BASE: 00136 if (enable) { 00137 LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin; 00138 } else { 00139 LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin); 00140 } 00141 break; 00142 } 00143 } 00144 }
Generated on Tue Jul 12 2022 13:47:01 by
![doxygen](doxygen.png)