Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
SerialBase.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "SerialBase.h" 00017 #include "wait_api.h" 00018 00019 #if DEVICE_SERIAL 00020 00021 namespace mbed { 00022 00023 SerialBase::SerialBase(PinName tx, PinName rx) : 00024 #if DEVICE_SERIAL_ASYNCH 00025 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), 00026 _rx_usage(DMA_USAGE_NEVER), 00027 #endif 00028 _serial(), _baud(9600) { 00029 serial_init(&_serial, tx, rx); 00030 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this); 00031 } 00032 00033 void SerialBase::baud(int baudrate) { 00034 serial_baud(&_serial, baudrate); 00035 _baud = baudrate; 00036 } 00037 00038 void SerialBase::format(int bits, Parity parity, int stop_bits) { 00039 serial_format(&_serial, bits, (SerialParity)parity, stop_bits); 00040 } 00041 00042 int SerialBase::readable() { 00043 return serial_readable(&_serial); 00044 } 00045 00046 00047 int SerialBase::writeable() { 00048 return serial_writable(&_serial); 00049 } 00050 00051 void SerialBase::attach(void (*fptr)(void), IrqType type) { 00052 if (fptr) { 00053 _irq[type].attach(fptr); 00054 serial_irq_set(&_serial, (SerialIrq)type, 1); 00055 } else { 00056 serial_irq_set(&_serial, (SerialIrq)type, 0); 00057 } 00058 } 00059 00060 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { 00061 SerialBase *handler = (SerialBase*)id; 00062 handler->_irq[irq_type].call(); 00063 } 00064 00065 int SerialBase::_base_getc() { 00066 return serial_getc(&_serial); 00067 } 00068 00069 int SerialBase::_base_putc(int c) { 00070 serial_putc(&_serial, c); 00071 return c; 00072 } 00073 00074 void SerialBase::send_break() { 00075 // Wait for 1.5 frames before clearing the break condition 00076 // This will have different effects on our platforms, but should 00077 // ensure that we keep the break active for at least one frame. 00078 // We consider a full frame (1 start bit + 8 data bits bits + 00079 // 1 parity bit + 2 stop bits = 12 bits) for computation. 00080 // One bit time (in us) = 1000000/_baud 00081 // Twelve bits: 12000000/baud delay 00082 // 1.5 frames: 18000000/baud delay 00083 serial_break_set(&_serial); 00084 wait_us(18000000/_baud); 00085 serial_break_clear(&_serial); 00086 } 00087 00088 #if DEVICE_SERIAL_FC 00089 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) { 00090 FlowControl flow_type = (FlowControl)type; 00091 switch(type) { 00092 case RTS: 00093 serial_set_flow_control(&_serial, flow_type, flow1, NC); 00094 break; 00095 00096 case CTS: 00097 serial_set_flow_control(&_serial, flow_type, NC, flow1); 00098 break; 00099 00100 case RTSCTS: 00101 case Disabled: 00102 serial_set_flow_control(&_serial, flow_type, flow1, flow2); 00103 break; 00104 00105 default: 00106 break; 00107 } 00108 } 00109 #endif 00110 00111 #if DEVICE_SERIAL_ASYNCH 00112 00113 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t & callback, int event) 00114 { 00115 if (serial_tx_active(&_serial)) { 00116 return -1; // transaction ongoing 00117 } 00118 start_write((void *)buffer, length, 8, callback, event); 00119 return 0; 00120 } 00121 00122 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t & callback, int event) 00123 { 00124 if (serial_tx_active(&_serial)) { 00125 return -1; // transaction ongoing 00126 } 00127 start_write((void *)buffer, length, 16, callback, event); 00128 return 0; 00129 } 00130 00131 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t & callback, int event) 00132 { 00133 _tx_callback = callback; 00134 00135 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00136 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); 00137 } 00138 00139 void SerialBase::abort_write(void) 00140 { 00141 serial_tx_abort_asynch(&_serial); 00142 } 00143 00144 void SerialBase::abort_read(void) 00145 { 00146 serial_rx_abort_asynch(&_serial); 00147 } 00148 00149 int SerialBase::set_dma_usage_tx(DMAUsage usage) 00150 { 00151 if (serial_tx_active(&_serial)) { 00152 return -1; 00153 } 00154 _tx_usage = usage; 00155 return 0; 00156 } 00157 00158 int SerialBase::set_dma_usage_rx(DMAUsage usage) 00159 { 00160 if (serial_tx_active(&_serial)) { 00161 return -1; 00162 } 00163 _rx_usage = usage; 00164 return 0; 00165 } 00166 00167 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t & callback, int event, unsigned char char_match) 00168 { 00169 if (serial_rx_active(&_serial)) { 00170 return -1; // transaction ongoing 00171 } 00172 start_read((void*)buffer, length, 8, callback, event, char_match); 00173 return 0; 00174 } 00175 00176 00177 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t & callback, int event, unsigned char char_match) 00178 { 00179 if (serial_rx_active(&_serial)) { 00180 return -1; // transaction ongoing 00181 } 00182 start_read((void*)buffer, length, 16, callback, event, char_match); 00183 return 0; 00184 } 00185 00186 00187 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t & callback, int event, unsigned char char_match) 00188 { 00189 _rx_callback = callback; 00190 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00191 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); 00192 } 00193 00194 void SerialBase::interrupt_handler_asynch(void) 00195 { 00196 int event = serial_irq_handler_asynch(&_serial); 00197 int rx_event = event & SERIAL_EVENT_RX_MASK; 00198 if (_rx_callback && rx_event) { 00199 _rx_callback.call(rx_event); 00200 } 00201 00202 int tx_event = event & SERIAL_EVENT_TX_MASK; 00203 if (_tx_callback && tx_event) { 00204 _tx_callback.call(tx_event); 00205 } 00206 } 00207 00208 #endif 00209 00210 } // namespace mbed 00211 00212 #endif
Generated on Tue Jul 12 2022 18:56:14 by
