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.
BufferedSerial.cpp
00001 /** 00002 * @file BufferedSerial.cpp 00003 * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX 00004 * @author sam grove 00005 * @version 1.0 00006 * @see 00007 * 00008 * Copyright (c) 2013 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 #include "BufferedSerial.h" 00024 #include <stdarg.h> 00025 00026 BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name) 00027 : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size)) 00028 { 00029 RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq); 00030 this->_buf_size = buf_size; 00031 this->_tx_multiple = tx_multiple; 00032 return; 00033 } 00034 00035 BufferedSerial::~BufferedSerial(void) 00036 { 00037 RawSerial::attach(NULL, RawSerial::RxIrq); 00038 RawSerial::attach(NULL, RawSerial::TxIrq); 00039 00040 return; 00041 } 00042 00043 int BufferedSerial::readable(void) 00044 { 00045 return _rxbuf.available(); // note: look if things are in the buffer 00046 } 00047 00048 int BufferedSerial::writeable(void) 00049 { 00050 return 1; // buffer allows overwriting by design, always true 00051 } 00052 00053 int BufferedSerial::getc(void) 00054 { 00055 return _rxbuf; 00056 } 00057 00058 int BufferedSerial::putc(int c) 00059 { 00060 _txbuf = (char)c; 00061 BufferedSerial::prime(); 00062 00063 return c; 00064 } 00065 00066 int BufferedSerial::puts(const char *s) 00067 { 00068 if (s != NULL) { 00069 const char* ptr = s; 00070 00071 while(*(ptr) != 0) { 00072 _txbuf = *(ptr++); 00073 } 00074 _txbuf = '\n'; // done per puts definition 00075 BufferedSerial::prime(); 00076 00077 return (ptr - s) + 1; 00078 } 00079 return 0; 00080 } 00081 00082 int BufferedSerial::printf(const char* format, ...) 00083 { 00084 char buffer[this->_buf_size]; 00085 memset(buffer,0,this->_buf_size); 00086 int r = 0; 00087 00088 va_list arg; 00089 va_start(arg, format); 00090 r = vsprintf(buffer, format, arg); 00091 // this may not hit the heap but should alert the user anyways 00092 if(r > this->_buf_size) { 00093 error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r); 00094 va_end(arg); 00095 return 0; 00096 } 00097 va_end(arg); 00098 r = BufferedSerial::write(buffer, r); 00099 00100 return r; 00101 } 00102 00103 ssize_t BufferedSerial::write(const void *s, size_t length) 00104 { 00105 if (s != NULL && length > 0) { 00106 const char* ptr = (const char*)s; 00107 const char* end = ptr + length; 00108 00109 while (ptr != end) { 00110 _txbuf = *(ptr++); 00111 } 00112 BufferedSerial::prime(); 00113 00114 return ptr - (const char*)s; 00115 } 00116 return 0; 00117 } 00118 00119 00120 void BufferedSerial::rxIrq(void) 00121 { 00122 // read from the peripheral and make sure something is available 00123 if(serial_readable(&_serial)) { 00124 _rxbuf = serial_getc(&_serial); // if so load them into a buffer 00125 } 00126 00127 return; 00128 } 00129 00130 void BufferedSerial::txIrq(void) 00131 { 00132 // see if there is room in the hardware fifo and if something is in the software fifo 00133 while(serial_writable(&_serial)) { 00134 if(_txbuf.available()) { 00135 serial_putc(&_serial, (int)_txbuf.get()); 00136 } else { 00137 // disable the TX interrupt when there is nothing left to send 00138 RawSerial::attach(NULL, RawSerial::TxIrq); 00139 break; 00140 } 00141 } 00142 00143 return; 00144 } 00145 00146 void BufferedSerial::prime(void) 00147 { 00148 // if already busy then the irq will pick this up 00149 if(serial_writable(&_serial)) { 00150 RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq 00151 BufferedSerial::txIrq(); // only write to hardware in one place 00152 RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq); 00153 } 00154 00155 return; 00156 } 00157 00158
Generated on Thu Jul 14 2022 10:09:22 by
