mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-09-02 02:42:36 +02:00
Fixed a bunch of bugs. Needs a lot more bug fixing probably.
This commit is contained in:
@@ -22,9 +22,9 @@
|
|||||||
# include "src/Grbl.h"
|
# include "src/Grbl.h"
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
# ifdef PIN_DEBUG
|
// # ifdef PIN_DEBUG
|
||||||
sleep(1000);
|
delay(2000);
|
||||||
# endif
|
// # endif
|
||||||
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
grbl_init();
|
grbl_init();
|
||||||
|
@@ -1,45 +1,8 @@
|
|||||||
name: "6 Pack Controller StepStick XYZ"
|
name: "Debug config"
|
||||||
board: bdring-6pack
|
board: Debug-board
|
||||||
|
|
||||||
i2so:
|
|
||||||
bck: gpio.22
|
|
||||||
ws: gpio.17
|
|
||||||
data: gpio.21
|
|
||||||
|
|
||||||
axes:
|
axes:
|
||||||
number_axis: 3
|
number_axis: 3
|
||||||
x:
|
|
||||||
steps_per_mm: 800
|
|
||||||
max_rate: 2000
|
|
||||||
acceleration: 25
|
|
||||||
max_travel: 1000
|
|
||||||
home_mpos: 10
|
|
||||||
|
|
||||||
gang1:
|
|
||||||
endstop:
|
|
||||||
dual: gpio.33:low # or: positive: gpio.33:low, negative: gpio.34:low
|
|
||||||
|
|
||||||
tmc_2130:
|
|
||||||
step: gpio.4
|
|
||||||
direction: gpio.16
|
|
||||||
run_current: 1.0
|
|
||||||
hold_current: 0.25
|
|
||||||
microsteps: 255
|
|
||||||
stallguard: 0
|
|
||||||
|
|
||||||
y:
|
|
||||||
gang1:
|
|
||||||
endstop: gpio.32:low
|
|
||||||
stepstick:
|
|
||||||
step: gpio.18
|
|
||||||
direction: gpio.18
|
|
||||||
gang2:
|
|
||||||
endstop: gpio.34:low
|
|
||||||
stepstick:
|
|
||||||
step: gpio.19
|
|
||||||
direction: gpio.19
|
|
||||||
|
|
||||||
coolant:
|
coolant:
|
||||||
flood: gpio.12
|
flood: gpio.2
|
||||||
mist: gpio.13
|
|
||||||
|
|
||||||
|
13
Grbl_Esp32/src/Configuration/AfterParse.cpp
Normal file
13
Grbl_Esp32/src/Configuration/AfterParse.cpp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include "AfterParse.h"
|
||||||
|
|
||||||
|
#include "Configurable.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace Configuration
|
||||||
|
{
|
||||||
|
void AfterParse::handleDetail(const char* name, Configurable* value) {
|
||||||
|
value->afterParse();
|
||||||
|
value->handle(*this);
|
||||||
|
}
|
||||||
|
}
|
32
Grbl_Esp32/src/Configuration/AfterParse.h
Normal file
32
Grbl_Esp32/src/Configuration/AfterParse.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../Pin.h"
|
||||||
|
#include "HandlerBase.h"
|
||||||
|
|
||||||
|
namespace Configuration
|
||||||
|
{
|
||||||
|
class Configurable;
|
||||||
|
|
||||||
|
class AfterParse : public HandlerBase
|
||||||
|
{
|
||||||
|
AfterParse(const AfterParse&) = delete;
|
||||||
|
AfterParse& operator=(const AfterParse&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void handleDetail(const char* name, Configurable* value) override;
|
||||||
|
bool matchesUninitialized(const char* name) override { return false; }
|
||||||
|
HandlerType handlerType() override { return HandlerType::AfterParse; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
AfterParse() = default;
|
||||||
|
|
||||||
|
void handle(const char* name, bool& value) override { }
|
||||||
|
void handle(const char* name, int& value) override { }
|
||||||
|
void handle(const char* name, float& value) override { }
|
||||||
|
void handle(const char* name, double& value) override { }
|
||||||
|
void handle(const char* name, StringRange& value) override { }
|
||||||
|
void handle(const char* name, Pin& value) override { }
|
||||||
|
};
|
||||||
|
}
|
@@ -20,8 +20,9 @@ namespace Configuration
|
|||||||
|
|
||||||
virtual void validate() const = 0;
|
virtual void validate() const = 0;
|
||||||
virtual void handle(HandlerBase& handler) = 0;
|
virtual void handle(HandlerBase& handler) = 0;
|
||||||
|
virtual void afterParse() {}
|
||||||
// virtual const char* name() const = 0;
|
// virtual const char* name() const = 0;
|
||||||
|
|
||||||
virtual ~Configurable() {}
|
virtual ~Configurable() {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,9 @@ namespace Configuration
|
|||||||
enum struct HandlerType
|
enum struct HandlerType
|
||||||
{
|
{
|
||||||
Parser,
|
Parser,
|
||||||
|
AfterParse,
|
||||||
Runtime,
|
Runtime,
|
||||||
Generator,
|
Generator,
|
||||||
Validator
|
Validator
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,7 @@ namespace Configuration
|
|||||||
handleLegacy(value, str);
|
handleLegacy(value, str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warn("Incorrect setting '" << start << "': cannot find '='.");
|
log_warn("Incorrect setting '" << start << "': cannot find '='.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ namespace Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
warn("Cannot find handler for $" << index << ". Setting was ignored.");
|
log_warn("Cannot find handler for $" << index << ". Setting was ignored.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,12 +5,13 @@ namespace Configuration {
|
|||||||
int line_;
|
int line_;
|
||||||
int column_;
|
int column_;
|
||||||
const char* description_;
|
const char* description_;
|
||||||
|
const char* current_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParseException() = default;
|
ParseException() = default;
|
||||||
ParseException(const ParseException&) = default;
|
ParseException(const ParseException&) = default;
|
||||||
|
|
||||||
ParseException(const char* start, const char* current, const char* description) : description_(description) {
|
ParseException(const char* start, const char* current, const char* description) : description_(description), current_(current) {
|
||||||
line_ = 1;
|
line_ = 1;
|
||||||
column_ = 1;
|
column_ = 1;
|
||||||
while (start != current) {
|
while (start != current) {
|
||||||
@@ -18,12 +19,14 @@ namespace Configuration {
|
|||||||
++line_;
|
++line_;
|
||||||
column_ = 1;
|
column_ = 1;
|
||||||
}
|
}
|
||||||
|
++column_;
|
||||||
++start;
|
++start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int LineNumber() const { return line_; }
|
inline int LineNumber() const { return line_; }
|
||||||
inline int ColumnNumber() const { return column_; }
|
inline int ColumnNumber() const { return column_; }
|
||||||
|
inline const char* Near() const { return current_; }
|
||||||
inline const char* What() const { return description_; }
|
inline const char* What() const { return description_; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ namespace Configuration {
|
|||||||
protected:
|
protected:
|
||||||
void handleDetail(const char* name, Configuration::Configurable* value) override {
|
void handleDetail(const char* name, Configuration::Configurable* value) override {
|
||||||
if (value != nullptr && parser_.is(name)) {
|
if (value != nullptr && parser_.is(name)) {
|
||||||
debug("Parsing configurable " << name);
|
log_debug("Parsing configurable " << name);
|
||||||
|
|
||||||
parser_.enter();
|
parser_.enter();
|
||||||
for (; !parser_.isEndSection(); parser_.moveNext()) {
|
for (; !parser_.isEndSection(); parser_.moveNext()) {
|
||||||
|
@@ -176,7 +176,7 @@ namespace Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip more whitespaces
|
// Skip more whitespaces
|
||||||
while (!Eof() && IsSpace()) {
|
while (!Eof() && IsWhiteSpace()) {
|
||||||
Inc();
|
Inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TokenKind.h"
|
#include "TokenKind.h"
|
||||||
|
#include "../Logging.h"
|
||||||
|
|
||||||
namespace Configuration {
|
namespace Configuration {
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ namespace Configuration {
|
|||||||
|
|
||||||
inline bool IsWhiteSpace() {
|
inline bool IsWhiteSpace() {
|
||||||
char c = Current();
|
char c = Current();
|
||||||
return c == ' ' || c == '\t' || c == '\f';
|
return c == ' ' || c == '\t' || c == '\f' || c == '\r';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsEndLine() { return Current() == '\n'; }
|
inline bool IsEndLine() { return Current() == '\n'; }
|
||||||
|
@@ -25,12 +25,14 @@
|
|||||||
|
|
||||||
void grbl_init() {
|
void grbl_init() {
|
||||||
try {
|
try {
|
||||||
|
Serial.println("Initializing WiFi...");
|
||||||
WiFi.persistent(false);
|
WiFi.persistent(false);
|
||||||
WiFi.disconnect(true);
|
WiFi.disconnect(true);
|
||||||
WiFi.enableSTA(false);
|
WiFi.enableSTA(false);
|
||||||
WiFi.enableAP(false);
|
WiFi.enableAP(false);
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
|
|
||||||
|
Serial.println("Initializing serial communications...");
|
||||||
// Setup serial baud rate and interrupts
|
// Setup serial baud rate and interrupts
|
||||||
serial_init();
|
serial_init();
|
||||||
grbl_msg_sendf(
|
grbl_msg_sendf(
|
||||||
@@ -41,19 +43,26 @@ void grbl_init() {
|
|||||||
#ifdef MACHINE_NAME
|
#ifdef MACHINE_NAME
|
||||||
report_machine_type(CLIENT_SERIAL);
|
report_machine_type(CLIENT_SERIAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load Grbl settings from non-volatile storage
|
// Load Grbl settings from non-volatile storage
|
||||||
|
Serial.println("Initializing settings...");
|
||||||
settings_init();
|
settings_init();
|
||||||
MachineConfig::instance()->load();
|
MachineConfig::instance()->load();
|
||||||
|
|
||||||
#ifdef USE_I2S_OUT
|
#ifdef USE_I2S_OUT
|
||||||
|
Serial.println("Initializing I2SO...");
|
||||||
// The I2S out must be initialized before it can access the expanded GPIO port. Must be initialized _after_ settings!
|
// The I2S out must be initialized before it can access the expanded GPIO port. Must be initialized _after_ settings!
|
||||||
i2s_out_init();
|
i2s_out_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Serial.println("Initializing steppers...");
|
||||||
stepper_init(); // Configure stepper pins and interrupt timers
|
stepper_init(); // Configure stepper pins and interrupt timers
|
||||||
|
|
||||||
|
Serial.println("Initializing axes...");
|
||||||
MachineConfig::instance()->_axes->read_settings();
|
MachineConfig::instance()->_axes->read_settings();
|
||||||
MachineConfig::instance()->_axes->init();
|
MachineConfig::instance()->_axes->init();
|
||||||
|
|
||||||
|
Serial.println("Initializing system...");
|
||||||
system_ini(); // Configure pinout pins and pin-change interrupt (Renamed due to conflict with esp32 files)
|
system_ini(); // Configure pinout pins and pin-change interrupt (Renamed due to conflict with esp32 files)
|
||||||
memset(sys_position, 0, sizeof(sys_position)); // Clear machine position.
|
memset(sys_position, 0, sizeof(sys_position)); // Clear machine position.
|
||||||
|
|
||||||
@@ -79,10 +88,15 @@ void grbl_init() {
|
|||||||
sys.state = State::Alarm;
|
sys.state = State::Alarm;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Serial.println("Initializing spindle...");
|
||||||
Spindles::Spindle::select();
|
Spindles::Spindle::select();
|
||||||
|
|
||||||
|
Serial.println("Initializing WiFi-config...");
|
||||||
#ifdef ENABLE_WIFI
|
#ifdef ENABLE_WIFI
|
||||||
WebUI::wifi_config.begin();
|
WebUI::wifi_config.begin();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Serial.println("Initializing Bluetooth...");
|
||||||
#ifdef ENABLE_BLUETOOTH
|
#ifdef ENABLE_BLUETOOTH
|
||||||
WebUI::bt_config.begin();
|
WebUI::bt_config.begin();
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,6 +16,8 @@ DebugStream::~DebugStream() { std::cout << ']' << std::endl; }
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
DebugStream::DebugStream(const char* name) {
|
DebugStream::DebugStream(const char* name) {
|
||||||
Serial.print("[");
|
Serial.print("[");
|
||||||
Serial.print(name);
|
Serial.print(name);
|
||||||
|
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
#include "SimpleOutputStream.h"
|
#include "SimpleOutputStream.h"
|
||||||
|
|
||||||
class DebugStream : public SimpleOutputStream
|
// How to use logging? Well, the basics are pretty simple:
|
||||||
{
|
//
|
||||||
|
// - The syntax is like standard iostream's.
|
||||||
|
// - It is simplified though, so no ios or iomanip. But should be sufficient.
|
||||||
|
// - But, you wrap it in an 'info', 'debug', 'warn', 'error' or 'fatal'.
|
||||||
|
//
|
||||||
|
// The streams here ensure the data goes where it belongs, without too much
|
||||||
|
// buffer space being wasted.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// log_info("Twelve is written as " << 12 << ", isn't it");
|
||||||
|
|
||||||
|
class DebugStream : public SimpleOutputStream {
|
||||||
public:
|
public:
|
||||||
DebugStream(const char* name);
|
DebugStream(const char* name);
|
||||||
void add(char c) override;
|
void add(char c) override;
|
||||||
@@ -12,8 +24,34 @@ public:
|
|||||||
|
|
||||||
#include "StringStream.h"
|
#include "StringStream.h"
|
||||||
|
|
||||||
#define debug(x) { DebugStream ss("DBG "); ss << x; }
|
// Note: these '{'..'}' scopes are here for a reason: the destructor should flush.
|
||||||
#define info(x) { DebugStream ss("INFO"); ss << x; }
|
#define log_debug(x) \
|
||||||
#define warn(x) { DebugStream ss("WARN"); ss << x; }
|
{ \
|
||||||
#define error(x) { DebugStream ss("ERR "); ss << x; }
|
DebugStream ss("DBG "); \
|
||||||
|
ss << x; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define log_info(x) \
|
||||||
|
{ \
|
||||||
|
DebugStream ss("INFO"); \
|
||||||
|
ss << x; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define log_warn(x) \
|
||||||
|
{ \
|
||||||
|
DebugStream ss("WARN"); \
|
||||||
|
ss << x; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define log_error(x) \
|
||||||
|
{ \
|
||||||
|
DebugStream ss("ERR "); \
|
||||||
|
ss << x; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define log_fatal(x) \
|
||||||
|
{ \
|
||||||
|
DebugStream ss("FATAL "); \
|
||||||
|
ss << x; \
|
||||||
|
Assert(false, "A fatal error occurred."); \
|
||||||
|
}
|
||||||
|
@@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
#include "Configuration/ParserHandler.h"
|
#include "Configuration/ParserHandler.h"
|
||||||
#include "Configuration/Validator.h"
|
#include "Configuration/Validator.h"
|
||||||
|
#include "Configuration/AfterParse.h"
|
||||||
#include "Configuration/ParseException.h"
|
#include "Configuration/ParseException.h"
|
||||||
|
|
||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
// TODO FIXME: Split this file up into several files, perhaps put it in some folder and namespace Machine?
|
||||||
|
|
||||||
void Endstops::validate() const {
|
void Endstops::validate() const {
|
||||||
if (!_dual.undefined()) {
|
if (!_dual.undefined()) {
|
||||||
Assert(_positive.undefined(), "If dual endstops are defined, you cannot also define positive and negative endstops");
|
Assert(_positive.undefined(), "If dual endstops are defined, you cannot also define positive and negative endstops");
|
||||||
@@ -36,6 +39,11 @@ void Gang::handle(Configuration::HandlerBase& handler) {
|
|||||||
handler.handle("endstops", _endstops);
|
handler.handle("endstops", _endstops);
|
||||||
Motors::MotorFactory::handle(handler, _motor);
|
Motors::MotorFactory::handle(handler, _motor);
|
||||||
}
|
}
|
||||||
|
void Gang::afterParse() {
|
||||||
|
if (_motor == nullptr) {
|
||||||
|
_motor = new Motors::Nullmotor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Gang::~Gang() {
|
Gang::~Gang() {
|
||||||
delete _motor;
|
delete _motor;
|
||||||
@@ -57,6 +65,14 @@ void Axis::handle(Configuration::HandlerBase& handler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Axis::afterParse() {
|
||||||
|
for (size_t i = 0; i < MAX_NUMBER_GANGED; ++i) {
|
||||||
|
if (_gangs[i] == nullptr) {
|
||||||
|
_gangs[i] = new Gang();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if a motor matches this axis:
|
// Checks if a motor matches this axis:
|
||||||
bool Axis::hasMotor(const Motors::Motor* const motor) const {
|
bool Axis::hasMotor(const Motors::Motor* const motor) const {
|
||||||
for (uint8_t gang_index = 0; gang_index < MAX_NUMBER_GANGED; gang_index++) {
|
for (uint8_t gang_index = 0; gang_index < MAX_NUMBER_GANGED; gang_index++) {
|
||||||
@@ -284,12 +300,21 @@ void Axes::handle(Configuration::HandlerBase& handler) {
|
|||||||
tmp[0] = allAxis[a];
|
tmp[0] = allAxis[a];
|
||||||
tmp[1] = '\0';
|
tmp[1] = '\0';
|
||||||
|
|
||||||
if (handler.handlerType() == Configuration::HandlerType::Runtime || handler.handlerType() == Configuration::HandlerType::Parser) {
|
if (handler.handlerType() == Configuration::HandlerType::Runtime || handler.handlerType() == Configuration::HandlerType::Parser ||
|
||||||
|
handler.handlerType() == Configuration::HandlerType::AfterParse) {
|
||||||
handler.handle(tmp, _axis[a]);
|
handler.handle(tmp, _axis[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Axes::afterParse() {
|
||||||
|
for (size_t i = 0; i < MAX_NUMBER_AXIS; ++i) {
|
||||||
|
if (_axis[i] == nullptr) {
|
||||||
|
_axis[i] = new Axis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Axes::~Axes() {
|
Axes::~Axes() {
|
||||||
for (int i = 0; i < MAX_NUMBER_AXIS; ++i) {
|
for (int i = 0; i < MAX_NUMBER_AXIS; ++i) {
|
||||||
delete _axis[i];
|
delete _axis[i];
|
||||||
@@ -337,24 +362,61 @@ void MachineConfig::handle(Configuration::HandlerBase& handler) {
|
|||||||
handler.handle("laser_mode", _laserMode);
|
handler.handle("laser_mode", _laserMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MachineConfig::afterParse() {
|
||||||
|
if (_axes == nullptr) {
|
||||||
|
log_info("Axes config missing; building default axes.");
|
||||||
|
_axes = new Axes();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_coolant == nullptr) {
|
||||||
|
log_info("Coolant control config missing; building default coolant.");
|
||||||
|
_coolant = new CoolantControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_spi == nullptr) {
|
||||||
|
log_info("SPI config missing; building default SPI bus.");
|
||||||
|
_spi = new SPIBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_probe == nullptr) {
|
||||||
|
log_info("Probe config missing; building default probe.");
|
||||||
|
_probe = new Probe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MachineConfig::load(const char* filename) {
|
bool MachineConfig::load(const char* filename) {
|
||||||
if (!SPIFFS.begin(true)) {
|
if (!SPIFFS.begin(true)) {
|
||||||
error("An error has occurred while mounting SPIFFS");
|
log_fatal("An error has occurred while mounting SPIFFS");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* file = fopen(filename, "rb");
|
FILE* file = fopen(filename, "rb");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
error("There was an error opening the config file for reading");
|
log_fatal("There was an error opening the config file for reading");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regardless of what we do next, we _always_ want a MachineConfig instance.
|
||||||
|
|
||||||
|
// instance() is by reference, so we can just get rid of an old instance and
|
||||||
|
// create a new one here:
|
||||||
|
{
|
||||||
|
auto& machineConfig = instance();
|
||||||
|
if (machineConfig != nullptr) {
|
||||||
|
delete machineConfig;
|
||||||
|
}
|
||||||
|
machineConfig = new MachineConfig();
|
||||||
|
}
|
||||||
|
MachineConfig* machine = instance();
|
||||||
|
|
||||||
// Let's just read the entire file in one chunk for now. If we get
|
// Let's just read the entire file in one chunk for now. If we get
|
||||||
// in trouble with this, we can cut it in pieces and read it per chunk.
|
// in trouble with this, we can cut it in pieces and read it per chunk.
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
auto filesize = ftell(file);
|
auto filesize = ftell(file);
|
||||||
|
log_debug("Configuration file is " << int(filesize) << " bytes.");
|
||||||
|
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
char* buffer = new char[filesize];
|
char* buffer = new char[filesize + 1];
|
||||||
|
|
||||||
long pos = 0;
|
long pos = 0;
|
||||||
while (pos < filesize) {
|
while (pos < filesize) {
|
||||||
@@ -366,11 +428,14 @@ bool MachineConfig::load(const char* filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
buffer[filesize] = 0;
|
||||||
|
|
||||||
|
log_debug("Read config file:\r\n" << buffer);
|
||||||
|
|
||||||
if (pos != filesize) {
|
if (pos != filesize) {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
error("There was an error reading the config file");
|
log_error("There was an error reading the config file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,27 +446,28 @@ bool MachineConfig::load(const char* filename) {
|
|||||||
Configuration::Parser parser(input.begin(), input.end());
|
Configuration::Parser parser(input.begin(), input.end());
|
||||||
Configuration::ParserHandler handler(parser);
|
Configuration::ParserHandler handler(parser);
|
||||||
|
|
||||||
// Instance is by reference, so we can just get rid of an old instance and
|
|
||||||
// create a new one here:
|
|
||||||
if (instance() != nullptr) {
|
|
||||||
delete instance();
|
|
||||||
}
|
|
||||||
instance() = new MachineConfig();
|
|
||||||
MachineConfig* machine = instance();
|
|
||||||
|
|
||||||
for (; !parser.isEndSection(); parser.moveNext()) {
|
for (; !parser.isEndSection(); parser.moveNext()) {
|
||||||
info("Parsing key " << parser.key().str());
|
log_info("Parsing key " << parser.key().str());
|
||||||
machine->handle(handler);
|
machine->handle(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
info("Done parsing machine config.");
|
log_info("Done parsing machine config. Running after-parse tasks");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Configuration::AfterParse afterParse;
|
||||||
|
machine->afterParse();
|
||||||
|
machine->handle(afterParse);
|
||||||
|
} catch (std::exception& ex) { log_info("Validation error: " << ex.what()); }
|
||||||
|
|
||||||
|
log_info("Validating machine config");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Configuration::Validator validator;
|
Configuration::Validator validator;
|
||||||
|
machine->validate();
|
||||||
machine->handle(validator);
|
machine->handle(validator);
|
||||||
} catch (std::exception& ex) { info("Validation error: " << ex.what()); }
|
} catch (std::exception& ex) { log_info("Validation error: " << ex.what()); }
|
||||||
|
|
||||||
info("Done validating machine config.");
|
log_info("Done validating machine config.");
|
||||||
|
|
||||||
succesful = true;
|
succesful = true;
|
||||||
|
|
||||||
@@ -410,13 +476,20 @@ 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.
|
// 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) {
|
} catch (const Configuration::ParseException& ex) {
|
||||||
error("Configuration parse error: " << ex.What() << " @ " << ex.LineNumber() << ":" << ex.ColumnNumber());
|
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) {
|
} catch (const AssertionFailed& ex) {
|
||||||
// Get rid of buffer and return
|
// Get rid of buffer and return
|
||||||
error("Configuration loading failed: " << ex.what());
|
log_error("Configuration loading failed: " << ex.what());
|
||||||
} catch (std::exception& ex) { error("Configuration validation error: " << ex.what()); } catch (...) {
|
} catch (std::exception& ex) {
|
||||||
|
// Log exception:
|
||||||
|
log_error("Configuration validation error: " << ex.what());
|
||||||
|
} catch (...) {
|
||||||
// Get rid of buffer and return
|
// Get rid of buffer and return
|
||||||
error("Unknown error occurred while processing configuration file.");
|
log_error("Unknown error occurred while processing configuration file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get rid of buffer and return
|
// Get rid of buffer and return
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
#include "CoolantControl.h"
|
#include "CoolantControl.h"
|
||||||
#include "Probe.h"
|
#include "Probe.h"
|
||||||
|
|
||||||
|
// TODO FIXME: Split this file up into several files, perhaps put it in some folder and namespace Machine?
|
||||||
|
|
||||||
namespace Motors {
|
namespace Motors {
|
||||||
class Motor;
|
class Motor;
|
||||||
}
|
}
|
||||||
@@ -35,6 +37,7 @@ public:
|
|||||||
// Configuration system helpers:
|
// Configuration system helpers:
|
||||||
void validate() const override;
|
void validate() const override;
|
||||||
void handle(Configuration::HandlerBase& handler) override;
|
void handle(Configuration::HandlerBase& handler) override;
|
||||||
|
void afterParse() override;
|
||||||
|
|
||||||
~Gang();
|
~Gang();
|
||||||
};
|
};
|
||||||
@@ -85,6 +88,7 @@ public:
|
|||||||
// Configuration system helpers:
|
// Configuration system helpers:
|
||||||
void validate() const override;
|
void validate() const override;
|
||||||
void handle(Configuration::HandlerBase& handler) override;
|
void handle(Configuration::HandlerBase& handler) override;
|
||||||
|
void afterParse() override;
|
||||||
|
|
||||||
// Checks if a motor matches this axis:
|
// Checks if a motor matches this axis:
|
||||||
bool hasMotor(const Motors::Motor* const motor) const;
|
bool hasMotor(const Motors::Motor* const motor) const;
|
||||||
@@ -119,6 +123,7 @@ public:
|
|||||||
// Configuration helpers:
|
// Configuration helpers:
|
||||||
void validate() const override;
|
void validate() const override;
|
||||||
void handle(Configuration::HandlerBase& handler) override;
|
void handle(Configuration::HandlerBase& handler) override;
|
||||||
|
void afterParse() override;
|
||||||
|
|
||||||
~Axes();
|
~Axes();
|
||||||
};
|
};
|
||||||
@@ -199,7 +204,7 @@ public:
|
|||||||
} else if (ch != ' ') {
|
} else if (ch != ' ') {
|
||||||
// For convenience / layouting.
|
// For convenience / layouting.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tmp > 255) {
|
if (tmp > 255) {
|
||||||
return false;
|
return false;
|
||||||
@@ -325,6 +330,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validate() const override;
|
void validate() const override;
|
||||||
|
void afterParse() override;
|
||||||
void handle(Configuration::HandlerBase& handler) override;
|
void handle(Configuration::HandlerBase& handler) override;
|
||||||
|
|
||||||
bool load(const char* file = "/spiffs/config.yaml");
|
bool load(const char* file = "/spiffs/config.yaml");
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
void Probe::init() {
|
void Probe::init() {
|
||||||
static bool show_init_msg = true; // used to show message only once.
|
static bool show_init_msg = true; // used to show message only once.
|
||||||
|
|
||||||
if (_probePin != Pin::UNDEFINED) {
|
if (!_probePin.undefined()) {
|
||||||
#ifdef DISABLE_PROBE_PIN_PULL_UP
|
#ifdef DISABLE_PROBE_PIN_PULL_UP
|
||||||
_probePin.setAttr(Pin::Attr::Input);
|
_probePin.setAttr(Pin::Attr::Input);
|
||||||
#else
|
#else
|
||||||
|
@@ -59,4 +59,4 @@ inline SimpleOutputStream& operator<<(SimpleOutputStream& lhs, StringRange v) {
|
|||||||
inline SimpleOutputStream& operator<<(SimpleOutputStream& lhs, const Pin& v) {
|
inline SimpleOutputStream& operator<<(SimpleOutputStream& lhs, const Pin& v) {
|
||||||
lhs.add(v);
|
lhs.add(v);
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user