MHVLib  20111011
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_Device_TX.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Make, Hack, Void Inc
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *  * Redistributions of source code must retain the above copyright
00008  *    notice, this list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright
00010  *    notice, this list of conditions and the following disclaimer in the
00011  *    documentation and/or other materials provided with the distribution.
00012  *  * Neither the name of the Make, Hack, Void nor the
00013  *    names of its contributors may be used to endorse or promote products
00014  *    derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY
00020  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 
00029 #include <stdio.h>
00030 #include <avr/pgmspace.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <inttypes.h>
00034 
00035 #include "MHV_Device_TX.h"
00036 
00041 MHV_Device_TX::MHV_Device_TX(MHV_RingBuffer *txPointers) {
00042         _txPointers = txPointers;
00043 
00044         _currentTx.data = NULL;
00045         _currentTx.length = 0;
00046         _currentTx.completeFunction = NULL;
00047         _currentTx.progmem = false;
00048         _currentTx.isString = false;
00049 }
00050 
00055 bool MHV_Device_TX::moreTX() {
00056 // Call the completeFunction, if one is provided - allows the user to free memory, etc
00057         if (NULL != _currentTx.completeFunction) {
00058                 _currentTx.completeFunction(_currentTx.data);
00059         }
00060 
00061         if (_txPointers->consume(&_currentTx, sizeof(_currentTx))) {
00062                 _tx = NULL;
00063                 return false;
00064         }
00065 
00066         _tx = _currentTx.data;
00067 
00068         return true;
00069 }
00070 
00071 /* Can we accept another buffer?
00072  */
00073 bool MHV_Device_TX::canWrite() {
00074         return !(_txPointers->full(sizeof(MHV_TX_BUFFER)));
00075 }
00076 
00081 int MHV_Device_TX::nextCharacter() {
00082         char c = '\0';
00083 
00084         if (NULL != _tx) {
00085                 if (_currentTx.progmem) {
00086                         c = pgm_read_byte(_tx);
00087                 } else {
00088                         c = *_tx;
00089                 }
00090         }
00091 
00092         if ((_currentTx.isString && ('\0' == c)) ||
00093                         (!_currentTx.isString && (_tx == _currentTx.data + _currentTx.length))) {
00094                 if (!moreTX()) {
00095                         _tx = NULL;
00096                         _currentTx.data = NULL;
00097                         _currentTx.length = 0;
00098                         _currentTx.completeFunction = NULL;
00099                         _currentTx.progmem = false;
00100                         _currentTx.isString = false;
00101                         return -1;
00102                 }
00103 
00104                 return nextCharacter();
00105         }
00106 
00107         _tx++;
00108         return (int)c;
00109 }
00110 
00116 bool MHV_Device_TX::write_P(PGM_P buffer) {
00117         MHV_TX_BUFFER buf;
00118 
00119         if (_txPointers->full(sizeof(buf))) {
00120                 return true;
00121         }
00122 
00123         buf.data = buffer;
00124         buf.length = 0;
00125         buf.completeFunction = NULL;
00126         buf.progmem = true;
00127         buf.isString = true;
00128 
00129         _txPointers->append(&buf, sizeof(buf));
00130         if (!_tx) {
00131                 runTxBuffers();
00132         }
00133 
00134         return false;
00135 }
00136 
00142 bool MHV_Device_TX::write(const char *buffer) {
00143         MHV_TX_BUFFER buf;
00144 
00145         if (_txPointers->full(sizeof(buf))) {
00146                 return true;
00147         }
00148 
00149         buf.data = buffer;
00150         buf.length = 0;
00151         buf.completeFunction = NULL;
00152         buf.progmem = false;
00153         buf.isString = true;
00154 
00155         _txPointers->append(&buf, sizeof(buf));
00156         if (!_tx) {
00157                 runTxBuffers();
00158         }
00159 
00160         return false;
00161 }
00162 
00169 bool MHV_Device_TX::write(const char *buffer, void (*completeFunction)(const char *)) {
00170         MHV_TX_BUFFER buf;
00171 
00172         if (_txPointers->full(sizeof(buf))) {
00173                 return true;
00174         }
00175 
00176         buf.data = buffer;
00177         buf.length = 0;
00178         buf.completeFunction = completeFunction;
00179         buf.progmem = false;
00180         buf.isString = true;
00181 
00182         _txPointers->append(&buf, sizeof(buf));
00183         if (!_tx) {
00184                 runTxBuffers();
00185         }
00186 
00187         return false;
00188 }
00189 
00197 bool MHV_Device_TX::write_P(PGM_P buffer, uint16_t length) {
00198         MHV_TX_BUFFER buf;
00199 
00200         if (_txPointers->full(sizeof(buf))) {
00201                 return true;
00202         }
00203 
00204         buf.data = buffer;
00205         buf.length = length;
00206         buf.completeFunction = NULL;
00207         buf.progmem = true;
00208         buf.isString = false;
00209 
00210         _txPointers->append(&buf, sizeof(buf));
00211         if (!_tx) {
00212                 runTxBuffers();
00213         }
00214 
00215         return false;
00216 }
00217 
00225 bool MHV_Device_TX::write(const char *buffer, uint16_t length) {
00226         MHV_TX_BUFFER buf;
00227 
00228         if (_txPointers->full(sizeof(buf))) {
00229                 return true;
00230         }
00231 
00232         buf.data = buffer;
00233         buf.length = length;
00234         buf.completeFunction = NULL;
00235         buf.progmem = false;
00236         buf.isString = false;
00237 
00238         _txPointers->append(&buf, sizeof(buf));
00239         if (!_tx) {
00240                 runTxBuffers();
00241         }
00242 
00243         return false;
00244 }
00245 
00254 bool MHV_Device_TX::write(const char *buffer, uint16_t length, void (*completeFunction)(const char *)) {
00255         MHV_TX_BUFFER buf;
00256 
00257         if (_txPointers->full(sizeof(buf))) {
00258                 return true;
00259         }
00260 
00261         buf.data = buffer;
00262         buf.length = length;
00263         buf.completeFunction = completeFunction;
00264         buf.progmem = false;
00265         buf.isString = false;
00266 
00267         _txPointers->append(&buf, sizeof(buf));
00268         if (!_tx) {
00269                 runTxBuffers();
00270         }
00271 
00272         return false;
00273 }