Dependencies:   Buffer SoftSerial

Fork of BufferedSoftSerial by Erik -

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BufferedSoftSerial.cpp Source File

BufferedSoftSerial.cpp

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