From 5eee10845bd1ea825f71228ab7131d068bba5fa6 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 9 Nov 2015 21:54:26 -0700 Subject: [PATCH] Pin state reporting of all pins. Flash optimization. - New pin state realtime reporting feature. Instead of `Lim:000` for limit state reports, the new feature shows `Pin:000|0|0000`, or something similar. The `|` delimited fields indicate xyz limits, probe, and control pin states, where 0 is always not triggered, and 1 is triggered. Invert masks ARE accounted for. Each field may be enabled or disabled via the `$10` status report setting. The probe and control pin flags are bits 5 and 6, respectively. - Remove the now deprecated `REPORT_CONTROL_PIN_STATE` option in config.h - The old limit pin reports `Lim:000` may be re-enabled by commenting out `REPORT_ALL_PIN_STATES` in config.h. - Incremented the version letter (v1.0c) to indicate the change in reporting style. - Replaced all bit_true_atomic and bit_false_atomic macros with function calls. This saved a couple hundred bytes of flash. --- README.md | 4 +- doc/log/commit_log_v1.0b.txt | 36 ++++++++++++++++++ grbl/config.h | 11 +++--- grbl/gcode.c | 2 +- grbl/grbl.h | 4 +- grbl/limits.c | 12 +++--- grbl/motion_control.c | 14 +++---- grbl/nuts_bolts.h | 3 -- grbl/probe.c | 2 +- grbl/protocol.c | 18 ++++----- grbl/report.c | 30 +++++++++++---- grbl/serial.c | 8 ++-- grbl/settings.h | 2 + grbl/stepper.c | 2 +- grbl/system.c | 72 +++++++++++++++++++++++++++++------- grbl/system.h | 25 ++++++++++++- 16 files changed, 182 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 1cc8055..a470ef3 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,11 @@ Grbl includes full acceleration management with look ahead. That means the contr *** -##Update Summary for v1.0b +##Update Summary for v1.0c - **IMPORTANT:** Your EEPROM will be wiped and restored with new settings. This is due to the addition of two new spindle speed '$' settings. +- Altered limit pin status reports from `Lim:000` to `Pin:000|0|0000`, where the `|` delimiters separate the new probe state and control pin states. Each new field may be disabled by the `$10` Grbl setting. NOTE: Commenting `REPORT_ALL_PIN_STATES` in config.h reverts to old `Lim:` reports, if needed. + - New safety door parking motion as a compile-option. Grbl will retract, disable the spindle/coolant, and park near Z max. When resumed, it will perform these task in reverse order and continue the program. Highly configurable. See config.h for details. - New '$' Grbl settings for max and min spindle rpm. Allows for tweaking the PWM output to more closely match true spindle rpm. When max rpm is set to zero or less than min rpm, the PWM pin D11 will act like a simple enable on/off output. diff --git a/doc/log/commit_log_v1.0b.txt b/doc/log/commit_log_v1.0b.txt index 0cff318..8623d45 100644 --- a/doc/log/commit_log_v1.0b.txt +++ b/doc/log/commit_log_v1.0b.txt @@ -1,3 +1,39 @@ +---------------- +Date: 2015-09-30 +Author: Sonny Jeon +Subject: Bug fixes. + +- G38.x was not printing correctly in the $G g-code state reports. Now +fixed. + +- When investigating the above issue, it was noticed that G38.x +wouldn’t show at all, but instead a G0 would be printed. This was +unlike the v0.9j master build. It turned out volatile variables do not +like to be defined inside a C struct. These are undefined on how to be +handled. Once pulled out, all weird issues went away. + +- Also changed two ‘sizeof()’ statements in the mc_probe() and +probe_state_monitor() functions to be more robust later on. + +- Updated the commit logs to individual files for each minor release. +Forgot to update the generating script to account for this. + + +---------------- +Date: 2015-09-30 +Author: Sonny Jeon +Subject: Minor bug fixes. + +- G38.x was not printing correctly in the $G g-code state reports. Now +fixed. + +- Potential bug regarding volatile variables inside a struct. It has +never been a problem in v0.9, but ran into this during v1.0 +development. Just to be safe, the fixes are applied here. + +- Updated pre-built firmwares with these two bug fixes. + + ---------------- Date: 2015-09-24 Author: Sonny Jeon diff --git a/grbl/config.h b/grbl/config.h index 5ca1f24..d91c16a 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -164,11 +164,12 @@ // uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below. // #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable. -// Enable control pin states feedback in status reports. The data is presented as simple binary of -// the control pin port (0 (low) or 1(high)), masked to show only the input pins. Non-control pins on the -// port will always show a 0 value. See cpu_map.h for the pin bitmap. As with the limit pin reporting, -// we do not recommend keeping this option enabled. Try to only use this for setting up a new CNC. -// #define REPORT_CONTROL_PIN_STATE // Default disabled. Uncomment to enable. +// Enable all pin states feedback in status reports. Configurable with Grbl settings to print only +// the desired data, which is presented as simple binary reading of each pin as (0 (low) or 1(high)). +// The fields are printed in a particular order and settings groups are separated by '|' characters. +// NOTE: This option is here for backward compatibility of the old style of pin state reports, i.e. +// `Lim:000`. This new `Pin:` report will be the standard going forward. +#define REPORT_ALL_PIN_STATES // Default enabled. Comment to disable. // When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM // by default. This is to make it as simple as possible for new users to start using Grbl. When homing diff --git a/grbl/gcode.c b/grbl/gcode.c index a93e71c..7b3f23b 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1044,7 +1044,7 @@ uint8_t gc_execute_line(char *line) protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { if (sys.state != STATE_CHECK_MODE) { - bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. + system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause. protocol_execute_realtime(); // Execute suspend. } } else { // == PROGRAM_FLOW_COMPLETED diff --git a/grbl/grbl.h b/grbl/grbl.h index 843f02f..0c073aa 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -22,8 +22,8 @@ #define grbl_h // Grbl versioning system -#define GRBL_VERSION "1.0b" -#define GRBL_VERSION_BUILD "20150930" +#define GRBL_VERSION "1.0c" +#define GRBL_VERSION_BUILD "20151109" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 747d75b..8386178 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -106,11 +106,11 @@ uint8_t limits_get_state() // Check limit pin state. if (limits_get_state()) { mc_reset(); // Initiate system kill. - bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event } #else mc_reset(); // Initiate system kill. - bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event #endif } } @@ -126,7 +126,7 @@ uint8_t limits_get_state() // Check limit pin state. if (limits_get_state()) { mc_reset(); // Initiate system kill. - bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event } } } @@ -235,7 +235,7 @@ void limits_go_home(uint8_t cycle_mask) return; } else { // Pull-off motion complete. Disable CYCLE_STOP from executing. - bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); + system_clear_exec_state_flag(EXEC_CYCLE_STOP); break; } } @@ -335,7 +335,7 @@ void limits_soft_check(float *target) // workspace volume so just come to a controlled stop so position is not lost. When complete // enter alarm mode. if (sys.state == STATE_CYCLE) { - bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); + system_set_exec_state_flag(EXEC_FEED_HOLD); do { protocol_execute_realtime(); if (sys.abort) { return; } @@ -343,7 +343,7 @@ void limits_soft_check(float *target) } mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. - bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event + system_set_exec_alarm_flag((EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event protocol_execute_realtime(); // Execute to enter critical event loop and system abort return; } diff --git a/grbl/motion_control.c b/grbl/motion_control.c index 7804ac5..b0c6f6e 100644 --- a/grbl/motion_control.c +++ b/grbl/motion_control.c @@ -220,7 +220,7 @@ void mc_homing_cycle() #ifdef LIMITS_TWO_SWITCHES_ON_AXES if (limits_get_state()) { mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. - bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); + system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); return; } #endif @@ -276,7 +276,7 @@ void mc_homing_cycle() // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. - bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); + system_set_exec_alarm_flag(EXEC_ALARM_PROBE_FAIL); protocol_execute_realtime(); } if (sys.abort) { return; } // Return if system reset has been issued. @@ -292,7 +292,7 @@ void mc_homing_cycle() sys_probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. - bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); + system_set_exec_state_flag(EXEC_CYCLE_START); do { protocol_execute_realtime(); if (sys.abort) { return; } // Check for system abort @@ -303,7 +303,7 @@ void mc_homing_cycle() // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys_probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(sys.position)); } - else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } + else { system_set_exec_alarm_flag(EXEC_ALARM_PROBE_FAIL); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } @@ -366,7 +366,7 @@ void mc_reset() { // Only this function can set the system reset. Helps prevent multiple kill calls. if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) { - bit_true_atomic(sys_rt_exec_state, EXEC_RESET); + system_set_exec_state_flag(EXEC_RESET); // Kill spindle and coolant. spindle_stop(); @@ -378,8 +378,8 @@ void mc_reset() // violated, by which, all bets are off. if ((sys.state & (STATE_CYCLE | STATE_HOMING)) || (sys.step_control & (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_PARK))) { - if (sys.state == STATE_HOMING) { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_HOMING_FAIL); } - else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); } + if (sys.state == STATE_HOMING) { system_set_exec_alarm_flag(EXEC_ALARM_HOMING_FAIL); } + else { system_set_exec_alarm_flag(EXEC_ALARM_ABORT_CYCLE); } st_go_idle(); // Force kill steppers. Position has likely been lost. } } diff --git a/grbl/nuts_bolts.h b/grbl/nuts_bolts.h index 1f2cd07..7611aac 100644 --- a/grbl/nuts_bolts.h +++ b/grbl/nuts_bolts.h @@ -56,9 +56,6 @@ // Bit field and masking macros #define bit(n) (1 << n) -#define bit_true_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) |= (mask); SREG = sreg; } -#define bit_false_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) &= ~(mask); SREG = sreg; } -#define bit_toggle_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) ^= (mask); SREG = sreg; } #define bit_true(x,mask) (x) |= (mask) #define bit_false(x,mask) (x) &= ~(mask) #define bit_istrue(x,mask) ((x & mask) != 0) diff --git a/grbl/probe.c b/grbl/probe.c index 37816bf..5a33777 100644 --- a/grbl/probe.c +++ b/grbl/probe.c @@ -34,7 +34,7 @@ void probe_init() #else PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. #endif - // probe_configure_invert_mask(false); // Initialize invert mask. Not required. Updated when in-use. + probe_configure_invert_mask(false); // Initialize invert mask. Re-updated during use. } diff --git a/grbl/protocol.c b/grbl/protocol.c index e91e8d4..e1927b6 100644 --- a/grbl/protocol.c +++ b/grbl/protocol.c @@ -190,7 +190,7 @@ void protocol_buffer_synchronize() // when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming // is finished, single commands), a command that needs to wait for the motions in the buffer to // execute calls a buffer sync, or the planner buffer is full and ready to go. -void protocol_auto_cycle_start() { bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); } +void protocol_auto_cycle_start() { system_set_exec_state_flag(EXEC_CYCLE_START); } // This function is the general interface to Grbl's real-time command execution system. It is called @@ -237,7 +237,7 @@ void protocol_exec_rt_system() // Halt everything upon a critical event flag. Currently hard and soft limits flag this. if (rt_exec & EXEC_CRITICAL_EVENT) { report_feedback_message(MESSAGE_CRITICAL_EVENT); - bit_false_atomic(sys_rt_exec_state,EXEC_RESET); // Disable any existing reset + system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset do { // Block everything, except reset and status reports, until user issues reset or power // cycles. Hard limits typically occur while unattended or not paying attention. Gives @@ -248,12 +248,12 @@ void protocol_exec_rt_system() // TODO: Allow status reports during a critical alarm. Still need to think about implications of this. // if (sys_rt_exec_state & EXEC_STATUS_REPORT) { // report_realtime_status(); - // bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT); + // system_clear_exec_state_flag(EXEC_STATUS_REPORT); // } } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET)); } - bit_false_atomic(sys_rt_exec_alarm,0xFF); // Clear all alarm flags + system_clear_exec_alarm_flag(0xFF); // Clear all alarm flags } rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state. @@ -268,7 +268,7 @@ void protocol_exec_rt_system() // Execute and serial print status if (rt_exec & EXEC_STATUS_REPORT) { report_realtime_status(); - bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT); + system_clear_exec_state_flag(EXEC_STATUS_REPORT); } // NOTE: The math involved to calculate the hold should be low enough for most, if not all, @@ -340,7 +340,7 @@ void protocol_exec_rt_system() } - bit_false_atomic(sys_rt_exec_state,(EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR)); + system_clear_exec_state_flag((EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR)); } // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue. @@ -380,7 +380,7 @@ void protocol_exec_rt_system() } } } - bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_START); + system_clear_exec_state_flag(EXEC_CYCLE_START); } if (rt_exec & EXEC_CYCLE_STOP) { @@ -399,7 +399,7 @@ void protocol_exec_rt_system() sys.suspend = SUSPEND_DISABLE; sys.state = STATE_IDLE; } - bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); + system_clear_exec_state_flag(EXEC_CYCLE_STOP); } } @@ -544,7 +544,7 @@ static void protocol_exec_rt_suspend() if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { sys.suspend |= SUSPEND_RESTORE_COMPLETE; - bit_true_atomic(sys_rt_exec_state,EXEC_CYCLE_START); // Set to resume program. + system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. } } diff --git a/grbl/report.c b/grbl/report.c index d90de9c..eaa79b9 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -502,14 +502,28 @@ void report_realtime_status() printFloat_RateValue(st_get_realtime_rate()); #endif - if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) { - printPgmString(PSTR(",Lim:")); - print_unsigned_int8(limits_get_state(),2,N_AXIS); - } - - #ifdef REPORT_CONTROL_PIN_STATE - printPgmString(PSTR(",Ctl:")); - print_uint8_base2(CONTROL_PIN & CONTROL_MASK); + #ifdef REPORT_ALL_PIN_STATES + if (bit_istrue(settings.status_report_mask, + ( BITFLAG_RT_STATUS_LIMIT_PINS| BITFLAG_RT_STATUS_PROBE_PIN | BITFLAG_RT_STATUS_CONTROL_PINS ))) { + printPgmString(PSTR(",Pin:")); + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) { + print_unsigned_int8(limits_get_state(),2,N_AXIS); + } + printPgmString(PSTR("|")); + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_PROBE_PIN)) { + if (probe_get_state()) { printPgmString(PSTR("1")); } + else { printPgmString(PSTR("0")); } + } + printPgmString(PSTR("|")); + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_CONTROL_PINS)) { + print_unsigned_int8(system_control_get_state(),2,N_CONTROL_PIN); + } + } + #else + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) { + printPgmString(PSTR(",Lim:")); + print_unsigned_int8(limits_get_state(),2,N_AXIS); + } #endif printPgmString(PSTR(">\r\n")); diff --git a/grbl/serial.c b/grbl/serial.c index 56f84e0..d7d54dd 100644 --- a/grbl/serial.c +++ b/grbl/serial.c @@ -164,10 +164,10 @@ ISR(SERIAL_RX) // Pick off realtime command characters directly from the serial stream. These characters are // not passed into the buffer, but these set system state flag bits for realtime execution. switch (data) { - case CMD_STATUS_REPORT: bit_true_atomic(sys_rt_exec_state, EXEC_STATUS_REPORT); break; // Set as true - case CMD_CYCLE_START: bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); break; // Set as true - case CMD_FEED_HOLD: bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); break; // Set as true - case CMD_SAFETY_DOOR: bit_true_atomic(sys_rt_exec_state, EXEC_SAFETY_DOOR); break; // Set as true + case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true + case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true + case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true + case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true case CMD_RESET: mc_reset(); break; // Call motion control reset routine. default: // Write character to buffer next_head = serial_rx_buffer_head + 1; diff --git a/grbl/settings.h b/grbl/settings.h index aebf480..3a9d25d 100644 --- a/grbl/settings.h +++ b/grbl/settings.h @@ -45,6 +45,8 @@ #define BITFLAG_RT_STATUS_PLANNER_BUFFER bit(2) #define BITFLAG_RT_STATUS_SERIAL_RX bit(3) #define BITFLAG_RT_STATUS_LIMIT_PINS bit(4) +#define BITFLAG_RT_STATUS_PROBE_PIN bit(5) +#define BITFLAG_RT_STATUS_CONTROL_PINS bit(6) // Define settings restore bitflags. #define SETTINGS_RESTORE_ALL 0xFF // All bitflags diff --git a/grbl/stepper.c b/grbl/stepper.c index 578ac08..d3517d9 100644 --- a/grbl/stepper.c +++ b/grbl/stepper.c @@ -349,7 +349,7 @@ ISR(TIMER1_COMPA_vect) } else { // Segment buffer empty. Shutdown. st_go_idle(); - bit_true_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); // Flag main program for cycle end + system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end return; // Nothing to do but exit. } } diff --git a/grbl/system.c b/grbl/system.c index c4ac418..23e8a22 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -34,27 +34,45 @@ void system_init() } +// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where +// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is +// defined by the CONTROL_PIN_INDEX in the header file. +uint8_t system_control_get_state() +{ + uint8_t control_state = 0; + uint8_t pin = (CONTROL_PIN & CONTROL_MASK); + #ifndef INVERT_ALL_CONTROL_PINS + pin ^= CONTROL_INVERT_MASK; + #endif + if (pin) { + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + if (bit_istrue(pin,(1<