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 OmniWheels by
mbed-os/targets/TARGET_NUVOTON/TARGET_M480/gpio_irq_api.c@2:798925c9e4a8, 2018-05-01 (annotated)
- Committer:
- gustavatmel
- Date:
- Tue May 01 15:55:34 2018 +0000
- Revision:
- 2:798925c9e4a8
- Parent:
- 1:9c5af431a1f1
bluetooth
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gustavatmel | 1:9c5af431a1f1 | 1 | /* mbed Microcontroller Library |
gustavatmel | 1:9c5af431a1f1 | 2 | * Copyright (c) 2015-2016 Nuvoton |
gustavatmel | 1:9c5af431a1f1 | 3 | * |
gustavatmel | 1:9c5af431a1f1 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
gustavatmel | 1:9c5af431a1f1 | 5 | * you may not use this file except in compliance with the License. |
gustavatmel | 1:9c5af431a1f1 | 6 | * You may obtain a copy of the License at |
gustavatmel | 1:9c5af431a1f1 | 7 | * |
gustavatmel | 1:9c5af431a1f1 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
gustavatmel | 1:9c5af431a1f1 | 9 | * |
gustavatmel | 1:9c5af431a1f1 | 10 | * Unless required by applicable law or agreed to in writing, software |
gustavatmel | 1:9c5af431a1f1 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
gustavatmel | 1:9c5af431a1f1 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
gustavatmel | 1:9c5af431a1f1 | 13 | * See the License for the specific language governing permissions and |
gustavatmel | 1:9c5af431a1f1 | 14 | * limitations under the License. |
gustavatmel | 1:9c5af431a1f1 | 15 | */ |
gustavatmel | 1:9c5af431a1f1 | 16 | |
gustavatmel | 1:9c5af431a1f1 | 17 | #include "gpio_irq_api.h" |
gustavatmel | 1:9c5af431a1f1 | 18 | |
gustavatmel | 1:9c5af431a1f1 | 19 | #if DEVICE_INTERRUPTIN |
gustavatmel | 1:9c5af431a1f1 | 20 | |
gustavatmel | 1:9c5af431a1f1 | 21 | #include "gpio_api.h" |
gustavatmel | 1:9c5af431a1f1 | 22 | #include "cmsis.h" |
gustavatmel | 1:9c5af431a1f1 | 23 | #include "pinmap.h" |
gustavatmel | 1:9c5af431a1f1 | 24 | #include "PeripheralPins.h" |
gustavatmel | 1:9c5af431a1f1 | 25 | #include "nu_bitutil.h" |
gustavatmel | 1:9c5af431a1f1 | 26 | |
gustavatmel | 1:9c5af431a1f1 | 27 | #define NU_MAX_PIN_PER_PORT 16 |
gustavatmel | 1:9c5af431a1f1 | 28 | |
gustavatmel | 1:9c5af431a1f1 | 29 | struct nu_gpio_irq_var { |
gustavatmel | 1:9c5af431a1f1 | 30 | gpio_irq_t * obj_arr[NU_MAX_PIN_PER_PORT]; |
gustavatmel | 1:9c5af431a1f1 | 31 | IRQn_Type irq_n; |
gustavatmel | 1:9c5af431a1f1 | 32 | void (*vec)(void); |
gustavatmel | 1:9c5af431a1f1 | 33 | uint32_t port_index; |
gustavatmel | 1:9c5af431a1f1 | 34 | }; |
gustavatmel | 1:9c5af431a1f1 | 35 | |
gustavatmel | 1:9c5af431a1f1 | 36 | static void gpio_irq_0_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 37 | static void gpio_irq_1_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 38 | static void gpio_irq_2_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 39 | static void gpio_irq_3_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 40 | static void gpio_irq_4_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 41 | static void gpio_irq_5_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 42 | static void gpio_irq_6_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 43 | static void gpio_irq_7_vec(void); |
gustavatmel | 1:9c5af431a1f1 | 44 | static void gpio_irq(struct nu_gpio_irq_var *var); |
gustavatmel | 1:9c5af431a1f1 | 45 | |
gustavatmel | 1:9c5af431a1f1 | 46 | //EINT0_IRQn |
gustavatmel | 1:9c5af431a1f1 | 47 | static struct nu_gpio_irq_var gpio_irq_var_arr[] = { |
gustavatmel | 1:9c5af431a1f1 | 48 | {{NULL}, GPA_IRQn, gpio_irq_0_vec, 0}, |
gustavatmel | 1:9c5af431a1f1 | 49 | {{NULL}, GPB_IRQn, gpio_irq_1_vec, 1}, |
gustavatmel | 1:9c5af431a1f1 | 50 | {{NULL}, GPC_IRQn, gpio_irq_2_vec, 2}, |
gustavatmel | 1:9c5af431a1f1 | 51 | {{NULL}, GPD_IRQn, gpio_irq_3_vec, 3}, |
gustavatmel | 1:9c5af431a1f1 | 52 | {{NULL}, GPE_IRQn, gpio_irq_4_vec, 4}, |
gustavatmel | 1:9c5af431a1f1 | 53 | {{NULL}, GPF_IRQn, gpio_irq_5_vec, 5}, |
gustavatmel | 1:9c5af431a1f1 | 54 | {{NULL}, GPG_IRQn, gpio_irq_6_vec, 6}, |
gustavatmel | 1:9c5af431a1f1 | 55 | {{NULL}, GPH_IRQn, gpio_irq_7_vec, 7}, |
gustavatmel | 1:9c5af431a1f1 | 56 | }; |
gustavatmel | 1:9c5af431a1f1 | 57 | |
gustavatmel | 1:9c5af431a1f1 | 58 | #define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0])) |
gustavatmel | 1:9c5af431a1f1 | 59 | |
gustavatmel | 1:9c5af431a1f1 | 60 | #ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE |
gustavatmel | 1:9c5af431a1f1 | 61 | #define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE 0 |
gustavatmel | 1:9c5af431a1f1 | 62 | #endif |
gustavatmel | 1:9c5af431a1f1 | 63 | |
gustavatmel | 1:9c5af431a1f1 | 64 | #ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST |
gustavatmel | 1:9c5af431a1f1 | 65 | #define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC |
gustavatmel | 1:9c5af431a1f1 | 66 | #endif |
gustavatmel | 1:9c5af431a1f1 | 67 | static PinName gpio_irq_debounce_arr[] = { |
gustavatmel | 1:9c5af431a1f1 | 68 | MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST |
gustavatmel | 1:9c5af431a1f1 | 69 | }; |
gustavatmel | 1:9c5af431a1f1 | 70 | |
gustavatmel | 1:9c5af431a1f1 | 71 | #ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE |
gustavatmel | 1:9c5af431a1f1 | 72 | #define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC |
gustavatmel | 1:9c5af431a1f1 | 73 | #endif |
gustavatmel | 1:9c5af431a1f1 | 74 | |
gustavatmel | 1:9c5af431a1f1 | 75 | #ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE |
gustavatmel | 1:9c5af431a1f1 | 76 | #define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 |
gustavatmel | 1:9c5af431a1f1 | 77 | #endif |
gustavatmel | 1:9c5af431a1f1 | 78 | |
gustavatmel | 1:9c5af431a1f1 | 79 | int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) |
gustavatmel | 1:9c5af431a1f1 | 80 | { |
gustavatmel | 1:9c5af431a1f1 | 81 | if (pin == NC) { |
gustavatmel | 1:9c5af431a1f1 | 82 | return -1; |
gustavatmel | 1:9c5af431a1f1 | 83 | } |
gustavatmel | 1:9c5af431a1f1 | 84 | |
gustavatmel | 1:9c5af431a1f1 | 85 | uint32_t pin_index = NU_PINNAME_TO_PIN(pin); |
gustavatmel | 1:9c5af431a1f1 | 86 | uint32_t port_index = NU_PINNAME_TO_PORT(pin); |
gustavatmel | 1:9c5af431a1f1 | 87 | if (pin_index >= NU_MAX_PIN_PER_PORT || port_index >= NU_MAX_PORT) { |
gustavatmel | 1:9c5af431a1f1 | 88 | return -1; |
gustavatmel | 1:9c5af431a1f1 | 89 | } |
gustavatmel | 1:9c5af431a1f1 | 90 | |
gustavatmel | 1:9c5af431a1f1 | 91 | obj->pin = pin; |
gustavatmel | 1:9c5af431a1f1 | 92 | obj->irq_handler = (uint32_t) handler; |
gustavatmel | 1:9c5af431a1f1 | 93 | obj->irq_id = id; |
gustavatmel | 1:9c5af431a1f1 | 94 | |
gustavatmel | 1:9c5af431a1f1 | 95 | GPIO_T *gpio_base = NU_PORT_BASE(port_index); |
gustavatmel | 1:9c5af431a1f1 | 96 | // NOTE: In InterruptIn constructor, gpio_irq_init() is called with gpio_init_in() which is responsible for multi-function pin setting. |
gustavatmel | 1:9c5af431a1f1 | 97 | // There is no need to call gpio_set() redundantly. |
gustavatmel | 1:9c5af431a1f1 | 98 | |
gustavatmel | 1:9c5af431a1f1 | 99 | { |
gustavatmel | 1:9c5af431a1f1 | 100 | #if MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE |
gustavatmel | 1:9c5af431a1f1 | 101 | // Suppress compiler warning |
gustavatmel | 1:9c5af431a1f1 | 102 | (void) gpio_irq_debounce_arr; |
gustavatmel | 1:9c5af431a1f1 | 103 | |
gustavatmel | 1:9c5af431a1f1 | 104 | // Configure de-bounce clock source and sampling cycle time |
gustavatmel | 1:9c5af431a1f1 | 105 | GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); |
gustavatmel | 1:9c5af431a1f1 | 106 | GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 107 | #else |
gustavatmel | 1:9c5af431a1f1 | 108 | // Enable de-bounce if the pin is in the de-bounce enable list |
gustavatmel | 1:9c5af431a1f1 | 109 | |
gustavatmel | 1:9c5af431a1f1 | 110 | // De-bounce defaults to disabled. |
gustavatmel | 1:9c5af431a1f1 | 111 | GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 112 | |
gustavatmel | 1:9c5af431a1f1 | 113 | PinName *debounce_pos = gpio_irq_debounce_arr; |
gustavatmel | 1:9c5af431a1f1 | 114 | PinName *debounce_end = gpio_irq_debounce_arr + sizeof (gpio_irq_debounce_arr) / sizeof (gpio_irq_debounce_arr[0]); |
gustavatmel | 1:9c5af431a1f1 | 115 | for (; debounce_pos != debounce_end && *debounce_pos != NC; debounce_pos ++) { |
gustavatmel | 1:9c5af431a1f1 | 116 | uint32_t pin_index_debunce = NU_PINNAME_TO_PIN(*debounce_pos); |
gustavatmel | 1:9c5af431a1f1 | 117 | uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos); |
gustavatmel | 1:9c5af431a1f1 | 118 | |
gustavatmel | 1:9c5af431a1f1 | 119 | if (pin_index == pin_index_debunce && |
gustavatmel | 1:9c5af431a1f1 | 120 | port_index == port_index_debounce) { |
gustavatmel | 1:9c5af431a1f1 | 121 | // Configure de-bounce clock source and sampling cycle time |
gustavatmel | 1:9c5af431a1f1 | 122 | GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); |
gustavatmel | 1:9c5af431a1f1 | 123 | GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 124 | break; |
gustavatmel | 1:9c5af431a1f1 | 125 | } |
gustavatmel | 1:9c5af431a1f1 | 126 | } |
gustavatmel | 1:9c5af431a1f1 | 127 | #endif |
gustavatmel | 1:9c5af431a1f1 | 128 | } |
gustavatmel | 1:9c5af431a1f1 | 129 | |
gustavatmel | 1:9c5af431a1f1 | 130 | struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; |
gustavatmel | 1:9c5af431a1f1 | 131 | |
gustavatmel | 1:9c5af431a1f1 | 132 | var->obj_arr[pin_index] = obj; |
gustavatmel | 1:9c5af431a1f1 | 133 | |
gustavatmel | 1:9c5af431a1f1 | 134 | // NOTE: InterruptIn requires IRQ enabled by default. |
gustavatmel | 1:9c5af431a1f1 | 135 | gpio_irq_enable(obj); |
gustavatmel | 1:9c5af431a1f1 | 136 | |
gustavatmel | 1:9c5af431a1f1 | 137 | return 0; |
gustavatmel | 1:9c5af431a1f1 | 138 | } |
gustavatmel | 1:9c5af431a1f1 | 139 | |
gustavatmel | 1:9c5af431a1f1 | 140 | void gpio_irq_free(gpio_irq_t *obj) |
gustavatmel | 1:9c5af431a1f1 | 141 | { |
gustavatmel | 1:9c5af431a1f1 | 142 | uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 143 | uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 144 | struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; |
gustavatmel | 1:9c5af431a1f1 | 145 | |
gustavatmel | 1:9c5af431a1f1 | 146 | NVIC_DisableIRQ(var->irq_n); |
gustavatmel | 1:9c5af431a1f1 | 147 | NU_PORT_BASE(port_index)->INTEN = 0; |
gustavatmel | 1:9c5af431a1f1 | 148 | |
gustavatmel | 1:9c5af431a1f1 | 149 | MBED_ASSERT(pin_index < NU_MAX_PIN_PER_PORT); |
gustavatmel | 1:9c5af431a1f1 | 150 | var->obj_arr[pin_index] = NULL; |
gustavatmel | 1:9c5af431a1f1 | 151 | } |
gustavatmel | 1:9c5af431a1f1 | 152 | |
gustavatmel | 1:9c5af431a1f1 | 153 | void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) |
gustavatmel | 1:9c5af431a1f1 | 154 | { |
gustavatmel | 1:9c5af431a1f1 | 155 | uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 156 | uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 157 | GPIO_T *gpio_base = NU_PORT_BASE(port_index); |
gustavatmel | 1:9c5af431a1f1 | 158 | |
gustavatmel | 1:9c5af431a1f1 | 159 | switch (event) { |
gustavatmel | 1:9c5af431a1f1 | 160 | case IRQ_RISE: |
gustavatmel | 1:9c5af431a1f1 | 161 | if (enable) { |
gustavatmel | 1:9c5af431a1f1 | 162 | GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING); |
gustavatmel | 1:9c5af431a1f1 | 163 | } else { |
gustavatmel | 1:9c5af431a1f1 | 164 | gpio_base->INTEN &= ~(GPIO_INT_RISING << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 165 | } |
gustavatmel | 1:9c5af431a1f1 | 166 | break; |
gustavatmel | 1:9c5af431a1f1 | 167 | |
gustavatmel | 1:9c5af431a1f1 | 168 | case IRQ_FALL: |
gustavatmel | 1:9c5af431a1f1 | 169 | if (enable) { |
gustavatmel | 1:9c5af431a1f1 | 170 | GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING); |
gustavatmel | 1:9c5af431a1f1 | 171 | } else { |
gustavatmel | 1:9c5af431a1f1 | 172 | gpio_base->INTEN &= ~(GPIO_INT_FALLING << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 173 | } |
gustavatmel | 1:9c5af431a1f1 | 174 | break; |
gustavatmel | 1:9c5af431a1f1 | 175 | |
gustavatmel | 1:9c5af431a1f1 | 176 | case IRQ_NONE: |
gustavatmel | 1:9c5af431a1f1 | 177 | default: |
gustavatmel | 1:9c5af431a1f1 | 178 | break; |
gustavatmel | 1:9c5af431a1f1 | 179 | } |
gustavatmel | 1:9c5af431a1f1 | 180 | } |
gustavatmel | 1:9c5af431a1f1 | 181 | |
gustavatmel | 1:9c5af431a1f1 | 182 | void gpio_irq_enable(gpio_irq_t *obj) |
gustavatmel | 1:9c5af431a1f1 | 183 | { |
gustavatmel | 1:9c5af431a1f1 | 184 | uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 185 | struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; |
gustavatmel | 1:9c5af431a1f1 | 186 | |
gustavatmel | 1:9c5af431a1f1 | 187 | NVIC_SetVector(var->irq_n, (uint32_t) var->vec); |
gustavatmel | 1:9c5af431a1f1 | 188 | NVIC_EnableIRQ(var->irq_n); |
gustavatmel | 1:9c5af431a1f1 | 189 | } |
gustavatmel | 1:9c5af431a1f1 | 190 | |
gustavatmel | 1:9c5af431a1f1 | 191 | void gpio_irq_disable(gpio_irq_t *obj) |
gustavatmel | 1:9c5af431a1f1 | 192 | { |
gustavatmel | 1:9c5af431a1f1 | 193 | uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); |
gustavatmel | 1:9c5af431a1f1 | 194 | struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; |
gustavatmel | 1:9c5af431a1f1 | 195 | |
gustavatmel | 1:9c5af431a1f1 | 196 | NVIC_DisableIRQ(var->irq_n); |
gustavatmel | 1:9c5af431a1f1 | 197 | } |
gustavatmel | 1:9c5af431a1f1 | 198 | |
gustavatmel | 1:9c5af431a1f1 | 199 | static void gpio_irq_0_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 200 | { |
gustavatmel | 1:9c5af431a1f1 | 201 | gpio_irq(gpio_irq_var_arr + 0); |
gustavatmel | 1:9c5af431a1f1 | 202 | } |
gustavatmel | 1:9c5af431a1f1 | 203 | static void gpio_irq_1_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 204 | { |
gustavatmel | 1:9c5af431a1f1 | 205 | gpio_irq(gpio_irq_var_arr + 1); |
gustavatmel | 1:9c5af431a1f1 | 206 | } |
gustavatmel | 1:9c5af431a1f1 | 207 | static void gpio_irq_2_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 208 | { |
gustavatmel | 1:9c5af431a1f1 | 209 | gpio_irq(gpio_irq_var_arr + 2); |
gustavatmel | 1:9c5af431a1f1 | 210 | } |
gustavatmel | 1:9c5af431a1f1 | 211 | static void gpio_irq_3_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 212 | { |
gustavatmel | 1:9c5af431a1f1 | 213 | gpio_irq(gpio_irq_var_arr + 3); |
gustavatmel | 1:9c5af431a1f1 | 214 | } |
gustavatmel | 1:9c5af431a1f1 | 215 | static void gpio_irq_4_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 216 | { |
gustavatmel | 1:9c5af431a1f1 | 217 | gpio_irq(gpio_irq_var_arr + 4); |
gustavatmel | 1:9c5af431a1f1 | 218 | } |
gustavatmel | 1:9c5af431a1f1 | 219 | static void gpio_irq_5_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 220 | { |
gustavatmel | 1:9c5af431a1f1 | 221 | gpio_irq(gpio_irq_var_arr + 5); |
gustavatmel | 1:9c5af431a1f1 | 222 | } |
gustavatmel | 1:9c5af431a1f1 | 223 | static void gpio_irq_6_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 224 | { |
gustavatmel | 1:9c5af431a1f1 | 225 | gpio_irq(gpio_irq_var_arr + 6); |
gustavatmel | 1:9c5af431a1f1 | 226 | } |
gustavatmel | 1:9c5af431a1f1 | 227 | static void gpio_irq_7_vec(void) |
gustavatmel | 1:9c5af431a1f1 | 228 | { |
gustavatmel | 1:9c5af431a1f1 | 229 | gpio_irq(gpio_irq_var_arr + 7); |
gustavatmel | 1:9c5af431a1f1 | 230 | } |
gustavatmel | 1:9c5af431a1f1 | 231 | |
gustavatmel | 1:9c5af431a1f1 | 232 | static void gpio_irq(struct nu_gpio_irq_var *var) |
gustavatmel | 1:9c5af431a1f1 | 233 | { |
gustavatmel | 1:9c5af431a1f1 | 234 | // NOTE: GPA_IRQn, GPB_IRQn, ... are not arranged sequentially, so we cannot calculate out port_index through offset from GPA_IRQn. |
gustavatmel | 1:9c5af431a1f1 | 235 | // Instead, we add port_index into gpio_irq_var_arr table. |
gustavatmel | 1:9c5af431a1f1 | 236 | uint32_t port_index = var->port_index; |
gustavatmel | 1:9c5af431a1f1 | 237 | GPIO_T *gpio_base = NU_PORT_BASE(port_index); |
gustavatmel | 1:9c5af431a1f1 | 238 | |
gustavatmel | 1:9c5af431a1f1 | 239 | uint32_t intsrc = gpio_base->INTSRC; |
gustavatmel | 1:9c5af431a1f1 | 240 | uint32_t inten = gpio_base->INTEN; |
gustavatmel | 1:9c5af431a1f1 | 241 | while (intsrc) { |
gustavatmel | 1:9c5af431a1f1 | 242 | int pin_index = nu_ctz(intsrc); |
gustavatmel | 1:9c5af431a1f1 | 243 | gpio_irq_t *obj = var->obj_arr[pin_index]; |
gustavatmel | 1:9c5af431a1f1 | 244 | if (inten & (GPIO_INT_RISING << pin_index)) { |
gustavatmel | 1:9c5af431a1f1 | 245 | if (GPIO_PIN_DATA(port_index, pin_index)) { |
gustavatmel | 1:9c5af431a1f1 | 246 | if (obj->irq_handler) { |
gustavatmel | 1:9c5af431a1f1 | 247 | ((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_RISE); |
gustavatmel | 1:9c5af431a1f1 | 248 | } |
gustavatmel | 1:9c5af431a1f1 | 249 | } |
gustavatmel | 1:9c5af431a1f1 | 250 | } |
gustavatmel | 1:9c5af431a1f1 | 251 | |
gustavatmel | 1:9c5af431a1f1 | 252 | if (inten & (GPIO_INT_FALLING << pin_index)) { |
gustavatmel | 1:9c5af431a1f1 | 253 | if (! GPIO_PIN_DATA(port_index, pin_index)) { |
gustavatmel | 1:9c5af431a1f1 | 254 | if (obj->irq_handler) { |
gustavatmel | 1:9c5af431a1f1 | 255 | ((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_FALL); |
gustavatmel | 1:9c5af431a1f1 | 256 | } |
gustavatmel | 1:9c5af431a1f1 | 257 | } |
gustavatmel | 1:9c5af431a1f1 | 258 | } |
gustavatmel | 1:9c5af431a1f1 | 259 | |
gustavatmel | 1:9c5af431a1f1 | 260 | intsrc &= ~(1 << pin_index); |
gustavatmel | 1:9c5af431a1f1 | 261 | } |
gustavatmel | 1:9c5af431a1f1 | 262 | // Clear all interrupt flags |
gustavatmel | 1:9c5af431a1f1 | 263 | gpio_base->INTSRC = gpio_base->INTSRC; |
gustavatmel | 1:9c5af431a1f1 | 264 | } |
gustavatmel | 1:9c5af431a1f1 | 265 | |
gustavatmel | 1:9c5af431a1f1 | 266 | #endif |