mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-31 10:01:48 +02:00
Added better error reporting for incorrect configs. Added ConfigAlarm state, which you can't get out off so easily - but you are still able to upload, use files, etc.
This commit is contained in:
@@ -71,12 +71,14 @@ void grbl_init() {
|
||||
|
||||
machine_init(); // user supplied function for special initialization
|
||||
// Initialize system state.
|
||||
if (sys.state != State::ConfigAlarm) {
|
||||
#ifdef FORCE_INITIALIZATION_ALARM
|
||||
// Force Grbl into an ALARM state upon a power-cycle or hard reset.
|
||||
sys.state = State::Alarm;
|
||||
// Force Grbl into an ALARM state upon a power-cycle or hard reset.
|
||||
sys.state = State::Alarm;
|
||||
#else
|
||||
sys.state = State::Idle;
|
||||
sys.state = State::Idle;
|
||||
#endif
|
||||
}
|
||||
// Check for power-up and set system alarm if homing is enabled to force homing cycle
|
||||
// by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
|
||||
// startup scripts, but allows access to settings and internal commands. Only a homing
|
||||
@@ -84,7 +86,7 @@ void grbl_init() {
|
||||
// NOTE: The startup script will run after successful completion of the homing cycle, but
|
||||
// not after disabling the alarm locks. Prevents motion startup blocks from crashing into
|
||||
// things uncontrollably. Very bad.
|
||||
if (config->_homingInitLock && homingAxes()) {
|
||||
if (config->_homingInitLock && homingAxes() && sys.state != State::ConfigAlarm) {
|
||||
// If there is an axis with homing configured, enter Alarm state on startup
|
||||
sys.state = State::Alarm;
|
||||
}
|
||||
@@ -108,6 +110,7 @@ void grbl_init() {
|
||||
} catch (const AssertionFailed& ex) {
|
||||
// This means something is terribly broken:
|
||||
info_serial("Critical error in run_once: %s", ex.what());
|
||||
sys.state = State::ConfigAlarm;
|
||||
sleep(10000);
|
||||
throw;
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@ void IRAM_ATTR isr_limit_switches(void* /*unused */) {
|
||||
// moves in the planner and serial buffers are all cleared and newly sent blocks will be
|
||||
// locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
|
||||
// limit setting if their limits are constantly triggering after a reset and move their axes.
|
||||
if (sys.state != State::Alarm && sys.state != State::Homing) {
|
||||
if (sys.state != State::Alarm && sys.state != State::ConfigAlarm && sys.state != State::Homing) {
|
||||
if (sys_rt_exec_alarm == ExecAlarm::None) {
|
||||
#ifdef ENABLE_SOFTWARE_DEBOUNCE
|
||||
// we will start a task that will recheck the switches after a small delay
|
||||
|
@@ -570,18 +570,22 @@ bool MachineConfig::load(const char* filename) {
|
||||
// That way, we can always check if the yaml is there, and if it's not, load the yaml.new.
|
||||
|
||||
} catch (const Configuration::ParseException& ex) {
|
||||
sys.state = State::ConfigAlarm;
|
||||
auto startNear = ex.Near();
|
||||
auto endNear = (startNear + 10) > (buffer + filesize) ? (buffer + filesize) : (startNear + 10);
|
||||
|
||||
StringRange near(startNear, endNear);
|
||||
log_error("Configuration parse error: " << ex.What() << " @ " << ex.LineNumber() << ":" << ex.ColumnNumber() << " near " << near);
|
||||
} catch (const AssertionFailed& ex) {
|
||||
sys.state = State::ConfigAlarm;
|
||||
// Get rid of buffer and return
|
||||
log_error("Configuration loading failed: " << ex.what());
|
||||
} catch (std::exception& ex) {
|
||||
sys.state = State::ConfigAlarm;
|
||||
// Log exception:
|
||||
log_error("Configuration validation error: " << ex.what());
|
||||
} catch (...) {
|
||||
sys.state = State::ConfigAlarm;
|
||||
// Get rid of buffer and return
|
||||
log_error("Unknown error while processing config file");
|
||||
}
|
||||
|
@@ -321,7 +321,7 @@ public:
|
||||
class MachineConfig : public Configuration::Configurable {
|
||||
public:
|
||||
MachineConfig() = default;
|
||||
|
||||
|
||||
Axes* _axes = nullptr;
|
||||
SPIBus* _spi = nullptr;
|
||||
I2SOBus* _i2so = nullptr;
|
||||
|
@@ -20,8 +20,6 @@
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
// #define false 0
|
||||
// #define true 1
|
||||
|
||||
|
@@ -41,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
Pins::PinDetail* Pin::undefinedPin = new Pins::VoidPinDetail();
|
||||
Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail();
|
||||
Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail("unknown");
|
||||
|
||||
bool Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) {
|
||||
String str = tmp.str();
|
||||
@@ -151,7 +151,7 @@ Pin Pin::create(const StringRange& str) {
|
||||
pin_error("Setting up pin [%s] failed. Details: %s\r\n", str.str().c_str(), ex.what());
|
||||
(void)ex; // Get rid of compiler warning
|
||||
|
||||
return Pin(pinImplementation);
|
||||
return Pin(new Pins::ErrorPinDetail(str.str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,15 +19,30 @@
|
||||
#include "ErrorPinDetail.h"
|
||||
#include "../Assert.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include "../Report.h"
|
||||
#endif
|
||||
|
||||
namespace Pins {
|
||||
ErrorPinDetail::ErrorPinDetail() : PinDetail(0) {}
|
||||
ErrorPinDetail::ErrorPinDetail(const String& descr) : PinDetail(0), _description(descr) {}
|
||||
|
||||
PinCapabilities ErrorPinDetail::capabilities() const { return PinCapabilities::Error; }
|
||||
|
||||
#ifdef ESP32
|
||||
void ErrorPinDetail::write(int high) { info_all("Cannot write to pin %s. The config is incorrect.", _description.c_str()); }
|
||||
int ErrorPinDetail::read() { info_all("Cannot read from pin %s. The config is incorrect.", _description.c_str()); }
|
||||
void ErrorPinDetail::setAttr(PinAttributes value) {
|
||||
info_all("Cannot set mode on pin %s. The config is incorrect.", _description.c_str());
|
||||
}
|
||||
|
||||
#else
|
||||
void ErrorPinDetail::write(int high) { Assert(false, "Cannot write to an error pin."); }
|
||||
int ErrorPinDetail::read() { Assert(false, "Cannot read from an error pin."); }
|
||||
void ErrorPinDetail::setAttr(PinAttributes value) { /* Fine, this won't get you anywhere. */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PinAttributes ErrorPinDetail::getAttr() const { return PinAttributes::None; }
|
||||
|
||||
String ErrorPinDetail::toString() { return "ERROR_PIN"; }
|
||||
|
@@ -23,8 +23,10 @@
|
||||
|
||||
namespace Pins {
|
||||
class ErrorPinDetail : public PinDetail {
|
||||
String _description;
|
||||
|
||||
public:
|
||||
ErrorPinDetail();
|
||||
ErrorPinDetail(const String& descr);
|
||||
|
||||
PinCapabilities capabilities() const override;
|
||||
|
||||
|
@@ -87,7 +87,7 @@ Error execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_l
|
||||
return system_execute_line(line, client, auth_level);
|
||||
}
|
||||
// Everything else is gcode. Block if in alarm or jog mode.
|
||||
if (sys.state == State::Alarm || sys.state == State::Jog) {
|
||||
if (sys.state == State::Alarm || sys.state == State::ConfigAlarm || sys.state == State::Jog) {
|
||||
return Error::SystemGcLock;
|
||||
}
|
||||
return gc_execute_line(line, client);
|
||||
@@ -137,7 +137,9 @@ void protocol_main_loop() {
|
||||
// Check for and report alarm state after a reset, error, or an initial power up.
|
||||
// NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed.
|
||||
// Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges.
|
||||
if (sys.state == State::Alarm || sys.state == State::Sleep) {
|
||||
if (sys.state == State::ConfigAlarm) {
|
||||
report_feedback_message(Message::AlarmLock);
|
||||
} else if (sys.state == State::Alarm || sys.state == State::Sleep) {
|
||||
report_feedback_message(Message::AlarmLock);
|
||||
sys.state = State::Alarm; // Ensure alarm state is set.
|
||||
} else {
|
||||
@@ -325,6 +327,7 @@ static void protocol_do_motion_cancel() {
|
||||
// will handle and clear multiple planner block motions.
|
||||
switch (sys.state) {
|
||||
case State::Alarm:
|
||||
case State::ConfigAlarm:
|
||||
case State::CheckMode:
|
||||
return; // Do not set motionCancel
|
||||
|
||||
@@ -356,6 +359,7 @@ static void protocol_do_feedhold() {
|
||||
rtFeedHold = false;
|
||||
rtCycleStart = false; // Cancel any pending start
|
||||
switch (sys.state) {
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
case State::CheckMode:
|
||||
case State::SafetyDoor:
|
||||
@@ -390,6 +394,8 @@ static void protocol_do_safety_door() {
|
||||
rtCycleStart = false; // Cancel any pending start
|
||||
report_feedback_message(Message::SafetyDoorAjar);
|
||||
switch (sys.state) {
|
||||
case State::ConfigAlarm:
|
||||
return;
|
||||
case State::Alarm:
|
||||
case State::CheckMode:
|
||||
case State::Sleep:
|
||||
@@ -443,6 +449,7 @@ static void protocol_do_safety_door() {
|
||||
static void protocol_do_sleep() {
|
||||
rtSleep = false;
|
||||
switch (sys.state) {
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
sys.suspend.bit.retractComplete = true;
|
||||
sys.suspend.bit.holdComplete = true;
|
||||
@@ -518,6 +525,7 @@ static void protocol_do_cycle_start() {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
case State::CheckMode:
|
||||
case State::Sleep:
|
||||
@@ -552,6 +560,7 @@ static void protocol_do_cycle_stop() {
|
||||
break;
|
||||
}
|
||||
// Fall through
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
case State::CheckMode:
|
||||
case State::Idle:
|
||||
@@ -686,6 +695,7 @@ void protocol_exec_rt_system() {
|
||||
#endif
|
||||
// Reload step segment buffer
|
||||
switch (sys.state) {
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
case State::CheckMode:
|
||||
case State::Idle:
|
||||
|
@@ -858,6 +858,7 @@ char* report_state_text() {
|
||||
case State::Homing:
|
||||
strcpy(state, "Home");
|
||||
break;
|
||||
case State::ConfigAlarm:
|
||||
case State::Alarm:
|
||||
strcpy(state, "Alarm");
|
||||
break;
|
||||
|
@@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Error.h"
|
||||
#include "NutsBolts.h"
|
||||
#include "Exec.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
/*
|
||||
Report.h - Header for system level commands and real-time processes
|
||||
|
@@ -40,6 +40,7 @@ enum class State : uint8_t {
|
||||
Jog, // Jogging mode.
|
||||
SafetyDoor, // Safety door is ajar. Feed holds and de-energizes system.
|
||||
Sleep, // Sleep state.
|
||||
ConfigAlarm, // You can't do anything but fix your config file.
|
||||
};
|
||||
|
||||
// Step segment generator state flags.
|
||||
|
@@ -678,7 +678,7 @@ namespace WebUI {
|
||||
|
||||
static Error runSDFile(char* parameter, AuthenticationLevel auth_level) { // ESP220
|
||||
Error err;
|
||||
if (sys.state == State::Alarm) {
|
||||
if (sys.state == State::Alarm || sys.state == State::ConfigAlarm) {
|
||||
webPrintln("Alarm");
|
||||
return Error::IdleError;
|
||||
}
|
||||
|
Reference in New Issue
Block a user