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