This fork captures the mbed lib v125 for ease of integration into older projects.

Fork of mbed-dev by mbed official

Committer:
apluscw
Date:
Fri Jul 20 21:24:42 2018 +0000
Revision:
187:92cbb9eec47b
Mbed library with source code from mbed lib v125. Posted to ease integration with some older projects.

Who changed what in which revision?

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