This fork captures the mbed lib v125 for ease of integration into older projects.
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 #include "critical.h" 00019 00020 #if DEVICE_SERIAL 00021 00022 namespace mbed { 00023 00024 SerialBase::SerialBase(PinName tx, PinName rx) : 00025 #if DEVICE_SERIAL_ASYNCH 00026 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), 00027 _rx_usage(DMA_USAGE_NEVER), 00028 #endif 00029 _serial(), _baud(9600) { 00030 // No lock needed in the constructor 00031 00032 serial_init(&_serial, tx, rx); 00033 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this); 00034 } 00035 00036 void SerialBase::baud(int baudrate) { 00037 lock(); 00038 serial_baud(&_serial, baudrate); 00039 _baud = baudrate; 00040 unlock(); 00041 } 00042 00043 void SerialBase::format(int bits, Parity parity, int stop_bits) { 00044 lock(); 00045 serial_format(&_serial, bits, (SerialParity)parity, stop_bits); 00046 unlock(); 00047 } 00048 00049 int SerialBase::readable() { 00050 lock(); 00051 int ret = serial_readable(&_serial); 00052 unlock(); 00053 return ret; 00054 } 00055 00056 00057 int SerialBase::writeable() { 00058 lock(); 00059 int ret = serial_writable(&_serial); 00060 unlock(); 00061 return ret; 00062 } 00063 00064 void SerialBase::attach(Callback<void()> func, IrqType type) { 00065 lock(); 00066 // Disable interrupts when attaching interrupt handler 00067 core_util_critical_section_enter(); 00068 if (func) { 00069 _irq[type].attach(func); 00070 serial_irq_set(&_serial, (SerialIrq)type, 1); 00071 } else { 00072 serial_irq_set(&_serial, (SerialIrq)type, 0); 00073 } 00074 core_util_critical_section_exit(); 00075 unlock(); 00076 } 00077 00078 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { 00079 SerialBase *handler = (SerialBase*)id; 00080 handler->_irq[irq_type].call(); 00081 } 00082 00083 int SerialBase::_base_getc() { 00084 // Mutex is already held 00085 return serial_getc(&_serial); 00086 } 00087 00088 int SerialBase::_base_putc(int c) { 00089 // Mutex is already held 00090 serial_putc(&_serial, c); 00091 return c; 00092 } 00093 00094 void SerialBase::send_break() { 00095 lock(); 00096 // Wait for 1.5 frames before clearing the break condition 00097 // This will have different effects on our platforms, but should 00098 // ensure that we keep the break active for at least one frame. 00099 // We consider a full frame (1 start bit + 8 data bits bits + 00100 // 1 parity bit + 2 stop bits = 12 bits) for computation. 00101 // One bit time (in us) = 1000000/_baud 00102 // Twelve bits: 12000000/baud delay 00103 // 1.5 frames: 18000000/baud delay 00104 serial_break_set(&_serial); 00105 wait_us(18000000/_baud); 00106 serial_break_clear(&_serial); 00107 unlock(); 00108 } 00109 00110 void SerialBase::lock() { 00111 // Stub 00112 } 00113 00114 void SerialBase:: unlock() { 00115 // Stub 00116 } 00117 00118 #if DEVICE_SERIAL_FC 00119 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) { 00120 lock(); 00121 FlowControl flow_type = (FlowControl)type; 00122 switch(type) { 00123 case RTS: 00124 serial_set_flow_control(&_serial, flow_type, flow1, NC); 00125 break; 00126 00127 case CTS: 00128 serial_set_flow_control(&_serial, flow_type, NC, flow1); 00129 break; 00130 00131 case RTSCTS: 00132 case Disabled: 00133 serial_set_flow_control(&_serial, flow_type, flow1, flow2); 00134 break; 00135 00136 default: 00137 break; 00138 } 00139 unlock(); 00140 } 00141 #endif 00142 00143 #if DEVICE_SERIAL_ASYNCH 00144 00145 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event) 00146 { 00147 if (serial_tx_active(&_serial)) { 00148 return -1; // transaction ongoing 00149 } 00150 start_write((void *)buffer, length, 8, callback, event); 00151 return 0; 00152 } 00153 00154 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event) 00155 { 00156 if (serial_tx_active(&_serial)) { 00157 return -1; // transaction ongoing 00158 } 00159 start_write((void *)buffer, length, 16, callback, event); 00160 return 0; 00161 } 00162 00163 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event) 00164 { 00165 _tx_callback = callback; 00166 00167 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00168 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); 00169 } 00170 00171 void SerialBase::abort_write(void) 00172 { 00173 serial_tx_abort_asynch(&_serial); 00174 } 00175 00176 void SerialBase::abort_read(void) 00177 { 00178 serial_rx_abort_asynch(&_serial); 00179 } 00180 00181 int SerialBase::set_dma_usage_tx(DMAUsage usage) 00182 { 00183 if (serial_tx_active(&_serial)) { 00184 return -1; 00185 } 00186 _tx_usage = usage; 00187 return 0; 00188 } 00189 00190 int SerialBase::set_dma_usage_rx(DMAUsage usage) 00191 { 00192 if (serial_tx_active(&_serial)) { 00193 return -1; 00194 } 00195 _rx_usage = usage; 00196 return 0; 00197 } 00198 00199 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00200 { 00201 if (serial_rx_active(&_serial)) { 00202 return -1; // transaction ongoing 00203 } 00204 start_read((void*)buffer, length, 8, callback, event, char_match); 00205 return 0; 00206 } 00207 00208 00209 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00210 { 00211 if (serial_rx_active(&_serial)) { 00212 return -1; // transaction ongoing 00213 } 00214 start_read((void*)buffer, length, 16, callback, event, char_match); 00215 return 0; 00216 } 00217 00218 00219 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match) 00220 { 00221 _rx_callback = callback; 00222 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00223 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); 00224 } 00225 00226 void SerialBase::interrupt_handler_asynch(void) 00227 { 00228 int event = serial_irq_handler_asynch(&_serial); 00229 int rx_event = event & SERIAL_EVENT_RX_MASK; 00230 if (_rx_callback && rx_event) { 00231 _rx_callback.call(rx_event); 00232 } 00233 00234 int tx_event = event & SERIAL_EVENT_TX_MASK; 00235 if (_tx_callback && tx_event) { 00236 _tx_callback.call(tx_event); 00237 } 00238 } 00239 00240 #endif 00241 00242 } // namespace mbed 00243 00244 #endif
Generated on Tue Jul 12 2022 19:06:16 by 1.7.2