Includes library modifications to allow access to AIN_4 (AIN_0 / 5)

Committer:
bryantaylor
Date:
Tue Sep 20 21:26:12 2016 +0000
Revision:
0:eafc3fd41f75
hackathon

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bryantaylor 0:eafc3fd41f75 1 /* mbed Microcontroller Library
bryantaylor 0:eafc3fd41f75 2 * Copyright (c) 2006-2013 ARM Limited
bryantaylor 0:eafc3fd41f75 3 *
bryantaylor 0:eafc3fd41f75 4 * Licensed under the Apache License, Version 2.0 (the "License");
bryantaylor 0:eafc3fd41f75 5 * you may not use this file except in compliance with the License.
bryantaylor 0:eafc3fd41f75 6 * You may obtain a copy of the License at
bryantaylor 0:eafc3fd41f75 7 *
bryantaylor 0:eafc3fd41f75 8 * http://www.apache.org/licenses/LICENSE-2.0
bryantaylor 0:eafc3fd41f75 9 *
bryantaylor 0:eafc3fd41f75 10 * Unless required by applicable law or agreed to in writing, software
bryantaylor 0:eafc3fd41f75 11 * distributed under the License is distributed on an "AS IS" BASIS,
bryantaylor 0:eafc3fd41f75 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bryantaylor 0:eafc3fd41f75 13 * See the License for the specific language governing permissions and
bryantaylor 0:eafc3fd41f75 14 * limitations under the License.
bryantaylor 0:eafc3fd41f75 15 */
bryantaylor 0:eafc3fd41f75 16 #include "SerialBase.h"
bryantaylor 0:eafc3fd41f75 17 #include "wait_api.h"
bryantaylor 0:eafc3fd41f75 18 #include "critical.h"
bryantaylor 0:eafc3fd41f75 19
bryantaylor 0:eafc3fd41f75 20 #if DEVICE_SERIAL
bryantaylor 0:eafc3fd41f75 21
bryantaylor 0:eafc3fd41f75 22 namespace mbed {
bryantaylor 0:eafc3fd41f75 23
bryantaylor 0:eafc3fd41f75 24 static void donothing() {};
bryantaylor 0:eafc3fd41f75 25
bryantaylor 0:eafc3fd41f75 26 SerialBase::SerialBase(PinName tx, PinName rx) :
bryantaylor 0:eafc3fd41f75 27 #if DEVICE_SERIAL_ASYNCH
bryantaylor 0:eafc3fd41f75 28 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
bryantaylor 0:eafc3fd41f75 29 _rx_usage(DMA_USAGE_NEVER),
bryantaylor 0:eafc3fd41f75 30 #endif
bryantaylor 0:eafc3fd41f75 31 _serial(), _baud(9600) {
bryantaylor 0:eafc3fd41f75 32 // No lock needed in the constructor
bryantaylor 0:eafc3fd41f75 33
bryantaylor 0:eafc3fd41f75 34 for (int i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
bryantaylor 0:eafc3fd41f75 35 _irq[i].attach(donothing);
bryantaylor 0:eafc3fd41f75 36 }
bryantaylor 0:eafc3fd41f75 37
bryantaylor 0:eafc3fd41f75 38 serial_init(&_serial, tx, rx);
bryantaylor 0:eafc3fd41f75 39 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
bryantaylor 0:eafc3fd41f75 40 }
bryantaylor 0:eafc3fd41f75 41
bryantaylor 0:eafc3fd41f75 42 void SerialBase::baud(int baudrate) {
bryantaylor 0:eafc3fd41f75 43 lock();
bryantaylor 0:eafc3fd41f75 44 serial_baud(&_serial, baudrate);
bryantaylor 0:eafc3fd41f75 45 _baud = baudrate;
bryantaylor 0:eafc3fd41f75 46 unlock();
bryantaylor 0:eafc3fd41f75 47 }
bryantaylor 0:eafc3fd41f75 48
bryantaylor 0:eafc3fd41f75 49 void SerialBase::format(int bits, Parity parity, int stop_bits) {
bryantaylor 0:eafc3fd41f75 50 lock();
bryantaylor 0:eafc3fd41f75 51 serial_format(&_serial, bits, (SerialParity)parity, stop_bits);
bryantaylor 0:eafc3fd41f75 52 unlock();
bryantaylor 0:eafc3fd41f75 53 }
bryantaylor 0:eafc3fd41f75 54
bryantaylor 0:eafc3fd41f75 55 int SerialBase::readable() {
bryantaylor 0:eafc3fd41f75 56 lock();
bryantaylor 0:eafc3fd41f75 57 int ret = serial_readable(&_serial);
bryantaylor 0:eafc3fd41f75 58 unlock();
bryantaylor 0:eafc3fd41f75 59 return ret;
bryantaylor 0:eafc3fd41f75 60 }
bryantaylor 0:eafc3fd41f75 61
bryantaylor 0:eafc3fd41f75 62
bryantaylor 0:eafc3fd41f75 63 int SerialBase::writeable() {
bryantaylor 0:eafc3fd41f75 64 lock();
bryantaylor 0:eafc3fd41f75 65 int ret = serial_writable(&_serial);
bryantaylor 0:eafc3fd41f75 66 unlock();
bryantaylor 0:eafc3fd41f75 67 return ret;
bryantaylor 0:eafc3fd41f75 68 }
bryantaylor 0:eafc3fd41f75 69
bryantaylor 0:eafc3fd41f75 70 void SerialBase::attach(Callback<void()> func, IrqType type) {
bryantaylor 0:eafc3fd41f75 71 lock();
bryantaylor 0:eafc3fd41f75 72 // Disable interrupts when attaching interrupt handler
bryantaylor 0:eafc3fd41f75 73 core_util_critical_section_enter();
bryantaylor 0:eafc3fd41f75 74 if (func) {
bryantaylor 0:eafc3fd41f75 75 _irq[type].attach(func);
bryantaylor 0:eafc3fd41f75 76 serial_irq_set(&_serial, (SerialIrq)type, 1);
bryantaylor 0:eafc3fd41f75 77 } else {
bryantaylor 0:eafc3fd41f75 78 _irq[type].attach(donothing);
bryantaylor 0:eafc3fd41f75 79 serial_irq_set(&_serial, (SerialIrq)type, 0);
bryantaylor 0:eafc3fd41f75 80 }
bryantaylor 0:eafc3fd41f75 81 core_util_critical_section_exit();
bryantaylor 0:eafc3fd41f75 82 unlock();
bryantaylor 0:eafc3fd41f75 83 }
bryantaylor 0:eafc3fd41f75 84
bryantaylor 0:eafc3fd41f75 85 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) {
bryantaylor 0:eafc3fd41f75 86 SerialBase *handler = (SerialBase*)id;
bryantaylor 0:eafc3fd41f75 87 handler->_irq[irq_type].call();
bryantaylor 0:eafc3fd41f75 88 }
bryantaylor 0:eafc3fd41f75 89
bryantaylor 0:eafc3fd41f75 90 int SerialBase::_base_getc() {
bryantaylor 0:eafc3fd41f75 91 // Mutex is already held
bryantaylor 0:eafc3fd41f75 92 return serial_getc(&_serial);
bryantaylor 0:eafc3fd41f75 93 }
bryantaylor 0:eafc3fd41f75 94
bryantaylor 0:eafc3fd41f75 95 int SerialBase::_base_putc(int c) {
bryantaylor 0:eafc3fd41f75 96 // Mutex is already held
bryantaylor 0:eafc3fd41f75 97 serial_putc(&_serial, c);
bryantaylor 0:eafc3fd41f75 98 return c;
bryantaylor 0:eafc3fd41f75 99 }
bryantaylor 0:eafc3fd41f75 100
bryantaylor 0:eafc3fd41f75 101 void SerialBase::send_break() {
bryantaylor 0:eafc3fd41f75 102 lock();
bryantaylor 0:eafc3fd41f75 103 // Wait for 1.5 frames before clearing the break condition
bryantaylor 0:eafc3fd41f75 104 // This will have different effects on our platforms, but should
bryantaylor 0:eafc3fd41f75 105 // ensure that we keep the break active for at least one frame.
bryantaylor 0:eafc3fd41f75 106 // We consider a full frame (1 start bit + 8 data bits bits +
bryantaylor 0:eafc3fd41f75 107 // 1 parity bit + 2 stop bits = 12 bits) for computation.
bryantaylor 0:eafc3fd41f75 108 // One bit time (in us) = 1000000/_baud
bryantaylor 0:eafc3fd41f75 109 // Twelve bits: 12000000/baud delay
bryantaylor 0:eafc3fd41f75 110 // 1.5 frames: 18000000/baud delay
bryantaylor 0:eafc3fd41f75 111 serial_break_set(&_serial);
bryantaylor 0:eafc3fd41f75 112 wait_us(18000000/_baud);
bryantaylor 0:eafc3fd41f75 113 serial_break_clear(&_serial);
bryantaylor 0:eafc3fd41f75 114 unlock();
bryantaylor 0:eafc3fd41f75 115 }
bryantaylor 0:eafc3fd41f75 116
bryantaylor 0:eafc3fd41f75 117 void SerialBase::lock() {
bryantaylor 0:eafc3fd41f75 118 // Stub
bryantaylor 0:eafc3fd41f75 119 }
bryantaylor 0:eafc3fd41f75 120
bryantaylor 0:eafc3fd41f75 121 void SerialBase:: unlock() {
bryantaylor 0:eafc3fd41f75 122 // Stub
bryantaylor 0:eafc3fd41f75 123 }
bryantaylor 0:eafc3fd41f75 124
bryantaylor 0:eafc3fd41f75 125 #if DEVICE_SERIAL_FC
bryantaylor 0:eafc3fd41f75 126 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) {
bryantaylor 0:eafc3fd41f75 127 lock();
bryantaylor 0:eafc3fd41f75 128 FlowControl flow_type = (FlowControl)type;
bryantaylor 0:eafc3fd41f75 129 switch(type) {
bryantaylor 0:eafc3fd41f75 130 case RTS:
bryantaylor 0:eafc3fd41f75 131 serial_set_flow_control(&_serial, flow_type, flow1, NC);
bryantaylor 0:eafc3fd41f75 132 break;
bryantaylor 0:eafc3fd41f75 133
bryantaylor 0:eafc3fd41f75 134 case CTS:
bryantaylor 0:eafc3fd41f75 135 serial_set_flow_control(&_serial, flow_type, NC, flow1);
bryantaylor 0:eafc3fd41f75 136 break;
bryantaylor 0:eafc3fd41f75 137
bryantaylor 0:eafc3fd41f75 138 case RTSCTS:
bryantaylor 0:eafc3fd41f75 139 case Disabled:
bryantaylor 0:eafc3fd41f75 140 serial_set_flow_control(&_serial, flow_type, flow1, flow2);
bryantaylor 0:eafc3fd41f75 141 break;
bryantaylor 0:eafc3fd41f75 142
bryantaylor 0:eafc3fd41f75 143 default:
bryantaylor 0:eafc3fd41f75 144 break;
bryantaylor 0:eafc3fd41f75 145 }
bryantaylor 0:eafc3fd41f75 146 unlock();
bryantaylor 0:eafc3fd41f75 147 }
bryantaylor 0:eafc3fd41f75 148 #endif
bryantaylor 0:eafc3fd41f75 149
bryantaylor 0:eafc3fd41f75 150 #if DEVICE_SERIAL_ASYNCH
bryantaylor 0:eafc3fd41f75 151
bryantaylor 0:eafc3fd41f75 152 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event)
bryantaylor 0:eafc3fd41f75 153 {
bryantaylor 0:eafc3fd41f75 154 if (serial_tx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 155 return -1; // transaction ongoing
bryantaylor 0:eafc3fd41f75 156 }
bryantaylor 0:eafc3fd41f75 157 start_write((void *)buffer, length, 8, callback, event);
bryantaylor 0:eafc3fd41f75 158 return 0;
bryantaylor 0:eafc3fd41f75 159 }
bryantaylor 0:eafc3fd41f75 160
bryantaylor 0:eafc3fd41f75 161 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event)
bryantaylor 0:eafc3fd41f75 162 {
bryantaylor 0:eafc3fd41f75 163 if (serial_tx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 164 return -1; // transaction ongoing
bryantaylor 0:eafc3fd41f75 165 }
bryantaylor 0:eafc3fd41f75 166 start_write((void *)buffer, length, 16, callback, event);
bryantaylor 0:eafc3fd41f75 167 return 0;
bryantaylor 0:eafc3fd41f75 168 }
bryantaylor 0:eafc3fd41f75 169
bryantaylor 0:eafc3fd41f75 170 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event)
bryantaylor 0:eafc3fd41f75 171 {
bryantaylor 0:eafc3fd41f75 172 _tx_callback = callback;
bryantaylor 0:eafc3fd41f75 173
bryantaylor 0:eafc3fd41f75 174 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
bryantaylor 0:eafc3fd41f75 175 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage);
bryantaylor 0:eafc3fd41f75 176 }
bryantaylor 0:eafc3fd41f75 177
bryantaylor 0:eafc3fd41f75 178 void SerialBase::abort_write(void)
bryantaylor 0:eafc3fd41f75 179 {
bryantaylor 0:eafc3fd41f75 180 serial_tx_abort_asynch(&_serial);
bryantaylor 0:eafc3fd41f75 181 }
bryantaylor 0:eafc3fd41f75 182
bryantaylor 0:eafc3fd41f75 183 void SerialBase::abort_read(void)
bryantaylor 0:eafc3fd41f75 184 {
bryantaylor 0:eafc3fd41f75 185 serial_rx_abort_asynch(&_serial);
bryantaylor 0:eafc3fd41f75 186 }
bryantaylor 0:eafc3fd41f75 187
bryantaylor 0:eafc3fd41f75 188 int SerialBase::set_dma_usage_tx(DMAUsage usage)
bryantaylor 0:eafc3fd41f75 189 {
bryantaylor 0:eafc3fd41f75 190 if (serial_tx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 191 return -1;
bryantaylor 0:eafc3fd41f75 192 }
bryantaylor 0:eafc3fd41f75 193 _tx_usage = usage;
bryantaylor 0:eafc3fd41f75 194 return 0;
bryantaylor 0:eafc3fd41f75 195 }
bryantaylor 0:eafc3fd41f75 196
bryantaylor 0:eafc3fd41f75 197 int SerialBase::set_dma_usage_rx(DMAUsage usage)
bryantaylor 0:eafc3fd41f75 198 {
bryantaylor 0:eafc3fd41f75 199 if (serial_tx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 200 return -1;
bryantaylor 0:eafc3fd41f75 201 }
bryantaylor 0:eafc3fd41f75 202 _rx_usage = usage;
bryantaylor 0:eafc3fd41f75 203 return 0;
bryantaylor 0:eafc3fd41f75 204 }
bryantaylor 0:eafc3fd41f75 205
bryantaylor 0:eafc3fd41f75 206 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
bryantaylor 0:eafc3fd41f75 207 {
bryantaylor 0:eafc3fd41f75 208 if (serial_rx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 209 return -1; // transaction ongoing
bryantaylor 0:eafc3fd41f75 210 }
bryantaylor 0:eafc3fd41f75 211 start_read((void*)buffer, length, 8, callback, event, char_match);
bryantaylor 0:eafc3fd41f75 212 return 0;
bryantaylor 0:eafc3fd41f75 213 }
bryantaylor 0:eafc3fd41f75 214
bryantaylor 0:eafc3fd41f75 215
bryantaylor 0:eafc3fd41f75 216 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
bryantaylor 0:eafc3fd41f75 217 {
bryantaylor 0:eafc3fd41f75 218 if (serial_rx_active(&_serial)) {
bryantaylor 0:eafc3fd41f75 219 return -1; // transaction ongoing
bryantaylor 0:eafc3fd41f75 220 }
bryantaylor 0:eafc3fd41f75 221 start_read((void*)buffer, length, 16, callback, event, char_match);
bryantaylor 0:eafc3fd41f75 222 return 0;
bryantaylor 0:eafc3fd41f75 223 }
bryantaylor 0:eafc3fd41f75 224
bryantaylor 0:eafc3fd41f75 225
bryantaylor 0:eafc3fd41f75 226 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match)
bryantaylor 0:eafc3fd41f75 227 {
bryantaylor 0:eafc3fd41f75 228 _rx_callback = callback;
bryantaylor 0:eafc3fd41f75 229 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
bryantaylor 0:eafc3fd41f75 230 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage);
bryantaylor 0:eafc3fd41f75 231 }
bryantaylor 0:eafc3fd41f75 232
bryantaylor 0:eafc3fd41f75 233 void SerialBase::interrupt_handler_asynch(void)
bryantaylor 0:eafc3fd41f75 234 {
bryantaylor 0:eafc3fd41f75 235 int event = serial_irq_handler_asynch(&_serial);
bryantaylor 0:eafc3fd41f75 236 int rx_event = event & SERIAL_EVENT_RX_MASK;
bryantaylor 0:eafc3fd41f75 237 if (_rx_callback && rx_event) {
bryantaylor 0:eafc3fd41f75 238 _rx_callback.call(rx_event);
bryantaylor 0:eafc3fd41f75 239 }
bryantaylor 0:eafc3fd41f75 240
bryantaylor 0:eafc3fd41f75 241 int tx_event = event & SERIAL_EVENT_TX_MASK;
bryantaylor 0:eafc3fd41f75 242 if (_tx_callback && tx_event) {
bryantaylor 0:eafc3fd41f75 243 _tx_callback.call(tx_event);
bryantaylor 0:eafc3fd41f75 244 }
bryantaylor 0:eafc3fd41f75 245 }
bryantaylor 0:eafc3fd41f75 246
bryantaylor 0:eafc3fd41f75 247 #endif
bryantaylor 0:eafc3fd41f75 248
bryantaylor 0:eafc3fd41f75 249 } // namespace mbed
bryantaylor 0:eafc3fd41f75 250
bryantaylor 0:eafc3fd41f75 251 #endif