Merge pull request #244 from synthetos/dev-227-marlin-compat

Fix #227 marlin compat
This commit is contained in:
Rob Giseburt
2017-03-21 22:30:59 -05:00
committed by GitHub
45 changed files with 2441 additions and 949 deletions
+1 -1
Submodule Motate updated: 222de41d50...41e5b92a98
+4 -1
View File
@@ -52,8 +52,11 @@ NEEDS_PRINTF_FLOAT=1
# Now invoke the Motate compile system
include $(MOTATE_PATH)/Motate.mk
ifeq ($(DEBUG),0)
DEVICE_DEFINES += DEBUG=0 IN_DEBUGGER=0
endif
ifeq ($(DEBUG),1)
DEVICE_DEFINES += DEBUG=1
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=0
endif
ifeq ($(DEBUG),2)
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1
+5 -1
View File
@@ -75,7 +75,9 @@ void board_hardware_init(void) // called 1st
}
void board_xio_init(void) // called later than board_hardware_init (there are thing in between)
auto startup_file = make_xio_flash_file("");
void board_xio_init(void) // called later than board_hardware_init (there are things in between)
{
// Init SPI
#if XIO_HAS_SPI
@@ -86,4 +88,6 @@ void board_xio_init(void) // called later than board_hardware_init (there are th
#if XIO_HAS_UART
Serial.init();
#endif
xio_send_file(startup_file);
}
+1
View File
@@ -30,6 +30,7 @@
#define board_xio_h
#include "settings.h"
#include "xio.h"
//******** USB ********
#if XIO_HAS_USB
+2 -1
View File
@@ -39,7 +39,8 @@ ifeq ("$(CONFIG)","Othermill")
ifeq ("$(BOARD)","NONE")
BOARD=g2v9k
endif
SETTINGS_FILE="settings_othermill.h"
# SETTINGS_FILE="settings_othermill.h"
SETTINGS_FILE="settings_othermill_test.h"
endif
ifeq ("$(CONFIG)","ProbotixV90")
+143 -46
View File
@@ -93,6 +93,7 @@
#include "controller.h"
#include "json_parser.h"
#include "text_parser.h"
#include "settings.h"
#include "plan_arc.h"
#include "planner.h"
@@ -259,6 +260,15 @@ void cm_set_model_linenum(const uint32_t linenum)
nv_add_object((const char *)"n"); // then add the line number to the nv list
}
stat_t cm_check_linenum() {
if (cm.gmx.last_line_number != cm.gm.linenum) {
_debug_trap("line number out of sequence");
return STAT_LINE_NUMBER_OUT_OF_SEQUENCE;
}
cm.gmx.last_line_number = cm.gm.linenum;
return STAT_OK;
}
/***********************************************************************************
* COORDINATE SYSTEMS AND OFFSETS
* Functions to get, set and report coordinate systems and work offsets
@@ -565,6 +575,31 @@ stat_t cm_get_tram(nvObj_t *nv)
}
/*
* cm_set_nxt_line() - JSON command to set the next line number
* cm_get_nxt_line() - JSON query to get the next expected line number
*
* There MUST be three valid probes stored.
*/
stat_t cm_set_nxln(nvObj_t *nv)
{
if (nv->valuetype == TYPE_INT || nv->valuetype == TYPE_FLOAT)
{
cm.gmx.last_line_number = ((int32_t)nv->value) - 1;
return (STAT_OK);
}
return (STAT_INPUT_VALUE_RANGE_ERROR);
}
stat_t cm_get_nxln(nvObj_t *nv)
{
nv->value = cm.gmx.last_line_number+1;
nv->valuetype = TYPE_INT;
return (STAT_OK);
}
/*
* cm_set_model_target() - set target vector in GM model
*
@@ -594,7 +629,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,15 +662,35 @@ 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 (mst.marlin_flavor && (cm.a[axis].axis_mode == AXIS_RADIUS)) {
if ((cm.gm.distance_mode == INCREMENTAL_DISTANCE_MODE) || (mst.extruder_mode == EXTRUDER_MOVES_RELATIVE)) {
cm.gm.target[axis] += tmp;
}
else { // if (cm.gmx.extruder_mode == EXTRUDER_MOVES_NORMAL)
cm.gm.target[axis] = tmp + cm_get_active_coord_offset(axis);
}
// 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;
}
}
}
/*
* cm_get_soft_limits()
* cm_set_soft_limits()
* cm_test_soft_limits() - return error code if soft limit is exceeded
*
* The target[] arg must be in absolute machine coordinates. Best done after cm_set_model_target().
@@ -643,6 +701,9 @@ void cm_set_model_target(const float target[], const bool flags[])
* This allows a single end to be tested w/the other disabled, should that requirement ever arise.
*/
bool cm_get_soft_limits() { return (cm.soft_limit_enable); }
void cm_set_soft_limits(bool enable) { cm.soft_limit_enable = enable; }
static stat_t _finalize_soft_limits(const stat_t status)
{
cm.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // cancel motion
@@ -693,9 +754,7 @@ void canonical_machine_init()
// If you can assume all memory has been zeroed by a hard reset you don't need this code:
// memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized
memset(&cm, 0, sizeof(cmSingleton_t)); // do not reset canonicalMachineSingleton once it's been initialized
memset(&cm.gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status
memset(&cm.gn, 0, sizeof(GCodeInput_t));
memset(&cm.gf, 0, sizeof(GCodeFlags_t));
cm.gm.reset(); // clear all values, pointers and status -- not ALL to zero, however
canonical_machine_init_assertions(); // establish assertions
ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer
@@ -719,19 +778,20 @@ void canonical_machine_reset()
cm_select_plane(cm.default_select_plane);
cm_set_path_control(MODEL, cm.default_path_control);
cm_set_distance_mode(cm.default_distance_mode);
cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE); // always the default
cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default
cm_reset_overrides(); // set overrides to initial conditions
cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default
cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default
cm_reset_overrides(); // set overrides to initial conditions
// NOTE: Should unhome axes here
// reset request flags
// reset requests and flags
cm.queue_flush_state = FLUSH_OFF;
cm.end_hold_requested = false;
cm.limit_requested = 0; // resets switch closures that occurred during initialization
cm.safety_interlock_disengaged = 0; // ditto
cm.safety_interlock_reengaged = 0; // ditto
cm.shutdown_requested = 0; // ditto
cm.probe_report_enable = PROBE_REPORT_ENABLE;
// set initial state and signal that the machine is ready for action
cm.cycle_state = CYCLE_OFF;
@@ -1038,10 +1098,11 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode)
* cm_set_work_offsets() immediately afterwards.
*/
stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word,
stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag,
const uint8_t L_word, const bool L_flag,
const float offset[], const bool flag[])
{
if (!cm.gf.L_word) {
if (!L_flag) {
return (STAT_L_WORD_IS_MISSING);
}
@@ -1057,8 +1118,9 @@ stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word,
cm.offset[P_word][axis] = _to_millimeters(offset[axis]);
} else {
// Should L20 take into account G92 offsets?
cm.offset[P_word][axis] = cm.gmx.position[axis] -
_to_millimeters(offset[axis]) -
cm.offset[P_word][axis] =
cm.gmx.position[axis] -
_to_millimeters(offset[axis]) -
cm.tl_offset[axis];
}
// persist offsets once machining cycle is over
@@ -1078,8 +1140,8 @@ stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word,
} else {
// L10 should also take into account G92 offset
cm.tt_offset[P_word][axis] =
cm.gmx.position[axis] - _to_millimeters(offset[axis]) -
cm.offset[cm.gm.coord_system][axis] -
cm.gmx.position[axis] - _to_millimeters(offset[axis]) -
cm.offset[cm.gm.coord_system][axis] -
(cm.gmx.origin_offset[axis] * cm.gmx.origin_offset_enable);
}
// persist offsets once machining cycle is over
@@ -1102,27 +1164,27 @@ stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word,
* cm_set_coord_system() - G54-G59
* _exec_offset() - callback from planner
*/
stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional)
stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional)
{
uint8_t tool;
if (cm.gf.H_word)
{
if (cm.gn.H_word > TOOLS) {
if (H_flag) {
if (H_word > TOOLS) {
return (STAT_H_WORD_IS_INVALID);
}
if (cm.gn.H_word == 0) { // interpret H0 as "current tool", just like no H at all.
if (H_word == 0) { // interpret H0 as "current tool", just like no H at all.
tool = cm.gm.tool;
} else {
tool = cm.gn.H_word;
tool = H_word;
}
} else {
} else {
tool = cm.gm.tool;
}
if (apply_additional) {
for (uint8_t axis = AXIS_X; axis < AXES; axis++) {
cm.tl_offset[axis] += cm.tt_offset[tool][axis];
}
} else {
} else {
for (uint8_t axis = AXIS_X; axis < AXES; axis++) {
cm.tl_offset[axis] = cm.tt_offset[tool][axis];
}
@@ -1174,7 +1236,7 @@ static void _exec_offset(float *value, bool *flag)
* This is useful for setting origins for homing, probing, and other operations.
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!!
* !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* More specifically, do not call this function if there are any moves in the planner or
@@ -1309,9 +1371,8 @@ stat_t cm_straight_traverse(const float target[], const bool flags[])
cm.gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE;
// it's legal for a G0 to have no axis words but we don't want to process it
if (!(flags[AXIS_X] || flags[AXIS_Y] || flags[AXIS_Z] ||
flags[AXIS_A] || flags[AXIS_B] || flags[AXIS_C])) {
return(STAT_OK);
if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) {
return(STAT_OK);
}
cm_set_model_target(target, flags);
@@ -1467,10 +1528,8 @@ stat_t cm_straight_feed(const float target[], const bool flags[])
}
cm.gm.motion_mode = MOTION_MODE_STRAIGHT_FEED;
// it's legal for a G1 to have no axis words but we don't want to process it
if (!(flags[AXIS_X] || flags[AXIS_Y] || flags[AXIS_Z] ||
flags[AXIS_A] || flags[AXIS_B] || flags[AXIS_C])) {
return(STAT_OK);
if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) {
return(STAT_OK);
}
cm_set_model_target(target, flags);
@@ -1601,7 +1660,7 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49
}
/*
* cm_feed_rate_override_enable() - M50
* cm_mfo_control() - M50 manual feed rate override comtrol
*
* M50 enables manual feedrate override and the optional P override parameter.
* P is expressed as M% to N% of programmed feedrate, typically a value from 0.05 to 2.000.
@@ -1640,38 +1699,64 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49
* ENABLE ENABLE M50 Pn ENABLE start ramp w/new P value; store P value
* (Note: new ramp will supercede any existing ramp)
*/
stat_t cm_mfo_enable(uint8_t enable) // M50
stat_t cm_mfo_control(const float P_word, const bool P_flag) // M50
{
bool new_enable = true;
bool new_override = false;
if (cm.gf.parameter) { // if parameter is present in Gcode block
if (fp_ZERO(cm.gn.parameter)) {
new_enable = false; // P0 disables override
if (P_flag) { // if parameter is present in Gcode block
if (fp_ZERO(P_word)) {
new_enable = false; // P0 disables override
} else {
if (cm.gn.parameter < FEED_OVERRIDE_MIN) {
if (P_word < FEED_OVERRIDE_MIN) {
return (STAT_INPUT_LESS_THAN_MIN_VALUE);
}
if (cm.gn.parameter > FEED_OVERRIDE_MAX) {
if (P_word > FEED_OVERRIDE_MAX) {
return (STAT_INPUT_EXCEEDS_MAX_VALUE);
}
cm.gmx.mfo_factor = cm.gn.parameter; // it validates - store it.
cm.gmx.mfo_factor = P_word; // P word is valid, store it.
new_override = true;
}
}
if (cm.gmx.m48_enable) { // if master enable is ON
if (cm.gmx.m48_enable) { // if master enable is ON
if (new_enable && (new_override || !cm.gmx.mfo_enable)) { // 3 cases to start a ramp
mp_start_feed_override(FEED_OVERRIDE_RAMP_TIME, cm.gmx.mfo_factor);
} else if (cm.gmx.mfo_enable && !new_enable) { // case to turn off the ramp
mp_end_feed_override(FEED_OVERRIDE_RAMP_TIME);
}
}
cm.gmx.mfo_enable = new_enable; // always update the enable state
cm.gmx.mfo_enable = new_enable; // always update the enable state
return (STAT_OK);
}
// if ((new_enable && new_override) || (new_enable && !cm.gmx.mfo_enable)) {
// if (!(cm.gmx.mfo_enable && new_override)) {
stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1
{
bool new_enable = true;
bool new_override = false;
if (P_flag) { // if parameter is present in Gcode block
if (fp_ZERO(P_word)) {
new_enable = false; // P0 disables override
} else {
if (P_word < TRAVERSE_OVERRIDE_MIN) {
return (STAT_INPUT_LESS_THAN_MIN_VALUE);
}
if (P_word > TRAVERSE_OVERRIDE_MAX) {
return (STAT_INPUT_EXCEEDS_MAX_VALUE);
}
cm.gmx.mto_factor = P_word; // P word is valid, store it.
new_override = true;
}
}
if (cm.gmx.m48_enable) { // if master enable is ON
if (new_enable && (new_override || !cm.gmx.mfo_enable)) { // 3 cases to start a ramp
mp_start_traverse_override(FEED_OVERRIDE_RAMP_TIME, cm.gmx.mto_factor);
} else if (cm.gmx.mto_enable && !new_enable) { // case to turn off the ramp
mp_end_traverse_override(FEED_OVERRIDE_RAMP_TIME);
}
}
cm.gmx.mto_enable = new_enable; // always update the enable state
return (STAT_OK);
}
/************************************************
* Feedhold and Related Functions (no NIST ref) *
@@ -2003,6 +2088,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
*/
@@ -2588,7 +2681,9 @@ stat_t cm_run_qf(nvObj_t *nv)
stat_t cm_run_home(nvObj_t *nv)
{
if (fp_TRUE(nv->value)) {
cm_homing_cycle_start();
float axes[] = { 1,1,1,1,1,1 };
bool flags[] = { 1,1,1,1,1,1 };
cm_homing_cycle_start(axes, flags);
}
return (STAT_OK);
}
@@ -2740,7 +2835,8 @@ static const char fmt_mfoe[] = "[mfoe] manual feed override enab%3d [0=disable,1
static const char fmt_mfo[] = "[mfo] manual feedrate override%8.3f [0.05 < mfo < 2.00]\n";
static const char fmt_mtoe[] = "[mtoe] manual traverse over enab%3d [0=disable,1=enable]\n";
static const char fmt_mto[] = "[mto] manual traverse override%8.3f [0.05 < mto < 1.00]\n";
static const char fmt_tram[] = "[tram] is coordinate space rotated to be tram %s\n";
static const char fmt_tram[] = "[tram] is coordinate space rotated to be tram %s\n";
static const char fmt_nxln[] = "[nxln] the next line number expected is %10d\n";
void cm_print_m48e(nvObj_t *nv) { text_print(nv, fmt_m48e);} // TYPE_INT
void cm_print_mfoe(nvObj_t *nv) { text_print(nv, fmt_mfoe);} // TYPE INT
@@ -2748,6 +2844,7 @@ void cm_print_mfo(nvObj_t *nv) { text_print(nv, fmt_mfo);} // TYPE FLOAT
void cm_print_mtoe(nvObj_t *nv) { text_print(nv, fmt_mtoe);} // TYPE INT
void cm_print_mto(nvObj_t *nv) { text_print(nv, fmt_mto);} // TYPE FLOAT
void cm_print_tram(nvObj_t *nv) { text_print(nv, fmt_tram);}; // TYPE BOOL
void cm_print_nxln(nvObj_t *nv) { text_print(nv, fmt_nxln);}; // TYPE INT
/*
* axis print functions
+49 -171
View File
@@ -34,6 +34,11 @@
#include "config.h"
#include "hardware.h" // Note: hardware.h is specific to the hardware target selected
#include "settings.h"
#if MARLIN_COMPAT_ENABLED == true
#include "marlin_compatibility.h" // import Marlin definitions and enums
#endif
/* Defines, Macros, and Assorted Parameters */
@@ -47,7 +52,7 @@
#define JOGGING_START_VELOCITY ((float)10.0)
#define DISABLE_SOFT_LIMIT (999999)
#define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3
#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3
#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3
#define PROBES_STORED 3 // we store three probes for coordinate rotation computation
@@ -82,15 +87,15 @@ typedef enum { // check alignment with messages in config.c / m
//### END CRITICAL REGION ###
typedef enum {
MACHINE_INITIALIZING = 0, // machine is initializing
MACHINE_READY, // machine is ready for use
MACHINE_ALARM, // machine in alarm state
MACHINE_PROGRAM_STOP, // no blocks to run; like PROGRAM_END but without the M2 to reset gcode state
MACHINE_PROGRAM_END, // program end (same as MACHINE_READY, really...)
MACHINE_CYCLE, // machine is running; blocks still to run, or steppers are busy
MACHINE_INTERLOCK, // machine in interlock state
MACHINE_SHUTDOWN, // machine in shutdown state
MACHINE_PANIC // machine in panic state
MACHINE_INITIALIZING = 0, // [0] machine is initializing
MACHINE_READY, // [1] machine is ready for use
MACHINE_ALARM, // [2] machine in alarm state
MACHINE_PROGRAM_STOP, // [3] no blocks to run; like PROGRAM_END but without the M2 to reset gcode state
MACHINE_PROGRAM_END, // [4] program end (same as MACHINE_READY, really...)
MACHINE_CYCLE, // [5] machine is running; blocks still to run, or steppers are busy
MACHINE_INTERLOCK, // [6] machine in interlock state
MACHINE_SHUTDOWN, // [7] machine in shutdown state
MACHINE_PANIC // [8] machine in panic state
} cmMachineState;
typedef enum {
@@ -139,7 +144,7 @@ typedef enum { // applies to cm.homing_state
typedef enum { // applies to cm.probe_state
PROBE_FAILED = 0, // probe reached endpoint without triggering
PROBE_SUCCEEDED = 1, // probe was triggered, cm.probe_results has position
PROBE_WAITING // probe is waiting to be started
PROBE_WAITING = 2 // probe is waiting to be started or is running
} cmProbeState;
typedef enum {
@@ -147,37 +152,6 @@ typedef enum {
SAFETY_INTERLOCK_DISENGAGED
} cmSafetyState;
/* The difference between NextAction and MotionMode is that NextAction is
* used by the current block, and may carry non-modal commands, whereas
* MotionMode persists across blocks (as G modal group 1)
*/
typedef enum { // these are in order to optimized CASE statement
NEXT_ACTION_DEFAULT = 0, // Must be zero (invokes motion modes)
NEXT_ACTION_DWELL, // G4
NEXT_ACTION_SET_G10_DATA, // G10
NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position
NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates
NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle
NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set
NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle with no coordinate setting
NEXT_ACTION_GOTO_G30_POSITION, // G30 go to machine position
NEXT_ACTION_SET_G30_POSITION, // G30.1 set position in abs coordinates
NEXT_ACTION_STRAIGHT_PROBE_ERR, // G38.2
NEXT_ACTION_STRAIGHT_PROBE, // G38.3
NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR,// G38.4
NEXT_ACTION_STRAIGHT_PROBE_AWAY, // G38.5
NEXT_ACTION_SET_TL_OFFSET, // G43
NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET,// G43.2
NEXT_ACTION_CANCEL_TL_OFFSET, // G49
NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92
NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1
NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2
NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3
NEXT_ACTION_JSON_COMMAND_SYNC, // M100
NEXT_ACTION_JSON_WAIT // M101
} cmNextAction;
typedef enum { // G Modal Group 1
MOTION_MODE_STRAIGHT_TRAVERSE=0, // G0 - straight traverse
MOTION_MODE_STRAIGHT_FEED, // G1 - straight feed
@@ -196,27 +170,6 @@ typedef enum { // G Modal Group 1
MOTION_MODE_CANNED_CYCLE_89 // G89 - boring, dwell, feed out
} cmMotionMode;
typedef enum { // Used for detecting gcode errors. See NIST section 3.4
MODAL_GROUP_G0 = 0, // {G10,G28,G28.1,G92} non-modal axis commands (note 1)
MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion
MODAL_GROUP_G2, // {G17,G18,G19} plane selection
MODAL_GROUP_G3, // {G90,G91} distance mode
MODAL_GROUP_G5, // {G93,G94} feed rate mode
MODAL_GROUP_G6, // {G20,G21} units
MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation
MODAL_GROUP_G8, // {G43,G49} tool length offset
MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles
MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection
MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode
MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping
MODAL_GROUP_M6, // {M6} tool change
MODAL_GROUP_M7, // {M3,M4,M5} spindle turning
MODAL_GROUP_M8, // {M7,M8,M9} coolant (M7 & M8 may be active together)
MODAL_GROUP_M9 // {M48,M49} speed/feed override switches
} cmModalGroup;
#define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1)
// Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check
typedef enum { // canonical plane - translates to:
// axis_0 axis_1 axis_2
CANON_PLANE_XY = 0, // G17 X Y Z
@@ -372,9 +325,8 @@ typedef struct GCodeState { // Gcode model state - used by model, pl
arc_distance_mode = ABSOLUTE_DISTANCE_MODE;
absolute_override = ABSOLUTE_OVERRIDE_OFF;
coord_system = ABSOLUTE_COORDS;
tool = 0;
tool_select = 0;
tool = 1;
tool_select = 1;
};
} GCodeState_t;
@@ -401,100 +353,12 @@ 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)
uint32_t last_line_number; // keep track of the last issued line number
uint16_t magic_end;
} GCodeStateX_t;
typedef struct GCodeInput { // Gcode model 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
uint32_t linenum; // N word
float target[AXES]; // XYZABC where the move should go
uint8_t H_word; // H word - used by G43s
uint8_t L_word; // L word - used by G10s
float feed_rate; // F - normalized to millimeters/minute
uint8_t feed_rate_mode; // See cmFeedRateMode for settings
float parameter; // P - parameter used for dwell time in seconds, G10 coord select...
float arc_radius; // R - radius value in arc radius mode
float arc_offset[3]; // IJK - used by arc commands
bool m48_enable; // M48/M49 input (enables for feed and spindle)
bool mfo_enable; // M50 feedrate override enable
bool mto_enable; // Mxx traverse override enable
bool sso_enable; // M51 spindle speed override enable
uint8_t select_plane; // G17,G18,G19 - values to set plane to
uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21)
uint8_t coord_system; // G54-G59 - select coordinate system 1-9
uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS
uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement
uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets
uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode
uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53)
uint8_t tool; // Tool after T and M6 (tool_select and tool_change)
uint8_t tool_select; // T value - T sets this value
uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool"
uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9)
uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9)
uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
float spindle_speed; // in RPM
float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there
uint8_t spindle_override_enable; // TRUE = override enabled
// unimplemented gcode parameters
// float cutter_radius; // D - cutter radius compensation (0 is off)
} GCodeInput_t;
typedef struct GCodeFlags { // Gcode model input flags
bool next_action;
bool motion_mode;
bool modals[MODAL_GROUP_COUNT];
bool program_flow;
bool linenum;
bool target[AXES];
bool H_word;
bool L_word;
bool feed_rate;
bool feed_rate_mode;
bool m48_enable;
bool mfo_enable;
bool mto_enable;
bool sso_enable;
bool select_plane;
bool units_mode;
bool coord_system;
bool path_control;
bool distance_mode;
bool arc_distance_mode;
bool origin_offset_mode;
bool absolute_override;
bool tool;
bool tool_select;
bool tool_change;
bool mist_coolant;
bool flood_coolant;
bool spindle_control;
bool spindle_speed;
bool spindle_override_factor;
bool spindle_override_enable;
bool parameter;
bool arc_radius;
bool arc_offset[3];
} GCodeFlags_t;
/*****************************************************************************
* CANONICAL MACHINE STRUCTURES
*/
@@ -568,6 +432,7 @@ typedef struct cmSingleton { // struct to manage cm globals and c
cmHomingState homing_state; // home: homing cycle sub-state machine
uint8_t homed[AXES]; // individual axis homing flags
bool probe_report_enable; // 0=disabled, 1=enabled
cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple)
float probe_results[PROBES_STORED][AXES]; // probing results
@@ -589,8 +454,6 @@ typedef struct cmSingleton { // struct to manage cm globals and c
GCodeState_t *am; // active Gcode model is maintained by state management
GCodeState_t gm; // core gcode model state
GCodeStateX_t gmx; // extended gcode model state
GCodeInput_t gn; // gcode input values - transient
GCodeFlags_t gf; // gcode input flags - transient
magic_t magic_end;
} cmSingleton_t;
@@ -637,6 +500,7 @@ void cm_set_motion_mode(GCodeState_t *gcode_state, const uint8_t motion_mode);
void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool);
void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override);
void cm_set_model_linenum(const uint32_t linenum);
stat_t cm_check_linenum();
// Coordinate systems and offsets
float cm_get_active_coord_offset(const uint8_t axis);
@@ -650,6 +514,9 @@ void cm_update_model_position_from_runtime(void);
void cm_finalize_move(void);
stat_t cm_deferred_write_callback(void);
void cm_set_model_target(const float target[], const bool flag[]);
bool cm_get_soft_limits(void);
void cm_set_soft_limits(bool enable);
stat_t cm_test_soft_limits(const float target[]);
/*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/
@@ -680,9 +547,11 @@ stat_t cm_select_plane(const uint8_t plane); // G
stat_t cm_set_units_mode(const uint8_t mode); // G20, G21
stat_t cm_set_distance_mode(const uint8_t mode); // G90, G91
stat_t cm_set_arc_distance_mode(const uint8_t mode); // G90.1, G91.1
stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional); // G43, G43.2
stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, // G43, G43.2
const bool apply_additional);
stat_t cm_cancel_tl_offset(void); // G49
stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, // G10
stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, // G10
const uint8_t L_word, const bool L_flag,
const float offset[], const bool flag[]);
void cm_set_position(const uint8_t axis, const float position); // set absolute position - single axis
@@ -722,17 +591,20 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // G
// see spindle.h for spindle functions - which would go right here
// Tool Functions (4.3.8)
stat_t cm_select_tool(const uint8_t tool); // T parameter
stat_t cm_change_tool(const uint8_t tool); // M6
stat_t cm_select_tool(const uint8_t tool); // T parameter
stat_t cm_change_tool(const uint8_t tool); // M6
// Miscellaneous Functions (4.3.9)
// see coolant.h for coolant functions - which would go right here
void cm_message(const char *message); // msg to console (e.g. Gcode comments)
void cm_message(const char *message); // msg to console (e.g. Gcode comments)
void cm_reset_overrides(void);
stat_t cm_m48_enable(uint8_t enable); // M48, M49
stat_t cm_mfo_enable(uint8_t enable); // M50
stat_t cm_m48_enable(uint8_t enable); // M48, M49
stat_t cm_mfo_enable(uint8_t enable); // M50
stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50
stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1
// See spindle.cpp for cm_sso_control() // M51
// Program Functions (4.3.10)
void cm_request_feedhold(void);
@@ -756,21 +628,22 @@ 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 ---*/
// Homing cycles
stat_t cm_homing_cycle_start(void); // G28.2
stat_t cm_homing_cycle_start_no_set(void); // G28.4
stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2
stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]); // G28.4
stat_t cm_homing_cycle_callback(void); // G28.2/.4 main loop callback
// Probe cycles
stat_t cm_straight_probe(float target[],
bool flags[],
bool failure_is_fatal,
bool moving_toward_switch); // G38.x
stat_t cm_straight_probe(float target[], bool flags[], // G38.x
bool trip_sense, bool alarm_flag);
stat_t cm_probing_cycle_callback(void); // G38.x main loop callback
stat_t cm_get_prbr(nvObj_t *nv); // enable/disable probe report
stat_t cm_set_prbr(nvObj_t *nv);
// Jogging cycle
stat_t cm_jogging_cycle_callback(void); // jogging cycle main loop
@@ -834,6 +707,9 @@ stat_t cm_set_mto(nvObj_t *nv); // set manual traverse override factor
stat_t cm_set_tram(nvObj_t *nv); // attempt setting the rotation matrix
stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non-identity
stat_t cm_set_nxln(nvObj_t *nv); // set what value we expect the next line number to have
stat_t cm_get_nxln(nvObj_t *nv); // return what value we expect the next line number to have
/*--- text_mode support functions ---*/
#ifdef __TEXT_MODE
@@ -884,6 +760,7 @@ stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non-
void cm_print_mto(nvObj_t *nv);
void cm_print_tram(nvObj_t *nv); // print if the axis has been rotated
void cm_print_nxln(nvObj_t *nv); // print the value of the next line number expected
void cm_print_am(nvObj_t *nv); // axis print functions
void cm_print_fr(nvObj_t *nv);
@@ -950,6 +827,7 @@ stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non-
#define cm_print_mto tx_print_stub
#define cm_print_tram tx_print_stub
#define cm_print_nxln tx_print_stub
#define cm_print_am tx_print_stub // axis print functions
#define cm_print_fr tx_print_stub
+1 -1
View File
@@ -732,7 +732,7 @@ nvObj_t *nv_add_conditional_message(const char *string) // conditionally add
void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags)
{
if (js.json_mode == JSON_MODE) {
if ((js.json_mode == JSON_MODE) || (js.json_mode == MARLIN_COMM_MODE)) {
json_print_list(status, json_flags);
} else {
text_print_list(status, text_flags);
+2 -1
View File
@@ -195,7 +195,8 @@ typedef uint16_t index_t; // use this if there are > 255 indexed o
typedef enum {
TEXT_MODE = 0, // sticky text mode
JSON_MODE, // sticky JSON mode
AUTO_MODE // auto-configure communications mode
AUTO_MODE, // auto-configure communications mode
MARLIN_COMM_MODE, // sticky marlin-compatibility mode (if compiled in)
} commMode;
typedef enum {
+19 -24
View File
@@ -165,13 +165,14 @@ const cfgItem_t cfgArray[] = {
{ "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_B], false }, // B homed
{ "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_C], false }, // C homed
{ "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_ro, (float *)&cm.probe_state[0], 0 }, // probing state
{ "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_ro, (float *)&cm.probe_state[0], 0 }, // probing state
{ "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_X], 0 },
{ "prb","prby",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Y], 0 },
{ "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Z], 0 },
{ "prb","prba",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_A], 0 },
{ "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_B], 0 },
{ "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_C], 0 },
{ "prb","prbr",_f0, 0, tx_print_nul, cm_get_prbr, cm_get_prbr, nullptr, 0 }, // enable probe report. Init in cm_init
{ "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm.jogging_dest, 0},
{ "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm.jogging_dest, 0},
@@ -603,14 +604,7 @@ const cfgItem_t cfgArray[] = {
{ "tof","tofa",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_A], 0 },
{ "tof","tofb",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 },
{ "tof","tofc",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 },
/*
{ "tl","tlx",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_X], 0 },
{ "tl","tly",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_Y], 0 },
{ "tl","tlz",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_Z], 0 },
{ "tl","tla",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_A], 0 },
{ "tl","tlb",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 },
{ "tl","tlc",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 },
*/
// Tool table offsets
{ "tt1","tt1x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[1][AXIS_X], TT1_X_OFFSET },
{ "tt1","tt1y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[1][AXIS_Y], TT1_Y_OFFSET },
@@ -881,9 +875,10 @@ const cfgItem_t cfgArray[] = {
#endif
{ "sys","ej", _fipn, 0, js_print_ej, get_ui8, json_set_ej,(float *)&cs.comm_mode, COMM_MODE },
{ "sys","jv", _fipn, 0, js_print_jv, get_ui8, json_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY },
{ "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_012, (float *)&qr.queue_report_verbosity, QUEUE_REPORT_VERBOSITY },
{ "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity,STATUS_REPORT_VERBOSITY },
{ "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_012, (float *)&qr.queue_report_verbosity, QR_OFF}, // default to OFF, set to QUEUE_REPORT_VERBOSITY after connected
{ "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity, SR_OFF}, // default to OFF, set to STATUS_REPORT_VERBOSITY after connectied
{ "sys","si", _fipn, 0, sr_print_si, get_int, sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS },
{ "", "nxln", _f0, 0, cm_print_nxln,cm_get_nxln,cm_set_nxln,(float *)&cs.null, 0 },
// Gcode defaults
// NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco
@@ -1120,7 +1115,7 @@ const cfgItem_t cfgArray[] = {
{ "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position
{ "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position
// +9 = 45
{ "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tof offsets
{ "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tool offsets
{ "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
@@ -1130,13 +1125,13 @@ const cfgItem_t cfgArray[] = {
{ "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
{ "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets
// +17 = 62
{ "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group
{ "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group
@@ -1358,7 +1353,7 @@ static stat_t _do_group_list(nvObj_t *nv, char list[][TOKEN_LEN+1]) // helper to
}
_do_group(nv, list[i]);
}
return (STAT_COMPLETE);
return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line
}
static stat_t _do_motors(nvObj_t *nv) // print parameters for all motor groups
@@ -1368,7 +1363,7 @@ static stat_t _do_motors(nvObj_t *nv) // print parameters for all motor groups
sprintf(group, "%d", i);
_do_group(nv, group);
}
return (STAT_COMPLETE);
return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line
}
static stat_t _do_axes(nvObj_t *nv) // print parameters for all axis groups
@@ -1390,7 +1385,7 @@ static stat_t _do_inputs(nvObj_t *nv) // print parameters for all input groups
sprintf(group, "di%d", i);
_do_group(nv, group);
}
return (STAT_COMPLETE);
return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line
}
static stat_t _do_outputs(nvObj_t *nv) // print parameters for all output groups
@@ -1400,7 +1395,7 @@ static stat_t _do_outputs(nvObj_t *nv) // print parameters for all output group
sprintf(group, "do%d", i);
_do_group(nv, group);
}
return (STAT_COMPLETE);
return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line
}
static stat_t _do_heaters(nvObj_t *nv) // print parameters for all heater groups
@@ -1410,7 +1405,7 @@ static stat_t _do_heaters(nvObj_t *nv) // print parameters for all heater group
sprintf(group, "he%d", i);
_do_group(nv, group);
}
return (STAT_COMPLETE);
return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line
}
static stat_t _do_all(nvObj_t *nv) // print all parameters
Executable → Regular
+75 -2
View File
@@ -48,6 +48,10 @@
#include "MotatePower.h"
#if MARLIN_COMPAT_ENABLED == true
#include "marlin_compatibility.h"
#endif
/***********************************************************************************
**** STRUCTURE ALLOCATIONS *********************************************************
***********************************************************************************/
@@ -167,6 +171,10 @@ static void _controller_HSM()
DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation
DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle
#if MARLIN_COMPAT_ENABLED == true
DISPATCH(marlin_callback()); // handle Marlin stuff - may return EAGAIN, must be after planner_callback!
#endif
//----- command readers and parsers --------------------------------------------------//
DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue
@@ -221,7 +229,17 @@ static void _dispatch_kernel(const devflags_t flags)
// It's possible to let some stuff through, but that's not happening yet.
return;
}
#if MARLIN_COMPAT_ENABLED == true
// marlin_handle_fake_stk500 returns true if it responded to a stk500v2 message
if (marlin_handle_fake_stk500(cs.bufp)) {
js.json_mode = MARLIN_COMM_MODE;
sr.status_report_verbosity = SR_OFF;
qr.queue_report_verbosity = QR_OFF;
return;
}
#endif
while ((*cs.bufp == SPC) || (*cs.bufp == TAB)) { // position past any leading whitespace
cs.bufp++;
}
@@ -263,6 +281,13 @@ static void _dispatch_kernel(const devflags_t flags)
text_response(gcode_parser(cs.bufp), cs.saved_buf);
}
#endif
#if MARLIN_COMPAT_ENABLED == true
else if (js.json_mode == MARLIN_COMM_MODE) { // handle marlin-specific protocol gcode
cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command
marlin_response(gcode_parser(cs.bufp), cs.saved_buf);
}
#endif
else { // anything else is interpreted as Gcode
cs.comm_request_mode = JSON_MODE; // mode of this command
@@ -272,12 +297,37 @@ static void _dispatch_kernel(const devflags_t flags)
nv_copy_string(nv, cs.bufp); // copy the Gcode line
nv->valuetype = TYPE_STRING;
status = gcode_parser(cs.bufp);
#if MARLIN_COMPAT_ENABLED == true
if (js.json_mode == MARLIN_COMM_MODE) { // in case a marlin-specific M-code was found
cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command
// We are switching to marlin_comm_mode, kill status reports and queue reports
sr.status_report_verbosity = SR_OFF;
qr.queue_report_verbosity = QR_OFF;
marlin_response(status, cs.saved_buf);
return;
}
#endif
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
}
}
/**** Local Functions ********************************************************/
/*
* _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 STATE MANAGEMENT
* _controller_state() - manage controller connection, startup, and other state changes
*/
@@ -287,9 +337,24 @@ static stat_t _controller_state()
{
if (cs.controller_state == CONTROLLER_CONNECTED) { // first time through after reset
cs.controller_state = CONTROLLER_STARTUP;
// This is here just to put a small delay in before the startup message.
#if MARLIN_COMPAT_ENABLED == true
// For Marlin compatibility, we need this to be long enough for the UI to say something and reveal
// if it's a Marlin-compatible UI.
if (xio_connected()) {
// xio_connected will only return true for USB and other non-permanent connections
_connection_timeout.set(2000);
} else {
_connection_timeout.set(1);
}
#else
_connection_timeout.set(10);
#endif
} else if ((cs.controller_state == CONTROLLER_STARTUP) && (_connection_timeout.isPast())) { // first time through after reset
if (MARLIN_COMM_MODE != js.json_mode) { // MARLIN_COMM_MODE is always defined, just not always used
_reset_comms_mode();
}
cs.controller_state = CONTROLLER_READY;
rpt_print_system_ready_message();
}
@@ -302,9 +367,14 @@ static stat_t _controller_state()
*/
void controller_set_connected(bool is_connected) {
// turn off reports while no-one's listening or we determine what dialect they speak
sr.status_report_verbosity = SR_OFF;
qr.queue_report_verbosity = QR_OFF;
if (is_connected) {
cs.controller_state = CONTROLLER_CONNECTED; // we JUST connected
} else { // we just disconnected from the last device, we'll expect a banner again
_reset_comms_mode();
cs.controller_state = CONTROLLER_NOT_CONNECTED;
}
}
@@ -321,7 +391,10 @@ void controller_set_muted(bool is_muted) {
const bool only_to_muted = true;
xio_writeline("{\"muted\":true}\n", only_to_muted);
} else {
// one channel just got unmuted, announce it (except to the muted)
// we're assuming anything that can be muted speaks g2core-dialect JSON
_reset_comms_mode();
// something was just unmuted (usually because USB disconnected), tell it
xio_writeline("{\"muted\":false}\n");
}
}
+3 -1
View File
@@ -64,10 +64,12 @@ typedef struct controllerSingleton { // main TG controller struct
uint32_t led_blink_rate; // used to flash indicator LED
// communications state variables
// cs.comm_mode is the setting for the communications more
// cs.comm_mode is the setting for the communications mode
// js.json_mode is the actual current mode (see also js.json_now)
commMode comm_mode; // ej: 0=text mode sticky, 1=JSON mode sticky, 2=auto mode
commMode comm_request_mode; // mode of request (may be different thatn the setting)
bool responses_suppressed; // if true, responses are to be suppressed (for internal-file delivery)
// controller serial buffers
char *bufp; // pointer to primary or secondary in buffer
+41 -37
View File
@@ -2,8 +2,8 @@
* cycle_homing.cpp - homing cycle extension to canonical_machine
* This file is part of the g2core project
*
* Copyright (c) 2010 - 2016 Alden S. Hart, Jr.
* Copyright (c) 2013 - 2016 Robert Giseburt
* Copyright (c) 2010 - 2017 Alden S. Hart, Jr.
* Copyright (c) 2013 - 2017 Robert 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
@@ -49,6 +49,8 @@ struct hmHomingSingleton { // persistent homing runtime variables
bool set_coordinates; // G28.4 flag. true = set coords to zero at the end of homing cycle
stat_t (*func)(int8_t axis); // binding for callback function state machine
bool axis_flags[AXES]; // local storage for axis flags
// per-axis parameters
float direction; // set to 1 for positive (max), -1 for negative (to min);
float search_travel; // signed distance to travel in search
@@ -152,7 +154,7 @@ static stat_t _set_homing_func(stat_t (*func)(int8_t axis)) {
* to cm_get_runtime_busy() is about.
*/
stat_t cm_homing_cycle_start(void) {
stat_t cm_homing_cycle_start(const float axes[], const bool flags[]) {
// save relevant non-axis parameters from Gcode model
hm.saved_units_mode = (cmUnitsMode)cm_get_units_mode(ACTIVE_MODEL);
hm.saved_coord_system = (cmCoordSystem)cm_get_coord_system(ACTIVE_MODEL);
@@ -160,6 +162,8 @@ stat_t cm_homing_cycle_start(void) {
hm.saved_feed_rate_mode = (cmFeedRateMode)cm_get_feed_rate_mode(ACTIVE_MODEL);
hm.saved_feed_rate = cm_get_feed_rate(ACTIVE_MODEL);
copy_vector(hm.axis_flags, flags);
// set working values
cm_set_units_mode(MILLIMETERS);
cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE);
@@ -178,8 +182,8 @@ stat_t cm_homing_cycle_start(void) {
return (STAT_OK);
}
stat_t cm_homing_cycle_start_no_set(void) {
cm_homing_cycle_start();
stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]) {
cm_homing_cycle_start(axes, flags);
hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle
return (STAT_OK);
}
@@ -407,38 +411,38 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom
static int8_t _get_next_axis(int8_t axis) {
#if (HOMING_AXES <= 4)
if (axis == -1) { // inelegant brute force solution
if (cm.gf.target[AXIS_Z]) {
if (hm.axis_flags[AXIS_Z]) {
return (AXIS_Z);
}
if (cm.gf.target[AXIS_X]) {
if (hm.axis_flags[AXIS_X]) {
return (AXIS_X);
}
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
return (-2); // error
} else if (axis == AXIS_Z) {
if (cm.gf.target[AXIS_X]) {
if (hm.axis_flags[AXIS_X]) {
return (AXIS_X);
}
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
} else if (axis == AXIS_X) {
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
} else if (axis == AXIS_Y) {
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
}
@@ -446,77 +450,77 @@ static int8_t _get_next_axis(int8_t axis) {
#else
if (axis == -1) {
if (cm.gf.target[AXIS_Z]) {
if (hm.axis_flags[AXIS_Z]) {
return (AXIS_Z);
}
if (cm.gf.target[AXIS_X]) {
if (hm.axis_flags[AXIS_X]) {
return (AXIS_X);
}
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
if (cm.gf.target[AXIS_B]) {
if (hm.axis_flags[AXIS_B]) {
return (AXIS_B);
}
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
return (-2); // error
} else if (axis == AXIS_Z) {
if (cm.gf.target[AXIS_X]) {
if (hm.axis_flags[AXIS_X]) {
return (AXIS_X);
}
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
if (cm.gf.target[AXIS_B]) {
if (hm.axis_flags[AXIS_B]) {
return (AXIS_B);
}
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
} else if (axis == AXIS_X) {
if (cm.gf.target[AXIS_Y]) {
if (hm.axis_flags[AXIS_Y]) {
return (AXIS_Y);
}
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
if (cm.gf.target[AXIS_B]) {
if (hm.axis_flags[AXIS_B]) {
return (AXIS_B);
}
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
} else if (axis == AXIS_Y) {
if (cm.gf.target[AXIS_A]) {
if (hm.axis_flags[AXIS_A]) {
return (AXIS_A);
}
if (cm.gf.target[AXIS_B]) {
if (hm.axis_flags[AXIS_B]) {
return (AXIS_B);
}
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
} else if (axis == AXIS_A) {
if (cm.gf.target[AXIS_B]) {
if (hm.axis_flags[AXIS_B]) {
return (AXIS_B);
}
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
} else if (axis == AXIS_B) {
if (cm.gf.target[AXIS_C]) {
if (hm.axis_flags[AXIS_C]) {
return (AXIS_C);
}
}
return (-1); // done
#endif // (HOMING_AXES <= 4)
}
}
+227 -305
View File
File diff suppressed because it is too large Load Diff
+12 -11
View File
@@ -202,10 +202,10 @@ 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 // the provided line number was out of sequence
#define STAT_MISSING_LINE_NUMBER_WITH_CHECKSUM 120 // if a checksum is provided, a line number should be present as well
#define STAT_ERROR_120 120
#define STAT_ERROR_121 121
#define STAT_ERROR_122 122
#define STAT_ERROR_123 123
@@ -279,6 +279,7 @@ char *get_status_message(stat_t status);
/* reserved for Gcode or other program errors */
#define STAT_ERROR_182 182
#define STAT_ERROR_183 183
#define STAT_ERROR_184 184
#define STAT_ERROR_185 185
@@ -312,7 +313,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
@@ -359,9 +360,9 @@ char *get_status_message(stat_t status);
#define STAT_PROBE_CYCLE_FAILED 250 // probing cycle did not complete
#define STAT_PROBE_TRAVEL_TOO_SMALL 251
#define STAT_NO_PROBE_SWITCH_CONFIGURED 252
#define STAT_NO_PROBE_INPUT_CONFIGURED 252
#define STAT_MULTIPLE_PROBE_SWITCHES_CONFIGURED 253
#define STAT_PROBE_SWITCH_ON_ABC_AXIS 254
#define STAT_PROBE_IS_ALREADY_TRIPPED 254
#define STAT_ERROR_255 255
@@ -498,9 +499,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";
@@ -603,7 +604,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";
@@ -650,7 +651,7 @@ static const char stat_250[] = "Probe cycle failed";
static const char stat_251[] = "Probe travel is too small";
static const char stat_252[] = "No probe switch configured";
static const char stat_253[] = "Multiple probe switches configured";
static const char stat_254[] = "Probe switch configured on ABC axis";
static const char stat_254[] = "Probe is already tripped";
static const char stat_255[] = "255";
static const char *const stat_msg[] = {
+10 -4
View File
@@ -5,7 +5,7 @@
<ProjectVersion>7.0</ProjectVersion>
<ToolchainName>com.Atmel.ARMGCC.CPP</ToolchainName>
<ProjectGuid>{44ea8fec-55d7-4149-8a78-a574fc26bf51}</ProjectGuid>
<avrdevice>ATSAM3X8E</avrdevice>
<avrdevice>ATSAM3X8C</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
@@ -68,7 +68,7 @@
<com_atmel_avrdbg_tool_atmelice>
<ToolOptions>
<InterfaceProperties>
<SwdClock>2000000</SwdClock>
<SwdClock>10000000</SwdClock>
</InterfaceProperties>
<InterfaceName>SWD</InterfaceName>
</ToolOptions>
@@ -101,8 +101,8 @@
</PercepioTrace>
<preserveEEPROM>true</preserveEEPROM>
<avrtoolserialnumber>J41800036434</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x285E0A60</avrdeviceexpectedsignature>
<avrtoolinterfaceclock>2000000</avrtoolinterfaceclock>
<avrdeviceexpectedsignature>0x284E0A60</avrdeviceexpectedsignature>
<avrtoolinterfaceclock>10000000</avrtoolinterfaceclock>
<custom>
<ToolOptions xmlns="">
<InterfaceProperties>
@@ -1713,6 +1713,12 @@
<Compile Include="g2core_info.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="marlin_compatibility.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="marlin_compatibility.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="settings\settings_makeblock.h">
<SubType>compile</SubType>
</Compile>
+7 -1
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 */,
@@ -201,7 +206,7 @@
/* Begin PBXLegacyTarget section */
D4037C091CDA42F300BC72AD /* G2 printrboardG2v3 PrintrbotPlus */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=PrintrbotPlus BOARD=printrboardG2v3 DEBUG=2";
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=PrintrbotPlus BOARD=printrboardG2v3 DEBUG=1";
buildConfigurationList = D4037C0A1CDA42F300BC72AD /* Build configuration list for PBXLegacyTarget "G2 printrboardG2v3 PrintrbotPlus" */;
buildPhases = (
);
@@ -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 */,
+583 -85
View File
File diff suppressed because it is too large Load Diff
Executable → Regular
+4 -4
View File
@@ -2,7 +2,7 @@
* gcode_parser.h - rs274/ngc Gcode parser
* This file is part of the g2core project
*
* Copyright (c) 2010 - 2016 Alden S. Hart, Jr.
* Copyright (c) 2010 - 2017 Alden S. Hart, Jr.
*
* 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
@@ -17,8 +17,8 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef GCODE_PARSER_H_ONCE
#define GCODE_PARSER_H_ONCE
#ifndef GCODE_H_ONCE
#define GCODE_H_ONCE
/*
* Global Scope Functions
@@ -27,4 +27,4 @@ stat_t gcode_parser(char* block);
stat_t gc_get_gc(nvObj_t* nv);
stat_t gc_run_gc(nvObj_t* nv);
#endif // End of include guard: GCODE_PARSER_H_ONCE
#endif // End of include guard: GCODE_H_ONCE
Executable → Regular
+25 -5
View File
@@ -2,8 +2,8 @@
* gpio.cpp - digital IO handling functions
* This file is part of the g2core project
*
* Copyright (c) 2015 - 2106 Alden S. Hart, Jr.
* Copyright (c) 2015 - 2016 Robert Giseburt
* Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
* Copyright (c) 2015 - 2017 Robert 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
@@ -335,11 +335,21 @@ void gpio_init(void)
void outputs_reset(void) {
// If the output is ACTIVE_LOW set it to 1. ACTIVE_HIGH gets set to 0.
#if D_OUT_CHANNELS >= 1
if (d_out[1-1].mode != IO_MODE_DISABLED) { (output_1_pin = (d_out[1-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
#if D_OUT_CHANNELS >= 2
if (d_out[2-1].mode != IO_MODE_DISABLED) { (output_2_pin = (d_out[2-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
#if D_OUT_CHANNELS >= 3
if (d_out[3-1].mode != IO_MODE_DISABLED) { (output_3_pin = (d_out[3-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
#if D_OUT_CHANNELS >= 4
if (d_out[4-1].mode != IO_MODE_DISABLED) { (output_4_pin = (d_out[4-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
#if D_OUT_CHANNELS >= 5
if (d_out[5-1].mode != IO_MODE_DISABLED) { (output_5_pin = (d_out[5-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
#if D_OUT_CHANNELS >= 6
if (d_out[6-1].mode != IO_MODE_DISABLED) { (output_6_pin = (d_out[6-1].mode == IO_ACTIVE_LOW) ? 1.0 : 0.0); }
#endif
@@ -422,6 +432,7 @@ void gpio_reset(void)
/*
* gpio_set_homing_mode() - set/clear input to homing mode
* gpio_set_probing_mode() - set/clear input to probing mode
* gpio_get_probing_input() - get probing input
* gpio_read_input() - read conditioned input
*
(* Note: input_num_ext means EXTERNAL input number -- 1-based
@@ -442,6 +453,16 @@ void gpio_set_probing_mode(const uint8_t input_num_ext, const bool is_probing)
d_in[input_num_ext-1].probing_mode = is_probing;
}
int8_t gpio_get_probing_input(void)
{
for (uint8_t i = 0; i <= D_IN_CHANNELS; i++) {
if (d_in[i-1].function == INPUT_FUNCTION_PROBE) {
return (i);
}
}
return (-1);
}
bool gpio_read_input(const uint8_t input_num_ext)
{
if (input_num_ext == 0) {
@@ -481,7 +502,6 @@ static stat_t _output_set_helper(nvObj_t *nv, const int8_t lower_bound, const in
return (STAT_OK);
}
stat_t io_set_mo(nvObj_t *nv) // input type or disabled
{
// return (_io_set_helper(nv, IO_MODE_DISABLED, IO_MODE_MAX));
@@ -668,9 +688,9 @@ stat_t io_set_output(nvObj_t *nv)
#ifdef __TEXT_MODE
static const char fmt_gpio_mo[] = "[%smo] input mode%17d [0=NO,1=NC,2=disabled]\n";
static const char fmt_gpio_mo[] = "[%smo] input mode%17d [0=active-low,1=active-hi,2=disabled]\n";
static const char fmt_gpio_ac[] = "[%sac] input action%15d [0=none,1=stop,2=fast_stop,3=halt,4=alarm,5=shutdown,6=panic,7=reset]\n";
static const char fmt_gpio_fn[] = "[%sfn] input function%13d [0=none,1=limit,2=interlock,3=shutdown]\n";
static const char fmt_gpio_fn[] = "[%sfn] input function%13d [0=none,1=limit,2=interlock,3=shutdown,4=probe]\n";
static const char fmt_gpio_in[] = "Input %s state: %5d\n";
static const char fmt_gpio_domode[] = "[%smo] output mode%16d [0=active low,1=active high,2=disabled]\n";
+5 -3
View File
@@ -68,9 +68,10 @@ typedef enum { // actions are initiated from within the
typedef enum { // functions are requested from the ISR, run from the main loop
INPUT_FUNCTION_NONE = 0,
INPUT_FUNCTION_LIMIT, // limit switch processing
INPUT_FUNCTION_INTERLOCK, // interlock processing
INPUT_FUNCTION_SHUTDOWN, // shutdown in support of external emergency stop
INPUT_FUNCTION_LIMIT = 1, // limit switch processing
INPUT_FUNCTION_INTERLOCK = 2, // interlock processing
INPUT_FUNCTION_SHUTDOWN = 3, // shutdown in support of external emergency stop
INPUT_FUNCTION_PROBE = 4, // assign input as probe input
INPUT_FUNCTION_MAX // unused. Just for range checking
} inputFunc;
@@ -130,6 +131,7 @@ void output_reset(void);
bool gpio_read_input(const uint8_t input_num);
void gpio_set_homing_mode(const uint8_t input_num, const bool is_homing);
void gpio_set_probing_mode(const uint8_t input_num, const bool is_probing);
int8_t gpio_get_probing_input(void);
stat_t io_set_mo(nvObj_t *nv);
stat_t io_set_ac(nvObj_t *nv);
+5 -4
View File
@@ -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
@@ -524,7 +525,7 @@ void json_print_list(stat_t status, uint8_t flags)
void json_print_response(uint8_t status, const bool only_to_muted /*= false*/)
{
if (js.json_verbosity == JV_SILENT) { // silent means no responses
if ((js.json_verbosity == JV_SILENT) || (cs.responses_suppressed)) { // silent means no responses
return;
}
if (js.json_verbosity == JV_EXCEPTIONS) { // cutout for JV_EXCEPTIONS mode
+1 -1
View File
@@ -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);
File diff suppressed because it is too large Load Diff
+68
View File
@@ -0,0 +1,68 @@
/*
* 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
enum cmExtruderMode {
EXTRUDER_MOVES_NORMAL = 0, // M82
EXTRUDER_MOVES_RELATIVE, // M83
EXTRUDER_MOVES_VOLUMETRIC // Ultimaker2Marlin
};
typedef struct MarlinStateExtended { // Canonical machine extensions for Marlin
bool marlin_flavor; // true if we are parsing gcode as Marlin-flavor
cmExtruderMode extruder_mode; // Mode of the extruder - changes how "E" is interpreted
} MarlinStateExtended_t;
extern MarlinStateExtended_t mst; // Marlin state object
/*
* Global Scope Functions
*/
// *** gcode and Mcode handling ***
stat_t marlin_start_tramming_bed(); // G29
stat_t marlin_list_sd_response(); // M20
stat_t marlin_select_sd_response(const char *file); // M23
stat_t marlin_set_extruder_mode(const uint8_t mode); // M82, M82
stat_t marlin_disable_motors(); // M84
stat_t marlin_set_motor_timeout(float s); // M84 Sxxx, M85 Sxxx, M18 Sxxx
stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait); // M104, M109, M140, M190
stat_t marlin_request_temperature_report(); // M105
stat_t marlin_set_fan_speed(const uint8_t fan, float speed); // M106, M107
stat_t marlin_request_position_report(); // M114
stat_t marlin_report_version(); // M115
// *** Marlin internal functions ***
stat_t marlin_callback(); // controller loop callback
void marlin_response(const stat_t status, char *buf); // response handler (primarily just prints "ok")
bool marlin_handle_fake_stk500(char *str); // fake stk500v2
#endif // End of include guard: MARLIN_COMPAT_H_ONCE
Executable → Regular
+4 -4
View File
@@ -2,7 +2,7 @@
* persistence.cpp - persistence functions
* This file is part of the g2core project
*
* Copyright (c) 2013 - 2016 Alden S. Hart Jr.
* Copyright (c) 2013 - 2017 Alden S. Hart Jr.
*
* 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
@@ -71,8 +71,8 @@ stat_t read_persistent_value(nvObj_t *nv)
stat_t write_persistent_value(nvObj_t *nv)
{
if (cm.cycle_state != CYCLE_OFF) { // can't write when machine is moving
return(rpt_exception(STAT_FILE_NOT_OPEN, "write_persistent_value() can't write when machine is in cycle"));
}
// if (cm.cycle_state != CYCLE_OFF) { // can't write when machine is moving
// return(rpt_exception(STAT_FILE_NOT_OPEN, "write_persistent_value() can't write when machine is in cycle"));
// }
return (STAT_OK);
}
+19 -1
View File
@@ -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
@@ -597,6 +605,16 @@ void mp_end_feed_override(const float ramp_time)
mp_start_feed_override (FEED_OVERRIDE_RAMP_TIME, 1.00);
}
void mp_start_traverse_override(const float ramp_time, const float override_factor)
{
return;
}
void mp_end_traverse_override(const float ramp_time)
{
return;
}
/*
* mp_planner_time_accounting() - gather time in planner
*/
+4 -1
View File
@@ -311,7 +311,7 @@ struct mpBuffer_to_clear {
float block_time_ms;
float plannable_time_ms; // time in planner
float plannable_length; // length in planner
uint8_t meet_iterations; // iterations needed in _get_meet_velocity
int8_t meet_iterations; // iterations needed in _get_meet_velocity
//+++++ to here
bufferState buffer_state; // used to manage queuing/dequeuing
@@ -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);
@@ -553,6 +554,8 @@ stat_t mp_planner_callback();
void mp_replan_queue(mpBuf_t *bf);
void mp_start_feed_override(const float ramp_time, const float override);
void mp_end_feed_override(const float ramp_time);
void mp_start_traverse_override(const float ramp_time, const float override);
void mp_end_traverse_override(const float ramp_time);
void mp_planner_time_accounting(void);
// planner buffer primitives
+6
View File
@@ -112,7 +112,13 @@ void rpt_print_loading_configs_message(void)
void rpt_print_system_ready_message(void)
{
#if MARLIN_COMPAT_ENABLED == true
if (MARLIN_COMM_MODE != js.json_mode) {
_startup_helper(STAT_OK, "SYSTEM READY");
}
#else
_startup_helper(STAT_OK, "SYSTEM READY");
#endif
if (cs.comm_mode == TEXT_MODE) { text_response(STAT_OK, (char *)"");}// prompt
}
+18 -16
View File
@@ -57,8 +57,10 @@
// Communications and reporting settings
#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
#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
#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects
#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE
#define JSON_VERBOSITY JV_LINENUM // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE
@@ -103,13 +105,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 +131,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,8 +57,10 @@
// 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
#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects
#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE
#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE
@@ -57,8 +57,10 @@
// 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
#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects
#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE
#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE
@@ -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
#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects
@@ -86,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 ************************************************************************************
@@ -282,7 +300,7 @@
// Zmin
#define DI5_MODE IO_ACTIVE_LOW // Z probe
#define DI5_ACTION INPUT_ACTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_PROBE
// Zmax
#define DI6_MODE IO_MODE_DISABLED
+20 -11
View File
@@ -2,7 +2,7 @@
* settings_default.h - default machine profile - Set for Shapeoko2
* This file is part of the g2core project
*
* Copyright (c) 2012 - 2016 Alden S. Hart, Jr.
* Copyright (c) 2012 - 2017 Alden S. Hart, Jr.
*
* 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
@@ -114,6 +114,10 @@
#define COOLANT_PAUSE_ON_HOLD true // {coph:
#endif
#ifndef PROBE_REPORT_ENABLE
#define PROBE_REPORT_ENABLE true // {prbr:
#endif
/*
* The following is to fix an issue where feedrate override was being defined in some users
* settings files but not others. This would otherwise cause an undefined compile error.
@@ -171,6 +175,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
@@ -674,7 +683,7 @@
// Xmin on v9 board
#ifndef DI1_MODE
#define DI1_MODE NORMALLY_OPEN
#define DI1_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI1_ACTION
#define DI1_ACTION INPUT_ACTION_NONE
@@ -685,7 +694,7 @@
// Xmax
#ifndef DI2_MODE
#define DI2_MODE NORMALLY_OPEN
#define DI2_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI2_ACTION
#define DI2_ACTION INPUT_ACTION_NONE
@@ -696,7 +705,7 @@
// Ymin
#ifndef DI3_MODE
#define DI3_MODE NORMALLY_OPEN
#define DI3_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI3_ACTION
#define DI3_ACTION INPUT_ACTION_NONE
@@ -707,7 +716,7 @@
// Ymax
#ifndef DI4_MODE
#define DI4_MODE NORMALLY_OPEN
#define DI4_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI4_ACTION
#define DI4_ACTION INPUT_ACTION_NONE
@@ -718,18 +727,18 @@
// Zmin
#ifndef DI5_MODE
#define DI5_MODE NORMALLY_OPEN
#define DI5_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI5_ACTION
#define DI5_ACTION INPUT_ACTION_NONE
#endif
#ifndef DI5_FUNCTION
#define DI5_FUNCTION INPUT_FUNCTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_PROBE
#endif
// Zmax
#ifndef DI6_MODE
#define DI6_MODE NORMALLY_OPEN
#define DI6_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI6_ACTION
#define DI6_ACTION INPUT_ACTION_NONE
@@ -740,7 +749,7 @@
// Amin
#ifndef DI7_MODE
#define DI7_MODE NORMALLY_OPEN
#define DI7_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI7_ACTION
#define DI7_ACTION INPUT_ACTION_NONE
@@ -751,7 +760,7 @@
// Amax
#ifndef DI8_MODE
#define DI8_MODE NORMALLY_OPEN
#define DI8_MODE IO_ACTIVE_LOW // Normally open
#endif
#ifndef DI8_ACTION
#define DI8_ACTION INPUT_ACTION_NONE
@@ -762,7 +771,7 @@
// Safety line
#ifndef DI9_MODE
#define DI9_MODE NORMALLY_CLOSED // Normally closed
#define DI9_MODE IO_ACTIVE_HIGH // Normally closed
#endif
#ifndef DI9_ACTION
#define DI9_ACTION INPUT_ACTION_NONE
+101 -40
View File
@@ -2,7 +2,7 @@
* settings_makeblock.h - makeblock engraving table
* This file is part of the g2core project
*
* Copyright (c) 2016 Alden S. Hart, Jr.
* Copyright (c) 2016 - 2017 Alden S. Hart, Jr.
*
* 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
@@ -50,26 +50,11 @@
#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high
#define COOLANT_PAUSE_ON_HOLD true
/*
#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster)
#define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm)
#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on
#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on
#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on
#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high
#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high
#define SPINDLE_PAUSE_ON_HOLD true
#define SPINDLE_DWELL_TIME 1.0
#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high
#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high
#define COOLANT_PAUSE_ON_HOLD false
*/
#define PROBE_REPORT_ENABLE true
// 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
#define USB_SERIAL_PORTS_EXPOSED 1
@@ -83,28 +68,13 @@
#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum
#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable
#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","vel","unit","stat","feed","coor","momo","plan","path","dist","mpox","mpoy","mpoz","admo","frmo","cycs","hold"
#define STATUS_REPORT_DEFAULTS "line","stat","posx","posy","posz",\
"vel", "unit","feed","coor","momo",\
"plan","path","dist","prbe","prbz",\
"mpox","mpoy","mpoz",\
"admo","frmo","cycs","hold"
// "_ts1","_cs1","_es1","_xs1","_fe1"
/*
#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE
#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE
#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE
#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE
#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE
#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum
#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable
//#define STATUS_REPORT_DEFAULTS
//"line","posx","posy","posz","posa","feed","vel","unit","coor","dist","admo","frmo","momo","stat"
#define STATUS_REPORT_DEFAULTS "line", "posx", "posy", "posz", "feed", "vel", "momo", "stat"
// Alternate SRs that report in drawable units
//#define STATUS_REPORT_DEFAULTS
//"line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo"
//#define STATUS_REPORT_DEFAULTS "_ts1","_cs1","_es1","_xs1","_fe1","line","posx","posy","posz","vel","stat"
*/
// Gcode startup defaults
#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES
#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ
@@ -120,7 +90,6 @@
// 2=MOTOR_POWERED_IN_CYCLE,
// 3=MOTOR_POWERED_ONLY_WHEN_MOVING
#define M1_POWER_LEVEL 0.4 // 0.0 = off, 1.0 = max
//.#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds
#define MOTOR_POWER_TIMEOUT 10.00 // motor power timeout in seconds
#define M1_MOTOR_MAP AXIS_X // 1ma
@@ -147,6 +116,14 @@
#define M3_POWER_MODE MOTOR_POWER_MODE
#define M3_POWER_LEVEL 0.4
#define M4_MOTOR_MAP AXIS_A
#define M4_STEP_ANGLE 1.8
#define M4_TRAVEL_PER_REV 1.25
#define M4_MICROSTEPS 8
#define M4_POLARITY 0
#define M4_POWER_MODE MOTOR_POWER_MODE
#define M4_POWER_LEVEL 0.4
// *** axis settings **********************************************************************************
#define JERK_MAX 5000
@@ -192,3 +169,87 @@
#define Z_LATCH_VELOCITY 25
#define Z_LATCH_BACKOFF 4
#define Z_ZERO_BACKOFF 2
#define A_AXIS_MODE AXIS_STANDARD
#define A_RADIUS 1
#define A_VELOCITY_MAX 360000
#define A_FEEDRATE_MAX A_VELOCITY_MAX
#define A_TRAVEL_MIN -1
#define A_TRAVEL_MAX -1
#define A_JERK_MAX 100000
#define A_JERK_HIGH_SPEED A_JERK_MAX
#define A_HOMING_INPUT 0
#define A_HOMING_DIRECTION 0
#define A_SEARCH_VELOCITY 600
#define A_LATCH_VELOCITY 100
#define A_LATCH_BACKOFF 10
#define A_ZERO_BACKOFF 2
//*** Input / output settings ***
/*
See gpio.h GPIO defines for options
Homing and probing settings are independent of ACTION and FUNCTION settings
but rely on proper switch MODE setting (i.e. NC or NO)
INPUT_MODE_DISABLED
INPUT_ACTIVE_LOW aka NORMALLY_OPEN
INPUT_ACTIVE_HIGH aka NORMALLY_CLOSED
INPUT_ACTION_NONE
INPUT_ACTION_STOP
INPUT_ACTION_FAST_STOP
INPUT_ACTION_HALT
INPUT_ACTION_RESET
INPUT_FUNCTION_NONE
INPUT_FUNCTION_LIMIT
INPUT_FUNCTION_INTERLOCK
INPUT_FUNCTION_SHUTDOWN
INPUT_FUNCTION_PROBE
*/
// Xmin on v9 board // X homing - see X axis setup
#define DI1_MODE NORMALLY_CLOSED
#define DI1_ACTION INPUT_ACTION_NONE
#define DI1_FUNCTION INPUT_FUNCTION_NONE
// Xmax // External ESTOP
#define DI2_MODE IO_ACTIVE_HIGH
#define DI2_ACTION INPUT_ACTION_HALT
#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN
// Ymin // Y homing - see Y axis setup
#define DI3_MODE NORMALLY_CLOSED
#define DI3_ACTION INPUT_ACTION_NONE
#define DI3_FUNCTION INPUT_FUNCTION_NONE
// Ymax // Safety interlock
#define DI4_MODE IO_ACTIVE_HIGH
#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function)
#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK
// Zmin // Z probe
#define DI5_MODE IO_ACTIVE_LOW
#define DI5_ACTION INPUT_ACTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_PROBE
// Zmax // Z homing - see Z axis for setup
#define DI6_MODE NORMALLY_CLOSED
#define DI6_ACTION INPUT_ACTION_NONE
#define DI6_FUNCTION INPUT_FUNCTION_NONE
// Amin // Unused
#define DI7_MODE IO_MODE_DISABLED
#define DI7_ACTION INPUT_ACTION_NONE
#define DI7_FUNCTION INPUT_FUNCTION_NONE
// Amax // Unused
#define DI8_MODE IO_MODE_DISABLED
#define DI8_ACTION INPUT_ACTION_NONE
#define DI8_FUNCTION INPUT_FUNCTION_NONE
// Safety line w/HW timer // Unused
#define DI9_MODE IO_MODE_DISABLED
#define DI9_ACTION INPUT_ACTION_NONE
#define DI9_FUNCTION INPUT_FUNCTION_NONE
+23 -45
View File
@@ -52,31 +52,6 @@
#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high
#define COOLANT_PAUSE_ON_HOLD true
constexpr float H1_DEFAULT_P = 7.0;
constexpr float H1_DEFAULT_I = 0.2;
constexpr float H1_DEFAULT_D = 100.0;
constexpr float H2_DEFAULT_P = 7.0;
constexpr float H2_DEFAULT_I = 0.2;
constexpr float H2_DEFAULT_D = 100.0;
constexpr float H3_DEFAULT_P = 7.0;
constexpr float H3_DEFAULT_I = 0.2;
constexpr float H3_DEFAULT_D = 100.0;
// WARNING: Older Othermill machines use a 15deg can stack for their Z axis.
// new machines use a stepper which has the same config as the other axis.
#define HAS_CANSTACK_Z_AXIS 0
/*
// Switch definitions for interlock & E-stop
#define ENABLE_INTERLOCK_AND_ESTOP
#define INTERLOCK_SWITCH_AXIS AXIS_Y
#define INTERLOCK_SWITCH_POSITION SW_MAX
#define ESTOP_SWITCH_AXIS AXIS_X
#define ESTOP_SWITCH_POSITION SW_MAX
#define PAUSE_DWELL_TIME 1.5 //after unpausing and turning the spindle on, dwell for 1.5s
*/
// Communications and reporting settings
#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE
@@ -89,7 +64,7 @@ constexpr float H3_DEFAULT_D = 100.0;
#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE
#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum
#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable
#define STATUS_REPORT_DEFAULTS \
#define STATUS_REPORT_DEFAULTS \
"mpox", "mpoy", "mpoz", "ofsx", "ofsy", "ofsz", "g55x", "g55y", "g55z", "unit", "stat", "coor", "momo", "dist", \
"home", "mots", "plan", "line", "path", "frmo", "prbe", "safe", "spe", "spd", "hold", "macs", "cycs", "sps"
@@ -132,13 +107,8 @@ constexpr float H3_DEFAULT_D = 100.0;
#define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE
#define M3_MOTOR_MAP AXIS_Z
#if HAS_CANSTACK_Z_AXIS
#define M3_STEP_ANGLE 15
#define M3_TRAVEL_PER_REV 1.27254
#else
#define M3_STEP_ANGLE 1.8
#define M3_TRAVEL_PER_REV 4.8768
#endif
#define M3_MICROSTEPS 8
#define M3_POLARITY 0
#define M3_POWER_MODE MOTOR_POWER_MODE
@@ -189,7 +159,7 @@ constexpr float H3_DEFAULT_D = 100.0;
#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive
#define X_SEARCH_VELOCITY (X_FEEDRATE_MAX / 3) // xsv
#define X_LATCH_VELOCITY LATCH_VELOCITY // xlv mm/min
#define X_LATCH_BACKOFF 5 // xlb mm
#define X_LATCH_BACKOFF 1.5 // xlb mm
#define X_ZERO_BACKOFF 0.4 // xzb mm
#define Y_AXIS_MODE AXIS_STANDARD
@@ -203,15 +173,11 @@ constexpr float H3_DEFAULT_D = 100.0;
#define Y_HOMING_DIRECTION 0
#define Y_SEARCH_VELOCITY (Y_FEEDRATE_MAX / 3)
#define Y_LATCH_VELOCITY LATCH_VELOCITY
#define Y_LATCH_BACKOFF 5
#define Y_LATCH_BACKOFF 1.5
#define Y_ZERO_BACKOFF 0.4
#define Z_AXIS_MODE AXIS_STANDARD
#if HAS_CANSTACK_Z_AXIS
#define Z_VELOCITY_MAX 1000
#else
#define Z_VELOCITY_MAX X_VELOCITY_MAX
#endif
#define Z_FEEDRATE_MAX Z_VELOCITY_MAX
#define Z_TRAVEL_MIN -60.1
#define Z_TRAVEL_MAX 0
@@ -221,7 +187,7 @@ constexpr float H3_DEFAULT_D = 100.0;
#define Z_HOMING_DIRECTION 1
#define Z_SEARCH_VELOCITY (Z_FEEDRATE_MAX / 3)
#define Z_LATCH_VELOCITY LATCH_VELOCITY
#define Z_LATCH_BACKOFF 5
#define Z_LATCH_BACKOFF 1.5
#define Z_ZERO_BACKOFF 0.4
// Rotary values are chosen to make the motor react the same as X for testing
@@ -300,7 +266,7 @@ constexpr float H3_DEFAULT_D = 100.0;
#define DI1_FUNCTION INPUT_FUNCTION_NONE
// Xmax // External ESTOP
#define DI2_MODE INPUT_ACTIVE_HIGH
#define DI2_MODE IO_ACTIVE_HIGH
#define DI2_ACTION INPUT_ACTION_HALT
#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN
@@ -310,14 +276,14 @@ constexpr float H3_DEFAULT_D = 100.0;
#define DI3_FUNCTION INPUT_FUNCTION_NONE
// Ymax // Safety interlock
#define DI4_MODE INPUT_ACTIVE_HIGH
#define DI4_MODE IO_ACTIVE_HIGH
#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function)
#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK
// Zmin // Z probe
#define DI5_MODE INPUT_ACTIVE_LOW
#define DI5_MODE IO_ACTIVE_LOW
#define DI5_ACTION INPUT_ACTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_NONE
#define DI5_FUNCTION INPUT_FUNCTION_PROBE
// Zmax // Z homing - see Z axis for setup
#define DI6_MODE NORMALLY_CLOSED
@@ -325,17 +291,17 @@ constexpr float H3_DEFAULT_D = 100.0;
#define DI6_FUNCTION INPUT_FUNCTION_NONE
// Amin // Unused
#define DI7_MODE INPUT_MODE_DISABLED
#define DI7_MODE IO_MODE_DISABLED
#define DI7_ACTION INPUT_ACTION_NONE
#define DI7_FUNCTION INPUT_FUNCTION_NONE
// Amax // Unused
#define DI8_MODE INPUT_MODE_DISABLED
#define DI8_MODE IO_MODE_DISABLED
#define DI8_ACTION INPUT_ACTION_NONE
#define DI8_FUNCTION INPUT_FUNCTION_NONE
// Safety line w/HW timer // Unused
#define DI9_MODE INPUT_MODE_DISABLED
#define DI9_MODE IO_MODE_DISABLED
#define DI9_ACTION INPUT_ACTION_NONE
#define DI9_FUNCTION INPUT_FUNCTION_NONE
@@ -420,3 +386,15 @@ constexpr float H3_DEFAULT_D = 100.0;
#define USER_DATA_D1 0
#define USER_DATA_D2 0
#define USER_DATA_D3 0
constexpr float H1_DEFAULT_P = 7.0;
constexpr float H1_DEFAULT_I = 0.2;
constexpr float H1_DEFAULT_D = 100.0;
constexpr float H2_DEFAULT_P = 7.0;
constexpr float H2_DEFAULT_I = 0.2;
constexpr float H2_DEFAULT_D = 100.0;
constexpr float H3_DEFAULT_P = 7.0;
constexpr float H3_DEFAULT_I = 0.2;
constexpr float H3_DEFAULT_D = 100.0;
+1 -1
View File
@@ -86,7 +86,7 @@
#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ
#define GCODE_DEFAULT_COORD_SYSTEM G54 // G54, G55, G56, G57, G58 or G59
#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS
#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_MODE
#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE
// *** motor settings ************************************************************************************
+37 -15
View File
@@ -2,7 +2,7 @@
* spindle.cpp - canonical machine spindle driver
* This file is part of the g2core project
*
* Copyright (c) 2010 - 2016 Alden S. Hart, Jr.
* Copyright (c) 2010 - 2017 Alden S. Hart, Jr.
*
* 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
@@ -222,28 +222,50 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction)
/*
* cm_spindle_override_enable()
* cm_spindle_override_factor()
* cm_spindle_override_control()
* cm_start_spindle_override()
* cm_end_spindle_override()
*/
/*
stat_t cm_spindle_override_enable(uint8_t flag) // M51.1
stat_t cm_sso_control(const float P_word, const bool P_flag) // M51
{
if (fp_TRUE(cm.gf.parameter) && fp_ZERO(cm.gn.parameter)) {
spindle.override_enable = false;
} else {
spindle.override_enable = true;
bool new_enable = true;
bool new_override = false;
if (P_flag) { // if parameter is present in Gcode block
if (fp_ZERO(P_word)) {
new_enable = false; // P0 disables override
} else {
if (P_word < SPINDLE_OVERRIDE_MIN) {
return (STAT_INPUT_LESS_THAN_MIN_VALUE);
}
if (P_word > SPINDLE_OVERRIDE_MAX) {
return (STAT_INPUT_EXCEEDS_MAX_VALUE);
}
spindle.sso_factor = P_word; // P word is valid, store it.
new_override = true;
}
}
if (cm.gmx.m48_enable) { // if master enable is ON
if (new_enable && (new_override || !spindle.sso_enable)) { // 3 cases to start a ramp
cm_start_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor);
} else if (spindle.sso_enable && !new_enable) { // case to turn off the ramp
cm_end_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME);
}
}
spindle.sso_enable = new_enable; // always update the enable state
return (STAT_OK);
}
stat_t cm_spindle_override_factor(uint8_t flag) // M50.1
void cm_start_spindle_override(const float ramp_time, const float override_factor)
{
spindle.override_enable = flag;
spindle.override_factor = cm.gn.parameter;
// change spindle speed
return (STAT_OK);
return;
}
*/
void cm_end_spindle_override(const float ramp_time)
{
return;
}
/****************************
* END OF SPINDLE FUNCTIONS *
****************************/
+6 -4
View File
@@ -60,8 +60,9 @@ typedef enum {
#define SPINDLE_OVERRIDE_ENABLE false
#define SPINDLE_OVERRIDE_FACTOR 1.00
#define SPINDLE_OVERRIDE_MIN 0.05 // 5%
#define SPINDLE_OVERRIDE_MAX 2.00 // 200%
#define SPINDLE_OVERRIDE_MIN 0.05 // 5%
#define SPINDLE_OVERRIDE_MAX 2.00 // 200%
#define SPINDLE_OVERRIDE_RAMP_TIME 1 // change speed in seconds
/*
* Spindle control structure
@@ -99,8 +100,9 @@ void cm_spindle_off_immediate(void);
void cm_spindle_optional_pause(bool option); // stop spindle based on system options selected
void cm_spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state
// stat_t cm_spindle_override_enable(uint8_t flag); // M51
// stat_t cm_spindle_override_factor(uint8_t flag); // M51.1
stat_t cm_sso_control(const float P_word, const bool P_flag); // M51
void cm_start_spindle_override(const float ramp_time, const float override_factor);
void cm_end_spindle_override(const float ramp_time);
stat_t cm_set_dir(nvObj_t* nv);
stat_t cm_set_sso(nvObj_t* nv);
+8 -4
View File
@@ -125,11 +125,11 @@ void stepper_init()
dda_timer.setInterrupts(kInterruptOnOverflow | kInterruptPriorityHighest);
// setup software interrupt exec timer & initial condition
exec_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityMedium);
exec_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityHigh);
st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;
// setup software interrupt forward plan timer & initial condition
fwd_plan_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityLow);
fwd_plan_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityMedium);
// setup motor power levels and apply power level to stepper drivers
for (uint8_t motor=0; motor<MOTORS; motor++) {
@@ -219,7 +219,11 @@ stat_t st_motor_power_callback() // called by controller
}
bool have_actually_stopped = false;
if ((!st_runtime_isbusy()) && (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER)) { // if there are no moves to load...
if ((!st_runtime_isbusy()) &&
(st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) &&
(cm_get_cycle_state() == CYCLE_OFF)
)
{ // if there are no moves to load...
have_actually_stopped = true;
}
@@ -793,7 +797,7 @@ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps)
if (motor >= MOTORS) {return;}
Motors[motor]->setMicrosteps(microsteps);
}
}
/***********************************************************************************
+89 -76
View File
@@ -82,7 +82,7 @@
// TEMP_MIN_RISE_TIME milliseconds, then it's a failure (the sensor is likely
// physically dislocated.)
#ifndef TEMP_MIN_RISE_DEGREES_OVER_TIME
#define TEMP_MIN_RISE_DEGREES_OVER_TIME (float)5.0
#define TEMP_MIN_RISE_DEGREES_OVER_TIME (float)10.0
#endif
#ifndef TEMP_MIN_RISE_TIME
#define TEMP_MIN_RISE_TIME (float)(60.0 * 1000.0) // 20 seconds
@@ -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;
@@ -663,7 +666,6 @@ stat_t cm_set_heater_p(nvObj_t *nv)
case '2': { pid2._p_factor = nv->value / 100.0; break; }
case '3': { pid3._p_factor = nv->value / 100.0; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
@@ -681,7 +683,6 @@ stat_t cm_get_heater_i(nvObj_t *nv)
case '2': { nv->value = pid2._i_factor * 100.0; break; }
case '3': { nv->value = pid3._i_factor * 100.0; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
@@ -697,7 +698,6 @@ stat_t cm_set_heater_i(nvObj_t *nv)
case '2': { pid2._i_factor = nv->value / 100.0; break; }
case '3': { pid3._i_factor = nv->value / 100.0; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
@@ -714,7 +714,6 @@ stat_t cm_get_heater_d(nvObj_t *nv)
case '2': { nv->value = pid2._d_factor * 100.0; break; }
case '3': { nv->value = pid3._d_factor * 100.0; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
@@ -729,7 +728,6 @@ stat_t cm_set_heater_d(nvObj_t *nv)
case '2': { pid2._d_factor = nv->value / 100.0; break; }
case '3': { pid3._d_factor = nv->value / 100.0; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
return (STAT_OK);
@@ -737,67 +735,81 @@ stat_t cm_set_heater_d(nvObj_t *nv)
/*
* cm_get_set_temperature()/cm_set_set_temperature() - get/set the set value of the PID
*
* There are both the file-to-file use version, and the NV-pair form (which uses the other).
*/
stat_t cm_get_set_temperature(nvObj_t *nv)
float cm_get_set_temperature(const uint8_t heater)
{
switch(_get_heater_number(nv)) {
case '1': { nv->value = pid1._set_point; break; }
case '2': { nv->value = pid2._set_point; break; }
case '3': { nv->value = pid3._set_point; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
switch(heater) {
case 1: { return pid1._set_point; break; }
case 2: { return pid2._set_point; break; }
case 3: { return pid3._set_point; break; }
default: { break; }
}
return 0.0;
}
stat_t cm_get_set_temperature(nvObj_t *nv)
{
nv->value = cm_get_set_temperature(_get_heater_number(nv) - '0');
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_FLOAT;
return (STAT_OK);
}
stat_t cm_set_set_temperature(nvObj_t *nv)
void cm_set_set_temperature(const uint8_t heater, const float value)
{
switch(_get_heater_number(nv)) {
case '1': { pid1._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; }
case '2': { pid2._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; }
case '3': { pid3._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; }
switch(heater) {
case 1: { pid1._set_point = min(TEMP_MAX_SETPOINT, value); break; }
case 2: { pid2._set_point = min(TEMP_MAX_SETPOINT, value); break; }
case 3: { pid3._set_point = min(TEMP_MAX_SETPOINT, value); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
// default to quiet the compiler
default: { break; }
}
}
stat_t cm_set_set_temperature(nvObj_t *nv)
{
cm_set_set_temperature(_get_heater_number(nv) - '0', nv->value);
return (STAT_OK);
}
/*
* cm_get_fan_power()/cm_set_fan_power() - get/set the set high-value setting of the heater fan
*/
stat_t cm_get_fan_power(nvObj_t *nv)
float cm_get_fan_power(const uint8_t heater)
{
switch(_get_heater_number(nv)) {
case '1': { nv->value = min(1.0f, heater_fan1.max_value); break; }
// case '2': { nv->value = min(1.0f, heater_fan2.max_value); break; }
// case '3': { nv->value = min(1.0f, heater_fan3.max_value); break; }
switch(heater) {
case 1: { return min(1.0f, heater_fan1.max_value); }
// case 2: { return min(1.0f, heater_fan2.max_value); }
// case 3: { return min(1.0f, heater_fan3.max_value); }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
default: { break; }
}
return 0.0;
}
stat_t cm_get_fan_power(nvObj_t *nv)
{
nv->value = cm_get_fan_power(_get_heater_number(nv) - '0');
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_FLOAT;
return (STAT_OK);
}
stat_t cm_set_fan_power(nvObj_t *nv)
{
switch(_get_heater_number(nv)) {
case '1': { heater_fan1.max_value = max(0.0f, nv->value); break; }
// case '2': { heater_fan2.max_value = max(0.0, nv->value); break; }
// case '3': { heater_fan3.max_value = max(0.0, nv->value); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
void cm_set_fan_power(const uint8_t heater, const float value)
{
switch(heater) {
case 1: { heater_fan1.max_value = max(0.0f, value); break; }
// case 2: { heater_fan2.max_value = max(0.0, value); break; }
// case 3: { heater_fan3.max_value = max(0.0, value); break; }
default: { break; }
}
}
stat_t cm_set_fan_power(nvObj_t *nv)
{
cm_set_fan_power(_get_heater_number(nv) - '0', nv->value);
return (STAT_OK);
}
@@ -811,7 +823,6 @@ stat_t cm_get_fan_min_power(nvObj_t *nv)
// case '2': { nv->value = heater_fan2.min_value; break; }
// case '3': { nv->value = heater_fan3.min_value; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
@@ -827,10 +838,9 @@ stat_t cm_set_fan_min_power(nvObj_t *nv)
// case '2': { heater_fan2.min_value = min(0.0, nv->value); break; }
// case '3': { heater_fan3.min_value = min(0.0, nv->value); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
return (STAT_OK);
}
@@ -844,7 +854,6 @@ stat_t cm_get_fan_low_temp(nvObj_t *nv)
// case '2': { nv->value = heater_fan2.low_temp; break; }
// case '3': { nv->value = heater_fan3.low_temp; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
@@ -860,10 +869,9 @@ stat_t cm_set_fan_low_temp(nvObj_t *nv)
// case '2': { heater_fan2.low_temp = min(0.0f, nv->value); break; }
// case '3': { heater_fan3.low_temp = min(0.0f, nv->value); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
return (STAT_OK);
}
@@ -877,7 +885,6 @@ stat_t cm_get_fan_high_temp(nvObj_t *nv)
// case '2': { nv->value = heater_fan2.high_temp; break; }
// case '3': { nv->value = heater_fan3.high_temp; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
@@ -893,27 +900,30 @@ stat_t cm_set_fan_high_temp(nvObj_t *nv)
// case '2': { heater_fan2.high_temp = min(0.0f, nv->value); break; }
// case '3': { heater_fan3.high_temp = min(0.0f, nv->value); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { break; }
}
return (STAT_OK);
}
/*
* cm_get_at_temperature() - get a boolean if the heater has reaced the set value of the PID
*/
stat_t cm_get_at_temperature(nvObj_t *nv)
bool cm_get_at_temperature(const uint8_t heater)
{
switch(_get_heater_number(nv)) {
case '1': { nv->value = pid1._at_set_point; break; }
case '2': { nv->value = pid2._at_set_point; break; }
case '3': { nv->value = pid3._at_set_point; break; }
switch(heater) {
case 1: { return pid1._at_set_point; }
case 2: { return pid2._at_set_point; }
case 3: { return pid3._at_set_point; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
default: { break; }
}
return false;
}
stat_t cm_get_at_temperature(nvObj_t *nv)
{
nv->value = cm_get_at_temperature(_get_heater_number(nv) - '0');
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_BOOL;
@@ -924,16 +934,20 @@ stat_t cm_get_at_temperature(nvObj_t *nv)
/*
* cm_get_heater_output() - get the output value (PWM duty cycle) of the PID
*/
float cm_get_heater_output(const uint8_t heater)
{
switch(heater) {
case 1: { return (float)fet_pin1; }
case 2: { return (float)fet_pin2; }
case 3: { return (float)fet_pin3; }
default: { break; }
}
return 0.0;
}
stat_t cm_get_heater_output(nvObj_t *nv)
{
switch(_get_heater_number(nv)) {
case '1': { nv->value = (float)fet_pin1; break; }
case '2': { nv->value = (float)fet_pin2; break; }
case '3': { nv->value = (float)fet_pin3; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->value = cm_get_heater_output(_get_heater_number(nv) - '0');
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_FLOAT;
@@ -950,7 +964,6 @@ stat_t cm_get_heater_adc(nvObj_t *nv)
case '2': { nv->value = (float)thermistor2.raw_adc_value; break; }
case '3': { nv->value = (float)thermistor3.raw_adc_value; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
@@ -962,17 +975,21 @@ stat_t cm_get_heater_adc(nvObj_t *nv)
/*
* cm_get_temperature() - get the current temperature
*/
float cm_get_temperature(const uint8_t heater)
{
switch(heater) {
case 1: { return (last_reported_temp1 = thermistor1.temperature_exact()); }
case 2: { return (last_reported_temp2 = thermistor2.temperature_exact()); }
case 3: { return (last_reported_temp3 = thermistor3.temperature_exact()); }
default: { break; }
}
return 0.0;
}
stat_t cm_get_temperature(nvObj_t *nv)
{
switch(_get_heater_number(nv)) {
case '1': { nv->value = last_reported_temp1 = thermistor1.temperature_exact(); break; }
case '2': { nv->value = last_reported_temp2 = thermistor2.temperature_exact(); break; }
case '3': { nv->value = last_reported_temp3 = thermistor3.temperature_exact(); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->value = cm_get_temperature(_get_heater_number(nv) - '0');
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_FLOAT;
@@ -989,7 +1006,6 @@ stat_t cm_get_thermistor_resistance(nvObj_t *nv)
case '2': { nv->value = thermistor2.get_resistance(); break; }
case '3': { nv->value = thermistor3.get_resistance(); break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
@@ -1019,7 +1035,6 @@ stat_t cm_get_pid_p(nvObj_t *nv)
case '2': { nv->value = pid2._proportional; break; }
case '3': { nv->value = pid3._proportional; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
@@ -1038,7 +1053,6 @@ stat_t cm_get_pid_i(nvObj_t *nv)
case '2': { nv->value = pid2._integral; break; }
case '3': { nv->value = pid3._integral; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
@@ -1057,12 +1071,11 @@ stat_t cm_get_pid_d(nvObj_t *nv)
case '2': { nv->value = pid2._derivative; break; }
case '3': { nv->value = pid3._derivative; break; }
// Failsafe. We can only get here if we set it up in config_app, but not here.
default: { nv->value = 0.0; break; }
}
nv->precision = GET_TABLE_WORD(precision);
nv->valuetype = TYPE_FLOAT;
return (STAT_OK);
}
+17
View File
@@ -49,20 +49,37 @@ stat_t cm_set_heater_d(nvObj_t* nv);
stat_t cm_get_pid_p(nvObj_t* nv);
stat_t cm_get_pid_i(nvObj_t* nv);
stat_t cm_get_pid_d(nvObj_t* nv);
float cm_get_set_temperature(const uint8_t heater);
stat_t cm_get_set_temperature(nvObj_t* nv);
void cm_set_set_temperature(const uint8_t heater, const float value);
stat_t cm_set_set_temperature(nvObj_t* nv);
float cm_get_fan_power(const uint8_t heater);
stat_t cm_get_fan_power(nvObj_t* nv);
void cm_set_fan_power(const uint8_t heater, const float value);
stat_t cm_set_fan_power(nvObj_t* nv);
stat_t cm_get_fan_min_power(nvObj_t* nv);
stat_t cm_set_fan_min_power(nvObj_t* nv);
stat_t cm_get_fan_low_temp(nvObj_t* nv);
stat_t cm_set_fan_low_temp(nvObj_t* nv);
stat_t cm_get_fan_high_temp(nvObj_t* nv);
stat_t cm_set_fan_high_temp(nvObj_t* nv);
bool cm_get_at_temperature(const uint8_t heater);
stat_t cm_get_at_temperature(nvObj_t* nv);
float cm_get_heater_output(const uint8_t heater);
stat_t cm_get_heater_output(nvObj_t* nv);
stat_t cm_get_heater_adc(nvObj_t* nv);
float cm_get_temperature(const uint8_t heater);
stat_t cm_get_temperature(nvObj_t* nv);
stat_t cm_get_thermistor_resistance(nvObj_t* nv);
+21
View File
@@ -173,10 +173,31 @@ 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) : ( (*p_ == '+') ? c_atof_int_(++p_, 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) {
// return count_>1 ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ : count_;
//}
template <int32_t length>
void str_concat(char *&dest, const char (&data)[length]) {
// length includes the \0
strncpy(dest, data, length); dest += length-1;
};
#endif // End of include guard: UTIL_H_ONCE
Executable → Regular
+144 -20
View File
@@ -33,7 +33,6 @@
#include "g2core.h"
#include "config.h"
#include "hardware.h"
#include "canonical_machine.h" // needs cm_has_hold()
#include "xio.h"
#include "report.h"
#include "controller.h"
@@ -168,6 +167,10 @@ struct xioDeviceWrapperBase { // C++ base class for device primit
virtual int16_t write(const char *buffer, int16_t len) { return -1; };
virtual char *readline(devflags_t limit_flags, uint16_t &size) { return nullptr; };
#if MARLIN_COMPAT_ENABLED == true
virtual void exitFakeBootloaderMode() {};
#endif
};
// Here we create the xio_t class, which has convenience methods to handle cross-device actions as a whole.
@@ -352,18 +355,18 @@ struct xio_t {
// Always check control-capable devices FIRST
for (uint8_t dev=0; dev < _dev_count; dev++) {
if (!DeviceWrappers[dev]->isActive())
if (!DeviceWrappers[dev]->isActive()) {
continue;
}
// If this channel is a DATA only, skip it this pass
if (!DeviceWrappers[dev]->isCtrl())
if (!DeviceWrappers[dev]->isCtrl()) {
continue;
}
ret_buffer = DeviceWrappers[dev]->readline(DEV_IS_CTRL, size);
if (size > 0) {
flags = DeviceWrappers[dev]->flags;
return ret_buffer;
}
}
@@ -378,18 +381,24 @@ struct xio_t {
if (size > 0) {
flags = DeviceWrappers[dev]->flags;
return ret_buffer;
}
}
}
size = 0;
flags = 0;
return (NULL);
};
#if MARLIN_COMPAT_ENABLED == true
void exitFakeBootloaderMode() {
for (int8_t i = 0; i < _dev_count; ++i) {
DeviceWrappers[i]->exitFakeBootloaderMode();
}
};
#endif
uint16_t magic_end;
};
@@ -442,6 +451,32 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
bool _last_returned_a_control = false;
#if MARLIN_COMPAT_ENABLED == true
enum class STK500V2_State {
Done, // not in the faked stk500v2 bootloader
Timeout, // timeout period, waiting for a start character
Start, // waiting for 0x1B
Sequence, // waiting for sequence byte
Length_0, // waiting for MSB of length
Length_1, // waiting for LSB of length
Header_End,// waiting for 0x0E
Data, // waiting for more data
Checksum // waiting for checksum byte
};
STK500V2_State _stk_parser_state;
uint16_t _stk_packet_data_length;
Motate::Timeout _stk_timeout;
void startFakeBootloaderMode() {
_stk_parser_state = STK500V2_State::Timeout;
_stk_timeout.set(2000); // two seconds
}
void exitFakeBootloaderMode() {
_stk_parser_state = STK500V2_State::Done;
}
#endif
LineRXBuffer(owner_type owner) : parent_type{owner} {};
void init() {
@@ -596,14 +631,80 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
while (_isMoreToScan()) {
bool ends_line = false;
bool is_control = false;
char c = _data[_scan_offset];
#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 (Marlin-mode)");
flush(); // consider the connection and all data trashed
return false;
}
if (_stk_parser_state >= STK500V2_State::Timeout) {
if (_stk_parser_state == STK500V2_State::Timeout) {
if (_stk_timeout.isPast()) {
_stk_parser_state = STK500V2_State::Done;
// start over, outside of stk500v2 mode
continue;
}
// if we got something before the timeout, then we're in stk500v2 mode
// we'll look at what we got and maybe exit anyway
_stk_parser_state = STK500V2_State::Start;
}
if (_stk_parser_state == STK500V2_State::Start) {
if (c == 0x1B) {
_stk_parser_state = STK500V2_State::Sequence;
// this is the start of this "line" and we can "read" (skip) everything up to here.
_read_offset = _scan_offset;
_line_start_offset = _scan_offset;
}
else if ((c == '{') || (c == 'N') || (c == '\n') || (c == '\r') || (c == 'G') || (c == 'M')) {
_stk_parser_state = STK500V2_State::Done; // jump out of bootloader mode
_read_offset = _scan_offset;
continue;
}
} else if (_stk_parser_state == STK500V2_State::Sequence) {
_stk_parser_state = STK500V2_State::Length_0; // we ignore the sequence
} else if (_stk_parser_state == STK500V2_State::Length_0) {
_stk_packet_data_length = c << 8;
_stk_parser_state = STK500V2_State::Length_1;
} else if (_stk_parser_state == STK500V2_State::Length_1) {
_stk_packet_data_length |= c;
_stk_parser_state = STK500V2_State::Header_End;
} else if (_stk_parser_state == STK500V2_State::Header_End) {
if (c == 0x0E) {
_stk_parser_state = STK500V2_State::Data;
} 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) {
if (--_stk_packet_data_length == 0) { // we don't read the data here, just return it
_stk_parser_state = STK500V2_State::Checksum;
}
} else if (_stk_parser_state == STK500V2_State::Checksum) {
// We do NOT check the checksum, since if it's corrupt, we'd need to reply, and we can't reply here.
// At this point, we at least have a complete packet we will use the "control" return mechanism to
// handle this since controls don't have to be \r\n-terminated
is_control = true;
ends_line = true;
_stk_parser_state = STK500V2_State::Start; // this line is complete, reset the state engine
}
}
else
#else // not MARLIN_COMPAT_ENABLED
if (c == 0) {
_debug_trap("scan ran into NULL");
flush(); // consider the connection and all data trashed
return false;
}
#endif // MARLIN_COMPAT_ENABLED
// Look for line endings
if (c == '\r' || c == '\n') {
@@ -673,7 +774,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
if (_data[_line_start_offset] == '{') {
is_control = true;
}
// TODO ---
}
@@ -708,8 +808,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
// move the start of the next skip section to after this skip
_line_start_offset = _scan_offset;
}
return false; // no control was found
};
@@ -998,11 +1096,11 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re
// set it as a MUTED channel, call controller_set_connected(true)
// then controller_set_muted(true)
flush(); // toss anything that has been written so far.
setAsConnectedAndReady();
if (isAlwaysDataAndCtrl()) {
// Case 1 (ignoring others)
if (isAlwaysDataAndCtrl()) { // Case 1 (ignoring others)
setActive();
controller_set_connected(true);
@@ -1010,11 +1108,10 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re
if (isMuteAsSecondary() && xio.othersConnected(this)) {
controller_set_muted(true); // something was muted
}
return;
}
if(!xio.othersConnected(this)) {
if (!xio.othersConnected(this)) {
// Case 1
setAsPrimaryActiveDualRole();
// report that there is now have a connection (only for the first one)
@@ -1023,15 +1120,17 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re
if (xio.checkMutedSecondaryChannels()) {
controller_set_muted(true); // something was muted
}
#if MARLIN_COMPAT_ENABLED == true
// start the "fake bootloader" to signal the Host that Marlin (mode) is operating
_rx_buffer.startFakeBootloaderMode();
#endif
}
else if (isMuteAsSecondary()) {
// Case 2b
else if (isMuteAsSecondary()) { // Case 2b
setAsMuted();
controller_set_connected(true); // it DID just just get connected
controller_set_muted(true); // but it muted it too
}
else {
// Case 2a
else { // Case 2a
xio.removeDataFromPrimary();
if (xio.checkMutedSecondaryChannels()) {
controller_set_muted(true); // something was muted
@@ -1085,6 +1184,13 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re
} // flags & DEV_IS_CONNECTED
}
};
#if MARLIN_COMPAT_ENABLED == true
void exitFakeBootloaderMode() override {
_rx_buffer.exitFakeBootloaderMode();
};
#endif
};
@@ -1121,6 +1227,14 @@ struct xioFlashFileDeviceWrapper : xioDeviceWrapperBase { // describes a devi
// to flush the file, just forget about it
// next time it's used it'll get reset
_current_file = nullptr;
cs.responses_suppressed = false;
}
bool flushToCommand() final {
// the end of the file is the next "command"
_current_file = nullptr;
cs.responses_suppressed = false;
return false;
}
int16_t write(const char *buffer, int16_t len) final {
@@ -1137,6 +1251,7 @@ struct xioFlashFileDeviceWrapper : xioDeviceWrapperBase { // describes a devi
if ((nullptr == from) && (_current_file->isDone())) {
// all done sending this file, "close" it
_current_file = nullptr;
cs.responses_suppressed = false;
clearActive();
return nullptr;
}
@@ -1151,6 +1266,7 @@ struct xioFlashFileDeviceWrapper : xioDeviceWrapperBase { // describes a devi
// null-terminate the string
*dst_ptr = 0;
cs.responses_suppressed = true;
return _line_buffer;
};
};
@@ -1287,7 +1403,15 @@ void xio_flush_to_command() {
return xio.flushToCommand();
}
#if MARLIN_COMPAT_ENABLED == true
/*
* xio_end_fake_bootloader() - end the fake bootloader mode
*/
void xio_exit_fake_bootloader() {
return xio.exitFakeBootloaderMode();
}
#endif
/***********************************************************************************
* newlib-nano support functions
+4
View File
@@ -51,6 +51,7 @@
//#include "g2core.h" // not required if used in g2core project
#include "config.h" // required for nvObj typedef
#include "canonical_machine.h" // needed for cm_has_hold()
#include "settings.h" // needed for MARLIN_COMPAT_ENABLED
/**** Defines, Macros, and Assorted Parameters ****/
@@ -120,6 +121,9 @@ char *xio_readline(devflags_t &flags, uint16_t &size);
int16_t xio_writeline(const char *buffer, bool only_to_muted = false);
bool xio_connected();
void xio_flush_to_command();
#if MARLIN_COMPAT_ENABLED == true
void xio_exit_fake_bootloader();
#endif
stat_t xio_set_spi(nvObj_t *nv);