MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
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 }