Leon Wehmeier / Mbed OS fiasco_max32630

Dependencies:   SoftSerial MAX14690 Buffer

Fork of rtos_threading_with_callback by mbed_example

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, 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     //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     //printf("destructor buffered serial\r\n");
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 int BufferedSerial::putc(int c)
00060 {
00061     _txbuf = (char)c;
00062     BufferedSerial::prime();
00063 
00064     return c;
00065 }
00066 
00067 int BufferedSerial::puts(const char *s)
00068 {
00069     if (s != NULL) {
00070         const char* ptr = s;
00071     
00072         while(*(ptr) != 0) {
00073             _txbuf = *(ptr++);
00074         }
00075         _txbuf = '\n';  // done per puts definition
00076         BufferedSerial::prime();
00077     
00078         return (ptr - s) + 1;
00079     }
00080     return 0;
00081 }
00082 
00083 int BufferedSerial::printf(const char* format, ...)
00084 {
00085     char buffer[this->_buf_size];
00086     memset(buffer,0,this->_buf_size);
00087     int r = 0;
00088 
00089     va_list arg;
00090     va_start(arg, format);
00091     r = vsprintf(buffer, format, arg);
00092     // this may not hit the heap but should alert the user anyways
00093     if(r > this->_buf_size) {
00094         error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
00095         va_end(arg);
00096         return 0;
00097     }
00098     va_end(arg);
00099     r = BufferedSerial::write(buffer, r);
00100 
00101     return r;
00102 }
00103 
00104 ssize_t BufferedSerial::write(const void *s, size_t length)
00105 {
00106     if (s != NULL && length > 0) {
00107         const char* ptr = (const char*)s;
00108         const char* end = ptr + length;
00109     
00110         while (ptr != end) {
00111             _txbuf = *(ptr++);
00112         }
00113         BufferedSerial::prime();
00114     
00115         return ptr - (const char*)s;
00116     }
00117     return 0;
00118 }
00119 
00120 
00121 void BufferedSerial::rxIrq(void)
00122 {
00123     //printf("rx\r\n");
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     //printf("prime\r\n");
00151     // if already busy then the irq will pick this up
00152     if(serial_writable(&_serial)) {
00153         RawSerial::attach(NULL, RawSerial::TxIrq);    // make sure not to cause contention in the irq
00154         BufferedSerial::txIrq();                // only write to hardware in one place
00155         RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
00156     }
00157 
00158     return;
00159 }
00160 
00161