Forked.

Fork of mbed-dev by mbed official

Committer:
Dollyparton
Date:
Tue Dec 19 12:50:13 2017 +0000
Revision:
174:ed647f63e28d
Parent:
165:e614a9f1c9e2
Added RAW socket.

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
AnnaBridge 165:e614a9f1c9e2 25 #elif defined(TARGET_MCU_NRF52832)
AnnaBridge 165:e614a9f1c9e2 26 #define GPIO_PIN_COUNT 32
AnnaBridge 165:e614a9f1c9e2 27 #elif defined(TARGET_MCU_NRF52840)
AnnaBridge 165:e614a9f1c9e2 28 #define GPIO_PIN_COUNT 48
<> 149:156823d33999 29 #else
AnnaBridge 165:e614a9f1c9e2 30 #error not recognized gpio count for mcu
<> 149:156823d33999 31 #endif
<> 149:156823d33999 32
<> 149:156823d33999 33 typedef struct {
<> 149:156823d33999 34 bool used_as_gpio : 1;
<> 149:156823d33999 35 PinDirection direction : 1;
<> 149:156823d33999 36 bool init_high : 1;
<> 149:156823d33999 37 PinMode pull : 2;
<> 149:156823d33999 38 bool used_as_irq : 1;
<> 149:156823d33999 39 bool irq_fall : 1;
<> 149:156823d33999 40 bool irq_rise : 1;
<> 149:156823d33999 41 } gpio_cfg_t;
<> 149:156823d33999 42
AnnaBridge 165:e614a9f1c9e2 43 #if GPIO_PIN_COUNT > 32
AnnaBridge 165:e614a9f1c9e2 44 typedef uint64_t gpio_mask_t;
AnnaBridge 165:e614a9f1c9e2 45 #else
AnnaBridge 165:e614a9f1c9e2 46 typedef uint32_t gpio_mask_t;
AnnaBridge 165:e614a9f1c9e2 47 #endif
AnnaBridge 165:e614a9f1c9e2 48
AnnaBridge 165:e614a9f1c9e2 49 static gpio_mask_t m_gpio_initialized;
AnnaBridge 165:e614a9f1c9e2 50 static gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
<> 149:156823d33999 51
<> 149:156823d33999 52
<> 149:156823d33999 53 /***********
<> 149:156823d33999 54 GPIO IRQ
<> 149:156823d33999 55 ***********/
<> 149:156823d33999 56
<> 149:156823d33999 57 static gpio_irq_handler m_irq_handler;
<> 149:156823d33999 58 static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
AnnaBridge 165:e614a9f1c9e2 59 static gpio_mask_t m_gpio_irq_enabled;
<> 149:156823d33999 60
<> 149:156823d33999 61
<> 149:156823d33999 62 static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
<> 149:156823d33999 63 {
<> 149:156823d33999 64 nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
<> 149:156823d33999 65 gpio_irq_event event = (sense == NRF_GPIO_PIN_SENSE_LOW) ? IRQ_RISE : IRQ_FALL;
<> 149:156823d33999 66
AnnaBridge 165:e614a9f1c9e2 67 if (m_gpio_irq_enabled & ((gpio_mask_t)1 << pin)) {
<> 149:156823d33999 68 if (((event == IRQ_RISE) && m_gpio_cfg[pin].irq_rise)
<> 149:156823d33999 69 || ((event == IRQ_FALL) && m_gpio_cfg[pin].irq_fall)) {
<> 149:156823d33999 70 m_irq_handler(m_channel_ids[pin], event);
<> 149:156823d33999 71 }
<> 149:156823d33999 72 }
<> 149:156823d33999 73 }
<> 149:156823d33999 74
<> 150:02e0a0aed4ec 75 void GPIOTE_IRQHandler(void);// exported from nrf_drv_gpiote.c
<> 149:156823d33999 76
<> 149:156823d33999 77 void gpio_init(gpio_t *obj, PinName pin)
<> 149:156823d33999 78 {
<> 149:156823d33999 79 obj->pin = pin;
<> 149:156823d33999 80 if (pin == (PinName)NC) {
<> 149:156823d33999 81 return;
<> 149:156823d33999 82 }
<> 149:156823d33999 83 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 150:02e0a0aed4ec 84
<> 150:02e0a0aed4ec 85 NVIC_SetVector(GPIOTE_IRQn, (uint32_t) GPIOTE_IRQHandler);
<> 150:02e0a0aed4ec 86
<> 149:156823d33999 87 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 88
<> 149:156823d33999 89 m_gpio_cfg[obj->pin].used_as_gpio = true;
<> 149:156823d33999 90 }
<> 149:156823d33999 91
AnnaBridge 165:e614a9f1c9e2 92 #ifdef TARGET_SDK11
AnnaBridge 165:e614a9f1c9e2 93 // implement polyfill of gpio hal for the nRF5 SDK v11
AnnaBridge 165:e614a9f1c9e2 94 __STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin)
AnnaBridge 165:e614a9f1c9e2 95 {
AnnaBridge 165:e614a9f1c9e2 96 return (NRF_GPIO->OUTSET & (1UL << (pin)));
AnnaBridge 165:e614a9f1c9e2 97 }
AnnaBridge 165:e614a9f1c9e2 98 #endif
<> 149:156823d33999 99
<> 149:156823d33999 100 int gpio_read(gpio_t *obj)
<> 149:156823d33999 101 {
<> 149:156823d33999 102 MBED_ASSERT(obj->pin != (PinName)NC);
<> 149:156823d33999 103 if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
AnnaBridge 165:e614a9f1c9e2 104 return (nrf_gpio_pin_out_read(obj->pin) ? 1 : 0);
<> 149:156823d33999 105 } else {
<> 149:156823d33999 106 return nrf_gpio_pin_read(obj->pin);
<> 149:156823d33999 107 }
<> 149:156823d33999 108 }
<> 149:156823d33999 109
<> 150:02e0a0aed4ec 110 static void gpiote_pin_uninit(uint8_t pin)
<> 149:156823d33999 111 {
AnnaBridge 165:e614a9f1c9e2 112 if (m_gpio_initialized & ((gpio_mask_t)1UL << pin)) {
<> 149:156823d33999 113 if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 114 nrf_drv_gpiote_out_uninit(pin);
<> 149:156823d33999 115 }
<> 149:156823d33999 116 else {
<> 149:156823d33999 117 nrf_drv_gpiote_in_uninit(pin);
<> 149:156823d33999 118 }
<> 149:156823d33999 119 }
<> 150:02e0a0aed4ec 120 }
<> 149:156823d33999 121
<> 150:02e0a0aed4ec 122 static void gpio_apply_config(uint8_t pin)
<> 150:02e0a0aed4ec 123 {
<> 149:156823d33999 124 if (m_gpio_cfg[pin].used_as_gpio || m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 125 if ((m_gpio_cfg[pin].direction == PIN_INPUT)
<> 149:156823d33999 126 || (m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 127 //Configure as input.
<> 149:156823d33999 128 nrf_drv_gpiote_in_config_t cfg;
<> 149:156823d33999 129
<> 149:156823d33999 130 cfg.hi_accuracy = false;
<> 149:156823d33999 131 cfg.is_watcher = false;
<> 149:156823d33999 132 cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE;
<> 149:156823d33999 133 if (m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 134 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 135 nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
AnnaBridge 165:e614a9f1c9e2 136 if ((m_gpio_irq_enabled & ((gpio_mask_t)1 << pin))
<> 149:156823d33999 137 && (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall))
<> 149:156823d33999 138 {
<> 149:156823d33999 139 nrf_drv_gpiote_in_event_enable(pin, true);
<> 149:156823d33999 140 }
<> 149:156823d33999 141 }
<> 149:156823d33999 142 else {
<> 149:156823d33999 143 switch(m_gpio_cfg[pin].pull) {
<> 149:156823d33999 144 case PullUp:
<> 149:156823d33999 145 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 146 break;
<> 149:156823d33999 147 case PullDown:
<> 149:156823d33999 148 cfg.pull = NRF_GPIO_PIN_PULLDOWN;
<> 149:156823d33999 149 break;
<> 149:156823d33999 150 default:
<> 149:156823d33999 151 cfg.pull = NRF_GPIO_PIN_NOPULL;
<> 149:156823d33999 152 break;
<> 149:156823d33999 153 }
<> 149:156823d33999 154 nrf_drv_gpiote_in_init(pin, &cfg, NULL);
<> 149:156823d33999 155 }
<> 149:156823d33999 156 }
<> 149:156823d33999 157 else {
<> 149:156823d33999 158 // Configure as output.
<> 149:156823d33999 159 nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(m_gpio_cfg[pin].init_high);
<> 149:156823d33999 160 nrf_drv_gpiote_out_init(pin, &cfg);
<> 149:156823d33999 161 }
AnnaBridge 165:e614a9f1c9e2 162 m_gpio_initialized |= ((gpio_mask_t)1UL << pin);
<> 149:156823d33999 163 }
<> 149:156823d33999 164 else {
AnnaBridge 165:e614a9f1c9e2 165 m_gpio_initialized &= ~((gpio_mask_t)1UL << pin);
<> 149:156823d33999 166 }
<> 149:156823d33999 167 }
<> 149:156823d33999 168
<> 149:156823d33999 169
<> 149:156823d33999 170 void gpio_mode(gpio_t *obj, PinMode mode)
<> 149:156823d33999 171 {
AnnaBridge 165:e614a9f1c9e2 172 MBED_ASSERT(obj->pin != (PinName)NC);
<> 150:02e0a0aed4ec 173
<> 150:02e0a0aed4ec 174 gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 175
<> 149:156823d33999 176 m_gpio_cfg[obj->pin].pull = mode;
<> 149:156823d33999 177 gpio_apply_config(obj->pin);
<> 149:156823d33999 178 }
<> 149:156823d33999 179
<> 149:156823d33999 180
<> 149:156823d33999 181 void gpio_dir(gpio_t *obj, PinDirection direction)
<> 149:156823d33999 182 {
AnnaBridge 165:e614a9f1c9e2 183 MBED_ASSERT(obj->pin != (PinName)NC);
<> 150:02e0a0aed4ec 184
<> 150:02e0a0aed4ec 185 gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 186
<> 149:156823d33999 187 m_gpio_cfg[obj->pin].direction = direction;
<> 149:156823d33999 188 gpio_apply_config(obj->pin);
<> 149:156823d33999 189 }
<> 149:156823d33999 190
<> 149:156823d33999 191
<> 149:156823d33999 192 /***********
<> 149:156823d33999 193 GPIO IRQ
<> 149:156823d33999 194 ***********/
<> 149:156823d33999 195
<> 149:156823d33999 196 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
<> 149:156823d33999 197 {
<> 149:156823d33999 198 if (pin == NC) {
<> 149:156823d33999 199 return -1;
<> 149:156823d33999 200 }
<> 149:156823d33999 201 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 149:156823d33999 202 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 203
<> 150:02e0a0aed4ec 204 gpiote_pin_uninit(pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 205
<> 149:156823d33999 206 m_gpio_cfg[pin].used_as_irq = true;
<> 149:156823d33999 207 m_channel_ids[pin] = id;
<> 149:156823d33999 208 obj->ch = pin;
<> 149:156823d33999 209 m_irq_handler = handler;
<> 149:156823d33999 210 m_channel_ids[pin] = id;
<> 149:156823d33999 211
<> 149:156823d33999 212 gpio_apply_config(pin);
<> 149:156823d33999 213 return 1;
<> 149:156823d33999 214 }
<> 149:156823d33999 215
<> 149:156823d33999 216
<> 149:156823d33999 217 void gpio_irq_free(gpio_irq_t *obj)
<> 149:156823d33999 218 {
<> 149:156823d33999 219 nrf_drv_gpiote_in_uninit(obj->ch);
<> 149:156823d33999 220 m_gpio_cfg[obj->ch].used_as_irq = false;
<> 149:156823d33999 221 m_channel_ids[obj->ch] = 0;
<> 149:156823d33999 222
<> 149:156823d33999 223 gpio_apply_config(obj->ch);
<> 149:156823d33999 224 }
<> 149:156823d33999 225
<> 149:156823d33999 226
<> 149:156823d33999 227 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
<> 149:156823d33999 228 {
<> 149:156823d33999 229 gpio_cfg_t* cfg = &m_gpio_cfg[obj->ch];
<> 149:156823d33999 230 bool irq_enabled_before =
AnnaBridge 165:e614a9f1c9e2 231 (m_gpio_irq_enabled & ((gpio_mask_t)1 << obj->ch)) &&
<> 149:156823d33999 232 (cfg->irq_rise || cfg->irq_fall);
<> 149:156823d33999 233
<> 149:156823d33999 234 if (event == IRQ_RISE) {
<> 149:156823d33999 235 cfg->irq_rise = enable ? true : false;
<> 149:156823d33999 236 }
<> 149:156823d33999 237 else if (event == IRQ_FALL) {
<> 149:156823d33999 238 cfg->irq_fall = enable ? true : false;
<> 149:156823d33999 239 }
<> 149:156823d33999 240
<> 149:156823d33999 241 bool irq_enabled_after = cfg->irq_rise || cfg->irq_fall;
<> 149:156823d33999 242
<> 149:156823d33999 243 if (irq_enabled_before != irq_enabled_after) {
<> 149:156823d33999 244 if (irq_enabled_after) {
<> 149:156823d33999 245 gpio_irq_enable(obj);
<> 149:156823d33999 246 } else {
<> 149:156823d33999 247 gpio_irq_disable(obj);
<> 149:156823d33999 248 }
<> 149:156823d33999 249 }
<> 149:156823d33999 250 }
<> 149:156823d33999 251
<> 149:156823d33999 252
<> 149:156823d33999 253 void gpio_irq_enable(gpio_irq_t *obj)
<> 149:156823d33999 254 {
AnnaBridge 165:e614a9f1c9e2 255 m_gpio_irq_enabled |= ((gpio_mask_t)1 << obj->ch);
<> 149:156823d33999 256 if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
<> 149:156823d33999 257 nrf_drv_gpiote_in_event_enable(obj->ch, true);
<> 149:156823d33999 258 }
<> 149:156823d33999 259 }
<> 149:156823d33999 260
<> 149:156823d33999 261
<> 149:156823d33999 262 void gpio_irq_disable(gpio_irq_t *obj)
<> 149:156823d33999 263 {
AnnaBridge 165:e614a9f1c9e2 264 m_gpio_irq_enabled &= ~((gpio_mask_t)1 << obj->ch);
<> 149:156823d33999 265 nrf_drv_gpiote_in_event_disable(obj->ch);
<> 149:156823d33999 266 }