Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 "cmsis.h" 00019 #include "gpio_irq_api.h" 00020 #include "error.h" 00021 00022 #define CHANNEL_NUM 8 00023 #define LPC_GPIO_X LPC_PIN_INT 00024 #define PININT_IRQ PININT0_IRQn 00025 00026 static uint32_t channel_ids[CHANNEL_NUM] = {0}; 00027 static gpio_irq_handler irq_handler; 00028 00029 static inline void handle_interrupt_in(uint32_t channel) { 00030 uint32_t ch_bit = (1 << channel); 00031 // Return immediately if: 00032 // * The interrupt was already served 00033 // * There is no user handler 00034 // * It is a level interrupt, not an edge interrupt 00035 if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || 00036 (channel_ids[channel] == 0 ) || 00037 (LPC_GPIO_X->ISEL & ch_bit ) ) return; 00038 00039 if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { 00040 irq_handler(channel_ids[channel], IRQ_RISE); 00041 LPC_GPIO_X->RISE = ch_bit; 00042 } 00043 if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { 00044 irq_handler(channel_ids[channel], IRQ_FALL); 00045 } 00046 LPC_GPIO_X->IST = ch_bit; 00047 } 00048 00049 void gpio_irq0(void) {handle_interrupt_in(0);} 00050 void gpio_irq1(void) {handle_interrupt_in(1);} 00051 void gpio_irq2(void) {handle_interrupt_in(2);} 00052 void gpio_irq3(void) {handle_interrupt_in(3);} 00053 void gpio_irq4(void) {handle_interrupt_in(4);} 00054 void gpio_irq5(void) {handle_interrupt_in(5);} 00055 void gpio_irq6(void) {handle_interrupt_in(6);} 00056 void gpio_irq7(void) {handle_interrupt_in(7);} 00057 00058 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { 00059 if (pin == NC) return -1; 00060 00061 irq_handler = handler; 00062 00063 int found_free_channel = 0; 00064 int i = 0; 00065 for (i=0; i<CHANNEL_NUM; i++) { 00066 if (channel_ids[i] == 0) { 00067 channel_ids[i] = id; 00068 obj->ch = i; 00069 found_free_channel = 1; 00070 break; 00071 } 00072 } 00073 if (!found_free_channel) return -1; 00074 00075 /* Enable AHB clock to the GPIO domain. */ 00076 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); 00077 00078 LPC_SYSCON->PINTSEL[obj->ch] = pin; 00079 00080 // Interrupt Wake-Up Enable 00081 LPC_SYSCON->STARTERP0 |= 1 << obj->ch; 00082 00083 void (*channels_irq)(void) = NULL; 00084 switch (obj->ch) { 00085 case 0: channels_irq = &gpio_irq0; break; 00086 case 1: channels_irq = &gpio_irq1; break; 00087 case 2: channels_irq = &gpio_irq2; break; 00088 case 3: channels_irq = &gpio_irq3; break; 00089 case 4: channels_irq = &gpio_irq4; break; 00090 case 5: channels_irq = &gpio_irq5; break; 00091 case 6: channels_irq = &gpio_irq6; break; 00092 case 7: channels_irq = &gpio_irq7; break; 00093 } 00094 NVIC_SetVector((IRQn_Type )(PININT_IRQ + obj->ch), (uint32_t)channels_irq); 00095 NVIC_EnableIRQ((IRQn_Type )(PININT_IRQ + obj->ch)); 00096 00097 return 0; 00098 } 00099 00100 void gpio_irq_free(gpio_irq_t *obj) { 00101 channel_ids[obj->ch] = 0; 00102 LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); 00103 } 00104 00105 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { 00106 unsigned int ch_bit = (1 << obj->ch); 00107 00108 // Clear interrupt 00109 if (!(LPC_GPIO_X->ISEL & ch_bit)) 00110 LPC_GPIO_X->IST = ch_bit; 00111 00112 // Edge trigger 00113 LPC_GPIO_X->ISEL &= ~ch_bit; 00114 if (event == IRQ_RISE) { 00115 if (enable) { 00116 LPC_GPIO_X->IENR |= ch_bit; 00117 } else { 00118 LPC_GPIO_X->IENR &= ~ch_bit; 00119 } 00120 } else { 00121 if (enable) { 00122 LPC_GPIO_X->IENF |= ch_bit; 00123 } else { 00124 LPC_GPIO_X->IENF &= ~ch_bit; 00125 } 00126 } 00127 }
Generated on Tue Jul 12 2022 13:47:01 by
1.7.2
