diff --git a/config.h b/config.h
index a598b5c..6e96453 100755
--- a/config.h
+++ b/config.h
@@ -149,7 +149,7 @@
// TODO: The following options are set as compile-time options for now, until the next EEPROM
// settings version has solidified. This is to prevent having to support dozens of different
// incremental settings versions.
-#define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
+// -> NOW CODED INTO SETTINGS #define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
// This parameter sets the delay time before disabling the steppers after the final block of movement.
// A short delay ensures the steppers come to a complete stop and the residual inertial force in the
diff --git a/gcode.c b/gcode.c
index cbda3df..2ba47c0 100755
--- a/gcode.c
+++ b/gcode.c
@@ -34,62 +34,8 @@
#include "protocol.h"
#include "report.h"
-// Define modal group internal numbers for checking multiple command violations and tracking the
-// type of command that is called in the block. A modal group is a group of g-code commands that are
-// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
-// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
-// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
-#define MODAL_GROUP_NONE 0
-#define MODAL_GROUP_0 1 // [G4,G10,G28,G30,G53,G92,G92.1] Non-modal
-#define MODAL_GROUP_1 2 // [G0,G1,G2,G3,G80] Motion
-#define MODAL_GROUP_2 3 // [G17,G18,G19] Plane selection
-#define MODAL_GROUP_3 4 // [G90,G91] Distance mode
-#define MODAL_GROUP_4 5 // [M0,M1,M2,M30] Stopping
-#define MODAL_GROUP_5 6 // [G93,G94] Feed rate mode
-#define MODAL_GROUP_6 7 // [G20,G21] Units
-#define MODAL_GROUP_7 8 // [M3,M4,M5] Spindle turning
-#define MODAL_GROUP_12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
-
-// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
-// internally by the parser to know which command to execute.
-#define MOTION_MODE_SEEK 0 // G0
-#define MOTION_MODE_LINEAR 1 // G1
-#define MOTION_MODE_CW_ARC 2 // G2
-#define MOTION_MODE_CCW_ARC 3 // G3
-#define MOTION_MODE_CANCEL 4 // G80
-
-#define PROGRAM_FLOW_RUNNING 0
-#define PROGRAM_FLOW_PAUSED 1 // M0, M1
-#define PROGRAM_FLOW_COMPLETED 2 // M2, M30
-
-#define NON_MODAL_NONE 0
-#define NON_MODAL_DWELL 1 // G4
-#define NON_MODAL_SET_COORDINATE_DATA 2 // G10
-#define NON_MODAL_GO_HOME_0 3 // G28
-#define NON_MODAL_SET_HOME_0 4 // G28.1
-#define NON_MODAL_GO_HOME_1 5 // G30
-#define NON_MODAL_SET_HOME_1 6 // G30.1
-#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
-#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
-
-typedef struct {
- uint8_t status_code; // Parser status for current block
- uint8_t motion_mode; // {G0, G1, G2, G3, G80}
- uint8_t inverse_feed_rate_mode; // {G93, G94}
- uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21}
- uint8_t absolute_mode; // 0 = relative motion, 1 = absolute motion {G90, G91}
- uint8_t program_flow; // {M0, M1, M2, M30}
- int8_t spindle_direction; // 1 = CW, -1 = CCW, 0 = Stop {M3, M4, M5}
- uint8_t coolant_mode; // 0 = Disable, 1 = Flood Enable {M8, M9}
- float feed_rate, seek_rate; // Millimeters/second
- float position[3]; // Where the interpreter considers the tool to be at this point in the code
- uint8_t tool;
- uint16_t spindle_speed; // RPM/100
- uint8_t plane_axis_0,
- plane_axis_1,
- plane_axis_2; // The axes of the selected plane
-} parser_state_t;
-static parser_state_t gc;
+// Declare gc extern struct
+parser_state_t gc;
#define FAIL(status) gc.status_code = status;
@@ -105,10 +51,15 @@ static void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2)
void gc_init()
{
memset(&gc, 0, sizeof(gc));
- gc.feed_rate = settings.default_feed_rate;
+ gc.feed_rate = settings.default_feed_rate; // Should be zero at initialization.
select_plane(X_AXIS, Y_AXIS, Z_AXIS);
gc.absolute_mode = true;
+ // Load default G54 coordinate system.
+ if (!(settings_read_coord_data(gc.coord_select,gc.coord_system))) {
+ report_status_message(STATUS_SETTING_READ_FAIL);
+ }
+
// protocol_status_message(settings_execute_startup());
}
@@ -186,9 +137,8 @@ uint8_t gc_execute_line(char *line)
case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break;
case 20: gc.inches_mode = true; break;
case 21: gc.inches_mode = false; break;
- // NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
case 28: case 30:
- int_value = trunc(10*value); // Multiply by 10 to pick up G92.1
+ int_value = trunc(10*value); // Multiply by 10 to pick up Gxx.1
switch(int_value) {
case 280: non_modal_action = NON_MODAL_GO_HOME_0; break;
case 281: non_modal_action = NON_MODAL_SET_HOME_0; break;
@@ -199,7 +149,7 @@ uint8_t gc_execute_line(char *line)
break;
case 53: absolute_override = true; break;
case 54: case 55: case 56: case 57: case 58: case 59:
- sys.coord_select = int_value-54;
+ gc.coord_select = int_value-54;
break;
case 80: gc.motion_mode = MOTION_MODE_CANCEL; break;
case 90: gc.absolute_mode = true; break;
@@ -226,10 +176,11 @@ uint8_t gc_execute_line(char *line)
// Set 'M' commands
switch(int_value) {
case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
- case 1: // Program pause with optional stop on
- // if (sys.opt_stop) { // TODO: Add system variable for optional stop.
- gc.program_flow = PROGRAM_FLOW_PAUSED; break;
- // }
+ case 1: // Program pause with optional stop on, otherwise do nothing.
+ if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) {
+ gc.program_flow = PROGRAM_FLOW_PAUSED;
+ }
+ break;
case 2: case 30: gc.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset
case 3: gc.spindle_direction = 1; break;
case 4: gc.spindle_direction = -1; break;
@@ -280,7 +231,8 @@ uint8_t gc_execute_line(char *line)
case 'R': r = to_millimeters(value); break;
case 'S':
if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative
- gc.spindle_speed = value;
+ // TBD: Spindle speed not supported due to PWM issues, but may come back once resolved.
+ // gc.spindle_speed = value;
break;
case 'T':
if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative
@@ -304,7 +256,7 @@ uint8_t gc_execute_line(char *line)
// ([M6]: Tool change should be executed here.)
// [M3,M4,M5]: Update spindle state
- spindle_run(gc.spindle_direction, gc.spindle_speed);
+ spindle_run(gc.spindle_direction); //, gc.spindle_speed);
// [*M7,M8,M9]: Update coolant state
coolant_run(gc.coolant_mode);
@@ -312,8 +264,8 @@ uint8_t gc_execute_line(char *line)
// [G54,G55,...,G59]: Coordinate system selection
if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block
float coord_data[N_AXIS];
- if (!(settings_read_coord_data(sys.coord_select,coord_data))) { return(STATUS_SETTING_READ_FAIL); }
- memcpy(sys.coord_system,coord_data,sizeof(coord_data));
+ if (!(settings_read_coord_data(gc.coord_select,coord_data))) { return(STATUS_SETTING_READ_FAIL); }
+ memcpy(gc.coord_system,coord_data,sizeof(coord_data));
}
// [G4,G10,G28,G30,G92,G92.1]: Perform dwell, set coordinate system data, homing, or set axis offsets.
@@ -338,7 +290,7 @@ uint8_t gc_execute_line(char *line)
if (l == 20) {
settings_write_coord_data(int_value,gc.position);
// Update system coordinate system if currently active.
- if (sys.coord_select == int_value) { memcpy(sys.coord_system,gc.position,sizeof(gc.position)); }
+ if (gc.coord_select == int_value) { memcpy(gc.coord_system,gc.position,sizeof(gc.position)); }
} else {
float coord_data[N_AXIS];
if (!settings_read_coord_data(int_value,coord_data)) { return(STATUS_SETTING_READ_FAIL); }
@@ -349,7 +301,7 @@ uint8_t gc_execute_line(char *line)
}
settings_write_coord_data(int_value,coord_data);
// Update system coordinate system if currently active.
- if (sys.coord_select == int_value) { memcpy(sys.coord_system,coord_data,sizeof(coord_data)); }
+ if (gc.coord_select == int_value) { memcpy(gc.coord_system,coord_data,sizeof(coord_data)); }
}
}
axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags.
@@ -363,7 +315,7 @@ uint8_t gc_execute_line(char *line)
for (i=0; i.
*/
-
#ifndef gcode_h
#define gcode_h
#include
+#include "nuts_bolts.h"
+
+// Define modal group internal numbers for checking multiple command violations and tracking the
+// type of command that is called in the block. A modal group is a group of g-code commands that are
+// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
+// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
+// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
+#define MODAL_GROUP_NONE 0
+#define MODAL_GROUP_0 1 // [G4,G10,G28,G30,G53,G92,G92.1] Non-modal
+#define MODAL_GROUP_1 2 // [G0,G1,G2,G3,G80] Motion
+#define MODAL_GROUP_2 3 // [G17,G18,G19] Plane selection
+#define MODAL_GROUP_3 4 // [G90,G91] Distance mode
+#define MODAL_GROUP_4 5 // [M0,M1,M2,M30] Stopping
+#define MODAL_GROUP_5 6 // [G93,G94] Feed rate mode
+#define MODAL_GROUP_6 7 // [G20,G21] Units
+#define MODAL_GROUP_7 8 // [M3,M4,M5] Spindle turning
+#define MODAL_GROUP_12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
+
+// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
+// internally by the parser to know which command to execute.
+#define MOTION_MODE_SEEK 0 // G0
+#define MOTION_MODE_LINEAR 1 // G1
+#define MOTION_MODE_CW_ARC 2 // G2
+#define MOTION_MODE_CCW_ARC 3 // G3
+#define MOTION_MODE_CANCEL 4 // G80
+
+#define PROGRAM_FLOW_RUNNING 0
+#define PROGRAM_FLOW_PAUSED 1 // M0, M1
+#define PROGRAM_FLOW_COMPLETED 2 // M2, M30
+
+#define NON_MODAL_NONE 0
+#define NON_MODAL_DWELL 1 // G4
+#define NON_MODAL_SET_COORDINATE_DATA 2 // G10
+#define NON_MODAL_GO_HOME_0 3 // G28
+#define NON_MODAL_SET_HOME_0 4 // G28.1
+#define NON_MODAL_GO_HOME_1 5 // G30
+#define NON_MODAL_SET_HOME_1 6 // G30.1
+#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
+#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
+
+typedef struct {
+ uint8_t status_code; // Parser status for current block
+ uint8_t motion_mode; // {G0, G1, G2, G3, G80}
+ uint8_t inverse_feed_rate_mode; // {G93, G94}
+ uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21}
+ uint8_t absolute_mode; // 0 = relative motion, 1 = absolute motion {G90, G91}
+ uint8_t program_flow; // {M0, M1, M2, M30}
+ int8_t spindle_direction; // 1 = CW, -1 = CCW, 0 = Stop {M3, M4, M5}
+ uint8_t coolant_mode; // 0 = Disable, 1 = Flood Enable {M8, M9}
+ float feed_rate; // Millimeters/min
+ float position[3]; // Where the interpreter considers the tool to be at this point in the code
+ uint8_t tool;
+// uint16_t spindle_speed; // RPM/100
+ uint8_t plane_axis_0,
+ plane_axis_1,
+ plane_axis_2; // The axes of the selected plane
+ uint8_t coord_select; // Active work coordinate system number. Default: 0=G54.
+ float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine
+ // position in mm. Loaded from EEPROM when called.
+ float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
+ // machine zero in mm. Non-persistent. Cleared upon reset and boot.
+} parser_state_t;
+extern parser_state_t gc;
// Initialize the parser
void gc_init();
diff --git a/nuts_bolts.h b/nuts_bolts.h
index 981bb50..2eb0525 100755
--- a/nuts_bolts.h
+++ b/nuts_bolts.h
@@ -35,12 +35,12 @@
#define Y_AXIS 1
#define Z_AXIS 2
-#define MM_PER_INCH (25.4)
-#define INCH_PER_MM (0.03937)
+#define MM_PER_INCH (25.40)
+#define INCH_PER_MM (0.0393701)
// Useful macros
#define clear_vector(a) memset(a, 0, sizeof(a))
-#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*3)
+#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS)
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
@@ -86,20 +86,16 @@ typedef struct {
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
-// uint8_t switches; // Switches state bitflag variable. For settings not governed by g-code.
-
- int32_t position[3]; // Real-time machine (aka home) position vector in steps.
- // NOTE: This may need to be a volatile variable, if problems arise.
+ uint8_t switches; // Switches state bitflag variable. For features not governed by g-code.
+
+// uint8_t state; // Tracks the current state of Grbl.
+// TODO: This may replace the functionality of the feed_hold and cycle_start variables. Need to
+// make sure that overall processes don't change.
- uint8_t coord_select; // Active work coordinate system number. Default: 0=G54.
- float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine
- // position in mm. Loaded from EEPROM when called.
- float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
- // machine zero in mm.
-
volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
-
+ int32_t position[3]; // Real-time machine (aka home) position vector in steps.
+ // NOTE: This may need to be a volatile variable, if problems arise.
} system_t;
extern system_t sys;
diff --git a/protocol.c b/protocol.c
index 439b148..864351e 100755
--- a/protocol.c
+++ b/protocol.c
@@ -135,77 +135,80 @@ uint8_t protocol_execute_line(char *line)
uint8_t char_counter = 1;
float parameter, value;
switch( line[char_counter] ) {
- case 0 :
- report_grbl_help();
- return(STATUS_OK);
+ case 0 : report_grbl_help(); break;
+ case '$' : // Prints Grbl settings
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ else { report_grbl_settings(); }
+ break;
+ case '#' : // Print gcode parameters
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ else { report_gcode_parameters(); }
+ break;
+ case 'G' : // Prints gcode parser state
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ else { report_gcode_modes(); }
break;
-// case '#' :
-// if ( line[++char_counter] == 0 ) {
-// // Print all parameters
-// return(STATUS_OK);
-// } else {
-// return(STATUS_UNSUPPORTED_STATEMENT);
-// }
-// case 'G' : // Start up blocks
-// if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
-// if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
-// // Extract startup block, execute, and store.
-// for (char_counter = 0; char_counter < LINE_BUFFER_SIZE-3; char_counter++) {
-// line[char_counter] = line[char_counter+3];
-// }
-// uint8_t status = gc_execute_line(line);
-// if (status) { return(status); }
-// else { settings_store_startup_block(line); }
-// break;
case 'H' : // Perform homing cycle
- if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
- mc_go_home();
- return(STATUS_OK);
- } else {
- return(STATUS_SETTING_DISABLED);
- }
+ if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { mc_go_home(); }
+ else { return(STATUS_SETTING_DISABLED); }
break;
-// // case 'J' : break; // Jogging methods
-// // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be
-// // susceptible to other runtime commands except for e-stop. The jogging function is intended to
-// // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped
-// // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would
-// // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the
-// // motion by repeatedly toggling to slow the motion to the desired location. Location data would
-// // need to be updated real-time and supplied to the user through status queries.
-// // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are
-// // handled by the planner. It would be possible for the jog subprogram to insert blocks into the
-// // block buffer without having the planner plan them. It would need to manage de/ac-celerations
-// // on its own carefully. This approach could be effective and possibly size/memory efficient.
-// case 'P' : // Print g-code parameters and parser state
-// if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); }
-//
-// break;
-// case 'S' : // Switch methods
-// // Opt stop and block delete are referred to as switches.
-// // How to store home position and work offsets real-time??
-// break;
-// // Parse $parameter=value settings
- default :
- if(!read_float(line, &char_counter, ¶meter)) {
- return(STATUS_BAD_NUMBER_FORMAT);
- }
- if(line[char_counter++] != '=') {
- return(STATUS_UNSUPPORTED_STATEMENT);
- }
- if(!read_float(line, &char_counter, &value)) {
- return(STATUS_BAD_NUMBER_FORMAT);
- }
- if(line[char_counter] != 0) {
- return(STATUS_UNSUPPORTED_STATEMENT);
- }
+// case 'J' : break; // Jogging methods
+ // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be
+ // susceptible to other runtime commands except for e-stop. The jogging function is intended to
+ // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped
+ // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would
+ // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the
+ // motion by repeatedly toggling to slow the motion to the desired location. Location data would
+ // need to be updated real-time and supplied to the user through status queries.
+ // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are
+ // handled by the planner. It would be possible for the jog subprogram to insert blocks into the
+ // block buffer without having the planner plan them. It would need to manage de/ac-celerations
+ // on its own carefully. This approach could be effective and possibly size/memory efficient.
+// case 'N' : // Start up blocks
+// if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
+// if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
+// // Extract startup block, execute, and store.
+// for (char_counter = 0; char_counter < LINE_BUFFER_SIZE-3; char_counter++) {
+// line[char_counter] = line[char_counter+3];
+// }
+// uint8_t status = gc_execute_line(line);
+// if (status) { return(status); }
+// else { settings_store_startup_block(line); }
+// break;
+ case 'B' : // Toggle block delete
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ sys.switches ^= BITFLAG_BLOCK_DELETE;
+ if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) { report_feedback_message(MESSAGE_SWITCH_ON); }
+ else { report_feedback_message(MESSAGE_SWITCH_OFF); }
+ break;
+ case 'S' : // Toggle single block mode
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ sys.switches ^= BITFLAG_SINGLE_BLOCK;
+ if (bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) { report_feedback_message(MESSAGE_SWITCH_ON); }
+ else { report_feedback_message(MESSAGE_SWITCH_OFF); }
+ break;
+ case 'O' : // Toggle optional stop
+ if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
+ sys.switches ^= BITFLAG_OPT_STOP;
+ if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) { report_feedback_message(MESSAGE_SWITCH_ON); }
+ else { report_feedback_message(MESSAGE_SWITCH_OFF); }
+ break;
+ default : // Store global setting
+ if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
+ if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
+ if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
+ if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); }
return(settings_store_global_setting(parameter, value));
}
+ return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
+
} else {
+
return(gc_execute_line(line)); // Everything else is gcode
// TODO: Install option to set system alarm upon any error code received back from the
// the g-code parser. This is a common safety feature on CNCs to help prevent crashes
// if the g-code doesn't perform as intended.
+
}
}
@@ -246,9 +249,9 @@ void protocol_process()
// Throw away whitepace and control characters
} else if (c == '/') {
// Disable block delete and throw away characters. Will ignore until EOL.
- #if BLOCK_DELETE_ENABLE
+ if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) {
iscomment = true;
- #endif
+ }
} else if (c == '(') {
// Enable comments flag and ignore all characters until ')' or EOL.
iscomment = true;
diff --git a/report.c b/report.c
index 9bb3522..2383695 100644
--- a/report.c
+++ b/report.c
@@ -34,6 +34,8 @@
#include
#include "report.h"
#include "protocol.h"
+#include "gcode.h"
+#include "coolant_control.h"
// Handles the primary confirmation protocol response for streaming interfaces and human-feedback.
@@ -82,12 +84,12 @@ void report_status_message(uint8_t status_code)
// Prints feedback messages. This serves as a centralized method to provide additional
// user feedback for things that are not of the status message response protocol. These
// are messages such as setup warnings and how to exit alarms.
-// NOTE: For interfaces, messages are always placed within parentheses. And if silent mode
-// is installed, the message codes are less than zero.
+// NOTE: For interfaces, messages are always placed within chevrons. And if silent mode
+// is installed, the message number codes are less than zero.
// TODO: Install silence feedback messages option in settings
void report_feedback_message(int8_t message_code)
{
- printPgmString(PSTR("("));
+ printPgmString(PSTR("<"));
switch(message_code) {
case MESSAGE_SYSTEM_ALARM:
printPgmString(PSTR("ALARM: Check and reset Grbl")); break;
@@ -95,20 +97,37 @@ void report_feedback_message(int8_t message_code)
printPgmString(PSTR("warning: Position may be lost")); break;
case MESSAGE_HOMING_ENABLE:
printPgmString(PSTR("'$H' to home. Ensure all limit switches are installed")); break;
+ case MESSAGE_SWITCH_ON:
+ printPgmString(PSTR("Switch enabled")); break;
+ case MESSAGE_SWITCH_OFF:
+ printPgmString(PSTR("Switch disabled")); break;
}
- printPgmString(PSTR(")\r\n"));
+ printPgmString(PSTR(">\r\n"));
}
// Welcome message
void report_init_message()
{
- // Print grbl initialization message
- printPgmString(PSTR("\r\nGrbl " GRBL_VERSION));
- printPgmString(PSTR("\r\n'$' for help and to view settings\r\n"));
+ printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
}
void report_grbl_help() {
+// char st_line[LINE_BUFFER_SIZE];
+// printPgmString(PSTR("\r\n\r\n Startup\r\n$100 = ")); printString(settings_read_startup(st_line,0));
+// printPgmString(PSTR("\r\n$101 = ")); printString(settings_read_startup(st_line,1));
+
+// char buf[4];
+// settings_startup_string((char *)buf);
+// printPgmString(PSTR("\r\n Startup: ")); printString(buf);
+
+ printPgmString(PSTR("$ (help)\r\n$$ (print Grbl settings)\r\n$# (print gcode parameters)\r\n$G (print gcode parser state)"));
+ printPgmString(PSTR("\r\n$x=value (store Grbl setting)\r\n$Nx=line (store startup block)\r\n$H (run homing cycle, if enabled)"));
+ printPgmString(PSTR("\r\n$B (toggle block delete)\r\n$S (toggle single block mode)\r\n$O (toggle opt stop)"));
+ printPgmString(PSTR("\r\n~ (cycle start)\r\n! (feed hold)\r\n? (current position)\r\n^x (reset Grbl)\r\n"));
+}
+
+void report_grbl_settings() {
printPgmString(PSTR("$0 = ")); printFloat(settings.steps_per_mm[X_AXIS]);
printPgmString(PSTR(" (x axis, steps/mm)\r\n$1 = ")); printFloat(settings.steps_per_mm[Y_AXIS]);
printPgmString(PSTR(" (y axis, steps/mm)\r\n$2 = ")); printFloat(settings.steps_per_mm[Z_AXIS]);
@@ -134,29 +153,108 @@ void report_grbl_help() {
printPgmString(PSTR(" (homing pull-off travel, mm)\r\n$20 = ")); printInteger(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (stepper idle lock time, msec)\r\n$21 = ")); printInteger(settings.decimal_places);
printPgmString(PSTR(" (decimal places, int)\r\n$22 = ")); printInteger(settings.n_arc_correction);
-// char st_line[LINE_BUFFER_SIZE];
-// printPgmString(PSTR("\r\n\r\n Startup\r\n$100 = ")); printString(settings_read_startup(st_line,0));
-// printPgmString(PSTR("\r\n$101 = ")); printString(settings_read_startup(st_line,1));
-
-// char buf[4];
-// settings_startup_string((char *)buf);
-// printPgmString(PSTR("\r\n Startup: ")); printString(buf);
-
- printPgmString(PSTR("\r\n'$x=value' to store setting"));
-// printPgmString(PSTR("\r\n'$Sx' to toggle switch\r\n"));
+ printPgmString(PSTR(" (n arc correction, int)\r\n"));
}
+void report_gcode_parameters()
+{
+ float coord_data[N_AXIS];
+ uint8_t coord_select, i;
+ for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
+ if (!(settings_read_coord_data(coord_select,coord_data))) {
+ report_status_message(STATUS_SETTING_READ_FAIL);
+ return;
+ }
+ switch (coord_select) {
+ case 0: printPgmString(PSTR("G54")); break;
+ case 1: printPgmString(PSTR("G55")); break;
+ case 2: printPgmString(PSTR("G56")); break;
+ case 3: printPgmString(PSTR("G57")); break;
+ case 4: printPgmString(PSTR("G58")); break;
+ case 5: printPgmString(PSTR("G59")); break;
+ case 6: printPgmString(PSTR("G28")); break;
+ case 7: printPgmString(PSTR("G30")); break;
+ // case 8: printPgmString(PSTR("G92")); break; // G92.2, G92.3 currently not supported.
+ }
+ printPgmString(PSTR(":["));
+ for (i=0; i.
-*/
-
-#include
-#include
-#include "nuts_bolts.h"
-#include "settings.h"
-#include "eeprom.h"
-#include "print.h"
-#include
-#include "protocol.h"
-#include "config.h"
-#include "report.h"
-
-settings_t settings;
-
-// Version 4 outdated settings record
-typedef struct {
- float steps_per_mm[3];
- uint8_t microsteps;
- uint8_t pulse_microseconds;
- float default_feed_rate;
- float default_seek_rate;
- uint8_t invert_mask;
- float mm_per_arc_segment;
- float acceleration;
- float junction_deviation;
-} settings_v4_t;
-
-// Default settings (used when resetting eeprom-settings)
-#define MICROSTEPS 8
-#define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS)
-#define DEFAULT_Y_STEPS_PER_MM (94.488188976378*MICROSTEPS)
-#define DEFAULT_Z_STEPS_PER_MM (94.488188976378*MICROSTEPS)
-#define DEFAULT_STEP_PULSE_MICROSECONDS 30
-#define DEFAULT_MM_PER_ARC_SEGMENT 0.1
-#define DEFAULT_RAPID_FEEDRATE 500.0 // mm/min
-#define DEFAULT_FEEDRATE 500.0
-#define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2
-#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm
-#define DEFAULT_STEPPING_INVERT_MASK ((1<= 50) {
- // Developmental settings. Version numbers greater than or equal to 50 are temporary.
- // Currently, this will update the user settings to v4 and the remainder of the settings
- // should be re-written to the default value, if the developmental version number changed.
-
- // Grab settings regardless of error.
- memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v4_t));
- settings_reset(false);
- } else {
- return(false);
- }
- }
- return(true);
-}
-
-
-// A helper method to set settings from command line
-uint8_t settings_store_global_setting(int parameter, float value) {
- switch(parameter) {
- case 0: case 1: case 2:
- if (value <= 0.0) { return(STATUS_SETTING_VALUE_NEG); }
- settings.steps_per_mm[parameter] = value; break;
- case 3:
- if (value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); }
- settings.pulse_microseconds = round(value); break;
- case 4: settings.default_feed_rate = value; break;
- case 5: settings.default_seek_rate = value; break;
- case 6: settings.mm_per_arc_segment = value; break;
- case 7: settings.invert_mask = trunc(value); break;
- case 8: settings.acceleration = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
- case 9: settings.junction_deviation = fabs(value); break;
- case 10:
- if (value) {
- settings.flags |= BITFLAG_REPORT_INCHES;
- } else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
- break;
- case 11:
- if (value) {
- settings.flags |= BITFLAG_AUTO_START;
- } else { settings.flags &= ~BITFLAG_AUTO_START; }
- break;
- case 12:
- if (value) {
- settings.flags |= BITFLAG_INVERT_ST_ENABLE;
- } else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; }
- break;
- case 13:
- if (value) {
- settings.flags |= BITFLAG_HARD_LIMIT_ENABLE;
- } else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
- break;
- case 14:
- if (value) {
- settings.flags |= BITFLAG_HOMING_ENABLE;
- report_feedback_message(MESSAGE_HOMING_ENABLE);
- } else { settings.flags &= ~BITFLAG_HOMING_ENABLE; }
- break;
- case 15: settings.homing_dir_mask = trunc(value); break;
- case 16: settings.homing_feed_rate = value; break;
- case 17: settings.homing_seek_rate = value; break;
- case 18: settings.homing_debounce_delay = round(value); break;
- case 19:
- if (value <= 0.0) { return(STATUS_SETTING_VALUE_NEG); }
- settings.homing_pulloff = value; break;
- case 20:
- settings.stepper_idle_lock_time = round(value);
- // TODO: Immediately check and toggle steppers from always enable or disable?
- break;
- case 21: settings.decimal_places = round(value); break;
- case 22: settings.n_arc_correction = round(value); break;
- default:
- return(STATUS_INVALID_STATEMENT);
- }
- write_global_settings();
- return(STATUS_OK);
-}
-
-// Initialize the config subsystem
-void settings_init() {
- if(!read_global_settings()) {
- report_status_message(STATUS_SETTING_READ_FAIL);
- settings_reset(true);
- report_grbl_help();
- }
-}
-
-// int8_t settings_execute_startup() {
-//
-// char buf[4];
-// settings_startup_string((char *)buf);
-// uint8_t i = 0;
-// while (i < 4) {
-// serial_write(buf[i++]);
-// }
-// return(gc_execute_line(buf));
-// }
+/*
+ settings.c - eeprom configuration handling
+ Part of Grbl
+
+ Copyright (c) 2009-2011 Simen Svale Skogsrud
+ Copyright (c) 2011-2012 Sungeun K. Jeon
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+*/
+
+#include
+#include
+#include "nuts_bolts.h"
+#include "settings.h"
+#include "eeprom.h"
+#include "print.h"
+#include
+#include "protocol.h"
+#include "config.h"
+#include "report.h"
+
+settings_t settings;
+
+// Version 4 outdated settings record
+typedef struct {
+ float steps_per_mm[3];
+ uint8_t microsteps;
+ uint8_t pulse_microseconds;
+ float default_feed_rate;
+ float default_seek_rate;
+ uint8_t invert_mask;
+ float mm_per_arc_segment;
+ float acceleration;
+ float junction_deviation;
+} settings_v4_t;
+
+// Default settings (used when resetting eeprom-settings)
+#define MICROSTEPS 8
+#define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS)
+#define DEFAULT_Y_STEPS_PER_MM (94.488188976378*MICROSTEPS)
+#define DEFAULT_Z_STEPS_PER_MM (94.488188976378*MICROSTEPS)
+#define DEFAULT_STEP_PULSE_MICROSECONDS 30
+#define DEFAULT_MM_PER_ARC_SEGMENT 0.1
+#define DEFAULT_RAPID_FEEDRATE 500.0 // mm/min
+#define DEFAULT_FEEDRATE 500.0
+#define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2
+#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm
+#define DEFAULT_STEPPING_INVERT_MASK ((1<= 50) {
+ // Developmental settings. Version numbers greater than or equal to 50 are temporary.
+ // Currently, this will update the user settings to v4 and the remainder of the settings
+ // should be re-written to the default value, if the developmental version number changed.
+
+ // Grab settings regardless of error.
+ memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t));
+ settings_reset(false);
+ } else {
+ return(false);
+ }
+ }
+ return(true);
+}
+
+
+// A helper method to set settings from command line
+uint8_t settings_store_global_setting(int parameter, float value) {
+ switch(parameter) {
+ case 0: case 1: case 2:
+ if (value <= 0.0) { return(STATUS_SETTING_VALUE_NEG); }
+ settings.steps_per_mm[parameter] = value; break;
+ case 3:
+ if (value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); }
+ settings.pulse_microseconds = round(value); break;
+ case 4: settings.default_feed_rate = value; break;
+ case 5: settings.default_seek_rate = value; break;
+ case 6: settings.mm_per_arc_segment = value; break;
+ case 7: settings.invert_mask = trunc(value); break;
+ case 8: settings.acceleration = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
+ case 9: settings.junction_deviation = fabs(value); break;
+ case 10:
+ if (value) {
+ settings.flags |= BITFLAG_REPORT_INCHES;
+ } else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
+ break;
+ case 11:
+ if (value) {
+ settings.flags |= BITFLAG_AUTO_START;
+ } else { settings.flags &= ~BITFLAG_AUTO_START; }
+ break;
+ case 12:
+ if (value) {
+ settings.flags |= BITFLAG_INVERT_ST_ENABLE;
+ } else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; }
+ break;
+ case 13:
+ if (value) {
+ settings.flags |= BITFLAG_HARD_LIMIT_ENABLE;
+ } else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
+ break;
+ case 14:
+ if (value) {
+ settings.flags |= BITFLAG_HOMING_ENABLE;
+ report_feedback_message(MESSAGE_HOMING_ENABLE);
+ } else { settings.flags &= ~BITFLAG_HOMING_ENABLE; }
+ break;
+ case 15: settings.homing_dir_mask = trunc(value); break;
+ case 16: settings.homing_feed_rate = value; break;
+ case 17: settings.homing_seek_rate = value; break;
+ case 18: settings.homing_debounce_delay = round(value); break;
+ case 19:
+ if (value <= 0.0) { return(STATUS_SETTING_VALUE_NEG); }
+ settings.homing_pulloff = value; break;
+ case 20:
+ settings.stepper_idle_lock_time = round(value);
+ // TODO: Immediately check and toggle steppers from always enable or disable?
+ break;
+ case 21: settings.decimal_places = round(value); break;
+ case 22: settings.n_arc_correction = round(value); break;
+ default:
+ return(STATUS_INVALID_STATEMENT);
+ }
+ write_global_settings();
+ return(STATUS_OK);
+}
+
+// Initialize the config subsystem
+void settings_init() {
+ if(!read_global_settings()) {
+ report_status_message(STATUS_SETTING_READ_FAIL);
+ settings_reset(true);
+ report_grbl_help();
+ }
+}
+
+// int8_t settings_execute_startup() {
+//
+// char buf[4];
+// settings_startup_string((char *)buf);
+// uint8_t i = 0;
+// while (i < 4) {
+// serial_write(buf[i++]);
+// }
+// return(gc_execute_line(buf));
+// }
diff --git a/settings.h b/settings.h
index 3af5ba5..3abf350 100755
--- a/settings.h
+++ b/settings.h
@@ -26,7 +26,7 @@
#include
#include "nuts_bolts.h"
-#define GRBL_VERSION "0.8b"
+#define GRBL_VERSION "0.8c"
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
// when firmware is upgraded. Always stored in byte 0 of eeprom
@@ -39,18 +39,21 @@
#define BITFLAG_HARD_LIMIT_ENABLE bit(3)
#define BITFLAG_HOMING_ENABLE bit(4)
-// Define EEPROM memory address location values for on-demand settings and parameters
+// Define EEPROM memory address location values for Grbl settings and parameters
+// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and
+// the startup script. The lower half contains the global settings and space for future
+// developments.
#define EEPROM_ADDR_GLOBAL 1
#define EEPROM_ADDR_PARAMETERS 512
#define EEPROM_ADDR_STARTUP_SCRIPT 768
// Define EEPROM address indexing for coordinate parameters
#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1)
-#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+2 // Total number of system stored (from index 0)
+#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0)
// NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59)
#define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1
#define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2
-#define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset
+// #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported)
// Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards)
typedef struct {
@@ -72,6 +75,7 @@ typedef struct {
uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable.
uint8_t decimal_places;
uint8_t n_arc_correction;
+// uint8_t status_report_mask; // Mask to indicate desired report data.
} settings_t;
extern settings_t settings;
diff --git a/spindle_control.c b/spindle_control.c
index abc67e2..1d65f41 100755
--- a/spindle_control.c
+++ b/spindle_control.c
@@ -43,7 +43,7 @@ void spindle_stop()
SPINDLE_ENABLE_PORT &= ~(1<
void spindle_init();
-void spindle_run(int8_t direction, uint16_t rpm);
+void spindle_run(int8_t direction); //, uint16_t rpm);
void spindle_stop();
#endif