diff --git a/repetier communication protocol.txt b/repetier communication protocol.txt index cd05994..5dc6044 100644 --- a/repetier communication protocol.txt +++ b/repetier communication protocol.txt @@ -62,6 +62,13 @@ I : Bit 0 : 32-Bit float J : Bit 1 : 32-Bit float R : Bit 2 : 32-Bit float D : Bit 3 : 32-Bit float (V3) +C : Bit 4 : 32-bit float (V3) +H : Bit 5 : 32-Bit float (V3) +A : Bit 6 : 32-Bit float (V3) +B : Bit 7 : 32-Bit float (V3) +K : Bit 8 : 32-Bit float (V3) +L : Bit 9 : 32-Bit float (V3) +O : Bit 10 : 32-Bit float (V3) Bit 2-15 reserved If Text bit is set in V2, the text length is send as byte 5 Text follows at diff --git a/src/ArduinoDUE/Repetier/Communication.cpp b/src/ArduinoDUE/Repetier/Communication.cpp index 39ef39a..ff835a6 100644 --- a/src/ArduinoDUE/Repetier/Communication.cpp +++ b/src/ArduinoDUE/Repetier/Communication.cpp @@ -21,13 +21,13 @@ #include "Repetier.h" -#if DRIVE_SYSTEM==DELTA -FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Delta EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:2") +#if DRIVE_SYSTEM == DELTA +FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Delta EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3") #else -#if DRIVE_SYSTEM==CARTESIAN -FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/luc-github/Repetier-Firmware PROTOCOL_VERSION:1.0 MACHINE_TYPE:DaVinci EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:2") +#if DRIVE_SYSTEM == CARTESIAN +FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/luc-github/Repetier-Firmware-0.92 PROTOCOL_VERSION:1.0 MACHINE_TYPE:DaVinci EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3") #else -FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Core_XY EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:2") +FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Core_XY EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3") #endif #endif @@ -240,7 +240,7 @@ FSTRINGVALUE(Com::tZProbePrinterHeight,"Printer height:") #ifdef WAITING_IDENTIFIER FSTRINGVALUE(Com::tWait,WAITING_IDENTIFIER) #endif // WAITING_IDENTIFIER -#if EEPROM_MODE==0 +#if EEPROM_MODE == 0 FSTRINGVALUE(Com::tNoEEPROMSupport,"No EEPROM support compiled.\r\n") #else FSTRINGVALUE(Com::tManualProbeX1,"Manual-probe X1") diff --git a/src/ArduinoDUE/Repetier/Configuration.h b/src/ArduinoDUE/Repetier/Configuration.h index 0c5d0b0..029ed07 100644 --- a/src/ArduinoDUE/Repetier/Configuration.h +++ b/src/ArduinoDUE/Repetier/Configuration.h @@ -27,8 +27,8 @@ //Warning: for DaVinci 1.0 need to add a permanent fan with power supply to cool extruder #define VERSION_MAJOR " 1" #define VERSION_MINOR_YEAR "15" -#define VERSION_MINOR_MONTH "01" -#define VERSION_MINOR_DAY "28" +#define VERSION_MINOR_MONTH "02" +#define VERSION_MINOR_DAY "26" #define VERSION_BUILD "1" // ################ END MANUAL SETTINGS ########################## @@ -1126,12 +1126,6 @@ boards you might need to make it inverting. */ #define KILL_METHOD 1 -/** \brief Cache size for incoming commands. - -There should be no reason to increase this cache. Commands are nearly immediately sent to -execution. -*/ -#define GCODE_BUFFER_SIZE 2 /** Appends the linenumber after every ok send, to acknowledge the received command. Uncomment for plain ok ACK if your host has problems with this */ #define ACK_WITH_LINENUMBER 1 /** Communication errors can swollow part of the ok, which tells the host software to send @@ -1139,6 +1133,7 @@ the next command. Not receiving it will cause your printer to stop. Sending this second, if our queue is empty should prevent this. Comment it, if you don't wan't this feature. */ #define WAITING_IDENTIFIER "wait" #define RESET_IDENTIFIER "start" + /** \brief Sets time for echo debug You can set M111 1 which enables ECHO of commands sent. This define specifies the position, diff --git a/src/ArduinoDUE/Repetier/Repetier.h b/src/ArduinoDUE/Repetier/Repetier.h index 9b8cda5..a284213 100644 --- a/src/ArduinoDUE/Repetier/Repetier.h +++ b/src/ArduinoDUE/Repetier/Repetier.h @@ -32,7 +32,7 @@ enum debugFlags {DEB_ECHO= 0x1, DEB_INFO=0x2, DEB_ERROR =0x4,DEB_DRYRUN=0x8, DEB_COMMUNICATION=0x10, DEB_NOMOVES=0x20, DEB_DEBUG=0x40}; /** Uncomment, to see detailed data for every move. Only for debugging purposes! */ -#define DEBUG_QUEUE_MOVE +//#define DEBUG_QUEUE_MOVE /** Allows M111 to set bit 5 (16) which disables all commands except M111. This can be used to test your data througput or search for communication problems. */ #define INCLUDE_DEBUG_COMMUNICATION 1 @@ -178,6 +178,8 @@ usage or for seraching for memory induced errors. Switch it off for production, #include "Configuration.h" +#define GCODE_BUFFER_SIZE 1 + #ifndef FEATURE_BABYSTEPPING #define FEATURE_BABYSTEPPING 0 #define BABYSTEP_MULTIPLICATOR 1 @@ -259,7 +261,7 @@ usage or for seraching for memory induced errors. Switch it off for production, #define EXT2_ANALOG_CHANNEL #endif -#if NUM_EXTRUDER>3 && EXT3_TEMPSENSOR_TYPE<101 +#if NUM_EXTRUDER > 3 && EXT3_TEMPSENSOR_TYPE < 101 #define EXT3_ANALOG_INPUTS 1 #define EXT3_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS #define EXT3_ANALOG_CHANNEL ACCOMMA2 EXT3_TEMPSENSOR_PIN @@ -271,7 +273,7 @@ usage or for seraching for memory induced errors. Switch it off for production, #define EXT3_ANALOG_CHANNEL #endif -#if NUM_EXTRUDER>4 && EXT4_TEMPSENSOR_TYPE<101 +#if NUM_EXTRUDER > 4 && EXT4_TEMPSENSOR_TYPE < 101 #define EXT4_ANALOG_INPUTS 1 #define EXT4_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS #define EXT4_ANALOG_CHANNEL ACCOMMA3 EXT4_TEMPSENSOR_PIN diff --git a/src/ArduinoDUE/Repetier/gcode.cpp b/src/ArduinoDUE/Repetier/gcode.cpp index a17fa89..af8b7d0 100644 --- a/src/ArduinoDUE/Repetier/gcode.cpp +++ b/src/ArduinoDUE/Repetier/gcode.cpp @@ -28,21 +28,21 @@ #endif GCode GCode::commandsBuffered[GCODE_BUFFER_SIZE]; ///< Buffer for received commands. -uint8_t GCode::bufferReadIndex=0; ///< Read position in gcode_buffer. -uint8_t GCode::bufferWriteIndex=0; ///< Write position in gcode_buffer. +uint8_t GCode::bufferReadIndex = 0; ///< Read position in gcode_buffer. +uint8_t GCode::bufferWriteIndex = 0; ///< Write position in gcode_buffer. uint8_t GCode::commandReceiving[MAX_CMD_SIZE]; ///< Current received command. -uint8_t GCode::commandsReceivingWritePosition=0; ///< Writing position in gcode_transbuffer. +uint8_t GCode::commandsReceivingWritePosition = 0; ///< Writing position in gcode_transbuffer. uint8_t GCode::sendAsBinary; ///< Flags the command as binary input. -uint8_t GCode::wasLastCommandReceivedAsBinary=0; ///< Was the last successful command in binary mode? -uint8_t GCode::commentDetected=false; ///< Flags true if we are reading the comment part of a command. +uint8_t GCode::wasLastCommandReceivedAsBinary = 0; ///< Was the last successful command in binary mode? +uint8_t GCode::commentDetected = false; ///< Flags true if we are reading the comment part of a command. uint8_t GCode::binaryCommandSize; ///< Expected size of the incoming binary command. -bool GCode::waitUntilAllCommandsAreParsed=false; ///< Don't read until all commands are parsed. Needed if gcode_buffer is misused as storage for strings. -uint32_t GCode::lastLineNumber=0; ///< Last line number received. +bool GCode::waitUntilAllCommandsAreParsed = false; ///< Don't read until all commands are parsed. Needed if gcode_buffer is misused as storage for strings. +uint32_t GCode::lastLineNumber = 0; ///< Last line number received. uint32_t GCode::actLineNumber; ///< Line number of current command. -int8_t GCode::waitingForResend=-1; ///< Waiting for line to be resend. -1 = no wait. -volatile uint8_t GCode::bufferLength=0; ///< Number of commands stored in gcode_buffer -millis_t GCode::timeOfLastDataPacket=0; ///< Time, when we got the last data packet. Used to detect missing uint8_ts. -uint8_t GCode::formatErrors=0; +int8_t GCode::waitingForResend = -1; ///< Waiting for line to be resend. -1 = no wait. +volatile uint8_t GCode::bufferLength = 0; ///< Number of commands stored in gcode_buffer +millis_t GCode::timeOfLastDataPacket = 0; ///< Time, when we got the last data packet. Used to detect missing uint8_ts. +uint8_t GCode::formatErrors = 0; /** \page Repetier-protocol @@ -94,36 +94,57 @@ Second word if V2: - I : Bit 0 : 32-Bit float - J : Bit 1 : 32-Bit float - R : Bit 2 : 32-Bit float +- D : Bit 3 : 32-Bit float +- C : Bit 4 : 32-Bit float +- H : Bit 5 : 32-Bit float +- A : Bit 6 : 32-Bit float +- B : Bit 7 : 32-Bit float +- K : Bit 8 : 32-Bit float +- L : Bit 9 : 32-Bit float +- O : Bit 0 : 32-Bit float */ uint8_t GCode::computeBinarySize(char *ptr) // unsigned int bitfield) { { uint8_t s = 4; // include checksum and bitfield uint16_t bitfield = *(uint16_t*)ptr; - if(bitfield & 1) s+=2; - if(bitfield & 8) s+=4; - if(bitfield & 16) s+=4; - if(bitfield & 32) s+=4; - if(bitfield & 64) s+=4; - if(bitfield & 256) s+=4; - if(bitfield & 512) s+=1; - if(bitfield & 1024) s+=4; - if(bitfield & 2048) s+=4; + if(bitfield & 1) s += 2; + if(bitfield & 8) s += 4; + if(bitfield & 16) s += 4; + if(bitfield & 32) s += 4; + if(bitfield & 64) s += 4; + if(bitfield & 256) s += 4; + if(bitfield & 512) s += 1; + if(bitfield & 1024) s += 4; + if(bitfield & 2048) s += 4; if(bitfield & 4096) // Version 2 or later { - s+=2; // for bitfield 2 - uint16_t bitfield2 = *(uint16_t*)(ptr+2); - if(bitfield & 2) s+=2; - if(bitfield & 4) s+=2; - if(bitfield2 & 1) s+= 4; - if(bitfield2 & 2) s+= 4; - if(bitfield2 & 4) s+= 4; - if(bitfield & 32768) s+=RMath::min(80,(uint8_t)ptr[4]+1); + s += 2; // for bitfield 2 + uint16_t bitfield2 = *(uint16_t*)(ptr + 2); + if(bitfield & 2) s += 2; + if(bitfield & 4) s += 2; + if(bitfield2 & 1) s += 4; + if(bitfield2 & 2) s += 4; + if(bitfield2 & 4) s += 4; + if(bitfield2 & 8) s += 4; + if(bitfield2 & 16) s += 4; + if(bitfield2 & 32) s += 4; + if(bitfield2 & 64) s += 4; + if(bitfield2 & 128) s += 4; + if(bitfield2 & 256) s += 4; + if(bitfield2 & 512) s += 4; + if(bitfield2 & 1024) s += 4; + if(bitfield2 & 2048) s += 4; + if(bitfield2 & 4096) s += 4; + if(bitfield2 & 8192) s += 4; + if(bitfield2 & 16384) s += 4; + if(bitfield2 & 32768) s += 4; + if(bitfield & 32768) s += RMath::min(80,(uint8_t)ptr[4] + 1); } else { - if(bitfield & 2) s+=1; - if(bitfield & 4) s+=1; - if(bitfield & 32768) s+=16; + if(bitfield & 2) s += 1; + if(bitfield & 4) s += 1; + if(bitfield & 32768) s += 16; } return s; } @@ -131,13 +152,13 @@ uint8_t GCode::computeBinarySize(char *ptr) // unsigned int bitfield) { void GCode::requestResend() { HAL::serialFlush(); - commandsReceivingWritePosition=0; + commandsReceivingWritePosition = 0; if(sendAsBinary) waitingForResend = 30; else waitingForResend = 14; Com::println(); - Com::printFLN(Com::tResend,lastLineNumber+1); + Com::printFLN(Com::tResend,lastLineNumber + 1); Com::printFLN(Com::tOk); } @@ -170,7 +191,7 @@ void GCode::checkAndPushCommand() } if(hasN()) { - if((((lastLineNumber + 1) & 0xffff) != (actLineNumber&0xffff))) + if((((lastLineNumber + 1) & 0xffff) != (actLineNumber & 0xffff))) { if(static_cast(lastLineNumber - actLineNumber) < 40) { @@ -214,7 +235,7 @@ void GCode::pushCommand() #if !ECHO_ON_EXECUTE commandsBuffered[bufferWriteIndex].echoCommand(); #endif - bufferWriteIndex = (bufferWriteIndex + 1) % GCODE_BUFFER_SIZE; + if(++bufferWriteIndex >= GCODE_BUFFER_SIZE) bufferWriteIndex = 0; bufferLength++; } @@ -273,7 +294,7 @@ void GCode::executeFString(FSTRINGPARAM(cmd)) { // Wait for a free place in command buffer // Scan next command from string - uint8_t comment=0; + uint8_t comment = 0; buflen = 0; do { @@ -283,12 +304,10 @@ void GCode::executeFString(FSTRINGPARAM(cmd)) if(comment) continue; buf[buflen++] = c; } - while(buflen<79); - if(buflen==0) // empty line ignore - { + while(buflen < 79); + if(buflen == 0) // empty line ignore continue; - } - buf[buflen]=0; + buf[buflen] = 0; // Send command into command buffer if(code.parseAscii((char *)buf,false) && (code.params & 518)) // Success { @@ -316,7 +335,7 @@ void GCode::readFromSerial() millis_t time = HAL::timeInMilliseconds(); if(!HAL::serialByteAvailable()) { - if((waitingForResend >= 0 || commandsReceivingWritePosition>0) && time - timeOfLastDataPacket > 200) + if((waitingForResend >= 0 || commandsReceivingWritePosition > 0) && time - timeOfLastDataPacket > 200) { requestResend(); // Something is wrong, a started line was not continued in the last second timeOfLastDataPacket = time; @@ -360,7 +379,7 @@ void GCode::readFromSerial() if(commandsReceivingWritePosition == binaryCommandSize) { GCode *act = &commandsBuffered[bufferWriteIndex]; - if(act->parseBinary(commandReceiving,true)) // Success + if(act->parseBinary(commandReceiving, true)) // Success act->checkAndPushCommand(); else requestResend(); @@ -494,11 +513,11 @@ void GCode::readFromSerial() bool GCode::parseBinary(uint8_t *buffer,bool fromSerial) { internalCommand = !fromSerial; - unsigned int sum1=0,sum2=0; // for fletcher-16 checksum + unsigned int sum1 = 0,sum2 = 0; // for fletcher-16 checksum // first do fletcher-16 checksum tests see // http://en.wikipedia.org/wiki/Fletcher's_checksum uint8_t *p = buffer; - uint8_t len = binaryCommandSize-2; + uint8_t len = binaryCommandSize - 2; while (len) { uint8_t tlen = len > 21 ? 21 : len; @@ -506,9 +525,9 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial) do { sum1 += *p++; - if(sum1>=255) sum1-=255; + if(sum1 >= 255) sum1 -= 255; sum2 += sum1; - if(sum2>=255) sum2-=255; + if(sum2 >= 255) sum2 -= 255; } while (--tlen); } @@ -524,8 +543,8 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial) } p = buffer; params = *(unsigned int *)p; - p+=2; - uint8_t textlen=16; + p += 2; + uint8_t textlen = 16; if(isV2()) { params2 = *(unsigned int *)p; @@ -536,87 +555,127 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial) else params2 = 0; if(params & 1) { - actLineNumber=N=*(uint16_t *)p; + actLineNumber = N = *(uint16_t *)p; p+=2; } if(isV2()) // Read G,M as 16 bit value { if(params & 2) { - M=*(uint16_t *)p; - p+=2; + M = *(uint16_t *)p; + p += 2; } if(params & 4) { - G=*(uint16_t *)p; - p+=2; + G = *(uint16_t *)p; + p += 2; } } else { if(params & 2) { - M=*p++; + M = *p++; } if(params & 4) { - G=*p++; + G = *p++; } } //if(code->params & 8) {memcpy(&code->X,p,4);p+=4;} if(params & 8) { - X=*(float *)p; - p+=4; + X = *(float *)p; + p += 4; } if(params & 16) { - Y=*(float *)p; - p+=4; + Y = *(float *)p; + p += 4; } if(params & 32) { - Z =*(float *)p; - p+=4; + Z = *(float *)p; + p += 4; } if(params & 64) { - E=*(float *)p; - p+=4; + E = *(float *)p; + p += 4; } if(params & 256) { - F=*(float *)p; - p+=4; + F = *(float *)p; + p += 4; } if(params & 512) { - T=*p++; + T = *p++; } if(params & 1024) { - S=*(int32_t*)p; - p+=4; + S = *(int32_t*)p; + p += 4; } if(params & 2048) { - P=*(int32_t*)p; - p+=4; + P = *(int32_t*)p; + p += 4; } if(hasI()) { - I=*(float *)p; - p+=4; + I = *(float *)p; + p += 4; } if(hasJ()) { - J=*(float *)p; - p+=4; + J = *(float *)p; + p += 4; } if(hasR()) { - R=*(float *)p; - p+=4; + R = *(float *)p; + p += 4; + } + if(hasD()) + { + D = *(float *)p; + p += 4; + } + if(hasC()) + { + C = *(float *)p; + p += 4; + } + if(hasH()) + { + H = *(float *)p; + p += 4; + } + if(hasA()) + { + A = *(float *)p; + p += 4; + } + if(hasB()) + { + B = *(float *)p; + p += 4; + } + if(hasK()) + { + K = *(float *)p; + p += 4; + } + if(hasL()) + { + L = *(float *)p; + p += 4; + } + if(hasO()) + { + O = *(float *)p; + p += 4; } if(hasString()) // set text pointer to string { @@ -772,6 +831,14 @@ bool GCode::parseAscii(char *line,bool fromSerial) params |= 4096; // Needs V2 for saving break; } + case 'D': + case 'd': + { + D = parseFloatValue(pos); + params2 |= 8; + params |= 4096; // Needs V2 for saving + break; + } case '*' : //checksum { uint8_t checksum_given = parseLongValue(pos); diff --git a/src/ArduinoDUE/Repetier/gcode.h b/src/ArduinoDUE/Repetier/gcode.h index 2bc2064..5bf0531 100644 --- a/src/ArduinoDUE/Repetier/gcode.h +++ b/src/ArduinoDUE/Repetier/gcode.h @@ -38,6 +38,15 @@ public: float I; float J; float R; + float D; + float C; + float H; + float A; + float B; + float K; + float L; + float O; + char *text; //text[17]; //moved the byte to the end and aligned ints on short boundary // Old habit from PC, which require alignments for data types such as int and long to be on 2 or 4 byte boundary @@ -114,6 +123,38 @@ public: { return ((params2 & 4)!=0); } + inline bool hasD() + { + return ((params2 & 8)!=0); + } + inline bool hasC() + { + return ((params2 & 16)!=0); + } + inline bool hasH() + { + return ((params2 & 32)!=0); + } + inline bool hasA() + { + return ((params2 & 64)!=0); + } + inline bool hasB() + { + return ((params2 & 128)!=0); + } + inline bool hasK() + { + return ((params2 & 256)!=0); + } + inline bool hasL() + { + return ((params2 & 512)!=0); + } + inline bool hasO() + { + return ((params2 & 1024)!=0); + } inline long getS(long def) { return (hasS() ? S : def); diff --git a/src/repetier communication protocol.txt b/src/repetier communication protocol.txt index 116dff0..5dc6044 100644 --- a/src/repetier communication protocol.txt +++ b/src/repetier communication protocol.txt @@ -1,5 +1,8 @@ repetier communication protocol +Intermediate description - a complete protocol definition will follow if have +the time to document it! + Why a new protocol? The current reprap communication is just sending the gcode string to the reprap. @@ -47,9 +50,30 @@ E : Bit 6 : 32-Bit Float : Bit 7 : always set to distinguish binary from ASCII line. F : Bit 8 : 32-Bit Float T : Bit 9 : 8 Bit Integer -S : Bit 10 : 16 Bit Value +S : Bit 10 : 32 Bit Integer P : Bit 11 : 32 Bit Integer -Text : Bit 15 : 8 Bit size + Data +V2 : Bit 12 : Version 2 command for additional commands/sizes +Ext : Bit 13 : There are 2 more bytes following with Bits, only for future versions +Int :Bit 14 : Marks it as internal command, +Text : Bit 15 : 16 Byte ASCII String terminated with 0 + +If version 2 is set, 2 more bytes with bitfields follow: +I : Bit 0 : 32-Bit float +J : Bit 1 : 32-Bit float +R : Bit 2 : 32-Bit float +D : Bit 3 : 32-Bit float (V3) +C : Bit 4 : 32-bit float (V3) +H : Bit 5 : 32-Bit float (V3) +A : Bit 6 : 32-Bit float (V3) +B : Bit 7 : 32-Bit float (V3) +K : Bit 8 : 32-Bit float (V3) +L : Bit 9 : 32-Bit float (V3) +O : Bit 10 : 32-Bit float (V3) + +Bit 2-15 reserved +If Text bit is set in V2, the text length is send as byte 5 Text follows at +the end just before the checksum. + A GCode line is transformed into a binary parameterization. 16 bit integer with given parameter set @@ -65,7 +89,15 @@ if bit 8 set: 8 bit T value if bit 9 set: 8 bit string length + string data 16 Bit checksum -The checksum is computed by Fletcher-16 checksum algorithm. +Protocol version 2 extension: +The existence of M codes > 255 and additional parameter made it necessary to +introduce version 2. Version 2 code is indicated by setting V2 bit 12 in the bits field. +If the extra data is not needed, it is preferred to use V1 command to send/store data. + +First main difference is G and M codes are 16 bit in V2. +Second difference are text codes send. + +The checksum is computed by Fletcher-16 checksum algorithm (using modulus 255). See http://en.wikipedia.org/wiki/Fletcher's_checksum Advantage: We build checksum over checksum and both bytes are 0 if correct.