mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
funshine
Date:
Sat Apr 08 17:03:55 2017 +0000
Revision:
162:16168a1438f3
Parent:
150:02e0a0aed4ec
add code to handle serial port rx error in uart_irq()

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
<> 150:02e0a0aed4ec 65 void GPIOTE_IRQHandler(void);// exported from nrf_drv_gpiote.c
<> 149:156823d33999 66
<> 149:156823d33999 67 void gpio_init(gpio_t *obj, PinName pin)
<> 149:156823d33999 68 {
<> 149:156823d33999 69 obj->pin = pin;
<> 149:156823d33999 70 if (pin == (PinName)NC) {
<> 149:156823d33999 71 return;
<> 149:156823d33999 72 }
<> 149:156823d33999 73 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 150:02e0a0aed4ec 74
<> 150:02e0a0aed4ec 75 NVIC_SetVector(GPIOTE_IRQn, (uint32_t) GPIOTE_IRQHandler);
<> 150:02e0a0aed4ec 76
<> 149:156823d33999 77 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 78
<> 149:156823d33999 79 m_gpio_cfg[obj->pin].used_as_gpio = true;
<> 149:156823d33999 80 }
<> 149:156823d33999 81
<> 149:156823d33999 82
<> 149:156823d33999 83 int gpio_read(gpio_t *obj)
<> 149:156823d33999 84 {
<> 149:156823d33999 85 MBED_ASSERT(obj->pin != (PinName)NC);
<> 149:156823d33999 86 if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
<> 149:156823d33999 87 return ((NRF_GPIO->OUTSET & (1UL << obj->pin)) ? 1 : 0);
<> 149:156823d33999 88 } else {
<> 149:156823d33999 89 return nrf_gpio_pin_read(obj->pin);
<> 149:156823d33999 90 }
<> 149:156823d33999 91 }
<> 149:156823d33999 92
<> 150:02e0a0aed4ec 93 static void gpiote_pin_uninit(uint8_t pin)
<> 149:156823d33999 94 {
<> 149:156823d33999 95 if (m_gpio_initialized & (1UL << pin)) {
<> 149:156823d33999 96 if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 97 nrf_drv_gpiote_out_uninit(pin);
<> 149:156823d33999 98 }
<> 149:156823d33999 99 else {
<> 149:156823d33999 100 nrf_drv_gpiote_in_uninit(pin);
<> 149:156823d33999 101 }
<> 149:156823d33999 102 }
<> 150:02e0a0aed4ec 103 }
<> 149:156823d33999 104
<> 150:02e0a0aed4ec 105 static void gpio_apply_config(uint8_t pin)
<> 150:02e0a0aed4ec 106 {
<> 149:156823d33999 107 if (m_gpio_cfg[pin].used_as_gpio || m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 108 if ((m_gpio_cfg[pin].direction == PIN_INPUT)
<> 149:156823d33999 109 || (m_gpio_cfg[pin].used_as_irq)) {
<> 149:156823d33999 110 //Configure as input.
<> 149:156823d33999 111 nrf_drv_gpiote_in_config_t cfg;
<> 149:156823d33999 112
<> 149:156823d33999 113 cfg.hi_accuracy = false;
<> 149:156823d33999 114 cfg.is_watcher = false;
<> 149:156823d33999 115 cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE;
<> 149:156823d33999 116 if (m_gpio_cfg[pin].used_as_irq) {
<> 149:156823d33999 117 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 118 nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
<> 149:156823d33999 119 if ((m_gpio_irq_enabled & (1 << pin))
<> 149:156823d33999 120 && (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall))
<> 149:156823d33999 121 {
<> 149:156823d33999 122 nrf_drv_gpiote_in_event_enable(pin, true);
<> 149:156823d33999 123 }
<> 149:156823d33999 124 }
<> 149:156823d33999 125 else {
<> 149:156823d33999 126 switch(m_gpio_cfg[pin].pull) {
<> 149:156823d33999 127 case PullUp:
<> 149:156823d33999 128 cfg.pull = NRF_GPIO_PIN_PULLUP;
<> 149:156823d33999 129 break;
<> 149:156823d33999 130 case PullDown:
<> 149:156823d33999 131 cfg.pull = NRF_GPIO_PIN_PULLDOWN;
<> 149:156823d33999 132 break;
<> 149:156823d33999 133 default:
<> 149:156823d33999 134 cfg.pull = NRF_GPIO_PIN_NOPULL;
<> 149:156823d33999 135 break;
<> 149:156823d33999 136 }
<> 149:156823d33999 137 nrf_drv_gpiote_in_init(pin, &cfg, NULL);
<> 149:156823d33999 138 }
<> 149:156823d33999 139 }
<> 149:156823d33999 140 else {
<> 149:156823d33999 141 // Configure as output.
<> 149:156823d33999 142 nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(m_gpio_cfg[pin].init_high);
<> 149:156823d33999 143 nrf_drv_gpiote_out_init(pin, &cfg);
<> 149:156823d33999 144 }
<> 149:156823d33999 145 m_gpio_initialized |= (1UL << pin);
<> 149:156823d33999 146 }
<> 149:156823d33999 147 else {
<> 149:156823d33999 148 m_gpio_initialized &= ~(1UL << pin);
<> 149:156823d33999 149 }
<> 149:156823d33999 150 }
<> 149:156823d33999 151
<> 149:156823d33999 152
<> 149:156823d33999 153 void gpio_mode(gpio_t *obj, PinMode mode)
<> 149:156823d33999 154 {
<> 149:156823d33999 155 MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
<> 150:02e0a0aed4ec 156
<> 150:02e0a0aed4ec 157 gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 158
<> 149:156823d33999 159 m_gpio_cfg[obj->pin].pull = mode;
<> 149:156823d33999 160 gpio_apply_config(obj->pin);
<> 149:156823d33999 161 }
<> 149:156823d33999 162
<> 149:156823d33999 163
<> 149:156823d33999 164 void gpio_dir(gpio_t *obj, PinDirection direction)
<> 149:156823d33999 165 {
<> 149:156823d33999 166 MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
<> 150:02e0a0aed4ec 167
<> 150:02e0a0aed4ec 168 gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 169
<> 149:156823d33999 170 m_gpio_cfg[obj->pin].direction = direction;
<> 149:156823d33999 171 gpio_apply_config(obj->pin);
<> 149:156823d33999 172 }
<> 149:156823d33999 173
<> 149:156823d33999 174
<> 149:156823d33999 175 /***********
<> 149:156823d33999 176 GPIO IRQ
<> 149:156823d33999 177 ***********/
<> 149:156823d33999 178
<> 149:156823d33999 179 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
<> 149:156823d33999 180 {
<> 149:156823d33999 181 if (pin == NC) {
<> 149:156823d33999 182 return -1;
<> 149:156823d33999 183 }
<> 149:156823d33999 184 MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
<> 149:156823d33999 185 (void) nrf_drv_gpiote_init();
<> 149:156823d33999 186
<> 150:02e0a0aed4ec 187 gpiote_pin_uninit(pin); // try to uninitialize gpio before a change.
<> 150:02e0a0aed4ec 188
<> 149:156823d33999 189 m_gpio_cfg[pin].used_as_irq = true;
<> 149:156823d33999 190 m_channel_ids[pin] = id;
<> 149:156823d33999 191 obj->ch = pin;
<> 149:156823d33999 192 m_irq_handler = handler;
<> 149:156823d33999 193 m_channel_ids[pin] = id;
<> 149:156823d33999 194
<> 149:156823d33999 195 gpio_apply_config(pin);
<> 149:156823d33999 196 return 1;
<> 149:156823d33999 197 }
<> 149:156823d33999 198
<> 149:156823d33999 199
<> 149:156823d33999 200 void gpio_irq_free(gpio_irq_t *obj)
<> 149:156823d33999 201 {
<> 149:156823d33999 202 nrf_drv_gpiote_in_uninit(obj->ch);
<> 149:156823d33999 203 m_gpio_cfg[obj->ch].used_as_irq = false;
<> 149:156823d33999 204 m_channel_ids[obj->ch] = 0;
<> 149:156823d33999 205
<> 149:156823d33999 206 gpio_apply_config(obj->ch);
<> 149:156823d33999 207 }
<> 149:156823d33999 208
<> 149:156823d33999 209
<> 149:156823d33999 210 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
<> 149:156823d33999 211 {
<> 149:156823d33999 212 gpio_cfg_t* cfg = &m_gpio_cfg[obj->ch];
<> 149:156823d33999 213 bool irq_enabled_before =
<> 149:156823d33999 214 (m_gpio_irq_enabled & (1 << obj->ch)) &&
<> 149:156823d33999 215 (cfg->irq_rise || cfg->irq_fall);
<> 149:156823d33999 216
<> 149:156823d33999 217 if (event == IRQ_RISE) {
<> 149:156823d33999 218 cfg->irq_rise = enable ? true : false;
<> 149:156823d33999 219 }
<> 149:156823d33999 220 else if (event == IRQ_FALL) {
<> 149:156823d33999 221 cfg->irq_fall = enable ? true : false;
<> 149:156823d33999 222 }
<> 149:156823d33999 223
<> 149:156823d33999 224 bool irq_enabled_after = cfg->irq_rise || cfg->irq_fall;
<> 149:156823d33999 225
<> 149:156823d33999 226 if (irq_enabled_before != irq_enabled_after) {
<> 149:156823d33999 227 if (irq_enabled_after) {
<> 149:156823d33999 228 gpio_irq_enable(obj);
<> 149:156823d33999 229 } else {
<> 149:156823d33999 230 gpio_irq_disable(obj);
<> 149:156823d33999 231 }
<> 149:156823d33999 232 }
<> 149:156823d33999 233 }
<> 149:156823d33999 234
<> 149:156823d33999 235
<> 149:156823d33999 236 void gpio_irq_enable(gpio_irq_t *obj)
<> 149:156823d33999 237 {
<> 149:156823d33999 238 m_gpio_irq_enabled |= (1 << obj->ch);
<> 149:156823d33999 239 if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
<> 149:156823d33999 240 nrf_drv_gpiote_in_event_enable(obj->ch, true);
<> 149:156823d33999 241 }
<> 149:156823d33999 242 }
<> 149:156823d33999 243
<> 149:156823d33999 244
<> 149:156823d33999 245 void gpio_irq_disable(gpio_irq_t *obj)
<> 149:156823d33999 246 {
<> 149:156823d33999 247 m_gpio_irq_enabled &= ~(1 << obj->ch);
<> 149:156823d33999 248 nrf_drv_gpiote_in_event_disable(obj->ch);
<> 149:156823d33999 249 }