MHVLib  20111227
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         _currentTx.data = NULL;
00044         _currentTx.length = 0;
00045         _currentTx.completeFunction = NULL;
00046         _currentTx.progmem = false;
00047         _currentTx.isString = false;
00048 }
00049 
00054 bool MHV_Device_TX::moreTX() {
00055 // Call the completeFunction, if one is provided - allows the user to free memory, etc
00056         if (NULL != _currentTx.completeFunction) {
00057                 _currentTx.completeFunction(_currentTx.data);
00058         }
00059 
00060         if (_txPointers.consume(&_currentTx, sizeof(_currentTx))) {
00061                 _tx = NULL;
00062                 return false;
00063         }
00064 
00065         _tx = _currentTx.data;
00066 
00067         return true;
00068 }
00069 
00070 /* Can we accept another buffer?
00071  */
00072 bool MHV_Device_TX::canWrite() {
00073         return !(_txPointers.full(sizeof(MHV_TX_BUFFER)));
00074 }
00075 
00080 int MHV_Device_TX::nextCharacter() {
00081         char c = '\0';
00082 
00083         if (NULL != _tx) {
00084                 if (_currentTx.progmem) {
00085                         c = pgm_read_byte(_tx);
00086                 } else {
00087                         c = *_tx;
00088                 }
00089         }
00090 
00091         if ((_currentTx.isString && ('\0' == c)) ||
00092                         (!_currentTx.isString && (_tx == _currentTx.data + _currentTx.length))) {
00093                 if (!moreTX()) {
00094                         _tx = NULL;
00095                         _currentTx.data = NULL;
00096                         _currentTx.length = 0;
00097                         _currentTx.completeFunction = NULL;
00098                         _currentTx.progmem = false;
00099                         _currentTx.isString = false;
00100                         return -1;
00101                 }
00102 
00103                 return nextCharacter();
00104         }
00105 
00106         _tx++;
00107         return (int)c;
00108 }
00109 
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 
00143 bool MHV_Device_TX::write(const char *buffer) {
00144         MHV_TX_BUFFER buf;
00145 
00146         if (_txPointers.full(sizeof(buf))) {
00147                 return true;
00148         }
00149 
00150         buf.data = buffer;
00151         buf.length = 0;
00152         buf.completeFunction = NULL;
00153         buf.progmem = false;
00154         buf.isString = true;
00155 
00156         _txPointers.append(&buf, sizeof(buf));
00157         if (!_tx) {
00158                 runTxBuffers();
00159         }
00160 
00161         return false;
00162 }
00163 
00171 bool MHV_Device_TX::write(const char *buffer, void (*completeFunction)(const char *)) {
00172         MHV_TX_BUFFER buf;
00173 
00174         if (_txPointers.full(sizeof(buf))) {
00175                 return true;
00176         }
00177 
00178         buf.data = buffer;
00179         buf.length = 0;
00180         buf.completeFunction = completeFunction;
00181         buf.progmem = false;
00182         buf.isString = true;
00183 
00184         _txPointers.append(&buf, sizeof(buf));
00185         if (!_tx) {
00186                 runTxBuffers();
00187         }
00188 
00189         return false;
00190 }
00191 
00199 bool MHV_Device_TX::write_P(PGM_P buffer, uint16_t length) {
00200         MHV_TX_BUFFER buf;
00201 
00202         if (_txPointers.full(sizeof(buf))) {
00203                 return true;
00204         }
00205 
00206         buf.data = buffer;
00207         buf.length = length;
00208         buf.completeFunction = NULL;
00209         buf.progmem = true;
00210         buf.isString = false;
00211 
00212         _txPointers.append(&buf, sizeof(buf));
00213         if (!_tx) {
00214                 runTxBuffers();
00215         }
00216 
00217         return false;
00218 }
00219 
00227 bool MHV_Device_TX::write(const char *buffer, uint16_t length) {
00228         MHV_TX_BUFFER buf;
00229 
00230         if (_txPointers.full(sizeof(buf))) {
00231                 return true;
00232         }
00233 
00234         buf.data = buffer;
00235         buf.length = length;
00236         buf.completeFunction = NULL;
00237         buf.progmem = false;
00238         buf.isString = false;
00239 
00240         _txPointers.append(&buf, sizeof(buf));
00241         if (!_tx) {
00242                 runTxBuffers();
00243         }
00244 
00245         return false;
00246 }
00247 
00256 bool MHV_Device_TX::write(const char *buffer, uint16_t length, void (*completeFunction)(const char *)) {
00257         MHV_TX_BUFFER buf;
00258 
00259         if (_txPointers.full(sizeof(buf))) {
00260                 return true;
00261         }
00262 
00263         buf.data = buffer;
00264         buf.length = length;
00265         buf.completeFunction = completeFunction;
00266         buf.progmem = false;
00267         buf.isString = false;
00268 
00269         _txPointers.append(&buf, sizeof(buf));
00270         if (!_tx) {
00271                 runTxBuffers();
00272         }
00273 
00274         return false;
00275 }
00276 
00281 void mhv_device_tx_free(const char *buf) {
00282         free((void *)buf);
00283 }
00284 
00295 bool MHV_Device_TX::debug(const char *file, int line, const char *function,
00296                 PGM_P format, ...) {
00297         va_list ap;
00298         va_start(ap, format);
00299 
00300         int length = snprintf_P(NULL, 0, PSTR("%s:%d\t%s():\t\t"),
00301                         file, line, function);
00302         length += vsnprintf_P(NULL, 0, format, ap);
00303         length += 3; // "\r\n\0"
00304 
00305         char *buf = (char *)malloc(length);
00306         char *cur = buf;
00307         if (NULL != cur) {
00308                 cur += snprintf_P(cur, length, PSTR("%s:%d\t%s():\t\t"),
00309                                         file, line, function);
00310                 length -= cur - buf;
00311                 cur += vsnprintf_P(cur, length, format, ap);
00312                 *(cur++) = '\r';
00313                 *(cur++) = '\n';
00314                 *cur = '\0';
00315 
00316                 if (write(buf, length, &mhv_device_tx_free)) {
00317                         mhv_device_tx_free(buf);
00318                         va_end(ap);
00319                         return true;
00320                 }
00321 
00322                 va_end(ap);
00323                 return false;
00324         }
00325 
00326         va_end(ap);
00327         return true;
00328 }
00329 
00337 bool MHV_Device_TX::printf(PGM_P format, ...) {
00338         va_list ap;
00339         va_start(ap, format);
00340 
00341         int length = vsnprintf_P(NULL, 0, format, ap);
00342         length++; // "\0"
00343 
00344         char *buf = (char *)malloc(length);
00345         if (NULL != buf) {
00346                 vsnprintf_P(buf, length, format, ap);
00347 
00348                 if (write(buf, length, &mhv_device_tx_free)) {
00349                         mhv_device_tx_free(buf);
00350                         va_end(ap);
00351                         return true;
00352                 }
00353 
00354                 va_end(ap);
00355                 return false;
00356         }
00357 
00358         va_end(ap);
00359         return true;
00360 
00361 }
00362 
00369 bool MHV_Device_TX::write(uint8_t value) {
00370         char *buf = (char *)malloc(4);
00371         if (NULL != buf) {
00372                 utoa((uint16_t)value, buf, 10);
00373                 if (write(buf)) {
00374                         mhv_device_tx_free(buf);
00375                         return true;
00376                 }
00377                 return false;
00378         }
00379         return true;
00380 }
00381 
00388 bool MHV_Device_TX::write(uint16_t value) {
00389         char *buf = (char *)malloc(6);
00390         if (NULL != buf) {
00391                 utoa(value, buf, 10);
00392                 if (write(buf)) {
00393                         mhv_device_tx_free(buf);
00394                         return true;
00395                 }
00396                 return false;
00397         }
00398         return true;
00399 }
00400 
00407 bool MHV_Device_TX::write(uint32_t value) {
00408         char *buf = (char *)malloc(11);
00409         if (NULL != buf) {
00410                 ultoa(value, buf, 10);
00411                 if (write(buf)) {
00412                         mhv_device_tx_free(buf);
00413                         return true;
00414                 }
00415                 return false;
00416         }
00417         return true;
00418 }
00419 
00426 bool MHV_Device_TX::write(int8_t value) {
00427         char *buf = (char *)malloc(5);
00428         if (NULL != buf) {
00429                 itoa((uint16_t)value, buf, 10);
00430                 if (write(buf)) {
00431                         mhv_device_tx_free(buf);
00432                         return true;
00433                 }
00434                 return false;
00435         }
00436         return true;
00437 }
00438 
00445 bool MHV_Device_TX::write(int16_t value) {
00446         char *buf = (char *)malloc(7);
00447         if (NULL != buf) {
00448                 itoa(value, buf, 10);
00449                 if (write(buf)) {
00450                         mhv_device_tx_free(buf);
00451                         return true;
00452                 }
00453                 return false;
00454         }
00455         return true;
00456 }
00457 
00464 bool MHV_Device_TX::write(int32_t value) {
00465         char *buf = (char *)malloc(13);
00466         if (NULL != buf) {
00467                 ltoa(value, buf, 10);
00468                 if (write(buf)) {
00469                         mhv_device_tx_free(buf);
00470                         return true;
00471                 }
00472                 return false;
00473         }
00474         return true;
00475 }