mirror of
https://github.com/synthetos/g2.git
synced 2026-09-25 08:03:37 +08:00
Another pass at Marlin Compatibility mode. Functional enough to test.
This commit is contained in:
@@ -594,7 +594,10 @@ static float _calc_ABC(const uint8_t axis, const float target[])
|
||||
if ((cm.a[axis].axis_mode == AXIS_STANDARD) || (cm.a[axis].axis_mode == AXIS_INHIBITED)) {
|
||||
return(target[axis]); // no mm conversion - it's in degrees
|
||||
}
|
||||
return(_to_millimeters(target[axis]) * 360 / (2 * M_PI * cm.a[axis].radius));
|
||||
|
||||
// radius mode
|
||||
|
||||
return (_to_millimeters(target[axis]) * 360.0 / (2.0 * M_PI * cm.a[axis].radius));
|
||||
}
|
||||
|
||||
void cm_set_model_target(const float target[], const bool flags[])
|
||||
@@ -624,9 +627,27 @@ void cm_set_model_target(const float target[], const bool flags[])
|
||||
} else {
|
||||
tmp = _calc_ABC(axis, target);
|
||||
}
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
// If we are in absolute mode (generally), but the extruder is relative,
|
||||
// then we adjust the extruder to a relative position
|
||||
if (cm.gmx.marlin_flavor && (cm.a[axis].axis_mode == AXIS_RADIUS)) {
|
||||
if (cm.gmx.extruder_mode == EXTRUDER_MOVES_ABSOLUTE) {
|
||||
cm.gm.target[axis] = tmp + cm_get_active_coord_offset(axis);
|
||||
}
|
||||
else if (cm.gmx.extruder_mode == EXTRUDER_MOVES_RELATIVE) {
|
||||
cm.gm.target[axis] += tmp;
|
||||
}
|
||||
// TODO
|
||||
// else {
|
||||
// cm.gm.target[axis] += tmp * cm.gmx.volume_to_filament_length[axis-3];
|
||||
// }
|
||||
}
|
||||
else
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
if (cm.gm.distance_mode == ABSOLUTE_DISTANCE_MODE) {
|
||||
cm.gm.target[axis] = tmp + cm_get_active_coord_offset(axis); // sacidu93's fix to Issue #22
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cm.gm.target[axis] += tmp;
|
||||
}
|
||||
}
|
||||
@@ -2024,6 +2045,14 @@ stat_t cm_json_command(char *json_string)
|
||||
return mp_json_command(json_string);
|
||||
}
|
||||
|
||||
/*
|
||||
* cm_json_command_immediate() - M100.1
|
||||
*/
|
||||
stat_t cm_json_command_immediate(char *json_string)
|
||||
{
|
||||
return mp_json_command_immediate(json_string);
|
||||
}
|
||||
|
||||
/*
|
||||
* cm_json_wait() - M102
|
||||
*/
|
||||
|
||||
@@ -180,8 +180,16 @@ typedef enum { // these are in order to optimized CASE
|
||||
NEXT_ACTION_JSON_WAIT, // M101
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP, // 104, 109
|
||||
NEXT_ACTION_MARLIN_SET_BED_TEMP, // 140, 190
|
||||
NEXT_ACTION_MARLIN_PRINT_TEMPERATURES, // M105
|
||||
NEXT_ACTION_MARLIN_PRINT_POSITION, // M114
|
||||
NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP, // M104, M109
|
||||
NEXT_ACTION_MARLIN_SET_BED_TEMP, // M140, M190
|
||||
NEXT_ACTION_MARLIN_CANCEL_WAIT_TEMP, // M108
|
||||
NEXT_ACTION_MARLIN_TRAM_BED, // G29
|
||||
NEXT_ACTION_MARLIN_SET_FAN_SPEED, // M106
|
||||
NEXT_ACTION_MARLIN_STOP_FAN, // M107
|
||||
NEXT_ACTION_MARLIN_DISABLE_MOTORS, // M84
|
||||
NEXT_ACTION_MARLIN_DISPLAY_ON_SCREEN, // M117
|
||||
#endif
|
||||
} cmNextAction;
|
||||
|
||||
@@ -384,6 +392,14 @@ typedef struct GCodeState { // Gcode model state - used by model, pl
|
||||
};
|
||||
} GCodeState_t;
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
enum cmExtruderMode {
|
||||
EXTRUDER_MOVES_ABSOLUTE = 0, // M82
|
||||
EXTRUDER_MOVES_RELATIVE, // M83
|
||||
EXTRUDER_MOVES_VOLUMETRIC // Ultimaker2Marlin
|
||||
};
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
|
||||
typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used by model and arcs
|
||||
uint16_t magic_start; // magic number to test memory integrity
|
||||
uint8_t next_action; // handles G modal group 1 moves & non-modals
|
||||
@@ -409,7 +425,8 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
bool marlin_flavor;
|
||||
#endif
|
||||
cmExtruderMode extruder_mode; // Mode of the extruder - changes how "E" is interpreted
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
|
||||
uint16_t magic_end;
|
||||
|
||||
@@ -679,6 +696,7 @@ void cm_optional_program_stop(void); // M1
|
||||
void cm_program_end(void); // M2
|
||||
|
||||
stat_t cm_json_command(char *json_string); // M100
|
||||
stat_t cm_json_command_immediate(char *json_string); // M100.1
|
||||
stat_t cm_json_wait(char *json_string); // M102
|
||||
|
||||
/*--- Cycles ---*/
|
||||
|
||||
@@ -328,6 +328,18 @@ static stat_t _controller_state()
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _reset_comms_mode() - reset the communications mode (and other effected settings) after connection or disconnection
|
||||
*/
|
||||
void _reset_comms_mode() {
|
||||
// reset the communications mode
|
||||
cs.comm_mode = COMM_MODE;
|
||||
js.json_mode = (COMM_MODE < AUTO_MODE) ? COMM_MODE : JSON_MODE;
|
||||
sr.status_report_verbosity = STATUS_REPORT_VERBOSITY;
|
||||
qr.queue_report_verbosity = QUEUE_REPORT_VERBOSITY;
|
||||
}
|
||||
|
||||
/*
|
||||
* controller_set_connected(bool) - hook for xio to tell the controller that we
|
||||
* have/don't have a connection.
|
||||
@@ -335,6 +347,8 @@ static stat_t _controller_state()
|
||||
|
||||
void controller_set_connected(bool is_connected) {
|
||||
if (is_connected) {
|
||||
_reset_comms_mode();
|
||||
|
||||
cs.controller_state = CONTROLLER_CONNECTED; // we JUST connected
|
||||
} else { // we just disconnected from the last device, we'll expect a banner again
|
||||
cs.controller_state = CONTROLLER_NOT_CONNECTED;
|
||||
@@ -353,6 +367,8 @@ void controller_set_muted(bool is_muted) {
|
||||
const bool only_to_muted = true;
|
||||
xio_writeline("{\"muted\":true}\n", only_to_muted);
|
||||
} else {
|
||||
_reset_comms_mode();
|
||||
|
||||
// one channel just got unmuted, announce it (except to the muted)
|
||||
xio_writeline("{\"muted\":false}\n");
|
||||
}
|
||||
|
||||
+6
-6
@@ -206,7 +206,7 @@ char *get_status_message(stat_t status);
|
||||
|
||||
#define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored
|
||||
#define STAT_CHECKSUM_MATCH_FAILED 118 // the provided checksum didn't match
|
||||
#define STAT_LINE_NUMBER_OUT_OF_SEQUENCE 119
|
||||
#define STAT_LINE_NUMBER_OUT_OF_SEQUENCE 119 // the provided line number was out of sequence
|
||||
|
||||
#define STAT_ERROR_120 120
|
||||
#define STAT_ERROR_121 121
|
||||
@@ -315,7 +315,7 @@ char *get_status_message(stat_t status);
|
||||
|
||||
#define STAT_TEMPERATURE_CONTROL_ERROR 209 // temperature controls err'd out
|
||||
|
||||
#define STAT_ERROR_210 210
|
||||
#define STAT_G29_NOT_CONFIGURED 210
|
||||
#define STAT_ERROR_211 211
|
||||
#define STAT_ERROR_212 212
|
||||
#define STAT_ERROR_213 213
|
||||
@@ -501,9 +501,9 @@ static const char stat_113[] = "JSON string too long";
|
||||
static const char stat_114[] = "JSON txt fields cannot be nested";
|
||||
static const char stat_115[] = "JSON maximum nesting depth exceeded";
|
||||
static const char stat_116[] = "JSON value does not agree with variable type";
|
||||
static const char stat_117[] = "117";
|
||||
static const char stat_118[] = "118";
|
||||
static const char stat_119[] = "119";
|
||||
static const char stat_117[] = "Input from a muted channel was ignored";
|
||||
static const char stat_118[] = "The provided checksum didn't match";
|
||||
static const char stat_119[] = "The provided line number was out of sequence";
|
||||
|
||||
static const char stat_120[] = "120";
|
||||
static const char stat_121[] = "121";
|
||||
@@ -606,7 +606,7 @@ static const char stat_207[] = "Kill job";
|
||||
static const char stat_208[] = "No GPIO for this value";
|
||||
static const char stat_209[] = "209";
|
||||
|
||||
static const char stat_210[] = "210";
|
||||
static const char stat_210[] = "Marlin G29 command was not configured at compile-time";
|
||||
static const char stat_211[] = "211";
|
||||
static const char stat_212[] = "212";
|
||||
static const char stat_213[] = "213";
|
||||
|
||||
+167
-38
@@ -74,10 +74,9 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context
|
||||
bool sso_control; // M51 spindle speed override control
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
bool marlin_temp_requested; // M105 temperature report request (Marlin-only)
|
||||
bool marlin_position_requested; // M114 position report request (Marlin-only)
|
||||
float E_word; // E - "extruder" - may be interpreted any number of ways
|
||||
|
||||
bool marlin_wait_for_temp; // M140 or M190 - wait for temperature (Marlin-only)
|
||||
bool marlin_relative_extruder_mode; // M82, M83 (Marlin-only)
|
||||
#endif
|
||||
} GCodeValue_t;
|
||||
|
||||
@@ -120,8 +119,11 @@ typedef struct GCodeFlags { // Gcode input flags
|
||||
bool sso_control;
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
bool marlin_temp_requested;
|
||||
bool marlin_position_requested;
|
||||
bool E_word;
|
||||
|
||||
bool marlin_wait_for_temp; // M140 or M190 - wait for temperature (Marlin-only)
|
||||
|
||||
bool marlin_relative_extruder_mode;
|
||||
#endif
|
||||
} GCodeFlag_t;
|
||||
|
||||
@@ -488,18 +490,31 @@ stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
|
||||
*letter = **pstr;
|
||||
(*pstr)++;
|
||||
|
||||
// X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255
|
||||
if ((**pstr == '0') && (*(*pstr+1) == 'X')) {
|
||||
*value = 0;
|
||||
(*pstr)++;
|
||||
return (STAT_OK); // pointer points to X
|
||||
}
|
||||
// // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255
|
||||
// if ((**pstr == '0') && (*(*pstr+1) == 'X')) {
|
||||
// *value = 0;
|
||||
// (*pstr)++;
|
||||
// return (STAT_OK); // pointer points to X
|
||||
// }
|
||||
//
|
||||
// // get-value general case
|
||||
// char *end = *pstr;
|
||||
// *value = strtof(*pstr, &end);
|
||||
|
||||
// get-value general case
|
||||
char *end;
|
||||
*value = strtof(*pstr, &end);
|
||||
char *end = *pstr;
|
||||
*value = c_atof(end);
|
||||
|
||||
if(end == *pstr) {
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
if (cm.gmx.marlin_flavor) {
|
||||
*value = 0;
|
||||
} else {
|
||||
return(STAT_BAD_NUMBER_FORMAT);
|
||||
}
|
||||
#else
|
||||
return(STAT_BAD_NUMBER_FORMAT);
|
||||
#endif
|
||||
} // more robust test then checking for value=0;
|
||||
*pstr = end;
|
||||
return (STAT_OK); // pointer points to next character after the word
|
||||
@@ -585,7 +600,14 @@ stat_t _parse_gcode_block(char *buf, char *active_comment)
|
||||
case 21: SET_MODAL (MODAL_GROUP_G6, units_mode, MILLIMETERS);
|
||||
case 28: {
|
||||
switch (_point(value)) {
|
||||
case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G28_POSITION);
|
||||
case 0: {
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
if (cm.gmx.marlin_flavor) {
|
||||
SET_NON_MODAL (next_action, NEXT_ACTION_SEARCH_HOME);
|
||||
}
|
||||
#endif
|
||||
SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G28_POSITION);
|
||||
}
|
||||
case 1: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G28_POSITION);
|
||||
case 2: SET_NON_MODAL (next_action, NEXT_ACTION_SEARCH_HOME);
|
||||
case 3: SET_NON_MODAL (next_action, NEXT_ACTION_SET_ABSOLUTE_ORIGIN);
|
||||
@@ -668,6 +690,10 @@ stat_t _parse_gcode_block(char *buf, char *active_comment)
|
||||
case 93: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, INVERSE_TIME_MODE);
|
||||
case 94: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_MINUTE_MODE);
|
||||
// case 95: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_REVOLUTION_MODE);
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
case 29: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_TRAM_BED);
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
|
||||
}
|
||||
break;
|
||||
@@ -695,19 +721,36 @@ stat_t _parse_gcode_block(char *buf, char *active_comment)
|
||||
}
|
||||
break;
|
||||
case 51: SET_MODAL (MODAL_GROUP_M9, sso_control, true);
|
||||
case 100: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC);
|
||||
case 100:
|
||||
switch (_point(value)) {
|
||||
case 0: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC);
|
||||
case 1: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_ASYNC);
|
||||
default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
|
||||
}
|
||||
break;
|
||||
case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT);
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
#warning MARLIN_COMPAT_ENABLED
|
||||
case 105: SET_NON_MODAL (marlin_temp_requested, true);
|
||||
case 114: SET_NON_MODAL (marlin_position_requested, true);
|
||||
case 105: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_PRINT_TEMPERATURES);
|
||||
case 114: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_PRINT_POSITION);
|
||||
|
||||
case 140: gv.marlin_wait_for_temp = true; // NO break!
|
||||
case 140: gf.marlin_wait_for_temp = true; // NO break!
|
||||
case 104: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP);
|
||||
|
||||
case 190: gv.marlin_wait_for_temp = true; // NO break!
|
||||
case 190: gf.marlin_wait_for_temp = true; // NO break!
|
||||
case 109: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_BED_TEMP);
|
||||
|
||||
case 108: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_CANCEL_WAIT_TEMP);
|
||||
|
||||
case 82: SET_NON_MODAL (marlin_relative_extruder_mode, false);
|
||||
case 83: SET_NON_MODAL (marlin_relative_extruder_mode, true);
|
||||
|
||||
case 106: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_FAN_SPEED);
|
||||
case 107: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_STOP_FAN);
|
||||
|
||||
case 117: return STAT_OK; //SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_DISPLAY_ON_SCREEN);
|
||||
|
||||
case 84: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_DISABLE_MOTORS);
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
|
||||
default: status = STAT_MCODE_COMMAND_UNSUPPORTED;
|
||||
@@ -734,6 +777,9 @@ stat_t _parse_gcode_block(char *buf, char *active_comment)
|
||||
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
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
case 'E': SET_NON_MODAL (E_word, value); // extruder value
|
||||
#endif // MARLIN_COMPAT_ENABLED
|
||||
default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
|
||||
}
|
||||
if(status != STAT_OK) break;
|
||||
@@ -792,33 +838,116 @@ stat_t _execute_gcode_block(char *active_comment)
|
||||
EXEC_FUNC(cm_set_feed_rate, F_word); // F
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
// adjust T real quick
|
||||
if (cm.gmx.marlin_flavor && gf.tool_select) {
|
||||
cm_select_tool(gv.tool_select); // We need to go ahead and apply to tool select
|
||||
}
|
||||
// Handle Marlin specifics
|
||||
// must be before we deal with S_word and P_word, since it MIGHT use those
|
||||
if (gf.marlin_temp_requested) { // M105
|
||||
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
|
||||
ritorno(marlin_request_temperature_report());
|
||||
}
|
||||
if (gf.marlin_position_requested) { // M114
|
||||
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
|
||||
ritorno(marlin_request_position_report());
|
||||
|
||||
// Deal with E
|
||||
EXEC_FUNC(cm_marlin_set_extruder_mode, marlin_relative_extruder_mode); // M82, M83
|
||||
if (gf.E_word) {
|
||||
cm.gmx.marlin_flavor = true; // E should ONLY be seen in marlin flavor
|
||||
|
||||
// Ennn T0 -> Annn
|
||||
if (cm.gm.tool_select == 0) {
|
||||
gf.target[AXIS_A] = true;
|
||||
gv.target[AXIS_A] = gv.E_word;
|
||||
}
|
||||
// Ennn T1 -> Bnnn
|
||||
else if (cm.gm.tool_select == 1) {
|
||||
gf.target[AXIS_B] = true;
|
||||
gv.target[AXIS_B] = gv.E_word;
|
||||
}
|
||||
else {
|
||||
return STAT_INPUT_VALUE_RANGE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
switch (gv.next_action) {
|
||||
case NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP: { // M104 or M140
|
||||
float temp = 0;
|
||||
if (gf.S_word) { temp = gv.S_word; }
|
||||
if (gf.P_word) { temp = gv.P_word; } // we treat them the same, for now
|
||||
status = marlin_set_temperature(cm.gm.tool_select, temp, gv.marlin_wait_for_temp);
|
||||
return status;
|
||||
case NEXT_ACTION_MARLIN_PRINT_TEMPERATURES: { // M105
|
||||
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
|
||||
ritorno(marlin_request_temperature_report());
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_PRINT_POSITION: { // M114
|
||||
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
|
||||
ritorno(marlin_request_position_report());
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP: // M104 or M140
|
||||
case NEXT_ACTION_MARLIN_SET_BED_TEMP: { // M109 or M190
|
||||
cm.gmx.marlin_flavor = true; // these gcodes are ONLY in marlin flavor
|
||||
float temp = 0;
|
||||
if (gf.S_word) { temp = gv.S_word; }
|
||||
if (gf.P_word) { temp = gv.P_word; } // we treat them the same, for now
|
||||
|
||||
// Note: tool is zero-based, so to gt he3 (the bed) we pass tool as 2
|
||||
status = marlin_set_temperature(2, temp, gv.marlin_wait_for_temp);
|
||||
uint8_t tool = (NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP == gv.next_action) ? cm.gm.tool_select : 2; // heat bed is 2 here, normally 3
|
||||
|
||||
ritorno(marlin_set_temperature(tool, temp, gf.marlin_wait_for_temp));
|
||||
|
||||
gf.P_word = false;
|
||||
gf.S_word = false;
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_CANCEL_WAIT_TEMP: { // M108
|
||||
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
|
||||
cm_request_feedhold();
|
||||
cm_request_queue_flush();
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_TRAM_BED: { // G29
|
||||
cm.gmx.marlin_flavor = true; // these gcodes are ONLY in marlin flavor
|
||||
ritorno(marlin_start_tramming_bed());
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_SET_FAN_SPEED: { // M106
|
||||
cm.gmx.marlin_flavor = true; // these gcodes are ONLY in marlin flavor
|
||||
ritorno(marlin_set_fan_speed(gf.P_word?gv.P_word:0, gf.S_word?gv.S_word:0));
|
||||
gf.P_word = false;
|
||||
gf.S_word = false;
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_STOP_FAN: { // M107
|
||||
cm.gmx.marlin_flavor = true; // these gcodes are ONLY in marlin flavor
|
||||
ritorno(marlin_set_fan_speed(gf.P_word?gv.P_word:0, 0));
|
||||
gf.P_word = false;
|
||||
gf.S_word = false;
|
||||
break;
|
||||
}
|
||||
// adjust G28 (already adjusted to G28.2)
|
||||
// with no X, Y, or Z, we assume all three
|
||||
case NEXT_ACTION_SEARCH_HOME: { // G28 (g2core G28.2)
|
||||
if (!gf.target[AXIS_X] && !gf.target[AXIS_Y] && !gf.target[AXIS_Z]) {
|
||||
gv.target[AXIS_X]=0.0; gf.target[AXIS_X]=true;
|
||||
gv.target[AXIS_Y]=0.0; gf.target[AXIS_Y]=true;
|
||||
gv.target[AXIS_Z]=0.0; gf.target[AXIS_Z]=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_DISABLE_MOTORS: { // M84
|
||||
ritorno(marlin_disable_motors());
|
||||
break;
|
||||
}
|
||||
case NEXT_ACTION_MARLIN_DISPLAY_ON_SCREEN: { // M184
|
||||
// ignore for now
|
||||
return status;
|
||||
}
|
||||
case NEXT_ACTION_DEFAULT: {
|
||||
if (cm.gmx.marlin_flavor) {
|
||||
// adjust G0 to almost always be the same as G1
|
||||
if (gf.motion_mode)
|
||||
{
|
||||
if (gf.E_word &&
|
||||
(!gf.target[AXIS_X] && !gf.target[AXIS_Y] && !gf.target[AXIS_Z])
|
||||
)
|
||||
{
|
||||
gv.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; // G0
|
||||
} else {
|
||||
gv.motion_mode = MOTION_MODE_STRAIGHT_FEED; // G1
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -900,9 +1029,9 @@ stat_t _execute_gcode_block(char *active_comment)
|
||||
case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2
|
||||
case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3
|
||||
|
||||
case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100
|
||||
case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100.0
|
||||
case NEXT_ACTION_JSON_COMMAND_ASYNC: { status = cm_json_command_immediate(active_comment); break;} // M100.1
|
||||
case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101
|
||||
// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102
|
||||
|
||||
case NEXT_ACTION_DEFAULT: {
|
||||
cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override
|
||||
|
||||
@@ -85,7 +85,7 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth);
|
||||
* _json_parser_execute() executes sets and gets in an application agnostic way. It should work for other apps than g2core
|
||||
*/
|
||||
|
||||
void json_parser(char *str)
|
||||
stat_t json_parser(char *str, bool suppress_response) // suppress_response defaults to false, see decalaration in .h
|
||||
{
|
||||
nvObj_t *nv = nv_reset_nv_list(); // get a fresh nvObj list
|
||||
stat_t status = _json_parser_kernal(nv, str);
|
||||
@@ -93,11 +93,12 @@ void json_parser(char *str)
|
||||
nv = nv_body;
|
||||
status = _json_parser_execute(nv);
|
||||
}
|
||||
if (status == STAT_COMPLETE) { // skip the print if returning from something that already did it.
|
||||
return;
|
||||
if (suppress_response || (status == STAT_COMPLETE)) { // skip the print if returning from something that already did it.
|
||||
return status;
|
||||
}
|
||||
nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_FORMAT);
|
||||
sr_request_status_report(SR_REQUEST_TIMED); // generate incremental status report to show any changes
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
// This is almost the same as json_parser, except it doesn't *always* execute the parsed out list, and it never returns a reponse
|
||||
|
||||
@@ -82,7 +82,7 @@ extern jsSingleton_t js;
|
||||
|
||||
/**** Function Prototypes ****/
|
||||
|
||||
void json_parser(char *str);
|
||||
stat_t json_parser(char *str, bool suppress_response = false);
|
||||
void json_parse_for_exec(char *str, bool execute);
|
||||
uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size);
|
||||
void json_print_object(nvObj_t *nv);
|
||||
|
||||
+193
-86
@@ -65,7 +65,7 @@ enum class MarlinSetTempState {
|
||||
MarlinSetTempState set_temp_state; // record the state for the temperature-control pseudo-cycle
|
||||
// These next parameters for the next temperature-control pseudo-cycle are only needed until the calls are queued.
|
||||
float next_temperature; // as it says
|
||||
uint8_t next_temperature_tool; // this is a g2core (1-based) tool
|
||||
uint8_t next_temperature_tool; // 0-based, with 2 being the heat-bed
|
||||
|
||||
// Information about if we are to be dumping periodic temperature updates
|
||||
bool temperature_updates_requested = false;
|
||||
@@ -74,10 +74,101 @@ Motate::Timeout temperature_update_timeout;
|
||||
// local helper functions and macros
|
||||
|
||||
/*
|
||||
* marlin_verify_checksum() - check to see if we have a line number (cheaply) and a valid checksum
|
||||
* _report_temperatures() - convenience function to get a value via the JSON NV system
|
||||
*/
|
||||
nvObj_t *_get_spcific_nv(const char *key) {
|
||||
nvObj_t *nv = nv_reset_nv_list(); // returns first object in the body
|
||||
|
||||
strncpy(nv->token, key, TOKEN_LEN);
|
||||
|
||||
// validate and post-process the token
|
||||
if ((nv->index = nv_get_index((const char *)"", nv->token)) == NO_MATCH) { // get index or fail it
|
||||
// since we JUST provided the keys, this should never happen
|
||||
return nullptr;
|
||||
}
|
||||
strcpy(nv->group, cfgArray[nv->index].group); // capture the group string if there is one
|
||||
|
||||
nv_get(nv);
|
||||
|
||||
return nv;
|
||||
}
|
||||
|
||||
/*
|
||||
* _report_temperatures() - convenience function called from marlin_response() and marlin_callback()
|
||||
*/
|
||||
void _report_temperatures(char *(&str)) {
|
||||
// Tool 0 is extruder 1
|
||||
uint8_t tool = cm.gm.tool_select;
|
||||
|
||||
nvObj_t *nv = nullptr;
|
||||
|
||||
if (tool == 0) {
|
||||
nv = _get_spcific_nv("he1t");
|
||||
} else if (tool == 1) {
|
||||
nv = _get_spcific_nv("he2t");
|
||||
} else {
|
||||
return; // we have no way of reporting errors here, ATM
|
||||
}
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " T:%.2f", (float)nv->value);
|
||||
|
||||
if (tool == 0) {
|
||||
nv = _get_spcific_nv("he1st");
|
||||
} else if (tool == 1) {
|
||||
nv = _get_spcific_nv("he2st");
|
||||
} else {
|
||||
return; // we have no way of reporting errors here, ATM
|
||||
}
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " /%.2f", (float)nv->value);
|
||||
|
||||
nv = _get_spcific_nv("he3t");
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " B:%.2f", (float)nv->value);
|
||||
|
||||
nv = _get_spcific_nv("he3st");
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " /%.2f", (float)nv->value);
|
||||
|
||||
if (tool == 0) {
|
||||
nv = _get_spcific_nv("he1op");
|
||||
} else if (tool == 1) {
|
||||
nv = _get_spcific_nv("he2op");
|
||||
} if (!nv) { return; }
|
||||
str += sprintf(str, " @:%.0f", (float)nv->value * 255.0);
|
||||
|
||||
nv = _get_spcific_nv("he3op");
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " B@:%.0f", (float)nv->value * 255.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* _report_position() - convenience function called from marlin_response()
|
||||
*/
|
||||
void _report_position(char *(&str)) {
|
||||
str += sprintf(str, " X:%.2f", cm_get_work_position(ACTIVE_MODEL, 0));
|
||||
str += sprintf(str, " Y:%.2f", cm_get_work_position(ACTIVE_MODEL, 1));
|
||||
str += sprintf(str, " Z:%.2f", cm_get_work_position(ACTIVE_MODEL, 2));
|
||||
|
||||
uint8_t tool = cm.gm.tool_select;
|
||||
if (tool == 0) {
|
||||
str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 3));
|
||||
} else if (tool == 1) {
|
||||
str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 4));
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* CONFIGURATION AND INTERFACE FUNCTIONS
|
||||
* Functions to get and set variables from the cfgArray table
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* marlin_verify_checksum() - check to see if we have a line number (cheaply) and a valid checksum
|
||||
* called from gcode_parser
|
||||
*/
|
||||
stat_t marlin_verify_checksum(char *str)
|
||||
{
|
||||
if (*str != 'N') { return STAT_OK; } // we only check if we have a line number
|
||||
@@ -91,12 +182,18 @@ stat_t marlin_verify_checksum(char *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;
|
||||
if (c == '*') {
|
||||
*(str-1) = 0; // null terminate, the parser won't like this * here!
|
||||
if (strtol(str, NULL, 10) != checksum) {
|
||||
return STAT_CHECKSUM_MATCH_FAILED;
|
||||
}
|
||||
}
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* _marlin_fake_stk500_response() - convenience function for formang responses from marlin_handle_fake_stk500()
|
||||
*/
|
||||
void _marlin_fake_stk500_response(char *resp, uint16_t length)
|
||||
{
|
||||
char *str = resp;
|
||||
@@ -151,15 +248,13 @@ bool marlin_handle_fake_stk500(char *str)
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
* CONFIGURATION AND INTERFACE FUNCTIONS
|
||||
* Functions to get and set variables from the cfgArray table
|
||||
***********************************************************************************/
|
||||
|
||||
/*
|
||||
* marlin_request_temperature_report() - called from the gcode parser for M105
|
||||
*/
|
||||
stat_t marlin_request_temperature_report() // M105
|
||||
{
|
||||
uint8_t tool = cm.gm.tool_select;
|
||||
if (tool > 1) {
|
||||
if ((tool < 0) || (tool > 1)) {
|
||||
return STAT_INPUT_VALUE_RANGE_ERROR;
|
||||
}
|
||||
|
||||
@@ -167,82 +262,19 @@ stat_t marlin_request_temperature_report() // M105
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* marlin_request_temperature_report() - called from the gcode parser for M114
|
||||
*/
|
||||
stat_t marlin_request_position_report() // M114
|
||||
{
|
||||
position_requested = true;
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
nvObj_t *_get_spcific_nv(const char *key) {
|
||||
nvObj_t *nv = nv_reset_nv_list(); // returns first object in the body
|
||||
|
||||
strncpy(nv->token, key, TOKEN_LEN);
|
||||
|
||||
// validate and post-process the token
|
||||
if ((nv->index = nv_get_index((const char *)"", nv->token)) == NO_MATCH) { // get index or fail it
|
||||
// since we JUST provided the keys, this should never happen
|
||||
return nullptr;
|
||||
}
|
||||
strcpy(nv->group, cfgArray[nv->index].group); // capture the group string if there is one
|
||||
|
||||
nv_get(nv);
|
||||
|
||||
return nv;
|
||||
}
|
||||
|
||||
void _report_temperatures(char *(&str)) {
|
||||
// Tool 0 is extruder 1
|
||||
uint8_t tool = cm.gm.tool_select;
|
||||
|
||||
nvObj_t *nv = nullptr;
|
||||
|
||||
if (tool == 0) {
|
||||
nv = _get_spcific_nv("he1t");
|
||||
} else if (tool == 1) {
|
||||
nv = _get_spcific_nv("he2t");
|
||||
} else {
|
||||
return; // we have no way of reporting errors here, ATM
|
||||
}
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " T:%.2f", (float)nv->value);
|
||||
|
||||
if (tool == 0) {
|
||||
nv = _get_spcific_nv("he1st");
|
||||
} else if (tool == 1) {
|
||||
nv = _get_spcific_nv("he2st");
|
||||
} else {
|
||||
return; // we have no way of reporting errors here, ATM
|
||||
}
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " /%.2f", (float)nv->value);
|
||||
|
||||
nv = _get_spcific_nv("he3t");
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " B:%.2f", (float)nv->value);
|
||||
|
||||
nv = _get_spcific_nv("he3st");
|
||||
if (!nv) { return; }
|
||||
str += sprintf(str, " /%.2f", (float)nv->value);
|
||||
}
|
||||
|
||||
void _report_position(char *(&str)) {
|
||||
//
|
||||
// Tool 0 is extruder 1
|
||||
uint8_t tool = cm.gm.tool_select;
|
||||
|
||||
str += sprintf(str, " X:%.2f", cm_get_work_position(ACTIVE_MODEL, 0));
|
||||
str += sprintf(str, " Y:%.2f", cm_get_work_position(ACTIVE_MODEL, 1));
|
||||
str += sprintf(str, " Z:%.2f", cm_get_work_position(ACTIVE_MODEL, 2));
|
||||
|
||||
if (tool == 0) {
|
||||
str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 3));
|
||||
} else if (tool == 1) {
|
||||
str += sprintf(str, " E:%.2f", cm_get_work_position(ACTIVE_MODEL, 4));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* marlin_response() - marlin mirror if text_response()
|
||||
* marlin_response() - marlin mirror of text_response(), called from _dispatch_kernel() in controller.cpp
|
||||
*/
|
||||
void marlin_response(const stat_t status, char *buf)
|
||||
{
|
||||
@@ -283,6 +315,7 @@ void marlin_response(const stat_t status, char *buf)
|
||||
xio_writeline(buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _marlin_start_temperature_updates()/_marlin_end_temperature_updates() -
|
||||
* calls from commands in the buffer to manage temperature_updates_requested
|
||||
@@ -291,11 +324,11 @@ void _marlin_start_temperature_updates(float* vect, bool* flag) {
|
||||
temperature_updates_requested = true;
|
||||
temperature_update_timeout.set(1); // immediately
|
||||
}
|
||||
|
||||
void _marlin_end_temperature_updates(float* vect, bool* flag) {
|
||||
temperature_updates_requested = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _queue_next_temperature_comands() - returns true if it finished
|
||||
*/
|
||||
@@ -312,7 +345,7 @@ bool _queue_next_temperature_commands()
|
||||
if ((MarlinSetTempState::SettingTemperature == set_temp_state) ||
|
||||
(MarlinSetTempState::SettingTemperatureNoWait == set_temp_state))
|
||||
{
|
||||
str += sprintf(str, "{he%dst:%.2f}", next_temperature_tool, next_temperature);
|
||||
str += sprintf(str, "{he%dst:%.2f}", next_temperature_tool+1, next_temperature);
|
||||
cm_json_command(buffer);
|
||||
|
||||
if (MarlinSetTempState::SettingTemperatureNoWait == set_temp_state) {
|
||||
@@ -337,7 +370,7 @@ bool _queue_next_temperature_commands()
|
||||
|
||||
if (MarlinSetTempState::StartingWait == set_temp_state) {
|
||||
str = buffer;
|
||||
str += sprintf(str, "{he%dat:t}", next_temperature_tool);
|
||||
str += sprintf(str, "{he%dat:t}", next_temperature_tool+1);
|
||||
cm_json_wait(buffer);
|
||||
|
||||
set_temp_state = MarlinSetTempState::StoppingUpdates;
|
||||
@@ -356,12 +389,13 @@ bool _queue_next_temperature_commands()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* marlin_callback() - called by controller dispatcher - return STAT_EAGAIN if it failed
|
||||
*/
|
||||
stat_t marlin_callback()
|
||||
{
|
||||
if (temperature_updates_requested && (temperature_update_timeout.isPast())) {
|
||||
if ((js.json_mode == MARLIN_COMM_MODE) && temperature_updates_requested && (temperature_update_timeout.isPast())) {
|
||||
char buffer[128];
|
||||
char *str = buffer;
|
||||
|
||||
@@ -383,22 +417,95 @@ stat_t marlin_callback()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* marlin_set_temperature() - called from the gcode parser for M104,M140,M109,M190
|
||||
*/
|
||||
stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait) {
|
||||
if (MarlinSetTempState::Idle != set_temp_state) {
|
||||
return (STAT_BUFFER_FULL_FATAL); // this shouldn't happen
|
||||
return (STAT_BUFFER_FULL_FATAL); // we shouldn't be here
|
||||
}
|
||||
if ((tool < 0) || (tool > 3)) {
|
||||
if ((tool < 0) || (tool > 2)) {
|
||||
return STAT_INPUT_VALUE_RANGE_ERROR;
|
||||
}
|
||||
|
||||
set_temp_state = wait ? MarlinSetTempState::SettingTemperature : MarlinSetTempState::SettingTemperatureNoWait;
|
||||
next_temperature = temperature;
|
||||
|
||||
// Note the conversion from a "marlin" tool (zero-base) to a g2core tool (1-based)
|
||||
next_temperature_tool = tool + 1;
|
||||
next_temperature_tool = tool;
|
||||
|
||||
_queue_next_temperature_commands(); // we can ignore the return
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MARLIN_G29_SCRIPT
|
||||
auto marlin_g29_file = make_xio_flash_file(MARLIN_G29_SCRIPT);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* marlin_start_tramming_bed() - called from the gcode parser for G29
|
||||
*/
|
||||
stat_t marlin_start_tramming_bed() {
|
||||
#ifndef MARLIN_G29_SCRIPT
|
||||
return (STAT_G29_NOT_CONFIGURED);
|
||||
#else
|
||||
xio_send_file(marlin_g29_file);
|
||||
return (STAT_OK);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* cm_marlin_set_extruder_mode() - M82, M83 (affects MODEL only)
|
||||
*
|
||||
* EXTRUDER_MOVES_ABSOLUTE = 0, // M82
|
||||
* EXTRUDER_MOVES_RELATIVE, // M83
|
||||
* EXTRUDER_MOVES_VOLUMETRIC // Ultimaker2Marlin
|
||||
*/
|
||||
|
||||
stat_t cm_marlin_set_extruder_mode(const uint8_t mode)
|
||||
{
|
||||
cm.gmx.extruder_mode = (cmExtruderMode)mode;
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* marlin_set_fan_speed() - M106, M107
|
||||
*
|
||||
*/
|
||||
|
||||
stat_t marlin_set_fan_speed(const uint8_t fan, float speed)
|
||||
{
|
||||
char buffer[128];
|
||||
char *str = buffer;
|
||||
if ((fan != 0) || (speed < 0.0) || (speed > 255.0)) {
|
||||
return STAT_INPUT_VALUE_RANGE_ERROR;
|
||||
}
|
||||
|
||||
// TODO: support other fans, or remapping output
|
||||
str += sprintf(str, "{out4:%.2f}", (speed < 1.0) ? speed : (speed / 255.0));
|
||||
cm_json_command(buffer);
|
||||
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* marlin_disable_motors() - M84
|
||||
*
|
||||
*/
|
||||
|
||||
stat_t marlin_disable_motors()
|
||||
{
|
||||
char buffer[128];
|
||||
char *str = buffer;
|
||||
|
||||
// TODO: support other parameters
|
||||
strncpy(str, "{md:0}", 6);
|
||||
cm_json_command(buffer);
|
||||
|
||||
return (STAT_OK);
|
||||
}
|
||||
#endif // MARLIN_COMPAT_ENABLED == true
|
||||
|
||||
@@ -28,15 +28,24 @@
|
||||
* Global Scope Functions
|
||||
*/
|
||||
|
||||
// gcode parsing and fack stk500v2
|
||||
stat_t marlin_verify_checksum(char *str);
|
||||
bool marlin_handle_fake_stk500(char *str);
|
||||
|
||||
// gcode handling
|
||||
stat_t marlin_start_tramming_bed(); //G29
|
||||
stat_t marlin_request_temperature_report(); // M105
|
||||
stat_t marlin_request_position_report(); // M114
|
||||
stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait); // M104, M109, M140, M190
|
||||
|
||||
// response handler (primarily just prints "ok")
|
||||
void marlin_response(const stat_t status, char *buf);
|
||||
|
||||
// controller loop callback
|
||||
stat_t marlin_callback();
|
||||
|
||||
stat_t cm_marlin_set_extruder_mode(const uint8_t mode); // M82, M82
|
||||
stat_t marlin_set_fan_speed(const uint8_t fan, float speed); // M106, M107
|
||||
|
||||
stat_t marlin_disable_motors(); // M84
|
||||
#endif // End of include guard: MARLIN_COMPAT_H_ONCE
|
||||
|
||||
+9
-1
@@ -311,7 +311,7 @@ stat_t mp_runtime_command(mpBuf_t *bf)
|
||||
|
||||
/*************************************************************************
|
||||
* mp_json_command() - queue a json command
|
||||
* _exec_json_command() - execute json string
|
||||
* _exec_json_command() - execute json string (from exec system)
|
||||
*/
|
||||
|
||||
stat_t mp_json_command(char *json_string)
|
||||
@@ -334,6 +334,14 @@ static void _exec_json_command(float *value, bool *flag)
|
||||
jc.free_buffer();
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* mp_json_command_immediate() - execute a json command with response suppressed
|
||||
*/
|
||||
|
||||
stat_t mp_json_command_immediate(char *json_string)
|
||||
{
|
||||
return json_parser(json_string);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* mp_json_wait() - queue a json wait command
|
||||
|
||||
@@ -537,6 +537,7 @@ stat_t mp_runtime_command(mpBuf_t *bf);
|
||||
|
||||
stat_t mp_json_command(char *json_string);
|
||||
stat_t mp_json_wait(char *json_string);
|
||||
stat_t mp_json_command_immediate(char *json_string);
|
||||
|
||||
stat_t mp_dwell(const float seconds);
|
||||
void mp_end_dwell(void);
|
||||
|
||||
+5
-2
@@ -111,8 +111,11 @@ void rpt_print_loading_configs_message(void)
|
||||
|
||||
void rpt_print_system_ready_message(void)
|
||||
{
|
||||
#warning DEAL WITH STARTUP MESSAGE
|
||||
//_startup_helper(STAT_OK, "SYSTEM READY");
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
#warning DEAL WITH STARTUP MESSAGE
|
||||
#else
|
||||
_startup_helper(STAT_OK, "SYSTEM READY");
|
||||
#endif
|
||||
if (cs.comm_mode == TEXT_MODE) { text_response(STAT_OK, (char *)"");}// prompt
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,23 @@
|
||||
#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS
|
||||
#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE
|
||||
|
||||
#define MARLIN_G29_SCRIPT \
|
||||
"(MSG Tramming started)\n" \
|
||||
"M100 ({\"_leds\":3})\n" \
|
||||
"G1 X0 Y145 Z6 F20000\n" \
|
||||
"G38.2 Z-10 F200\n" \
|
||||
"G1 Z5 F20000\n" \
|
||||
"M100 ({\"_leds\":5})\n" \
|
||||
"G1 X210 Y65 F20000\n" \
|
||||
"G38.2 Z-10 F200\n" \
|
||||
"G1 Z5 F20000\n" \
|
||||
"M100 ({\"_leds\":6})\n" \
|
||||
"G1 X0 Y10 F20000\n" \
|
||||
"G38.2 Z-10 F200\n" \
|
||||
"G1 Z5 F20000\n" \
|
||||
"M100 ({\"_leds\":3})\n" \
|
||||
"M100 ({\"tram\":1})" \
|
||||
"(MSG Tramming completed)\n"
|
||||
|
||||
// *** motor settings ************************************************************************************
|
||||
|
||||
|
||||
@@ -365,7 +365,10 @@ struct PID {
|
||||
if (_rise_time_timeout.isPast()) {
|
||||
if (input < _rise_time_checkpoint) {
|
||||
// FAILURE!!
|
||||
cm_alarm(STAT_TEMPERATURE_CONTROL_ERROR, "Heater temperature failed to rise fast enough.");
|
||||
char buffer[128];
|
||||
char *str = buffer;
|
||||
str += sprintf(str, "Heater temperature failed to rise fast enough. At: %f Set: %f", input, _set_point);
|
||||
cm_alarm(STAT_TEMPERATURE_CONTROL_ERROR, buffer);
|
||||
_set_point = 0;
|
||||
_rise_time_timeout.clear();
|
||||
return -1;
|
||||
|
||||
@@ -173,6 +173,22 @@ inline T avg(const T a,const T b) {return (a+b)/2; }
|
||||
#define M_SQRT3 (1.73205080756888)
|
||||
#endif
|
||||
|
||||
// Fraction part
|
||||
constexpr float c_atof_frac_(char *&p_, float v_, float m_) {
|
||||
return ((*p_ >= '0') && (*p_ <= '9')) ? (v_ = ((v_) + ((*p_) - '0') * m_), c_atof_frac_(++p_, v_, m_ / 10.0)) : v_;
|
||||
}
|
||||
|
||||
// Integer part
|
||||
template <typename int_type>
|
||||
constexpr float c_atof_int_(char *&p_, int_type v_) {
|
||||
return (*p_ == '.')
|
||||
? (float)(v_) + c_atof_frac_(++p_, 0, 1.0 / 10.0)
|
||||
: (((*p_ >= '0') && (*p_ <= '9')) ? ((v_ = ((*p_) - '0') + (v_ * 10)), c_atof_int_(++p_, v_)) : v_);
|
||||
}
|
||||
|
||||
// Start portion
|
||||
constexpr float c_atof(char *&p_) { return (*p_ == '-') ? (c_atof_int_(++p_, 0) * -1.0) : (c_atof_int_(p_, 0)); }
|
||||
|
||||
|
||||
// It's assumed that the string buffer contains at lest count_ non-\0 chars
|
||||
//constexpr int c_strreverse(char * const t, const int count_, char hold = 0) {
|
||||
|
||||
+26
-4
@@ -640,15 +640,17 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
|
||||
|
||||
char c = _data[_scan_offset];
|
||||
|
||||
if (c == 0) {
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
// it's possible something will try to talk stk500v2 to us.
|
||||
// See https://github.com/synthetos/g2/wiki/Marlin-Compatibility#stk500v2
|
||||
|
||||
if ((_stk_parser_state == STK500V2_State::Done) && (c == 0)) {
|
||||
_debug_trap("scan ran into NULL");
|
||||
flush(); // consider the connection and all data trashed
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MARLIN_COMPAT_ENABLED == true
|
||||
// it's possible something will try to talk stk500v2 to us.
|
||||
// See https://github.com/synthetos/g2/wiki/Marlin-Compatibility#stk500v2
|
||||
if (_stk_parser_state >= STK500V2_State::Timeout)
|
||||
{
|
||||
if (_stk_parser_state == STK500V2_State::Timeout) {
|
||||
@@ -672,6 +674,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
|
||||
else if ((c == '{') || (c == '\n') || (c == '\r') || (c == 'G') || (c == 'M')) {
|
||||
// jump out of bootloader mode
|
||||
_stk_parser_state = STK500V2_State::Done;
|
||||
_read_offset = _scan_offset;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -690,6 +693,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
|
||||
} else {
|
||||
// end-of-header marker was corrupt, start over
|
||||
_stk_packet_data_length = 0;
|
||||
_read_offset = _scan_offset;
|
||||
_stk_parser_state = STK500V2_State::Start;
|
||||
}
|
||||
} else if (_stk_parser_state == STK500V2_State::Data) {
|
||||
@@ -706,9 +710,21 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
|
||||
// we will use the "control" return machanism to handle this
|
||||
// since controls don't have to be \r\n-terminated
|
||||
is_control = true;
|
||||
ends_line = true;
|
||||
|
||||
// this line is complete, reset the state engine
|
||||
_stk_parser_state = STK500V2_State::Start;
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
|
||||
if (c == 0) {
|
||||
_debug_trap("scan ran into NULL");
|
||||
flush(); // consider the connection and all data trashed
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
// Look for line endings
|
||||
if (c == '\r' || c == '\n') {
|
||||
@@ -1237,6 +1253,12 @@ struct xioFlashFileDeviceWrapper : xioDeviceWrapperBase { // describes a devi
|
||||
_current_file = nullptr;
|
||||
}
|
||||
|
||||
bool flushToCommand() final {
|
||||
// the end of the file is the next "command"
|
||||
_current_file = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
int16_t write(const char *buffer, int16_t len) final {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user