mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
sivasuren
Date:
Fri Nov 25 07:57:40 2016 +0000
Revision:
150:da61ba4e9755
Parent:
149:156823d33999
surendar changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /* mbed Microcontroller Library
<> 149:156823d33999 2 * Copyright (c) 2006-2013 ARM Limited
<> 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 #include "mbed_assert.h"
<> 149:156823d33999 17 #include "gpio_api.h"
<> 149:156823d33999 18 #include "gpio_irq_api.h"
<> 149:156823d33999 19 #include "pinmap.h"
<> 149:156823d33999 20 #include "nrf_drv_gpiote.h"
<> 149:156823d33999 21
<> 149:156823d33999 22
<> 149:156823d33999 23 #if defined(TARGET_MCU_NRF51822)
<> 149:156823d33999 24 #define GPIO_PIN_COUNT 31
<> 149:156823d33999 25 #else
<> 149:156823d33999 26 #define GPIO_PIN_COUNT 32
<> 149:156823d33999 27 #endif
<> 149:156823d33999 28
<> 149:156823d33999 29 typedef struct {
<> 149:156823d33999 30 bool used_as_gpio : 1;
<> 149:156823d33999 31 PinDirection direction : 1;
<> 149:156823d33999 32 bool init_high : 1;
<> 149:156823d33999 33 PinMode pull : 2;
<> 149:156823d33999 34 bool used_as_irq : 1;
<> 149:156823d33999 35 bool irq_fall : 1;
<> 149:156823d33999 36 bool irq_rise : 1;
<> 149:156823d33999 37 } gpio_cfg_t;
<> 149:156823d33999 38
<> 149:156823d33999 39 uint32_t m_gpio_initialized;
<> 149:156823d33999 40 gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
<> 149:156823d33999 41
<> 149:156823d33999 42
<> 149:156823d33999 43 /***********
<> 149:156823d33999 44 GPIO IRQ
<> 149:156823d33999 45 ***********/
<> 149:156823d33999 46
<> 149:156823d33999 47 static gpio_irq_handler m_irq_handler;
<> 149:156823d33999 48 static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
<> 149:156823d33999 49 uint32_t m_gpio_irq_enabled;
<> 149:156823d33999 50
<> 149:156823d33999 51
<> 149:156823d33999 52 static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
<> 149:156823d33999 53 {
<> 149:156823d33999 54 nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
<> 149:156823d33999 55 gpio_irq_event event = (sense == NRF_GPIO_PIN_SENSE_LOW) ? IRQ_RISE : IRQ_FALL;
<> 149:156823d33999 56
<> 149:156823d33999 57 if (m_gpio_irq_enabled & (1UL << pin)) {
<> 149:156823d33999 58 if (((event == IRQ_RISE) && m_gpio_cfg[pin].irq_rise)
<> 149:156823d33999 59 || ((event == IRQ_FALL) && m_gpio_cfg[pin].irq_fall)) {
<> 149:156823d33999 60 m_irq_handler(m_channel_ids[pin], event);
<> 149:156823d33999 61 }
<> 149:156823d33999 62 }
<> 149:156823d33999 63 }
<> 149:156823d33999 64
<> 149:156823d33999 65
<> 149:156823d33999 66 void gpio_init(gpio_t *obj, PinName pin)
<> 149:156823d33999 67 {
<> 149:156823d33999 68 obj->pin = pin;
<> 149:156823d33999 69 if (pin == (PinName)NC) {
<> 149:156823d33999 70 return;
<> 149:156823d33999 71 }
<> 149:156823d33999 72 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 149:156823d33999 73 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 74
<> 149:156823d33999 75 m_gpio_cfg[obj->pin].used_as_gpio = true;
<> 149:156823d33999 76 }
<> 149:156823d33999 77
<> 149:156823d33999 78
<> 149:156823d33999 79 int gpio_read(gpio_t *obj)
<> 149:156823d33999 80 {
<> 149:156823d33999 81 MBED_ASSERT(obj->pin != (PinName)NC);
<> 149:156823d33999 82 if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
<> 149:156823d33999 83 return ((NRF_GPIO->OUTSET & (1UL << obj->pin)) ? 1 : 0);
<> 149:156823d33999 84 } else {
<> 149:156823d33999 85 return nrf_gpio_pin_read(obj->pin);
<> 149:156823d33999 86 }
<> 149:156823d33999 87 }
<> 149:156823d33999 88
<> 149:156823d33999 89
<> 149:156823d33999 90 static void gpio_apply_config(uint8_t pin)
<> 149:156823d33999 91 {
<> 149:156823d33999 92 if (m_gpio_initialized & (1UL << pin)) {
<> 149:156823d33999 93 if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 94 nrf_drv_gpiote_out_uninit(pin);
<> 149:156823d33999 95 }
<> 149:156823d33999 96 else {
<> 149:156823d33999 97 nrf_drv_gpiote_in_uninit(pin);
<> 149:156823d33999 98 }
<> 149:156823d33999 99 }
<> 149:156823d33999 100
<> 149:156823d33999 101 if (m_gpio_cfg[pin].used_as_gpio || m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 102 if ((m_gpio_cfg[pin].direction == PIN_INPUT)
<> 149:156823d33999 103 || (m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 104 //Configure as input.
<> 149:156823d33999 105 nrf_drv_gpiote_in_config_t cfg;
<> 149:156823d33999 106
<> 149:156823d33999 107 cfg.hi_accuracy = false;
<> 149:156823d33999 108 cfg.is_watcher = false;
<> 149:156823d33999 109 cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE;
<> 149:156823d33999 110 if (m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 111 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 112 nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
<> 149:156823d33999 113 if ((m_gpio_irq_enabled & (1 << pin))
<> 149:156823d33999 114 && (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall))
<> 149:156823d33999 115 {
<> 149:156823d33999 116 nrf_drv_gpiote_in_event_enable(pin, true);
<> 149:156823d33999 117 }
<> 149:156823d33999 118 }
<> 149:156823d33999 119 else {
<> 149:156823d33999 120 switch(m_gpio_cfg[pin].pull) {
<> 149:156823d33999 121 case PullUp:
<> 149:156823d33999 122 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 123 break;
<> 149:156823d33999 124 case PullDown:
<> 149:156823d33999 125 cfg.pull = NRF_GPIO_PIN_PULLDOWN;
<> 149:156823d33999 126 break;
<> 149:156823d33999 127 default:
<> 149:156823d33999 128 cfg.pull = NRF_GPIO_PIN_NOPULL;
<> 149:156823d33999 129 break;
<> 149:156823d33999 130 }
<> 149:156823d33999 131 nrf_drv_gpiote_in_init(pin, &cfg, NULL);
<> 149:156823d33999 132 }
<> 149:156823d33999 133 }
<> 149:156823d33999 134 else {
<> 149:156823d33999 135 // Configure as output.
<> 149:156823d33999 136 nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(m_gpio_cfg[pin].init_high);
<> 149:156823d33999 137 nrf_drv_gpiote_out_init(pin, &cfg);
<> 149:156823d33999 138 }
<> 149:156823d33999 139 m_gpio_initialized |= (1UL << pin);
<> 149:156823d33999 140 }
<> 149:156823d33999 141 else {
<> 149:156823d33999 142 m_gpio_initialized &= ~(1UL << pin);
<> 149:156823d33999 143 }
<> 149:156823d33999 144 }
<> 149:156823d33999 145
<> 149:156823d33999 146
<> 149:156823d33999 147 void gpio_mode(gpio_t *obj, PinMode mode)
<> 149:156823d33999 148 {
<> 149:156823d33999 149 MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
<> 149:156823d33999 150 m_gpio_cfg[obj->pin].pull = mode;
<> 149:156823d33999 151 gpio_apply_config(obj->pin);
<> 149:156823d33999 152 }
<> 149:156823d33999 153
<> 149:156823d33999 154
<> 149:156823d33999 155 void gpio_dir(gpio_t *obj, PinDirection direction)
<> 149:156823d33999 156 {
<> 149:156823d33999 157 MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
<> 149:156823d33999 158 m_gpio_cfg[obj->pin].direction = direction;
<> 149:156823d33999 159 gpio_apply_config(obj->pin);
<> 149:156823d33999 160 }
<> 149:156823d33999 161
<> 149:156823d33999 162
<> 149:156823d33999 163 /***********
<> 149:156823d33999 164 GPIO IRQ
<> 149:156823d33999 165 ***********/
<> 149:156823d33999 166
<> 149:156823d33999 167 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
<> 149:156823d33999 168 {
<> 149:156823d33999 169 if (pin == NC) {
<> 149:156823d33999 170 return -1;
<> 149:156823d33999 171 }
<> 149:156823d33999 172 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 149:156823d33999 173 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 174
<> 149:156823d33999 175 m_gpio_cfg[pin].used_as_irq = true;
<> 149:156823d33999 176 m_channel_ids[pin] = id;
<> 149:156823d33999 177 obj->ch = pin;
<> 149:156823d33999 178 m_irq_handler = handler;
<> 149:156823d33999 179 m_channel_ids[pin] = id;
<> 149:156823d33999 180
<> 149:156823d33999 181 gpio_apply_config(pin);
<> 149:156823d33999 182 return 1;
<> 149:156823d33999 183 }
<> 149:156823d33999 184
<> 149:156823d33999 185
<> 149:156823d33999 186 void gpio_irq_free(gpio_irq_t *obj)
<> 149:156823d33999 187 {
<> 149:156823d33999 188 nrf_drv_gpiote_in_uninit(obj->ch);
<> 149:156823d33999 189 m_gpio_cfg[obj->ch].used_as_irq = false;
<> 149:156823d33999 190 m_channel_ids[obj->ch] = 0;
<> 149:156823d33999 191
<> 149:156823d33999 192 gpio_apply_config(obj->ch);
<> 149:156823d33999 193 }
<> 149:156823d33999 194
<> 149:156823d33999 195
<> 149:156823d33999 196 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
<> 149:156823d33999 197 {
<> 149:156823d33999 198 gpio_cfg_t* cfg = &m_gpio_cfg[obj->ch];
<> 149:156823d33999 199 bool irq_enabled_before =
<> 149:156823d33999 200 (m_gpio_irq_enabled & (1 << obj->ch)) &&
<> 149:156823d33999 201 (cfg->irq_rise || cfg->irq_fall);
<> 149:156823d33999 202
<> 149:156823d33999 203 if (event == IRQ_RISE) {
<> 149:156823d33999 204 cfg->irq_rise = enable ? true : false;
<> 149:156823d33999 205 }
<> 149:156823d33999 206 else if (event == IRQ_FALL) {
<> 149:156823d33999 207 cfg->irq_fall = enable ? true : false;
<> 149:156823d33999 208 }
<> 149:156823d33999 209
<> 149:156823d33999 210 bool irq_enabled_after = cfg->irq_rise || cfg->irq_fall;
<> 149:156823d33999 211
<> 149:156823d33999 212 if (irq_enabled_before != irq_enabled_after) {
<> 149:156823d33999 213 if (irq_enabled_after) {
<> 149:156823d33999 214 gpio_irq_enable(obj);
<> 149:156823d33999 215 } else {
<> 149:156823d33999 216 gpio_irq_disable(obj);
<> 149:156823d33999 217 }
<> 149:156823d33999 218 }
<> 149:156823d33999 219 }
<> 149:156823d33999 220
<> 149:156823d33999 221
<> 149:156823d33999 222 void gpio_irq_enable(gpio_irq_t *obj)
<> 149:156823d33999 223 {
<> 149:156823d33999 224 m_gpio_irq_enabled |= (1 << obj->ch);
<> 149:156823d33999 225 if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
<> 149:156823d33999 226 nrf_drv_gpiote_in_event_enable(obj->ch, true);
<> 149:156823d33999 227 }
<> 149:156823d33999 228 }
<> 149:156823d33999 229
<> 149:156823d33999 230
<> 149:156823d33999 231 void gpio_irq_disable(gpio_irq_t *obj)
<> 149:156823d33999 232 {
<> 149:156823d33999 233 m_gpio_irq_enabled &= ~(1 << obj->ch);
<> 149:156823d33999 234 nrf_drv_gpiote_in_event_disable(obj->ch);
<> 149:156823d33999 235 }