#include <string>
using std::string;
-#include "mbed.h"
#include "libs/Module.h"
#include "libs/Kernel.h"
#include "utils/Gcode.h"
#include "libs/nuts_bolts.h"
#include "GcodeDispatch.h"
#include "modules/robot/Player.h"
+#include "libs/SerialMessage.h"
+#include "libs/StreamOutput.h"
GcodeDispatch::GcodeDispatch(){}
// Called when the module has just been loaded
void GcodeDispatch::on_module_loaded() {
this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
+ currentline = -1;
}
// When a command is received, if it is a Gcode, dispatch it as an object via an event
string possible_command = new_message.message;
char first_char = possible_command[0];
- if( first_char == 'G' || first_char == 'M' || first_char == 'T' || first_char == 'S' ){
-
+ int ln = 0;
+ int cs = 0;
+ if( first_char == 'G' || first_char == 'M' || first_char == 'T' || first_char == 'S' || first_char == 'N' ){
+
+ //Get linenumber
+ if( first_char == 'N' ){
+ Gcode full_line = Gcode();
+ full_line.command = possible_command;
+ full_line.stream = new_message.stream;
+ ln = (int) full_line.get_value('N');
+ int chksum = (int) full_line.get_value('*');
+
+ //Strip checksum value from possible_command
+ size_t chkpos = possible_command.find_first_of("*");
+ possible_command = possible_command.substr(0, chkpos);
+ //Calculate checksum
+ if( chkpos != string::npos ){
+ for(int i = 0; possible_command[i] != '*' && possible_command[i] != NULL; i++)
+ cs = cs ^ possible_command[i];
+ cs &= 0xff; // Defensive programming...
+ cs -= chksum;
+ }
+ //Strip line number value from possible_command
+ size_t lnsize = possible_command.find_first_of(" ") + 1;
+ possible_command = possible_command.substr(lnsize);
+ }else{
+ //Assume checks succeeded
+ cs = 0x00;
+ ln = currentline + 1;
+ }
+
//Remove comments
size_t comment = possible_command.find_first_of(";");
if( comment != string::npos ){ possible_command = possible_command.substr(0, comment); }
- // Dispatch
+ //Prepare gcode for dispatch
Gcode gcode = Gcode();
gcode.command = possible_command;
- this->kernel->call_event(ON_GCODE_RECEIVED, &gcode );
-
- new_message.stream->printf("ok\r\n");
+ gcode.stream = new_message.stream;
+
+ //Catch message if it is M110: Set Current Line Number
+ if( gcode.has_letter('M') ){
+ if( ((int) gcode.get_value('M')) == 110 ){
+ currentline = ln;
+ new_message.stream->printf("ok\r\n");
+ return;
+ }
+ }
+
+ //If checksum passes then process message, else request resend
+ int nextline = currentline + 1;
+ if( cs == 0x00 && ln == nextline ){
+ if( first_char == 'N' )
+ currentline = nextline;
+ //Dispatch message!
+ this->kernel->call_event(ON_GCODE_RECEIVED, &gcode );
+ new_message.stream->printf("ok\r\n");
+ }else{
+ //Request resend
+ new_message.stream->printf("rs N%d\r\n", nextline, ((int) gcode.get_value('M')), possible_command.c_str());
+ }
- // Ignore comments
- }else if( first_char == ';' || first_char == '(' ){
+ // Ignore comments and blank lines
+ }else if( first_char == ';' || first_char == '(' || first_char == ' ' || first_char == '\n' || first_char == '\r' ){
new_message.stream->printf("ok\r\n");
}
}