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 #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
