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 BufferedSerial by
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 00036 00037 BufferedSerial::~BufferedSerial(void) 00038 { 00039 RawSerial::attach(NULL, RawSerial::RxIrq); 00040 RawSerial::attach(NULL, RawSerial::TxIrq); 00041 00042 return; 00043 } 00044 00045 int BufferedSerial::readable(void) 00046 { 00047 return _rxbuf.available(); // note: look if things are in the buffer 00048 } 00049 00050 int BufferedSerial::writeable(void) 00051 { 00052 return 1; // buffer allows overwriting by design, always true 00053 } 00054 00055 int BufferedSerial::getc(void) 00056 { 00057 return _rxbuf; 00058 } 00059 00060 int BufferedSerial::putc(int c) 00061 { 00062 _txbuf = (char)c; 00063 BufferedSerial::prime(); 00064 00065 return c; 00066 } 00067 00068 int BufferedSerial::puts(const char *s) 00069 { 00070 if (s != NULL) { 00071 const char* ptr = s; 00072 00073 while(*(ptr) != 0) { 00074 _txbuf = *(ptr++); 00075 } 00076 _txbuf = '\n'; // done per puts definition 00077 BufferedSerial::prime(); 00078 00079 return (ptr - s) + 1; 00080 } 00081 return 0; 00082 } 00083 00084 int BufferedSerial::printf(const char* format, ...) 00085 { 00086 char buffer[this->_buf_size]; 00087 memset(buffer,0,this->_buf_size); 00088 int r = 0; 00089 00090 va_list arg; 00091 va_start(arg, format); 00092 r = vsprintf(buffer, format, arg); 00093 // this may not hit the heap but should alert the user anyways 00094 if(r > this->_buf_size) { 00095 error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r); 00096 va_end(arg); 00097 return 0; 00098 } 00099 va_end(arg); 00100 r = BufferedSerial::write(buffer, r); 00101 00102 return r; 00103 } 00104 00105 ssize_t BufferedSerial::write(const void *s, size_t length) 00106 { 00107 if (s != NULL && length > 0) { 00108 const char* ptr = (const char*)s; 00109 const char* end = ptr + length; 00110 00111 while (ptr != end) { 00112 _txbuf = *(ptr++); 00113 } 00114 BufferedSerial::prime(); 00115 00116 return ptr - (const char*)s; 00117 } 00118 return 0; 00119 } 00120 00121 00122 void BufferedSerial::rxIrq(void) 00123 { 00124 // read from the peripheral and make sure something is available 00125 if(serial_readable(&_serial)) { 00126 _rxbuf = serial_getc(&_serial); // if so load them into a buffer 00127 } 00128 00129 return; 00130 } 00131 00132 void BufferedSerial::txIrq(void) 00133 { 00134 // see if there is room in the hardware fifo and if something is in the software fifo 00135 while(serial_writable(&_serial)) { 00136 if(_txbuf.available()) { 00137 serial_putc(&_serial, (int)_txbuf.get()); 00138 } else { 00139 // disable the TX interrupt when there is nothing left to send 00140 RawSerial::attach(NULL, RawSerial::TxIrq); 00141 break; 00142 } 00143 } 00144 00145 return; 00146 } 00147 00148 void BufferedSerial::prime(void) 00149 { 00150 // if already busy then the irq will pick this up 00151 if(serial_writable(&_serial)) { 00152 RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq 00153 BufferedSerial::txIrq(); // only write to hardware in one place 00154 RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq); 00155 } 00156 00157 return; 00158 } 00159 00160
Generated on Sun Jul 17 2022 01:33:34 by
1.7.2
