mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 1:9db0e321a9f4 1 /* mbed Microcontroller Library
kenjiArai 1:9db0e321a9f4 2 * Copyright (c) 2006-2013 ARM Limited
kenjiArai 1:9db0e321a9f4 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 1:9db0e321a9f4 4 *
kenjiArai 1:9db0e321a9f4 5 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 1:9db0e321a9f4 6 * you may not use this file except in compliance with the License.
kenjiArai 1:9db0e321a9f4 7 * You may obtain a copy of the License at
kenjiArai 1:9db0e321a9f4 8 *
kenjiArai 1:9db0e321a9f4 9 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 1:9db0e321a9f4 10 *
kenjiArai 1:9db0e321a9f4 11 * Unless required by applicable law or agreed to in writing, software
kenjiArai 1:9db0e321a9f4 12 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 1:9db0e321a9f4 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 1:9db0e321a9f4 14 * See the License for the specific language governing permissions and
kenjiArai 1:9db0e321a9f4 15 * limitations under the License.
kenjiArai 1:9db0e321a9f4 16 */
kenjiArai 1:9db0e321a9f4 17 #include "drivers/SerialBase.h"
kenjiArai 1:9db0e321a9f4 18 #include "platform/mbed_wait_api.h"
kenjiArai 1:9db0e321a9f4 19 #include "platform/mbed_critical.h"
kenjiArai 1:9db0e321a9f4 20 #include "platform/mbed_power_mgmt.h"
kenjiArai 1:9db0e321a9f4 21
kenjiArai 1:9db0e321a9f4 22 #if DEVICE_SERIAL
kenjiArai 1:9db0e321a9f4 23
kenjiArai 1:9db0e321a9f4 24 namespace mbed {
kenjiArai 1:9db0e321a9f4 25
kenjiArai 1:9db0e321a9f4 26 SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
kenjiArai 1:9db0e321a9f4 27 #if DEVICE_SERIAL_ASYNCH
kenjiArai 1:9db0e321a9f4 28 _thunk_irq(this),
kenjiArai 1:9db0e321a9f4 29 #endif
kenjiArai 1:9db0e321a9f4 30 _baud(baud),
kenjiArai 1:9db0e321a9f4 31 _tx_pin(tx),
kenjiArai 1:9db0e321a9f4 32 _rx_pin(rx),
kenjiArai 1:9db0e321a9f4 33 _init_func(&SerialBase::_init)
kenjiArai 1:9db0e321a9f4 34 {
kenjiArai 1:9db0e321a9f4 35 // No lock needed in the constructor
kenjiArai 1:9db0e321a9f4 36
kenjiArai 1:9db0e321a9f4 37 for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
kenjiArai 1:9db0e321a9f4 38 _irq[i] = NULL;
kenjiArai 1:9db0e321a9f4 39 }
kenjiArai 1:9db0e321a9f4 40
kenjiArai 1:9db0e321a9f4 41 (this->*_init_func)();
kenjiArai 1:9db0e321a9f4 42 }
kenjiArai 1:9db0e321a9f4 43
kenjiArai 1:9db0e321a9f4 44 SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
kenjiArai 1:9db0e321a9f4 45 #if DEVICE_SERIAL_ASYNCH
kenjiArai 1:9db0e321a9f4 46 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
kenjiArai 1:9db0e321a9f4 47 _rx_usage(DMA_USAGE_NEVER), _tx_callback(NULL),
kenjiArai 1:9db0e321a9f4 48 _rx_callback(NULL), _tx_asynch_set(false),
kenjiArai 1:9db0e321a9f4 49 _rx_asynch_set(false),
kenjiArai 1:9db0e321a9f4 50 #endif
kenjiArai 1:9db0e321a9f4 51 _serial(),
kenjiArai 1:9db0e321a9f4 52 _baud(baud),
kenjiArai 1:9db0e321a9f4 53 _tx_pin(static_pinmap.tx_pin),
kenjiArai 1:9db0e321a9f4 54 _rx_pin(static_pinmap.rx_pin),
kenjiArai 1:9db0e321a9f4 55 _static_pinmap(&static_pinmap),
kenjiArai 1:9db0e321a9f4 56 _init_func(&SerialBase::_init_direct)
kenjiArai 1:9db0e321a9f4 57 {
kenjiArai 1:9db0e321a9f4 58 // No lock needed in the constructor
kenjiArai 1:9db0e321a9f4 59
kenjiArai 1:9db0e321a9f4 60 for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
kenjiArai 1:9db0e321a9f4 61 _irq[i] = NULL;
kenjiArai 1:9db0e321a9f4 62 }
kenjiArai 1:9db0e321a9f4 63
kenjiArai 1:9db0e321a9f4 64 (this->*_init_func)();
kenjiArai 1:9db0e321a9f4 65 }
kenjiArai 1:9db0e321a9f4 66
kenjiArai 1:9db0e321a9f4 67 void SerialBase::baud(int baudrate)
kenjiArai 1:9db0e321a9f4 68 {
kenjiArai 1:9db0e321a9f4 69 lock();
kenjiArai 1:9db0e321a9f4 70 serial_baud(&_serial, baudrate);
kenjiArai 1:9db0e321a9f4 71 _baud = baudrate;
kenjiArai 1:9db0e321a9f4 72 unlock();
kenjiArai 1:9db0e321a9f4 73 }
kenjiArai 1:9db0e321a9f4 74
kenjiArai 1:9db0e321a9f4 75 void SerialBase::format(int bits, Parity parity, int stop_bits)
kenjiArai 1:9db0e321a9f4 76 {
kenjiArai 1:9db0e321a9f4 77 lock();
kenjiArai 1:9db0e321a9f4 78 serial_format(&_serial, bits, (SerialParity)parity, stop_bits);
kenjiArai 1:9db0e321a9f4 79 unlock();
kenjiArai 1:9db0e321a9f4 80 }
kenjiArai 1:9db0e321a9f4 81
kenjiArai 1:9db0e321a9f4 82 int SerialBase::readable()
kenjiArai 1:9db0e321a9f4 83 {
kenjiArai 1:9db0e321a9f4 84 lock();
kenjiArai 1:9db0e321a9f4 85 int ret = serial_readable(&_serial);
kenjiArai 1:9db0e321a9f4 86 unlock();
kenjiArai 1:9db0e321a9f4 87 return ret;
kenjiArai 1:9db0e321a9f4 88 }
kenjiArai 1:9db0e321a9f4 89
kenjiArai 1:9db0e321a9f4 90
kenjiArai 1:9db0e321a9f4 91 int SerialBase::writeable()
kenjiArai 1:9db0e321a9f4 92 {
kenjiArai 1:9db0e321a9f4 93 lock();
kenjiArai 1:9db0e321a9f4 94 int ret = serial_writable(&_serial);
kenjiArai 1:9db0e321a9f4 95 unlock();
kenjiArai 1:9db0e321a9f4 96 return ret;
kenjiArai 1:9db0e321a9f4 97 }
kenjiArai 1:9db0e321a9f4 98
kenjiArai 1:9db0e321a9f4 99 void SerialBase::attach(Callback<void()> func, IrqType type)
kenjiArai 1:9db0e321a9f4 100 {
kenjiArai 1:9db0e321a9f4 101 lock();
kenjiArai 1:9db0e321a9f4 102 const bool enabled { (_rx_enabled &&(type == RxIrq)) || (_tx_enabled &&(type == TxIrq)) };
kenjiArai 1:9db0e321a9f4 103 // If corresponding direction is not enabled only update the handler
kenjiArai 1:9db0e321a9f4 104 if (!enabled) {
kenjiArai 1:9db0e321a9f4 105 _irq[type] = func;
kenjiArai 1:9db0e321a9f4 106 } else {
kenjiArai 1:9db0e321a9f4 107 // Disable interrupts when attaching interrupt handler
kenjiArai 1:9db0e321a9f4 108 core_util_critical_section_enter();
kenjiArai 1:9db0e321a9f4 109 if (func) {
kenjiArai 1:9db0e321a9f4 110 // lock deep sleep only the first time
kenjiArai 1:9db0e321a9f4 111 if (!_irq[type]) {
kenjiArai 1:9db0e321a9f4 112 sleep_manager_lock_deep_sleep();
kenjiArai 1:9db0e321a9f4 113 }
kenjiArai 1:9db0e321a9f4 114 _irq[type] = func;
kenjiArai 1:9db0e321a9f4 115 serial_irq_set(&_serial, (SerialIrq)type, 1);
kenjiArai 1:9db0e321a9f4 116 } else {
kenjiArai 1:9db0e321a9f4 117 // unlock deep sleep only the first time
kenjiArai 1:9db0e321a9f4 118 if (_irq[type]) {
kenjiArai 1:9db0e321a9f4 119 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 120 }
kenjiArai 1:9db0e321a9f4 121 _irq[type] = NULL;
kenjiArai 1:9db0e321a9f4 122 serial_irq_set(&_serial, (SerialIrq)type, 0);
kenjiArai 1:9db0e321a9f4 123 }
kenjiArai 1:9db0e321a9f4 124 core_util_critical_section_exit();
kenjiArai 1:9db0e321a9f4 125 }
kenjiArai 1:9db0e321a9f4 126 unlock();
kenjiArai 1:9db0e321a9f4 127 }
kenjiArai 1:9db0e321a9f4 128
kenjiArai 1:9db0e321a9f4 129 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type)
kenjiArai 1:9db0e321a9f4 130 {
kenjiArai 1:9db0e321a9f4 131 SerialBase *handler = (SerialBase *)id;
kenjiArai 1:9db0e321a9f4 132 if (handler->_irq[irq_type]) {
kenjiArai 1:9db0e321a9f4 133 handler->_irq[irq_type]();
kenjiArai 1:9db0e321a9f4 134 }
kenjiArai 1:9db0e321a9f4 135 }
kenjiArai 1:9db0e321a9f4 136
kenjiArai 1:9db0e321a9f4 137 int SerialBase::_base_getc()
kenjiArai 1:9db0e321a9f4 138 {
kenjiArai 1:9db0e321a9f4 139 // Mutex is already held
kenjiArai 1:9db0e321a9f4 140 return serial_getc(&_serial);
kenjiArai 1:9db0e321a9f4 141 }
kenjiArai 1:9db0e321a9f4 142
kenjiArai 1:9db0e321a9f4 143 int SerialBase::_base_putc(int c)
kenjiArai 1:9db0e321a9f4 144 {
kenjiArai 1:9db0e321a9f4 145 // Mutex is already held
kenjiArai 1:9db0e321a9f4 146 serial_putc(&_serial, c);
kenjiArai 1:9db0e321a9f4 147 return c;
kenjiArai 1:9db0e321a9f4 148 }
kenjiArai 1:9db0e321a9f4 149
kenjiArai 1:9db0e321a9f4 150 void SerialBase::_init()
kenjiArai 1:9db0e321a9f4 151 {
kenjiArai 1:9db0e321a9f4 152 serial_init(&_serial, _tx_pin, _rx_pin);
kenjiArai 1:9db0e321a9f4 153 #if DEVICE_SERIAL_FC
kenjiArai 1:9db0e321a9f4 154 if (_set_flow_control_dp_func) {
kenjiArai 1:9db0e321a9f4 155 (this->*_set_flow_control_dp_func)(_flow_type, _flow1, _flow2);
kenjiArai 1:9db0e321a9f4 156 }
kenjiArai 1:9db0e321a9f4 157 #endif
kenjiArai 1:9db0e321a9f4 158 serial_baud(&_serial, _baud);
kenjiArai 1:9db0e321a9f4 159 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
kenjiArai 1:9db0e321a9f4 160 }
kenjiArai 1:9db0e321a9f4 161
kenjiArai 1:9db0e321a9f4 162 void SerialBase::_init_direct()
kenjiArai 1:9db0e321a9f4 163 {
kenjiArai 1:9db0e321a9f4 164 serial_init_direct(&_serial, _static_pinmap);
kenjiArai 1:9db0e321a9f4 165 #if DEVICE_SERIAL_FC
kenjiArai 1:9db0e321a9f4 166 if (_static_pinmap_fc && _set_flow_control_dp_func) {
kenjiArai 1:9db0e321a9f4 167 (this->*_set_flow_control_sp_func)(_flow_type, *_static_pinmap_fc);
kenjiArai 1:9db0e321a9f4 168 }
kenjiArai 1:9db0e321a9f4 169 #endif
kenjiArai 1:9db0e321a9f4 170 serial_baud(&_serial, _baud);
kenjiArai 1:9db0e321a9f4 171 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
kenjiArai 1:9db0e321a9f4 172 }
kenjiArai 1:9db0e321a9f4 173
kenjiArai 1:9db0e321a9f4 174 void SerialBase::_deinit()
kenjiArai 1:9db0e321a9f4 175 {
kenjiArai 1:9db0e321a9f4 176 serial_free(&_serial);
kenjiArai 1:9db0e321a9f4 177 }
kenjiArai 1:9db0e321a9f4 178
kenjiArai 1:9db0e321a9f4 179 void SerialBase::enable_input(bool enable)
kenjiArai 1:9db0e321a9f4 180 {
kenjiArai 1:9db0e321a9f4 181 lock();
kenjiArai 1:9db0e321a9f4 182 if (_rx_enabled != enable) {
kenjiArai 1:9db0e321a9f4 183 if (enable && !_tx_enabled) {
kenjiArai 1:9db0e321a9f4 184 (this->*_init_func)();
kenjiArai 1:9db0e321a9f4 185 }
kenjiArai 1:9db0e321a9f4 186
kenjiArai 1:9db0e321a9f4 187 core_util_critical_section_enter();
kenjiArai 1:9db0e321a9f4 188 if (enable) {
kenjiArai 1:9db0e321a9f4 189 // Enable rx IRQ and lock deep sleep if a rx handler is attached
kenjiArai 1:9db0e321a9f4 190 // (indicated by rx IRQ callback not NULL)
kenjiArai 1:9db0e321a9f4 191 if (_irq[RxIrq]) {
kenjiArai 1:9db0e321a9f4 192 _irq[RxIrq].call();
kenjiArai 1:9db0e321a9f4 193 sleep_manager_lock_deep_sleep();
kenjiArai 1:9db0e321a9f4 194 serial_irq_set(&_serial, (SerialIrq)RxIrq, 1);
kenjiArai 1:9db0e321a9f4 195 }
kenjiArai 1:9db0e321a9f4 196 } else {
kenjiArai 1:9db0e321a9f4 197 // Disable rx IRQ
kenjiArai 1:9db0e321a9f4 198 serial_irq_set(&_serial, (SerialIrq)RxIrq, 0);
kenjiArai 1:9db0e321a9f4 199 // Unlock deep sleep if a rx handler is attached
kenjiArai 1:9db0e321a9f4 200 // (indicated by rx IRQ callback not NULL)
kenjiArai 1:9db0e321a9f4 201 if (_irq[RxIrq]) {
kenjiArai 1:9db0e321a9f4 202 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 203 }
kenjiArai 1:9db0e321a9f4 204 }
kenjiArai 1:9db0e321a9f4 205 core_util_critical_section_exit();
kenjiArai 1:9db0e321a9f4 206
kenjiArai 1:9db0e321a9f4 207 _rx_enabled = enable;
kenjiArai 1:9db0e321a9f4 208
kenjiArai 1:9db0e321a9f4 209 if (!enable && !_tx_enabled) {
kenjiArai 1:9db0e321a9f4 210 _deinit();
kenjiArai 1:9db0e321a9f4 211 }
kenjiArai 1:9db0e321a9f4 212 }
kenjiArai 1:9db0e321a9f4 213 unlock();
kenjiArai 1:9db0e321a9f4 214 }
kenjiArai 1:9db0e321a9f4 215
kenjiArai 1:9db0e321a9f4 216 void SerialBase::enable_output(bool enable)
kenjiArai 1:9db0e321a9f4 217 {
kenjiArai 1:9db0e321a9f4 218 lock();
kenjiArai 1:9db0e321a9f4 219 if (_tx_enabled != enable) {
kenjiArai 1:9db0e321a9f4 220 if (enable && !_rx_enabled) {
kenjiArai 1:9db0e321a9f4 221 (this->*_init_func)();
kenjiArai 1:9db0e321a9f4 222 }
kenjiArai 1:9db0e321a9f4 223
kenjiArai 1:9db0e321a9f4 224 core_util_critical_section_enter();
kenjiArai 1:9db0e321a9f4 225 if (enable) {
kenjiArai 1:9db0e321a9f4 226 // Enable tx IRQ and lock deep sleep if a tx handler is attached
kenjiArai 1:9db0e321a9f4 227 // (indicated by tx IRQ callback not NULL)
kenjiArai 1:9db0e321a9f4 228 if (_irq[TxIrq]) {
kenjiArai 1:9db0e321a9f4 229 _irq[TxIrq].call();
kenjiArai 1:9db0e321a9f4 230 sleep_manager_lock_deep_sleep();
kenjiArai 1:9db0e321a9f4 231 serial_irq_set(&_serial, (SerialIrq)TxIrq, 1);
kenjiArai 1:9db0e321a9f4 232 }
kenjiArai 1:9db0e321a9f4 233 } else {
kenjiArai 1:9db0e321a9f4 234 // Disable tx IRQ
kenjiArai 1:9db0e321a9f4 235 serial_irq_set(&_serial, (SerialIrq)TxIrq, 0);
kenjiArai 1:9db0e321a9f4 236 // Unlock deep sleep if a tx handler is attached
kenjiArai 1:9db0e321a9f4 237 // (indicated by tx IRQ callback not NULL)
kenjiArai 1:9db0e321a9f4 238 if (_irq[TxIrq]) {
kenjiArai 1:9db0e321a9f4 239 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 240 }
kenjiArai 1:9db0e321a9f4 241 }
kenjiArai 1:9db0e321a9f4 242 core_util_critical_section_exit();
kenjiArai 1:9db0e321a9f4 243
kenjiArai 1:9db0e321a9f4 244 _tx_enabled = enable;
kenjiArai 1:9db0e321a9f4 245
kenjiArai 1:9db0e321a9f4 246 if (!enable && !_rx_enabled) {
kenjiArai 1:9db0e321a9f4 247 _deinit();
kenjiArai 1:9db0e321a9f4 248 }
kenjiArai 1:9db0e321a9f4 249 }
kenjiArai 1:9db0e321a9f4 250 unlock();
kenjiArai 1:9db0e321a9f4 251 }
kenjiArai 1:9db0e321a9f4 252
kenjiArai 1:9db0e321a9f4 253 void SerialBase::set_break()
kenjiArai 1:9db0e321a9f4 254 {
kenjiArai 1:9db0e321a9f4 255 lock();
kenjiArai 1:9db0e321a9f4 256 serial_break_set(&_serial);
kenjiArai 1:9db0e321a9f4 257 unlock();
kenjiArai 1:9db0e321a9f4 258 }
kenjiArai 1:9db0e321a9f4 259
kenjiArai 1:9db0e321a9f4 260 void SerialBase::clear_break()
kenjiArai 1:9db0e321a9f4 261 {
kenjiArai 1:9db0e321a9f4 262 lock();
kenjiArai 1:9db0e321a9f4 263 serial_break_clear(&_serial);
kenjiArai 1:9db0e321a9f4 264 unlock();
kenjiArai 1:9db0e321a9f4 265 }
kenjiArai 1:9db0e321a9f4 266
kenjiArai 1:9db0e321a9f4 267 void SerialBase::send_break()
kenjiArai 1:9db0e321a9f4 268 {
kenjiArai 1:9db0e321a9f4 269 lock();
kenjiArai 1:9db0e321a9f4 270 // Wait for 1.5 frames before clearing the break condition
kenjiArai 1:9db0e321a9f4 271 // This will have different effects on our platforms, but should
kenjiArai 1:9db0e321a9f4 272 // ensure that we keep the break active for at least one frame.
kenjiArai 1:9db0e321a9f4 273 // We consider a full frame (1 start bit + 8 data bits bits +
kenjiArai 1:9db0e321a9f4 274 // 1 parity bit + 2 stop bits = 12 bits) for computation.
kenjiArai 1:9db0e321a9f4 275 // One bit time (in us) = 1000000/_baud
kenjiArai 1:9db0e321a9f4 276 // Twelve bits: 12000000/baud delay
kenjiArai 1:9db0e321a9f4 277 // 1.5 frames: 18000000/baud delay
kenjiArai 1:9db0e321a9f4 278 serial_break_set(&_serial);
kenjiArai 1:9db0e321a9f4 279 wait_us(18000000 / _baud);
kenjiArai 1:9db0e321a9f4 280 serial_break_clear(&_serial);
kenjiArai 1:9db0e321a9f4 281 unlock();
kenjiArai 1:9db0e321a9f4 282 }
kenjiArai 1:9db0e321a9f4 283
kenjiArai 1:9db0e321a9f4 284 void SerialBase::lock()
kenjiArai 1:9db0e321a9f4 285 {
kenjiArai 1:9db0e321a9f4 286 // Stub
kenjiArai 1:9db0e321a9f4 287 }
kenjiArai 1:9db0e321a9f4 288
kenjiArai 1:9db0e321a9f4 289 void SerialBase:: unlock()
kenjiArai 1:9db0e321a9f4 290 {
kenjiArai 1:9db0e321a9f4 291 // Stub
kenjiArai 1:9db0e321a9f4 292 }
kenjiArai 1:9db0e321a9f4 293
kenjiArai 1:9db0e321a9f4 294 SerialBase::~SerialBase()
kenjiArai 1:9db0e321a9f4 295 {
kenjiArai 1:9db0e321a9f4 296 // No lock needed in destructor
kenjiArai 1:9db0e321a9f4 297
kenjiArai 1:9db0e321a9f4 298 // Detaching interrupts releases the sleep lock if it was locked
kenjiArai 1:9db0e321a9f4 299 for (int irq = 0; irq < IrqCnt; irq++) {
kenjiArai 1:9db0e321a9f4 300 attach(NULL, (IrqType)irq);
kenjiArai 1:9db0e321a9f4 301 }
kenjiArai 1:9db0e321a9f4 302 }
kenjiArai 1:9db0e321a9f4 303
kenjiArai 1:9db0e321a9f4 304 #if DEVICE_SERIAL_FC
kenjiArai 1:9db0e321a9f4 305 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2)
kenjiArai 1:9db0e321a9f4 306 {
kenjiArai 1:9db0e321a9f4 307 MBED_ASSERT(_static_pinmap == NULL); // this function must be used when serial object has been created using dynamic pin-map constructor
kenjiArai 1:9db0e321a9f4 308 _set_flow_control_dp_func = &SerialBase::set_flow_control;
kenjiArai 1:9db0e321a9f4 309 lock();
kenjiArai 1:9db0e321a9f4 310
kenjiArai 1:9db0e321a9f4 311 _flow_type = type;
kenjiArai 1:9db0e321a9f4 312 _flow1 = flow1;
kenjiArai 1:9db0e321a9f4 313 _flow2 = flow2;
kenjiArai 1:9db0e321a9f4 314
kenjiArai 1:9db0e321a9f4 315 FlowControl flow_type = (FlowControl)type;
kenjiArai 1:9db0e321a9f4 316 switch (type) {
kenjiArai 1:9db0e321a9f4 317 case RTS:
kenjiArai 1:9db0e321a9f4 318 serial_set_flow_control(&_serial, flow_type, flow1, NC);
kenjiArai 1:9db0e321a9f4 319 break;
kenjiArai 1:9db0e321a9f4 320
kenjiArai 1:9db0e321a9f4 321 case CTS:
kenjiArai 1:9db0e321a9f4 322 serial_set_flow_control(&_serial, flow_type, NC, flow1);
kenjiArai 1:9db0e321a9f4 323 break;
kenjiArai 1:9db0e321a9f4 324
kenjiArai 1:9db0e321a9f4 325 case RTSCTS:
kenjiArai 1:9db0e321a9f4 326 case Disabled:
kenjiArai 1:9db0e321a9f4 327 serial_set_flow_control(&_serial, flow_type, flow1, flow2);
kenjiArai 1:9db0e321a9f4 328 break;
kenjiArai 1:9db0e321a9f4 329
kenjiArai 1:9db0e321a9f4 330 default:
kenjiArai 1:9db0e321a9f4 331 break;
kenjiArai 1:9db0e321a9f4 332 }
kenjiArai 1:9db0e321a9f4 333 unlock();
kenjiArai 1:9db0e321a9f4 334 }
kenjiArai 1:9db0e321a9f4 335
kenjiArai 1:9db0e321a9f4 336 void SerialBase::set_flow_control(Flow type, const serial_fc_pinmap_t &static_pinmap)
kenjiArai 1:9db0e321a9f4 337 {
kenjiArai 1:9db0e321a9f4 338 MBED_ASSERT(_static_pinmap != NULL); // this function must be used when serial object has been created using static pin-map constructor
kenjiArai 1:9db0e321a9f4 339 _set_flow_control_sp_func = &SerialBase::set_flow_control;
kenjiArai 1:9db0e321a9f4 340 lock();
kenjiArai 1:9db0e321a9f4 341 _static_pinmap_fc = &static_pinmap;
kenjiArai 1:9db0e321a9f4 342 _flow_type = type;
kenjiArai 1:9db0e321a9f4 343 FlowControl flow_type = (FlowControl)type;
kenjiArai 1:9db0e321a9f4 344 serial_set_flow_control_direct(&_serial, flow_type, _static_pinmap_fc);
kenjiArai 1:9db0e321a9f4 345 unlock();
kenjiArai 1:9db0e321a9f4 346 }
kenjiArai 1:9db0e321a9f4 347 #endif
kenjiArai 1:9db0e321a9f4 348
kenjiArai 1:9db0e321a9f4 349 #if DEVICE_SERIAL_ASYNCH
kenjiArai 1:9db0e321a9f4 350
kenjiArai 1:9db0e321a9f4 351 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t &callback, int event)
kenjiArai 1:9db0e321a9f4 352 {
kenjiArai 1:9db0e321a9f4 353 int result = 0;
kenjiArai 1:9db0e321a9f4 354 lock();
kenjiArai 1:9db0e321a9f4 355 if (!serial_tx_active(&_serial) && !_tx_asynch_set) {
kenjiArai 1:9db0e321a9f4 356 start_write((void *)buffer, length, 8, callback, event);
kenjiArai 1:9db0e321a9f4 357 } else {
kenjiArai 1:9db0e321a9f4 358 result = -1; // transaction ongoing
kenjiArai 1:9db0e321a9f4 359 }
kenjiArai 1:9db0e321a9f4 360 unlock();
kenjiArai 1:9db0e321a9f4 361 return result;
kenjiArai 1:9db0e321a9f4 362 }
kenjiArai 1:9db0e321a9f4 363
kenjiArai 1:9db0e321a9f4 364 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t &callback, int event)
kenjiArai 1:9db0e321a9f4 365 {
kenjiArai 1:9db0e321a9f4 366 int result = 0;
kenjiArai 1:9db0e321a9f4 367 lock();
kenjiArai 1:9db0e321a9f4 368 if (!serial_tx_active(&_serial) && !_tx_asynch_set) {
kenjiArai 1:9db0e321a9f4 369 start_write((void *)buffer, length, 16, callback, event);
kenjiArai 1:9db0e321a9f4 370 } else {
kenjiArai 1:9db0e321a9f4 371 result = -1; // transaction ongoing
kenjiArai 1:9db0e321a9f4 372 }
kenjiArai 1:9db0e321a9f4 373 unlock();
kenjiArai 1:9db0e321a9f4 374 return result;
kenjiArai 1:9db0e321a9f4 375 }
kenjiArai 1:9db0e321a9f4 376
kenjiArai 1:9db0e321a9f4 377 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t &callback, int event)
kenjiArai 1:9db0e321a9f4 378 {
kenjiArai 1:9db0e321a9f4 379 _tx_asynch_set = true;
kenjiArai 1:9db0e321a9f4 380 _tx_callback = callback;
kenjiArai 1:9db0e321a9f4 381
kenjiArai 1:9db0e321a9f4 382 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
kenjiArai 1:9db0e321a9f4 383 sleep_manager_lock_deep_sleep();
kenjiArai 1:9db0e321a9f4 384 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage);
kenjiArai 1:9db0e321a9f4 385 }
kenjiArai 1:9db0e321a9f4 386
kenjiArai 1:9db0e321a9f4 387 void SerialBase::abort_write(void)
kenjiArai 1:9db0e321a9f4 388 {
kenjiArai 1:9db0e321a9f4 389 lock();
kenjiArai 1:9db0e321a9f4 390 core_util_critical_section_enter();
kenjiArai 1:9db0e321a9f4 391 if (_tx_asynch_set) {
kenjiArai 1:9db0e321a9f4 392 _tx_callback = NULL;
kenjiArai 1:9db0e321a9f4 393 _tx_asynch_set = false;
kenjiArai 1:9db0e321a9f4 394 serial_tx_abort_asynch(&_serial);
kenjiArai 1:9db0e321a9f4 395 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 396 }
kenjiArai 1:9db0e321a9f4 397 core_util_critical_section_exit();
kenjiArai 1:9db0e321a9f4 398 unlock();
kenjiArai 1:9db0e321a9f4 399 }
kenjiArai 1:9db0e321a9f4 400
kenjiArai 1:9db0e321a9f4 401 void SerialBase::abort_read(void)
kenjiArai 1:9db0e321a9f4 402 {
kenjiArai 1:9db0e321a9f4 403 lock();
kenjiArai 1:9db0e321a9f4 404 core_util_critical_section_enter();
kenjiArai 1:9db0e321a9f4 405 if (_rx_asynch_set) {
kenjiArai 1:9db0e321a9f4 406 _rx_callback = NULL;
kenjiArai 1:9db0e321a9f4 407 _rx_asynch_set = false;
kenjiArai 1:9db0e321a9f4 408 serial_rx_abort_asynch(&_serial);
kenjiArai 1:9db0e321a9f4 409 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 410 }
kenjiArai 1:9db0e321a9f4 411 core_util_critical_section_exit();
kenjiArai 1:9db0e321a9f4 412 unlock();
kenjiArai 1:9db0e321a9f4 413 }
kenjiArai 1:9db0e321a9f4 414
kenjiArai 1:9db0e321a9f4 415 int SerialBase::set_dma_usage_tx(DMAUsage usage)
kenjiArai 1:9db0e321a9f4 416 {
kenjiArai 1:9db0e321a9f4 417 if (serial_tx_active(&_serial)) {
kenjiArai 1:9db0e321a9f4 418 return -1;
kenjiArai 1:9db0e321a9f4 419 }
kenjiArai 1:9db0e321a9f4 420 _tx_usage = usage;
kenjiArai 1:9db0e321a9f4 421 return 0;
kenjiArai 1:9db0e321a9f4 422 }
kenjiArai 1:9db0e321a9f4 423
kenjiArai 1:9db0e321a9f4 424 int SerialBase::set_dma_usage_rx(DMAUsage usage)
kenjiArai 1:9db0e321a9f4 425 {
kenjiArai 1:9db0e321a9f4 426 if (serial_tx_active(&_serial)) {
kenjiArai 1:9db0e321a9f4 427 return -1;
kenjiArai 1:9db0e321a9f4 428 }
kenjiArai 1:9db0e321a9f4 429 _rx_usage = usage;
kenjiArai 1:9db0e321a9f4 430 return 0;
kenjiArai 1:9db0e321a9f4 431 }
kenjiArai 1:9db0e321a9f4 432
kenjiArai 1:9db0e321a9f4 433 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
kenjiArai 1:9db0e321a9f4 434 {
kenjiArai 1:9db0e321a9f4 435 int result = 0;
kenjiArai 1:9db0e321a9f4 436 lock();
kenjiArai 1:9db0e321a9f4 437 if (!serial_rx_active(&_serial) && !_rx_asynch_set) {
kenjiArai 1:9db0e321a9f4 438 start_read((void *)buffer, length, 8, callback, event, char_match);
kenjiArai 1:9db0e321a9f4 439 } else {
kenjiArai 1:9db0e321a9f4 440 result = -1; // transaction ongoing
kenjiArai 1:9db0e321a9f4 441 }
kenjiArai 1:9db0e321a9f4 442 unlock();
kenjiArai 1:9db0e321a9f4 443 return result;
kenjiArai 1:9db0e321a9f4 444 }
kenjiArai 1:9db0e321a9f4 445
kenjiArai 1:9db0e321a9f4 446
kenjiArai 1:9db0e321a9f4 447 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
kenjiArai 1:9db0e321a9f4 448 {
kenjiArai 1:9db0e321a9f4 449 int result = 0;
kenjiArai 1:9db0e321a9f4 450 lock();
kenjiArai 1:9db0e321a9f4 451 if (!serial_rx_active(&_serial) && !_rx_asynch_set) {
kenjiArai 1:9db0e321a9f4 452 start_read((void *)buffer, length, 16, callback, event, char_match);
kenjiArai 1:9db0e321a9f4 453 } else {
kenjiArai 1:9db0e321a9f4 454 result = -1; // transaction ongoing
kenjiArai 1:9db0e321a9f4 455 }
kenjiArai 1:9db0e321a9f4 456 unlock();
kenjiArai 1:9db0e321a9f4 457 return result;
kenjiArai 1:9db0e321a9f4 458 }
kenjiArai 1:9db0e321a9f4 459
kenjiArai 1:9db0e321a9f4 460
kenjiArai 1:9db0e321a9f4 461 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t &callback, int event, unsigned char char_match)
kenjiArai 1:9db0e321a9f4 462 {
kenjiArai 1:9db0e321a9f4 463 _rx_asynch_set = true;
kenjiArai 1:9db0e321a9f4 464 _rx_callback = callback;
kenjiArai 1:9db0e321a9f4 465 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
kenjiArai 1:9db0e321a9f4 466 sleep_manager_lock_deep_sleep();
kenjiArai 1:9db0e321a9f4 467 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage);
kenjiArai 1:9db0e321a9f4 468 }
kenjiArai 1:9db0e321a9f4 469
kenjiArai 1:9db0e321a9f4 470 void SerialBase::interrupt_handler_asynch(void)
kenjiArai 1:9db0e321a9f4 471 {
kenjiArai 1:9db0e321a9f4 472 int event = serial_irq_handler_asynch(&_serial);
kenjiArai 1:9db0e321a9f4 473 int rx_event = event & SERIAL_EVENT_RX_MASK;
kenjiArai 1:9db0e321a9f4 474
kenjiArai 1:9db0e321a9f4 475 if (_rx_asynch_set && rx_event) {
kenjiArai 1:9db0e321a9f4 476 event_callback_t cb = _rx_callback;
kenjiArai 1:9db0e321a9f4 477 _rx_asynch_set = false;
kenjiArai 1:9db0e321a9f4 478 _rx_callback = NULL;
kenjiArai 1:9db0e321a9f4 479 if (cb) {
kenjiArai 1:9db0e321a9f4 480 cb.call(rx_event);
kenjiArai 1:9db0e321a9f4 481 }
kenjiArai 1:9db0e321a9f4 482 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 483 }
kenjiArai 1:9db0e321a9f4 484
kenjiArai 1:9db0e321a9f4 485 int tx_event = event & SERIAL_EVENT_TX_MASK;
kenjiArai 1:9db0e321a9f4 486 if (_tx_asynch_set && tx_event) {
kenjiArai 1:9db0e321a9f4 487 event_callback_t cb = _tx_callback;
kenjiArai 1:9db0e321a9f4 488 _tx_asynch_set = false;
kenjiArai 1:9db0e321a9f4 489 _tx_callback = NULL;
kenjiArai 1:9db0e321a9f4 490 if (cb) {
kenjiArai 1:9db0e321a9f4 491 cb.call(tx_event);
kenjiArai 1:9db0e321a9f4 492 }
kenjiArai 1:9db0e321a9f4 493 sleep_manager_unlock_deep_sleep();
kenjiArai 1:9db0e321a9f4 494 }
kenjiArai 1:9db0e321a9f4 495 }
kenjiArai 1:9db0e321a9f4 496
kenjiArai 1:9db0e321a9f4 497 #endif
kenjiArai 1:9db0e321a9f4 498
kenjiArai 1:9db0e321a9f4 499 } // namespace mbed
kenjiArai 1:9db0e321a9f4 500
kenjiArai 1:9db0e321a9f4 501 #endif