MHVLib  20111109
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 
00117 bool MHV_Device_TX::write_P(PGM_P buffer) {
00118         MHV_TX_BUFFER buf;
00119 
00120         if (_txPointers->full(sizeof(buf))) {
00121                 return true;
00122         }
00123 
00124         buf.data = buffer;
00125         buf.length = 0;
00126         buf.completeFunction = NULL;
00127         buf.progmem = true;
00128         buf.isString = true;
00129 
00130         _txPointers->append(&buf, sizeof(buf));
00131         if (!_tx) {
00132                 runTxBuffers();
00133         }
00134 
00135         return false;
00136 }
00137 
00144 bool MHV_Device_TX::write(const char *buffer) {
00145         MHV_TX_BUFFER buf;
00146 
00147         if (_txPointers->full(sizeof(buf))) {
00148                 return true;
00149         }
00150 
00151         buf.data = buffer;
00152         buf.length = 0;
00153         buf.completeFunction = NULL;
00154         buf.progmem = false;
00155         buf.isString = true;
00156 
00157         _txPointers->append(&buf, sizeof(buf));
00158         if (!_tx) {
00159                 runTxBuffers();
00160         }
00161 
00162         return false;
00163 }
00164 
00172 bool MHV_Device_TX::write(const char *buffer, void (*completeFunction)(const char *)) {
00173         MHV_TX_BUFFER buf;
00174 
00175         if (_txPointers->full(sizeof(buf))) {
00176                 return true;
00177         }
00178 
00179         buf.data = buffer;
00180         buf.length = 0;
00181         buf.completeFunction = completeFunction;
00182         buf.progmem = false;
00183         buf.isString = true;
00184 
00185         _txPointers->append(&buf, sizeof(buf));
00186         if (!_tx) {
00187                 runTxBuffers();
00188         }
00189 
00190         return false;
00191 }
00192 
00200 bool MHV_Device_TX::write_P(PGM_P buffer, uint16_t length) {
00201         MHV_TX_BUFFER buf;
00202 
00203         if (_txPointers->full(sizeof(buf))) {
00204                 return true;
00205         }
00206 
00207         buf.data = buffer;
00208         buf.length = length;
00209         buf.completeFunction = NULL;
00210         buf.progmem = true;
00211         buf.isString = false;
00212 
00213         _txPointers->append(&buf, sizeof(buf));
00214         if (!_tx) {
00215                 runTxBuffers();
00216         }
00217 
00218         return false;
00219 }
00220 
00228 bool MHV_Device_TX::write(const char *buffer, uint16_t length) {
00229         MHV_TX_BUFFER buf;
00230 
00231         if (_txPointers->full(sizeof(buf))) {
00232                 return true;
00233         }
00234 
00235         buf.data = buffer;
00236         buf.length = length;
00237         buf.completeFunction = NULL;
00238         buf.progmem = false;
00239         buf.isString = false;
00240 
00241         _txPointers->append(&buf, sizeof(buf));
00242         if (!_tx) {
00243                 runTxBuffers();
00244         }
00245 
00246         return false;
00247 }
00248 
00257 bool MHV_Device_TX::write(const char *buffer, uint16_t length, void (*completeFunction)(const char *)) {
00258         MHV_TX_BUFFER buf;
00259 
00260         if (_txPointers->full(sizeof(buf))) {
00261                 return true;
00262         }
00263 
00264         buf.data = buffer;
00265         buf.length = length;
00266         buf.completeFunction = completeFunction;
00267         buf.progmem = false;
00268         buf.isString = false;
00269 
00270         _txPointers->append(&buf, sizeof(buf));
00271         if (!_tx) {
00272                 runTxBuffers();
00273         }
00274 
00275         return false;
00276 }
00277 
00282 void mhv_device_tx_free(const char *buf) {
00283         free((void *)buf);
00284 }
00285 
00296 bool MHV_Device_TX::debug(const char *file, int line, const char *function,
00297                 PGM_P format, ...) {
00298         va_list ap;
00299         va_start(ap, format);
00300 
00301         int length = snprintf_P(NULL, 0, PSTR("%s:%d\t%s():\t\t"),
00302                         file, line, function);
00303         length += vsnprintf_P(NULL, 0, format, ap);
00304         length += 3; // "\r\n\0"
00305 
00306         char *buf = (char *)malloc(length);
00307         char *cur = buf;
00308         if (NULL != cur) {
00309                 cur += snprintf_P(cur, length, PSTR("%s:%d\t%s():\t\t"),
00310                                         file, line, function);
00311                 length -= cur - buf;
00312                 cur += vsnprintf_P(cur, length, format, ap);
00313                 *(cur++) = '\r';
00314                 *(cur++) = '\n';
00315                 *cur = '\0';
00316 
00317                 if (write(buf, length, &mhv_device_tx_free)) {
00318                         mhv_device_tx_free(buf);
00319                         va_end(ap);
00320                         return true;
00321                 }
00322 
00323                 va_end(ap);
00324                 return false;
00325         }
00326 
00327         va_end(ap);
00328         return true;
00329 }
00330 
00338 bool MHV_Device_TX::printf(PGM_P format, ...) {
00339         va_list ap;
00340         va_start(ap, format);
00341 
00342         int length = vsnprintf_P(NULL, 0, format, ap);
00343         length++; // "\0"
00344 
00345         char *buf = (char *)malloc(length);
00346         if (NULL != buf) {
00347                 vsnprintf_P(buf, length, format, ap);
00348 
00349                 if (write(buf, length, &mhv_device_tx_free)) {
00350                         mhv_device_tx_free(buf);
00351                         va_end(ap);
00352                         return true;
00353                 }
00354 
00355                 va_end(ap);
00356                 return false;
00357         }
00358 
00359         va_end(ap);
00360         return true;
00361 
00362 }
00363 
00370 bool MHV_Device_TX::write(uint8_t value) {
00371         char *buf = (char *)malloc(4);
00372         if (NULL != buf) {
00373                 utoa((uint16_t)value, buf, 10);
00374                 if (write(buf)) {
00375                         mhv_device_tx_free(buf);
00376                         return true;
00377                 }
00378                 return false;
00379         }
00380         return true;
00381 }
00382 
00389 bool MHV_Device_TX::write(uint16_t value) {
00390         char *buf = (char *)malloc(6);
00391         if (NULL != buf) {
00392                 utoa(value, buf, 10);
00393                 if (write(buf)) {
00394                         mhv_device_tx_free(buf);
00395                         return true;
00396                 }
00397                 return false;
00398         }
00399         return true;
00400 }
00401 
00408 bool MHV_Device_TX::write(uint32_t value) {
00409         char *buf = (char *)malloc(11);
00410         if (NULL != buf) {
00411                 ultoa(value, buf, 10);
00412                 if (write(buf)) {
00413                         mhv_device_tx_free(buf);
00414                         return true;
00415                 }
00416                 return false;
00417         }
00418         return true;
00419 }
00420 
00427 bool MHV_Device_TX::write(int8_t value) {
00428         char *buf = (char *)malloc(5);
00429         if (NULL != buf) {
00430                 itoa((uint16_t)value, buf, 10);
00431                 if (write(buf)) {
00432                         mhv_device_tx_free(buf);
00433                         return true;
00434                 }
00435                 return false;
00436         }
00437         return true;
00438 }
00439 
00446 bool MHV_Device_TX::write(int16_t value) {
00447         char *buf = (char *)malloc(7);
00448         if (NULL != buf) {
00449                 itoa(value, buf, 10);
00450                 if (write(buf)) {
00451                         mhv_device_tx_free(buf);
00452                         return true;
00453                 }
00454                 return false;
00455         }
00456         return true;
00457 }
00458 
00465 bool MHV_Device_TX::write(int32_t value) {
00466         char *buf = (char *)malloc(13);
00467         if (NULL != buf) {
00468                 ltoa(value, buf, 10);
00469                 if (write(buf)) {
00470                         mhv_device_tx_free(buf);
00471                         return true;
00472                 }
00473                 return false;
00474         }
00475         return true;
00476 }