Changes added to reflect changes in MyBuffer which was modified to use static memory allocation.

Dependencies:   BufferStatic

Fork of BufferedSerialStatic by Goran Kecman

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BufferedSerial.cpp Source File

BufferedSerial.cpp

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