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:
150:02e0a0aed4ec
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 150:02e0a0aed4ec 1 /*******************************************************************************
<> 150:02e0a0aed4ec 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
<> 150:02e0a0aed4ec 3 *
<> 150:02e0a0aed4ec 4 * Permission is hereby granted, free of charge, to any person obtaining a
<> 150:02e0a0aed4ec 5 * copy of this software and associated documentation files (the "Software"),
<> 150:02e0a0aed4ec 6 * to deal in the Software without restriction, including without limitation
<> 150:02e0a0aed4ec 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
<> 150:02e0a0aed4ec 8 * and/or sell copies of the Software, and to permit persons to whom the
<> 150:02e0a0aed4ec 9 * Software is furnished to do so, subject to the following conditions:
<> 150:02e0a0aed4ec 10 *
<> 150:02e0a0aed4ec 11 * The above copyright notice and this permission notice shall be included
<> 150:02e0a0aed4ec 12 * in all copies or substantial portions of the Software.
<> 150:02e0a0aed4ec 13 *
<> 150:02e0a0aed4ec 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
<> 150:02e0a0aed4ec 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
<> 150:02e0a0aed4ec 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
<> 150:02e0a0aed4ec 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
<> 150:02e0a0aed4ec 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
<> 150:02e0a0aed4ec 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
<> 150:02e0a0aed4ec 20 * OTHER DEALINGS IN THE SOFTWARE.
<> 150:02e0a0aed4ec 21 *
<> 150:02e0a0aed4ec 22 * Except as contained in this notice, the name of Maxim Integrated
<> 150:02e0a0aed4ec 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
<> 150:02e0a0aed4ec 24 * Products, Inc. Branding Policy.
<> 150:02e0a0aed4ec 25 *
<> 150:02e0a0aed4ec 26 * The mere transfer of this software does not imply any licenses
<> 150:02e0a0aed4ec 27 * of trade secrets, proprietary technology, copyrights, patents,
<> 150:02e0a0aed4ec 28 * trademarks, maskwork rights, or any other form of intellectual
<> 150:02e0a0aed4ec 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
<> 150:02e0a0aed4ec 30 * ownership rights.
<> 150:02e0a0aed4ec 31 *******************************************************************************
<> 150:02e0a0aed4ec 32 */
<> 150:02e0a0aed4ec 33
<> 150:02e0a0aed4ec 34 #include <stddef.h>
<> 150:02e0a0aed4ec 35 #include "cmsis.h"
<> 150:02e0a0aed4ec 36 #include "gpio_irq_api.h"
<> 150:02e0a0aed4ec 37 #include "mbed_error.h"
<> 150:02e0a0aed4ec 38
<> 150:02e0a0aed4ec 39 static gpio_irq_t *objs[MXC_GPIO_NUM_PORTS][MXC_GPIO_MAX_PINS_PER_PORT] = {{0}};
<> 150:02e0a0aed4ec 40 static gpio_irq_handler irq_handler;
<> 150:02e0a0aed4ec 41
<> 150:02e0a0aed4ec 42 static void handle_irq(unsigned int port)
<> 150:02e0a0aed4ec 43 {
<> 150:02e0a0aed4ec 44 uint32_t intfl, in_val;
<> 150:02e0a0aed4ec 45 uint32_t mask;
<> 150:02e0a0aed4ec 46 unsigned int pin;
<> 150:02e0a0aed4ec 47
<> 150:02e0a0aed4ec 48 /* Read pin state */
<> 150:02e0a0aed4ec 49 in_val = MXC_GPIO->in_val[port];
<> 150:02e0a0aed4ec 50
<> 150:02e0a0aed4ec 51 /* Read interrupts */
<> 150:02e0a0aed4ec 52 intfl = MXC_GPIO->intfl[port] & MXC_GPIO->inten[port];
<> 150:02e0a0aed4ec 53
<> 150:02e0a0aed4ec 54 mask = 1;
<> 150:02e0a0aed4ec 55
<> 150:02e0a0aed4ec 56 for (pin = 0; pin < MXC_GPIO_MAX_PINS_PER_PORT; pin++) {
<> 150:02e0a0aed4ec 57 if (intfl & mask) {
<> 150:02e0a0aed4ec 58 MXC_GPIO->intfl[port] = mask; /* clear interrupt */
<> 150:02e0a0aed4ec 59 gpio_irq_event event = (in_val & mask) ? IRQ_RISE : IRQ_FALL;
<> 150:02e0a0aed4ec 60 gpio_irq_t *obj = objs[port][pin];
<> 150:02e0a0aed4ec 61 if (obj && obj->id) {
<> 150:02e0a0aed4ec 62 if ((event == IRQ_RISE) && obj->rise_en) {
<> 150:02e0a0aed4ec 63 irq_handler(obj->id, IRQ_RISE);
<> 150:02e0a0aed4ec 64 } else if ((event == IRQ_FALL) && obj->fall_en) {
<> 150:02e0a0aed4ec 65 irq_handler(obj->id, IRQ_FALL);
<> 150:02e0a0aed4ec 66 }
<> 150:02e0a0aed4ec 67 }
<> 150:02e0a0aed4ec 68 }
<> 150:02e0a0aed4ec 69 mask <<= 1;
<> 150:02e0a0aed4ec 70 }
<> 150:02e0a0aed4ec 71 }
<> 150:02e0a0aed4ec 72
<> 150:02e0a0aed4ec 73 void gpio_irq_0(void) { handle_irq(0); }
<> 150:02e0a0aed4ec 74 void gpio_irq_1(void) { handle_irq(1); }
<> 150:02e0a0aed4ec 75 void gpio_irq_2(void) { handle_irq(2); }
<> 150:02e0a0aed4ec 76 void gpio_irq_3(void) { handle_irq(3); }
<> 150:02e0a0aed4ec 77 void gpio_irq_4(void) { handle_irq(4); }
<> 150:02e0a0aed4ec 78
<> 150:02e0a0aed4ec 79 int gpio_irq_init(gpio_irq_t *obj, PinName name, gpio_irq_handler handler, uint32_t id)
<> 150:02e0a0aed4ec 80 {
<> 150:02e0a0aed4ec 81 if (name == NC) {
<> 150:02e0a0aed4ec 82 return -1;
<> 150:02e0a0aed4ec 83 }
<> 150:02e0a0aed4ec 84
<> 150:02e0a0aed4ec 85 uint8_t port = PINNAME_TO_PORT(name);
<> 150:02e0a0aed4ec 86 uint8_t pin = PINNAME_TO_PIN(name);
<> 150:02e0a0aed4ec 87
<> 150:02e0a0aed4ec 88 if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) {
<> 150:02e0a0aed4ec 89 return 1;
<> 150:02e0a0aed4ec 90 }
<> 150:02e0a0aed4ec 91
<> 150:02e0a0aed4ec 92 obj->port = port;
<> 150:02e0a0aed4ec 93 obj->pin = pin;
<> 150:02e0a0aed4ec 94 obj->id = id;
<> 150:02e0a0aed4ec 95 objs[port][pin] = obj;
<> 150:02e0a0aed4ec 96
<> 150:02e0a0aed4ec 97 /* register handlers */
<> 150:02e0a0aed4ec 98 irq_handler = handler;
<> 150:02e0a0aed4ec 99 NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)gpio_irq_0);
<> 150:02e0a0aed4ec 100 NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)gpio_irq_1);
<> 150:02e0a0aed4ec 101 NVIC_SetVector(GPIO_P2_IRQn, (uint32_t)gpio_irq_2);
<> 150:02e0a0aed4ec 102 NVIC_SetVector(GPIO_P3_IRQn, (uint32_t)gpio_irq_3);
<> 150:02e0a0aed4ec 103 NVIC_SetVector(GPIO_P4_IRQn, (uint32_t)gpio_irq_4);
<> 150:02e0a0aed4ec 104
<> 150:02e0a0aed4ec 105 /* disable the interrupt locally */
<> 150:02e0a0aed4ec 106 MXC_GPIO->int_mode[port] &= ~(0xF << (pin*4));
<> 150:02e0a0aed4ec 107
<> 150:02e0a0aed4ec 108 /* clear a pending request */
<> 150:02e0a0aed4ec 109 MXC_GPIO->intfl[port] = 1 << pin;
<> 150:02e0a0aed4ec 110
<> 150:02e0a0aed4ec 111 /* enable the requested interrupt */
<> 150:02e0a0aed4ec 112 MXC_GPIO->inten[port] |= (1 << pin);
<> 150:02e0a0aed4ec 113 NVIC_EnableIRQ((IRQn_Type)((uint32_t)GPIO_P0_IRQn + port));
<> 150:02e0a0aed4ec 114
<> 150:02e0a0aed4ec 115 return 0;
<> 150:02e0a0aed4ec 116 }
<> 150:02e0a0aed4ec 117
<> 150:02e0a0aed4ec 118 void gpio_irq_free(gpio_irq_t *obj)
<> 150:02e0a0aed4ec 119 {
<> 150:02e0a0aed4ec 120 /* disable interrupt */
<> 150:02e0a0aed4ec 121 MXC_GPIO->inten[obj->port] &= ~(1 << obj->pin);
<> 150:02e0a0aed4ec 122 MXC_GPIO->int_mode[obj->port] &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 123 objs[obj->port][obj->pin] = NULL;
<> 150:02e0a0aed4ec 124 }
<> 150:02e0a0aed4ec 125
<> 150:02e0a0aed4ec 126 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
<> 150:02e0a0aed4ec 127 {
<> 150:02e0a0aed4ec 128 if (event == IRQ_FALL) {
<> 150:02e0a0aed4ec 129 obj->fall_en = enable;
<> 150:02e0a0aed4ec 130 } else if (event == IRQ_RISE) {
<> 150:02e0a0aed4ec 131 obj->rise_en = enable;
<> 150:02e0a0aed4ec 132 }
<> 150:02e0a0aed4ec 133
<> 150:02e0a0aed4ec 134 if (obj->fall_en && obj->rise_en) {
<> 150:02e0a0aed4ec 135 MXC_GPIO->int_mode[obj->port] |= (MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 136 } else if (obj->fall_en) {
<> 150:02e0a0aed4ec 137 uint32_t int_mode = MXC_GPIO->int_mode[obj->port];
<> 150:02e0a0aed4ec 138 int_mode &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 139 int_mode |= (MXC_V_GPIO_INT_MODE_FALLING_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 140 MXC_GPIO->int_mode[obj->port] = int_mode;
<> 150:02e0a0aed4ec 141 } else if (obj->rise_en) {
<> 150:02e0a0aed4ec 142 uint32_t int_mode = MXC_GPIO->int_mode[obj->port];
<> 150:02e0a0aed4ec 143 int_mode &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 144 int_mode |= (MXC_V_GPIO_INT_MODE_RISING_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 145 MXC_GPIO->int_mode[obj->port] = int_mode;
<> 150:02e0a0aed4ec 146 } else {
<> 150:02e0a0aed4ec 147 MXC_GPIO->int_mode[obj->port] &= ~(MXC_V_GPIO_INT_MODE_ANY_EDGE << (obj->pin*4));
<> 150:02e0a0aed4ec 148 }
<> 150:02e0a0aed4ec 149 }
<> 150:02e0a0aed4ec 150
<> 150:02e0a0aed4ec 151 void gpio_irq_enable(gpio_irq_t *obj)
<> 150:02e0a0aed4ec 152 {
<> 150:02e0a0aed4ec 153 MXC_GPIO->inten[obj->port] |= (1 << obj->pin);
<> 150:02e0a0aed4ec 154 }
<> 150:02e0a0aed4ec 155
<> 150:02e0a0aed4ec 156 void gpio_irq_disable(gpio_irq_t *obj)
<> 150:02e0a0aed4ec 157 {
<> 150:02e0a0aed4ec 158 MXC_GPIO->inten[obj->port] &= ~(1 << obj->pin);
<> 150:02e0a0aed4ec 159 }
<> 150:02e0a0aed4ec 160
<> 150:02e0a0aed4ec 161 gpio_irq_t *gpio_irq_get_obj(PinName name)
<> 150:02e0a0aed4ec 162 {
<> 150:02e0a0aed4ec 163 if (name == NC) {
<> 150:02e0a0aed4ec 164 return NULL;
<> 150:02e0a0aed4ec 165 }
<> 150:02e0a0aed4ec 166
<> 150:02e0a0aed4ec 167 unsigned int port = PINNAME_TO_PORT(name);
<> 150:02e0a0aed4ec 168 unsigned int pin = PINNAME_TO_PIN(name);
<> 150:02e0a0aed4ec 169
<> 150:02e0a0aed4ec 170 if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) {
<> 150:02e0a0aed4ec 171 return NULL;
<> 150:02e0a0aed4ec 172 }
<> 150:02e0a0aed4ec 173
<> 150:02e0a0aed4ec 174 return objs[port][pin];
<> 150:02e0a0aed4ec 175 }