mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

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