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