Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mx_cmd_buffer.h Source File

mx_cmd_buffer.h

00001 /**
00002  * File:      mx_ascii_cmd_buffer.h
00003  *
00004  * Author:    Modtronix Engineering - www.modtronix.com
00005  *
00006  * Description:
00007  *
00008  * Software License Agreement:
00009  * This software has been written or modified by Modtronix Engineering. The code
00010  * may be modified and can be used free of charge for commercial and non commercial
00011  * applications. If this is modified software, any license conditions from original
00012  * software also apply. Any redistribution must include reference to 'Modtronix
00013  * Engineering' and web link(www.modtronix.com) in the file header.
00014  *
00015  * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS,
00016  * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00017  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE
00018  * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
00019  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00020  */
00021 #ifndef SRC_MX_CMD_BUFFER_H_
00022 #define SRC_MX_CMD_BUFFER_H_
00023 
00024 // This file contains an ASCII command buffer. It is used to store ASCII commands.
00025 //
00026 // Each command ends with a ';' character. CR(0x0a='\r') and LF(0x0d='\n') are converted to ';' characters.
00027 //
00028 // A ASCII command is an ASCII Formatted String, with Escape Sequences (Control Characters).
00029 // It uses 2 upper case characters to represent a single hex character, and can have embedded strings (enclosed
00030 // within single quotation marks = ') and "Control Characters" (Lower case characters 'a' to 'z')
00031 //
00032 // It has the following format:
00033 // HH   = Two upper case characters representing a single byte (hex value).
00034 // XHH  = **Not Implemented Yet** Same as HH
00035 // NDD  = **Not Implemented Yet**  Decimal number. For example "N100" = decimal 100 t0='500'
00036 // c    = **Not Implemented Yet** Lower case character 'a' to 'z' represents a "control character".
00037 // '    = Enclose string with single quotes. A double ' character will not end the string, but represents a
00038 //        single ' character.
00039 // ^^   = Two "escape characters" represents a single '^' character.
00040 // ^x   = Use this format to represent a "control character" that is not lower. Lower case characters do not have
00041 //        to be escaped. Currently not used, but reserved for future use!
00042 //
00043 //
00044 // ===== Examples when NOT using "Escape Character" =====
00045 // 0156A9BC; is decoded as:
00046 //  0x01, 0x56, 0xA9, 0xBC
00047 //
00048 // BC56'Hello'; is decoded as:
00049 //  0xBC, 0x56, H, e, l, l, o
00050 //
00051 // A1'Hi^'; is decoded as:
00052 //  0xA1, H, i, ^
00053 //
00054 // s6A52p; is decoded as("lower case" control characters NOT supported without "Escape Character"):
00055 //  0x6A, 0x52
00056 //
00057 //
00058 // ===== Examples when using "Escape Character" '^' =====
00059 // s6A52p; is decoded as:
00060 //  ^, s, 0x6A, 0x52, ^, p
00061 //
00062 // s50'Hi'p; is decoded as:
00063 //  ^, s, 0x50, H, i, ^, p
00064 //
00065 // 'Hi^'; is decoded as:
00066 //  H, i, ^, ^
00067 
00068 #include "nz32s_default_config.h"
00069 #include "mx_buffer_base.h"
00070 #include "mx_circular_buffer.h"
00071 
00072 
00073 // Debugging //////////////////////////////////////////////////////////////////
00074 // To enable debug output from this file, define MX_DEBUG and DEBUG_ENABLE_MX_CMD_BUFFER before
00075 // including this file.
00076 //
00077 //Defines for MXH_DEBUG - debugging for include file
00078 #if !defined(DEBUG_ENABLE_MX_CMD_BUFFER)
00079     #define DEBUG_ENABLE_MX_CMD_BUFFER          0
00080 #endif
00081 #if !defined(DEBUG_ENABLE_INFO_MX_CMD_BUFFER)
00082     #define DEBUG_ENABLE_INFO_MX_CMD_BUFFER     0
00083 #endif
00084 
00085 #if !defined(MXH_DEBUG)
00086     #if defined(MX_DEBUG) && (DEBUG_ENABLE_MX_CMD_BUFFER==1)
00087         #define MXH_DEBUG MX_DEBUG
00088     #else
00089         #define MXH_DEBUG(format, args...) ((void)0)
00090     #endif
00091 #endif
00092 
00093 #if !defined(MXH_DEBUG_INFO)
00094     #if defined(MX_DEBUG) && (DEBUG_ENABLE_MX_CMD_BUFFER==1) && (DEBUG_ENABLE_INFO_MX_CMD_BUFFER==1)
00095         #define MXH_DEBUG_INFO MX_DEBUG
00096     #else
00097         #define MXH_DEBUG_INFO(format, args...) ((void)0)
00098     #endif
00099 #endif
00100 
00101 
00102 /** Templated Circular buffer class
00103  */
00104 template<uint32_t BufferSize, uint8_t Commands = 16, typename CounterType = uint32_t>
00105 class MxCmdBuffer : public MxBuffer {
00106 public:
00107     MxCmdBuffer() : _head(0), _tail(0), _full(false),
00108             _errBufFull(0), _dontSaveCurrentCommand(0), _lastCharWasEOF(0), flags(0)
00109     {
00110         //flags.Val = 0;
00111     }
00112 
00113     ~MxCmdBuffer() {
00114     }
00115 
00116     /** Adds a byte to the current command in the buffer. This function checks for the "End of Command" character,
00117      * and if found, increments the "command count" register indicating how many commands this buffer has.
00118      *
00119      * If the buffer becomes full before the "End of Command" character is reached, all bytes added for current
00120      * command are removed. And, all following bytes added until the next "End of Command" character will be ignored.
00121      *
00122      * The checkBufferFullError() function can be used to check if this function caused an error, and command was
00123      * not added to buffer.
00124      *
00125      * @param data Data to be pushed to the buffer
00126      *
00127      * @return true if character added to buffer, else false. Important to note that all characters added to
00128      *      current command CAN BE REMOVED if buffer gets full before "End of Command" added to buffer!
00129      */
00130     bool put(const uint8_t& data) {
00131         uint8_t c = data;
00132 
00133         //Check if buffer full! If so:
00134         // - All data for this command added till now is lost
00135         // - All future data added for this command is ignored, until next "End of command" character is received
00136         if (isFull() && (_dontSaveCurrentCommand==false)) {
00137             _dontSaveCurrentCommand = true;
00138             _errBufFull = true;
00139             MXH_DEBUG("\r\nBuffer full, cmd LOST!");
00140 
00141             //Remove all character added for this command. Restore head to last "End of Command" pointer
00142             if (cmdEndsBuf.isEmpty() == false) {
00143                 //Restore head to byte following last "End of Command" pointer
00144                 CounterType oldHead;
00145                 oldHead = ((cmdEndsBuf.peekLastAdded()+1) % BufferSize);
00146                 //Ensure buffer not still full
00147                 if (oldHead != _head) {
00148                     _head = oldHead;
00149                     _full = false;
00150                 }
00151             }
00152             //If no commands in buffer, set head=tail
00153             else {
00154                 _head = _tail;
00155                 _full = false;
00156             }
00157         }
00158 
00159         //Check if "End of Command" byte. A command string is terminated with a ';', CR(0x0a='\r') or LF(0x0d='\n') character
00160         if ((c == ';') || (c == 0x0d) || (c == 0x0a)) {
00161             if (flags.bits.replaceCrLfWithEoc) {
00162                 c = ';';    //Change to "end of command" character
00163             }
00164 
00165             //If last character was also an "End of Command" character, ignore this one
00166             if (_lastCharWasEOF == true) {
00167                 MXH_DEBUG_INFO("\r\nMultiple EOC");
00168                 return false;   //Nothing added
00169             }
00170 
00171             _lastCharWasEOF = true; //Remember this was an "End of Command" character
00172 
00173             //Current command is now finished, so reset _dontSaveCurrentCommand
00174             if (_dontSaveCurrentCommand == true) {
00175                 _dontSaveCurrentCommand = false;
00176                 return false;   //Nothing added
00177             }
00178 
00179             //Add pointer to "end of command" character
00180             cmdEndsBuf.put(_head);
00181             //End of command character will be added to buffer below at current _head pointer
00182             MXH_DEBUG_INFO("\r\nAdded Cmd, EOC=%d", _head);
00183         }
00184         else {
00185             _lastCharWasEOF = false;
00186         }
00187 
00188         if (_dontSaveCurrentCommand) {
00189             return false;
00190         }
00191 
00192         //Add byte to buffer
00193         _pool[_head++] = c;
00194         _head %= BufferSize;
00195         if (_head == _tail) {
00196             _full = true;
00197         }
00198 
00199         return true;
00200     }
00201 
00202     /** Adds given NULL terminated string to the buffer. This function checks for the "End of Command" character,
00203      * and if found, increments the "command count" register indicating how many commands this buffer has.
00204      *
00205      * If the buffer becomes full before the "End of Command" character is reached, all bytes added for current
00206      * command are removed. And, all following bytes added until the next "End of Command" character will be ignored.
00207      *
00208      * The checkBufferFullError() function can be used to check if this function caused an error, and command was
00209      * not added to buffer.
00210      *
00211      * @param buf Source buffer containing array to add to buffer
00212      * @param bufSize Size of array to add to buffer
00213      *
00214      * @return Returns true if something added to buffer, else false. Important to note that all characters added to
00215      *      current command CAN BE REMOVED if buffer gets full before "End of Command" added to buffer!
00216      */
00217     bool put(const char* str) {
00218         bool retVal = 0;
00219 
00220         //DO NOT DO this check here! This check MUST be done by put() function, because if buffer becomes full before
00221         //"End of Command" character received, the put() function will remove all current command characters added!
00222         //if (isFull() == true) {
00223         //    return false;
00224         //}
00225 
00226         //Add whole string to buffer. DO NOT check isFull() in next line, MUST be checked in put() below!!!!
00227         while((*str != 0) /*&& (isFull()==false)*/) {
00228             retVal = retVal | put((uint8_t)(*str++));
00229         }
00230         return retVal;
00231     }
00232 
00233 
00234     /** Adds given array to the buffer. This function checks for the "End of Command" character,
00235      * and if found, increments the "command count" register indicating how many commands this buffer has.
00236      *
00237      * If the buffer becomes full before the "End of Command" character is reached, all bytes added for current
00238      * command are removed. And, all following bytes added until the next "End of Command" character will be ignored.
00239      *
00240      * The checkBufferFullError() function can be used to check if this function caused an error, and command was
00241      * not added to buffer.
00242 
00243      * @param buf Source buffer containing array to add to buffer
00244      * @param bufSize Size of array to add to buffer
00245      *
00246      * @return Returns true if something added to buffer, else false. Important to note that all characters added to
00247      *      current command CAN BE REMOVED if buffer gets full before "End of Command" added to buffer!
00248      */
00249     bool putArray(uint8_t* buf, uint16_t bufSize) {
00250         bool retVal = 0;
00251         int i;
00252 
00253         //DO NOT DO this check here! This check MUST be done by put() function, because if buffer becomes full before
00254         //"End of Command" character received, the put() function will remove all current command characters added!
00255         //if (getFree() < bufSize) {
00256         //    return 0;
00257         //}
00258 
00259         for(i=0; i<bufSize; i++) {
00260             retVal = retVal | put(buf[i]);
00261         }
00262         return retVal;
00263     }
00264 
00265     /** Gets and object from the buffer. Ensure buffer is NOT empty before calling this function!
00266      *
00267      * @return Read data
00268      */
00269     uint8_t get() {
00270         if (!isEmpty()) {
00271             uint8_t retData;
00272             retData = _pool[_tail++];
00273             _tail %= BufferSize;
00274             _full = false;
00275             return retData;
00276         }
00277         return 0;
00278     }
00279 
00280     /** Gets and object from the buffer. Returns true if OK, else false
00281      *
00282      * @param data Variable to put read data into
00283      * @return True if the buffer is not empty and data contains a transaction, false otherwise
00284      */
00285     bool getAndCheck(uint8_t& data) {
00286         if (!isEmpty()) {
00287             data = _pool[_tail++];
00288             _tail %= BufferSize;
00289             _full = false;
00290             return true;
00291         }
00292         return false;
00293     }
00294 
00295 
00296     /** Gets and object from the buffer, but do NOT remove it. Ensure buffer is NOT empty before calling
00297      * this function! If buffer is empty, will return an undefined value.
00298      *
00299      * @return Read data
00300      */
00301     uint8_t peek() {
00302         return _pool[_tail];
00303     }
00304 
00305     /** Gets an object from the buffer at given offset, but do NOT remove it. Given offset is a value from
00306      * 0 to n. Ensure buffer has as many objects as the offset requested! For example, if buffer has 5 objects
00307      * available, given offset can be a value from 0 to 4.
00308      *
00309      * @param offset Offset of requested object. A value from 0-n, where (n+1) = available objects = getAvailable()
00310      * @return Object at given offset
00311      */
00312     uint8_t peekAt(CounterType offset) {
00313         return _pool[(offset+_tail)%BufferSize];
00314     }
00315 
00316     /** Gets the last object added to the buffer, but do NOT remove it.
00317      *
00318      * @return Object at given offset
00319      */
00320     uint8_t peekLastAdded() {
00321         return _pool[(_head-1)%BufferSize];
00322     }
00323 
00324     /** Gets and array of given size, and write it to given buffer.
00325      * Nothing is removed from buffer
00326      *
00327      * @param buf Destination buffer to array to
00328      * @param bufSize Maximum size to write to destination buffer
00329      * @param lenReq Requested length
00330      *
00331      *
00332      * @return Number of bytes written to given buffer
00333      */
00334     uint16_t peekArray(uint8_t* buf, uint16_t bufSize, CounterType lenReq) {
00335         uint16_t lenWritten=0;
00336         CounterType currTail;
00337         currTail = _tail;
00338 
00339         //Some checks
00340         if (isEmpty() || (bufSize==0) || (lenReq==0)) {
00341             return 0;
00342         }
00343 
00344         do  {
00345             buf[lenWritten++] = _pool[currTail];
00346             currTail = ((currTail+1)%BufferSize);
00347         } while((lenWritten<bufSize) && (lenWritten<lenReq));
00348 
00349 
00350         return lenWritten;
00351     }
00352 
00353     /** Check if the buffer has a complete command
00354      *
00355      * @return True if the buffer has a command, false if not
00356      */
00357     bool hasCommand() {
00358         return !cmdEndsBuf.isEmpty();
00359     }
00360 
00361     /** Get length of next command in buffer, excluding "end of command" character! For example,
00362      * the command "r=100;" will return 5.
00363      * @return Length of next command in buffer
00364      */
00365     uint8_t getCommandLength() {
00366         CounterType offsetEOC;
00367 
00368         if (cmdEndsBuf.isEmpty()) {
00369             return 0;
00370         }
00371 
00372         //Get offset of "end of command" character of current command in buffer
00373         offsetEOC = cmdEndsBuf.peek();
00374 
00375         return ((offsetEOC-_tail) % BufferSize);
00376     }
00377 
00378     /** Get number of commands waiting in buffer
00379      * @return Number of commands waiting in buffer
00380      */
00381     uint8_t getCommandsAvailable() {
00382         return cmdEndsBuf.getAvailable();
00383     }
00384 
00385     /** If current command has "name=value" format, the 'name' part is returned.
00386      * Else, the whole command is returned(excluding a possible trailing '=' character).
00387      * Returned string is NULL terminated by default.
00388      * Nothing is removed from the buffer!
00389      *
00390      * If true is returned in the "isNameValue" parameter, this is a "name=value" command, with a name part of at
00391      * lease 1 character long. The offset of the 'value' part will be the returned
00392      *
00393      * If false is returned in the "isNameValue" parameter, there is no 'value' part of at least 1 character. There could however
00394      * still be a '=' character with no 'value' following it. Any possible trailing '=' character is removed string returned in 'buf'.
00395      *
00396      * @param buf Destination buffer to write string to
00397      *
00398      * @param bufSize Maximum size to write to destination buffer
00399      *
00400      * @param isNameValue Returns true if a '=' character was found -AND- at least 1 char following it. This indicates
00401      *        this is a "name=value" command, and has a value part(of at least 1 character) following the '='.
00402      *        First character of 'value' is value returned by this function + 1!
00403      *
00404      * @return Size in bytes of string returned in 'buf' parameter(is 'name' if isNameValue=true).
00405      *         If true is returned in 'isNameValue', 'buf' contains the 'name' part of a 'name=value' command. This returned offset points to '='.
00406      *         If false is returned in 'isNameValue', 'buf' contains the whole command string(excluding possible trailing '=' character).
00407      */
00408     uint16_t getCommandName(uint8_t* buf, uint16_t bufSize, bool& isNameValue, bool nullTerminate = true) {
00409         CounterType offsetEOC;
00410         CounterType currTail;
00411         uint16_t nameLen = 0;
00412         isNameValue=false;
00413 
00414         //Some checks
00415         if (cmdEndsBuf.isEmpty() || (bufSize==0) || (_pool[_tail]=='=')) {
00416             return 0;
00417         }
00418         offsetEOC = cmdEndsBuf.peek();
00419         currTail = _tail;
00420 
00421         //Copy current command string to given buffer, until '=' reached
00422         do {
00423             buf[nameLen++] = _pool[currTail];
00424             currTail = ((currTail+1)%BufferSize);
00425             //If next character is '='
00426             if(_pool[currTail] == '=') {
00427                 //Check at least 1 character following '='
00428                 //Get pointer of character following '=', and ensure it is not "end of command"(offsetEOC). Meaning there is
00429                 //still at least 1 more character following '='
00430                 if(((currTail+1)%BufferSize) != offsetEOC) {
00431                     isNameValue = true;
00432                 }
00433                 break;
00434             }
00435         } while((currTail!=offsetEOC) && (nameLen<bufSize));
00436 
00437 
00438         if (nullTerminate) {
00439             if(nameLen<bufSize) {
00440                 buf[nameLen] = 0;
00441             }
00442             buf[bufSize-1] = 0; //Null terminate last position of buffer in case it filled up
00443         }
00444 
00445         return nameLen;
00446     }
00447 
00448     /** For commands with "name=value" format, returns the 'value' part.
00449      * Returned string is NULL terminated by default.
00450      * Nothing is removed from the buffer!
00451      *
00452      * To optimize this function, call getCommandName() before calling this function. The getCommandName() return value(+1)
00453      * can be used as 'offset' parameter to this function. This will save this function from searching for '=' character.
00454      *
00455      *
00456      * @param buf Destination buffer to write string to
00457      * @param bufSize Maximum size to write to destination buffer
00458      * @param offset Gives offset of value string if known. This can be value(+1) returned by
00459      *        getCommandName() function. Use -1 if unknown.
00460      *
00461      * @return Size in bytes of returned string
00462      */
00463     uint16_t getCommandValue(uint8_t* buf, uint16_t bufSize, uint16_t offset = -1, bool nullTerminate = true) {
00464         CounterType offsetEOC;
00465         CounterType currTail;
00466         uint16_t valueLen = 0;
00467         bool foundEq=false;     //'=' character found
00468 
00469         //Some checks
00470         if (cmdEndsBuf.isEmpty() || (bufSize==0)) {
00471             return 0;
00472         }
00473         offsetEOC = cmdEndsBuf.peek();  //offset of "end of command" character
00474 
00475         currTail = _tail;
00476 
00477         //If offset was given, it will point to first character of value string
00478         if (offset != -1) {
00479             //Check offset point somewhere inside current command! Where ((offsetEOC-_tail) % BufferSize) = command length
00480             if (offset < ((offsetEOC-_tail)%BufferSize)) {
00481                 currTail = ((currTail + offset)%BufferSize);    //Add offset to tail
00482 
00483                 //If given offset was for first character of 'value', it will NOT point to '='. It will be next character.
00484                 if(_pool[currTail] != '=') {
00485                     //Points to character after '=', indicate '=' has already been found.
00486                     foundEq=true;
00487                 }
00488                 //ELSE, assume offset for for '=' character. It will be found in step below
00489             }
00490             else {
00491                 //currTail = _tail; //Ignore given offset, and search whole command for '='
00492                 MXH_DEBUG("\r\ngetCommandValue() Offset error!");
00493             }
00494         }
00495 
00496         do {
00497             if (foundEq) {
00498                 buf[valueLen++] = _pool[currTail];
00499             }
00500             else {
00501                 if(_pool[currTail] == '=') {
00502                     foundEq=true;
00503                 }
00504             }
00505             currTail = ((currTail+1)%BufferSize);
00506         } while((currTail != offsetEOC) && (valueLen<bufSize));
00507 
00508         if (nullTerminate) {
00509             if(valueLen<bufSize) {
00510                 buf[valueLen] = 0;
00511             }
00512             buf[bufSize-1] = 0; //Null terminate last position of buffer in case it filled up
00513         }
00514 
00515         return valueLen;
00516     }
00517 
00518     /** Search current command for given character
00519      *
00520      * @param offset Returns offset of found character. If NULL, this parameter is not used.
00521      *
00522      * @return Returns true if found, else false
00523      */
00524     bool search(uint8_t c, uint16_t* offsetFound) {
00525         CounterType offsetEOF;
00526         CounterType currTail;
00527 
00528         //Get command length
00529         if (cmdEndsBuf.isEmpty()) {
00530             return false;
00531         }
00532         offsetEOF = cmdEndsBuf.peek();
00533         currTail = _tail;
00534         do {
00535             if(_pool[currTail] == c) {
00536                 if (offsetFound!=NULL) {
00537                     *offsetFound = (uint16_t)currTail;
00538                 }
00539                 return true;
00540             }
00541             currTail = ((currTail+1)%BufferSize);
00542         } while(currTail != offsetEOF);
00543 
00544 //        CounterType i;
00545 //        CounterType cmdLen;
00546 //        cmdLen = (offsetEOF-_tail) % BufferSize;
00547 //        for (i=0; i<cmdLen; i++) {
00548 //            if(_pool[(i+_tail)%BufferSize] == c) {
00549 //            //if(peekAt(i)==c) {
00550 //                offsetFound = (uint16_t)i;
00551 //                return true;
00552 //            }
00553 //        }
00554         return false;
00555     }
00556 
00557     /** Check if the buffer is empty
00558      *
00559      * @return True if the buffer is empty, false if not
00560      */
00561     bool isEmpty() {
00562         return (_head == _tail) && !_full;
00563     }
00564 
00565     /** Check if the buffer is full
00566      *
00567      * @return True if the buffer is full, false if not
00568      */
00569     bool isFull() {
00570         return _full;
00571     }
00572 
00573     /** Get number of available bytes in buffer
00574      * @return Number of available bytes in buffer
00575      */
00576     CounterType getAvailable() {
00577         if (_head != _tail) {
00578             CounterType avail;
00579             avail = _head - _tail;
00580             avail %= BufferSize;
00581             return avail;
00582         }
00583 
00584         //Head=Tail. Can be full or empty
00585         if (_full==false) {
00586             return 0;
00587         }
00588         else {
00589             return BufferSize;
00590         }
00591     }
00592 
00593 
00594     /** Get number of free bytes in buffer available for writing data to.
00595      * @return Number of free bytes in buffer available for writing data to.
00596      */
00597     CounterType getFree() {
00598         CounterType free;
00599         //Full
00600         if (_full==true) {
00601             return 0;
00602         }
00603         //Empty
00604         if(_head == _tail) {
00605             return BufferSize;
00606         }
00607         free = _tail - _head;
00608         free %= BufferSize;
00609         return free;
00610     }
00611 
00612     /** Replaces any LF or CR characters with an "End of Command" character = ';'
00613      */
00614     void enableReplaceCrLfWithEoc() {
00615         flags.bits.replaceCrLfWithEoc = true;
00616     }
00617 
00618     /** Do NOT replaces LF and CR characters with an "End of Command" character = ';'
00619      */
00620     void disableReplaceCrLfWithEoc() {
00621         flags.bits.replaceCrLfWithEoc = false;
00622     }
00623 
00624     /** Check if an overwrite error occurred. It resets the error flag if it was set
00625      * @return True if overwrite error occurred since last time this function was called, else false
00626      */
00627     bool checkBufferFullError() {
00628         bool retVal = _errBufFull;
00629         _errBufFull = false;
00630         return retVal;
00631     }
00632 
00633     /** Reset the buffer
00634      */
00635     void reset() {
00636         _head = 0;
00637         _tail = 0;
00638         _full = false;
00639         _errBufFull = false;
00640         _dontSaveCurrentCommand = false;
00641     }
00642 
00643     /** Remove a command from buffer
00644      */
00645     void removeCommand() {
00646         if (cmdEndsBuf.isEmpty()) {
00647             return;
00648         }
00649 
00650         //MXH_DEBUG("\r\nRemoving Cmd");
00651 
00652         //Set tail = "end of command" character + 1. This is first character of next command
00653         _tail = (cmdEndsBuf.get()+1) % BufferSize;
00654         _full = false;
00655     }
00656 
00657 private:
00658     uint8_t _pool[BufferSize];
00659     volatile CounterType _head;
00660     volatile CounterType _tail;
00661     volatile bool _full;
00662     volatile bool _errBufFull;
00663     volatile bool _dontSaveCurrentCommand;
00664     volatile bool _lastCharWasEOF;
00665 
00666     union Flags {
00667         struct {
00668             uint8_t replaceCrLfWithEoc : 1;         //Replace CR and LF with "End of Command" character = ';'
00669         } bits;
00670         uint8_t     Val;
00671         //Union constructor. Used in initialization list of this class.
00672         Flags(uint8_t v) : Val(v) {}
00673     } flags;
00674 
00675 public:
00676     //Buffer for storing "end of command" locations
00677     MxCircularBuffer <uint16_t, Commands, CounterType>  cmdEndsBuf;
00678     //MxCircularBuffer <uint16_t, Commands, uint16_t> cmdEndsBuf;   //Creates larger code
00679 };
00680 
00681 #if defined(MXH_DEBUG)
00682     #undef MXH_DEBUG
00683 #endif
00684 #if defined(MXH_DEBUG_INFO)
00685     #undef MXH_DEBUG_INFO
00686 #endif
00687 
00688 
00689 #endif /* SRC_MX_CMD_BUFFER_H_ */