smoothie port to mbed online compiler (smoothieware.org)

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GcodeDispatch.cpp Source File

GcodeDispatch.cpp

00001 /*  
00002       This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
00003       Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
00004       Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00005       You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>. 
00006 */
00007 
00008 #include <string>
00009 using std::string;
00010 #include "libs/Module.h"
00011 #include "libs/Kernel.h"
00012 #include "utils/Gcode.h"
00013 #include "libs/nuts_bolts.h"
00014 #include "GcodeDispatch.h"
00015 #include "modules/robot/Player.h" 
00016 #include "libs/SerialMessage.h"
00017 #include "libs/StreamOutput.h"
00018 
00019 GcodeDispatch::GcodeDispatch(){}
00020 
00021 // Called when the module has just been loaded
00022 void GcodeDispatch::on_module_loaded() {
00023     this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
00024     currentline = -1;
00025 }
00026 
00027 // When a command is received, if it is a Gcode, dispatch it as an object via an event
00028 void GcodeDispatch::on_console_line_received(void * line){
00029     SerialMessage new_message = *static_cast<SerialMessage*>(line);
00030     string possible_command = new_message.message;    
00031 
00032     char first_char = possible_command[0];
00033     int ln = 0;
00034     int cs = 0;
00035     if( first_char == 'G' || first_char == 'M' || first_char == 'T' || first_char == 'N' ){ 
00036 
00037         //Get linenumber
00038         if( first_char == 'N' ){ 
00039             Gcode full_line = Gcode();
00040             full_line.command = possible_command;
00041             full_line.stream = new_message.stream;
00042             ln = (int) full_line.get_value('N');
00043             int chksum = (int) full_line.get_value('*');
00044 
00045             //Catch message if it is M110: Set Current Line Number
00046             if( full_line.has_letter('M') ){
00047                 if( ((int) full_line.get_value('M')) == 110 ){
00048                     currentline = ln;
00049                     new_message.stream->printf("ok\r\n");
00050                     return;
00051                 }
00052             }
00053 
00054             //Strip checksum value from possible_command
00055             size_t chkpos = possible_command.find_first_of("*");
00056             possible_command = possible_command.substr(0, chkpos); 
00057             //Calculate checksum
00058             if( chkpos != string::npos ){ 
00059                 for(int i = 0; possible_command[i] != '*' && possible_command[i] != NULL; i++)
00060                     cs = cs ^ possible_command[i];
00061                 cs &= 0xff;  // Defensive programming...
00062                 cs -= chksum;
00063             }
00064             //Strip line number value from possible_command
00065             size_t lnsize = possible_command.find_first_of(" ") + 1;
00066             possible_command = possible_command.substr(lnsize); 
00067 
00068         }else{
00069             //Assume checks succeeded
00070             cs = 0x00;
00071             ln = currentline + 1;
00072         }
00073 
00074         //Remove comments
00075         size_t comment = possible_command.find_first_of(";");
00076         if( comment != string::npos ){ possible_command = possible_command.substr(0, comment); }
00077 
00078         //If checksum passes then process message, else request resend
00079         int nextline = currentline + 1;
00080         if( cs == 0x00 && ln == nextline ){
00081             if( first_char == 'N' ) {
00082                 currentline = nextline;
00083             }
00084 
00085             while(possible_command.size() > 0) {
00086                 size_t nextcmd = possible_command.find_first_of("GMT", possible_command.find_first_of("GMT")+1);
00087                 string single_command;
00088                 if(nextcmd == string::npos) {
00089                     single_command = possible_command;
00090                     possible_command = "";
00091                 }
00092                 else {
00093                     single_command = possible_command.substr(0,nextcmd);
00094                     possible_command = possible_command.substr(nextcmd);
00095                 }
00096                 //Prepare gcode for dispatch
00097                 Gcode gcode = Gcode();
00098                 gcode.command = single_command;
00099                 gcode.stream = new_message.stream;
00100 
00101                 //Dispatch message!
00102                 this->kernel->call_event(ON_GCODE_RECEIVED, &gcode );
00103                 new_message.stream->printf("ok\r\n");
00104             }
00105         }else{
00106             //Request resend
00107             new_message.stream->printf("rs N%d\r\n", nextline);
00108         }
00109 
00110     // Ignore comments and blank lines
00111     }else if( first_char == ';' || first_char == '(' || first_char == ' ' || first_char == '\n' || first_char == '\r' ){
00112         new_message.stream->printf("ok\r\n");
00113     }
00114 }
00115