Protocol V3 and Code Formating

Protocol V3 and Code Formating
pull/71/head
Luc 2015-02-26 13:18:48 +08:00
rodzic 7e2b60468e
commit c7d79c7264
7 zmienionych plików z 241 dodań i 97 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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")

Wyświetl plik

@ -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,

Wyświetl plik

@ -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

Wyświetl plik

@ -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<uint16_t>(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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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.