mbed library sources. Supersedes mbed-src.
Fork of mbed-dev by
targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/gpio_irq_api.c@15:a81a8d6c1dfe, 2015-11-04 (annotated)
- Committer:
- mbed_official
- Date:
- Wed Nov 04 16:30:11 2015 +0000
- Revision:
- 15:a81a8d6c1dfe
- Child:
- 64:41a834223ea3
Synchronized with git revision 46af745ef4405614c3fa49abbd9a706a362ea514
Full URL: https://github.com/mbedmicro/mbed/commit/46af745ef4405614c3fa49abbd9a706a362ea514/
Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 15:a81a8d6c1dfe | 1 | /* mbed Microcontroller Library |
mbed_official | 15:a81a8d6c1dfe | 2 | * Copyright (c) 2006-2015 ARM Limited |
mbed_official | 15:a81a8d6c1dfe | 3 | * |
mbed_official | 15:a81a8d6c1dfe | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
mbed_official | 15:a81a8d6c1dfe | 5 | * you may not use this file except in compliance with the License. |
mbed_official | 15:a81a8d6c1dfe | 6 | * You may obtain a copy of the License at |
mbed_official | 15:a81a8d6c1dfe | 7 | * |
mbed_official | 15:a81a8d6c1dfe | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
mbed_official | 15:a81a8d6c1dfe | 9 | * |
mbed_official | 15:a81a8d6c1dfe | 10 | * Unless required by applicable law or agreed to in writing, software |
mbed_official | 15:a81a8d6c1dfe | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
mbed_official | 15:a81a8d6c1dfe | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mbed_official | 15:a81a8d6c1dfe | 13 | * See the License for the specific language governing permissions and |
mbed_official | 15:a81a8d6c1dfe | 14 | * limitations under the License. |
mbed_official | 15:a81a8d6c1dfe | 15 | */ |
mbed_official | 15:a81a8d6c1dfe | 16 | #include <stddef.h> |
mbed_official | 15:a81a8d6c1dfe | 17 | #include "cmsis.h" |
mbed_official | 15:a81a8d6c1dfe | 18 | |
mbed_official | 15:a81a8d6c1dfe | 19 | #include "gpio_irq_api.h" |
mbed_official | 15:a81a8d6c1dfe | 20 | #include "gpio_api.h" |
mbed_official | 15:a81a8d6c1dfe | 21 | #include "mbed_error.h" |
mbed_official | 15:a81a8d6c1dfe | 22 | #include "extint.h" |
mbed_official | 15:a81a8d6c1dfe | 23 | #include "pinmap.h" |
mbed_official | 15:a81a8d6c1dfe | 24 | #include "PeripheralPins.h" |
mbed_official | 15:a81a8d6c1dfe | 25 | #include "port.h" |
mbed_official | 15:a81a8d6c1dfe | 26 | |
mbed_official | 15:a81a8d6c1dfe | 27 | #define IRQ_RISE_POSITION 1 |
mbed_official | 15:a81a8d6c1dfe | 28 | #define IRQ_FALL_POSITION 2 |
mbed_official | 15:a81a8d6c1dfe | 29 | #define CHANNEL_NUM 16 |
mbed_official | 15:a81a8d6c1dfe | 30 | #define pEXT_CONF(obj) (obj->config_extint_chan) |
mbed_official | 15:a81a8d6c1dfe | 31 | static uint32_t channel_ids[CHANNEL_NUM] = {0}; |
mbed_official | 15:a81a8d6c1dfe | 32 | static gpio_irq_handler irq_handler; |
mbed_official | 15:a81a8d6c1dfe | 33 | uint8_t ext_int_pins[EIC_NUMBER_OF_INTERRUPTS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
mbed_official | 15:a81a8d6c1dfe | 34 | |
mbed_official | 15:a81a8d6c1dfe | 35 | void gpio_irq(void) |
mbed_official | 15:a81a8d6c1dfe | 36 | { |
mbed_official | 15:a81a8d6c1dfe | 37 | uint32_t current_channel; |
mbed_official | 15:a81a8d6c1dfe | 38 | uint32_t mask; |
mbed_official | 15:a81a8d6c1dfe | 39 | gpio_irq_event event; |
mbed_official | 15:a81a8d6c1dfe | 40 | PortGroup *port_base; |
mbed_official | 15:a81a8d6c1dfe | 41 | |
mbed_official | 15:a81a8d6c1dfe | 42 | for (current_channel = 0; current_channel < EIC_NUMBER_OF_INTERRUPTS ; current_channel++) { |
mbed_official | 15:a81a8d6c1dfe | 43 | if (extint_chan_is_detected(current_channel)) { |
mbed_official | 15:a81a8d6c1dfe | 44 | extint_chan_clear_detected(current_channel); |
mbed_official | 15:a81a8d6c1dfe | 45 | port_base = (PortGroup*)port_get_group_from_gpio_pin(ext_int_pins[current_channel]); |
mbed_official | 15:a81a8d6c1dfe | 46 | mask = gpio_set(ext_int_pins[current_channel]); |
mbed_official | 15:a81a8d6c1dfe | 47 | if ((port_base->IN.reg & mask) != 0) { |
mbed_official | 15:a81a8d6c1dfe | 48 | event = IRQ_RISE; |
mbed_official | 15:a81a8d6c1dfe | 49 | } else { |
mbed_official | 15:a81a8d6c1dfe | 50 | event = IRQ_FALL; |
mbed_official | 15:a81a8d6c1dfe | 51 | } |
mbed_official | 15:a81a8d6c1dfe | 52 | if(irq_handler) { |
mbed_official | 15:a81a8d6c1dfe | 53 | irq_handler(channel_ids[current_channel], event); |
mbed_official | 15:a81a8d6c1dfe | 54 | } |
mbed_official | 15:a81a8d6c1dfe | 55 | } |
mbed_official | 15:a81a8d6c1dfe | 56 | } |
mbed_official | 15:a81a8d6c1dfe | 57 | } |
mbed_official | 15:a81a8d6c1dfe | 58 | |
mbed_official | 15:a81a8d6c1dfe | 59 | int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) |
mbed_official | 15:a81a8d6c1dfe | 60 | { |
mbed_official | 15:a81a8d6c1dfe | 61 | MBED_ASSERT(obj); |
mbed_official | 15:a81a8d6c1dfe | 62 | if (pin == NC) |
mbed_official | 15:a81a8d6c1dfe | 63 | return -1; |
mbed_official | 15:a81a8d6c1dfe | 64 | |
mbed_official | 15:a81a8d6c1dfe | 65 | IRQn_Type irq_n = (IRQn_Type)0; |
mbed_official | 15:a81a8d6c1dfe | 66 | uint32_t vector = 0; |
mbed_official | 15:a81a8d6c1dfe | 67 | int int_channel = 0; |
mbed_official | 15:a81a8d6c1dfe | 68 | irq_handler = handler; // assuming the usage of these apis in mbed layer only |
mbed_official | 15:a81a8d6c1dfe | 69 | |
mbed_official | 15:a81a8d6c1dfe | 70 | obj->pin = pin; |
mbed_official | 15:a81a8d6c1dfe | 71 | |
mbed_official | 15:a81a8d6c1dfe | 72 | extint_chan_get_config_defaults(&pEXT_CONF(obj)); |
mbed_official | 15:a81a8d6c1dfe | 73 | pEXT_CONF(obj).gpio_pin = (uint32_t)pin; |
mbed_official | 15:a81a8d6c1dfe | 74 | pEXT_CONF(obj).gpio_pin_mux = 0; // mux setting for ext int is 0 |
mbed_official | 15:a81a8d6c1dfe | 75 | pEXT_CONF(obj).gpio_pin_pull = EXTINT_PULL_UP; |
mbed_official | 15:a81a8d6c1dfe | 76 | pEXT_CONF(obj).detection_criteria = EXTINT_DETECT_NONE; |
mbed_official | 15:a81a8d6c1dfe | 77 | |
mbed_official | 15:a81a8d6c1dfe | 78 | int_channel = pinmap_find_peripheral(pin, PinMap_EXTINT); |
mbed_official | 15:a81a8d6c1dfe | 79 | if (int_channel == NC) { |
mbed_official | 15:a81a8d6c1dfe | 80 | return -1; |
mbed_official | 15:a81a8d6c1dfe | 81 | } |
mbed_official | 15:a81a8d6c1dfe | 82 | extint_chan_set_config(int_channel, &pEXT_CONF(obj)); |
mbed_official | 15:a81a8d6c1dfe | 83 | ext_int_pins[int_channel] = pin; |
mbed_official | 15:a81a8d6c1dfe | 84 | |
mbed_official | 15:a81a8d6c1dfe | 85 | irq_n = EIC_IRQn; |
mbed_official | 15:a81a8d6c1dfe | 86 | vector = (uint32_t)gpio_irq; |
mbed_official | 15:a81a8d6c1dfe | 87 | NVIC_SetVector(irq_n, vector); |
mbed_official | 15:a81a8d6c1dfe | 88 | NVIC_EnableIRQ(irq_n); |
mbed_official | 15:a81a8d6c1dfe | 89 | obj->ch = int_channel; |
mbed_official | 15:a81a8d6c1dfe | 90 | channel_ids[int_channel] = id; |
mbed_official | 15:a81a8d6c1dfe | 91 | obj->irqmask = 0; |
mbed_official | 15:a81a8d6c1dfe | 92 | |
mbed_official | 15:a81a8d6c1dfe | 93 | return 0; |
mbed_official | 15:a81a8d6c1dfe | 94 | } |
mbed_official | 15:a81a8d6c1dfe | 95 | |
mbed_official | 15:a81a8d6c1dfe | 96 | void gpio_irq_free(gpio_irq_t *obj) |
mbed_official | 15:a81a8d6c1dfe | 97 | { |
mbed_official | 15:a81a8d6c1dfe | 98 | MBED_ASSERT(obj); |
mbed_official | 15:a81a8d6c1dfe | 99 | Eic *const eic = _extint_get_eic_from_channel(obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 100 | channel_ids[obj->ch] = 0; |
mbed_official | 15:a81a8d6c1dfe | 101 | eic->INTENCLR.reg = (1UL << obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 102 | } |
mbed_official | 15:a81a8d6c1dfe | 103 | |
mbed_official | 15:a81a8d6c1dfe | 104 | void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) |
mbed_official | 15:a81a8d6c1dfe | 105 | { |
mbed_official | 15:a81a8d6c1dfe | 106 | MBED_ASSERT(obj); |
mbed_official | 15:a81a8d6c1dfe | 107 | Eic *const eic = _extint_get_eic_from_channel(obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 108 | if (enable) { |
mbed_official | 15:a81a8d6c1dfe | 109 | if (event == IRQ_RISE) { |
mbed_official | 15:a81a8d6c1dfe | 110 | obj->irqmask |= IRQ_RISE_POSITION; |
mbed_official | 15:a81a8d6c1dfe | 111 | } else if (event == IRQ_FALL) { |
mbed_official | 15:a81a8d6c1dfe | 112 | obj->irqmask |= IRQ_FALL_POSITION; |
mbed_official | 15:a81a8d6c1dfe | 113 | } |
mbed_official | 15:a81a8d6c1dfe | 114 | eic->INTENSET.reg = (1UL << obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 115 | } else { |
mbed_official | 15:a81a8d6c1dfe | 116 | if (event == IRQ_RISE) { |
mbed_official | 15:a81a8d6c1dfe | 117 | obj->irqmask &= ~IRQ_RISE_POSITION; |
mbed_official | 15:a81a8d6c1dfe | 118 | } else if (event == IRQ_FALL) { |
mbed_official | 15:a81a8d6c1dfe | 119 | obj->irqmask &= ~IRQ_FALL_POSITION; |
mbed_official | 15:a81a8d6c1dfe | 120 | } |
mbed_official | 15:a81a8d6c1dfe | 121 | } |
mbed_official | 15:a81a8d6c1dfe | 122 | |
mbed_official | 15:a81a8d6c1dfe | 123 | if (obj->irqmask == (IRQ_RISE_POSITION | IRQ_FALL_POSITION)) { |
mbed_official | 15:a81a8d6c1dfe | 124 | pEXT_CONF(obj).detection_criteria = EXTINT_DETECT_BOTH; |
mbed_official | 15:a81a8d6c1dfe | 125 | } else if (obj->irqmask == IRQ_RISE_POSITION) { |
mbed_official | 15:a81a8d6c1dfe | 126 | pEXT_CONF(obj).detection_criteria = EXTINT_DETECT_RISING; |
mbed_official | 15:a81a8d6c1dfe | 127 | } else if (obj->irqmask == IRQ_FALL_POSITION) { |
mbed_official | 15:a81a8d6c1dfe | 128 | pEXT_CONF(obj).detection_criteria = EXTINT_DETECT_FALLING; |
mbed_official | 15:a81a8d6c1dfe | 129 | } else { |
mbed_official | 15:a81a8d6c1dfe | 130 | pEXT_CONF(obj).detection_criteria = EXTINT_DETECT_NONE; |
mbed_official | 15:a81a8d6c1dfe | 131 | eic->INTENCLR.reg = (1UL << obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 132 | } |
mbed_official | 15:a81a8d6c1dfe | 133 | |
mbed_official | 15:a81a8d6c1dfe | 134 | extint_chan_set_config(obj->ch, &pEXT_CONF(obj)); |
mbed_official | 15:a81a8d6c1dfe | 135 | } |
mbed_official | 15:a81a8d6c1dfe | 136 | |
mbed_official | 15:a81a8d6c1dfe | 137 | void gpio_irq_enable(gpio_irq_t *obj) |
mbed_official | 15:a81a8d6c1dfe | 138 | { |
mbed_official | 15:a81a8d6c1dfe | 139 | MBED_ASSERT(obj); |
mbed_official | 15:a81a8d6c1dfe | 140 | Eic *const eic = _extint_get_eic_from_channel(obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 141 | NVIC_EnableIRQ(EIC_IRQn); |
mbed_official | 15:a81a8d6c1dfe | 142 | eic->INTENSET.reg = (1UL << obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 143 | } |
mbed_official | 15:a81a8d6c1dfe | 144 | |
mbed_official | 15:a81a8d6c1dfe | 145 | void gpio_irq_disable(gpio_irq_t *obj) |
mbed_official | 15:a81a8d6c1dfe | 146 | { |
mbed_official | 15:a81a8d6c1dfe | 147 | MBED_ASSERT(obj); |
mbed_official | 15:a81a8d6c1dfe | 148 | Eic *const eic = _extint_get_eic_from_channel(obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 149 | eic->INTENCLR.reg = (1UL << obj->ch); |
mbed_official | 15:a81a8d6c1dfe | 150 | if (eic->INTENSET.reg == 0) { |
mbed_official | 15:a81a8d6c1dfe | 151 | NVIC_DisableIRQ(EIC_IRQn); |
mbed_official | 15:a81a8d6c1dfe | 152 | } |
mbed_official | 15:a81a8d6c1dfe | 153 | } |