First steps at marlin compatibility.

This commit is contained in:
Rob Giseburt
2017-01-16 12:50:56 -06:00
parent 7ee1f1ae45
commit c2158b9662
9 changed files with 210 additions and 43 deletions
+5 -1
View File
@@ -34,6 +34,7 @@
#include "config.h"
#include "hardware.h" // Note: hardware.h is specific to the hardware target selected
#include "settings.h"
/* Defines, Macros, and Assorted Parameters */
@@ -374,7 +375,6 @@ typedef struct GCodeState { // Gcode model state - used by model, pl
coord_system = ABSOLUTE_COORDS;
tool = 0;
tool_select = 0;
};
} GCodeState_t;
@@ -401,6 +401,10 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used
// float cutter_radius; // D - cutter radius compensation (0 is off)
// float cutter_length; // H - cutter length compensation (0 is off)
#if MARLIN_COMPAT_ENABLED == true
bool marlin_flavor;
#endif
uint16_t magic_end;
} GCodeStateX_t;
+2 -2
View File
@@ -205,8 +205,8 @@ char *get_status_message(stat_t status);
#define STAT_VALUE_TYPE_ERROR 116 // JSON value does not agree with variable type
#define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored
#define STAT_ERROR_118 118
#define STAT_ERROR_119 119
#define STAT_CHECKSUM_MATCH_FAILED 118 // the provided checksum didn't match
#define STAT_LINE_NUMBER_OUT_OF_SEQUENCE 119
#define STAT_ERROR_120 120
#define STAT_ERROR_121 121
+6
View File
@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
D44E72C11D663B0300ECD5DD /* coolant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44E72C01D663B0300ECD5DD /* coolant.cpp */; };
D457117C17053EFA00EA19A8 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = D457117B17053EFA00EA19A8 /* Makefile */; };
D4694F9E1E295B5E00F813BA /* marlin_compatibility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4694F9C1E295B5E00F813BA /* marlin_compatibility.cpp */; };
D48F5A56172CB1FA00D0E055 /* canonical_machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48F5A40172CB1F900D0E055 /* canonical_machine.cpp */; };
D48F5A57172CB1FA00D0E055 /* config_app.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48F5A41172CB1F900D0E055 /* config_app.cpp */; };
D48F5A58172CB1FA00D0E055 /* config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48F5A42172CB1F900D0E055 /* config.cpp */; };
@@ -59,6 +60,8 @@
D44E72C21D663B0F00ECD5DD /* coolant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coolant.h; sourceTree = "<group>"; };
D4522DC91C45F41D0086AAE6 /* g2core_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g2core_info.h; sourceTree = "<group>"; };
D457117B17053EFA00EA19A8 /* Makefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile; sourceTree = "<group>"; usesTabs = 1; xcLanguageSpecificationIdentifier = xcode.lang.sh; };
D4694F9C1E295B5E00F813BA /* marlin_compatibility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = marlin_compatibility.cpp; sourceTree = "<group>"; };
D4694F9D1E295B5E00F813BA /* marlin_compatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = marlin_compatibility.h; sourceTree = "<group>"; };
D47B744C1D4925B4004FAB53 /* device */ = {isa = PBXFileReference; lastKnownFileType = folder; path = device; sourceTree = "<group>"; };
D48F5A40172CB1F900D0E055 /* canonical_machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = canonical_machine.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
D48F5A41172CB1F900D0E055 /* config_app.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = config_app.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -160,6 +163,8 @@
D48F5A74172CB21100D0E055 /* json_parser.h */,
D48F5A4A172CB1FA00D0E055 /* kinematics.cpp */,
D48F5A75172CB21100D0E055 /* kinematics.h */,
D4694F9C1E295B5E00F813BA /* marlin_compatibility.cpp */,
D4694F9D1E295B5E00F813BA /* marlin_compatibility.h */,
D48F5A4C172CB1FA00D0E055 /* persistence.cpp */,
D48F5A76172CB21100D0E055 /* persistence.h */,
D48F5A4D172CB1FA00D0E055 /* plan_arc.cpp */,
@@ -420,6 +425,7 @@
D457117C17053EFA00EA19A8 /* Makefile in Sources */,
D4B657A718B5C23C00F8616C /* pwm.cpp in Sources */,
D44E72C11D663B0300ECD5DD /* coolant.cpp in Sources */,
D4694F9E1E295B5E00F813BA /* marlin_compatibility.cpp in Sources */,
D4B657A318B5C21600F8616C /* cycle_probing.cpp in Sources */,
D4D6453919BCAE3F0053705B /* plan_zoid.cpp in Sources */,
D4B657A218B5C21600F8616C /* cycle_jogging.cpp in Sources */,
+55 -26
View File
@@ -22,15 +22,20 @@
#include "controller.h"
#include "gcode_parser.h"
#include "canonical_machine.h"
#include "settings.h"
#include "spindle.h"
#include "coolant.h"
#include "util.h"
#include "xio.h" // for char definitions
#if MARLIN_COMPAT_ENABLED == true
#include "marlin_compatibility.h"
#endif
// Structures used by Gcode parser
typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context
uint8_t next_action; // handles G modal group 1 moves & non-modals
cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89
uint8_t program_flow; // used only by the gcode_parser
@@ -116,17 +121,18 @@ GCodeValue_t gv; // gcode input values
GCodeFlag_t gf; // gcode input flags
// local helper functions and macros
static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag);
static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value);
static stat_t _point(float value);
static stat_t _validate_gcode_block(char *active_comment);
static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs
static stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block
void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag);
stat_t _get_next_gcode_word(char **pstr, char *letter, float *value);
stat_t _point(float value);
stat_t _verify_checksum(char *str);
stat_t _validate_gcode_block(char *active_comment);
stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs
stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block
#define SET_MODAL(m,parm,val) ({gv.parm=val; gf.parm=true; gp.modals[m]=true; break;})
#define SET_NON_MODAL(parm,val) ({gv.parm=val; gf.parm=true; break;})
#define EXEC_FUNC(f,v) if(gf.v) { status=f(gv.v);}
/*
* gcode_parser_init()
*/
@@ -150,6 +156,11 @@ stat_t gcode_parser(char *block)
char *active_comment = &none; // gcode comment or NUL string
uint8_t block_delete_flag;
stat_t check_ret = _verify_checksum(str);
if (check_ret != STAT_OK) {
return check_ret;
}
_normalize_gcode_block(str, &active_comment, &block_delete_flag);
// TODO, now MSG is put in the active comment, handle that.
@@ -171,6 +182,24 @@ stat_t gcode_parser(char *block)
return(_parse_gcode_block(block, active_comment));
}
/*
* _verify_checksum() - ensure that, if there is a checksum, that it's valid
*
* Returns STAT_OK is it's valid.
* Returns STAT_CHECKSUM_MATCH_FAILED if the checksum doesn't match.
*/
stat_t _verify_checksum(char *str)
{
#if MARLIN_COMPAT_ENABLED == true
if (true == cm.gmx.marlin_flavor) {
return marlin_verify_checksum(str);
}
#endif
// for now, always assume it's ok
return STAT_OK;
}
/*
* _normalize_gcode_block() - normalize a block (line) of gcode in place
*
@@ -205,9 +234,9 @@ stat_t gcode_parser(char *block)
* - block_delete_flag is set true if block delete encountered, false otherwise
*/
static char _normalize_scratch[RX_BUFFER_MIN_SIZE];
char _normalize_scratch[RX_BUFFER_MIN_SIZE];
static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag)
void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag)
{
_normalize_scratch[0] = 0;
@@ -435,7 +464,7 @@ static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *bl
* G0X... is not interpreted as hexadecimal. This is trapped.
*/
static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
{
if (**pstr == NUL) { return (STAT_COMPLETE); } // no more words
@@ -467,7 +496,7 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
* _point() - isolate the decimal point value as an integer
*/
static uint8_t _point(float value)
uint8_t _point(const float value)
{
return((uint8_t)(value*10 - trunc(value)*10)); // isolate the decimal point as an int
}
@@ -476,7 +505,7 @@ static uint8_t _point(float value)
* _validate_gcode_block() - check for some gross Gcode block semantic violations
*/
static stat_t _validate_gcode_block(char *active_comment)
stat_t _validate_gcode_block(char *active_comment)
{
// Check for modal group violations. From NIST, section 3.4 "It is an error to put
// a G-code from group 1 and a G-code from group 0 on the same line if both of them
@@ -505,7 +534,7 @@ static stat_t _validate_gcode_block(char *active_comment)
* contain only uppercase characters and signed floats (no whitespace).
*/
static stat_t _parse_gcode_block(char *buf, char *active_comment)
stat_t _parse_gcode_block(char *buf, char *active_comment)
{
char *pstr = (char *)buf; // persistent pointer into gcode block for parsing words
char letter; // parsed letter, eg.g. G or X or Y
@@ -678,7 +707,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment)
case 'K': SET_NON_MODAL (arc_offset[2], value);
case 'L': SET_NON_MODAL (L_word, value);
case 'R': SET_NON_MODAL (arc_radius, value);
case 'N': SET_NON_MODAL (linenum,(uint32_t)value); // line number
case 'N': SET_NON_MODAL (linenum,(uint32_t)value); // line number
default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
}
if(status != STAT_OK) break;
@@ -728,7 +757,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment)
* to calling the canonical functions (which do the unit conversions)
*/
static stat_t _execute_gcode_block(char *active_comment)
stat_t _execute_gcode_block(char *active_comment)
{
stat_t status = STAT_OK;
@@ -754,7 +783,7 @@ static stat_t _execute_gcode_block(char *active_comment)
if (gf.mto_control) { // manual traverse override
ritorno(cm_mto_control(gv.P_word, gf.P_word));
}
if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell
ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block
}
@@ -764,23 +793,23 @@ static stat_t _execute_gcode_block(char *active_comment)
switch (gv.next_action) { // Tool length offsets
case NEXT_ACTION_SET_TL_OFFSET: { // G43
ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, false));
break;
ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, false));
break;
}
case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2
ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, true));
break;
ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, true));
break;
}
case NEXT_ACTION_CANCEL_TL_OFFSET: { // G49
ritorno(cm_cancel_tl_offset());
break;
ritorno(cm_cancel_tl_offset());
break;
}
}
EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59
if (gf.path_control) { // G61, G61.1, G64
status = cm_set_path_control(MODEL, gv.path_control);
status = cm_set_path_control(MODEL, gv.path_control);
}
EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91
@@ -802,10 +831,10 @@ static stat_t _execute_gcode_block(char *active_comment)
case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gv.target, gf.target, true, false); break;} // G38.4
case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gv.target, gf.target, false, false); break;}// G38.5
case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word,
case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word,
gv.L_word, gf.L_word,
gv.target, gf.target); break;}
case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gv.target, gf.target); break;}// G92
case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1
case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2
+89
View File
@@ -0,0 +1,89 @@
/*
* marlin_compatibility.cpp - support for marlin protocol and gcode
* This file is part of the g2core project
*
* Copyright (c) 2017 Alden S. Hart, Jr.
* Copyright (c) 2017 Rob Giseburt
*
* This file ("the software") is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 as published by the
* Free Software Foundation. You should have received a copy of the GNU General Public
* License, version 2 along with the software. If not, see <http://www.gnu.org/licenses/>.
*
* THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "g2core.h" // #1
#include "config.h" // #2
#include "settings.h"
#if MARLIN_COMPAT_ENABLED == true
#include "controller.h"
#include "gcode_parser.h"
#include "canonical_machine.h"
#include "util.h"
#include "xio.h" // for char definitions
// Structures used
// local helper functions and macros
/*
* marlin_verify_checksum() - check to see if we have a line number (cheaply) and a valid checksum
*/
stat_t marlin_verify_checksum(char *str)
{
if (*str != 'N') { return STAT_OK; } // we only check if we have a line number
char checksum = 0;
char c = *str++;
while (c && (c != '*')) {
checksum ^= c;
c = *str++;
}
// c might be 0 here, in which case we didn't get a checksum and we return STAT_OK
if ((c == '*') && strtol(str, NULL, 10) != checksum) {
return STAT_CHECKSUM_MATCH_FAILED;
}
return STAT_OK;
}
/***********************************************************************************
* CONFIGURATION AND INTERFACE FUNCTIONS
* Functions to get and set variables from the cfgArray table
***********************************************************************************/
//stat_t gc_get_gc(nvObj_t *nv)
//{
// ritorno(nv_copy_string(nv, cs.saved_buf));
// nv->valuetype = TYPE_STRING;
// return (STAT_OK);
//}
//
//stat_t gc_run_gc(nvObj_t *nv)
//{
// return(gcode_parser(*nv->stringp));
//}
/***********************************************************************************
* TEXT MODE SUPPORT
* Functions to print variables from the cfgArray table
***********************************************************************************/
#ifdef __TEXT_MODE
// no text mode functions here. Move along
#endif // __TEXT_MODE
#endif // MARLIN_COMPAT_ENABLED == true
+33
View File
@@ -0,0 +1,33 @@
/*
* marlin_compatibility.cpp - support for marlin protocol and gcode
* This file is part of the g2core project
*
* Copyright (c) 2017 Alden S. Hart, Jr.
* Copyright (c) 2017 Rob Giseburt
*
* This file ("the software") is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 as published by the
* Free Software Foundation. You should have received a copy of the GNU General Public
* License, version 2 along with the software. If not, see <http://www.gnu.org/licenses/>.
*
* THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef MARLIN_COMPAT_H_ONCE
#define MARLIN_COMPAT_H_ONCE
#include "g2core.h" // #1
#include "config.h" // #2
/*
* Global Scope Functions
*/
stat_t marlin_verify_checksum(char *str);
#endif // End of include guard: MARLIN_COMPAT_H_ONCE
+14 -14
View File
@@ -103,13 +103,13 @@
#define M1_POWER_LEVEL 0.4 // 1mp
// 80 steps/mm at 1/16 microstepping = 40 mm/rev
#define M3_MOTOR_MAP AXIS_Y
#define M3_STEP_ANGLE 1.8
#define M3_TRAVEL_PER_REV 40.64
#define M3_MICROSTEPS 32
#define M3_POLARITY 0
#define M3_POWER_MODE MOTOR_POWER_MODE
#define M3_POWER_LEVEL 0.4
#define M5_MOTOR_MAP AXIS_Y
#define M5_STEP_ANGLE 1.8
#define M5_TRAVEL_PER_REV 40.64
#define M5_MICROSTEPS 32
#define M5_POLARITY 0
#define M5_POWER_MODE MOTOR_POWER_MODE
#define M5_POWER_LEVEL 0.4
#define M2_MOTOR_MAP AXIS_Z
#define M2_STEP_ANGLE 1.8
@@ -129,13 +129,13 @@
#define M4_POWER_LEVEL 0.4
// 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev
#define M5_MOTOR_MAP AXIS_B
#define M5_STEP_ANGLE 1.8
#define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev
#define M5_MICROSTEPS 32
#define M5_POLARITY 0
#define M5_POWER_MODE MOTOR_POWER_MODE
#define M5_POWER_LEVEL 0.35
#define M3_MOTOR_MAP AXIS_B
#define M3_STEP_ANGLE 1.8
#define M3_TRAVEL_PER_REV 360 // degrees moved per motor rev
#define M3_MICROSTEPS 32
#define M3_POLARITY 0
#define M3_POWER_MODE MOTOR_POWER_MODE
#define M3_POWER_LEVEL 0.35
// *** axis settings **********************************************************************************
@@ -57,6 +57,7 @@
// Communications and reporting settings
#define MARLIN_COMPAT_ENABLED true // enable marlin compatibility mode
#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE
#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS
+5
View File
@@ -171,6 +171,11 @@
//#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo"
#endif
#ifndef MARLIN_COMPAT_ENABLED
#define MARLIN_COMPAT_ENABLED false // boolean, either true or false
#endif
// *** Gcode Startup Defaults *** //
#ifndef GCODE_DEFAULT_UNITS