mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
172:7d866c31b3c5
mbed library release version 165

Who changed what in which revision?

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