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:
184:08ed48f1de7f
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 167:e84263d55307 1 /* mbed Microcontroller Library
AnnaBridge 184:08ed48f1de7f 2 * Copyright (c) 2006-2018 ARM Limited
AnnaBridge 167:e84263d55307 3 *
AnnaBridge 167:e84263d55307 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 167:e84263d55307 5 * you may not use this file except in compliance with the License.
AnnaBridge 167:e84263d55307 6 * You may obtain a copy of the License at
AnnaBridge 167:e84263d55307 7 *
AnnaBridge 167:e84263d55307 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 167:e84263d55307 9 *
AnnaBridge 167:e84263d55307 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 167:e84263d55307 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 167:e84263d55307 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 167:e84263d55307 13 * See the License for the specific language governing permissions and
AnnaBridge 167:e84263d55307 14 * limitations under the License.
AnnaBridge 167:e84263d55307 15 */
AnnaBridge 167:e84263d55307 16 #include <stddef.h>
AnnaBridge 184:08ed48f1de7f 17 #include "objects.h"
AnnaBridge 167:e84263d55307 18 #include "gpio_irq_api.h"
AnnaBridge 167:e84263d55307 19 #include "mbed_error.h"
AnnaBridge 167:e84263d55307 20
AnnaBridge 184:08ed48f1de7f 21 #define ERROR_BIT_NUMBER 0xFF
AnnaBridge 167:e84263d55307 22
AnnaBridge 184:08ed48f1de7f 23 struct gpio_irq_handler_t {
AnnaBridge 184:08ed48f1de7f 24 gpio_irq_handler handler;
AnnaBridge 184:08ed48f1de7f 25 gpio_irq_event event;
AnnaBridge 184:08ed48f1de7f 26 uint32_t id;
AnnaBridge 184:08ed48f1de7f 27 };
AnnaBridge 167:e84263d55307 28
AnnaBridge 184:08ed48f1de7f 29 /* Handlers registered */
AnnaBridge 184:08ed48f1de7f 30 static struct gpio_irq_handler_t gpio_irq[PINS_NUMBER];
AnnaBridge 167:e84263d55307 31
AnnaBridge 184:08ed48f1de7f 32 /*
AnnaBridge 184:08ed48f1de7f 33 * Return the bit number of the lowest significant bit set to 1 or
AnnaBridge 184:08ed48f1de7f 34 * ERROR_BIT_NUMBER if there is no bit set.
AnnaBridge 184:08ed48f1de7f 35 */
AnnaBridge 184:08ed48f1de7f 36 static uint8_t find_first_set_bit(uint32_t word)
AnnaBridge 167:e84263d55307 37 {
AnnaBridge 184:08ed48f1de7f 38 uint8_t bit_number = 0;
AnnaBridge 167:e84263d55307 39
AnnaBridge 184:08ed48f1de7f 40 if (word == 0) {
AnnaBridge 184:08ed48f1de7f 41 return ERROR_BIT_NUMBER;
AnnaBridge 184:08ed48f1de7f 42 }
AnnaBridge 167:e84263d55307 43
AnnaBridge 184:08ed48f1de7f 44 while (((word >> bit_number++) & 1UL) == 0);
AnnaBridge 167:e84263d55307 45
AnnaBridge 184:08ed48f1de7f 46 return (bit_number - 1);
AnnaBridge 167:e84263d55307 47 }
AnnaBridge 167:e84263d55307 48
AnnaBridge 184:08ed48f1de7f 49 static void handler(struct arm_gpio_dev_t* dev, uint32_t gpio_number,
AnnaBridge 184:08ed48f1de7f 50 uint32_t exp_pin_base)
AnnaBridge 167:e84263d55307 51 {
AnnaBridge 184:08ed48f1de7f 52 uint32_t irq_status = 0;
AnnaBridge 184:08ed48f1de7f 53 /* Pin that triggered the IRQ in this GPIO */
AnnaBridge 184:08ed48f1de7f 54 uint8_t pin_number;
AnnaBridge 184:08ed48f1de7f 55 /* Pin number in the expension port */
AnnaBridge 184:08ed48f1de7f 56 uint8_t exp_pin_number;
AnnaBridge 167:e84263d55307 57
AnnaBridge 184:08ed48f1de7f 58 (void)arm_gpio_get_irq_status(dev, ARM_GPIO_ACCESS_PORT, ARG_NOT_USED,
AnnaBridge 184:08ed48f1de7f 59 &irq_status);
AnnaBridge 167:e84263d55307 60
AnnaBridge 184:08ed48f1de7f 61 pin_number = find_first_set_bit(irq_status);
AnnaBridge 184:08ed48f1de7f 62 if (pin_number == ERROR_BIT_NUMBER) {
AnnaBridge 184:08ed48f1de7f 63 /* There was no IRQ */
AnnaBridge 184:08ed48f1de7f 64 return;
AnnaBridge 184:08ed48f1de7f 65 }
AnnaBridge 167:e84263d55307 66
AnnaBridge 184:08ed48f1de7f 67 (void)arm_gpio_clear_interrupt(dev, pin_number);
AnnaBridge 167:e84263d55307 68
AnnaBridge 184:08ed48f1de7f 69 exp_pin_number = exp_pin_base + pin_number;
AnnaBridge 167:e84263d55307 70
AnnaBridge 184:08ed48f1de7f 71 gpio_irq[exp_pin_number].handler(gpio_irq[exp_pin_number].id,
AnnaBridge 184:08ed48f1de7f 72 gpio_irq[exp_pin_number].event);
AnnaBridge 167:e84263d55307 73 }
AnnaBridge 167:e84263d55307 74
AnnaBridge 184:08ed48f1de7f 75 #ifdef ARM_GPIO0
AnnaBridge 184:08ed48f1de7f 76 void PORT0_IRQHandler(void)
AnnaBridge 167:e84263d55307 77 {
AnnaBridge 184:08ed48f1de7f 78 handler(&ARM_GPIO0_DEV, GPIO0_NUMBER, EXP_PIN_BASE0);
AnnaBridge 167:e84263d55307 79 }
AnnaBridge 184:08ed48f1de7f 80 #endif /* ARM_GPIO0 */
AnnaBridge 167:e84263d55307 81
AnnaBridge 184:08ed48f1de7f 82 #ifdef ARM_GPIO1
AnnaBridge 184:08ed48f1de7f 83 void PORT1_ALL_IRQHandler(void)
AnnaBridge 167:e84263d55307 84 {
AnnaBridge 184:08ed48f1de7f 85 handler(&ARM_GPIO1_DEV, GPIO1_NUMBER, EXP_PIN_BASE1);
AnnaBridge 167:e84263d55307 86 }
AnnaBridge 184:08ed48f1de7f 87 #endif /* ARM_GPIO1 */
AnnaBridge 167:e84263d55307 88
AnnaBridge 184:08ed48f1de7f 89 #ifdef ARM_GPIO2
AnnaBridge 184:08ed48f1de7f 90 void PORT2_ALL_IRQHandler(void)
AnnaBridge 167:e84263d55307 91 {
AnnaBridge 184:08ed48f1de7f 92 handler(&ARM_GPIO2_DEV, GPIO2_NUMBER, EXP_PIN_BASE2);
AnnaBridge 167:e84263d55307 93 }
AnnaBridge 184:08ed48f1de7f 94 #endif /* ARM_GPIO2 */
AnnaBridge 167:e84263d55307 95
AnnaBridge 184:08ed48f1de7f 96 #ifdef ARM_GPIO3
AnnaBridge 184:08ed48f1de7f 97 void PORT3_ALL_IRQHandler(void)
AnnaBridge 167:e84263d55307 98 {
AnnaBridge 184:08ed48f1de7f 99 handler(&ARM_GPIO3_DEV, GPIO3_NUMBER, EXP_PIN_BASE3);
AnnaBridge 167:e84263d55307 100 }
AnnaBridge 184:08ed48f1de7f 101 #endif /* ARM_GPIO3 */
AnnaBridge 184:08ed48f1de7f 102
AnnaBridge 184:08ed48f1de7f 103 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
AnnaBridge 184:08ed48f1de7f 104 uint32_t id)
AnnaBridge 184:08ed48f1de7f 105 {
AnnaBridge 184:08ed48f1de7f 106 struct arm_gpio_dev_t *gpio_dev;
AnnaBridge 167:e84263d55307 107
AnnaBridge 184:08ed48f1de7f 108 if (pin >= EXP0 && pin <= EXP51) {
AnnaBridge 184:08ed48f1de7f 109 /* GPIO pins */
AnnaBridge 184:08ed48f1de7f 110 switch (GPIO_DEV_NUMBER(pin)) {
AnnaBridge 184:08ed48f1de7f 111 #ifdef ARM_GPIO0
AnnaBridge 184:08ed48f1de7f 112 case 0:
AnnaBridge 184:08ed48f1de7f 113 gpio_dev = &ARM_GPIO0_DEV;
AnnaBridge 184:08ed48f1de7f 114 obj->irq_number = PORT0_ALL_IRQn;
AnnaBridge 184:08ed48f1de7f 115 break;
AnnaBridge 184:08ed48f1de7f 116 #endif /* ARM_GPIO0 */
AnnaBridge 184:08ed48f1de7f 117 #ifdef ARM_GPIO1
AnnaBridge 184:08ed48f1de7f 118 case 1:
AnnaBridge 184:08ed48f1de7f 119 gpio_dev = &ARM_GPIO1_DEV;
AnnaBridge 184:08ed48f1de7f 120 obj->irq_number = PORT1_ALL_IRQn;
AnnaBridge 184:08ed48f1de7f 121 break;
AnnaBridge 184:08ed48f1de7f 122 #endif /* ARM_GPIO1 */
AnnaBridge 184:08ed48f1de7f 123 #ifdef ARM_GPIO2
AnnaBridge 184:08ed48f1de7f 124 case 2:
AnnaBridge 184:08ed48f1de7f 125 gpio_dev = &ARM_GPIO2_DEV;
AnnaBridge 184:08ed48f1de7f 126 obj->irq_number = PORT2_ALL_IRQn;
AnnaBridge 184:08ed48f1de7f 127 break;
AnnaBridge 184:08ed48f1de7f 128 #endif /* ARM_GPIO2 */
AnnaBridge 184:08ed48f1de7f 129 #ifdef ARM_GPIO3
AnnaBridge 184:08ed48f1de7f 130 case 3:
AnnaBridge 184:08ed48f1de7f 131 gpio_dev = &ARM_GPIO3_DEV;
AnnaBridge 184:08ed48f1de7f 132 obj->irq_number = PORT3_ALL_IRQn;
AnnaBridge 184:08ed48f1de7f 133 break;
AnnaBridge 184:08ed48f1de7f 134 #endif /* ARM_GPIO3 */
AnnaBridge 184:08ed48f1de7f 135 default:
AnnaBridge 184:08ed48f1de7f 136 error("GPIO %d is not enabled", GPIO_DEV_NUMBER(pin));
AnnaBridge 184:08ed48f1de7f 137 return -1;
AnnaBridge 184:08ed48f1de7f 138 }
AnnaBridge 167:e84263d55307 139
AnnaBridge 184:08ed48f1de7f 140 obj->gpio_dev = gpio_dev;
AnnaBridge 184:08ed48f1de7f 141 obj->pin_number = GPIO_PIN_NUMBER(pin);
AnnaBridge 184:08ed48f1de7f 142 obj->exp_pin_number = pin;
AnnaBridge 184:08ed48f1de7f 143
AnnaBridge 184:08ed48f1de7f 144 arm_gpio_init(gpio_dev);
AnnaBridge 167:e84263d55307 145
AnnaBridge 184:08ed48f1de7f 146 /* Save the handler and id into the global structure */
AnnaBridge 184:08ed48f1de7f 147 gpio_irq[pin].handler = handler;
AnnaBridge 184:08ed48f1de7f 148 gpio_irq[pin].id = id;
AnnaBridge 167:e84263d55307 149
AnnaBridge 184:08ed48f1de7f 150 return 0;
AnnaBridge 184:08ed48f1de7f 151 } else {
AnnaBridge 184:08ed48f1de7f 152 /* The pin is not concerned with GPIO IRQ */
AnnaBridge 184:08ed48f1de7f 153 error("Pin %d is not a GPIO", pin);
AnnaBridge 167:e84263d55307 154 return -1;
AnnaBridge 167:e84263d55307 155 }
AnnaBridge 167:e84263d55307 156 }
AnnaBridge 167:e84263d55307 157
AnnaBridge 167:e84263d55307 158 void gpio_irq_free(gpio_irq_t *obj)
AnnaBridge 167:e84263d55307 159 {
AnnaBridge 184:08ed48f1de7f 160 /* Not implemented because the device can not be uninitialized. */
AnnaBridge 167:e84263d55307 161 }
AnnaBridge 167:e84263d55307 162
AnnaBridge 167:e84263d55307 163 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
AnnaBridge 167:e84263d55307 164 {
AnnaBridge 184:08ed48f1de7f 165 /* Interrupt is set on an input pin on rising or falling edge */
AnnaBridge 184:08ed48f1de7f 166 uint32_t flags = ARM_GPIO_PIN_ENABLE | ARM_GPIO_INPUT | ARM_GPIO_IRQ |
AnnaBridge 184:08ed48f1de7f 167 ARM_GPIO_IRQ_EDGE;
AnnaBridge 167:e84263d55307 168
AnnaBridge 184:08ed48f1de7f 169 switch (event) {
AnnaBridge 184:08ed48f1de7f 170 case IRQ_RISE:
AnnaBridge 184:08ed48f1de7f 171 flags |= ARM_GPIO_IRQ_ACTIVE_HIGH;
AnnaBridge 184:08ed48f1de7f 172 break;
AnnaBridge 184:08ed48f1de7f 173 case IRQ_FALL:
AnnaBridge 184:08ed48f1de7f 174 flags |= ARM_GPIO_IRQ_ACTIVE_LOW;
AnnaBridge 184:08ed48f1de7f 175 break;
AnnaBridge 184:08ed48f1de7f 176 case IRQ_NONE:
AnnaBridge 184:08ed48f1de7f 177 return;
AnnaBridge 184:08ed48f1de7f 178 }
AnnaBridge 184:08ed48f1de7f 179
AnnaBridge 184:08ed48f1de7f 180 (void)arm_gpio_config(obj->gpio_dev, ARM_GPIO_ACCESS_PIN, obj->pin_number,
AnnaBridge 184:08ed48f1de7f 181 flags);
AnnaBridge 184:08ed48f1de7f 182
AnnaBridge 184:08ed48f1de7f 183 /* Record the event type of this pin */
AnnaBridge 184:08ed48f1de7f 184 gpio_irq[obj->exp_pin_number].event = event;
AnnaBridge 184:08ed48f1de7f 185
AnnaBridge 184:08ed48f1de7f 186 NVIC_EnableIRQ(obj->irq_number);
AnnaBridge 184:08ed48f1de7f 187
AnnaBridge 184:08ed48f1de7f 188 if (enable) {
AnnaBridge 184:08ed48f1de7f 189 gpio_irq_enable(obj);
AnnaBridge 167:e84263d55307 190 } else {
AnnaBridge 184:08ed48f1de7f 191 gpio_irq_disable(obj);
AnnaBridge 167:e84263d55307 192 }
AnnaBridge 167:e84263d55307 193 }
AnnaBridge 167:e84263d55307 194
AnnaBridge 167:e84263d55307 195 void gpio_irq_enable(gpio_irq_t *obj)
AnnaBridge 167:e84263d55307 196 {
AnnaBridge 184:08ed48f1de7f 197 (void)arm_gpio_set_interrupt(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
AnnaBridge 184:08ed48f1de7f 198 obj->pin_number, ARM_GPIO_IRQ_ENABLE);
AnnaBridge 167:e84263d55307 199 }
AnnaBridge 167:e84263d55307 200
AnnaBridge 167:e84263d55307 201 void gpio_irq_disable(gpio_irq_t *obj)
AnnaBridge 167:e84263d55307 202 {
AnnaBridge 184:08ed48f1de7f 203 (void)arm_gpio_set_interrupt(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
AnnaBridge 184:08ed48f1de7f 204 obj->pin_number, ARM_GPIO_IRQ_DISABLE);
AnnaBridge 167:e84263d55307 205 }