From ffb44b33ecfe2afd7b38e8782a50f213334807dc Mon Sep 17 00:00:00 2001 From: Vlad A Date: Sun, 12 Mar 2023 20:01:43 -0400 Subject: [PATCH 01/51] Configuration::Configurable::validate changed to non-const. Signed-off-by: Vlad A --- FluidNC/src/Configuration/Configurable.h | 2 +- FluidNC/src/Configuration/ConfigurationHandlers.md | 2 +- FluidNC/src/Configuration/_Overview.md | 2 +- FluidNC/src/Kinematics/Cartesian.h | 2 +- FluidNC/src/Kinematics/CoreXY.h | 2 +- FluidNC/src/Kinematics/Kinematics.h | 2 +- FluidNC/src/Kinematics/WallPlotter.h | 2 +- FluidNC/src/Machine/Homing.h | 2 +- FluidNC/src/Machine/I2CBus.cpp | 2 +- FluidNC/src/Machine/I2CBus.h | 2 +- FluidNC/src/Machine/I2SOBus.cpp | 2 +- FluidNC/src/Machine/I2SOBus.h | 2 +- FluidNC/src/Machine/SPIBus.cpp | 2 +- FluidNC/src/Machine/SPIBus.h | 2 +- FluidNC/src/Machine/WifiAPConfig.h | 2 +- FluidNC/src/Machine/WifiSTAConfig.h | 2 +- FluidNC/src/Motors/Dynamixel2.h | 2 +- FluidNC/src/Motors/StandardStepper.cpp | 2 +- FluidNC/src/Motors/StandardStepper.h | 2 +- FluidNC/src/Motors/StepStick.cpp | 2 +- FluidNC/src/Motors/StepStick.h | 2 +- FluidNC/src/Motors/TMC2130Driver.h | 2 +- FluidNC/src/Motors/TMC2208Driver.h | 2 +- FluidNC/src/Motors/TMC2209Driver.h | 2 +- FluidNC/src/Motors/TMC5160Driver.h | 2 +- FluidNC/src/Motors/TMC5160ProDriver.h | 2 +- FluidNC/src/Motors/TrinamicSpiDriver.h | 2 +- FluidNC/src/Motors/TrinamicUartDriver.h | 2 +- FluidNC/src/Motors/UnipolarMotor.h | 2 +- FluidNC/src/OLED.h | 2 +- FluidNC/src/Probe.cpp | 2 +- FluidNC/src/Probe.h | 2 +- FluidNC/src/Spindles/10vSpindle.h | 2 +- FluidNC/src/Spindles/BESCSpindle.h | 2 +- FluidNC/src/Spindles/HBridgeSpindle.h | 2 +- FluidNC/src/Spindles/OnOffSpindle.h | 2 +- FluidNC/src/Spindles/PWMSpindle.h | 2 +- FluidNC/src/Spindles/Spindle.h | 2 +- FluidNC/src/Spindles/VFDSpindle.h | 2 +- FluidNC/src/Uart.h | 2 +- 40 files changed, 40 insertions(+), 40 deletions(-) diff --git a/FluidNC/src/Configuration/Configurable.h b/FluidNC/src/Configuration/Configurable.h index 8ed1fff47..12f2e0b44 100644 --- a/FluidNC/src/Configuration/Configurable.h +++ b/FluidNC/src/Configuration/Configurable.h @@ -19,7 +19,7 @@ namespace Configuration { public: Configurable() = default; - virtual void validate() const {}; + virtual void validate() {}; virtual void group(HandlerBase& handler) = 0; virtual void afterParse() {} // virtual const char* name() const = 0; diff --git a/FluidNC/src/Configuration/ConfigurationHandlers.md b/FluidNC/src/Configuration/ConfigurationHandlers.md index 3545f859f..59d701593 100644 --- a/FluidNC/src/Configuration/ConfigurationHandlers.md +++ b/FluidNC/src/Configuration/ConfigurationHandlers.md @@ -40,7 +40,7 @@ public: Pin _data; Pin _ws; - void validate() const override { + void validate() override { if (!_bck.undefined() || !_data.undefined() || !_ws.undefined()) { Assert(!_bck.undefined(), "I2SO BCK pin should be configured once."); Assert(!_data.undefined(), "I2SO Data pin should be configured once."); diff --git a/FluidNC/src/Configuration/_Overview.md b/FluidNC/src/Configuration/_Overview.md index df2606fad..624a642a4 100644 --- a/FluidNC/src/Configuration/_Overview.md +++ b/FluidNC/src/Configuration/_Overview.md @@ -45,7 +45,7 @@ public: Pin _bck; // ... - void validate() const override { + void validate() override { if (!_bck.undefined() || !_data.undefined() || !_ws.undefined()) { Assert(!_bck.undefined(), "I2SO BCK pin should be configured once."); // ... diff --git a/FluidNC/src/Kinematics/Cartesian.h b/FluidNC/src/Kinematics/Cartesian.h index d2814cce3..50476241a 100644 --- a/FluidNC/src/Kinematics/Cartesian.h +++ b/FluidNC/src/Kinematics/Cartesian.h @@ -36,7 +36,7 @@ namespace Kinematics { // Configuration handlers: void afterParse() override {} void group(Configuration::HandlerBase& handler) override {} - void validate() const override {} + void validate() override {} // Name of the configurable. Must match the name registered in the cpp file. const char* name() const override { return "Cartesian"; } diff --git a/FluidNC/src/Kinematics/CoreXY.h b/FluidNC/src/Kinematics/CoreXY.h index de2891614..9c5d6c63f 100644 --- a/FluidNC/src/Kinematics/CoreXY.h +++ b/FluidNC/src/Kinematics/CoreXY.h @@ -36,7 +36,7 @@ namespace Kinematics { bool limitReached(AxisMask& axisMask, MotorMask& motors, MotorMask limited); // Configuration handlers: - void validate() const override {} + void validate() override {} virtual void group(Configuration::HandlerBase& handler) override; void afterParse() override {} diff --git a/FluidNC/src/Kinematics/Kinematics.h b/FluidNC/src/Kinematics/Kinematics.h index cd88e05ea..e8ea30352 100644 --- a/FluidNC/src/Kinematics/Kinematics.h +++ b/FluidNC/src/Kinematics/Kinematics.h @@ -80,7 +80,7 @@ namespace Kinematics { // Configuration interface. void afterParse() override {} void group(Configuration::HandlerBase& handler) override {} - void validate() const override {} + void validate() override {} // Name of the configurable. Must match the name registered in the cpp file. virtual const char* name() const = 0; diff --git a/FluidNC/src/Kinematics/WallPlotter.h b/FluidNC/src/Kinematics/WallPlotter.h index e713d6661..ed558dfe0 100644 --- a/FluidNC/src/Kinematics/WallPlotter.h +++ b/FluidNC/src/Kinematics/WallPlotter.h @@ -31,7 +31,7 @@ namespace Kinematics { void transform_cartesian_to_motors(float* cartesian, float* motors) override; // Configuration handlers: - void validate() const override {} + void validate() override {} void group(Configuration::HandlerBase& handler) override; void afterParse() override {} diff --git a/FluidNC/src/Machine/Homing.h b/FluidNC/src/Machine/Homing.h index b218e4799..d1a780c22 100644 --- a/FluidNC/src/Machine/Homing.h +++ b/FluidNC/src/Machine/Homing.h @@ -55,7 +55,7 @@ namespace Machine { float _feed_scaler = 1.1f; // multiplier to pulloff for moving to switch after pulloff // Configuration system helpers: - void validate() const override { Assert(_cycle >= set_mpos_only, "Homing cycle must be defined"); } + void validate() override { Assert(_cycle >= set_mpos_only, "Homing cycle must be defined"); } void group(Configuration::HandlerBase& handler) override { handler.item("cycle", _cycle, set_mpos_only, MAX_N_AXIS); diff --git a/FluidNC/src/Machine/I2CBus.cpp b/FluidNC/src/Machine/I2CBus.cpp index 46265d26b..285c4bbbf 100644 --- a/FluidNC/src/Machine/I2CBus.cpp +++ b/FluidNC/src/Machine/I2CBus.cpp @@ -7,7 +7,7 @@ namespace Machine { I2CBus::I2CBus(int busNumber) : _busNumber(busNumber) {} - void I2CBus::validate() const { + void I2CBus::validate() { if (_sda.defined() || _scl.defined()) { Assert(_sda.defined(), "I2C SDA pin configured multiple times"); Assert(_scl.defined(), "I2C SCL pin configured multiple times"); diff --git a/FluidNC/src/Machine/I2CBus.h b/FluidNC/src/Machine/I2CBus.h index 32fbc05da..27aa7c2aa 100644 --- a/FluidNC/src/Machine/I2CBus.h +++ b/FluidNC/src/Machine/I2CBus.h @@ -23,7 +23,7 @@ namespace Machine { uint32_t _frequency = 100000; void init(); - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override; int write(uint8_t address, const uint8_t* data, size_t count); diff --git a/FluidNC/src/Machine/I2SOBus.cpp b/FluidNC/src/Machine/I2SOBus.cpp index a64172499..10394679d 100644 --- a/FluidNC/src/Machine/I2SOBus.cpp +++ b/FluidNC/src/Machine/I2SOBus.cpp @@ -6,7 +6,7 @@ #include "../I2SOut.h" namespace Machine { - void I2SOBus::validate() const { + void I2SOBus::validate() { if (_bck.defined() || _data.defined() || _ws.defined()) { Assert(_bck.defined(), "I2SO BCK pin should be configured once"); Assert(_data.defined(), "I2SO Data pin should be configured once"); diff --git a/FluidNC/src/Machine/I2SOBus.h b/FluidNC/src/Machine/I2SOBus.h index 153085196..da3c31367 100644 --- a/FluidNC/src/Machine/I2SOBus.h +++ b/FluidNC/src/Machine/I2SOBus.h @@ -15,7 +15,7 @@ namespace Machine { Pin _data; Pin _ws; - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override; void init(); diff --git a/FluidNC/src/Machine/SPIBus.cpp b/FluidNC/src/Machine/SPIBus.cpp index a6d961e62..cdbd4a85d 100644 --- a/FluidNC/src/Machine/SPIBus.cpp +++ b/FluidNC/src/Machine/SPIBus.cpp @@ -8,7 +8,7 @@ #include "src/SettingsDefinitions.h" namespace Machine { - void SPIBus::validate() const { + void SPIBus::validate() { if (_miso.defined() || _mosi.defined() || _sck.defined()) { Assert(_miso.defined(), "SPI MISO pin should be configured once"); Assert(_mosi.defined(), "SPI MOSI pin should be configured once"); diff --git a/FluidNC/src/Machine/SPIBus.h b/FluidNC/src/Machine/SPIBus.h index 84f8a7891..f8a8ae3c9 100644 --- a/FluidNC/src/Machine/SPIBus.h +++ b/FluidNC/src/Machine/SPIBus.h @@ -15,7 +15,7 @@ namespace Machine { Pin _mosi; Pin _sck; - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override; void afterParse() override; diff --git a/FluidNC/src/Machine/WifiAPConfig.h b/FluidNC/src/Machine/WifiAPConfig.h index 108e22e0f..6b54152fc 100644 --- a/FluidNC/src/Machine/WifiAPConfig.h +++ b/FluidNC/src/Machine/WifiAPConfig.h @@ -14,7 +14,7 @@ namespace Machine { int _channel = 1; - void validate() const override { + void validate() override { WifiConfig::validate(); Assert(_channel >= 1 && _channel <= 16, "WIFI channel %d is out of bounds", _channel); // TODO: I guess? } diff --git a/FluidNC/src/Machine/WifiSTAConfig.h b/FluidNC/src/Machine/WifiSTAConfig.h index 453f53658..5a5990efa 100644 --- a/FluidNC/src/Machine/WifiSTAConfig.h +++ b/FluidNC/src/Machine/WifiSTAConfig.h @@ -12,7 +12,7 @@ namespace Machine { public: WifiSTAConfig() = default; - void validate() const override { WifiConfig::validate(); } + void validate() override { WifiConfig::validate(); } void group(Configuration::HandlerBase& handler) override { WifiConfig::group(handler); } diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index 9da9cb228..aa5dcd3b9 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -106,7 +106,7 @@ namespace MotorDrivers { void config_motor() override; // Configuration handlers: - void validate() const override { + void validate() override { Assert(_uart_num != -1, "Dynamixel: Missing uart_num configuration"); Assert(_id != 255, "Dynamixel: ID must be configured."); } diff --git a/FluidNC/src/Motors/StandardStepper.cpp b/FluidNC/src/Motors/StandardStepper.cpp index bef63eb32..41e740971 100644 --- a/FluidNC/src/Motors/StandardStepper.cpp +++ b/FluidNC/src/Motors/StandardStepper.cpp @@ -115,7 +115,7 @@ namespace MotorDrivers { MotorFactory::InstanceBuilder registration("standard_stepper"); } - void StandardStepper::validate() const { + void StandardStepper::validate() { Assert(_step_pin.defined(), "Step pin must be configured."); bool isI2SO = config->_stepping->_engine == Stepping::I2S_STREAM || config->_stepping->_engine == Stepping::I2S_STATIC; if (isI2SO) { diff --git a/FluidNC/src/Motors/StandardStepper.h b/FluidNC/src/Motors/StandardStepper.h index 1f4f6c0eb..1a14954ae 100644 --- a/FluidNC/src/Motors/StandardStepper.h +++ b/FluidNC/src/Motors/StandardStepper.h @@ -32,7 +32,7 @@ namespace MotorDrivers { Pin _disable_pin; // Configuration handlers: - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override { handler.item("step_pin", _step_pin); diff --git a/FluidNC/src/Motors/StepStick.cpp b/FluidNC/src/Motors/StepStick.cpp index 6c68fa3cf..f09bd518a 100644 --- a/FluidNC/src/Motors/StepStick.cpp +++ b/FluidNC/src/Motors/StepStick.cpp @@ -18,7 +18,7 @@ namespace MotorDrivers { } // Configuration handlers: - void StepStick::validate() const { StandardStepper::validate(); } + void StepStick::validate() { StandardStepper::validate(); } void StepStick::group(Configuration::HandlerBase& handler) { StandardStepper::group(handler); diff --git a/FluidNC/src/Motors/StepStick.h b/FluidNC/src/Motors/StepStick.h index 72b70129a..a3de1ba93 100644 --- a/FluidNC/src/Motors/StepStick.h +++ b/FluidNC/src/Motors/StepStick.h @@ -22,7 +22,7 @@ namespace MotorDrivers { void init() override; // Configuration handlers: - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override; void afterParse() override; diff --git a/FluidNC/src/Motors/TMC2130Driver.h b/FluidNC/src/Motors/TMC2130Driver.h index 943204f02..11c680fcc 100644 --- a/FluidNC/src/Motors/TMC2130Driver.h +++ b/FluidNC/src/Motors/TMC2130Driver.h @@ -20,7 +20,7 @@ namespace MotorDrivers { void set_disable(bool disable); void config_motor() override; void debug_message() override; - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } // Name of the configurable. Must match the name registered in the cpp file. const char* name() const override { return "tmc_2130"; } diff --git a/FluidNC/src/Motors/TMC2208Driver.h b/FluidNC/src/Motors/TMC2208Driver.h index b3b16735b..226842568 100644 --- a/FluidNC/src/Motors/TMC2208Driver.h +++ b/FluidNC/src/Motors/TMC2208Driver.h @@ -20,7 +20,7 @@ namespace MotorDrivers { void set_disable(bool disable); void config_motor() override; void debug_message() override; - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void group(Configuration::HandlerBase& handler) override { TrinamicUartDriver::group(handler); diff --git a/FluidNC/src/Motors/TMC2209Driver.h b/FluidNC/src/Motors/TMC2209Driver.h index 8e7bacc20..c6c38e4a4 100644 --- a/FluidNC/src/Motors/TMC2209Driver.h +++ b/FluidNC/src/Motors/TMC2209Driver.h @@ -20,7 +20,7 @@ namespace MotorDrivers { void set_disable(bool disable); void config_motor() override; void debug_message() override; - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void group(Configuration::HandlerBase& handler) override { TrinamicUartDriver::group(handler); diff --git a/FluidNC/src/Motors/TMC5160Driver.h b/FluidNC/src/Motors/TMC5160Driver.h index 8bd3ba185..ddc27081e 100644 --- a/FluidNC/src/Motors/TMC5160Driver.h +++ b/FluidNC/src/Motors/TMC5160Driver.h @@ -20,7 +20,7 @@ namespace MotorDrivers { void set_disable(bool disable); void config_motor() override; void debug_message() override; - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void group(Configuration::HandlerBase& handler) override { TrinamicSpiDriver::group(handler); diff --git a/FluidNC/src/Motors/TMC5160ProDriver.h b/FluidNC/src/Motors/TMC5160ProDriver.h index 473ec40ac..c91b5443f 100644 --- a/FluidNC/src/Motors/TMC5160ProDriver.h +++ b/FluidNC/src/Motors/TMC5160ProDriver.h @@ -32,7 +32,7 @@ namespace MotorDrivers { void set_disable(bool disable); void config_motor() override; void debug_message() override; - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void group(Configuration::HandlerBase& handler) override { //handler.item("tpfd", _tpfd, 0, 15); diff --git a/FluidNC/src/Motors/TrinamicSpiDriver.h b/FluidNC/src/Motors/TrinamicSpiDriver.h index bb690ea23..4599549b2 100644 --- a/FluidNC/src/Motors/TrinamicSpiDriver.h +++ b/FluidNC/src/Motors/TrinamicSpiDriver.h @@ -49,7 +49,7 @@ namespace MotorDrivers { _spi_setup_done = true; } - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void group(Configuration::HandlerBase& handler) override { TrinamicBase::group(handler); diff --git a/FluidNC/src/Motors/TrinamicUartDriver.h b/FluidNC/src/Motors/TrinamicUartDriver.h index f8d257189..eb0f8e443 100644 --- a/FluidNC/src/Motors/TrinamicUartDriver.h +++ b/FluidNC/src/Motors/TrinamicUartDriver.h @@ -28,7 +28,7 @@ namespace MotorDrivers { uint8_t _addr; // Configuration handlers: - void validate() const override { StandardStepper::validate(); } + void validate() override { StandardStepper::validate(); } void afterParse() override { StandardStepper::validate(); diff --git a/FluidNC/src/Motors/UnipolarMotor.h b/FluidNC/src/Motors/UnipolarMotor.h index 456233bc6..29384b674 100644 --- a/FluidNC/src/Motors/UnipolarMotor.h +++ b/FluidNC/src/Motors/UnipolarMotor.h @@ -18,7 +18,7 @@ namespace MotorDrivers { void step() override; // Configuration handlers: - void validate() const override { + void validate() override { Assert(!_pin_phase0.undefined(), "Phase 0 pin should be configured."); Assert(!_pin_phase1.undefined(), "Phase 1 pin should be configured."); Assert(!_pin_phase2.undefined(), "Phase 2 pin should be configured."); diff --git a/FluidNC/src/OLED.h b/FluidNC/src/OLED.h index 7ff04c611..12aaa2bcd 100644 --- a/FluidNC/src/OLED.h +++ b/FluidNC/src/OLED.h @@ -117,7 +117,7 @@ class OLED : public Channel, public Configuration::Configurable { size_t timedReadBytes(char* buffer, size_t length, TickType_t timeout) override { return 0; } // Configuration handlers: - void validate() const override {} + void validate() override {} void afterParse() override; diff --git a/FluidNC/src/Probe.cpp b/FluidNC/src/Probe.cpp index 52435a697..0017cb70c 100644 --- a/FluidNC/src/Probe.cpp +++ b/FluidNC/src/Probe.cpp @@ -36,7 +36,7 @@ bool IRAM_ATTR Probe::tripped() { return _probePin.read() ^ _isProbeAway; } -void Probe::validate() const {} +void Probe::validate() {} void Probe::group(Configuration::HandlerBase& handler) { handler.item("pin", _probePin); diff --git a/FluidNC/src/Probe.h b/FluidNC/src/Probe.h index 7ead4ecad..14c5176c2 100644 --- a/FluidNC/src/Probe.h +++ b/FluidNC/src/Probe.h @@ -46,7 +46,7 @@ class Probe : public Configuration::Configurable { bool IRAM_ATTR tripped(); // Configuration handlers. - void validate() const override; + void validate() override; void group(Configuration::HandlerBase& handler) override; ~Probe() = default; diff --git a/FluidNC/src/Spindles/10vSpindle.h b/FluidNC/src/Spindles/10vSpindle.h index 607636b21..c9143fdb0 100644 --- a/FluidNC/src/Spindles/10vSpindle.h +++ b/FluidNC/src/Spindles/10vSpindle.h @@ -33,7 +33,7 @@ namespace Spindles { void deinit() override; // Configuration handlers: - void validate() const override { PWM::validate(); } + void validate() override { PWM::validate(); } void group(Configuration::HandlerBase& handler) override { handler.item("forward_pin", _forward_pin); diff --git a/FluidNC/src/Spindles/BESCSpindle.h b/FluidNC/src/Spindles/BESCSpindle.h index 912635738..98b4cb579 100644 --- a/FluidNC/src/Spindles/BESCSpindle.h +++ b/FluidNC/src/Spindles/BESCSpindle.h @@ -56,7 +56,7 @@ namespace Spindles { void set_output(uint32_t duty) override; // Configuration handlers: - void validate() const override { PWM::validate(); } + void validate() override { PWM::validate(); } void group(Configuration::HandlerBase& handler) override { PWM::group(handler); diff --git a/FluidNC/src/Spindles/HBridgeSpindle.h b/FluidNC/src/Spindles/HBridgeSpindle.h index 0784b81fd..88caa25bb 100644 --- a/FluidNC/src/Spindles/HBridgeSpindle.h +++ b/FluidNC/src/Spindles/HBridgeSpindle.h @@ -47,7 +47,7 @@ namespace Spindles { void setState(SpindleState state, SpindleSpeed speed) override; void config_message() override; // Configuration handlers: - void validate() const override { Spindle::validate(); } + void validate() override { Spindle::validate(); } void group(Configuration::HandlerBase& handler) override { // The APB clock frequency is 80MHz and the maximum divisor diff --git a/FluidNC/src/Spindles/OnOffSpindle.h b/FluidNC/src/Spindles/OnOffSpindle.h index 7d4dcee81..85389b7e9 100644 --- a/FluidNC/src/Spindles/OnOffSpindle.h +++ b/FluidNC/src/Spindles/OnOffSpindle.h @@ -46,7 +46,7 @@ namespace Spindles { virtual void set_enable(bool enable); // Configuration handlers: - void validate() const override { Spindle::validate(); } + void validate() override { Spindle::validate(); } void group(Configuration::HandlerBase& handler) override { handler.item("direction_pin", _direction_pin); diff --git a/FluidNC/src/Spindles/PWMSpindle.h b/FluidNC/src/Spindles/PWMSpindle.h index 7e0f3385c..9e3273847 100644 --- a/FluidNC/src/Spindles/PWMSpindle.h +++ b/FluidNC/src/Spindles/PWMSpindle.h @@ -33,7 +33,7 @@ namespace Spindles { void setState(SpindleState state, SpindleSpeed speed) override; void config_message() override; // Configuration handlers: - void validate() const override { Spindle::validate(); } + void validate() override { Spindle::validate(); } void group(Configuration::HandlerBase& handler) override { // The APB clock frequency is 80MHz and the maximum divisor diff --git a/FluidNC/src/Spindles/Spindle.h b/FluidNC/src/Spindles/Spindle.h index c9d88acfa..ccf5d3255 100644 --- a/FluidNC/src/Spindles/Spindle.h +++ b/FluidNC/src/Spindles/Spindle.h @@ -73,7 +73,7 @@ namespace Spindles { virtual const char* name() const = 0; // Configuration handlers: - void validate() const override { + void validate() override { // TODO: Validate spinup/spindown delay? } diff --git a/FluidNC/src/Spindles/VFDSpindle.h b/FluidNC/src/Spindles/VFDSpindle.h index 68a85884b..d7f0aa816 100644 --- a/FluidNC/src/Spindles/VFDSpindle.h +++ b/FluidNC/src/Spindles/VFDSpindle.h @@ -94,7 +94,7 @@ namespace Spindles { SpindleSpeed _slop; // Configuration handlers: - void validate() const override { + void validate() override { Spindle::validate(); Assert(_uart != nullptr || _uart_num != -1, "VFD: missing UART configuration"); Assert(!(_uart != nullptr && _uart_num != -1), "VFD: conflicting UART configuration"); diff --git a/FluidNC/src/Uart.h b/FluidNC/src/Uart.h index a494484f0..5bae71528 100644 --- a/FluidNC/src/Uart.h +++ b/FluidNC/src/Uart.h @@ -74,7 +74,7 @@ class Uart : public Stream, public Configuration::Configurable { bool setHalfDuplex(); // Configuration handlers: - void validate() const override { + void validate() override { Assert(!_txd_pin.undefined(), "UART: TXD is undefined"); Assert(!_rxd_pin.undefined(), "UART: RXD is undefined"); // RTS and CTS are optional. From 1b036a46f530b0ea14f1654eb730058fd81649ff Mon Sep 17 00:00:00 2001 From: bdring Date: Wed, 15 Mar 2023 09:30:12 -0500 Subject: [PATCH 02/51] Switch to new uart config style --- example_configs/TMC2209_corexy.yaml | 18 +++++++++++++----- example_configs/TMC2209_pen.yaml | 20 ++++++++++++-------- example_configs/TMC2209_pen_SG.yaml | 20 ++++++++++++-------- example_configs/tmc2209_10V.yaml | 24 ++++++++++++++++-------- example_configs/tmc2209_BESC.yaml | 24 ++++++++++++++++-------- example_configs/tmc2209_huanyang.yml | 9 +++++++++ example_configs/tmc2209_laser.yaml | 21 +++++++++++++-------- example_configs/tmc2209_relay.yaml | 23 +++++++++++++++-------- 8 files changed, 106 insertions(+), 53 deletions(-) diff --git a/example_configs/TMC2209_corexy.yaml b/example_configs/TMC2209_corexy.yaml index 5435aa67e..97eb3916c 100644 --- a/example_configs/TMC2209_corexy.yaml +++ b/example_configs/TMC2209_corexy.yaml @@ -1,5 +1,7 @@ board: TMC2209 4X name: TMC2209 XYZA +meta: "update for 3.6.8" + stepping: engine: RMT idle_ms: 255 @@ -9,6 +11,14 @@ stepping: kinematics: corexy: + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.25:high @@ -32,11 +42,7 @@ axes: hard_limits: false pulloff_mm: 2.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - baud: 115200 - mode: 8N1 + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 0.500 @@ -76,6 +82,7 @@ axes: hard_limits: false pulloff_mm: 2.00 tmc_2209: + uart_num: 1 addr: 1 r_sense_ohms: 0.110 run_amps: 0.500 @@ -114,6 +121,7 @@ axes: hard_limits: false pulloff_mm: 4.00 tmc_2209: + uart_num: 1 addr: 2 r_sense_ohms: 0.110 run_amps: 0.500 diff --git a/example_configs/TMC2209_pen.yaml b/example_configs/TMC2209_pen.yaml index 9396dc689..6059dbdec 100644 --- a/example_configs/TMC2209_pen.yaml +++ b/example_configs/TMC2209_pen.yaml @@ -1,11 +1,21 @@ board: TMC2209 Pen name: TMC2209 Pen +meta: "update for 3.6.8" + stepping: engine: RMT idle_ms: 250 pulse_us: 2 dir_delay_us: 1 disable_delay_us: 0 + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.13 @@ -32,14 +42,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - rts_pin: NO_PIN - cts_pin: NO_PIN - baud: 115200 - mode: 8N1 - + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 0.500 @@ -88,6 +91,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: + uart_num: 1 addr: 1 r_sense_ohms: 0.110 run_amps: 0.500 diff --git a/example_configs/TMC2209_pen_SG.yaml b/example_configs/TMC2209_pen_SG.yaml index 92b4bbdf8..66f8641b1 100644 --- a/example_configs/TMC2209_pen_SG.yaml +++ b/example_configs/TMC2209_pen_SG.yaml @@ -1,11 +1,21 @@ board: TMC2209 Pen name: TMC2209 Pen +meta: "update for 3.6.8" + stepping: engine: RMT idle_ms: 250 pulse_us: 2 dir_delay_us: 1 disable_delay_us: 0 + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.13 @@ -32,14 +42,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - rts_pin: NO_PIN - cts_pin: NO_PIN - baud: 115200 - mode: 8N1 - + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 1.00 @@ -88,6 +91,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: + uart_num: 1 addr: 1 r_sense_ohms: 0.110 run_amps: 0.500 diff --git a/example_configs/tmc2209_10V.yaml b/example_configs/tmc2209_10V.yaml index dba3c65f8..19bf960e0 100644 --- a/example_configs/tmc2209_10V.yaml +++ b/example_configs/tmc2209_10V.yaml @@ -1,5 +1,6 @@ name: "ESP32 Dev Controller V4" board: "ESP32 Dev Controller V4" +meta: "update for 3.6.8" stepping: engine: RMT @@ -7,6 +8,14 @@ stepping: dir_delay_us: 1 pulse_us: 2 disable_delay_us: 0 + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.25:high @@ -29,11 +38,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - baud: 115200 - mode: 8N1 + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 0.500 @@ -73,11 +78,12 @@ axes: limit_pos_pin: gpio.34 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.33 direction_pin: gpio.32 microsteps: 16 + uart_num: 1 addr: 1 motor1: @@ -102,10 +108,11 @@ axes: limit_pos_pin: gpio.39 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.2 direction_pin: gpio.14 + uart_num: 1 addr: 2 motor1: @@ -131,10 +138,11 @@ axes: limit_pos_pin: gpio.36 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.16 direction_pin: gpio.15 + uart_num: 1 addr: 3 motor1: diff --git a/example_configs/tmc2209_BESC.yaml b/example_configs/tmc2209_BESC.yaml index 1053f3f1e..a638d4246 100644 --- a/example_configs/tmc2209_BESC.yaml +++ b/example_configs/tmc2209_BESC.yaml @@ -1,5 +1,6 @@ name: "ESP32 Dev Controller V4" board: "ESP32 Dev Controller V4" +meta: "update for 3.6.8" stepping: engine: RMT @@ -7,6 +8,14 @@ stepping: dir_delay_us: 1 pulse_us: 2 disable_delay_us: 0 + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.25:high @@ -29,11 +38,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - baud: 115200 - mode: 8N1 + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 0.500 @@ -73,11 +78,12 @@ axes: limit_pos_pin: gpio.34 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.33 direction_pin: gpio.32 microsteps: 16 + uart_num: 1 addr: 1 motor1: @@ -102,10 +108,11 @@ axes: limit_pos_pin: gpio.39 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.2 direction_pin: gpio.14 + uart_num: 1 addr: 2 motor1: @@ -131,10 +138,11 @@ axes: limit_pos_pin: gpio.36 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.16 direction_pin: gpio.15 + uart_num: 1 addr: 3 motor1: diff --git a/example_configs/tmc2209_huanyang.yml b/example_configs/tmc2209_huanyang.yml index c69d876a6..8dda93dc9 100644 --- a/example_configs/tmc2209_huanyang.yml +++ b/example_configs/tmc2209_huanyang.yml @@ -1,5 +1,6 @@ name: "TMC2209 XYZA PWM Spindle" board: "TMC2209 4x" +meta: "update for 3.6.8" stepping: engine: RMT @@ -10,6 +11,14 @@ stepping: homing_init_lock: true +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 + axes: shared_stepper_disable_pin: gpio.25:high diff --git a/example_configs/tmc2209_laser.yaml b/example_configs/tmc2209_laser.yaml index fc48d4504..f72dc9127 100644 --- a/example_configs/tmc2209_laser.yaml +++ b/example_configs/tmc2209_laser.yaml @@ -1,5 +1,6 @@ name: "TMC2209 XYYZ Laser" board: "TMC2209 4x DK" +meta: "update for 3.6.8" stepping: engine: RMT @@ -7,6 +8,14 @@ stepping: dir_delay_us: 1 pulse_us: 2 disable_delay_us: 0 + +uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.25:high @@ -34,14 +43,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - rts_pin: NO_PIN - cts_pin: NO_PIN - baud: 115200 - mode: 8N1 - + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 1.200 @@ -90,6 +92,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: + uart_num: 1 addr: 1 r_sense_ohms: 0.110 run_amps: 1.200 @@ -138,6 +141,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: + uart_num: 1 addr: 2 r_sense_ohms: 0.110 run_amps: 1.200 @@ -186,6 +190,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: + uart_num: 1 addr: 3 r_sense_ohms: 0.110 run_amps: 1.200 diff --git a/example_configs/tmc2209_relay.yaml b/example_configs/tmc2209_relay.yaml index 4fd8489ed..8c1f06f8b 100644 --- a/example_configs/tmc2209_relay.yaml +++ b/example_configs/tmc2209_relay.yaml @@ -1,5 +1,6 @@ name: "TMC2209 XYYZ Laser" board: "TMC2209 4x DK" +meta: "update for 3.6.8" stepping: engine: RMT @@ -7,6 +8,14 @@ stepping: dir_delay_us: 1 pulse_us: 2 disable_delay_us: 0 + + uart1: + txd_pin: gpio.22 + rxd_pin: gpio.21 + rts_pin: NO_PIN + cts_pin: NO_PIN + baud: 115200 + mode: 8N1 axes: shared_stepper_disable_pin: gpio.25:high @@ -29,11 +38,7 @@ axes: hard_limits: false pulloff_mm: 1.000 tmc_2209: - uart: - txd_pin: gpio.22 - rxd_pin: gpio.21 - baud: 115200 - mode: 8N1 + uart_num: 1 addr: 0 r_sense_ohms: 0.110 run_amps: 0.500 @@ -73,11 +78,12 @@ axes: limit_pos_pin: gpio.34 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.33 direction_pin: gpio.32 microsteps: 16 + uart_num: 1 addr: 1 motor1: @@ -102,10 +108,11 @@ axes: limit_pos_pin: gpio.39 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.2 direction_pin: gpio.14 + uart_num: 1 addr: 2 motor1: @@ -131,7 +138,7 @@ axes: limit_pos_pin: gpio.36 limit_all_pin: NO_PIN hard_limits: false - pulloff_mm:1.00 + pulloff_mm: 1.00 tmc_2209: step_pin: gpio.16 direction_pin: gpio.15 From 204caa00dc89f37769427c9dd270b25fe15a4399 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 09:33:45 -1000 Subject: [PATCH 03/51] String -> std::string in StringSetting --- FluidNC/src/Settings.cpp | 2 +- FluidNC/src/Settings.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/FluidNC/src/Settings.cpp b/FluidNC/src/Settings.cpp index ad1ab0758..2b4ea96d7 100644 --- a/FluidNC/src/Settings.cpp +++ b/FluidNC/src/Settings.cpp @@ -220,7 +220,7 @@ void StringSetting::load() { _currentValue = _defaultValue; return; } - _storedValue = String(buf); + _storedValue = buf; _currentValue = _storedValue; } diff --git a/FluidNC/src/Settings.h b/FluidNC/src/Settings.h index fdaa71b48..4ceb360c5 100644 --- a/FluidNC/src/Settings.h +++ b/FluidNC/src/Settings.h @@ -229,12 +229,12 @@ extern Coordinates* coords[CoordIndex::End]; class StringSetting : public Setting { private: - String _defaultValue; - String _currentValue; - String _storedValue; - int _minLength; - int _maxLength; - void _setStoredValue(const char* s); + std::string _defaultValue; + std::string _currentValue; + std::string _storedValue; + int _minLength; + int _maxLength; + void _setStoredValue(const char* s); public: StringSetting(const char* description, From 871982166dc1f782d8bd5d717688fcc666cb082e Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 12:03:46 -1000 Subject: [PATCH 04/51] String -> std::string in config items --- FluidNC/src/Configuration/AfterParse.h | 2 +- FluidNC/src/Configuration/Completer.h | 2 +- FluidNC/src/Configuration/Generator.h | 2 +- FluidNC/src/Configuration/HandlerBase.h | 3 ++- FluidNC/src/Configuration/JsonGenerator.cpp | 4 ++-- FluidNC/src/Configuration/JsonGenerator.h | 2 +- FluidNC/src/Configuration/ParserHandler.h | 4 ++-- FluidNC/src/Configuration/RuntimeSetting.cpp | 4 ++-- FluidNC/src/Configuration/RuntimeSetting.h | 2 +- FluidNC/src/Configuration/Validator.h | 2 +- FluidNC/src/Machine/MachineConfig.h | 6 +++--- FluidNC/src/Machine/Macros.cpp | 2 +- FluidNC/src/Machine/Macros.h | 11 ++++++----- FluidNC/src/ProcessSettings.cpp | 2 +- 14 files changed, 25 insertions(+), 23 deletions(-) diff --git a/FluidNC/src/Configuration/AfterParse.h b/FluidNC/src/Configuration/AfterParse.h index f1f2f7df1..d9f00e8b1 100644 --- a/FluidNC/src/Configuration/AfterParse.h +++ b/FluidNC/src/Configuration/AfterParse.h @@ -31,7 +31,7 @@ namespace Configuration { void item(const char* name, float& value, float minValue, float maxValue) override {} void item(const char* name, std::vector& value) override {} void item(const char* name, UartData& wordLength, UartParity& parity, UartStop& stopBits) override {} - void item(const char* name, String& value, int minLength, int maxLength) override {} + void item(const char* name, std::string& value, int minLength, int maxLength) override {} void item(const char* name, Pin& value) override {} void item(const char* name, IPAddress& value) override {} void item(const char* name, int& value, EnumItem* e) override {} diff --git a/FluidNC/src/Configuration/Completer.h b/FluidNC/src/Configuration/Completer.h index 58e9bf287..ae6f0a2dd 100644 --- a/FluidNC/src/Configuration/Completer.h +++ b/FluidNC/src/Configuration/Completer.h @@ -32,7 +32,7 @@ namespace Configuration { void item(const char* name, float& value, float minValue, float maxValue) override { item(name); } void item(const char* name, std::vector& value) override { item(name); } void item(const char* name, UartData& wordLength, UartParity& parity, UartStop& stopBits) override { item(name); } - void item(const char* name, String& value, int minLength, int maxLength) override { item(name); } + void item(const char* name, std::string& value, int minLength, int maxLength) override { item(name); } void item(const char* name, Pin& value) { item(name); } void item(const char* name, IPAddress& value) override { item(name); } void item(const char* name, int& value, EnumItem* e) override { item(name); } diff --git a/FluidNC/src/Configuration/Generator.h b/FluidNC/src/Configuration/Generator.h index 537671b2b..212f05f97 100644 --- a/FluidNC/src/Configuration/Generator.h +++ b/FluidNC/src/Configuration/Generator.h @@ -98,7 +98,7 @@ namespace Configuration { send_item(name, s); } - void item(const char* name, String& value, int minLength, int maxLength) override { send_item(name, value.c_str()); } + void item(const char* name, std::string& value, int minLength, int maxLength) override { send_item(name, value.c_str()); } void item(const char* name, bool& value) override { send_item(name, value ? "true" : "false"); } diff --git a/FluidNC/src/Configuration/HandlerBase.h b/FluidNC/src/Configuration/HandlerBase.h index 727868159..5f94cfd67 100644 --- a/FluidNC/src/Configuration/HandlerBase.h +++ b/FluidNC/src/Configuration/HandlerBase.h @@ -10,6 +10,7 @@ #include "../UartTypes.h" #include +#include namespace Configuration { class Configurable; @@ -52,7 +53,7 @@ namespace Configuration { virtual void item(const char* name, int& value, EnumItem* e) = 0; - virtual void item(const char* name, String& value, int minLength = 0, int maxLength = 255) = 0; + virtual void item(const char* name, std::string& value, int minLength = 0, int maxLength = 255) = 0; virtual HandlerType handlerType() = 0; diff --git a/FluidNC/src/Configuration/JsonGenerator.cpp b/FluidNC/src/Configuration/JsonGenerator.cpp index 0f9ec45e4..3d345a475 100644 --- a/FluidNC/src/Configuration/JsonGenerator.cpp +++ b/FluidNC/src/Configuration/JsonGenerator.cpp @@ -73,7 +73,7 @@ namespace Configuration { leave(); } - void JsonGenerator::item(const char* name, uint32_t& value, uint32_t minValue, uint32_t maxValue) { + void JsonGenerator::item(const char* name, uint32_t& value, uint32_t minValue, uint32_t maxValue) { enter(name); char buf[32]; itoa(value, buf, 10); @@ -100,7 +100,7 @@ namespace Configuration { // Not sure if I should comment this out or not. The implementation is similar to the one in Generator.h. } - void JsonGenerator::item(const char* name, String& value, int minLength, int maxLength) { + void JsonGenerator::item(const char* name, std::string& value, int minLength, int maxLength) { enter(name); _encoder.begin_webui(_currentPath, _currentPath, "S", value.c_str(), minLength, maxLength); _encoder.end_object(); diff --git a/FluidNC/src/Configuration/JsonGenerator.h b/FluidNC/src/Configuration/JsonGenerator.h index 8e87686bd..2b009aae8 100644 --- a/FluidNC/src/Configuration/JsonGenerator.h +++ b/FluidNC/src/Configuration/JsonGenerator.h @@ -41,7 +41,7 @@ namespace Configuration { void item(const char* name, float& value, float minValue, float maxValue) override; void item(const char* name, std::vector& value) override; void item(const char* name, UartData& wordLength, UartParity& parity, UartStop& stopBits) override; - void item(const char* name, String& value, int minLength, int maxLength) override; + void item(const char* name, std::string& value, int minLength, int maxLength) override; void item(const char* name, Pin& value) override; void item(const char* name, IPAddress& value) override; void item(const char* name, int& value, EnumItem* e) override; diff --git a/FluidNC/src/Configuration/ParserHandler.h b/FluidNC/src/Configuration/ParserHandler.h index a5e5c3bc2..2fb46e7a7 100644 --- a/FluidNC/src/Configuration/ParserHandler.h +++ b/FluidNC/src/Configuration/ParserHandler.h @@ -142,9 +142,9 @@ namespace Configuration { } } - void item(const char* name, String& value, int minLength, int maxLength) override { + void item(const char* name, std::string& value, int minLength, int maxLength) override { if (_parser.is(name)) { - value = _parser.stringValue().str(); + value = _parser.stringValue().str().c_str(); } } diff --git a/FluidNC/src/Configuration/RuntimeSetting.cpp b/FluidNC/src/Configuration/RuntimeSetting.cpp index f827fa0f7..ea8cf0630 100644 --- a/FluidNC/src/Configuration/RuntimeSetting.cpp +++ b/FluidNC/src/Configuration/RuntimeSetting.cpp @@ -109,13 +109,13 @@ namespace Configuration { } } - void RuntimeSetting::item(const char* name, String& value, int minLength, int maxLength) { + void RuntimeSetting::item(const char* name, std::string& value, int minLength, int maxLength) { if (is(name)) { isHandled_ = true; if (newValue_ == nullptr) { log_to(out_, "", setting_prefix() << value); } else { - value = String(newValue_); + value = newValue_; } } } diff --git a/FluidNC/src/Configuration/RuntimeSetting.h b/FluidNC/src/Configuration/RuntimeSetting.h index 014176455..cbce85588 100644 --- a/FluidNC/src/Configuration/RuntimeSetting.h +++ b/FluidNC/src/Configuration/RuntimeSetting.h @@ -39,7 +39,7 @@ namespace Configuration { void item(const char* name, float& value, float minValue, float maxValue) override; void item(const char* name, std::vector& value) override; void item(const char* name, UartData& wordLength, UartParity& parity, UartStop& stopBits) override {} - void item(const char* name, String& value, int minLength, int maxLength) override; + void item(const char* name, std::string& value, int minLength, int maxLength) override; void item(const char* name, Pin& value) override; void item(const char* name, IPAddress& value) override; void item(const char* name, int& value, EnumItem* e) override; diff --git a/FluidNC/src/Configuration/Validator.h b/FluidNC/src/Configuration/Validator.h index e0d70f0ea..c44e859ae 100644 --- a/FluidNC/src/Configuration/Validator.h +++ b/FluidNC/src/Configuration/Validator.h @@ -31,7 +31,7 @@ namespace Configuration { void item(const char* name, float& value, float minValue, float maxValue) override {} void item(const char* name, std::vector& value) override {} void item(const char* name, UartData& wordLength, UartParity& parity, UartStop& stopBits) override {} - void item(const char* name, String& value, int minLength, int maxLength) override {} + void item(const char* name, std::string& value, int minLength, int maxLength) override {} void item(const char* name, Pin& value) override {} void item(const char* name, IPAddress& value) override {} void item(const char* name, int& value, EnumItem* e) override {} diff --git a/FluidNC/src/Machine/MachineConfig.h b/FluidNC/src/Machine/MachineConfig.h index 16c0673e7..8f5ff270c 100644 --- a/FluidNC/src/Machine/MachineConfig.h +++ b/FluidNC/src/Machine/MachineConfig.h @@ -93,9 +93,9 @@ namespace Machine { // Tracks and reports gcode line numbers. Disabled by default. bool _useLineNumbers = false; - String _board = "None"; - String _name = "None"; - String _meta = ""; + std::string _board = "None"; + std::string _name = "None"; + std::string _meta = ""; #if 1 static MachineConfig*& instance() { static MachineConfig* instance = nullptr; diff --git a/FluidNC/src/Machine/Macros.cpp b/FluidNC/src/Machine/Macros.cpp index 381a955d3..a493af8ea 100644 --- a/FluidNC/src/Machine/Macros.cpp +++ b/FluidNC/src/Machine/Macros.cpp @@ -51,7 +51,7 @@ bool Macros::run_macro(size_t index) { if (index >= n_macros) { return false; } - String macro = _macro[index]; + auto macro = _macro[index]; if (macro == "") { return true; } diff --git a/FluidNC/src/Machine/Macros.h b/FluidNC/src/Machine/Macros.h index 905c618dc..ac785b10f 100644 --- a/FluidNC/src/Machine/Macros.h +++ b/FluidNC/src/Machine/Macros.h @@ -8,6 +8,7 @@ #include "src/WebUI/InputBuffer.h" // WebUI::inputBuffer #include "src/UartChannel.h" #include "src/Event.h" +#include class MacroEvent : public Event { int _num; @@ -29,25 +30,25 @@ namespace Machine { static const int n_macros = 4; private: - String _startup_line[n_startup_lines]; - String _macro[n_macros]; + std::string _startup_line[n_startup_lines]; + std::string _macro[n_macros]; public: Macros() = default; bool run_macro(size_t index); - String startup_line(size_t index) { + std::string startup_line(size_t index) { if (index >= n_startup_lines) { return ""; } - String s = _startup_line[index]; + auto s = _startup_line[index]; if (s == "") { return s; } // & is a proxy for newlines in startup lines, because you cannot // enter a newline directly in a config file string value. - s.replace('&', '\n'); + std::replace(s.begin(), s.end(), '&', '\n'); return s + "\n"; } diff --git a/FluidNC/src/ProcessSettings.cpp b/FluidNC/src/ProcessSettings.cpp index 884045f10..b8f614815 100644 --- a/FluidNC/src/ProcessSettings.cpp +++ b/FluidNC/src/ProcessSettings.cpp @@ -985,7 +985,7 @@ Error settings_execute_line(char* line, Channel& out, WebUI::AuthenticationLevel void settings_execute_startup() { Error status_code; for (int i = 0; i < config->_macros->n_startup_lines; i++) { - String str = config->_macros->startup_line(i); + auto str = config->_macros->startup_line(i); if (str.length()) { // We have to copy this to a mutable array because // gc_execute_line modifies the line while parsing. From 36679290000922ea65f687706e3d088d5b758bb8 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 12:25:11 -1000 Subject: [PATCH 05/51] String -> std::string in completer --- FluidNC/src/Configuration/Completer.cpp | 25 ++++++++++++++----------- FluidNC/src/Configuration/Completer.h | 10 +++++----- FluidNC/src/Event.h | 1 - 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/FluidNC/src/Configuration/Completer.cpp b/FluidNC/src/Configuration/Completer.cpp index 046ce87e4..040fc884e 100644 --- a/FluidNC/src/Configuration/Completer.cpp +++ b/FluidNC/src/Configuration/Completer.cpp @@ -13,7 +13,7 @@ namespace Configuration { Completer::Completer(const char* key, int reqMatch, char* matchedStr) : _key(key), _reqMatch(reqMatch), _matchedStr(matchedStr), _currentPath("/"), _numMatches(0) {} - void Completer::addCandidate(String fullName) { + void Completer::addCandidate(std::string fullName) { if (_matchedStr && _numMatches == _reqMatch) { strcpy(_matchedStr, fullName.c_str()); } @@ -24,13 +24,13 @@ namespace Configuration { auto previous = _currentPath; _currentPath += name; _currentPath += "/"; - if (_key.startsWith(_currentPath)) { + if (_key.rfind(_currentPath, 0) == 0) { // If _currentPath is an initial substring of _key, this section // is part of a path leading to the key, so we have to check // this section's children // Example: _key = /axes/x/motor0/cy _currentPath=/axes/x/motor0 value->group(*this); - } else if (_currentPath.startsWith(_key)) { + } else if (_currentPath.rfind(_key, 0) == 0) { // If _key is an initial substring of _currentPath, this section // is a candidate. Example: _key = /axes/x/h _currentPath=/axes/x/homing addCandidate(_currentPath); @@ -39,8 +39,8 @@ namespace Configuration { } void Completer::item(const char* name) { - String fullItemName = _currentPath + name; - if (fullItemName.startsWith(_key)) { + std::string fullItemName = _currentPath + name; + if (fullItemName.rfind(_key, 0) == 0) { addCandidate(fullItemName); } } @@ -73,13 +73,16 @@ int num_initial_matches(char* key, int keylen, int matchnum, char* matchname) { nfound = completer._numMatches; } else { // Match NVS settings - auto lcKey = String(key); - lcKey.toLowerCase(); + std::string lcKey(key); + for (auto& c : lcKey) { + c = tolower(c); + } for (Setting* s = Setting::List; s; s = s->next()) { - auto lcTest = String(s->getName()); - lcTest.toLowerCase(); - - if (*key == '\0' || lcTest.startsWith(lcKey)) { + std::string lcTest(s->getName()); + for (auto& c : lcTest) { + c = tolower(c); + } + if (*key == '\0' || (lcTest.rfind(lcKey, 0) == 0)) { if (matchname && nfound == matchnum) { strcpy(matchname, s->getName()); } diff --git a/FluidNC/src/Configuration/Completer.h b/FluidNC/src/Configuration/Completer.h index ae6f0a2dd..a7db12f5a 100644 --- a/FluidNC/src/Configuration/Completer.h +++ b/FluidNC/src/Configuration/Completer.h @@ -9,12 +9,12 @@ namespace Configuration { class Completer : public Configuration::HandlerBase { private: - String _key; - int _reqMatch; - char* _matchedStr; - String _currentPath; + std::string _key; + int _reqMatch; + char* _matchedStr; + std::string _currentPath; - void addCandidate(String fullName); + void addCandidate(std::string fullName); protected: void enterSection(const char* name, Configuration::Configurable* value) override; diff --git a/FluidNC/src/Event.h b/FluidNC/src/Event.h index daeceafa7..a6453c79f 100644 --- a/FluidNC/src/Event.h +++ b/FluidNC/src/Event.h @@ -2,7 +2,6 @@ // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. #pragma once -#include // String // Objects derived from the Event base class are placed in the event queue. // Protocol dequeues them and calls their run methods. From a1e143c448b9566004ad4b31d5a06b66bc38bad3 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 12:44:49 -1000 Subject: [PATCH 06/51] String -> std::string in Completer --- FluidNC/src/Configuration/Completer.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/FluidNC/src/Configuration/Completer.cpp b/FluidNC/src/Configuration/Completer.cpp index 040fc884e..da673332c 100644 --- a/FluidNC/src/Configuration/Completer.cpp +++ b/FluidNC/src/Configuration/Completer.cpp @@ -50,6 +50,14 @@ namespace Configuration { #include "../Settings.h" +static bool isInitialSubstringCI(const char* key, const char* test) { + while (*key && *test) { + if (tolower(*key++) != tolower(*test++)) { + return false; + } + } + return *key == '\0'; +} // This provides the interface to the completion routines in lineedit.cpp // The argument signature is idiosyncratic, based on the needs of the // Forth implementation for which the completion code was first developed. @@ -73,16 +81,8 @@ int num_initial_matches(char* key, int keylen, int matchnum, char* matchname) { nfound = completer._numMatches; } else { // Match NVS settings - std::string lcKey(key); - for (auto& c : lcKey) { - c = tolower(c); - } for (Setting* s = Setting::List; s; s = s->next()) { - std::string lcTest(s->getName()); - for (auto& c : lcTest) { - c = tolower(c); - } - if (*key == '\0' || (lcTest.rfind(lcKey, 0) == 0)) { + if (isInitialSubstringCI(key, s->getName())) { if (matchname && nfound == matchnum) { strcpy(matchname, s->getName()); } From c667e87a11f096273b7eb46c6a5700beb15ce27a Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 13:17:50 -1000 Subject: [PATCH 07/51] String -> std::string in JSON Encoder and some in WebServer --- FluidNC/src/Configuration/JsonGenerator.h | 1 - FluidNC/src/WebUI/JSONEncoder.cpp | 10 +--- FluidNC/src/WebUI/JSONEncoder.h | 1 - FluidNC/src/WebUI/WebServer.cpp | 59 ++++++++++--------- FluidNC/src/WebUI/WebServer.h | 8 +-- FluidNC/src/WebUI/WifiConfig.cpp | 70 ++++++----------------- 6 files changed, 57 insertions(+), 92 deletions(-) diff --git a/FluidNC/src/Configuration/JsonGenerator.h b/FluidNC/src/Configuration/JsonGenerator.h index 2b009aae8..4d6d1dcd8 100644 --- a/FluidNC/src/Configuration/JsonGenerator.h +++ b/FluidNC/src/Configuration/JsonGenerator.h @@ -6,7 +6,6 @@ #include #include "../Pin.h" -#include "../StringStream.h" #include "HandlerBase.h" #include "../WebUI/JSONEncoder.h" diff --git a/FluidNC/src/WebUI/JSONEncoder.cpp b/FluidNC/src/WebUI/JSONEncoder.cpp index 7a72e4775..c2998c5fa 100644 --- a/FluidNC/src/WebUI/JSONEncoder.cpp +++ b/FluidNC/src/WebUI/JSONEncoder.cpp @@ -180,14 +180,8 @@ namespace WebUI { quoted(value.c_str()); } - // Creates a "tag":"value" member from an Arduino string - void JSONencoder::member(const char* tag, String value) { - begin_member(tag); - quoted(value.c_str()); - } - // Creates a "tag":"value" member from an integer - void JSONencoder::member(const char* tag, int value) { member(tag, String(value)); } + void JSONencoder::member(const char* tag, int value) { member(tag, std::to_string(value)); } // Creates an Esp32_WebUI configuration item specification from // a value passed in as a C-style string. @@ -208,7 +202,7 @@ namespace WebUI { // Creates an Esp32_WebUI configuration item specification from // an integer value. void JSONencoder::begin_webui(const char* brief, const char* full, const char* type, int val) { - begin_webui(brief, full, type, String(val).c_str()); + begin_webui(brief, full, type, std::to_string(val).c_str()); } // Creates an Esp32_WebUI configuration item specification from diff --git a/FluidNC/src/WebUI/JSONEncoder.h b/FluidNC/src/WebUI/JSONEncoder.h index 61fafb6f1..cc4a059cd 100644 --- a/FluidNC/src/WebUI/JSONEncoder.h +++ b/FluidNC/src/WebUI/JSONEncoder.h @@ -42,7 +42,6 @@ namespace WebUI { // member() creates a "tag":"value" element void member(const char* tag, const char* value); - void member(const char* tag, String value); void member(const char* tag, const std::string& value); void member(const char* tag, int value); diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 1c199f9e0..437dc47ea 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -75,12 +75,19 @@ namespace WebUI { FileStream* Web_Server::_uploadFile = nullptr; EnumSetting *http_enable, *http_block_during_motion; - IntSetting *http_port; + IntSetting* http_port; Web_Server::Web_Server() { - http_port = new IntSetting("HTTP Port", WEBSET, WA, "ESP121", "HTTP/Port", DEFAULT_HTTP_PORT, MIN_HTTP_PORT, MAX_HTTP_PORT, NULL); - http_enable = new EnumSetting("HTTP Enable", WEBSET, WA, "ESP120", "HTTP/Enable", DEFAULT_HTTP_STATE, &onoffOptions, NULL); - http_block_during_motion = new EnumSetting("Block serving HTTP content during motion", WEBSET, WA, "", "HTTP/BlockDuringMotion", DEFAULT_HTTP_BLOCKED_DURING_MOTION, &onoffOptions, NULL); + http_port = new IntSetting("HTTP Port", WEBSET, WA, "ESP121", "HTTP/Port", DEFAULT_HTTP_PORT, MIN_HTTP_PORT, MAX_HTTP_PORT, NULL); + http_enable = new EnumSetting("HTTP Enable", WEBSET, WA, "ESP120", "HTTP/Enable", DEFAULT_HTTP_STATE, &onoffOptions, NULL); + http_block_during_motion = new EnumSetting("Block serving HTTP content during motion", + WEBSET, + WA, + "", + "HTTP/BlockDuringMotion", + DEFAULT_HTTP_BLOCKED_DURING_MOTION, + &onoffOptions, + NULL); } Web_Server::~Web_Server() { end(); } @@ -462,11 +469,11 @@ namespace WebUI { //login status check void Web_Server::handle_login() { # ifdef ENABLE_AUTHENTICATION - String smsg; - String sUser, sPassword; - String auths; - int code = 200; - bool msg_alert_error = false; + const char* smsg; + String sUser, sPassword; + const char* auths; + int code = 200; + bool msg_alert_error = false; //disconnect can be done anytime no need to check credential if (_webserver->hasArg("DISCONNECT")) { String cookie = _webserver->header("Cookie"); @@ -711,22 +718,22 @@ namespace WebUI { _webserver->send(200, "application/json", s); } - void Web_Server::sendAuth(const String& status, const String& level, const String& user) { + void Web_Server::sendAuth(const char* status, const char* level, const char* user) { std::string s; JSONencoder j(false, &s); j.begin(); j.member("status", status); - if (level != "") { + if (*level != '\0') { j.member("authentication_lvl", level); } - if (user != "") { + if (*user != '\0') { j.member("user", user); } j.end(); sendJSON(200, s.c_str()); } - void Web_Server::sendStatus(int code, const String& status) { + void Web_Server::sendStatus(int code, const char* status) { std::string s; JSONencoder j(false, &s); j.begin(); @@ -749,7 +756,7 @@ namespace WebUI { return; } - sendStatus(200, String(int(_upload_status))); + sendStatus(200, std::to_string(int(_upload_status)).c_str()); //if success restart if (_upload_status == UploadStatus::SUCCESSFUL) { @@ -864,8 +871,8 @@ namespace WebUI { std::error_code ec; - String path = ""; - String sstatus = "Ok"; + String path = ""; + std::string sstatus = "Ok"; if ((_upload_status == UploadStatus::FAILED) || (_upload_status == UploadStatus::FAILED)) { sstatus = "Upload failed"; } @@ -895,28 +902,28 @@ namespace WebUI { // Handle deletions and directory creation if (_webserver->hasArg("action") && _webserver->hasArg("filename")) { - String action = _webserver->arg("action"); - String filename = _webserver->arg("filename"); + String action = _webserver->arg("action"); + std::string filename = std::string(_webserver->arg("filename").c_str()); if (action == "delete") { if (stdfs::remove(fpath / filename.c_str(), ec)) { sstatus = filename + " deleted"; } else { sstatus = "Cannot delete "; - sstatus += filename + " " + ec.message().c_str(); + sstatus += filename + " " + ec.message(); } } else if (action == "deletedir") { if (stdfs::remove_all(fpath / filename.c_str(), ec)) { sstatus = filename + " deleted"; } else { sstatus = "Cannot delete "; - sstatus += filename + " " + ec.message().c_str(); + sstatus += filename + " " + ec.message(); } } else if (action == "createdir") { - if (stdfs::create_directory(fpath / filename.c_str(), ec)) { + if (stdfs::create_directory(fpath / filename, ec)) { sstatus = filename + " created"; } else { sstatus = "Cannot create "; - sstatus += filename + " " + ec.message().c_str(); + sstatus += filename + " " + ec.message(); } } } @@ -951,13 +958,13 @@ namespace WebUI { totalspace = space.capacity; usedspace = totalspace - space.available; - j.member("path", path); - j.member("total", formatBytes(totalspace)); - j.member("used", formatBytes(usedspace + 1)); + j.member("path", path.c_str()); + j.member("total", formatBytes(totalspace).c_str()); + j.member("used", formatBytes(usedspace + 1).c_str()); uint32_t percent = totalspace ? (usedspace * 100) / totalspace : 100; - j.member("occupation", String(percent)); + j.member("occupation", percent); j.member("status", sstatus); j.end(); sendJSON(200, s.c_str()); diff --git a/FluidNC/src/WebUI/WebServer.h b/FluidNC/src/WebUI/WebServer.h index 863193fe7..2eabb236b 100644 --- a/FluidNC/src/WebUI/WebServer.h +++ b/FluidNC/src/WebUI/WebServer.h @@ -17,9 +17,9 @@ class WebSocketsServer; class WebServer; namespace WebUI { - static const int DEFAULT_HTTP_STATE = 1; + static const int DEFAULT_HTTP_STATE = 1; static const int DEFAULT_HTTP_BLOCKED_DURING_MOTION = 1; - static const int DEFAULT_HTTP_PORT = 80; + static const int DEFAULT_HTTP_PORT = 80; static const int MIN_HTTP_PORT = 1; static const int MAX_HTTP_PORT = 65001; @@ -106,9 +106,9 @@ namespace WebUI { static void sendFSError(Error err); static void sendJSON(int code, const String& s); - static void sendAuth(const String& status, const String& level, const String& user); + static void sendAuth(const char* status, const char* level, const char* user); static void sendAuthFailed(); - static void sendStatus(int code, const String& str); + static void sendStatus(int code, const char* str); static void sendWithOurAddress(String s); static void sendCaptivePortal(); diff --git a/FluidNC/src/WebUI/WifiConfig.cpp b/FluidNC/src/WebUI/WifiConfig.cpp index c73350908..309e310c8 100644 --- a/FluidNC/src/WebUI/WifiConfig.cpp +++ b/FluidNC/src/WebUI/WifiConfig.cpp @@ -44,7 +44,7 @@ namespace WebUI { }; enum WiFiContry { - WiFiCountry01 = 0, // country "01" is the safest set of settings which complies with all regulatory domains + WiFiCountry01 = 0, // country "01" is the safest set of settings which complies with all regulatory domains WiFiCountryAT, WiFiCountryAU, WiFiCountryBE, @@ -92,51 +92,15 @@ namespace WebUI { }; enum_opt_t wifiContryOptions = { - { "01", WiFiCountry01 }, - { "AT", WiFiCountryAT }, - { "AU", WiFiCountryAU }, - { "BE", WiFiCountryBE }, - { "BG", WiFiCountryBG }, - { "BR", WiFiCountryBR }, - { "CA", WiFiCountryCA }, - { "CH", WiFiCountryCH }, - { "CN", WiFiCountryCN }, - { "CY", WiFiCountryCY }, - { "CZ", WiFiCountryCZ }, - { "DE", WiFiCountryDE }, - { "DK", WiFiCountryDK }, - { "EE", WiFiCountryEE }, - { "ES", WiFiCountryES }, - { "FI", WiFiCountryFI }, - { "FR", WiFiCountryFR }, - { "GB", WiFiCountryGB }, - { "GR", WiFiCountryGR }, - { "HK", WiFiCountryHK }, - { "HR", WiFiCountryHR }, - { "HU", WiFiCountryHU }, - { "IE", WiFiCountryIE }, - { "IN", WiFiCountryIN }, - { "IS", WiFiCountryIS }, - { "IT", WiFiCountryIT }, - { "JP", WiFiCountryJP }, - { "KR", WiFiCountryKR }, - { "LI", WiFiCountryLI }, - { "LT", WiFiCountryLT }, - { "LU", WiFiCountryLU }, - { "LV", WiFiCountryLV }, - { "MT", WiFiCountryMT }, - { "MX", WiFiCountryMX }, - { "NL", WiFiCountryNL }, - { "NO", WiFiCountryNO }, - { "NZ", WiFiCountryNZ }, - { "PL", WiFiCountryPL }, - { "PT", WiFiCountryPT }, - { "RO", WiFiCountryRO }, - { "SE", WiFiCountrySE }, - { "SI", WiFiCountrySI }, - { "SK", WiFiCountrySK }, - { "TW", WiFiCountryTW }, - { "US", WiFiCountryUS }, + { "01", WiFiCountry01 }, { "AT", WiFiCountryAT }, { "AU", WiFiCountryAU }, { "BE", WiFiCountryBE }, { "BG", WiFiCountryBG }, + { "BR", WiFiCountryBR }, { "CA", WiFiCountryCA }, { "CH", WiFiCountryCH }, { "CN", WiFiCountryCN }, { "CY", WiFiCountryCY }, + { "CZ", WiFiCountryCZ }, { "DE", WiFiCountryDE }, { "DK", WiFiCountryDK }, { "EE", WiFiCountryEE }, { "ES", WiFiCountryES }, + { "FI", WiFiCountryFI }, { "FR", WiFiCountryFR }, { "GB", WiFiCountryGB }, { "GR", WiFiCountryGR }, { "HK", WiFiCountryHK }, + { "HR", WiFiCountryHR }, { "HU", WiFiCountryHU }, { "IE", WiFiCountryIE }, { "IN", WiFiCountryIN }, { "IS", WiFiCountryIS }, + { "IT", WiFiCountryIT }, { "JP", WiFiCountryJP }, { "KR", WiFiCountryKR }, { "LI", WiFiCountryLI }, { "LT", WiFiCountryLT }, + { "LU", WiFiCountryLU }, { "LV", WiFiCountryLV }, { "MT", WiFiCountryMT }, { "MX", WiFiCountryMX }, { "NL", WiFiCountryNL }, + { "NO", WiFiCountryNO }, { "NZ", WiFiCountryNZ }, { "PL", WiFiCountryPL }, { "PT", WiFiCountryPT }, { "RO", WiFiCountryRO }, + { "SE", WiFiCountrySE }, { "SI", WiFiCountrySI }, { "SK", WiFiCountrySK }, { "TW", WiFiCountryTW }, { "US", WiFiCountryUS }, }; EnumSetting* wifi_mode; @@ -267,13 +231,16 @@ namespace WebUI { case WIFI_AP: print_mac(out, "Current WiFi Mode: AP", WiFi.softAPmacAddress()); - wifi_config_t conf; + wifi_config_t conf; wifi_country_t country; esp_wifi_get_config(WIFI_IF_AP, &conf); esp_wifi_get_country(&country); log_to(out, "SSID: ", (const char*)conf.ap.ssid); log_to(out, "Visible: ", (conf.ap.ssid_hidden == 0 ? "Yes" : "No")); - log_to(out, "Radio country set: ", country.cc << " (channels " << country.schan << "-" << (country.schan+country.nchan-1) << ", max power " << country.max_tx_power << "dBm)"); + log_to(out, + "Radio country set: ", + country.cc << " (channels " << country.schan << "-" << (country.schan + country.nchan - 1) << ", max power " + << country.max_tx_power << "dBm)"); const char* mode; switch (conf.ap.authmode) { @@ -372,8 +339,7 @@ namespace WebUI { (bool (*)(char*))WiFiConfig::isPasswordValid); wifi_ap_ssid = new StringSetting( "AP SSID", WEBSET, WA, "ESP105", "AP/SSID", DEFAULT_AP_SSID, MIN_SSID_LENGTH, MAX_SSID_LENGTH, (bool (*)(char*))WiFiConfig::isSSIDValid); - wifi_ap_country = new EnumSetting( - "AP regulatory domain", WEBSET, WA, NULL, "AP/Country", WiFiCountry01, &wifiContryOptions, NULL); + wifi_ap_country = new EnumSetting("AP regulatory domain", WEBSET, WA, NULL, "AP/Country", WiFiCountry01, &wifiContryOptions, NULL); wifi_sta_netmask = new IPaddrSetting("Station Static Mask", WEBSET, WA, NULL, "Sta/Netmask", DEFAULT_STA_MK, NULL); wifi_sta_gateway = new IPaddrSetting("Station Static Gateway", WEBSET, WA, NULL, "Sta/Gateway", DEFAULT_STA_GW, NULL); wifi_sta_ip = new IPaddrSetting("Station Static IP", WEBSET, WA, NULL, "Sta/IP", DEFAULT_STA_IP, NULL); @@ -701,7 +667,7 @@ namespace WebUI { WiFi.enableSTA(false); WiFi.mode(WIFI_AP); - const char *country = wifi_ap_country->getStringValue(); + const char* country = wifi_ap_country->getStringValue(); if (ESP_OK != esp_wifi_set_country_code(country, true)) { log_error("failed to set Wifi regulatory domain to " << country); } @@ -872,7 +838,7 @@ namespace WebUI { default: for (int i = 0; i < n; ++i) { j.begin_object(); - j.member("SSID", WiFi.SSID(i)); + j.member("SSID", WiFi.SSID(i).c_str()); j.member("SIGNAL", wifi_config.getSignal(WiFi.RSSI(i))); j.member("IS_PROTECTED", WiFi.encryptionType(i) != WIFI_AUTH_OPEN); // j->member("IS_PROTECTED", WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "0" : "1"); From 3c2a12f6a0d1a15e171d1f7976a1ef7406998bbb Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 14:44:19 -1000 Subject: [PATCH 08/51] String -> std::string in FileStream --- FluidNC/src/Configuration/JsonGenerator.cpp | 6 +- FluidNC/src/FileStream.cpp | 4 +- FluidNC/src/FileStream.h | 14 +-- FluidNC/src/WebUI/JSONEncoder.h | 3 + FluidNC/src/WebUI/WebServer.cpp | 95 ++++++++++++--------- FluidNC/src/WebUI/WebServer.h | 4 +- 6 files changed, 73 insertions(+), 53 deletions(-) diff --git a/FluidNC/src/Configuration/JsonGenerator.cpp b/FluidNC/src/Configuration/JsonGenerator.cpp index 3d345a475..408ef4b72 100644 --- a/FluidNC/src/Configuration/JsonGenerator.cpp +++ b/FluidNC/src/Configuration/JsonGenerator.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include namespace Configuration { JsonGenerator::JsonGenerator(WebUI::JSONencoder& encoder) : _encoder(encoder) { @@ -90,7 +92,9 @@ namespace Configuration { } else if (value < -999999.999f) { value = -999999.999f; } - _encoder.begin_webui(_currentPath, _currentPath, "R", String(value, 3).c_str()); + std::ostringstream fstr; + fstr << std::fixed << std::setprecision(3) << value; + _encoder.begin_webui(_currentPath, _currentPath, "R", fstr.str()); _encoder.end_object(); leave(); } diff --git a/FluidNC/src/FileStream.cpp b/FluidNC/src/FileStream.cpp index 3cb6e2a29..4d5cfcbed 100644 --- a/FluidNC/src/FileStream.cpp +++ b/FluidNC/src/FileStream.cpp @@ -5,11 +5,11 @@ #include "Machine/MachineConfig.h" // config-> #include "Driver/localfs.h" -String FileStream::path() { +std::string FileStream::path() { return _fpath.c_str(); } -String FileStream::name() { +std::string FileStream::name() { return path(); } diff --git a/FluidNC/src/FileStream.h b/FluidNC/src/FileStream.h index 8962f4169..01559bafd 100644 --- a/FluidNC/src/FileStream.h +++ b/FluidNC/src/FileStream.h @@ -26,18 +26,18 @@ class FileStream : public Channel { public: FileStream() = default; - FileStream(String filename, const char* mode, const char* defaultFs = "") : FileStream(filename.c_str(), mode, defaultFs) {} + FileStream(std::string filename, const char* mode, const char* defaultFs = "") : FileStream(filename.c_str(), mode, defaultFs) {} FileStream(const char* filename, const char* mode, const char* defaultFs = ""); FileStream(FluidPath fpath, const char* mode); FluidPath fpath() { return _fpath; } - String path(); - String name(); - int available() override; - int read() override; - int peek() override; - void flush() override; + std::string path(); + std::string name(); + int available() override; + int read() override; + int peek() override; + void flush() override; size_t readBytes(char* buffer, size_t length) { return read((uint8_t*)buffer, length); } diff --git a/FluidNC/src/WebUI/JSONEncoder.h b/FluidNC/src/WebUI/JSONEncoder.h index cc4a059cd..8d80a8330 100644 --- a/FluidNC/src/WebUI/JSONEncoder.h +++ b/FluidNC/src/WebUI/JSONEncoder.h @@ -83,6 +83,9 @@ namespace WebUI { // S => 0 .. 255 // A => 7 .. 15 (0.0.0.0 .. 255.255.255.255) // I => 0 .. 2^31-1 + void begin_webui(const char* brief, const char* full, const char* type, const std::string val) { + begin_webui(brief, full, type, val.c_str()); + } void begin_webui(const char* brief, const char* full, const char* type, const char* val); void begin_webui(const char* brief, const char* full, const char* type, const int val); void begin_webui(const char* brief, const char* full, const char* type, const char* val, int min, int max); diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 437dc47ea..d5ed04ce5 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -239,7 +239,7 @@ namespace WebUI { } // Send a file, either the specified path or path.gz - bool Web_Server::streamFile(String path, bool download) { + bool Web_Server::myStreamFile(const char* path, bool download) { // If you load or reload WebUI while a program is running, there is a high // risk of stalling the motion because serving a file from // the local FLASH filesystem takes away a lot of CPU cycles. If we get @@ -252,19 +252,34 @@ namespace WebUI { return true; } + bool isGzip = false; FileStream* file; try { file = new FileStream(path, "r", ""); } catch (const Error err) { try { - file = new FileStream(path + ".gz", "r", ""); + std::string spath(path); + file = new FileStream(spath + ".gz", "r", ""); + isGzip = true; } catch (const Error err) { return false; } } if (download) { _webserver->sendHeader("Content-Disposition", "attachment"); } - _webserver->streamFile(*file, getContentType(path)); + log_debug("path " << path << " CT " << getContentType(path)); + _webserver->setContentLength(file->size()); + if (isGzip) { + _webserver->sendHeader("Content-Encoding", "gzip"); + } + _webserver->send(200, getContentType(path), ""); + + // This depends on the fact that FileStream inherits from Stream + // The Arduino implementation of WiFiClient::write(Stream*) just + // reads repetitively from the stream in 1360-byte chunks and + // sends the data over the TCP socket. so nothing special. + _webserver->client().write(*file); + delete file; return true; } @@ -303,7 +318,7 @@ namespace WebUI { void Web_Server::handle_root() { if (!(_webserver->hasArg("forcefallback") && _webserver->arg("forcefallback") == "yes")) { - if (streamFile("/index.html")) { + if (myStreamFile("/index.html")) { return; } } @@ -331,7 +346,7 @@ namespace WebUI { } // Download a file. The true forces a download instead of displaying the file - if (streamFile(path, true)) { + if (myStreamFile(path.c_str(), true)) { return; } @@ -342,7 +357,7 @@ namespace WebUI { // This lets the user customize the not-found page by // putting a "404.htm" file on the local filesystem - if (streamFile("/404.htm")) { + if (myStreamFile("/404.htm")) { return; } @@ -1154,41 +1169,39 @@ namespace WebUI { } } - //helper to extract content type from file extension - //Check what is the content tye according extension file - String Web_Server::getContentType(String filename) { - String file_name = filename; - file_name.toLowerCase(); - if (filename.endsWith(".htm")) { - return "text/html"; - } else if (file_name.endsWith(".html")) { - return "text/html"; - } else if (file_name.endsWith(".css")) { - return "text/css"; - } else if (file_name.endsWith(".js")) { - return "application/javascript"; - } else if (file_name.endsWith(".png")) { - return "image/png"; - } else if (file_name.endsWith(".gif")) { - return "image/gif"; - } else if (file_name.endsWith(".jpeg")) { - return "image/jpeg"; - } else if (file_name.endsWith(".jpg")) { - return "image/jpeg"; - } else if (file_name.endsWith(".ico")) { - return "image/x-icon"; - } else if (file_name.endsWith(".xml")) { - return "text/xml"; - } else if (file_name.endsWith(".pdf")) { - return "application/x-pdf"; - } else if (file_name.endsWith(".zip")) { - return "application/x-zip"; - } else if (file_name.endsWith(".gz")) { - return "application/x-gzip"; - } else if (file_name.endsWith(".txt")) { - return "text/plain"; - } - return "application/octet-stream"; + //Convert file extension to content type + struct mime_type { + const char* suffix; + const char* mime_type; + } mime_types[] = { + { ".htm", "text/html" }, { ".html", "text/html" }, { ".css", "text/css" }, { ".js", "application/javascript" }, + { ".htm", "text/html" }, { ".png", "image/png" }, { ".gif", "image/gif" }, { ".jpeg", "image/jpeg" }, + { ".jpg", "image/jpeg" }, { ".ico", "image/x-icon" }, { ".xml", "text/xml" }, { ".pdf", "application/x-pdf" }, + { ".zip", "application/x-zip" }, { ".gz", "application/x-gzip" }, { ".txt", "text/plain" }, { "", "application/octet-stream" } + }; + static bool endsWithCI(const char* suffix, const char* test) { + size_t slen = strlen(suffix); + size_t tlen = strlen(test); + if (slen > tlen) { + return false; + } + const char* s = suffix + slen; + const char* t = test + tlen; + while (--s != s) { + if (tolower(*s) != tolower(*--t)) { + return false; + } + } + return true; + } + const char* Web_Server::getContentType(const char* filename) { + mime_type* m; + for (m = mime_types; *(m->suffix) != '\0'; ++m) { + if (endsWithCI(m->suffix, filename)) { + return m->mime_type; + } + } + return m->mime_type; } //check authentification diff --git a/FluidNC/src/WebUI/WebServer.h b/FluidNC/src/WebUI/WebServer.h index 2eabb236b..839a434fb 100644 --- a/FluidNC/src/WebUI/WebServer.h +++ b/FluidNC/src/WebUI/WebServer.h @@ -62,7 +62,7 @@ namespace WebUI { static UploadStatus _upload_status; static FileStream* _uploadFile; - static String getContentType(String filename); + static const char* getContentType(const char* filename); static AuthenticationLevel is_authenticated(); # ifdef ENABLE_AUTHENTICATION @@ -89,7 +89,7 @@ namespace WebUI { static void handleUpdate(); static void WebUpdateUpload(); - static bool streamFile(String path, bool download = false); + static bool myStreamFile(const char* path, bool download = false); static void pushError(int code, const char* st, bool web_error = 500, uint16_t timeout = 1000); From 93edc864a6eb846950db2118bd13ecc690caae13 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 15:03:55 -1000 Subject: [PATCH 09/51] String -> std::string misc --- FluidNC/src/Configuration/Tokenizer.cpp | 4 ++-- FluidNC/src/Limits.cpp | 5 ++--- FluidNC/src/Machine/Axes.cpp | 12 ++++++------ FluidNC/src/Machine/Axes.h | 6 +++--- FluidNC/src/Machine/EventPin.h | 2 +- FluidNC/src/Machine/LimitPin.cpp | 6 ++++-- FluidNC/src/Pin.h | 3 ++- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/FluidNC/src/Configuration/Tokenizer.cpp b/FluidNC/src/Configuration/Tokenizer.cpp index a4105602e..a75defcd2 100644 --- a/FluidNC/src/Configuration/Tokenizer.cpp +++ b/FluidNC/src/Configuration/Tokenizer.cpp @@ -93,8 +93,8 @@ namespace Configuration { } if (Current() != ':') { - String err = "Key "; - err += StringRange(token_.keyStart_, token_.keyEnd_).str(); + std::string err = "Key "; + err += StringRange(token_.keyStart_, token_.keyEnd_).str().c_str(); err += "must be followed by ':'"; ParseError(err.c_str()); } diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index 3a471a481..731ead8db 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -84,8 +84,7 @@ void limits_soft_check(float* cartesian) { for (int axis = 0; axis < n_axis; axis++) { if (axes->_axis[axis]->_softLimits && (cartesian[axis] < limitsMinPosition(axis) || cartesian[axis] > limitsMaxPosition(axis))) { - String axis_letter = String(Machine::Axes::_names[axis]); - log_info("Soft limit on " << axis_letter << " target:" << cartesian[axis]); + log_info("Soft limit on " << Machine::Axes::_names[axis] << " target:" << cartesian[axis]); limit_error = true; } } @@ -121,7 +120,7 @@ void limitCheckTask(void* pvParameters) { vTaskDelay(config->_softwareDebounceMs / portTICK_PERIOD_MS); // delay a while auto switch_state = limits_get_state(); if (switch_state) { - log_debug("Limit Switch State " << String(switch_state, HEX)); + log_debug("Limit Switch State " << to_hex(switch_state)); mc_reset(); // Initiate system kill. rtAlarm = ExecAlarm::HardLimit; // Indicate hard limit critical event } diff --git a/FluidNC/src/Machine/Axes.cpp b/FluidNC/src/Machine/Axes.cpp index d502153fe..4e94efd7b 100644 --- a/FluidNC/src/Machine/Axes.cpp +++ b/FluidNC/src/Machine/Axes.cpp @@ -227,9 +227,9 @@ namespace Machine { } } - String Axes::maskToNames(AxisMask mask) { - String retval = ""; - auto n_axis = _numberAxis; + std::string Axes::maskToNames(AxisMask mask) { + std::string retval(""); + auto n_axis = _numberAxis; for (int axis = 0; axis < n_axis; axis++) { if (bitnum_is_true(mask, axis)) { retval += _names[axis]; @@ -237,9 +237,9 @@ namespace Machine { } return retval; } - String Axes::motorMaskToNames(MotorMask mask) { - String retval = ""; - auto n_axis = _numberAxis; + std::string Axes::motorMaskToNames(MotorMask mask) { + std::string retval(""); + auto n_axis = _numberAxis; for (int axis = 0; axis < n_axis; axis++) { if (bitnum_is_true(mask, axis)) { retval += " "; diff --git a/FluidNC/src/Machine/Axes.h b/FluidNC/src/Machine/Axes.h index d7991b24f..dfbd7005f 100644 --- a/FluidNC/src/Machine/Axes.h +++ b/FluidNC/src/Machine/Axes.h @@ -71,10 +71,10 @@ namespace Machine { void unstep(); void config_motors(); - String maskToNames(AxisMask mask); - bool namesToMask(const char* names, AxisMask& mask); + std::string maskToNames(AxisMask mask); + bool namesToMask(const char* names, AxisMask& mask); - String motorMaskToNames(MotorMask mask); + std::string motorMaskToNames(MotorMask mask); // Configuration helpers: void group(Configuration::HandlerBase& handler) override; diff --git a/FluidNC/src/Machine/EventPin.h b/FluidNC/src/Machine/EventPin.h index 696502d1b..709237bb9 100644 --- a/FluidNC/src/Machine/EventPin.h +++ b/FluidNC/src/Machine/EventPin.h @@ -16,7 +16,7 @@ namespace Machine { static bool inactive(EventPin* pin); public: - String _legend; // The name that appears in init() messages and the name of the configuration item + std::string _legend; // The name that appears in init() messages and the name of the configuration item EventPin(Event* event, const char* legend, Pin* pin); diff --git a/FluidNC/src/Machine/LimitPin.cpp b/FluidNC/src/Machine/LimitPin.cpp index 58be4cb36..c4a10008b 100644 --- a/FluidNC/src/Machine/LimitPin.cpp +++ b/FluidNC/src/Machine/LimitPin.cpp @@ -9,7 +9,7 @@ namespace Machine { LimitPin::LimitPin(Pin& pin, int axis, int motor, int direction, bool& pHardLimits, bool& pLimited) : EventPin(&limitEvent, "Limit", &pin), _axis(axis), _motorNum(motor), _value(false), _pHardLimits(pHardLimits), _pLimited(pLimited) { - String sDir; + const char* sDir; // Select one or two bitmask variables to receive the switch data switch (direction) { case 1: @@ -38,7 +38,9 @@ namespace Machine { // The bitmap looks like CBAZYX..cbazyx where motor0 motors are in the lower bits _bitmask = 1 << Axes::motor_bit(axis, motor); _legend = config->_axes->motorMaskToNames(_bitmask); - _legend += " " + sDir + " Limit"; + _legend += " "; + _legend += sDir; + _legend += " Limit"; } void LimitPin::init() { diff --git a/FluidNC/src/Pin.h b/FluidNC/src/Pin.h index f60a8cf7a..b93171452 100644 --- a/FluidNC/src/Pin.h +++ b/FluidNC/src/Pin.h @@ -10,6 +10,7 @@ #include // IRAM_ATTR #include +#include #include #include #include "Assert.h" @@ -161,7 +162,7 @@ class Pin { inline String name() const { return _detail->toString(); } void report(const char* legend); - void report(String legend) { report(legend.c_str()); } + void report(std::string legend) { report(legend.c_str()); } inline void swap(Pin& o) { std::swap(o._detail, _detail); } From 02e907203b39e564dc4d1face4bf70298c90ccda Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 15:09:29 -1000 Subject: [PATCH 10/51] String -> std::string in debug messages --- FluidNC/src/Motors/Dynamixel2.cpp | 4 ++-- FluidNC/src/Motors/TMC5160Driver.cpp | 18 ++++++++---------- FluidNC/src/Motors/TrinamicBase.cpp | 2 +- FluidNC/src/Motors/TrinamicSpiDriver.cpp | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.cpp b/FluidNC/src/Motors/Dynamixel2.cpp index b1f21e0fd..0c368f0e0 100644 --- a/FluidNC/src/Motors/Dynamixel2.cpp +++ b/FluidNC/src/Motors/Dynamixel2.cpp @@ -95,9 +95,9 @@ namespace MotorDrivers { if (len == PING_RSP_LEN) { uint16_t model_num = _dxl_rx_message[10] << 8 | _dxl_rx_message[9]; if (model_num == 1060) { - log_info("Axis ping reply " << axisName() << " Model XL430-W250 F/W Rev " << String(_dxl_rx_message[11], HEX)); + log_info("Axis ping reply " << axisName() << " Model XL430-W250 F/W Rev " << to_hex(_dxl_rx_message[11])); } else { - log_info("Axis ping reply " << axisName() << " M/N " << model_num << " F/W Rev " << String(_dxl_rx_message[11], HEX)); + log_info("Axis ping reply " << axisName() << " M/N " << model_num << " F/W Rev " << to_hex(_dxl_rx_message[11])); } } else { log_warn(" Ping failed"); diff --git a/FluidNC/src/Motors/TMC5160Driver.cpp b/FluidNC/src/Motors/TMC5160Driver.cpp index 6da247c06..c61a4d10f 100644 --- a/FluidNC/src/Motors/TMC5160Driver.cpp +++ b/FluidNC/src/Motors/TMC5160Driver.cpp @@ -29,9 +29,7 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC5160Driver::test() { - return checkVersion(0x30, tmc5160->version()); - } + bool TMC5160Driver::test() { return checkVersion(0x30, tmc5160->version()); } void TMC5160Driver::set_registers(bool isHoming) { if (_has_errors) { @@ -82,13 +80,13 @@ namespace MotorDrivers { } } // dump the registers. This is helpful for people migrating to the Pro version - log_debug("CHOPCONF: 0x" << String(tmc5160->CHOPCONF(), HEX)); - log_debug("COOLCONF: 0x" << String(tmc5160->COOLCONF(), HEX)); - log_debug("THIGH: 0x" << String(tmc5160->THIGH(), HEX)); - log_debug("TCOOLTHRS: 0x" << String(tmc5160->TCOOLTHRS(), HEX)); - log_debug("GCONF: 0x" << String(tmc5160->GCONF(), HEX)); - log_debug("PWMCONF: 0x" << String(tmc5160->PWMCONF(), HEX)); - log_debug("IHOLD_IRUN: 0x" << String(tmc5160->IHOLD_IRUN(), HEX)); + log_debug("CHOPCONF: 0x" << to_hex(tmc5160->CHOPCONF())); + log_debug("COOLCONF: 0x" << to_hex(tmc5160->COOLCONF())); + log_debug("THIGH: 0x" << to_hex(tmc5160->THIGH())); + log_debug("TCOOLTHRS: 0x" << to_hex(tmc5160->TCOOLTHRS())); + log_debug("GCONF: 0x" << to_hex(tmc5160->GCONF())); + log_debug("PWMCONF: 0x" << to_hex(tmc5160->PWMCONF())); + log_debug("IHOLD_IRUN: 0x" << to_hex(tmc5160->IHOLD_IRUN())); } // Report diagnostic and tuning info diff --git a/FluidNC/src/Motors/TrinamicBase.cpp b/FluidNC/src/Motors/TrinamicBase.cpp index a4202a56d..4121ce2f8 100644 --- a/FluidNC/src/Motors/TrinamicBase.cpp +++ b/FluidNC/src/Motors/TrinamicBase.cpp @@ -122,7 +122,7 @@ namespace MotorDrivers { bool TrinamicBase::checkVersion(uint8_t expected, uint8_t got) { if (expected != got) { - log_error(axisName() << " TMC driver not detected - expected 0x" << String(expected, 16) << " got 0x" << String(got, 16)); + log_error(axisName() << " TMC driver not detected - expected 0x" << to_hex(expected) << " got 0x" << to_hex(got)); return false; } log_info(axisName() << " driver test passed"); diff --git a/FluidNC/src/Motors/TrinamicSpiDriver.cpp b/FluidNC/src/Motors/TrinamicSpiDriver.cpp index df4ffcd29..233ea80ed 100644 --- a/FluidNC/src/Motors/TrinamicSpiDriver.cpp +++ b/FluidNC/src/Motors/TrinamicSpiDriver.cpp @@ -44,7 +44,7 @@ namespace MotorDrivers { // Display the stepper library version message once, before the first // TMC config message. Link is NULL for the first TMC instance. if (!link) { - log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); + log_debug("TMCStepper Library Ver. 0x" << to_hex(TMCSTEPPER_VERSION)); } config_message(); From f9e8017c3431b8a79817dfb039f0629233646685 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 19:01:53 -1000 Subject: [PATCH 11/51] String -> std::string more misc --- FluidNC/src/Machine/Homing.cpp | 12 ++++++------ FluidNC/src/Machine/WifiConfig.h | 2 +- FluidNC/src/Main.h | 2 -- FluidNC/src/Motors/MotorDriver.cpp | 4 ++-- FluidNC/src/Motors/MotorDriver.h | 2 +- FluidNC/src/NutsBolts.cpp | 22 ++++++++++++++++------ FluidNC/src/NutsBolts.h | 3 +-- FluidNC/src/WebUI/WebServer.cpp | 4 ++-- 8 files changed, 29 insertions(+), 22 deletions(-) diff --git a/FluidNC/src/Machine/Homing.cpp b/FluidNC/src/Machine/Homing.cpp index fa985ccbd..d4e00ec4e 100644 --- a/FluidNC/src/Machine/Homing.cpp +++ b/FluidNC/src/Machine/Homing.cpp @@ -67,9 +67,7 @@ namespace Machine { protocol_send_event(&cycleStartEvent); } - static MotorMask limited() { - return Machine::Axes::posLimitMask | Machine::Axes::negLimitMask; - } + static MotorMask limited() { return Machine::Axes::posLimitMask | Machine::Axes::negLimitMask; } void Homing::cycleStop() { log_debug("CycleStop " << phaseName(_phase)); @@ -406,9 +404,10 @@ namespace Machine { axes->set_homing_mode(_cycleAxes, false); // tell motors homing is done } - static String axisNames(AxisMask axisMask) { - String retval = ""; - auto n_axis = config->_axes->_numberAxis; +#if 0 + static std::string axisNames(AxisMask axisMask) { + std::string retval = ""; + auto n_axis = config->_axes->_numberAxis; for (size_t axis = 0; axis < n_axis; axis++) { if (bitnum_is_true(axisMask, axis)) { retval += Machine::Axes::_names[axis]; @@ -416,6 +415,7 @@ namespace Machine { } return retval; } +#endif // Construct a list of homing cycles to run. If there are any // such cycles, enter Homing state and begin running the first diff --git a/FluidNC/src/Machine/WifiConfig.h b/FluidNC/src/Machine/WifiConfig.h index ee4a4593b..546bb86ae 100644 --- a/FluidNC/src/Machine/WifiConfig.h +++ b/FluidNC/src/Machine/WifiConfig.h @@ -16,7 +16,7 @@ namespace Machine { WifiConfig() : _ipAddress(10, 0, 0, 1), _gateway(10, 0, 0, 1), _netmask(255, 255, 0, 0) {} - String _ssid = "FluidNC"; + std::string _ssid = "FluidNC"; // Passwords don't belong in a YAML! // String _password = "12345678"; diff --git a/FluidNC/src/Main.h b/FluidNC/src/Main.h index 02a0fc9bd..c75e0f919 100644 --- a/FluidNC/src/Main.h +++ b/FluidNC/src/Main.h @@ -3,7 +3,5 @@ #pragma once -#include - void main_init(); void run_once(); diff --git a/FluidNC/src/Motors/MotorDriver.cpp b/FluidNC/src/Motors/MotorDriver.cpp index 0a6bdf32f..47b5aaf37 100644 --- a/FluidNC/src/Motors/MotorDriver.cpp +++ b/FluidNC/src/Motors/MotorDriver.cpp @@ -26,8 +26,8 @@ #include "../Limits.h" // limitsMinPosition namespace MotorDrivers { - String MotorDriver::axisName() const { - return String(config->_axes->axisName(axis_index())) + (dual_axis_index() ? "2" : "") + " Axis"; + std::string MotorDriver::axisName() const { + return std::string(1, config->_axes->axisName(axis_index())) + (dual_axis_index() ? "2" : "") + " Axis"; } void MotorDriver::debug_message() {} diff --git a/FluidNC/src/Motors/MotorDriver.h b/FluidNC/src/Motors/MotorDriver.h index 159ef6704..d2e3558ef 100644 --- a/FluidNC/src/Motors/MotorDriver.h +++ b/FluidNC/src/Motors/MotorDriver.h @@ -102,7 +102,7 @@ namespace MotorDrivers { virtual ~MotorDriver() {} protected: - String axisName() const; + std::string axisName() const; // config_message(), called from init(), displays a message describing // the motor configuration - pins and other motor-specific items diff --git a/FluidNC/src/NutsBolts.cpp b/FluidNC/src/NutsBolts.cpp index 2e16090e2..19d6bfd12 100644 --- a/FluidNC/src/NutsBolts.cpp +++ b/FluidNC/src/NutsBolts.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include const int MAX_INT_DIGITS = 8; // Maximum number of digits in int32 (and float) @@ -223,26 +225,34 @@ const char* to_hex(uint32_t n) { return hexstr; } -String formatBytes(uint64_t bytes) { +std::string formatBytes(uint64_t bytes) { if (bytes < 1024) { - return String((uint16_t)bytes) + " B"; + return std::to_string((uint16_t)bytes) + " B"; } float b = bytes; b /= 1024; if (b < 1024) { - return String(b, 2) + " KB"; + std::ostringstream msg; + msg << std::fixed << std::setprecision(2) << b << " KB"; + return msg.str(); } b /= 1024; if (b < 1024) { - return String(b, 2) + " MB"; + std::ostringstream msg; + msg << std::fixed << std::setprecision(2) << b << " MB"; + return msg.str(); } b /= 1024; if (b < 1024) { - return String(b, 2) + " GB"; + std::ostringstream msg; + msg << std::fixed << std::setprecision(2) << b << " TB"; + return msg.str(); } b /= 1024; if (b > 99999) { b = 99999; } - return String(b, 2) + " TB"; + std::ostringstream msg; + msg << std::fixed << std::setprecision(2) << b << " GB"; + return msg.str(); } diff --git a/FluidNC/src/NutsBolts.h b/FluidNC/src/NutsBolts.h index 1aea1970d..510064dc9 100644 --- a/FluidNC/src/NutsBolts.h +++ b/FluidNC/src/NutsBolts.h @@ -6,7 +6,6 @@ // #define false 0 // #define true 1 -#include #include #include #include @@ -164,4 +163,4 @@ bool constrain_with_message(T& value, T min, T max, const char* name = "") { bool multiple_bits_set(uint32_t val); -String formatBytes(uint64_t bytes); +std::string formatBytes(uint64_t bytes); diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index d5ed04ce5..6442a0117 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -974,8 +974,8 @@ namespace WebUI { usedspace = totalspace - space.available; j.member("path", path.c_str()); - j.member("total", formatBytes(totalspace).c_str()); - j.member("used", formatBytes(usedspace + 1).c_str()); + j.member("total", formatBytes(totalspace)); + j.member("used", formatBytes(usedspace + 1)); uint32_t percent = totalspace ? (usedspace * 100) / totalspace : 100; From ab8e2c60584a2d0c254226ac15ecb5578738850c Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 19:02:09 -1000 Subject: [PATCH 12/51] String -> std::string in OLED --- FluidNC/src/OLED.cpp | 51 +++++++++++++++++++++----------------------- FluidNC/src/OLED.h | 17 +++++---------- 2 files changed, 29 insertions(+), 39 deletions(-) diff --git a/FluidNC/src/OLED.cpp b/FluidNC/src/OLED.cpp index c23aa414a..0d226523d 100644 --- a/FluidNC/src/OLED.cpp +++ b/FluidNC/src/OLED.cpp @@ -2,13 +2,13 @@ #include "Machine/MachineConfig.h" -void OLED::show(Layout& layout, const String& msg) { +void OLED::show(Layout& layout, const char* msg) { if (_width < layout._width_required) { return; } _oled->setTextAlignment(layout._align); _oled->setFont(layout._font); - _oled->drawString(layout._x, layout._y, msg); + _oled->drawString(layout._x, layout._y, String(msg)); } OLED::Layout OLED::bannerLayout128 = { 0, 0, 0, ArialMT_Plain_24, TEXT_ALIGN_CENTER }; @@ -118,7 +118,7 @@ void OLED::show_file() { return; } if (_width == 128) { - show(percentLayout128, String(pct) + '%'); + show(percentLayout128, std::to_string(pct) + '%'); _ticker += "-"; if (_ticker.length() >= 12) { @@ -130,7 +130,7 @@ void OLED::show_file() { _oled->drawProgressBar(0, 45, 120, 10, pct); } else { - show(percentLayout64, String(pct) + '%'); + show(percentLayout64, std::to_string(pct) + '%'); } } void OLED::show_dro(const float* axes, bool isMpos, bool* limits) { @@ -153,16 +153,16 @@ void OLED::show_dro(const float* axes, bool isMpos, bool* limits) { for (uint8_t axis = X_AXIS; axis < n_axis; axis++) { oled_y_pos = ((_height == 64) ? 24 : 17) + (axis * 10); - String axis_letter = String(Machine::Axes::_names[axis]); + std::string axis_msg(1, Machine::Axes::_names[axis]); if (_width == 128) { - axis_letter += ":"; + axis_msg += ":"; } else { // For small displays there isn't room for separate limit boxes // so we put it after the label - axis_letter += limits[axis] ? "L" : ":"; + axis_msg += limits[axis] ? "L" : ":"; } _oled->setTextAlignment(TEXT_ALIGN_LEFT); - _oled->drawString(0, oled_y_pos, axis_letter); + _oled->drawString(0, oled_y_pos, String(axis_msg.c_str())); _oled->setTextAlignment(TEXT_ALIGN_RIGHT); snprintf(axisVal, 20 - 1, "%.3f", axes[axis]); @@ -386,9 +386,8 @@ void OLED::parse_gcode_report() { // [MSG:INFO: Connecting to STA:SSID foo] void OLED::parse_STA() { - size_t start = strlen("[MSG:INFO: Connecting to STA SSID:"); - std::string ssid = _report.substr(start, _report.size() - start - 1); - _radio_info = String(ssid.c_str()); + size_t start = strlen("[MSG:INFO: Connecting to STA SSID:"); + _radio_info = _report.substr(start, _report.size() - start - 1); _oled->clear(); auto fh = font_height(ArialMT_Plain_10); @@ -398,9 +397,8 @@ void OLED::parse_STA() { // [MSG:INFO: Connected - IP is 192.168.68.134] void OLED::parse_IP() { - size_t start = _report.rfind(" ") + 1; - std::string ipaddr = _report.substr(start, _report.size() - start - 1); - _radio_addr = String(ipaddr.c_str()); + size_t start = _report.rfind(" ") + 1; + _radio_addr = _report.substr(start, _report.size() - start - 1); _oled->clear(); auto fh = font_height(ArialMT_Plain_10); @@ -412,15 +410,14 @@ void OLED::parse_IP() { // [MSG:INFO: AP SSID foo IP 192.168.68.134 mask foo channel foo] void OLED::parse_AP() { - size_t start = strlen("[MSG:INFO: AP SSID "); - size_t ssid_end = _report.rfind(" IP "); - size_t ip_end = _report.rfind(" mask "); - std::string ssid = _report.substr(start, ssid_end - start); - size_t ip_start = ssid_end + strlen(" IP "); - std::string ipaddr = _report.substr(ip_start, ip_end - ip_start); - _radio_info = "AP: "; - _radio_info += ssid.c_str(); - _radio_addr = String(ipaddr.c_str()); + size_t start = strlen("[MSG:INFO: AP SSID "); + size_t ssid_end = _report.rfind(" IP "); + size_t ip_end = _report.rfind(" mask "); + size_t ip_start = ssid_end + strlen(" IP "); + + _radio_info = "AP: "; + _radio_info += _report.substr(start, ssid_end - start); + _radio_addr = _report.substr(ip_start, ip_end - ip_start); _oled->clear(); auto fh = font_height(ArialMT_Plain_10); @@ -512,7 +509,7 @@ size_t OLED::char_width(char c, font_t font) { return (index < 0) ? 0 : xf->glyphs[index].width; } -void OLED::wrapped_draw_string(int16_t y, const String& s, font_t font) { +void OLED::wrapped_draw_string(int16_t y, const std::string& s, font_t font) { _oled->setFont(font); _oled->setTextAlignment(TEXT_ALIGN_LEFT); @@ -526,10 +523,10 @@ void OLED::wrapped_draw_string(int16_t y, const String& s, font_t font) { } } if (swidth < _width) { - _oled->drawString(0, y, s); + _oled->drawString(0, y, String(s.c_str())); } else { - _oled->drawString(0, y, s.substring(0, i)); - _oled->drawString(0, y + font_height(font) - 1, s.substring(i, slen)); + _oled->drawString(0, y, String(s.substr(0, i).c_str())); + _oled->drawString(0, y + font_height(font) - 1, String(s.substr(i, slen).c_str())); } } diff --git a/FluidNC/src/OLED.h b/FluidNC/src/OLED.h index 12aaa2bcd..c9937ba89 100644 --- a/FluidNC/src/OLED.h +++ b/FluidNC/src/OLED.h @@ -32,8 +32,8 @@ class OLED : public Channel, public Configuration::Configurable { private: std::string _report; - String _radio_info; - String _radio_addr; + std::string _radio_info; + std::string _radio_addr; std::string _state; std::string _filename; @@ -63,17 +63,10 @@ class OLED : public Channel, public Configuration::Configurable { void show_radio_info(); void draw_checkbox(int16_t x, int16_t y, int16_t width, int16_t height, bool checked); - void wrapped_draw_string(int16_t y, const String& s, font_t font); + void wrapped_draw_string(int16_t y, const std::string& s, font_t font); - void show(Layout& layout, const String& msg); - void show(Layout& layout, const char* msg) { - String s(msg); - show(layout, s); - } - void show(Layout& layout, const std::string& msg) { - String s(msg.c_str()); - show(layout, s); - } + void show(Layout& layout, const std::string& msg) { show(layout, msg.c_str()); } + void show(Layout& layout, const char* msg); uint8_t font_width(font_t font); uint8_t font_height(font_t font); From 6fdac4e488fbc21eb3ced55d55a243caac12792a Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 23 Mar 2023 21:55:59 -1000 Subject: [PATCH 13/51] String -> std::string even more misc --- FluidNC/src/FluidPath.h | 8 +- FluidNC/src/Motors/TrinamicUartDriver.cpp | 2 +- FluidNC/src/ProcessSettings.cpp | 2 +- FluidNC/src/Protocol.cpp | 1 - FluidNC/src/Report.cpp | 5 +- FluidNC/src/Report.h | 1 - FluidNC/src/Settings.cpp | 16 +-- FluidNC/src/Uart.cpp | 2 +- FluidNC/src/WebUI/Authentication.cpp | 6 +- FluidNC/src/WebUI/BTConfig.h | 25 ++-- FluidNC/src/WebUI/NotificationsService.cpp | 44 +++---- FluidNC/src/WebUI/NotificationsService.h | 1 - FluidNC/src/WebUI/WSChannel.cpp | 4 +- FluidNC/src/WebUI/WSChannel.h | 4 +- FluidNC/src/WebUI/WebServer.cpp | 142 +++++++++++---------- FluidNC/src/WebUI/WebServer.h | 9 +- FluidNC/src/WebUI/WebSettings.cpp | 10 +- FluidNC/src/WebUI/WifiConfig.cpp | 33 +++-- FluidNC/src/WebUI/WifiConfig.h | 2 - FluidNC/src/WebUI/WifiServices.cpp | 7 +- 20 files changed, 159 insertions(+), 165 deletions(-) diff --git a/FluidNC/src/FluidPath.h b/FluidNC/src/FluidPath.h index 706ab7a04..dc5aa8141 100644 --- a/FluidNC/src/FluidPath.h +++ b/FluidNC/src/FluidPath.h @@ -9,11 +9,11 @@ namespace stdfs = std::filesystem; class FluidPath : public stdfs::path { public: FluidPath(const char* name, const char* fs, std::error_code& ec) noexcept : FluidPath(name, fs, &ec) {} - FluidPath(String name, const char* fs, std::error_code& ec) noexcept : FluidPath(name.c_str(), fs, &ec) {} - // FluidPath(std::string name, std::error_code& ec) noexcept : FluidPath(name.c_str(), &ec) {} + // FluidPath(String name, const char* fs, std::error_code& ec) noexcept : FluidPath(name.c_str(), fs, &ec) {} + FluidPath(const std::string& name, const char* fs, std::error_code& ec) noexcept : FluidPath(name.c_str(), fs, &ec) {} FluidPath(const char* name, const char* fs) : FluidPath(name, fs, nullptr) {} - FluidPath(String name, const char* fs) : FluidPath(name.c_str(), fs) {} - // FluidPath(std::string name) : FluidPath(name.c_str()) {} + // FluidPath(String name, const char* fs) : FluidPath(name.c_str(), fs) {} + FluidPath(const std::string& name, const char* fs) : FluidPath(name.c_str(), fs) {} ~FluidPath(); diff --git a/FluidNC/src/Motors/TrinamicUartDriver.cpp b/FluidNC/src/Motors/TrinamicUartDriver.cpp index af4667f6b..5ae295fb2 100644 --- a/FluidNC/src/Motors/TrinamicUartDriver.cpp +++ b/FluidNC/src/Motors/TrinamicUartDriver.cpp @@ -44,7 +44,7 @@ namespace MotorDrivers { // Display the stepper library version message once, before the first // TMC config message. Link is NULL for the first TMC instance. if (!link) { - log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); + log_debug("TMCStepper Library Ver. 0x" << to_hex(TMCSTEPPER_VERSION)); } config_message(); diff --git a/FluidNC/src/ProcessSettings.cpp b/FluidNC/src/ProcessSettings.cpp index b8f614815..0fa05f133 100644 --- a/FluidNC/src/ProcessSettings.cpp +++ b/FluidNC/src/ProcessSettings.cpp @@ -580,7 +580,7 @@ static Error motor_control(const char* value, bool disable) { char axisName = axes->axisName(i); if (strchr(value, axisName) || strchr(value, tolower(axisName))) { - log_info((disable ? "Dis" : "En") << "abling " << String(axisName) << " motors"); + log_info((disable ? "Dis" : "En") << "abling " << axisName << " motors"); axes->set_disable(i, disable); } } diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index c1307452f..877356498 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -275,7 +275,6 @@ void protocol_main_loop() { #ifdef DEBUG_REPORT_ECHO_RAW_LINE_RECEIVED report_echo_line_received(activeLine, allChannels); #endif - display("GCODE", activeLine); Error status_code = execute_line(activeLine, *activeChannel, WebUI::AuthenticationLevel::LEVEL_GUEST); diff --git a/FluidNC/src/Report.cpp b/FluidNC/src/Report.cpp index c00a038fa..cc28272a4 100644 --- a/FluidNC/src/Report.cpp +++ b/FluidNC/src/Report.cpp @@ -223,9 +223,9 @@ void report_ngc_coord(CoordIndex coord, Channel& channel) { return; } // Persistent offsets G54 - G59, G28, and G30 - String name = coords[coord]->getName(); + std::string name(coords[coord]->getName()); name += ":"; - log_to(channel, "[", name.c_str() << report_util_axis_values(coords[coord]->get())); + log_to(channel, "[", name << report_util_axis_values(coords[coord]->get())); } void report_ngc_parameters(Channel& channel) { for (auto coord = CoordIndex::Begin; coord < CoordIndex::End; ++coord) { @@ -667,4 +667,3 @@ void reportTaskStackSize(UBaseType_t& saved) { } void WEAK_LINK display_init() {} -void WEAK_LINK display(const char* tag, String s) {} diff --git a/FluidNC/src/Report.h b/FluidNC/src/Report.h index d00fc69d4..35d8f2b26 100644 --- a/FluidNC/src/Report.h +++ b/FluidNC/src/Report.h @@ -93,6 +93,5 @@ extern const char* git_info; // Callout to custom code void display_init(); -void display(const char* tag, String s); extern bool readyNext; diff --git a/FluidNC/src/Settings.cpp b/FluidNC/src/Settings.cpp index 2b4ea96d7..b1b42cb3a 100644 --- a/FluidNC/src/Settings.cpp +++ b/FluidNC/src/Settings.cpp @@ -376,7 +376,7 @@ const char* EnumSetting::getStringValue() { } void EnumSetting::showList() { - String optList = ""; + std::string optList = ""; for (enum_opt_t::iterator it = _options->begin(); it != _options->end(); it++) { optList = optList + " " + it->first; } @@ -387,7 +387,7 @@ void EnumSetting::addWebui(WebUI::JSONencoder* j) { if (!getDescription()) { return; } - j->begin_webui(getName(), getName(), "B", String(get()).c_str()); + j->begin_webui(getName(), getName(), "B", get()); j->begin_array("O"); for (enum_opt_t::iterator it = _options->begin(); it != _options->end(); it++) { j->begin_object(); @@ -505,14 +505,14 @@ Error IPaddrSetting::setStringValue(char* s) { } const char* IPaddrSetting::getDefaultString() { - static String s; - s = IPAddress(_defaultValue).toString(); - return s.c_str(); + static char ipstr[50]; + strncpy(ipstr, IPAddress(_defaultValue).toString().c_str(), 50); + return ipstr; } const char* IPaddrSetting::getStringValue() { - static String s; - s = IPAddress(get()).toString(); - return s.c_str(); + static char ipstr[50]; + strncpy(ipstr, IPAddress(get()).toString().c_str(), 50); + return ipstr; } void IPaddrSetting::addWebui(WebUI::JSONencoder* j) { diff --git a/FluidNC/src/Uart.cpp b/FluidNC/src/Uart.cpp index 21cc42cd8..5e31104b3 100644 --- a/FluidNC/src/Uart.cpp +++ b/FluidNC/src/Uart.cpp @@ -49,7 +49,7 @@ void Uart::begin() { } begin(_baud, _dataBits, _stopBits, _parity); - config_message("UART", String(_uart_num, 10).c_str()); + config_message("UART", std::to_string(_uart_num).c_str()); } int Uart::read() { diff --git a/FluidNC/src/WebUI/Authentication.cpp b/FluidNC/src/WebUI/Authentication.cpp index b218078fd..4d2086a9f 100644 --- a/FluidNC/src/WebUI/Authentication.cpp +++ b/FluidNC/src/WebUI/Authentication.cpp @@ -12,9 +12,9 @@ namespace WebUI { StringSetting* admin_password; void remove_password(char* str, AuthenticationLevel& auth_level) { - String paramStr = String((const char*)str); - int pos = paramStr.indexOf("pwd="); - if (pos == -1) { + std::string paramStr(str); + size_t pos = paramStr.find("pwd="); + if (pos == std::string::npos) { return; } diff --git a/FluidNC/src/WebUI/BTConfig.h b/FluidNC/src/WebUI/BTConfig.h index 6a8e59269..3e030472e 100644 --- a/FluidNC/src/WebUI/BTConfig.h +++ b/FluidNC/src/WebUI/BTConfig.h @@ -23,7 +23,6 @@ namespace WebUI { # include "../Settings.h" // ENABLE_* # include "../lineedit.h" -# include # include const char* const DEFAULT_BT_NAME = "FluidNC"; @@ -62,9 +61,9 @@ namespace WebUI { private: static BTConfig* instance; // BT Callback does not support passing parameters. Sigh. - String _btclient = ""; - String _btname; - char _deviceAddrBuffer[18]; + std::string _btclient = ""; + std::string _btname; + char _deviceAddrBuffer[18]; static void my_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t* param); @@ -77,15 +76,15 @@ namespace WebUI { std::string info(); - static bool isBTnameValid(const char* hostname); - const String& BTname() const { return _btname; } - const String& client_name() const { return _btclient; } - const char* device_address(); - bool begin(); - void end(); - void handle(); - void reset_settings(); - bool isOn() const; + static bool isBTnameValid(const char* hostname); + const std::string& BTname() const { return _btname; } + const std::string& client_name() const { return _btclient; } + const char* device_address(); + bool begin(); + void end(); + void handle(); + void reset_settings(); + bool isOn() const; ~BTConfig(); }; diff --git a/FluidNC/src/WebUI/NotificationsService.cpp b/FluidNC/src/WebUI/NotificationsService.cpp index b2f85c3ec..c1a5a1e6c 100644 --- a/FluidNC/src/WebUI/NotificationsService.cpp +++ b/FluidNC/src/WebUI/NotificationsService.cpp @@ -134,11 +134,11 @@ namespace WebUI { bool Wait4Answer(WiFiClientSecure& client, const char* linetrigger, const char* expected_answer, uint32_t timeout) { if (client.connected()) { - String answer; - uint32_t start_time = millis(); + std::string answer; + uint32_t start_time = millis(); while (client.connected() && ((millis() - start_time) < timeout)) { - answer = client.readStringUntil('\n'); - if ((answer.indexOf(linetrigger) != -1) || (strlen(linetrigger) == 0)) { + answer = std::string(client.readStringUntil('\n').c_str()); + if ((answer.find(linetrigger) != std::string::npos) || (strlen(linetrigger) == 0)) { break; } delay_ms(10); @@ -146,11 +146,7 @@ namespace WebUI { if (strlen(expected_answer) == 0) { return true; } - if (answer.indexOf(expected_answer) == -1) { - return false; - } else { - return true; - } + return answer.find(expected_answer) != std::string::npos; } return false; } @@ -316,36 +312,38 @@ namespace WebUI { } //Email#serveraddress:port bool NotificationsService::getPortFromSettings() { - String tmp = notification_ts->get(); - int pos = tmp.lastIndexOf(':'); - if (pos == -1) { + std::string tmp(notification_ts->get()); + size_t pos = tmp.rfind(':'); + if (pos == std::string::npos) { return false; } - _port = tmp.substring(pos + 1).toInt(); - return _port > 0; + try { + _port = stoi(tmp.substr(pos + 1)); + } catch (...) { return false; } + return true; } //Email#serveraddress:port bool NotificationsService::getServerAddressFromSettings() { - String tmp = notification_ts->get(); - int pos1 = tmp.indexOf('#'); - int pos2 = tmp.lastIndexOf(':'); - if ((pos1 == -1) || (pos2 == -1)) { + std::string tmp(notification_ts->get()); + int pos1 = tmp.find('#'); + int pos2 = tmp.rfind(':'); + if ((pos1 == std::string::npos) || (pos2 == std::string::npos)) { return false; } //TODO add a check for valid email ? - _serveraddress = tmp.substring(pos1 + 1, pos2).c_str(); + _serveraddress = tmp.substr(pos1 + 1, pos2); return true; } //Email#serveraddress:port bool NotificationsService::getEmailFromSettings() { - String tmp = notification_ts->get(); - int pos = tmp.indexOf('#'); - if (pos == -1) { + std::string tmp(notification_ts->get()); + int pos = tmp.find('#'); + if (pos == std::string::npos) { return false; } - _settings = tmp.substring(0, pos).c_str(); + _settings = tmp.substr(0, pos); //TODO add a check for valid email ? return true; } diff --git a/FluidNC/src/WebUI/NotificationsService.h b/FluidNC/src/WebUI/NotificationsService.h index b8b3682d7..1177c4fbd 100644 --- a/FluidNC/src/WebUI/NotificationsService.h +++ b/FluidNC/src/WebUI/NotificationsService.h @@ -15,7 +15,6 @@ namespace WebUI { extern NotificationsService notificationsService; } #else -# include # include namespace WebUI { diff --git a/FluidNC/src/WebUI/WSChannel.cpp b/FluidNC/src/WebUI/WSChannel.cpp index 6d0b6ba6d..ea7e7857a 100644 --- a/FluidNC/src/WebUI/WSChannel.cpp +++ b/FluidNC/src/WebUI/WSChannel.cpp @@ -56,14 +56,14 @@ namespace WebUI { return true; } - bool WSChannel::push(String& s) { return push((uint8_t*)s.c_str(), s.length()); } + bool WSChannel::push(std::string& s) { return push((uint8_t*)s.c_str(), s.length()); } void WSChannel::handle() { if (_TXbufferSize > 0 && ((_TXbufferSize >= TXBUFFERSIZE) || ((millis() - _lastflush) > FLUSHTIMEOUT))) { flush(); } } - size_t WSChannel::sendTXT(String& s) { return _server->sendTXT(_clientNum, s); } + size_t WSChannel::sendTXT(std::string& s) { return _server->sendTXT(_clientNum, s.c_str()); } void WSChannel::flush(void) { if (_TXbufferSize > 0) { _server->sendBIN(_clientNum, _TXbuffer, _TXbufferSize); diff --git a/FluidNC/src/WebUI/WSChannel.h b/FluidNC/src/WebUI/WSChannel.h index ba670cef0..4ffccfc98 100644 --- a/FluidNC/src/WebUI/WSChannel.h +++ b/FluidNC/src/WebUI/WSChannel.h @@ -37,7 +37,7 @@ namespace WebUI { size_t write(uint8_t c); size_t write(const uint8_t* buffer, size_t size); - size_t sendTXT(String& s); + size_t sendTXT(std::string& s); inline size_t write(const char* s) { return write((uint8_t*)s, ::strlen(s)); } inline size_t write(unsigned long n) { return write((uint8_t)n); } @@ -50,7 +50,7 @@ namespace WebUI { void handle(); bool push(const uint8_t* data, size_t length); - bool push(String& s); + bool push(std::string& s); void pushRT(char ch); void flush(void); diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 6442a0117..022f38b21 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -283,7 +283,7 @@ namespace WebUI { delete file; return true; } - void Web_Server::sendWithOurAddress(String content) { + void Web_Server::sendWithOurAddress(const char* content) { auto ip = WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP(); String ipstr = ip.toString(); if (_port != 80) { @@ -291,9 +291,10 @@ namespace WebUI { ipstr += String(_port); } - content.replace("$WEB_ADDRESS$", ipstr); - content.replace("$QUERY$", _webserver->uri()); - _webserver->send(200, "text/html", content); + String scontent(content); + scontent.replace("$WEB_ADDRESS$", ipstr); + scontent.replace("$QUERY$", _webserver->uri()); + _webserver->send(200, "text/html", scontent); } // Captive Portal Page for use in AP mode @@ -331,7 +332,7 @@ namespace WebUI { // Handle filenames and other things that are not explicitly registered void Web_Server::handle_not_found() { if (is_authenticated() == AuthenticationLevel::LEVEL_GUEST) { - _webserver->sendHeader(String(FPSTR(LOCATION_HEADER)), String(F("/"))); + _webserver->sendHeader(LOCATION_HEADER, "/"); _webserver->send(302); //_webserver->client().stop(); @@ -371,60 +372,60 @@ namespace WebUI { _webserver->send(500); return; } - String templ = "" - "" - "" - "1" - "0" - "" - "http://%s:%u/" - "" - "upnp:rootdevice" - "%s" - "/" - "%s" - "ESP32" - "Marlin" - "http://espressif.com/en/products/hardware/esp-wroom-32/overview" - "Espressif Systems" - "http://espressif.com" - "uuid:%s" - "" - "\r\n" - "\r\n"; - char uuid[37]; - String sip = WiFi.localIP().toString(); - uint32_t chipId = (uint16_t)(ESP.getEfuseMac() >> 32); + const char* templ = "" + "" + "" + "1" + "0" + "" + "http://%s:%u/" + "" + "upnp:rootdevice" + "%s" + "/" + "%s" + "ESP32" + "Marlin" + "http://espressif.com/en/products/hardware/esp-wroom-32/overview" + "Espressif Systems" + "http://espressif.com" + "uuid:%s" + "" + "\r\n" + "\r\n"; + char uuid[37]; + const char* sip = WiFi.localIP().toString().c_str(); + uint32_t chipId = (uint16_t)(ESP.getEfuseMac() >> 32); sprintf(uuid, "38323636-4558-4dda-9188-cda0e6%02x%02x%02x", (uint16_t)((chipId >> 16) & 0xff), (uint16_t)((chipId >> 8) & 0xff), (uint16_t)chipId & 0xff); - String serialNumber = String(chipId); - sschema.printf(templ.c_str(), sip.c_str(), _port, wifi_config.Hostname().c_str(), serialNumber.c_str(), uuid); - _webserver->send(200, "text/xml", (String)sschema); + const char* serialNumber = std::to_string(chipId).c_str(); + sschema.printf(templ, sip, _port, wifi_config.Hostname().c_str(), serialNumber, uuid); + _webserver->send(200, "text/xml", sschema); } void Web_Server::_handle_web_command(bool silent) { AuthenticationLevel auth_level = is_authenticated(); - String cmd = ""; + std::string cmd; if (_webserver->hasArg("plain")) { - cmd = _webserver->arg("plain"); + cmd = std::string(_webserver->arg("plain").c_str()); } else if (_webserver->hasArg("commandText")) { - cmd = _webserver->arg("commandText"); + cmd = std::string(_webserver->arg("commandText").c_str()); } else { _webserver->send(200, "text/plain", "Invalid command"); return; } //if it is internal command [ESPXXX] - cmd.trim(); - int ESPpos = cmd.indexOf("[ESP"); - if (ESPpos > -1) { + // cmd.trim(); + int ESPpos = cmd.find("[ESP"); + if (ESPpos != std::string::npos) { char line[256]; strncpy(line, cmd.c_str(), 255); webClient.attachWS(_webserver, silent); - Error err = settings_execute_line(line, webClient, auth_level); - String answer; + Error err = settings_execute_line(line, webClient, auth_level); + std::string answer; if (err == Error::Ok) { answer = "ok\n"; } else { @@ -433,7 +434,7 @@ namespace WebUI { if (msg) { answer += msg; } else { - answer += static_cast(err); + answer += std::to_string(static_cast(err)); } answer += "\n"; } @@ -443,7 +444,7 @@ namespace WebUI { vTaskDelay(10); if (!webClient.anyOutput()) { - _webserver->send(err != Error::Ok ? 500 : 200, "text/plain", answer); + _webserver->send(err != Error::Ok ? 500 : 200, "text/plain", answer.c_str()); } webClient.detachWS(); } else { //execute GCODE @@ -469,7 +470,7 @@ namespace WebUI { } else if (cmd.length() == 1 && is_realtime_command(cmd[0])) { wsChannel->pushRT(cmd[0]); } else { - if (!cmd.endsWith("\n")) { + if (cmd.length() && cmd[cmd.length() - 1] == '\n') { cmd += '\n'; } hasError = !wsChannel->push(cmd); @@ -659,14 +660,15 @@ namespace WebUI { void Web_Server::handleFeedholdReload() { protocol_send_event(&feedHoldEvent); // Go to the main page - _webserver->sendHeader(String(FPSTR(LOCATION_HEADER)), String(F("/"))); + _webserver->sendHeader(LOCATION_HEADER, "/"); _webserver->send(302); } //push error code and message to websocket. Used by upload code void Web_Server::pushError(int code, const char* st, bool web_error, uint16_t timeout) { if (_socket_server && st) { - String s = "ERROR:" + String(code) + ":"; + std::string s("ERROR:"); + s += std::to_string(code) + ":"; s += st; try { @@ -712,7 +714,7 @@ namespace WebUI { if (upload.status == UPLOAD_FILE_START) { String sizeargname = upload.filename + "S"; size_t filesize = _webserver->hasArg(sizeargname) ? _webserver->arg(sizeargname).toInt() : 0; - uploadStart(upload.filename, filesize, fs); + uploadStart(upload.filename.c_str(), filesize, fs); } else if (upload.status == UPLOAD_FILE_WRITE) { uploadWrite(upload.buf, upload.currentSize); } else if (upload.status == UPLOAD_FILE_END) { @@ -725,10 +727,10 @@ namespace WebUI { } } } - uploadCheck(upload.filename); + uploadCheck(); } - void Web_Server::sendJSON(int code, const String& s) { + void Web_Server::sendJSON(int code, const char* s) { _webserver->sendHeader("Cache-Control", "no-cache"); _webserver->send(200, "application/json", s); } @@ -745,7 +747,7 @@ namespace WebUI { j.member("user", user); } j.end(); - sendJSON(200, s.c_str()); + sendJSON(200, s); } void Web_Server::sendStatus(int code, const char* status) { @@ -754,7 +756,7 @@ namespace WebUI { j.begin(); j.member("status", status); j.end(); - sendJSON(code, s.c_str()); + sendJSON(code, s); } void Web_Server::sendAuthFailed() { sendStatus(401, "Authentication failed"); } @@ -909,7 +911,7 @@ namespace WebUI { } } - FluidPath fpath { path, fs, ec }; + FluidPath fpath { path.c_str(), fs, ec }; if (ec) { sendJSON(200, "{\"status\":\"No SD card\"}"); return; @@ -917,7 +919,7 @@ namespace WebUI { // Handle deletions and directory creation if (_webserver->hasArg("action") && _webserver->hasArg("filename")) { - String action = _webserver->arg("action"); + std::string action(_webserver->arg("action").c_str()); std::string filename = std::string(_webserver->arg("filename").c_str()); if (action == "delete") { if (stdfs::remove(fpath / filename.c_str(), ec)) { @@ -968,10 +970,9 @@ namespace WebUI { } } - String stotalspace, susedspace; - auto space = stdfs::space(fpath, ec); - totalspace = space.capacity; - usedspace = totalspace - space.available; + auto space = stdfs::space(fpath, ec); + totalspace = space.capacity; + usedspace = totalspace - space.available; j.member("path", path.c_str()); j.member("total", formatBytes(totalspace)); @@ -982,14 +983,14 @@ namespace WebUI { j.member("occupation", percent); j.member("status", sstatus); j.end(); - sendJSON(200, s.c_str()); + sendJSON(200, s); } void Web_Server::handle_direct_SDFileList() { handleFileOps(sdName); } void Web_Server::handleFileList() { handleFileOps(localfsName); } // File upload - void Web_Server::uploadStart(String filename, size_t filesize, const char* fs) { + void Web_Server::uploadStart(const char* filename, size_t filesize, const char* fs) { std::error_code ec; FluidPath fpath { filename, fs, ec }; @@ -1049,7 +1050,6 @@ namespace WebUI { // delete _uploadFile; // _uploadFile = nullptr; - // String path = _uploadFile->path().c_str(); auto fpath = _uploadFile->fpath(); delete _uploadFile; _uploadFile = nullptr; @@ -1087,7 +1087,7 @@ namespace WebUI { _uploadFile = nullptr; } } - void Web_Server::uploadCheck(String filename) { + void Web_Server::uploadCheck() { std::error_code error_code; if (_upload_status == UploadStatus::FAILED) { cancelUpload(); @@ -1113,8 +1113,8 @@ namespace WebUI { } if ((millis() - start_time) > 10000 && _socket_server) { for (WSChannel* wsChannel : webWsChannels) { - String s = "PING:"; - s += String(wsChannel->id()); + std::string s("PING:"); + s += wsChannel->id(); wsChannel->sendTXT(s); } @@ -1149,11 +1149,13 @@ namespace WebUI { wsChannels[num] = wsChannel; if (strcmp(data, "/") == 0) { - String s = "CURRENT_ID:" + String(num); + std::string s("CURRENT_ID:"); + s += std::to_string(num); // send message to client webWsChannels.push_front(wsChannel); wsChannel->sendTXT(s); - s = "ACTIVE_ID:" + String(wsChannel->id()); + s = "ACTIVE_ID:"; + s += wsChannel->id(); wsChannel->sendTXT(s); } } @@ -1208,12 +1210,12 @@ namespace WebUI { AuthenticationLevel Web_Server::is_authenticated() { # ifdef ENABLE_AUTHENTICATION if (_webserver->hasHeader("Cookie")) { - String cookie = _webserver->header("Cookie"); - int pos = cookie.indexOf("ESPSESSIONID="); - if (pos != -1) { - int pos2 = cookie.indexOf(";", pos); - String sessionID = cookie.substring(pos + strlen("ESPSESSIONID="), pos2); - IPAddress ip = _webserver->client().remoteIP(); + std::string cookie(_webserver->header("Cookie").c_str()); + size_t pos = cookie.find("ESPSESSIONID="); + if (pos != std::string::npos) { + size_t pos2 = cookie.find(";", pos); + std::string sessionID = cookie.substr(pos + strlen("ESPSESSIONID="), pos2); + IPAddress ip = _webserver->client().remoteIP(); //check if cookie can be reset and clean table in same time return ResetAuthIP(ip, sessionID.c_str()); } diff --git a/FluidNC/src/WebUI/WebServer.h b/FluidNC/src/WebUI/WebServer.h index 839a434fb..9434b8d60 100644 --- a/FluidNC/src/WebUI/WebServer.h +++ b/FluidNC/src/WebUI/WebServer.h @@ -98,19 +98,20 @@ namespace WebUI { static void handle_direct_SDFileList(); static void fileUpload(const char* fs); static void SDFileUpload(); - static void uploadStart(String filename, size_t filesize, const char* fs); + static void uploadStart(const char* filename, size_t filesize, const char* fs); static void uploadWrite(uint8_t* buffer, size_t length); static void uploadEnd(size_t filesize); static void uploadStop(); - static void uploadCheck(String filename); + static void uploadCheck(); static void sendFSError(Error err); - static void sendJSON(int code, const String& s); + static void sendJSON(int code, const char* s); + static void sendJSON(int code, const std::string& s) { sendJSON(code, s.c_str()); } static void sendAuth(const char* status, const char* level, const char* user); static void sendAuthFailed(); static void sendStatus(int code, const char* str); - static void sendWithOurAddress(String s); + static void sendWithOurAddress(const char* s); static void sendCaptivePortal(); static void send404Page(); diff --git a/FluidNC/src/WebUI/WebSettings.cpp b/FluidNC/src/WebUI/WebSettings.cpp index a1e5164f7..f94aaea23 100644 --- a/FluidNC/src/WebUI/WebSettings.cpp +++ b/FluidNC/src/WebUI/WebSettings.cpp @@ -444,7 +444,7 @@ namespace WebUI { } return Error::Ok; } - static Error copyDir(String iDir, String oDir, Channel& out) { // No ESP command + static Error copyDir(const char* iDir, const char* oDir, Channel& out) { // No ESP command std::error_code ec; { // Block to manage scope of outDir @@ -479,8 +479,12 @@ namespace WebUI { if (dir_entry.is_directory()) { log_error("Not handling localfs subdirectories"); } else { - String opath = oDir + "/" + dir_entry.path().filename().c_str(); - String ipath = iDir + "/" + dir_entry.path().filename().c_str(); + std::string opath(oDir); + opath += "/"; + opath += dir_entry.path().filename().c_str(); + std::string ipath(iDir); + ipath += "/"; + ipath += dir_entry.path().filename().c_str(); log_info_to(out, ipath << " -> " << opath); auto err1 = copyFile(ipath.c_str(), opath.c_str(), out); if (err1 != Error::Ok) { diff --git a/FluidNC/src/WebUI/WifiConfig.cpp b/FluidNC/src/WebUI/WifiConfig.cpp index 309e310c8..9e928bef6 100644 --- a/FluidNC/src/WebUI/WifiConfig.cpp +++ b/FluidNC/src/WebUI/WifiConfig.cpp @@ -12,7 +12,7 @@ WebUI::WiFiConfig wifi_config; #ifdef ENABLE_WIFI # include "../Config.h" -# include "../Main.h" // display() +# include "../Main.h" # include "Commands.h" // COMMANDS # include "WifiServices.h" // wifi_services.start() etc. # include "WebSettings.h" // split_params(), get_params() @@ -586,7 +586,6 @@ namespace WebUI { return false; case WL_CONNECTED: log_info("Connected - IP is " << WiFi.localIP().toString()); - display("IP", WiFi.localIP().toString()); return true; default: if ((dot > 3) || (dot == 0)) { @@ -620,8 +619,8 @@ namespace WebUI { } WiFi.enableAP(false); //SSID - String SSID = wifi_sta_ssid->get(); - if (SSID.length() == 0) { + const char* SSID = wifi_sta_ssid->get(); + if (strlen(SSID) == 0) { log_info("STA SSID is not set"); return false; } @@ -629,21 +628,20 @@ namespace WebUI { WiFi.setMinSecurity(static_cast(wifi_sta_min_security->get())); WiFi.setScanMethod(wifi_fast_scan->get() ? WIFI_FAST_SCAN : WIFI_ALL_CHANNEL_SCAN); //Get parameters for STA - String h = wifi_hostname->get(); - WiFi.setHostname(h.c_str()); + WiFi.setHostname(wifi_hostname->get()); //password - String password = wifi_sta_password->get(); - int8_t IP_mode = wifi_sta_mode->get(); - int32_t IP = wifi_sta_ip->get(); - int32_t GW = wifi_sta_gateway->get(); - int32_t MK = wifi_sta_netmask->get(); + const char* password = wifi_sta_password->get(); + int8_t IP_mode = wifi_sta_mode->get(); + int32_t IP = wifi_sta_ip->get(); + int32_t GW = wifi_sta_gateway->get(); + int32_t MK = wifi_sta_netmask->get(); //if not DHCP if (IP_mode != DHCP_MODE) { IPAddress ip(IP), mask(MK), gateway(GW); WiFi.config(ip, gateway, mask); } - if (WiFi.begin(SSID.c_str(), (password.length() > 0) ? password.c_str() : NULL)) { - log_info("Connecting to STA SSID:" << SSID.c_str()); + if (WiFi.begin(SSID, (strlen(password) > 0) ? password : NULL)) { + log_info("Connecting to STA SSID:" << SSID); return ConnectSTA2AP(); } else { log_info("Starting client failed"); @@ -682,12 +680,12 @@ namespace WebUI { //Get parameters for AP //SSID - String SSID = wifi_ap_ssid->get(); - if (SSID.length() == 0) { + const char* SSID = wifi_ap_ssid->get(); + if (strlen(SSID) == 0) { SSID = DEFAULT_AP_SSID; } - String password = wifi_ap_password->get(); + const char* password = wifi_ap_password->get(); int8_t channel = int8_t(wifi_ap_channel->get()); if (channel == 0) { @@ -704,9 +702,8 @@ namespace WebUI { WiFi.softAPConfig(ip, ip, mask); //Start AP - if (WiFi.softAP(SSID.c_str(), (password.length() > 0) ? password.c_str() : NULL, channel)) { + if (WiFi.softAP(SSID, (strlen(password) > 0) ? password : NULL, channel)) { log_info("AP started"); - display("IP", ip.toString()); return true; } diff --git a/FluidNC/src/WebUI/WifiConfig.h b/FluidNC/src/WebUI/WifiConfig.h index a9f2ad63f..3fe426eea 100644 --- a/FluidNC/src/WebUI/WifiConfig.h +++ b/FluidNC/src/WebUI/WifiConfig.h @@ -10,8 +10,6 @@ #include "../Error.h" // Error #include "Authentication.h" // AuthenticationLevel -#include - #ifndef ENABLE_WIFI namespace WebUI { class WiFiConfig { diff --git a/FluidNC/src/WebUI/WifiServices.cpp b/FluidNC/src/WebUI/WifiServices.cpp index 934dd7617..d01a002c6 100644 --- a/FluidNC/src/WebUI/WifiServices.cpp +++ b/FluidNC/src/WebUI/WifiServices.cpp @@ -42,11 +42,9 @@ namespace WebUI { return false; } - String h = wifi_hostname->get(); - ArduinoOTA .onStart([]() { - String type; + const char* type; if (ArduinoOTA.getCommand() == U_FLASH) { type = "sketch"; } else { @@ -86,7 +84,8 @@ namespace WebUI { //no need in AP mode if (WiFi.getMode() == WIFI_STA) { //start mDns - if (!MDNS.begin(h.c_str())) { + const char* h = wifi_hostname->get(); + if (!MDNS.begin(h)) { log_info("Cannot start mDNS"); no_error = false; } else { From ef1c132cf2d5024e9026c3b962df0278346ab89b Mon Sep 17 00:00:00 2001 From: bdring Date: Fri, 24 Mar 2023 10:57:28 -0500 Subject: [PATCH 14/51] Add reg dump in debug mode --- FluidNC/src/Motors/TMC2209Driver.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index b8753882d..4623d2af6 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -72,6 +72,15 @@ namespace MotorDrivers { break; } } + + // dump the registers. This is helpful for people migrating to the Pro version + log_debug("CHOPCONF: 0x" << String(tmc2209->CHOPCONF(), HEX)); + log_debug("COOLCONF: 0x" << String(tmc2209->COOLCONF(), HEX)); + log_debug("TPWMTHRS: 0x" << String(tmc2209->TPWMTHRS(), HEX)); + log_debug("TCOOLTHRS: 0x" << String(tmc2209->TCOOLTHRS(), HEX)); + log_debug("GCONF: 0x" << String(tmc2209->GCONF(), HEX)); + log_debug("PWMCONF: 0x" << String(tmc2209->PWMCONF(), HEX)); + log_debug("IHOLD_IRUN: 0x" << String(tmc2209->IHOLD_IRUN(), HEX)); } void TMC2209Driver::debug_message() { From 864116d869eada4eaa8329c3a7986fb9d72f2cf9 Mon Sep 17 00:00:00 2001 From: bdring Date: Fri, 24 Mar 2023 14:42:15 -0500 Subject: [PATCH 15/51] Set I_scale_analog=false This prevents people from using the pot from changing the scaling. We use amps in the config, so it does not makes sense to allow this. 5160 does not have this feature. --- FluidNC/src/Motors/TMC2130Driver.cpp | 5 ++++- FluidNC/src/Motors/TMC2208Driver.cpp | 1 + FluidNC/src/Motors/TMC2209Driver.cpp | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/FluidNC/src/Motors/TMC2130Driver.cpp b/FluidNC/src/Motors/TMC2130Driver.cpp index b0d77866c..4741b6624 100644 --- a/FluidNC/src/Motors/TMC2130Driver.cpp +++ b/FluidNC/src/Motors/TMC2130Driver.cpp @@ -29,7 +29,9 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC2130Driver::test() { return checkVersion(0x11, tmc2130->version()); } + bool TMC2130Driver::test() { + return checkVersion(0x11, tmc2130->version()); + } void TMC2130Driver::set_registers(bool isHoming) { if (_has_errors) { @@ -42,6 +44,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2130->I_scale_analog(false); // do not scale via pot tmc2130->rms_current(run_i, TrinamicSpiDriver::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping diff --git a/FluidNC/src/Motors/TMC2208Driver.cpp b/FluidNC/src/Motors/TMC2208Driver.cpp index ef9b161a7..69dc04bb7 100644 --- a/FluidNC/src/Motors/TMC2208Driver.cpp +++ b/FluidNC/src/Motors/TMC2208Driver.cpp @@ -41,6 +41,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2208->I_scale_analog(false); // do not scale via pot tmc2208->rms_current(run_i, TrinamicBase::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index 4623d2af6..786342cbe 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -42,6 +42,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2209->I_scale_analog(false); // do not scale via pot tmc2209->rms_current(run_i, TrinamicBase::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping From 016280a20746321bd511ef8bce3df881833f9559 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Fri, 24 Mar 2023 13:55:01 -1000 Subject: [PATCH 16/51] String -> std::string in Pins and WebServer and whatnot --- FluidNC/esp32/sdspi.cpp | 2 +- FluidNC/esp32/tmc_spi.cpp | 4 +- FluidNC/src/Configuration/Generator.h | 6 +- FluidNC/src/Configuration/Parser.cpp | 6 +- FluidNC/src/Configuration/RuntimeSetting.cpp | 2 +- FluidNC/src/Machine/WifiConfig.h | 6 +- FluidNC/src/Motors/StandardStepper.cpp | 8 +-- FluidNC/src/MyIOStream.h | 9 ++- FluidNC/src/NutsBolts.cpp | 17 +++++ FluidNC/src/NutsBolts.h | 4 ++ FluidNC/src/Pin.cpp | 44 +++++-------- FluidNC/src/Pin.h | 8 +-- FluidNC/src/Pins/DebugPinDetail.cpp | 10 +-- FluidNC/src/Pins/DebugPinDetail.h | 2 +- FluidNC/src/Pins/ErrorPinDetail.cpp | 7 ++- FluidNC/src/Pins/ErrorPinDetail.h | 6 +- FluidNC/src/Pins/GPIOPinDetail.cpp | 5 +- FluidNC/src/Pins/GPIOPinDetail.h | 2 +- FluidNC/src/Pins/I2SOPinDetail.cpp | 5 +- FluidNC/src/Pins/I2SOPinDetail.h | 2 +- FluidNC/src/Pins/PinDetail.h | 4 +- FluidNC/src/Pins/PinOptionsParser.cpp | 65 ++++++++++++++------ FluidNC/src/Pins/PinOptionsParser.h | 27 ++++---- FluidNC/src/Pins/VoidPinDetail.cpp | 2 +- FluidNC/src/Pins/VoidPinDetail.h | 2 +- FluidNC/src/Settings.cpp | 4 +- FluidNC/src/StackTrace/AssertionFailed.cpp | 6 +- FluidNC/src/StackTrace/AssertionFailed.h | 12 ++-- FluidNC/src/StringRange.h | 39 ++++++++++-- FluidNC/src/WebUI/WebServer.cpp | 18 +++--- FluidNC/src/WebUI/WebSettings.cpp | 6 +- FluidNC/src/WebUI/WifiConfig.cpp | 60 +++++++++--------- 32 files changed, 232 insertions(+), 168 deletions(-) diff --git a/FluidNC/esp32/sdspi.cpp b/FluidNC/esp32/sdspi.cpp index 079e4293b..a2a3dd32f 100644 --- a/FluidNC/esp32/sdspi.cpp +++ b/FluidNC/esp32/sdspi.cpp @@ -12,7 +12,7 @@ #define CHECK_EXECUTE_RESULT(err, str) \ do { \ if ((err) != ESP_OK) { \ - log_error(str << " code 0x" << String(err, 16)); \ + log_error(str << " code 0x" << to_hex(err)); \ goto cleanup; \ } \ } while (0) diff --git a/FluidNC/esp32/tmc_spi.cpp b/FluidNC/esp32/tmc_spi.cpp index f03d10c41..45ac63a8a 100644 --- a/FluidNC/esp32/tmc_spi.cpp +++ b/FluidNC/esp32/tmc_spi.cpp @@ -120,7 +120,7 @@ static void tmc_spi_rw_reg(uint8_t cmd, uint32_t data, int index) { // This is executed in the object context so it has access to class // data such as the CS pin that switchCSpin() uses void TMC2130Stepper::write(uint8_t reg, uint32_t data) { - log_verbose("TMC reg 0x" << String(reg, 16) << " write 0x" << String(data, 16)); + log_verbose("TMC reg 0x" << to_hex(reg) << " write 0x" << to_hex(data)); tmc_spi_bus_setup(); switchCSpin(0); @@ -165,7 +165,7 @@ uint32_t TMC2130Stepper::read(uint8_t reg) { data += (uint32_t)in[dummy_in_bytes + 4]; switchCSpin(1); - log_verbose("TMC reg 0x" << String(reg, 16) << " read 0x" << String(data, 16) << " status 0x" << String(status, 16)); + log_verbose("TMC reg 0x" << to_hex(reg) << " read 0x" << to_hex(data) << " status 0x" << to_hex(status)); return data; } diff --git a/FluidNC/src/Configuration/Generator.h b/FluidNC/src/Configuration/Generator.h index 212f05f97..f59c39c62 100644 --- a/FluidNC/src/Configuration/Generator.h +++ b/FluidNC/src/Configuration/Generator.h @@ -98,13 +98,13 @@ namespace Configuration { send_item(name, s); } - void item(const char* name, std::string& value, int minLength, int maxLength) override { send_item(name, value.c_str()); } + void item(const char* name, std::string& value, int minLength, int maxLength) override { send_item(name, value); } void item(const char* name, bool& value) override { send_item(name, value ? "true" : "false"); } - void item(const char* name, Pin& value) override { send_item(name, value.name().c_str()); } + void item(const char* name, Pin& value) override { send_item(name, value.name()); } - void item(const char* name, IPAddress& value) override { send_item(name, value.toString().c_str()); } + void item(const char* name, IPAddress& value) override { send_item(name, IP_string(value)); } void item(const char* name, int& value, EnumItem* e) override { const char* str = "unknown"; for (; e->name; ++e) { diff --git a/FluidNC/src/Configuration/Parser.cpp b/FluidNC/src/Configuration/Parser.cpp index b321648c0..5b28301df 100644 --- a/FluidNC/src/Configuration/Parser.cpp +++ b/FluidNC/src/Configuration/Parser.cpp @@ -38,9 +38,7 @@ namespace Configuration { return result; } - StringRange Parser::stringValue() const { - return StringRange(token_.sValueStart_, token_.sValueEnd_); - } + StringRange Parser::stringValue() const { return StringRange(token_.sValueStart_, token_.sValueEnd_); } bool Parser::boolValue() const { auto str = StringRange(token_.sValueStart_, token_.sValueEnd_); @@ -118,7 +116,7 @@ namespace Configuration { IPAddress Parser::ipValue() const { IPAddress ip; auto str = StringRange(token_.sValueStart_, token_.sValueEnd_); - if (!ip.fromString(str.str())) { + if (!ip.fromString(str.str().c_str())) { parseError("Expected an IP address like 192.168.0.100"); } return ip; diff --git a/FluidNC/src/Configuration/RuntimeSetting.cpp b/FluidNC/src/Configuration/RuntimeSetting.cpp index ea8cf0630..b8d677e4d 100644 --- a/FluidNC/src/Configuration/RuntimeSetting.cpp +++ b/FluidNC/src/Configuration/RuntimeSetting.cpp @@ -205,7 +205,7 @@ namespace Configuration { if (is(name)) { isHandled_ = true; if (newValue_ == nullptr) { - log_to(out_, "", setting_prefix() << value.toString()); + log_to(out_, "", setting_prefix() << IP_string(value)); } else { IPAddress ip; if (!ip.fromString(newValue_)) { diff --git a/FluidNC/src/Machine/WifiConfig.h b/FluidNC/src/Machine/WifiConfig.h index 546bb86ae..fe130d871 100644 --- a/FluidNC/src/Machine/WifiConfig.h +++ b/FluidNC/src/Machine/WifiConfig.h @@ -18,15 +18,11 @@ namespace Machine { std::string _ssid = "FluidNC"; - // Passwords don't belong in a YAML! - // String _password = "12345678"; - bool _dhcp = true; void group(Configuration::HandlerBase& handler) override { handler.item("ssid", _ssid); - // handler.item("password", _password); - + // No passwords in the config file! handler.item("ip_address", _ipAddress); handler.item("gateway", _gateway); handler.item("netmask", _netmask); diff --git a/FluidNC/src/Motors/StandardStepper.cpp b/FluidNC/src/Motors/StandardStepper.cpp index 41e740971..3c9bbfdcb 100644 --- a/FluidNC/src/Motors/StandardStepper.cpp +++ b/FluidNC/src/Motors/StandardStepper.cpp @@ -119,15 +119,15 @@ namespace MotorDrivers { Assert(_step_pin.defined(), "Step pin must be configured."); bool isI2SO = config->_stepping->_engine == Stepping::I2S_STREAM || config->_stepping->_engine == Stepping::I2S_STATIC; if (isI2SO) { - Assert(_step_pin.name().startsWith("I2SO"), "Step pin must be an I2SO pin"); + Assert(_step_pin.name().rfind("I2SO", 0) == 0, "Step pin must be an I2SO pin"); if (_dir_pin.defined()) { - Assert((_dir_pin.name().startsWith("I2SO")), "Direction pin must be an I2SO pin"); + Assert(_dir_pin.name().rfind("I2SO", 0) == 0, "Direction pin must be an I2SO pin"); } } else { - Assert(_step_pin.name().startsWith("gpio"), "Step pin must be a GPIO pin"); + Assert(_step_pin.name().rfind("gpio", 0) == 0, "Step pin must be a GPIO pin"); if (_dir_pin.defined()) { - Assert((_dir_pin.name().startsWith("gpio")), "Direction pin must be a GPIO pin"); + Assert(_dir_pin.name().rfind("gpio", 0) == 0, "Direction pin must be a GPIO pin"); } } } diff --git a/FluidNC/src/MyIOStream.h b/FluidNC/src/MyIOStream.h index b29b7797f..515d813e3 100644 --- a/FluidNC/src/MyIOStream.h +++ b/FluidNC/src/MyIOStream.h @@ -8,6 +8,7 @@ #include #include "Pin.h" +#include "StringRange.h" inline Print& operator<<(Print& lhs, char c) { lhs.print(c); @@ -19,8 +20,10 @@ inline Print& operator<<(Print& lhs, const char* v) { return lhs; } -inline Print& operator<<(Print& lhs, String v) { - lhs.print(v.c_str()); +inline Print& operator<<(Print& lhs, const StringRange& s) { + for (const char* p = s.begin(); p < s.end(); ++p) { + lhs.print(*p); + } return lhs; } @@ -55,7 +58,7 @@ inline Print& operator<<(Print& lhs, double v) { } inline Print& operator<<(Print& lhs, const Pin& v) { - lhs.print(v.name()); + lhs.print(v.name().c_str()); return lhs; } diff --git a/FluidNC/src/NutsBolts.cpp b/FluidNC/src/NutsBolts.cpp index 19d6bfd12..b5330f013 100644 --- a/FluidNC/src/NutsBolts.cpp +++ b/FluidNC/src/NutsBolts.cpp @@ -256,3 +256,20 @@ std::string formatBytes(uint64_t bytes) { msg << std::fixed << std::setprecision(2) << b << " GB"; return msg.str(); } + +std::string IP_string(uint32_t ipaddr) { + std::string retval; + retval += std::to_string(uint8_t((ipaddr >> 00) & 0xff)) + "."; + retval += std::to_string(uint8_t((ipaddr >> 8) & 0xff)) + "."; + retval += std::to_string(uint8_t((ipaddr >> 16) & 0xff)) + "."; + retval += std::to_string(uint8_t((ipaddr >> 24) & 0xff)); + return retval; +} + +void replace_string_in_place(std::string& subject, const std::string& search, const std::string& replace) { + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } +} diff --git a/FluidNC/src/NutsBolts.h b/FluidNC/src/NutsBolts.h index 510064dc9..388ee8714 100644 --- a/FluidNC/src/NutsBolts.h +++ b/FluidNC/src/NutsBolts.h @@ -164,3 +164,7 @@ bool constrain_with_message(T& value, T min, T max, const char* name = "") { bool multiple_bits_set(uint32_t val); std::string formatBytes(uint64_t bytes); + +std::string IP_string(uint32_t ipaddr); + +void replace_string_in_place(std::string& subject, const std::string& search, const std::string& replace); diff --git a/FluidNC/src/Pin.cpp b/FluidNC/src/Pin.cpp index 074db9d07..4cd075d61 100644 --- a/FluidNC/src/Pin.cpp +++ b/FluidNC/src/Pin.cpp @@ -16,65 +16,55 @@ Pins::PinDetail* Pin::undefinedPin = new Pins::VoidPinDetail(); Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail("unknown"); const char* Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) { - String str = tmp.str(); - // Initialize pinImplementation first! Callers might want to delete it, and we don't want a random pointer. pinImplementation = nullptr; // Parse the definition: [GPIO].[pinNumber]:[attributes] + const char* end = tmp.end(); + // Skip whitespaces at the start - auto nameStart = str.begin(); - for (; nameStart != str.end() && ::isspace(*nameStart); ++nameStart) {} + auto nameStart = tmp.begin(); + for (; nameStart != end && ::isspace(*nameStart); ++nameStart) {} - if (nameStart == str.end()) { + if (nameStart == end) { // Re-use undefined pins happens in 'create': pinImplementation = new Pins::VoidPinDetail(); return nullptr; } auto idx = nameStart; - for (; idx != str.end() && *idx != '.' && *idx != ':'; ++idx) { - *idx = char(::tolower(*idx)); - } + for (; idx != end && *idx != '.' && *idx != ':'; ++idx) {} - String prefix = str.substring(0, int(idx - str.begin())); + StringRange prefix(tmp.begin(), idx); - if (idx != str.end()) { // skip '.' + if (idx != end) { // skip '.' ++idx; } int pinNumber = 0; if (prefix != "") { - if (idx != str.end()) { - for (int n = 0; idx != str.end() && n <= 4 && *idx >= '0' && *idx <= '9'; ++idx, ++n) { + if (idx != end) { + for (int n = 0; idx != end && n <= 4 && *idx >= '0' && *idx <= '9'; ++idx, ++n) { pinNumber = pinNumber * 10 + int(*idx - '0'); } } } - while (idx != str.end() && ::isspace(*idx)) { + while (idx != end && ::isspace(*idx)) { ++idx; } - String options; - if (idx != str.end()) { + if (idx != end) { if (*idx != ':') { // Pin definition attributes or EOF expected. return "Pin attributes (':') were expected."; } ++idx; - - options = str.substring(int(idx - str.begin())); } - // What would be a simple, practical way to parse the options? I figured, why not - // just use the C-style string, convert it to lower case, and change the separators - // into 'nul' tokens. We then pass the number of 'nul' tokens, and the first char* - // which is pretty easy to parse. - // Build an options parser: - Pins::PinOptionsParser parser(options.begin(), options.end()); + Pins::PinOptionsParser parser(idx, end); // Build this pin: if (prefix == "gpio") { @@ -106,10 +96,6 @@ const char* Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) { } } -Pin Pin::create(const String& str) { - return create(StringRange(str)); -} - Pin Pin::create(const StringRange& str) { Pins::PinDetail* pinImplementation = nullptr; try { @@ -120,7 +106,7 @@ Pin Pin::create(const StringRange& str) { } log_error("Setting up pin:" << str.str() << " failed:" << err); - return Pin(new Pins::ErrorPinDetail(str.str())); + return Pin(new Pins::ErrorPinDetail(str.str().c_str())); } else { return Pin(pinImplementation); } @@ -139,7 +125,7 @@ Pin Pin::create(const StringRange& str) { } } -bool Pin::validate(const String& str) { +bool Pin::validate(const char* str) { Pins::PinDetail* pinImplementation; auto valid = parse(str, pinImplementation); diff --git a/FluidNC/src/Pin.h b/FluidNC/src/Pin.h index b93171452..e40e38d4e 100644 --- a/FluidNC/src/Pin.h +++ b/FluidNC/src/Pin.h @@ -17,9 +17,6 @@ // #define DEBUG_PIN_DUMP // Pin debugging. WILL spam you with a lot of data! -// Forward declarations: -class String; - // Yuck, yuck, yuck... apparently we can't create a template with an IRAM_ATTR, because GCC refuses to obide // by the attributes. In other words, _all_ templates are out when using an ISR! This define makes an anonymous // method in the class, which can be used to wrap a single function. It can then be used by running the attachInterrupt @@ -106,8 +103,7 @@ class Pin { static Pin create(const char* str) { return create(StringRange(str)); } // ensure it's not ambiguous static Pin create(const StringRange& str); - static Pin create(const String& str); - static bool validate(const String& str); + static bool validate(const char* str); // We delete the copy constructor, and implement the move constructor. The move constructor is required to support // the correct execution of 'return' in f.ex. `create` calls. It basically transfers ownership from the callee to the @@ -159,7 +155,7 @@ class Pin { // Other functions: Capabilities capabilities() const { return _detail->capabilities(); } - inline String name() const { return _detail->toString(); } + inline std::string name() const { return _detail->toString(); } void report(const char* legend); void report(std::string legend) { report(legend.c_str()); } diff --git a/FluidNC/src/Pins/DebugPinDetail.cpp b/FluidNC/src/Pins/DebugPinDetail.cpp index 4d40b4b0b..63e72d236 100644 --- a/FluidNC/src/Pins/DebugPinDetail.cpp +++ b/FluidNC/src/Pins/DebugPinDetail.cpp @@ -26,7 +26,7 @@ namespace Pins { if (high != int(_isHigh)) { _isHigh = bool(high); if (shouldEvent()) { - WriteSerial("Write %s < %d", toString().c_str(), high); + WriteSerial("Write %s < %d", toString(), high); } } _implementation->write(high); @@ -35,7 +35,7 @@ namespace Pins { int DebugPinDetail::read() { auto result = _implementation->read(); if (shouldEvent()) { - WriteSerial("Read %s > %d", toString().c_str(), result); + WriteSerial("Read %s > %d", toString(), result); } return result; } @@ -66,7 +66,7 @@ namespace Pins { buf[n++] = 0; if (shouldEvent()) { - WriteSerial("Set pin attr %s = %s", toString().c_str(), buf); + WriteSerial("Set pin attr %s = %s", toString(), buf); } _implementation->setAttr(value); } @@ -76,7 +76,7 @@ namespace Pins { void DebugPinDetail::CallbackHandler::handle(void* arg) { auto handler = static_cast(arg); if (handler->_myPin->shouldEvent()) { - WriteSerial("Received ISR on %s", handler->_myPin->toString().c_str()); + WriteSerial("Received ISR on %s", handler->_myPin->toString()); } handler->callback(handler->argument); } @@ -88,7 +88,7 @@ namespace Pins { _isrHandler.callback = callback; if (shouldEvent()) { - WriteSerial("Attaching interrupt to pin %s, mode %d", toString().c_str(), mode); + WriteSerial("Attaching interrupt to pin %s, mode %d", toString(), mode); } _implementation->attachInterrupt(_isrHandler.handle, &_isrHandler, mode); } diff --git a/FluidNC/src/Pins/DebugPinDetail.h b/FluidNC/src/Pins/DebugPinDetail.h index 8914af3af..b6b10ff84 100644 --- a/FluidNC/src/Pins/DebugPinDetail.h +++ b/FluidNC/src/Pins/DebugPinDetail.h @@ -42,7 +42,7 @@ namespace Pins { void attachInterrupt(void (*callback)(void*), void* arg, int mode) override; void detachInterrupt() override; - String toString() override { return _implementation->toString(); } + std::string toString() override { return _implementation->toString(); } ~DebugPinDetail() override {} }; diff --git a/FluidNC/src/Pins/ErrorPinDetail.cpp b/FluidNC/src/Pins/ErrorPinDetail.cpp index 82640f3d5..996ebe342 100644 --- a/FluidNC/src/Pins/ErrorPinDetail.cpp +++ b/FluidNC/src/Pins/ErrorPinDetail.cpp @@ -6,7 +6,7 @@ #include "../Assert.h" namespace Pins { - ErrorPinDetail::ErrorPinDetail(const String& descr) : PinDetail(0), _description(descr) {} + ErrorPinDetail::ErrorPinDetail(const char* descr) : PinDetail(0), _description(descr) {} PinCapabilities ErrorPinDetail::capabilities() const { return PinCapabilities::Error; } @@ -33,5 +33,8 @@ namespace Pins { PinAttributes ErrorPinDetail::getAttr() const { return PinAttributes::None; } - String ErrorPinDetail::toString() { return "ERROR_PIN (for " + _description + ")"; } + std::string ErrorPinDetail::toString() { + std::string s("ERROR_PIN (for "); + return s + _description + ")"; + } } diff --git a/FluidNC/src/Pins/ErrorPinDetail.h b/FluidNC/src/Pins/ErrorPinDetail.h index dbc1a6b27..68eea1cc0 100644 --- a/FluidNC/src/Pins/ErrorPinDetail.h +++ b/FluidNC/src/Pins/ErrorPinDetail.h @@ -8,10 +8,10 @@ namespace Pins { class ErrorPinDetail : public PinDetail { - String _description; + std::string _description; public: - ErrorPinDetail(const String& descr); + ErrorPinDetail(const char* descr); PinCapabilities capabilities() const override; @@ -21,7 +21,7 @@ namespace Pins { void setAttr(PinAttributes value) override; PinAttributes getAttr() const override; - String toString() override; + std::string toString() override; ~ErrorPinDetail() override {} }; diff --git a/FluidNC/src/Pins/GPIOPinDetail.cpp b/FluidNC/src/Pins/GPIOPinDetail.cpp index 69f30df6d..fa1c428d0 100644 --- a/FluidNC/src/Pins/GPIOPinDetail.cpp +++ b/FluidNC/src/Pins/GPIOPinDetail.cpp @@ -179,8 +179,9 @@ namespace Pins { ::detachInterrupt(_index); } - String GPIOPinDetail::toString() { - auto s = String("gpio.") + int(_index); + std::string GPIOPinDetail::toString() { + std::string s("gpio."); + s += std::to_string(_index); if (_attributes.has(PinAttributes::ActiveLow)) { s += ":low"; } diff --git a/FluidNC/src/Pins/GPIOPinDetail.h b/FluidNC/src/Pins/GPIOPinDetail.h index 61af9696c..c4f04ef53 100644 --- a/FluidNC/src/Pins/GPIOPinDetail.h +++ b/FluidNC/src/Pins/GPIOPinDetail.h @@ -34,7 +34,7 @@ namespace Pins { void attachInterrupt(void (*callback)(void*), void* arg, int mode) override; void detachInterrupt() override; - String toString() override; + std::string toString() override; ~GPIOPinDetail() override { _claimed[_index] = false; } }; diff --git a/FluidNC/src/Pins/I2SOPinDetail.cpp b/FluidNC/src/Pins/I2SOPinDetail.cpp index f9667f0fe..02fad8e6a 100644 --- a/FluidNC/src/Pins/I2SOPinDetail.cpp +++ b/FluidNC/src/Pins/I2SOPinDetail.cpp @@ -79,8 +79,9 @@ namespace Pins { PinAttributes I2SOPinDetail::getAttr() const { return _attributes; } - String I2SOPinDetail::toString() { - auto s = String("I2SO.") + int(_index); + std::string I2SOPinDetail::toString() { + std::string s("I2SO."); + s += std::to_string(_index); if (_attributes.has(PinAttributes::ActiveLow)) { s += ":low"; } diff --git a/FluidNC/src/Pins/I2SOPinDetail.h b/FluidNC/src/Pins/I2SOPinDetail.h index e413200cd..e47e3d4fe 100644 --- a/FluidNC/src/Pins/I2SOPinDetail.h +++ b/FluidNC/src/Pins/I2SOPinDetail.h @@ -29,7 +29,7 @@ namespace Pins { void setAttr(PinAttributes value) override; PinAttributes getAttr() const override; - String toString() override; + std::string toString() override; ~I2SOPinDetail() override { _claimed[_index] = false; } }; diff --git a/FluidNC/src/Pins/PinDetail.h b/FluidNC/src/Pins/PinDetail.h index 3100945af..c0cf4cccb 100644 --- a/FluidNC/src/Pins/PinDetail.h +++ b/FluidNC/src/Pins/PinDetail.h @@ -7,9 +7,9 @@ #include "PinAttributes.h" #include "PinOptionsParser.h" -#include #include #include +#include #include typedef uint8_t pinnum_t; @@ -41,7 +41,7 @@ namespace Pins { virtual void attachInterrupt(void (*callback)(void*), void* arg, int mode); virtual void detachInterrupt(); - virtual String toString() = 0; + virtual std::string toString() = 0; inline int number() const { return _index; } diff --git a/FluidNC/src/Pins/PinOptionsParser.cpp b/FluidNC/src/Pins/PinOptionsParser.cpp index a7d21c2cb..e94e82933 100644 --- a/FluidNC/src/Pins/PinOptionsParser.cpp +++ b/FluidNC/src/Pins/PinOptionsParser.cpp @@ -8,63 +8,89 @@ #include namespace Pins { - PinOption::PinOption(char* start, const char* end) : _start(start), _end(end), _key(start), _value(start) { tokenize(); } + PinOption::PinOption(const char* start, const char* end) : _start(start), _end(end), _key(start), _value(start) { tokenize(); } + + // Copy the value into a null-terminated string, converting to lower case + const char* PinOption::value() const { + static char str[100]; + + int valuelen = _valueend - _value; + if (valuelen > 100) { + valuelen = 99; + } + const char* p = _value; + int i; + for (i = 0; i < valuelen; i++) { + str[i] = ::tolower(*p++); + } + str[i] = '\0'; + return str; + } void PinOption::tokenize() { if (_start != _end) { _key = _start; auto i = _start; - for (; i != _end && (*i) != ':' && (*i) != ';' && (*i) != '='; ++i) { - *i = ::tolower(*i); - } + for (; i != _end && (*i) != ':' && (*i) != ';' && (*i) != '='; ++i) {} if (i == _end) { // [start, end> is a key; value is nul - _value = _end; - _start = i; + _value = _end; + _valueend = _end; + _keyend = _end; + _start = i; } else if (*i == '=') { // Parsing a key-value pair. // // Mark end of the key, which is now in [start, end> - *i = '\0'; + _keyend = i; ++i; _value = i; // Parse the value: - for (; i != _end && (*i) != ':' && (*i) != ';'; ++i) { - *i = ::tolower(*i); - } + for (; i != _end && (*i) != ':' && (*i) != ';'; ++i) {} + _valueend = i; if (i != _end) { - *i = '\0'; _start = i + 1; } else { _start = i; } } else { // must be ':' or ';' - // [start, i> is a key; value is nul - _value = i; - *i = '\0'; - _start = i + 1; + // [start, i> is a key; value is nul + _keyend = _value = _valueend = i; + _start = i + 1; } } else { // Both key and value are nul. _key = _value = _end; + _keyend = _valueend = _end; } } - bool PinOption::is(const char* option) const { return !::strcmp(option, _key); } + bool PinOption::is(const char* option) const { + const char* k = _key; + while (*option && k != _keyend) { + if (::tolower(*k++) != ::tolower(*option++)) { + return false; + } + } + // If we get here, we have reached the end of either option or key + // and the initial substrings match ignoring case. + // If we are at the end of both, we have a match + return !*option && k == _keyend; + } int PinOption::iValue() const { // Parse to integer - return ::atoi(_value); + return ::atoi(value()); } double PinOption::dValue() const { // Parse to integer - return ::atof(_value); + return ::atof(value()); } PinOption& PinOption ::operator++() { @@ -72,7 +98,7 @@ namespace Pins { return *this; } - PinOptionsParser::PinOptionsParser(char* buffer, char* endBuffer) : _buffer(buffer), _bufferEnd(endBuffer) { + PinOptionsParser::PinOptionsParser(const char* buffer, const char* endBuffer) : _buffer(buffer), _bufferEnd(endBuffer) { // trim whitespaces: while (buffer != endBuffer && ::isspace(*buffer)) { ++buffer; @@ -81,7 +107,6 @@ namespace Pins { while (buffer - 1 != endBuffer && ::isspace(endBuffer[-1])) { --endBuffer; } - *endBuffer = '\0'; } _buffer = buffer; _bufferEnd = endBuffer; diff --git a/FluidNC/src/Pins/PinOptionsParser.h b/FluidNC/src/Pins/PinOptionsParser.h index a44fe20c3..73c430477 100644 --- a/FluidNC/src/Pins/PinOptionsParser.h +++ b/FluidNC/src/Pins/PinOptionsParser.h @@ -25,13 +25,15 @@ namespace Pins { class PinOption { friend class PinOptionsParser; - char* _start; + const char* _start; const char* _end; const char* _key; + const char* _keyend; const char* _value; + const char* _valueend; - PinOption(char* start, const char* end); + PinOption(const char* start, const char* end); void tokenize(); @@ -39,28 +41,27 @@ namespace Pins { inline const char* operator()() const { return _key; } bool is(const char* option) const; - int iValue() const; - double dValue() const; - inline const char* value() const { return _value; } + int iValue() const; + double dValue() const; + + const char* value() const; // Iterator support: inline PinOption const* operator->() const { return this; } inline PinOption operator*() const { return *this; } PinOption& operator++(); - bool operator==(const PinOption& o) const { return _key == o._key; } - bool operator!=(const PinOption& o) const { return _key != o._key; } + bool operator==(const PinOption& o) const { return _key == o._key && _keyend == o._keyend; } + bool operator!=(const PinOption& o) const { return _key != o._key || _keyend != o._keyend; } }; - // Options parser. This basically parses the options passed to the Pin class. Destroys - // the original options, and passes the options as lower case items to the enumerator. - // For the lazy people that want safe, reliable, easy parsing :-) + // This parses the options passed to the Pin class. class PinOptionsParser { - char* _buffer; - char* _bufferEnd; + const char* _buffer; + const char* _bufferEnd; public: - PinOptionsParser(char* buffer, char* endBuffer); + PinOptionsParser(const char* buffer, const char* endBuffer); inline PinOption begin() const { return PinOption(_buffer, _bufferEnd); } inline PinOption end() const { return PinOption(_bufferEnd, _bufferEnd); } diff --git a/FluidNC/src/Pins/VoidPinDetail.cpp b/FluidNC/src/Pins/VoidPinDetail.cpp index d92a8dbba..fa2df69bb 100644 --- a/FluidNC/src/Pins/VoidPinDetail.cpp +++ b/FluidNC/src/Pins/VoidPinDetail.cpp @@ -18,6 +18,6 @@ namespace Pins { void VoidPinDetail::setAttr(PinAttributes value) {} PinAttributes VoidPinDetail::getAttr() const { return PinAttributes::None; } - String VoidPinDetail::toString() { return "NO_PIN"; } + std::string VoidPinDetail::toString() { return std::string("NO_PIN"); } } diff --git a/FluidNC/src/Pins/VoidPinDetail.h b/FluidNC/src/Pins/VoidPinDetail.h index 988caceba..b4710bd48 100644 --- a/FluidNC/src/Pins/VoidPinDetail.h +++ b/FluidNC/src/Pins/VoidPinDetail.h @@ -20,7 +20,7 @@ namespace Pins { void setAttr(PinAttributes value) override; PinAttributes getAttr() const override; - String toString() override; + std::string toString() override; ~VoidPinDetail() override {} }; diff --git a/FluidNC/src/Settings.cpp b/FluidNC/src/Settings.cpp index b1b42cb3a..ded02e2a3 100644 --- a/FluidNC/src/Settings.cpp +++ b/FluidNC/src/Settings.cpp @@ -506,12 +506,12 @@ Error IPaddrSetting::setStringValue(char* s) { const char* IPaddrSetting::getDefaultString() { static char ipstr[50]; - strncpy(ipstr, IPAddress(_defaultValue).toString().c_str(), 50); + strncpy(ipstr, IP_string(IPAddress(_defaultValue)).c_str(), 50); return ipstr; } const char* IPaddrSetting::getStringValue() { static char ipstr[50]; - strncpy(ipstr, IPAddress(get()).toString().c_str(), 50); + strncpy(ipstr, IP_string(IPAddress(get())).c_str(), 50); return ipstr; } diff --git a/FluidNC/src/StackTrace/AssertionFailed.cpp b/FluidNC/src/StackTrace/AssertionFailed.cpp index 0a29eac30..2a093aaed 100644 --- a/FluidNC/src/StackTrace/AssertionFailed.cpp +++ b/FluidNC/src/StackTrace/AssertionFailed.cpp @@ -11,11 +11,10 @@ # ifdef BACKTRACE_ON_ASSERT # include "esp_debug_helpers.h" # endif -# include "WString.h" # include "stdio.h" AssertionFailed AssertionFailed::create(const char* condition, const char* msg, ...) { - String st = condition; + std::string st = condition; st += ": "; char tmp[255]; @@ -40,11 +39,10 @@ AssertionFailed AssertionFailed::create(const char* condition, const char* msg, # include # include # include -# include "WString.h" extern void DumpStackTrace(std::ostringstream& builder); -String stackTrace; +std::string stackTrace; std::exception AssertionFailed::create(const char* condition, const char* msg, ...) { std::ostringstream oss; diff --git a/FluidNC/src/StackTrace/AssertionFailed.h b/FluidNC/src/StackTrace/AssertionFailed.h index e438ded22..a3cc5bc4a 100644 --- a/FluidNC/src/StackTrace/AssertionFailed.h +++ b/FluidNC/src/StackTrace/AssertionFailed.h @@ -3,15 +3,15 @@ #pragma once -#include "WString.h" +#include #ifdef ESP32 class AssertionFailed { public: - String stackTrace; - String msg; + std::string stackTrace; + std::string msg; - AssertionFailed(String st, String message) : stackTrace(st), msg(message) {} + AssertionFailed(std::string st, std::string message) : stackTrace(st), msg(message) {} static AssertionFailed create(const char* condition) { return create(condition, "Assertion failed"); } static AssertionFailed create(const char* condition, const char* msg, ...); @@ -24,8 +24,8 @@ class AssertionFailed { class AssertionFailed { public: - String stackTrace; - String msg; + std::string stackTrace; + std::string msg; static std::exception create(const char* condition) { return create(condition, "Assertion failed"); } static std::exception create(const char* condition, const char* msg, ...); diff --git a/FluidNC/src/StringRange.h b/FluidNC/src/StringRange.h index f18e3c94b..ffc007a79 100644 --- a/FluidNC/src/StringRange.h +++ b/FluidNC/src/StringRange.h @@ -5,8 +5,6 @@ #include -#include "WString.h" - class StringRange { const char* start_; const char* end_; @@ -21,10 +19,26 @@ class StringRange { StringRange(const StringRange& o) = default; StringRange(StringRange&& o) = default; - StringRange(const String& str) : StringRange(str.begin(), str.end()) {} - StringRange& operator=(const StringRange& o) = default; StringRange& operator=(StringRange&& o) = default; + inline bool operator==(const char* s) { + const char* p = start_; + while (p != end_ && *s) { + if (::tolower(*p++) != ::tolower(*s++)) { + return false; + } + } + return !*s && p == end_; + } + inline bool operator!=(const char* s) { + const char* p = start_; + while (p != end_ && *s) { + if (::tolower(*p++) != ::tolower(*s++)) { + return true; + } + } + return *s || p != end_; + } int find(char c) const { const char* s = start_; @@ -89,6 +103,7 @@ class StringRange { const char* begin() const { return start_; } const char* end() const { return end_; } +#if 0 String str() const { // TODO: Check if we can eliminate this function. I'm pretty sure we can. auto len = length(); @@ -103,6 +118,22 @@ class StringRange { return tmp; } } +#else + std::string str() const { + // TODO: Check if we can eliminate this function. I'm pretty sure we can. + auto len = length(); + if (len == 0) { + return std::string(); + } else { + char* buf = new char[len + 1]; + memcpy(buf, begin(), len); + buf[len] = 0; + std::string tmp(buf); + delete[] buf; + return tmp; + } + } +#endif inline bool isUInteger(uint32_t& intval) { char* intEnd; diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 022f38b21..394690138 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -284,17 +284,17 @@ namespace WebUI { return true; } void Web_Server::sendWithOurAddress(const char* content) { - auto ip = WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP(); - String ipstr = ip.toString(); + auto ip = WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP(); + std::string ipstr = IP_string(ip); if (_port != 80) { ipstr += ":"; - ipstr += String(_port); + ipstr += std::to_string(_port); } - String scontent(content); - scontent.replace("$WEB_ADDRESS$", ipstr); - scontent.replace("$QUERY$", _webserver->uri()); - _webserver->send(200, "text/html", scontent); + std::string scontent(content); + replace_string_in_place(scontent, "$WEB_ADDRESS$", ipstr); + replace_string_in_place(scontent, "$QUERY$", _webserver->uri().c_str()); + _webserver->send(200, "text/html", scontent.c_str()); } // Captive Portal Page for use in AP mode @@ -394,7 +394,7 @@ namespace WebUI { "\r\n" "\r\n"; char uuid[37]; - const char* sip = WiFi.localIP().toString().c_str(); + const char* sip = IP_string(WiFi.localIP()).c_str(); uint32_t chipId = (uint16_t)(ESP.getEfuseMac() >> 32); sprintf(uuid, "38323636-4558-4dda-9188-cda0e6%02x%02x%02x", @@ -1155,7 +1155,7 @@ namespace WebUI { webWsChannels.push_front(wsChannel); wsChannel->sendTXT(s); s = "ACTIVE_ID:"; - s += wsChannel->id(); + s += std::to_string(wsChannel->id()); wsChannel->sendTXT(s); } } diff --git a/FluidNC/src/WebUI/WebSettings.cpp b/FluidNC/src/WebUI/WebSettings.cpp index f94aaea23..4cdbfdcf8 100644 --- a/FluidNC/src/WebUI/WebSettings.cpp +++ b/FluidNC/src/WebUI/WebSettings.cpp @@ -23,6 +23,8 @@ #include "WifiConfig.h" #include +#include +#include namespace WebUI { @@ -193,7 +195,9 @@ namespace WebUI { log_to(out, "Chip ID: ", (uint16_t)(ESP.getEfuseMac() >> 32)); log_to(out, "CPU Cores: ", ESP.getChipCores()); log_to(out, "CPU Frequency: ", ESP.getCpuFreqMHz() << "Mhz"); - log_to(out, "CPU Temperature: ", String(temperatureRead(), 1) << "°C"); + std::ostringstream msg; + msg << std::fixed << std::setprecision(1) << temperatureRead() << "°C"; + log_to(out, "CPU Temperature: ", msg.str()); log_to(out, "Free memory: ", formatBytes(ESP.getFreeHeap())); log_to(out, "SDK: ", ESP.getSdkVersion()); log_to(out, "Flash Size: ", formatBytes(ESP.getFlashChipSize())); diff --git a/FluidNC/src/WebUI/WifiConfig.cpp b/FluidNC/src/WebUI/WifiConfig.cpp index 9e928bef6..dd589533e 100644 --- a/FluidNC/src/WebUI/WifiConfig.cpp +++ b/FluidNC/src/WebUI/WifiConfig.cpp @@ -139,10 +139,10 @@ namespace WebUI { { "WPA2-ENTERPRISE", WIFI_AUTH_WPA2_ENTERPRISE }, }; - static void print_mac(Channel& out, const char* prefix, String mac) { log_to(out, prefix, " (" << mac << ")"); } + static void print_mac(Channel& out, const char* prefix, const char* mac) { log_to(out, prefix, " (" << mac << ")"); } static Error showIP(char* parameter, AuthenticationLevel auth_level, Channel& out) { // ESP111 - log_to(out, parameter, (WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP()).toString()); + log_to(out, parameter, IP_string(WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP())); return Error::Ok; } @@ -192,10 +192,10 @@ namespace WebUI { switch (mode) { case WIFI_STA: - print_mac(out, "Current WiFi Mode: STA", WiFi.macAddress()); + print_mac(out, "Current WiFi Mode: STA", WiFi.macAddress().c_str()); if (WiFi.isConnected()) { //in theory no need but ... - log_to(out, "Connected to: ", WiFi.SSID()); + log_to(out, "Connected to: ", WiFi.SSID().c_str()); log_to(out, "Signal: ", wifi_config.getSignal(WiFi.RSSI()) << "%"); uint8_t PhyMode; @@ -220,16 +220,16 @@ namespace WebUI { tcpip_adapter_dhcp_status_t dhcp_status; tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dhcp_status); log_to(out, "IP Mode: ", (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED ? "DHCP" : "Static")); - log_to(out, "IP: ", WiFi.localIP().toString()); - log_to(out, "Gateway: ", WiFi.gatewayIP().toString()); - log_to(out, "Mask: ", WiFi.subnetMask().toString()); - log_to(out, "DNS: ", WiFi.dnsIP().toString()); + log_to(out, "IP: ", IP_string(WiFi.localIP())); + log_to(out, "Gateway: ", IP_string(WiFi.gatewayIP())); + log_to(out, "Mask: ", IP_string(WiFi.subnetMask())); + log_to(out, "DNS: ", IP_string(WiFi.dnsIP())); } //this is web command so connection => no command - print_mac(out, "Disabled Mode: AP", WiFi.softAPmacAddress()); + print_mac(out, "Disabled Mode: AP", WiFi.softAPmacAddress().c_str()); break; case WIFI_AP: - print_mac(out, "Current WiFi Mode: AP", WiFi.softAPmacAddress()); + print_mac(out, "Current WiFi Mode: AP", WiFi.softAPmacAddress().c_str()); wifi_config_t conf; wifi_country_t country; @@ -270,12 +270,12 @@ namespace WebUI { tcpip_adapter_dhcps_get_status(TCPIP_ADAPTER_IF_AP, &dhcp_status); log_to(out, "DHCP Server: ", (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED ? "Started" : "Stopped")); - log_to(out, "IP: ", WiFi.softAPIP().toString()); + log_to(out, "IP: ", IP_string(WiFi.softAPIP())); tcpip_adapter_ip_info_t ip_AP; tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP); - log_to(out, "Gateway: ", IPAddress(ip_AP.gw.addr).toString()); - log_to(out, "Mask: ", IPAddress(ip_AP.netmask.addr).toString()); + log_to(out, "Gateway: ", IP_string(IPAddress(ip_AP.gw.addr))); + log_to(out, "Mask: ", IP_string(IPAddress(ip_AP.netmask.addr))); wifi_sta_list_t station; tcpip_adapter_sta_list_t tcpip_sta_list; @@ -286,15 +286,15 @@ namespace WebUI { for (int i = 0; i < station.num; i++) { log_to(out, "", - wifi_config.mac2str(tcpip_sta_list.sta[i].mac) << " " << IPAddress(tcpip_sta_list.sta[i].ip.addr).toString()); + wifi_config.mac2str(tcpip_sta_list.sta[i].mac) << " " << IP_string(IPAddress(tcpip_sta_list.sta[i].ip.addr))); } - print_mac(out, "Disabled Mode: STA", WiFi.macAddress()); + print_mac(out, "Disabled Mode: STA", WiFi.macAddress().c_str()); break; case WIFI_AP_STA: //we should not be in this state but just in case .... log_to(out, ""); - print_mac(out, "Mixed: STA", WiFi.macAddress()); - print_mac(out, "Mixed: AP", WiFi.softAPmacAddress()); + print_mac(out, "Mixed: STA", WiFi.macAddress().c_str()); + print_mac(out, "Mixed: AP", WiFi.softAPmacAddress().c_str()); break; default: //we should not be there if no wifi .... @@ -387,13 +387,13 @@ namespace WebUI { s += std::to_string(webServer.port() + 1) + ":"; switch (WiFi.getMode()) { case WIFI_MODE_AP: - s += WiFi.softAPIP().toString().c_str(); + s += IP_string(WiFi.softAPIP()); break; case WIFI_MODE_STA: - s += WiFi.localIP().toString().c_str(); + s += IP_string(WiFi.localIP()); break; case WIFI_MODE_APSTA: - s += WiFi.softAPIP().toString().c_str(); + s += IP_string(WiFi.softAPIP()); break; default: s += "0.0.0.0"; @@ -415,11 +415,11 @@ namespace WebUI { result += ":Status="; result += (WiFi.status() == WL_CONNECTED) ? "Connected" : "Not connected"; result += ":IP="; - result += WiFi.localIP().toString().c_str(); + result += IP_string(WiFi.localIP()); result += ":MAC="; - String tmp = WiFi.macAddress(); - tmp.replace(":", "-"); - result += tmp.c_str(); + std::string mac(WiFi.macAddress().c_str()); + std::replace(mac.begin(), mac.end(), ':', '-'); + result += mac; } return result; } @@ -436,11 +436,11 @@ namespace WebUI { esp_wifi_get_config(WIFI_IF_AP, &conf); result += (const char*)conf.ap.ssid; result += ":IP="; - result += WiFi.softAPIP().toString().c_str(); + result += IP_string(WiFi.softAPIP()); result += ":MAC="; - String tmp = WiFi.softAPmacAddress(); - tmp.replace(":", "-"); - result += tmp.c_str(); + std::string mac(WiFi.softAPmacAddress().c_str()); + std::replace(mac.begin(), mac.end(), ':', '-'); + result += mac; } return result; } @@ -585,7 +585,7 @@ namespace WebUI { log_info("Connection failed"); return false; case WL_CONNECTED: - log_info("Connected - IP is " << WiFi.localIP().toString()); + log_info("Connected - IP is " << IP_string(WiFi.localIP())); return true; default: if ((dot > 3) || (dot == 0)) { @@ -696,7 +696,7 @@ namespace WebUI { IPAddress mask; mask.fromString(DEFAULT_AP_MK); - log_info("AP SSID " << SSID << " IP " << ip.toString() << " mask " << mask.toString() << " channel " << channel); + log_info("AP SSID " << SSID << " IP " << IP_string(ip) << " mask " << IP_string(mask) << " channel " << channel); //Set static IP WiFi.softAPConfig(ip, ip, mask); From c08d3db1da61ecf279e516527ad450bd2abeaff4 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sat, 25 Mar 2023 09:32:24 -1000 Subject: [PATCH 17/51] Killed the last few residual String's --- FluidNC/src/Configuration/Completer.cpp | 2 +- FluidNC/src/Configuration/JsonGenerator.cpp | 2 +- FluidNC/src/Configuration/Parser.cpp | 4 +- FluidNC/src/Configuration/RuntimeSetting.cpp | 30 +++---- FluidNC/src/FluidPath.h | 2 - FluidNC/src/MyIOStream.h | 6 +- FluidNC/src/ProcessSettings.cpp | 14 ++-- FluidNC/src/Regex.cpp | 22 ++--- FluidNC/src/Regex.h | 2 +- FluidNC/src/Settings.h | 3 +- FluidNC/src/StringRange.h | 19 +---- FluidNC/src/WebUI/WebServer.cpp | 87 ++++++++++---------- FluidNC/src/WebUI/WebSettings.cpp | 2 +- 13 files changed, 91 insertions(+), 104 deletions(-) diff --git a/FluidNC/src/Configuration/Completer.cpp b/FluidNC/src/Configuration/Completer.cpp index da673332c..2c0bae939 100644 --- a/FluidNC/src/Configuration/Completer.cpp +++ b/FluidNC/src/Configuration/Completer.cpp @@ -6,7 +6,7 @@ #include "../Report.h" -#include +#include #include namespace Configuration { diff --git a/FluidNC/src/Configuration/JsonGenerator.cpp b/FluidNC/src/Configuration/JsonGenerator.cpp index 408ef4b72..54597fc0d 100644 --- a/FluidNC/src/Configuration/JsonGenerator.cpp +++ b/FluidNC/src/Configuration/JsonGenerator.cpp @@ -125,7 +125,7 @@ namespace Configuration { void JsonGenerator::item(const char* name, IPAddress& value) { enter(name); - _encoder.begin_webui(_currentPath, _currentPath, "A", value.toString().c_str()); + _encoder.begin_webui(_currentPath, _currentPath, "A", IP_string(value)); _encoder.end_object(); leave(); } diff --git a/FluidNC/src/Configuration/Parser.cpp b/FluidNC/src/Configuration/Parser.cpp index 5b28301df..9cdecaa5a 100644 --- a/FluidNC/src/Configuration/Parser.cpp +++ b/FluidNC/src/Configuration/Parser.cpp @@ -136,7 +136,7 @@ namespace Configuration { auto str = StringRange(token_.sValueStart_, token_.sValueEnd_); if (str.length() == 5 || str.length() == 3) { int32_t wordLenInt; - if (!str.subString(0, 1).isInteger(wordLenInt)) { + if (!str.substr(0, 1).isInteger(wordLenInt)) { parseError("Uart mode should be specified as [Bits Parity Stopbits] like [8N1]"); } else if (wordLenInt < 5 || wordLenInt > 8) { parseError("Number of data bits for uart is out of range. Expected format like [8N1]."); @@ -161,7 +161,7 @@ namespace Configuration { break; // Omits compiler warning. Never hit. } - auto stop = str.subString(2, str.length() - 2); + auto stop = str.substr(2, str.length() - 2); if (stop.equals("1")) { stopBits = UartStop::Bits1; } else if (stop.equals("1.5")) { diff --git a/FluidNC/src/Configuration/RuntimeSetting.cpp b/FluidNC/src/Configuration/RuntimeSetting.cpp index b8d677e4d..bfd80c17d 100644 --- a/FluidNC/src/Configuration/RuntimeSetting.cpp +++ b/FluidNC/src/Configuration/RuntimeSetting.cpp @@ -173,27 +173,27 @@ namespace Configuration { } } else { // It is distasteful to have this code that essentially duplicates - // Parser.cpp speedEntryValue(), albeit using String instead of - // StringRange. It would be better to have a single String version, + // Parser.cpp speedEntryValue(), albeit using std::string instead of + // StringRange. It might be better to have a single std::string version, // then pass it StringRange.str() - auto newStr = String(newValue_); + std::string newStr(newValue_); std::vector smValue; - while (newStr.trim(), newStr.length()) { - speedEntry entry; - String entryStr; - auto i = newStr.indexOf(' '); - if (i >= 0) { - entryStr = newStr.substring(0, i); - newStr = newStr.substring(i + 1); + while (newStr.length()) { + speedEntry entry; + std::string entryStr; + auto i = newStr.find(' '); + if (i != std::string::npos) { + entryStr = newStr.substr(0, i); + newStr = newStr.substr(i + 1); } else { entryStr = newStr; newStr = ""; } - String speed; - i = entryStr.indexOf('='); - Assert(i > 0, "Bad speed map entry"); - entry.speed = entryStr.substring(0, i).toInt(); - entry.percent = entryStr.substring(i + 1).toFloat(); + std::string speed; + i = entryStr.find('='); + Assert(i != std::string::npos, "Bad speed map entry"); + entry.speed = ::atoi(entryStr.substr(0, i).c_str()); + entry.percent = ::atof(entryStr.substr(i + 1).c_str()); smValue.push_back(entry); } value = smValue; diff --git a/FluidNC/src/FluidPath.h b/FluidNC/src/FluidPath.h index dc5aa8141..0701eceba 100644 --- a/FluidNC/src/FluidPath.h +++ b/FluidNC/src/FluidPath.h @@ -9,10 +9,8 @@ namespace stdfs = std::filesystem; class FluidPath : public stdfs::path { public: FluidPath(const char* name, const char* fs, std::error_code& ec) noexcept : FluidPath(name, fs, &ec) {} - // FluidPath(String name, const char* fs, std::error_code& ec) noexcept : FluidPath(name.c_str(), fs, &ec) {} FluidPath(const std::string& name, const char* fs, std::error_code& ec) noexcept : FluidPath(name.c_str(), fs, &ec) {} FluidPath(const char* name, const char* fs) : FluidPath(name, fs, nullptr) {} - // FluidPath(String name, const char* fs) : FluidPath(name.c_str(), fs) {} FluidPath(const std::string& name, const char* fs) : FluidPath(name.c_str(), fs) {} ~FluidPath(); diff --git a/FluidNC/src/MyIOStream.h b/FluidNC/src/MyIOStream.h index 515d813e3..157bc6045 100644 --- a/FluidNC/src/MyIOStream.h +++ b/FluidNC/src/MyIOStream.h @@ -10,6 +10,8 @@ #include "Pin.h" #include "StringRange.h" +std::string IP_string(uint32_t ipaddr); + inline Print& operator<<(Print& lhs, char c) { lhs.print(c); return lhs; @@ -62,8 +64,8 @@ inline Print& operator<<(Print& lhs, const Pin& v) { return lhs; } -inline Print& operator<<(Print& lhs, IPAddress a) { - lhs.print(a.toString()); +inline Print& operator<<(Print& lhs, IPAddress v) { + lhs.print(IP_string(v).c_str()); return lhs; } diff --git a/FluidNC/src/ProcessSettings.cpp b/FluidNC/src/ProcessSettings.cpp index 0fa05f133..892293d18 100644 --- a/FluidNC/src/ProcessSettings.cpp +++ b/FluidNC/src/ProcessSettings.cpp @@ -927,16 +927,16 @@ Error do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL // text form of the name, not to the nnn and ESPnnn forms. Error retval = Error::InvalidStatement; if (!value) { - auto lcKey = String(key); - lcKey.toLowerCase(); bool found = false; for (Setting* s = Setting::List; s; s = s->next()) { - auto lcTest = String(s->getName()); - lcTest.toLowerCase(); - - if (regexMatch(lcKey.c_str(), lcTest.c_str())) { + auto test = s->getName(); + // The C++ standard regular expression library supports many more + // regular expression forms than the simple one in Regex.cpp, but + // consumes a lot of FLASH. The extra capability is rarely useful + // especially now that there are only a few NVS settings. + if (regexMatch(key, test, false)) { const char* displayValue = auth_failed(s, value, auth_level) ? "" : s->getStringValue(); - show_setting(s->getName(), displayValue, NULL, out); + show_setting(test, displayValue, NULL, out); found = true; } } diff --git a/FluidNC/src/Regex.cpp b/FluidNC/src/Regex.cpp index 7f942ccc2..1d625b85c 100644 --- a/FluidNC/src/Regex.cpp +++ b/FluidNC/src/Regex.cpp @@ -16,12 +16,14 @@ // "bare * wildcard" is similar to filename wildcarding in many shells // and CLIs. -static bool matchHere(const char* regexp, const char* text); +#include + +static bool matchHere(const char* regexp, const char* text, bool case_sensitive); // matchStar - search for *regexp at beginning of text -static bool matchStar(const char* regexp, const char* text) { +static bool matchStar(const char* regexp, const char* text, bool case_sensitive) { do { - if (matchHere(regexp, text)) { + if (matchHere(regexp, text, case_sensitive)) { return true; } } while (*text++ != '\0'); @@ -29,30 +31,30 @@ static bool matchStar(const char* regexp, const char* text) { } // matchHere - search for regex at beginning of text -static bool matchHere(const char* regexp, const char* text) { +static bool matchHere(const char* regexp, const char* text, bool case_sensitive) { if (regexp[0] == '\0') { return true; } if (regexp[0] == '*') { - return matchStar(regexp + 1, text); + return matchStar(regexp + 1, text, case_sensitive); } if (regexp[0] == '$' && regexp[1] == '\0') { return *text == '\0'; } - if (*text != '\0' && (regexp[0] == *text)) { - return matchHere(++regexp, ++text); + if (*text != '\0' && (case_sensitive ? regexp[0] == *text : tolower(regexp[0]) == tolower(*text))) { + return matchHere(++regexp, ++text, case_sensitive); } return false; } // match - search for regular expression anywhere in text // Returns true if text contains the regular expression regexp -bool regexMatch(const char* regexp, const char* text) { +bool regexMatch(const char* regexp, const char* text, bool case_sensitive) { if (regexp[0] == '^') { - return matchHere(++regexp, text); + return matchHere(++regexp, text, case_sensitive); } do { - if (matchHere(regexp, text)) { + if (matchHere(regexp, text, case_sensitive)) { return true; } } while (*text++ != '\0'); diff --git a/FluidNC/src/Regex.h b/FluidNC/src/Regex.h index 9c0c5d131..e98d26a7e 100644 --- a/FluidNC/src/Regex.h +++ b/FluidNC/src/Regex.h @@ -2,4 +2,4 @@ // See Regex.cpp for attribution, description and discussion // Returns true if text contains the regular expression regexp -bool regexMatch(const char* regexp, const char* text); +bool regexMatch(const char* regexp, const char* text, bool case_sensitive = true); diff --git a/FluidNC/src/Settings.h b/FluidNC/src/Settings.h index 4ceb360c5..19577f3cb 100644 --- a/FluidNC/src/Settings.h +++ b/FluidNC/src/Settings.h @@ -154,8 +154,7 @@ class Setting : public Word { virtual void addWebui(WebUI::JSONencoder*) {}; virtual Error setStringValue(char* value) = 0; - Error setStringValue(String s) { return setStringValue(s.c_str()); } - virtual const char* getStringValue() = 0; + virtual const char* getStringValue() = 0; virtual const char* getCompatibleValue() { return getStringValue(); } virtual const char* getDefaultString() = 0; }; diff --git a/FluidNC/src/StringRange.h b/FluidNC/src/StringRange.h index ffc007a79..9e81c74a0 100644 --- a/FluidNC/src/StringRange.h +++ b/FluidNC/src/StringRange.h @@ -46,7 +46,7 @@ class StringRange { return (*s) ? (s - start_) : -1; } - StringRange subString(int index, int length) const { + StringRange substr(int index, int length) const { const char* s = start_ + index; if (s > end_) { s = end_; @@ -103,22 +103,6 @@ class StringRange { const char* begin() const { return start_; } const char* end() const { return end_; } -#if 0 - String str() const { - // TODO: Check if we can eliminate this function. I'm pretty sure we can. - auto len = length(); - if (len == 0) { - return String(); - } else { - char* buf = new char[len + 1]; - memcpy(buf, begin(), len); - buf[len] = 0; - String tmp(buf); - delete[] buf; - return tmp; - } - } -#else std::string str() const { // TODO: Check if we can eliminate this function. I'm pretty sure we can. auto len = length(); @@ -133,7 +117,6 @@ class StringRange { return tmp; } } -#endif inline bool isUInteger(uint32_t& intval) { char* intEnd; diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 394690138..2e0341554 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -339,9 +339,9 @@ namespace WebUI { return; } - String path = _webserver->urlDecode(_webserver->uri()); + std::string path(_webserver->urlDecode(_webserver->uri()).c_str()); - if (path.startsWith("/api/")) { + if (path.rfind("/api/", 0) == 0) { _webserver->send(404); return; } @@ -486,20 +486,20 @@ namespace WebUI { void Web_Server::handle_login() { # ifdef ENABLE_AUTHENTICATION const char* smsg; - String sUser, sPassword; + std::string sUser, sPassword; const char* auths; int code = 200; bool msg_alert_error = false; //disconnect can be done anytime no need to check credential if (_webserver->hasArg("DISCONNECT")) { - String cookie = _webserver->header("Cookie"); - int pos = cookie.indexOf("ESPSESSIONID="); - String sessionID; - if (pos != -1) { - int pos2 = cookie.indexOf(";", pos); - sessionID = cookie.substring(pos + strlen("ESPSESSIONID="), pos2); + std::string cookie(_webserver->header("Cookie").c_str()); + int pos = cookie.find("ESPSESSIONID="); + std::string sessionID; + if (pos != std::string::npos) { + int pos2 = cookie.find(";", pos); + sessionID = cookie.substr(pos + strlen("ESPSESSIONID="), pos2); } - ClearAuthIP(_webserver->client().remoteIP(), sessionID.c_str()); + ClearAuthIP(_webserver->client().remoteIP(), sessionID); _webserver->sendHeader("Set-Cookie", "ESPSESSIONID=0"); _webserver->sendHeader("Cache-Control", "no-cache"); sendAuth("Ok", "guest", ""); @@ -523,7 +523,7 @@ namespace WebUI { //is there a correct list of query? if (_webserver->hasArg("PASSWORD") && _webserver->hasArg("USER")) { //USER - sUser = _webserver->arg("USER"); + sUser = _webserver->arg("USER").c_str(); if (!((sUser == DEFAULT_ADMIN_LOGIN) || (sUser == DEFAULT_USER_LOGIN))) { msg_alert_error = true; smsg = "Error : Incorrect User"; @@ -532,9 +532,9 @@ namespace WebUI { if (msg_alert_error == false) { //Password - sPassword = _webserver->arg("PASSWORD"); - String sadminPassword = admin_password->get(); - String suserPassword = user_password->get(); + sPassword = _webserver->arg("PASSWORD").c_str(); + std::string sadminPassword(admin_password->get()); + std::string suserPassword(user_password->get()); if (!(sUser == DEFAULT_ADMIN_LOGIN && sPassword == sadminPassword) || (sUser == DEFAULT_USER_LOGIN && sPassword == suserPassword)) { @@ -551,7 +551,7 @@ namespace WebUI { //change password if (_webserver->hasArg("PASSWORD") && _webserver->hasArg("USER") && _webserver->hasArg("NEWPASSWORD") && (msg_alert_error == false)) { - String newpassword = _webserver->arg("NEWPASSWORD"); + std::string newpassword(_webserver->arg("NEWPASSWORD").c_str()); char pwdbuf[MAX_LOCAL_PASSWORD_LENGTH + 1]; newpassword.toCharArray(pwdbuf, MAX_LOCAL_PASSWORD_LENGTH + 1); @@ -593,8 +593,8 @@ namespace WebUI { strcpy(current_auth->userID, sUser.c_str()); current_auth->last_time = millis(); if (AddAuthIP(current_auth)) { - String tmps = "ESPSESSIONID="; - tmps += current_auth->sessionID; + std::string tmps = "ESPSESSIONID="; + tmps += current_auth->sessionID.c_str(); _webserver->sendHeader("Set-Cookie", tmps); _webserver->sendHeader("Cache-Control", "no-cache"); switch (current_auth->level) { @@ -623,12 +623,12 @@ namespace WebUI { sendAuth("Ok", "guest", ""); } else { if (auth_level != AuthenticationLevel::LEVEL_GUEST) { - String cookie = _webserver->header("Cookie"); - int pos = cookie.indexOf("ESPSESSIONID="); - String sessionID; - if (pos != -1) { - int pos2 = cookie.indexOf(";", pos); - sessionID = cookie.substring(pos + strlen("ESPSESSIONID="), pos2); + std::string cookie(_webserver->header("Cookie").c_str()); + int pos = cookie.find("ESPSESSIONID="); + std::string sessionID; + if (pos != std::string::npos) { + int pos2 = cookie.find(";", pos); + sessionID = cookie.substr(pos + strlen("ESPSESSIONID="), pos2); AuthenticationIP* current_auth_info = GetAuth(_webserver->client().remoteIP(), sessionID.c_str()); if (current_auth_info != NULL) { sUser = current_auth_info->userID; @@ -712,14 +712,16 @@ namespace WebUI { } else { if ((_upload_status != UploadStatus::FAILED) || (upload.status == UPLOAD_FILE_START)) { if (upload.status == UPLOAD_FILE_START) { - String sizeargname = upload.filename + "S"; - size_t filesize = _webserver->hasArg(sizeargname) ? _webserver->arg(sizeargname).toInt() : 0; + std::string sizeargname(upload.filename.c_str()); + sizeargname += "S"; + size_t filesize = _webserver->hasArg(sizeargname.c_str()) ? _webserver->arg(sizeargname.c_str()).toInt() : 0; uploadStart(upload.filename.c_str(), filesize, fs); } else if (upload.status == UPLOAD_FILE_WRITE) { uploadWrite(upload.buf, upload.currentSize); } else if (upload.status == UPLOAD_FILE_END) { - String sizeargname = upload.filename + "S"; - size_t filesize = _webserver->hasArg(sizeargname) ? _webserver->arg(sizeargname).toInt() : 0; + std::string sizeargname(upload.filename.c_str()); + sizeargname += "S"; + size_t filesize = _webserver->hasArg(sizeargname.c_str()) ? _webserver->arg(sizeargname.c_str()).toInt() : 0; uploadEnd(filesize); } else { //Upload cancelled uploadStop(); @@ -803,10 +805,11 @@ namespace WebUI { //************** if (upload.status == UPLOAD_FILE_START) { log_info("Update Firmware"); - _upload_status = UploadStatus::ONGOING; - String sizeargname = upload.filename + "S"; - if (_webserver->hasArg(sizeargname)) { - maxSketchSpace = _webserver->arg(sizeargname).toInt(); + _upload_status = UploadStatus::ONGOING; + std::string sizeargname(upload.filename.c_str()); + sizeargname += "S"; + if (_webserver->hasArg(sizeargname.c_str())) { + maxSketchSpace = _webserver->arg(sizeargname.c_str()).toInt(); } //check space size_t flashsize = 0; @@ -888,8 +891,8 @@ namespace WebUI { std::error_code ec; - String path = ""; - std::string sstatus = "Ok"; + std::string path(""); + std::string sstatus("Ok"); if ((_upload_status == UploadStatus::FAILED) || (_upload_status == UploadStatus::FAILED)) { sstatus = "Upload failed"; } @@ -900,18 +903,18 @@ namespace WebUI { //get current path if (_webserver->hasArg("path")) { - path += _webserver->arg("path"); - path.trim(); - path.replace("//", "/"); + path += _webserver->arg("path").c_str(); + // path.trim(); + replace_string_in_place(path, "//", "/"); if (path[path.length() - 1] == '/') { - path = path.substring(0, path.length() - 1); + path = path.substr(0, path.length() - 1); } - if (path.startsWith("/")) { - path = path.substring(1); + if (path.length() & path[0] == '/') { + path = path.substr(1); } } - FluidPath fpath { path.c_str(), fs, ec }; + FluidPath fpath { path, fs, ec }; if (ec) { sendJSON(200, "{\"status\":\"No SD card\"}"); return; @@ -960,8 +963,8 @@ namespace WebUI { j.begin_array("files"); for (auto const& dir_entry : iter) { j.begin_object(); - j.member("name", dir_entry.path().filename().c_str()); - j.member("shortname", dir_entry.path().filename().c_str()); + j.member("name", dir_entry.path().filename()); + j.member("shortname", dir_entry.path().filename()); j.member("size", dir_entry.is_directory() ? -1 : dir_entry.file_size()); j.member("datetime", ""); j.end_object(); diff --git a/FluidNC/src/WebUI/WebSettings.cpp b/FluidNC/src/WebUI/WebSettings.cpp index 4cdbfdcf8..8d29868ef 100644 --- a/FluidNC/src/WebUI/WebSettings.cpp +++ b/FluidNC/src/WebUI/WebSettings.cpp @@ -275,7 +275,7 @@ namespace WebUI { log_to(out, "Missing file name!"); return Error::InvalidValue; } - String path = trim(parameter); + std::string path(parameter); if (path[0] != '/') { path = "/" + path; } From a53c526dc37df729673e899b121652820c353f9f Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sat, 25 Mar 2023 09:37:49 -1000 Subject: [PATCH 18/51] Removed explicit String() in OLED.cpp; the compiler will do the work --- FluidNC/src/OLED.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FluidNC/src/OLED.cpp b/FluidNC/src/OLED.cpp index 0d226523d..ec7c9a501 100644 --- a/FluidNC/src/OLED.cpp +++ b/FluidNC/src/OLED.cpp @@ -8,7 +8,7 @@ void OLED::show(Layout& layout, const char* msg) { } _oled->setTextAlignment(layout._align); _oled->setFont(layout._font); - _oled->drawString(layout._x, layout._y, String(msg)); + _oled->drawString(layout._x, layout._y, msg); } OLED::Layout OLED::bannerLayout128 = { 0, 0, 0, ArialMT_Plain_24, TEXT_ALIGN_CENTER }; @@ -126,7 +126,7 @@ void OLED::show_file() { } show(tickerLayout, _ticker); - wrapped_draw_string(14, _filename.c_str(), ArialMT_Plain_16); + wrapped_draw_string(14, _filename, ArialMT_Plain_16); _oled->drawProgressBar(0, 45, 120, 10, pct); } else { @@ -162,7 +162,7 @@ void OLED::show_dro(const float* axes, bool isMpos, bool* limits) { axis_msg += limits[axis] ? "L" : ":"; } _oled->setTextAlignment(TEXT_ALIGN_LEFT); - _oled->drawString(0, oled_y_pos, String(axis_msg.c_str())); + _oled->drawString(0, oled_y_pos, axis_msg.c_str()); _oled->setTextAlignment(TEXT_ALIGN_RIGHT); snprintf(axisVal, 20 - 1, "%.3f", axes[axis]); @@ -523,10 +523,10 @@ void OLED::wrapped_draw_string(int16_t y, const std::string& s, font_t font) { } } if (swidth < _width) { - _oled->drawString(0, y, String(s.c_str())); + _oled->drawString(0, y, s.c_str()); } else { - _oled->drawString(0, y, String(s.substr(0, i).c_str())); - _oled->drawString(0, y + font_height(font) - 1, String(s.substr(i, slen).c_str())); + _oled->drawString(0, y, s.substr(0, i).c_str()); + _oled->drawString(0, y + font_height(font) - 1, s.substr(i, slen).c_str()); } } From 745316a9858293aa7f10f1f972e046d5239297c6 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Mon, 27 Mar 2023 09:33:17 -1000 Subject: [PATCH 19/51] Merge pull request #844 from bdring/2209_Reg_Debug 2209 reg debug --- FluidNC/src/Motors/TMC2130Driver.cpp | 5 ++++- FluidNC/src/Motors/TMC2208Driver.cpp | 1 + FluidNC/src/Motors/TMC2209Driver.cpp | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/FluidNC/src/Motors/TMC2130Driver.cpp b/FluidNC/src/Motors/TMC2130Driver.cpp index b0d77866c..4741b6624 100644 --- a/FluidNC/src/Motors/TMC2130Driver.cpp +++ b/FluidNC/src/Motors/TMC2130Driver.cpp @@ -29,7 +29,9 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC2130Driver::test() { return checkVersion(0x11, tmc2130->version()); } + bool TMC2130Driver::test() { + return checkVersion(0x11, tmc2130->version()); + } void TMC2130Driver::set_registers(bool isHoming) { if (_has_errors) { @@ -42,6 +44,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2130->I_scale_analog(false); // do not scale via pot tmc2130->rms_current(run_i, TrinamicSpiDriver::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping diff --git a/FluidNC/src/Motors/TMC2208Driver.cpp b/FluidNC/src/Motors/TMC2208Driver.cpp index ef9b161a7..69dc04bb7 100644 --- a/FluidNC/src/Motors/TMC2208Driver.cpp +++ b/FluidNC/src/Motors/TMC2208Driver.cpp @@ -41,6 +41,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2208->I_scale_analog(false); // do not scale via pot tmc2208->rms_current(run_i, TrinamicBase::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index b8753882d..786342cbe 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -42,6 +42,7 @@ namespace MotorDrivers { // but the TMCStepper library expresses run current as (uint16_t) mA // and hold current as (float) fraction of run current. uint16_t run_i = (uint16_t)(_run_current * 1000.0); + tmc2209->I_scale_analog(false); // do not scale via pot tmc2209->rms_current(run_i, TrinamicBase::holdPercent()); // The TMCStepper library uses the value 0 to mean 1x microstepping @@ -72,6 +73,15 @@ namespace MotorDrivers { break; } } + + // dump the registers. This is helpful for people migrating to the Pro version + log_debug("CHOPCONF: 0x" << String(tmc2209->CHOPCONF(), HEX)); + log_debug("COOLCONF: 0x" << String(tmc2209->COOLCONF(), HEX)); + log_debug("TPWMTHRS: 0x" << String(tmc2209->TPWMTHRS(), HEX)); + log_debug("TCOOLTHRS: 0x" << String(tmc2209->TCOOLTHRS(), HEX)); + log_debug("GCONF: 0x" << String(tmc2209->GCONF(), HEX)); + log_debug("PWMCONF: 0x" << String(tmc2209->PWMCONF(), HEX)); + log_debug("IHOLD_IRUN: 0x" << String(tmc2209->IHOLD_IRUN(), HEX)); } void TMC2209Driver::debug_message() { From ada9dd3875e166f7cbc2bc0a0c6af31354153db0 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Mon, 27 Mar 2023 09:34:31 -1000 Subject: [PATCH 20/51] to_hex in new TMC2209 debug messages --- FluidNC/src/Motors/TMC2209Driver.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index 786342cbe..ea7984725 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -75,13 +75,13 @@ namespace MotorDrivers { } // dump the registers. This is helpful for people migrating to the Pro version - log_debug("CHOPCONF: 0x" << String(tmc2209->CHOPCONF(), HEX)); - log_debug("COOLCONF: 0x" << String(tmc2209->COOLCONF(), HEX)); - log_debug("TPWMTHRS: 0x" << String(tmc2209->TPWMTHRS(), HEX)); - log_debug("TCOOLTHRS: 0x" << String(tmc2209->TCOOLTHRS(), HEX)); - log_debug("GCONF: 0x" << String(tmc2209->GCONF(), HEX)); - log_debug("PWMCONF: 0x" << String(tmc2209->PWMCONF(), HEX)); - log_debug("IHOLD_IRUN: 0x" << String(tmc2209->IHOLD_IRUN(), HEX)); + log_debug("CHOPCONF: 0x" << to_hex(tmc2209->CHOPCONF())); + log_debug("COOLCONF: 0x" << to_hex(tmc2209->COOLCONF())); + log_debug("TPWMTHRS: 0x" << to_hex(tmc2209->TPWMTHRS())); + log_debug("TCOOLTHRS: 0x" << to_hex(tmc2209->TCOOLTHRS())); + log_debug("GCONF: 0x" << to_hex(tmc2209->GCONF())); + log_debug("PWMCONF: 0x" << to_hex(tmc2209->PWMCONF())); + log_debug("IHOLD_IRUN: 0x" << to_hex// (tmc2209->IHOLD_IRUN())); } void TMC2209Driver::debug_message() { From acf168e9a64a1ed147f2c804c1913354f1f1b7bc Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 5 Apr 2023 14:05:43 -1000 Subject: [PATCH 21/51] SWAG at S3 support --- FluidNC/esp32/delay_usecs.cpp | 59 +++++++ FluidNC/esp32/spi.cpp | 9 +- FluidNC/esp32/tmc_spi.cpp | 7 +- FluidNC/include/Driver/delay_usecs.h | 9 + FluidNC/src/I2SOut.cpp | 225 ++++++++++++++----------- FluidNC/src/Main.cpp | 1 + FluidNC/src/Motors/StandardStepper.cpp | 10 +- FluidNC/src/NutsBolts.cpp | 4 - FluidNC/src/NutsBolts.h | 38 +---- FluidNC/src/Spindles/DacSpindle.cpp | 8 +- platformio.ini | 25 +++ 11 files changed, 252 insertions(+), 143 deletions(-) create mode 100644 FluidNC/esp32/delay_usecs.cpp create mode 100644 FluidNC/include/Driver/delay_usecs.h diff --git a/FluidNC/esp32/delay_usecs.cpp b/FluidNC/esp32/delay_usecs.cpp new file mode 100644 index 000000000..984d086cf --- /dev/null +++ b/FluidNC/esp32/delay_usecs.cpp @@ -0,0 +1,59 @@ +#include "Driver/delay_usecs.h" + +#include // IRAM_ATTR +#include + +#include + +#if CONFIG_IDF_TARGET_ESP32 +# include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +# include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +# include "esp32s3/clk.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +# include "esp32c3/clk.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +# include "esp32h2/clk.h" +#endif + +uint32_t ticks_per_us; +int esp_clk_cpu_freq(void); + +void timing_init() { + ticks_per_us = esp_clk_cpu_freq() / 1000000; +} + +void IRAM_ATTR delay_us(int32_t us) { + spinUntil(usToEndTicks(us)); +} + +int32_t IRAM_ATTR usToCpuTicks(int32_t us) { + return us * ticks_per_us; +} + +int32_t IRAM_ATTR usToEndTicks(int32_t us) { + return getCpuTicks() + usToCpuTicks(us); +} + +// At the usual ESP32 clock rate of 240MHz, the range of this is +// just under 18 seconds, but it really should be used only for +// short delays up to a few tens of microseconds. + +void IRAM_ATTR spinUntil(int32_t endTicks) { + while ((getCpuTicks() - endTicks) < 0) { +#ifdef ESP32 + asm volatile("nop"); +#endif + } +} + +// Short delays measured using the CPU cycle counter. There is a ROM +// routine "esp_delay_us(us)" that almost does what what we need, +// except that it is in ROM and thus dodgy for use from ISRs. We +// duplicate the esp_delay_us() here, but placed in IRAM, inlined, +// and factored so it can be used in different ways. + +int32_t IRAM_ATTR getCpuTicks() { + return XTHAL_GET_CCOUNT(); +} diff --git a/FluidNC/esp32/spi.cpp b/FluidNC/esp32/spi.cpp index 718735d44..afdd54d72 100644 --- a/FluidNC/esp32/spi.cpp +++ b/FluidNC/esp32/spi.cpp @@ -3,10 +3,15 @@ #include "Driver/spi.h" -#include #include "driver/spi_common.h" #include "src/Config.h" +#include + +#ifdef CONFIG_IDF_TARGET_ESP32S3 +# define HSPI_HOST SPI2_HOST +#endif + bool spi_init_bus(pinnum_t sck_pin, pinnum_t miso_pin, pinnum_t mosi_pin, bool dma) { // Start the SPI bus with the pins defined here. Once it has been started, // those pins "stick" and subsequent attempts to restart it with defaults @@ -22,7 +27,7 @@ bool spi_init_bus(pinnum_t sck_pin, pinnum_t miso_pin, pinnum_t mosi_pin, bool d }; // Depends on the chip variant - return !spi_bus_initialize(HSPI_HOST, &bus_cfg, dma ? SPI_DMA_CH1 : SPI_DMA_DISABLED); + return !spi_bus_initialize(HSPI_HOST, &bus_cfg, dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED); } void spi_deinit_bus() { diff --git a/FluidNC/esp32/tmc_spi.cpp b/FluidNC/esp32/tmc_spi.cpp index 45ac63a8a..772f3698d 100644 --- a/FluidNC/esp32/tmc_spi.cpp +++ b/FluidNC/esp32/tmc_spi.cpp @@ -40,7 +40,12 @@ #include "hal/spi_ll.h" -spi_dev_t* hw = SPI_LL_GET_HW(HSPI_HOST); +#include +#ifdef CONFIG_IDF_TARGET_ESP32S3 +# define HSPI_HOST SPI2_HOST +#endif + +spi_dev_t* hw = &GPSPI2; static spi_ll_clock_val_t clk_reg_val = 0; diff --git a/FluidNC/include/Driver/delay_usecs.h b/FluidNC/include/Driver/delay_usecs.h new file mode 100644 index 000000000..072713ae6 --- /dev/null +++ b/FluidNC/include/Driver/delay_usecs.h @@ -0,0 +1,9 @@ +#include + +void timing_init(); +void spinUntil(int32_t endTicks); +void delay_us(int32_t us); + +int32_t usToCpuTicks(int32_t us); +int32_t usToEndTicks(int32_t us); +int32_t getCpuTicks(); diff --git a/FluidNC/src/I2SOut.cpp b/FluidNC/src/I2SOut.cpp index 40ef6e65f..3cf336f0a 100644 --- a/FluidNC/src/I2SOut.cpp +++ b/FluidNC/src/I2SOut.cpp @@ -5,44 +5,76 @@ #include "I2SOut.h" -#include "Config.h" -#include "Pin.h" -#include "Settings.h" -#include "SettingsDefinitions.h" -#include "Machine/MachineConfig.h" -#include "Stepper.h" - -#include // IRAM_ATTR - -#include -#include -#include -#include -#include -#include -#include "Driver/fluidnc_gpio.h" +#include + +#ifndef CONFIG_IDF_TARGET_ESP32 +// The newer ESP32 variants have quite different I2S hardware engines +// then the old ESP32 hardware. For now we stub out I2S support for new ESP32s + +uint8_t i2s_out_read(pinnum_t pin) { + return 0; +} +void i2s_out_write(pinnum_t pin, uint8_t val) {} +void i2s_out_push_sample(uint32_t usec) {} +void i2s_out_push() {} +void i2s_out_delay() {} +int i2s_out_set_passthrough() { + return 0; +} +i2s_out_pulser_status_t i2s_out_get_pulser_status() { + return PASSTHROUGH; +} +int i2s_out_set_stepping() { + return 0; +} +int i2s_out_set_pulse_period(uint32_t period) { + return 0; +} +int i2s_out_reset() { + return 0; +} +int i2s_out_init() { + return -1; +} +#else +# include "Config.h" +# include "Pin.h" +# include "Settings.h" +# include "SettingsDefinitions.h" +# include "Machine/MachineConfig.h" +# include "Stepper.h" + +# include // IRAM_ATTR + +# include +# include +# include +# include +# include +# include +# include "Driver/fluidnc_gpio.h" // The library routines are not in IRAM so they can crash when called from FLASH // The GCC intrinsic versions which are prefixed with __ are compiled inline -#define USE_INLINE_ATOMIC - -#ifdef USE_INLINE_ATOMIC -# define MEMORY_MODEL_FETCH __ATOMIC_RELAXED -# define MEMORY_MODEL_STORE __ATOMIC_RELAXED -# define ATOMIC_LOAD(var) __atomic_load_n(var, MEMORY_MODEL_FETCH) -# define ATOMIC_STORE(var, val) __atomic_store_n(var, val, MEMORY_MODEL_STORE) -# define ATOMIC_FETCH_AND(var, val) __atomic_fetch_and(var, val, MEMORY_MODEL_FETCH) -# define ATOMIC_FETCH_OR(var, val) __atomic_fetch_or(var, val, MEMORY_MODEL_FETCH) +# define USE_INLINE_ATOMIC + +# ifdef USE_INLINE_ATOMIC +# define MEMORY_MODEL_FETCH __ATOMIC_RELAXED +# define MEMORY_MODEL_STORE __ATOMIC_RELAXED +# define ATOMIC_LOAD(var) __atomic_load_n(var, MEMORY_MODEL_FETCH) +# define ATOMIC_STORE(var, val) __atomic_store_n(var, val, MEMORY_MODEL_STORE) +# define ATOMIC_FETCH_AND(var, val) __atomic_fetch_and(var, val, MEMORY_MODEL_FETCH) +# define ATOMIC_FETCH_OR(var, val) __atomic_fetch_or(var, val, MEMORY_MODEL_FETCH) static uint32_t i2s_out_port_data = 0; -#else -# include -# define ATOMIC_LOAD(var) atomic_load(var) -# define ATOMIC_STORE(var, val) atomic_store(var, val) -# define ATOMIC_FETCH_AND(var, val) atomic_fetch_and(var, val) -# define ATOMIC_FETCH_OR(var, val) atomic_fetch_or(var, val) +# else +# include +# define ATOMIC_LOAD(var) atomic_load(var) +# define ATOMIC_STORE(var, val) atomic_store(var, val) +# define ATOMIC_FETCH_AND(var, val) atomic_fetch_and(var, val) +# define ATOMIC_FETCH_OR(var, val) atomic_fetch_or(var, val) static std::atomic i2s_out_port_data = ATOMIC_VAR_INIT(0); -#endif +# endif // // Configrations for DMA connected I2S @@ -77,24 +109,24 @@ static intr_handle_t i2s_out_isr_handle; // inner lock static portMUX_TYPE i2s_out_spinlock = portMUX_INITIALIZER_UNLOCKED; -#define I2S_OUT_ENTER_CRITICAL() \ - do { \ - if (xPortInIsrContext()) { \ - portENTER_CRITICAL_ISR(&i2s_out_spinlock); \ - } else { \ - portENTER_CRITICAL(&i2s_out_spinlock); \ - } \ - } while (0) -#define I2S_OUT_EXIT_CRITICAL() \ - do { \ - if (xPortInIsrContext()) { \ - portEXIT_CRITICAL_ISR(&i2s_out_spinlock); \ - } else { \ - portEXIT_CRITICAL(&i2s_out_spinlock); \ - } \ - } while (0) -#define I2S_OUT_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&i2s_out_spinlock) -#define I2S_OUT_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&i2s_out_spinlock) +# define I2S_OUT_ENTER_CRITICAL() \ + do { \ + if (xPortInIsrContext()) { \ + portENTER_CRITICAL_ISR(&i2s_out_spinlock); \ + } else { \ + portENTER_CRITICAL(&i2s_out_spinlock); \ + } \ + } while (0) +# define I2S_OUT_EXIT_CRITICAL() \ + do { \ + if (xPortInIsrContext()) { \ + portEXIT_CRITICAL_ISR(&i2s_out_spinlock); \ + } else { \ + portEXIT_CRITICAL(&i2s_out_spinlock); \ + } \ + } while (0) +# define I2S_OUT_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&i2s_out_spinlock) +# define I2S_OUT_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&i2s_out_spinlock) static int i2s_out_initialized = 0; @@ -109,30 +141,30 @@ static volatile i2s_out_pulser_status_t i2s_out_pulser_status = PASSTHROUGH; // outer lock static portMUX_TYPE i2s_out_pulser_spinlock = portMUX_INITIALIZER_UNLOCKED; -#define I2S_OUT_PULSER_ENTER_CRITICAL() \ - do { \ - if (xPortInIsrContext()) { \ - portENTER_CRITICAL_ISR(&i2s_out_pulser_spinlock); \ - } else { \ - portENTER_CRITICAL(&i2s_out_pulser_spinlock); \ - } \ - } while (0) -#define I2S_OUT_PULSER_EXIT_CRITICAL() \ - do { \ - if (xPortInIsrContext()) { \ - portEXIT_CRITICAL_ISR(&i2s_out_pulser_spinlock); \ - } else { \ - portEXIT_CRITICAL(&i2s_out_pulser_spinlock); \ - } \ - } while (0) -#define I2S_OUT_PULSER_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&i2s_out_pulser_spinlock) -#define I2S_OUT_PULSER_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&i2s_out_pulser_spinlock) - -#if I2S_OUT_NUM_BITS == 16 -# define DATA_SHIFT 16 -#else -# define DATA_SHIFT 0 -#endif +# define I2S_OUT_PULSER_ENTER_CRITICAL() \ + do { \ + if (xPortInIsrContext()) { \ + portENTER_CRITICAL_ISR(&i2s_out_pulser_spinlock); \ + } else { \ + portENTER_CRITICAL(&i2s_out_pulser_spinlock); \ + } \ + } while (0) +# define I2S_OUT_PULSER_EXIT_CRITICAL() \ + do { \ + if (xPortInIsrContext()) { \ + portEXIT_CRITICAL_ISR(&i2s_out_pulser_spinlock); \ + } else { \ + portEXIT_CRITICAL(&i2s_out_pulser_spinlock); \ + } \ + } while (0) +# define I2S_OUT_PULSER_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&i2s_out_pulser_spinlock) +# define I2S_OUT_PULSER_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&i2s_out_pulser_spinlock) + +# if I2S_OUT_NUM_BITS == 16 +# define DATA_SHIFT 16 +# else +# define DATA_SHIFT 0 +# endif // // Internal functions @@ -418,14 +450,14 @@ static void IRAM_ATTR i2s_out_intr_handler(void* arg) { port_data = ATOMIC_LOAD(&i2s_out_port_data); } I2S_OUT_PULSER_EXIT_CRITICAL_ISR(); -#ifdef CONFIG_IDF_TARGET_ESP32 +# ifdef CONFIG_IDF_TARGET_ESP32 // lldesc_t.buf is const for S2. Perhaps we can get by // without replacing the data in the buffer since we are // already in an error situation. for (int i = 0; i < DMA_SAMPLE_COUNT; i++) { front_desc->buf[i] = port_data; } -#endif +# endif front_desc->length = I2S_OUT_DMABUF_LEN; } @@ -493,9 +525,9 @@ static void i2sOutTask(void* parameter) { I2S_OUT_PULSER_EXIT_CRITICAL(); // Unlock pulser status static UBaseType_t uxHighWaterMark = 0; -#ifdef DEBUG_TASK_STACK +# ifdef DEBUG_TASK_STACK reportTaskStackSize(uxHighWaterMark); -#endif +# endif } } @@ -753,12 +785,12 @@ int i2s_out_init(i2s_out_init_t& init_param) { I2S0.lc_conf.out_eof_mode = 1; // I2S_OUT_EOF_INT generated when DMA has popped all data from the FIFO; I2S0.conf2.lcd_en = 0; I2S0.conf2.camera_en = 0; -#ifdef SOC_I2S_SUPPORTS_PDM_TX +# ifdef SOC_I2S_SUPPORTS_PDM_TX // i2s_ll_tx_enable_pdm(dev, false); // i2s_ll_tx_enable_pdm(dev2, false); I2S0.pdm_conf.pcm2pdm_conv_en = 0; I2S0.pdm_conf.pdm2pcm_conv_en = 0; -#endif +# endif I2S0.fifo_conf.dscr_en = 0; @@ -772,19 +804,19 @@ int i2s_out_init(i2s_out_init_t& init_param) { I2S0.conf_single_data = init_param.init_val; } -#if I2S_OUT_NUM_BITS == 16 +# if I2S_OUT_NUM_BITS == 16 I2S0.fifo_conf.tx_fifo_mod = 0; // 0: 16-bit dual channel data, 3: 32-bit single channel data I2S0.fifo_conf.rx_fifo_mod = 0; // 0: 16-bit dual channel data, 3: 32-bit single channel data I2S0.sample_rate_conf.tx_bits_mod = 16; // default is 16-bits I2S0.sample_rate_conf.rx_bits_mod = 16; // default is 16-bits -#else +# else I2S0.fifo_conf.tx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data I2S0.fifo_conf.rx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data // Data width is 32-bit. Forgetting this setting will result in a 16-bit transfer. I2S0.sample_rate_conf.tx_bits_mod = 32; I2S0.sample_rate_conf.rx_bits_mod = 32; -#endif - I2S0.conf.tx_mono = 0; // Set this bit to enable transmitter’s mono mode in PCM standard mode. +# endif + I2S0.conf.tx_mono = 0; // Set this bit to enable transmitter’s mono mode in PCM standard mode. I2S0.conf_chan.rx_chan_mod = 1; // 1: right+right I2S0.conf.rx_mono = 0; @@ -798,14 +830,14 @@ int i2s_out_init(i2s_out_init_t& init_param) { I2S0.conf.tx_slave_mod = 0; // Master I2S0.fifo_conf.tx_fifo_mod_force_en = 1; //The bit should always be set to 1. -#ifdef SOC_I2S_SUPPORTS_PDM_RX +# ifdef SOC_I2S_SUPPORTS_PDM_RX //i2s_ll_rx_enable_pdm(dev, false); I2S0.pdm_conf.rx_pdm_en = 0; // Set this bit to enable receiver’s PDM mode. -#endif -#ifdef SOC_I2S_SUPPORTS_PDM_TX +# endif +# ifdef SOC_I2S_SUPPORTS_PDM_TX //i2s_ll_tx_enable_pdm(dev, false); I2S0.pdm_conf.tx_pdm_en = 0; // Set this bit to enable transmitter’s PDM mode. -#endif +# endif // I2S_COMM_FORMAT_I2S_LSB I2S0.conf.tx_short_sync = 0; // Set this bit to enable transmitter in PCM standard mode. @@ -818,20 +850,20 @@ int i2s_out_init(i2s_out_init_t& init_param) { // // set clock (fi2s) 160MHz / 5 -#ifdef CONFIG_IDF_TARGET_ESP32 +# ifdef CONFIG_IDF_TARGET_ESP32 // i2s_ll_rx_clk_set_src(dev, I2S_CLK_D2CLK); I2S0.clkm_conf.clka_en = 0; // Use 160 MHz PLL_D2_CLK as reference -#endif +# endif // N + b/a = 0 -#if I2S_OUT_NUM_BITS == 16 +# if I2S_OUT_NUM_BITS == 16 // N = 10 I2S0.clkm_conf.clkm_div_num = 10; // minimum value of 2, reset value of 4, max 256 (I²S clock divider’s integral value) -#else +# else // N = 5 // 5 could be changed to 2 to make I2SO pulse at 312.5 kHZ instead of 125 kHz, but doing so would // require some changes to deal with pulse lengths that are not an integral number of microseconds. I2S0.clkm_conf.clkm_div_num = 5; // minimum value of 2, reset value of 4, max 256 (I²S clock divider’s integral value) -#endif +# endif // b/a = 0 I2S0.clkm_conf.clkm_div_b = 0; // 0 at reset I2S0.clkm_conf.clkm_div_a = 0; // 0 at reset, what about divide by 0? (not an issue) @@ -876,9 +908,9 @@ int i2s_out_init(i2s_out_init_t& init_param) { return 0; } -#ifndef I2S_OUT_INIT_VAL -# define I2S_OUT_INIT_VAL 0 -#endif +# ifndef I2S_OUT_INIT_VAL +# define I2S_OUT_INIT_VAL 0 +# endif /* Initialize I2S out by default parameters. @@ -915,3 +947,4 @@ int i2s_out_init() { return i2s_out_init(default_param); } } +#endif diff --git a/FluidNC/src/Main.cpp b/FluidNC/src/Main.cpp index 5647064b6..1462e3c95 100644 --- a/FluidNC/src/Main.cpp +++ b/FluidNC/src/Main.cpp @@ -30,6 +30,7 @@ extern void make_user_commands(); void setup() { disableCore0WDT(); try { + timing_init(); uartInit(); // Setup serial port Uart0.println(); // create some white space after ESP32 boot info diff --git a/FluidNC/src/Motors/StandardStepper.cpp b/FluidNC/src/Motors/StandardStepper.cpp index 3c9bbfdcb..fa519ffcc 100644 --- a/FluidNC/src/Motors/StandardStepper.cpp +++ b/FluidNC/src/Motors/StandardStepper.cpp @@ -12,6 +12,7 @@ #include "../Stepping.h" // config->_stepping->_engine #include // gpio +#include // CONFIG_IDF_TARGET_* using namespace Machine; @@ -42,7 +43,7 @@ namespace MotorDrivers { .idle_level = invert_step ? RMT_IDLE_LEVEL_HIGH : RMT_IDLE_LEVEL_LOW, .carrier_duty_percent = 50, #if SOC_RMT_SUPPORT_TX_LOOP_COUNT - .loop_count = DONT_KNOW_YET_SINCE_ESP32_DOES_NOT_HAVE_IT, + .loop_count = 1, #endif .carrier_en = false, .loop_en = false, @@ -92,9 +93,16 @@ namespace MotorDrivers { void IRAM_ATTR StandardStepper::step() { if (config->_stepping->_engine == Stepping::RMT && _rmt_chan_num != RMT_CHANNEL_MAX) { +#ifdef CONFIG_IDF_TARGET_ESP32 RMT.conf_ch[_rmt_chan_num].conf1.mem_rd_rst = 1; RMT.conf_ch[_rmt_chan_num].conf1.mem_rd_rst = 0; RMT.conf_ch[_rmt_chan_num].conf1.tx_start = 1; +#endif +#ifdef CONFIG_IDF_TARGET_ESP32S3 + RMT.chnconf0[_rmt_chan_num].mem_rd_rst_n = 1; + RMT.chnconf0[_rmt_chan_num].mem_rd_rst_n = 0; + RMT.chnconf0[_rmt_chan_num].tx_start_n = 1; +#endif } else { _step_pin.on(); } diff --git a/FluidNC/src/NutsBolts.cpp b/FluidNC/src/NutsBolts.cpp index b5330f013..fb7271d4e 100644 --- a/FluidNC/src/NutsBolts.cpp +++ b/FluidNC/src/NutsBolts.cpp @@ -94,10 +94,6 @@ bool read_float(const char* line, size_t* char_counter, float* float_ptr) { return true; } -void IRAM_ATTR delay_us(int32_t us) { - spinUntil(usToEndTicks(us)); -} - void delay_ms(uint16_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); } diff --git a/FluidNC/src/NutsBolts.h b/FluidNC/src/NutsBolts.h index 388ee8714..248649d65 100644 --- a/FluidNC/src/NutsBolts.h +++ b/FluidNC/src/NutsBolts.h @@ -7,9 +7,8 @@ // #define true 1 #include -#include -#include #include "Logging.h" +#include "Driver/delay_usecs.h" enum class DwellMode : uint8_t { Dwell = 0, // (Default: Must be zero) @@ -93,41 +92,6 @@ void swap(T& a, T& b) { b = c; } -// Short delays measured using the CPU cycle counter. There is a ROM -// routine "esp_delay_us(us)" that almost does what what we need, -// except that it is in ROM and thus dodgy for use from ISRs. We -// duplicate the esp_delay_us() here, but placed in IRAM, inlined, -// and factored so it can be used in different ways. - -inline int32_t IRAM_ATTR getCpuTicks() { - return XTHAL_GET_CCOUNT(); -} - -extern uint32_t g_ticks_per_us_pro; // For CPU 0 - typically 240 MHz -extern uint32_t g_ticks_per_us_app; // For CPU 1 - typically 240 MHz - -inline int32_t IRAM_ATTR usToCpuTicks(int32_t us) { - return us * g_ticks_per_us_pro; -} - -inline int32_t IRAM_ATTR usToEndTicks(int32_t us) { - return getCpuTicks() + usToCpuTicks(us); -} - -// At the usual ESP32 clock rate of 240MHz, the range of this is -// just under 18 seconds, but it really should be used only for -// short delays up to a few tens of microseconds. - -inline void IRAM_ATTR spinUntil(int32_t endTicks) { - while ((getCpuTicks() - endTicks) < 0) { -#ifdef ESP32 - asm volatile("nop"); -#endif - } -} - -void delay_us(int32_t us); - template T myMap(T x, T in_min, T in_max, T out_min, T out_max) { // DrawBot_Badge return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; diff --git a/FluidNC/src/Spindles/DacSpindle.cpp b/FluidNC/src/Spindles/DacSpindle.cpp index 1c5979e3b..dedf15131 100644 --- a/FluidNC/src/Spindles/DacSpindle.cpp +++ b/FluidNC/src/Spindles/DacSpindle.cpp @@ -9,9 +9,12 @@ a 0-5V or 0-10V value to control the spindle. You would use an Op Amp type circuit to get from the 0.3.3V of the ESP32 to that voltage. */ -#include "DacSpindle.h" +#include +#ifdef CONFIG_IDF_TARGET_ESP32 -#include // dacWrite +# include "DacSpindle.h" + +# include // dacWrite namespace Spindles { // ======================================== Dac ====================================== @@ -58,3 +61,4 @@ namespace Spindles { SpindleFactory::InstanceBuilder registration("DAC"); } } +#endif diff --git a/platformio.ini b/platformio.ini index b878665e7..cc81492d1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -72,6 +72,11 @@ extra_scripts = FluidNC/ld/esp32/vtable_in_dram.py extends = common_esp32_base board = esp32dev +[common_esp32_s3] +extends = common_esp32_base +board = esp32-s3-devkitc-1 +lib_deps = ${common.lib_deps} + [common_esp32_s2] extends = common_esp32_base board = esp32-s2-saola-1 @@ -126,6 +131,26 @@ extends = common_esp32 lib_deps = ${common.lib_deps} ${common.bt_deps} ${common.wifi_deps} build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH -DENABLE_WIFI +[env:noradio_s3] +extends = common_esp32_s3 +lib_deps = ${common.lib_deps} + +[env:wifi_s3] +board_build.filesystem = littlefs +extends = common_esp32_s3 +lib_deps = ${common.lib_deps} ${common.wifi_deps} +build_flags = ${common_esp32.build_flags} -DENABLE_WIFI -DUSE_LITTLEFS + +[env:bt_s3] +extends = common_esp32_s3 +lib_deps = ${common.lib_deps} ${common.bt_deps} +build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH + +[env:wifibt_s3] +extends = common_esp32_s3 +lib_deps = ${common.lib_deps} ${common.bt_deps} ${common.wifi_deps} +build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH -DENABLE_WIFI + [env:native] platform = native test_build_src = true From 9aa2a006d78b990e034a7b4012bbf1ad2e81f853 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 5 Apr 2023 14:11:13 -1000 Subject: [PATCH 22/51] Fixed typo in a use of to_hex() --- FluidNC/src/Motors/TMC2209Driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index ea7984725..f6122518c 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -81,7 +81,7 @@ namespace MotorDrivers { log_debug("TCOOLTHRS: 0x" << to_hex(tmc2209->TCOOLTHRS())); log_debug("GCONF: 0x" << to_hex(tmc2209->GCONF())); log_debug("PWMCONF: 0x" << to_hex(tmc2209->PWMCONF())); - log_debug("IHOLD_IRUN: 0x" << to_hex// (tmc2209->IHOLD_IRUN())); + log_debug("IHOLD_IRUN: 0x" << to_hex(tmc2209->IHOLD_IRUN())); } void TMC2209Driver::debug_message() { From abc6543c490727547901d0c54c01e3d36d786656 Mon Sep 17 00:00:00 2001 From: bdring Date: Fri, 7 Apr 2023 12:21:47 -0500 Subject: [PATCH 23/51] Fix timer_ms setting in object derived from Servo. The Servo `group()` function needs to be called in overridden functions to get the timer_ms setting. --- FluidNC/src/Motors/Dynamixel2.h | 4 ++-- FluidNC/src/Motors/RcServo.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index aa5dcd3b9..d986f42a2 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -114,10 +114,10 @@ namespace MotorDrivers { void group(Configuration::HandlerBase& handler) override { handler.item("uart_num", _uart_num); handler.item("id", _id); - handler.item("count_min", _countMin); handler.item("count_max", _countMax); - handler.item("timer_ms", _timer_ms); + + Servo::group(handler); } // Name of the configurable. Must match the name registered in the cpp file. diff --git a/FluidNC/src/Motors/RcServo.h b/FluidNC/src/Motors/RcServo.h index 8fb83f117..f8253e89f 100644 --- a/FluidNC/src/Motors/RcServo.h +++ b/FluidNC/src/Motors/RcServo.h @@ -54,6 +54,8 @@ namespace MotorDrivers { handler.item("pwm_hz", _pwm_freq, SERVO_PWM_FREQ_MIN, SERVO_PWM_FREQ_MAX); handler.item("min_pulse_us", _min_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); handler.item("max_pulse_us", _max_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); + + Servo::group(handler); } // Name of the configurable. Must match the name registered in the cpp file. From 43aa6160171f89daeb0993b1460bea92d2870fc0 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 9 Apr 2023 09:20:56 -1000 Subject: [PATCH 24/51] Update with fixes from various branches --- FluidNC/esp32/tmc_spi.cpp | 84 +---------------------------- FluidNC/esp32/tmc_spi_support.c | 93 +++++++++++++++++++++++++++++++++ FluidNC/esp32/tmc_spi_support.h | 16 ++++++ FluidNC/src/Motors/Dynamixel2.h | 4 +- FluidNC/src/Motors/RcServo.h | 2 + platformio.ini | 23 ++++---- 6 files changed, 128 insertions(+), 94 deletions(-) create mode 100644 FluidNC/esp32/tmc_spi_support.c create mode 100644 FluidNC/esp32/tmc_spi_support.h diff --git a/FluidNC/esp32/tmc_spi.cpp b/FluidNC/esp32/tmc_spi.cpp index 772f3698d..d0b700d4f 100644 --- a/FluidNC/esp32/tmc_spi.cpp +++ b/FluidNC/esp32/tmc_spi.cpp @@ -36,91 +36,9 @@ // with SCK, MOSI, and MISO pins assigned, via SPIBus.cpp #include "src/Config.h" +#include "esp32/tmc_spi_support.h" #include // https://github.com/teemuatlut/TMCStepper -#include "hal/spi_ll.h" - -#include -#ifdef CONFIG_IDF_TARGET_ESP32S3 -# define HSPI_HOST SPI2_HOST -#endif - -spi_dev_t* hw = &GPSPI2; - -static spi_ll_clock_val_t clk_reg_val = 0; - -// Establish the SPI bus configuration needed for TMC device access -// This should be done one before every TMC read or write operation, -// to reconfigure the bus from whatever mode the SD card driver used. -static void tmc_spi_bus_setup() { -#if 0 - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], PIN_FUNC_GPIO); - gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT); - gpio_matrix_out(bus_config->miso_io_num, io_signal[host].spiq_out, false, false); - gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false); -#endif - - if (clk_reg_val == 0) { - spi_ll_master_cal_clock(SPI_LL_PERIPH_CLK_FREQ, 2000000, 128, &clk_reg_val); - } - spi_ll_master_set_clock_by_reg(hw, &clk_reg_val); - - spi_ll_master_init(hw); - spi_ll_master_set_mode(hw, 3); - spi_ll_set_half_duplex(hw, false); - - spi_ll_master_set_line_mode(hw, { 1, 1, 1 }); // Single-line transfers; not DIO or QIO -} - -// Perform a full-duplex transfer from out/out_bitlen to in/in_bitlen -// If in_bitlen is 0, the input data will be ignored -static void tmc_spi_transfer_data(uint8_t* out, int out_bitlen, uint8_t* in, int in_bitlen) { - spi_ll_set_mosi_bitlen(hw, out_bitlen); - - spi_ll_set_miso_bitlen(hw, in_bitlen); - - spi_ll_set_addr_bitlen(hw, 0); - spi_ll_set_command_bitlen(hw, 0); - - spi_ll_write_buffer(hw, out, out_bitlen); - spi_ll_enable_mosi(hw, 1); - if (in_bitlen) { - spi_ll_enable_miso(hw, 1); - } - - spi_ll_clear_int_stat(hw); - spi_ll_master_user_start(hw); - while (!spi_ll_usr_is_done(hw)) {} - - spi_ll_read_buffer(hw, in, in_bitlen); // No-op if in_bitlen is 0 -} - -// Do a single 5-byte (reg# + data) access to a TMC register, -// accounting for the number of TMC devices (index) daisy-chained -// before the target device. For reads, this is the first register -// access that latches the register data into the output register. -static void tmc_spi_rw_reg(uint8_t cmd, uint32_t data, int index) { - int before = index > 0 ? index - 1 : 0; - - const size_t packetLen = 5; - size_t dummy_out_bytes = before * packetLen; - size_t total_bytes = (before + 1) * packetLen; - size_t total_bits = total_bytes * 8; - - uint8_t out[total_bytes] = { 0 }; - - // The data always starts at the beginning of the buffer then - // the trailing 0 bytes will push it through the chain to the - // target chip. - out[0] = cmd; - out[1] = data >> 24; - out[2] = data >> 16; - out[3] = data >> 8; - out[4] = data >> 0; - - tmc_spi_transfer_data(out, total_bits, NULL, 0); -} - // Replace the library's weak definition of TMC2130Stepper::write() // This is executed in the object context so it has access to class // data such as the CS pin that switchCSpin() uses diff --git a/FluidNC/esp32/tmc_spi_support.c b/FluidNC/esp32/tmc_spi_support.c new file mode 100644 index 000000000..7fcf14e40 --- /dev/null +++ b/FluidNC/esp32/tmc_spi_support.c @@ -0,0 +1,93 @@ +// Copyright (c) 2022 Mitch Bradley +// Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. + +// C support routines for tmc_spi.cpp . These routines must be complied +// by a C compiler instead of a C++ compiler because of a problem in the +// ESP32_S3 version of esp_addr.h . It defines a FLAG_ATTR() macro in a +// way that causes compiler error on spi_ll.h + +#include "hal/spi_ll.h" + +#include +#ifdef CONFIG_IDF_TARGET_ESP32S3 +# define HSPI_HOST SPI2_HOST +# define SPI2 GPSPI2 +#endif + +spi_dev_t* hw = &SPI2; + +static spi_ll_clock_val_t clk_reg_val = 0; + +// Establish the SPI bus configuration needed for TMC device access +// This should be done one before every TMC read or write operation, +// to reconfigure the bus from whatever mode the SD card driver used. +void tmc_spi_bus_setup() { +#if 0 + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], PIN_FUNC_GPIO); + gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT); + gpio_matrix_out(bus_config->miso_io_num, io_signal[host].spiq_out, false, false); + gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false); +#endif + + if (clk_reg_val == 0) { + spi_ll_master_cal_clock(SPI_LL_PERIPH_CLK_FREQ, 2000000, 128, &clk_reg_val); + } + spi_ll_master_set_clock_by_reg(hw, &clk_reg_val); + + spi_ll_master_init(hw); + spi_ll_master_set_mode(hw, 3); + spi_ll_set_half_duplex(hw, false); + + spi_line_mode_t mode = { 1, 1, 1 }; + spi_ll_master_set_line_mode(hw, mode); // Single-line transfers; not DIO or QIO +} + +// Perform a full-duplex transfer from out/out_bitlen to in/in_bitlen +// If in_bitlen is 0, the input data will be ignored +void tmc_spi_transfer_data(uint8_t* out, int out_bitlen, uint8_t* in, int in_bitlen) { + spi_ll_set_mosi_bitlen(hw, out_bitlen); + + spi_ll_set_miso_bitlen(hw, in_bitlen); + + spi_ll_set_addr_bitlen(hw, 0); + spi_ll_set_command_bitlen(hw, 0); + + spi_ll_write_buffer(hw, out, out_bitlen); + spi_ll_enable_mosi(hw, 1); + if (in_bitlen) { + spi_ll_enable_miso(hw, 1); + } + + spi_ll_clear_int_stat(hw); + spi_ll_master_user_start(hw); + while (!spi_ll_usr_is_done(hw)) {} + + spi_ll_read_buffer(hw, in, in_bitlen); // No-op if in_bitlen is 0 +} + +// Do a single 5-byte (reg# + data) access to a TMC register, +// accounting for the number of TMC devices (index) daisy-chained +// before the target device. For reads, this is the first register +// access that latches the register data into the output register. +void tmc_spi_rw_reg(uint8_t cmd, uint32_t data, int index) { + int before = index > 0 ? index - 1 : 0; + + const size_t packetLen = 5; + size_t dummy_out_bytes = before * packetLen; + size_t total_bytes = (before + 1) * packetLen; + size_t total_bits = total_bytes * 8; + + uint8_t out[total_bytes]; + + // The data always starts at the beginning of the buffer then + // the trailing 0 bytes will push it through the chain to the + // target chip. + out[0] = cmd; + out[1] = data >> 24; + out[2] = data >> 16; + out[3] = data >> 8; + out[4] = data >> 0; + memset(&out[5], 0, total_bytes - 5); + + tmc_spi_transfer_data(out, total_bits, NULL, 0); +} diff --git a/FluidNC/esp32/tmc_spi_support.h b/FluidNC/esp32/tmc_spi_support.h new file mode 100644 index 000000000..28b983739 --- /dev/null +++ b/FluidNC/esp32/tmc_spi_support.h @@ -0,0 +1,16 @@ +// Copyright (c) 2022 Mitch Bradley +// Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void tmc_spi_bus_setup(); +void tmc_spi_transfer_data(uint8_t* out, int out_bitlen, uint8_t* in, int in_bitlen); +void tmc_spi_rw_reg(uint8_t cmd, uint32_t data, int index); + +#ifdef __cplusplus +} +#endif diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index aa5dcd3b9..d986f42a2 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -114,10 +114,10 @@ namespace MotorDrivers { void group(Configuration::HandlerBase& handler) override { handler.item("uart_num", _uart_num); handler.item("id", _id); - handler.item("count_min", _countMin); handler.item("count_max", _countMax); - handler.item("timer_ms", _timer_ms); + + Servo::group(handler); } // Name of the configurable. Must match the name registered in the cpp file. diff --git a/FluidNC/src/Motors/RcServo.h b/FluidNC/src/Motors/RcServo.h index 8fb83f117..f8253e89f 100644 --- a/FluidNC/src/Motors/RcServo.h +++ b/FluidNC/src/Motors/RcServo.h @@ -54,6 +54,8 @@ namespace MotorDrivers { handler.item("pwm_hz", _pwm_freq, SERVO_PWM_FREQ_MIN, SERVO_PWM_FREQ_MAX); handler.item("min_pulse_us", _min_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); handler.item("max_pulse_us", _max_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); + + Servo::group(handler); } // Name of the configurable. Must match the name registered in the cpp file. diff --git a/platformio.ini b/platformio.ini index cc81492d1..6e5e34161 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,19 +33,24 @@ lib_deps = bt_deps = BluetoothSerial wifi_deps = - ArduinoOTA - DNSServer - ESPmDNS - Update - WebServer - WiFi - WiFiClientSecure arduinoWebSockets=https://github.com/Links2004/arduinoWebSockets + ; If we include the following explicit dependencies when we get the + ; Arduino framework code from github, platformio picks up different + ; and incompatible versions of these libraries from who knows where, + ; ArduinoOTA + ; DNSServer + ; ESPmDNS + ; Update + ; WebServer + ; WiFi + ; WiFiClientSecure [common_esp32_base] -platform = espressif32@^4.3.0 - +platform = https://github.com/platformio/platform-espressif32.git framework = arduino +platform_packages = + framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#2.0.7 + upload_speed = 921600 board_build.partitions = min_spiffs.csv ; For 4M ESP32 ; board_build.partitions = FluidNC/ld/esp32/app3M_spiffs1M_8MB.csv ; For 8Meg ESP32 From a2a2f08c7c2a81916750cf9ed09e99e9f235b2e4 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 9 Apr 2023 14:00:36 -1000 Subject: [PATCH 25/51] Fix Bluetooth build problem casused by std::string change --- FluidNC/src/WebUI/BTConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/WebUI/BTConfig.cpp b/FluidNC/src/WebUI/BTConfig.cpp index f312e8b08..25a7a6737 100644 --- a/FluidNC/src/WebUI/BTConfig.cpp +++ b/FluidNC/src/WebUI/BTConfig.cpp @@ -166,7 +166,7 @@ namespace WebUI { _btname = bt_name->getStringValue(); if (_btname.length()) { - if (!SerialBT.begin(_btname)) { + if (!SerialBT.begin(_btname.c_str())) { log_error("Bluetooth failed to start"); return false; } From f442290b1dde05490effc0c9ab696ec986ca43c2 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 9 Apr 2023 14:16:25 -1000 Subject: [PATCH 26/51] Fixed release build problems SPIFFS no longer works due to space issues, so LittleFS is now the default --- build-release.py | 6 +++--- platformio.ini | 34 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/build-release.py b/build-release.py index eaf45ae62..de7005460 100644 --- a/build-release.py +++ b/build-release.py @@ -123,10 +123,10 @@ def copyToZip(zipObj, platform, fileName, destPath, mode=0o100755): # Put FluidNC binaries, partition maps, and installers in the archive for envName in ['wifi','bt']: - # Put spiffs.bin and index.html.gz in the archive - # bt does not need a spiffs.bin because there is no use for index.html.gz + # Put littlefs.bin and index.html.gz in the archive + # bt does not need a littlefs.bin because there is no use for index.html.gz if envName == 'wifi': - name = 'spiffs.bin' + name = 'littlefs.bin' zipObj.write(os.path.join(pioPath, envName, name), os.path.join(zipDirName, envName, name)) name = 'index.html.gz' zipObj.write(os.path.join('FluidNC', 'data', name), os.path.join(zipDirName, envName, name)) diff --git a/platformio.ini b/platformio.ini index 6e5e34161..5cb33f65e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -52,7 +52,8 @@ platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#2.0.7 upload_speed = 921600 -board_build.partitions = min_spiffs.csv ; For 4M ESP32 +board_build.partitions = min_littlefs.csv ; For 4M ESP32 +board_build.filesystem = littlefs ; board_build.partitions = FluidNC/ld/esp32/app3M_spiffs1M_8MB.csv ; For 8Meg ESP32 ; board_build.partitions = FluidNC/ld/esp32/app3M_spiffs9M_16MB.csv ; For 16Meg ESP32 monitor_speed = 115200 @@ -87,6 +88,12 @@ extends = common_esp32_base board = esp32-s2-saola-1 lib_deps = ${common.lib_deps} +[common_wifi] +build_flags = -DENABLE_WIFI -DUSE_LITTLEFS + +[common_bt] +build_flags = -DENABLE_BLUETOOTH + [env:noradio_s2] extends = common_esp32_s2 lib_deps = ${common.lib_deps} @@ -94,17 +101,17 @@ lib_deps = ${common.lib_deps} [env:wifi_s2] extends = common_esp32_s2 lib_deps = ${common.lib_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_WIFI +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} [env:bt_s2] extends = common_esp32_s2 lib_deps = ${common.lib_deps} ${common.bt_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH +build_flags = ${common_esp32.build_flags} ${common_bt.build_flags}\ [env:wifibt_s2] extends = common_esp32_s2 lib_deps = ${common.lib_deps} ${common.bt_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH -DENABLE_WIFI +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} ${common_bt.build_flags} [env:debug] extends = common_esp32 @@ -118,43 +125,36 @@ lib_deps = ${common.lib_deps} [env:wifi] extends = common_esp32 lib_deps = ${common.lib_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_WIFI - -[env:wifi-littlefs] -board_build.filesystem = littlefs -extends = common_esp32 -lib_deps = ${common.lib_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_WIFI -DUSE_LITTLEFS +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} [env:bt] extends = common_esp32 lib_deps = ${common.lib_deps} ${common.bt_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH +build_flags = ${common_esp32.build_flags} ${common_bt.build_flags} [env:wifibt] extends = common_esp32 lib_deps = ${common.lib_deps} ${common.bt_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH -DENABLE_WIFI +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} ${common_bt.build_flags} [env:noradio_s3] extends = common_esp32_s3 lib_deps = ${common.lib_deps} [env:wifi_s3] -board_build.filesystem = littlefs extends = common_esp32_s3 lib_deps = ${common.lib_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_WIFI -DUSE_LITTLEFS +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} [env:bt_s3] extends = common_esp32_s3 lib_deps = ${common.lib_deps} ${common.bt_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH +build_flags = ${common_esp32.build_flags} ${common_bt.build_flags} [env:wifibt_s3] extends = common_esp32_s3 lib_deps = ${common.lib_deps} ${common.bt_deps} ${common.wifi_deps} -build_flags = ${common_esp32.build_flags} -DENABLE_BLUETOOTH -DENABLE_WIFI +build_flags = ${common_esp32.build_flags} ${common_wifi.build_flags} ${common_bt.build_flags} [env:native] platform = native From b0da5307889f2c364b2e07a60a0a2807e485fc2c Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 9 Apr 2023 14:27:43 -1000 Subject: [PATCH 27/51] Verbose build of filesystem for debugging --- build-release.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-release.py b/build-release.py index de7005460..dc48354de 100644 --- a/build-release.py +++ b/build-release.py @@ -34,11 +34,11 @@ def buildEnv(pioEnv, verbose=True, extraArgs=None): return app.returncode def buildFs(pioEnv, verbose=verbose, extraArgs=None): - cmd = ['platformio','run', '--disable-auto-clean', '-e', pioEnv, '-t', 'buildfs'] + cmd = ['platformio','run', '--disable-auto-clean', '-e', pioEnv, '-v', '-t', 'buildfs'] if extraArgs: cmd.append(extraArgs) print('Building file system for ' + pioEnv) - if verbose: + if True: app = subprocess.Popen(cmd, env=environ) else: app = subprocess.Popen(cmd, env=environ, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1) From bca3364db596780bcee7c02b04f45072c96fbdb7 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 9 Apr 2023 14:30:51 -1000 Subject: [PATCH 28/51] Added min_littlefs.csv, undo build verbosity --- build-release.py | 4 ++-- min_littlefs.csv | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 min_littlefs.csv diff --git a/build-release.py b/build-release.py index dc48354de..de7005460 100644 --- a/build-release.py +++ b/build-release.py @@ -34,11 +34,11 @@ def buildEnv(pioEnv, verbose=True, extraArgs=None): return app.returncode def buildFs(pioEnv, verbose=verbose, extraArgs=None): - cmd = ['platformio','run', '--disable-auto-clean', '-e', pioEnv, '-v', '-t', 'buildfs'] + cmd = ['platformio','run', '--disable-auto-clean', '-e', pioEnv, '-t', 'buildfs'] if extraArgs: cmd.append(extraArgs) print('Building file system for ' + pioEnv) - if True: + if verbose: app = subprocess.Popen(cmd, env=environ) else: app = subprocess.Popen(cmd, env=environ, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1) diff --git a/min_littlefs.csv b/min_littlefs.csv new file mode 100644 index 000000000..0b6a9ffd0 --- /dev/null +++ b/min_littlefs.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1E0000, +app1, app, ota_1, 0x1F0000,0x1E0000, +spiffs, data, spiffs, 0x3D0000,0x30000, From 0db4e52bda9ff7b3fe00bb4e000a1e50b4ea7488 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Mon, 10 Apr 2023 08:23:45 -1000 Subject: [PATCH 29/51] bootloader.bin is now in wifi/ and bt/, not common/ --- build-release.py | 10 ++++++---- install_scripts/posix/tools.sh | 2 +- install_scripts/win64/install-bt.bat | 2 +- install_scripts/win64/install-wifi.bat | 2 +- platformio.ini | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/build-release.py b/build-release.py index de7005460..97dd45959 100644 --- a/build-release.py +++ b/build-release.py @@ -111,11 +111,9 @@ def copyToZip(zipObj, platform, fileName, destPath, mode=0o100755): pioPath = os.path.join('.pio', 'build') - # Put bootloader binaries in the archive - tools = os.path.join(os.path.expanduser('~'),'.platformio','packages','framework-arduinoespressif32','tools') - bootloader = 'bootloader_dio_80m.bin' - zipObj.write(os.path.join(tools, 'sdk', 'esp32', 'bin', bootloader), os.path.join(zipDirName, 'common', bootloader)) + # Put boot_app binary in the archive bootapp = 'boot_app0.bin'; + tools = os.path.join(os.path.expanduser('~'),'.platformio','packages','framework-arduinoespressif32','tools') zipObj.write(os.path.join(tools, "partitions", bootapp), os.path.join(zipDirName, 'common', bootapp)) for secFuses in ['SecurityFusesOK.bin', 'SecurityFusesOK0.bin']: zipObj.write(os.path.join(sharedPath, 'common', secFuses), os.path.join(zipDirName, 'common', secFuses)) @@ -123,6 +121,10 @@ def copyToZip(zipObj, platform, fileName, destPath, mode=0o100755): # Put FluidNC binaries, partition maps, and installers in the archive for envName in ['wifi','bt']: + # Put bootloader binaries in the archive + bootloader = 'bootloader.bin' + zipObj.write(os.path.join(pioPath, envName, bootloader), os.path.join(zipDirName, envName, bootloader)) + # Put littlefs.bin and index.html.gz in the archive # bt does not need a littlefs.bin because there is no use for index.html.gz if envName == 'wifi': diff --git a/install_scripts/posix/tools.sh b/install_scripts/posix/tools.sh index c4a00d703..3917b5394 100644 --- a/install_scripts/posix/tools.sh +++ b/install_scripts/posix/tools.sh @@ -80,7 +80,7 @@ esptool_erase() { esptool_basic erase_flash } -Bootloader="0x1000 common/bootloader_dio_80m.bin" +Bootloader="0x1000 ${BuildType}/bootloader.bin" Bootapp="0xe000 common/boot_app0.bin" Firmware="0x10000 ${BuildType}/firmware.bin" Partitions="0x8000 ${BuildType}/partitions.bin" diff --git a/install_scripts/win64/install-bt.bat b/install_scripts/win64/install-bt.bat index a8a45c249..1caca2337 100644 --- a/install_scripts/win64/install-bt.bat +++ b/install_scripts/win64/install-bt.bat @@ -11,7 +11,7 @@ set EsptoolPath=win64\esptool.exe set BaseArgs=--chip esp32 --baud 921600 set SetupArgs=--before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect -set Bootloader=0x1000 common\bootloader_dio_80m.bin +set Bootloader=0x1000 %BuildType%\bootloader.bin set Bootapp=0xe000 common\boot_app0.bin set Firmware=0x10000 %BuildType%\firmware.bin set Partitions=0x8000 %BuildType%\partitions.bin diff --git a/install_scripts/win64/install-wifi.bat b/install_scripts/win64/install-wifi.bat index 5a02c28c6..6eb1f4db3 100644 --- a/install_scripts/win64/install-wifi.bat +++ b/install_scripts/win64/install-wifi.bat @@ -11,7 +11,7 @@ set EsptoolPath=win64\esptool.exe set BaseArgs=--chip esp32 --baud 921600 set SetupArgs=--before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect -set Bootloader=0x1000 common\bootloader_dio_80m.bin +set Bootloader=0x1000 %BuildType%\bootloader.bin set Bootapp=0xe000 common\boot_app0.bin set Firmware=0x10000 %BuildType%\firmware.bin set Partitions=0x8000 %BuildType%\partitions.bin diff --git a/platformio.ini b/platformio.ini index 5cb33f65e..f2e0961e5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -49,7 +49,8 @@ wifi_deps = platform = https://github.com/platformio/platform-espressif32.git framework = arduino platform_packages = - framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#2.0.7 + framework-arduinoespressif32@ https://github.com/espressif/arduino-esp32.git#2.0.7 +board_build.arduino.upstream_packages = no upload_speed = 921600 board_build.partitions = min_littlefs.csv ; For 4M ESP32 From 72bce307b3ebafd178c1839c14f18d6e42ea84b0 Mon Sep 17 00:00:00 2001 From: bdring Date: Sun, 16 Apr 2023 16:10:40 -0500 Subject: [PATCH 30/51] Don't constrain when starting outside the range. --- FluidNC/src/Limits.cpp | 6 ++++-- FluidNC/src/Motors/Servo.cpp | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index 3a471a481..f4ba85fd8 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -59,10 +59,12 @@ void constrainToSoftLimits(float* cartesian) { auto axes = config->_axes; auto n_axis = config->_axes->_numberAxis; - bool limit_error = false; + float* current_position = get_mpos(); + for (int axis = 0; axis < n_axis; axis++) { auto axisSetting = axes->_axis[axis]; - if (axisSetting->_softLimits) { + // If the axis is moving from the current location and soft limits are on. + if (axisSetting->_softLimits && cartesian[axis] != current_position[axis]) { if (cartesian[axis] < limitsMinPosition(axis)) { cartesian[axis] = limitsMinPosition(axis); } diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index f51982ff3..cd0d92f7e 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -33,7 +33,7 @@ namespace MotorDrivers { if (_timer_ms == 0 || ms < _timer_ms) { _timer_ms = ms; } - //log_info("Servo Update Task Started"); + if (this == List) { xTaskCreatePinnedToCore(updateTask, // task "servoUpdateTask", // name for task @@ -43,7 +43,10 @@ namespace MotorDrivers { NULL, // handle SUPPORT_TASK_CORE // core ); + log_info("Servo Update Task Started with ms:" << ms); } + + } void Servo::updateTask(void* pvParameters) { From b5e68748b40178e5cdf222db531bdea7ed165a6b Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Sun, 16 Apr 2023 13:19:25 -1000 Subject: [PATCH 31/51] Use timers instead of tasks for simple periodic operations --- FluidNC/src/Motors/Dynamixel2.cpp | 344 ++++++++++------------ FluidNC/src/Motors/Dynamixel2.h | 58 ++-- FluidNC/src/Motors/MotorDriver.h | 5 - FluidNC/src/Motors/RcServo.cpp | 2 +- FluidNC/src/Motors/Servo.cpp | 51 +--- FluidNC/src/Motors/Servo.h | 21 +- FluidNC/src/Motors/Solenoid.cpp | 2 +- FluidNC/src/Motors/TMC2130Driver.cpp | 6 +- FluidNC/src/Motors/TMC2208Driver.cpp | 2 +- FluidNC/src/Motors/TMC2209Driver.cpp | 2 +- FluidNC/src/Motors/TMC5160Driver.cpp | 6 +- FluidNC/src/Motors/TMC5160ProDriver.cpp | 6 +- FluidNC/src/Motors/TrinamicBase.cpp | 50 ++-- FluidNC/src/Motors/TrinamicBase.h | 13 +- FluidNC/src/Motors/TrinamicSpiDriver.cpp | 28 -- FluidNC/src/Motors/TrinamicSpiDriver.h | 1 - FluidNC/src/Motors/TrinamicUartDriver.cpp | 28 -- FluidNC/src/Motors/TrinamicUartDriver.h | 2 - 18 files changed, 235 insertions(+), 392 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.cpp b/FluidNC/src/Motors/Dynamixel2.cpp index b1f21e0fd..2de5ed36c 100644 --- a/FluidNC/src/Motors/Dynamixel2.cpp +++ b/FluidNC/src/Motors/Dynamixel2.cpp @@ -24,19 +24,18 @@ #include namespace MotorDrivers { - Uart* MotorDrivers::Dynamixel2::_uart = nullptr; - uint8_t MotorDrivers::Dynamixel2::_first_id = 0; - uint8_t MotorDrivers::Dynamixel2::_last_id = 0; + Uart* Dynamixel2::_uart = nullptr; + TimerHandle_t Dynamixel2::_timer = nullptr; + std::vector Dynamixel2::_instances; + bool Dynamixel2::_has_errors = false; - uint8_t MotorDrivers::Dynamixel2::bulk_message[100]; - uint8_t MotorDrivers::Dynamixel2::bulk_message_index; + uint8_t Dynamixel2::_tx_message[100]; // send to dynamixel + uint8_t Dynamixel2::_rx_message[50]; // received from dynamixel + uint8_t Dynamixel2::_msg_index = 0; // Current length of message being constructed - uint8_t MotorDrivers::Dynamixel2::_dxl_rx_message[50] = {}; // received from dynamixel - - bool MotorDrivers::Dynamixel2::_uart_started = false; + bool Dynamixel2::_uart_started = false; void Dynamixel2::init() { - _has_errors = false; // Initially assume okay _axis_index = axis_index(); if (!_uart_started) { @@ -52,17 +51,13 @@ namespace MotorDrivers { return; } _uart_started = true; + schedule_update(this, _timer_ms); } - // for bulk updating - if (_first_id == 0) { - _first_id = _id; - } - _last_id = _id; - config_message(); // print the config - startUpdateTask(_timer_ms); + // for bulk updating + _instances.push_back(this); } void Dynamixel2::config_motor() { @@ -85,20 +80,22 @@ namespace MotorDrivers { } bool Dynamixel2::test() { - uint16_t len = 3; + start_message(_id, DXL_INSTR_PING); + finish_message(); - _dxl_tx_message[DXL_MSG_INSTR] = DXL_INSTR_PING; - - dxl_finish_message(_id, _dxl_tx_message, len); - len = dxl_get_response(PING_RSP_LEN); // wait for and get response + uint16_t len = dxl_get_response(PING_RSP_LEN); // wait for and get response if (len == PING_RSP_LEN) { - uint16_t model_num = _dxl_rx_message[10] << 8 | _dxl_rx_message[9]; + uint16_t model_num = _rx_message[10] << 8 | _rx_message[9]; + uint8_t fw_rev = _rx_message[11]; + std::string msg("Axis ping reply "); + msg += axisName().c_str(); if (model_num == 1060) { - log_info("Axis ping reply " << axisName() << " Model XL430-W250 F/W Rev " << String(_dxl_rx_message[11], HEX)); + msg += " Model XL430-W250"; } else { - log_info("Axis ping reply " << axisName() << " M/N " << model_num << " F/W Rev " << String(_dxl_rx_message[11], HEX)); + msg += " M/N " + std::to_string(model_num); } + log_info(msg << " F/W Rev " << to_hex(fw_rev)); } else { log_warn(" Ping failed"); return false; @@ -111,48 +108,55 @@ namespace MotorDrivers { // sets the PWM to zero. This allows most servos to be manually moved void IRAM_ATTR Dynamixel2::set_disable(bool disable) { - uint8_t param_count = 1; - if (_disabled == disable) { return; } _disabled = disable; - dxl_write(DXL_ADDR_TORQUE_EN, param_count, !_disabled); + start_write(DXL_ADDR_TORQUE_EN); + add_uint8(!disable); + finish_write(); } void Dynamixel2::set_operating_mode(uint8_t mode) { - uint8_t param_count = 1; - dxl_write(DXL_OPERATING_MODE, param_count, mode); + start_write(DXL_OPERATING_MODE); + add_uint8(mode); + finish_write(); } - void Dynamixel2::update() { + // This is static; it updates the positions of all the Dynamixels on the UART bus + void Dynamixel2::update_all() { if (_has_errors) { return; } - if (_disabled) { - // TO DO need to properly time this. Currently it would read too fast. - // Needs delay between reads or bulk read. - //dxl_read_position(); - } else { - if (_id == _last_id) { // from a LIFO List - // initialize message - bulk_message_index = DXL_MSG_INSTR; - - bulk_message[bulk_message_index] = DXL_SYNC_WRITE; - bulk_message[++bulk_message_index] = DXL_GOAL_POSITION & 0xFF; // low order address - bulk_message[++bulk_message_index] = (DXL_GOAL_POSITION & 0xFF00) >> 8; // high order address - bulk_message[++bulk_message_index] = 4; // low order data length - bulk_message[++bulk_message_index] = 0; // high order data length - } - add_to_bulk_message(); - if (_id == _first_id) { - send_bulk_message(); - } + start_message(DXL_BROADCAST_ID, DXL_SYNC_WRITE); + add_uint16(DXL_GOAL_POSITION); + add_uint16(4); // data length + + float* mpos = get_mpos(); + float motors[MAX_N_AXIS]; + config->_kinematics->transform_cartesian_to_motors(motors, mpos); + + for (const auto& instance : _instances) { + float dxl_count_min, dxl_count_max; + uint32_t dxl_position; + + dxl_count_min = float(instance->_countMin); + dxl_count_max = float(instance->_countMax); + + // map the mm range to the servo range + auto axis_index = instance->_axis_index; + dxl_position = static_cast(mapConstrain( + motors[axis_index], limitsMinPosition(axis_index), limitsMaxPosition(axis_index), dxl_count_min, dxl_count_max)); + + add_uint8(instance->_id); // ID of the servo + add_uint32(dxl_position); } + finish_message(); } + void Dynamixel2::update() { update_all(); } void Dynamixel2::set_location() {} @@ -171,15 +175,48 @@ namespace MotorDrivers { return false; // Cannot do conventional homing } + void Dynamixel2::add_uint8(uint8_t n) { _tx_message[_msg_index++] = n & 0xff; } + void Dynamixel2::add_uint16(uint16_t n) { + add_uint8(n); + add_uint8(n >> 8); + } + void Dynamixel2::add_uint32(uint32_t n) { + add_uint16(n); + add_uint16(n >> 16); + } + + void Dynamixel2::start_message(uint8_t id, uint8_t instr) { + _msg_index = 0; + add_uint8(0xFF); // HDR1 + add_uint8(0xFF); // HDR2 + add_uint8(0xFD); // HDR3 + add_uint8(0x00); // reserved + add_uint8(id); // ID + _msg_index += 2; // Length goes here, filled in later + add_uint8(instr); // ID + } + void Dynamixel2::finish_message() { + // length is the number of bytes after the INSTR, including the CRC + uint16_t msg_len = _msg_index - DXL_MSG_INSTR + 2; + + _tx_message[DXL_MSG_LEN_L] = msg_len & 0xff; + _tx_message[DXL_MSG_LEN_H] = (msg_len >> 8) * 0xff; + + uint16_t crc = 0; + crc = dxl_update_crc(crc, _tx_message, _msg_index); + + add_uint16(crc); + + _uart->flushRx(); + _uart->write(_tx_message, _msg_index); + + //hex_msg(_tx_message, "0x", _msg_index); + } + void Dynamixel2::dxl_goal_position(int32_t position) { - uint8_t param_count = 4; - - dxl_write(DXL_GOAL_POSITION, - param_count, - (position & 0xFF), - (position & 0xFF00) >> 8, - (position & 0xFF0000) >> 16, - (position & 0xFF000000) >> 24); + start_write(DXL_GOAL_POSITION); + add_uint32(position); + finish_write(); } uint32_t Dynamixel2::dxl_read_position() { @@ -190,8 +227,7 @@ namespace MotorDrivers { data_len = dxl_get_response(15); if (data_len == 15) { - uint32_t dxl_position = _dxl_rx_message[9] | (_dxl_rx_message[10] << 8) | (_dxl_rx_message[11] << 16) | - (_dxl_rx_message[12] << 24); + uint32_t dxl_position = _rx_message[9] | (_rx_message[10] << 8) | (_rx_message[11] << 16) | (_rx_message[12] << 24); auto axis = config->_axes->_axis[_axis_index]; @@ -211,152 +247,72 @@ namespace MotorDrivers { } void Dynamixel2::dxl_read(uint16_t address, uint16_t data_len) { - uint8_t msg_len = 3 + 4; - - _dxl_tx_message[DXL_MSG_INSTR] = DXL_READ; - _dxl_tx_message[DXL_MSG_START] = (address & 0xFF); // low-order address value - _dxl_tx_message[DXL_MSG_START + 1] = ((address & 0xFF00) >> 8); // High-order address value - _dxl_tx_message[DXL_MSG_START + 2] = (data_len & 0xFF); // low-order data length value - _dxl_tx_message[DXL_MSG_START + 3] = ((data_len & 0xFF00) >> 8); // high-order address value - - dxl_finish_message(_id, _dxl_tx_message, msg_len); + start_message(_id, DXL_READ); + add_uint16(address); + add_uint16(data_len); + finish_message(); } + void Dynamixel2::start_write(uint16_t address) { + start_message(_id, DXL_WRITE); + add_uint16(address); + } + void Dynamixel2::finish_write() { + finish_message(); + show_status(); + } void Dynamixel2::LED_on(bool on) { - uint8_t param_count = 1; - - if (on) - dxl_write(DXL_ADDR_LED_ON, param_count, 1); - else - dxl_write(DXL_ADDR_LED_ON, param_count, 0); + start_write(DXL_ADDR_LED_ON); + add_uint8(on); + finish_write(); } // wait for and get the servo response - uint16_t Dynamixel2::dxl_get_response(uint16_t length) { - length = _uart->timedReadBytes((char*)_dxl_rx_message, length, DXL_RESPONSE_WAIT_TICKS); - return length; + size_t Dynamixel2::dxl_get_response(uint16_t length) { + return _uart->timedReadBytes((char*)_rx_message, length, DXL_RESPONSE_WAIT_TICKS); } - void Dynamixel2::dxl_write(uint16_t address, uint8_t paramCount, ...) { - _dxl_tx_message[DXL_MSG_INSTR] = DXL_WRITE; - _dxl_tx_message[DXL_MSG_START] = (address & 0xFF); // low-order address value - _dxl_tx_message[DXL_MSG_START + 1] = ((address & 0xFF00) >> 8); // High-order address value - - uint8_t msg_offset = 1; // this is the offset from DXL_MSG_START in the message - - va_list valist; - - /* Initializing arguments */ - va_start(valist, paramCount); - - for (int x = 0; x < paramCount; x++) { - msg_offset++; - _dxl_tx_message[DXL_MSG_START + msg_offset] = (uint8_t)va_arg(valist, int); - } - va_end(valist); // Cleans up the list - - dxl_finish_message(_id, _dxl_tx_message, msg_offset + 4); - - uint16_t len = 11; // response length - len = dxl_get_response(len); - - if (len == 11) { - uint8_t err = _dxl_rx_message[8]; - switch (err) { - case 1: - log_error(name() << " ID " << _id << " Write fail error"); - break; - case 2: - log_error(name() << " ID " << _id << " Write instruction error"); - break; - case 3: - log_error(name() << " ID " << _id << " CRC Error"); - break; - case 4: - log_error(name() << " ID " << _id << " Write data range error"); - break; - case 5: - log_error(name() << " ID " << _id << " Write data length error"); - break; - case 6: - log_error(name() << " ID " << _id << " Write data limit error"); - break; - case 7: - log_error(name() << " ID " << _id << " Write access error addr:" << address); - break; - default: - break; - } - } else { - // timeout + void Dynamixel2::show_status() { + size_t len = dxl_get_response(11); + if (len != 11) { log_error(name() << " ID " << _id << " Timeout"); + return; + } + uint8_t err = _rx_message[DXL_MSG_START]; + if (!err) { + return; } - } - - void Dynamixel2::add_to_bulk_message() { - float dxl_count_min, dxl_count_max; - uint32_t dxl_position; - - float* mpos = get_mpos(); - float motors[MAX_N_AXIS]; - - dxl_count_min = float(_countMin); - dxl_count_max = float(_countMax); - - config->_kinematics->transform_cartesian_to_motors(motors, mpos); - - // map the mm range to the servo range - dxl_position = static_cast(mapConstrain( - motors[_axis_index], limitsMinPosition(_axis_index), limitsMaxPosition(_axis_index), dxl_count_min, dxl_count_max)); - - bulk_message[++bulk_message_index] = _id; // ID of the servo - bulk_message[++bulk_message_index] = dxl_position & 0xFF; // data - bulk_message[++bulk_message_index] = (dxl_position & 0xFF00) >> 8; // data - bulk_message[++bulk_message_index] = (dxl_position & 0xFF0000) >> 16; // data - bulk_message[++bulk_message_index] = (dxl_position & 0xFF000000) >> 24; // data - } - - void Dynamixel2::send_bulk_message() { - //static uint64_t ping = esp_timer_get_time() / 1000; - //log_debug("Ping:" << esp_timer_get_time() / 1000 - ping); - //ping = esp_timer_get_time() / 1000; - dxl_finish_message(DXL_BROADCAST_ID, bulk_message, bulk_message_index - DXL_MSG_INSTR + 3); - } - - /* - Static - - This is a helper function to complete and send the message - The body of the message should be in msg, at the correct location - before calling this function. - This function will add the header, length bytes and CRC - It will then send the message -*/ - void Dynamixel2::dxl_finish_message(uint8_t id, uint8_t* msg, uint16_t msg_len) { - uint16_t crc = 0; - // header - msg[DXL_MSG_HDR1] = char(0xFF); - msg[DXL_MSG_HDR2] = char(0xFF); - msg[DXL_MSG_HDR3] = char(0xFD); - // - // reserved - msg[DXL_MSG_RSRV] = 0x00; - msg[DXL_MSG_ID] = id; - // length - msg[DXL_MSG_LEN_L] = msg_len & 0xFF; - msg[DXL_MSG_LEN_H] = (msg_len & 0xFF00) >> 8; - - // the message should already be here - - crc = dxl_update_crc(crc, msg, 5 + msg_len); - - msg[msg_len + 5] = crc & 0xFF; // CRC_L - msg[msg_len + 6] = (crc & 0xFF00) >> 8; - - _uart->flushRx(); - _uart->write(msg, msg_len + 7); - //hex_msg(msg, "0x", msg_len + 7); + std::string msg(name()); + msg += " ID " + _rx_message[DXL_MSG_ID]; + + switch (err) { + case 1: + msg += " Write fail error"; + break; + case 2: + msg += " Write instruction error"; + break; + case 3: + msg += " CRC Error"; + break; + case 4: + msg += " Write data range error"; + break; + case 5: + msg += " Write data length error"; + break; + case 6: + msg += " Write data limit error"; + break; + case 7: + msg += " Write access error addr:" + std::to_string(_rx_message[DXL_MSG_INSTR]); + break; + default: + msg += " Unknown error code:" + std::to_string(err); + break; + } + log_error(msg); } // from http://emanual.robotis.com/docs/en/dxl/crc/ diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index d986f42a2..81ac54bc2 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -22,27 +22,35 @@ namespace MotorDrivers { void set_location(); uint8_t _id; - uint8_t _dxl_tx_message[50]; // outgoing to dynamixel - static uint8_t _dxl_rx_message[50]; // received from dynamixel + static uint8_t _tx_message[100]; // outgoing to dynamixel + static uint8_t _msg_index; + static uint8_t _rx_message[50]; // received from dynamixel + + static void start_message(uint8_t id, uint8_t instr); + static void finish_message(); + static void add_uint8(uint8_t n); + static void add_uint16(uint16_t n); + static void add_uint32(uint32_t n); + + void start_write(uint16_t address); + void finish_write(); + void show_status(); bool test(); uint32_t dxl_read_position(); void dxl_read(uint16_t address, uint16_t data_len); - void dxl_write(uint16_t address, uint8_t paramCount, ...); - void dxl_goal_position(int32_t position); // set one motor - void set_operating_mode(uint8_t mode); - void LED_on(bool on); - static void dxl_finish_message(uint8_t id, uint8_t* msg, uint16_t msg_len); - static uint16_t dxl_get_response(uint16_t length); + void dxl_goal_position(int32_t position); // set one motor + void set_operating_mode(uint8_t mode); + void LED_on(bool on); + + size_t dxl_get_response(uint16_t length); + static uint16_t dxl_update_crc(uint16_t crc_accum, uint8_t* data_blk_ptr, uint8_t data_blk_size); - // static things for the bulk position command (set all axes at one time) - static void init_bulk_message(); - void add_to_bulk_message(); - static void send_bulk_message(); - static uint8_t bulk_message[100]; - static uint8_t bulk_message_index; + static TimerHandle_t _timer; + + static std::vector _instances; int _axis_index; @@ -50,9 +58,6 @@ namespace MotorDrivers { int _uart_num = -1; - static uint8_t _first_id; - static uint8_t _last_id; - static bool _uart_started; static const int DXL_RESPONSE_WAIT_TICKS = 20; // how long to wait for a response @@ -91,19 +96,20 @@ namespace MotorDrivers { uint32_t _countMin = 1024; uint32_t _countMax = 3072; - bool _disabled; - bool _has_errors; + bool _disabled; + static bool _has_errors; public: - Dynamixel2() : _id(255), _disabled(true), _has_errors(true) {} + Dynamixel2() : _id(255), _disabled(true) {} // Overrides for inherited methods - void init() override; - void read_settings() override; - bool set_homing_mode(bool isHoming) override; - void set_disable(bool disable) override; - void update() override; - void config_motor() override; + void init() override; + void read_settings() override; + bool set_homing_mode(bool isHoming) override; + void set_disable(bool disable) override; + void update() override; + static void update_all(); + void config_motor() override; // Configuration handlers: void validate() override { diff --git a/FluidNC/src/Motors/MotorDriver.h b/FluidNC/src/Motors/MotorDriver.h index 159ef6704..f02002d01 100644 --- a/FluidNC/src/Motors/MotorDriver.h +++ b/FluidNC/src/Motors/MotorDriver.h @@ -87,11 +87,6 @@ namespace MotorDrivers { // TODO Architecture: Should this be private? virtual bool test(); - // update() is used for some types of "smart" motors that - // can be told to move to a specific position. It is - // called from a periodic task. - virtual void update() {} - // Name is required for the configuration factory to work. virtual const char* name() const = 0; diff --git a/FluidNC/src/Motors/RcServo.cpp b/FluidNC/src/Motors/RcServo.cpp index dabbd9d33..11bafebe6 100644 --- a/FluidNC/src/Motors/RcServo.cpp +++ b/FluidNC/src/Motors/RcServo.cpp @@ -47,7 +47,7 @@ namespace MotorDrivers { _disabled = true; - startUpdateTask(_timer_ms); + schedule_update(this, _timer_ms); } void RcServo::config_message() { diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index f51982ff3..0418e5342 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -22,50 +22,19 @@ #include // portTICK_PERIOD_MS, vTaskDelay namespace MotorDrivers { - Servo* Servo::List = NULL; - Servo::Servo() : MotorDriver() { - link = List; - List = this; - } + Servo::Servo() : MotorDriver() {} - void Servo::startUpdateTask(int ms) { - if (_timer_ms == 0 || ms < _timer_ms) { - _timer_ms = ms; - } - //log_info("Servo Update Task Started"); - if (this == List) { - xTaskCreatePinnedToCore(updateTask, // task - "servoUpdateTask", // name for task - 4096, // size of task stack - (void*)&_timer_ms, // parameters - 1, // priority - NULL, // handle - SUPPORT_TASK_CORE // core - ); - } + void Servo::update_servo(TimerHandle_t object) { + Servo* servo = static_cast(object); + servo->update(); } - void Servo::updateTask(void* pvParameters) { - TickType_t xLastWakeTime; - const TickType_t xUpdate = *static_cast(pvParameters) / portTICK_PERIOD_MS; // in ticks (typically ms) - auto n_axis = config->_axes->_numberAxis; - - xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time. - vTaskDelay(2000); // initial delay - while (true) { // don't ever return from this or the task dies - std::atomic_thread_fence(std::memory_order::memory_order_seq_cst); // read fence for settings - //log_info("Servo update"); - for (Servo* p = List; p; p = p->link) { - p->update(); - } - - vTaskDelayUntil(&xLastWakeTime, xUpdate); - - static UBaseType_t uxHighWaterMark = 0; -#ifdef DEBUG_TASK_STACK - reportTaskStackSize(uxHighWaterMark); -#endif - } + void Servo::schedule_update(Servo* object, int interval) { + xTimerCreate("", + interval, + true, // auto reload + (TimerHandle_t)object, + update_servo); } } diff --git a/FluidNC/src/Motors/Servo.h b/FluidNC/src/Motors/Servo.h index 68f418f4b..83afb458b 100644 --- a/FluidNC/src/Motors/Servo.h +++ b/FluidNC/src/Motors/Servo.h @@ -17,27 +17,12 @@ namespace MotorDrivers { int _timer_ms = 75; Servo(); -#if 0 - // Overrides for inherited methods - void init() override; - void read_settings() override; - bool set_homing_mode(bool isHoming) override; - void IRAM_ATTR set_disable(bool disable) override; -#endif + virtual void update() = 0; // This must be implemented by derived classes void group(Configuration::HandlerBase& handler) override { handler.item("timer_ms", _timer_ms); } protected: - // Start the servo update task. Each derived subclass instance calls this - // during init(), which happens after all objects have been constructed. - // startUpdateTask(ms) finds the smallest update interval among all - // the calls, and starts the task on the final call. - void startUpdateTask(int ms); - - private: - // Linked list of servo instances, used by the servo task - static Servo* List; - Servo* link; - static void updateTask(void*); + static void update_servo(TimerHandle_t object); + static void schedule_update(Servo* object, int interval); }; } diff --git a/FluidNC/src/Motors/Solenoid.cpp b/FluidNC/src/Motors/Solenoid.cpp index 9c8072b04..061e111fd 100644 --- a/FluidNC/src/Motors/Solenoid.cpp +++ b/FluidNC/src/Motors/Solenoid.cpp @@ -64,7 +64,7 @@ namespace MotorDrivers { _current_pwm_duty = 0; - startUpdateTask(_update_rate_ms); + schedule_update(this, _update_rate_ms); } void Solenoid::update() { set_location(); } diff --git a/FluidNC/src/Motors/TMC2130Driver.cpp b/FluidNC/src/Motors/TMC2130Driver.cpp index 4741b6624..027b69d99 100644 --- a/FluidNC/src/Motors/TMC2130Driver.cpp +++ b/FluidNC/src/Motors/TMC2130Driver.cpp @@ -21,7 +21,7 @@ namespace MotorDrivers { tmc2130 = new TMC2130Stepper(cs_id, _r_sense, _spi_index); // TODO hardwired to non daisy chain index - TrinamicSpiDriver::finalInit(); + registration(); } void TMC2130Driver::config_motor() { @@ -29,9 +29,7 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC2130Driver::test() { - return checkVersion(0x11, tmc2130->version()); - } + bool TMC2130Driver::test() { return checkVersion(0x11, tmc2130->version()); } void TMC2130Driver::set_registers(bool isHoming) { if (_has_errors) { diff --git a/FluidNC/src/Motors/TMC2208Driver.cpp b/FluidNC/src/Motors/TMC2208Driver.cpp index 69dc04bb7..7434b8a84 100644 --- a/FluidNC/src/Motors/TMC2208Driver.cpp +++ b/FluidNC/src/Motors/TMC2208Driver.cpp @@ -22,7 +22,7 @@ namespace MotorDrivers { tmc2208 = new TMC2209Stepper(_uart, _r_sense, _addr); - TrinamicUartDriver::finalInit(); + registration(); } void TMC2208Driver::config_motor() { diff --git a/FluidNC/src/Motors/TMC2209Driver.cpp b/FluidNC/src/Motors/TMC2209Driver.cpp index 786342cbe..b79e545f6 100644 --- a/FluidNC/src/Motors/TMC2209Driver.cpp +++ b/FluidNC/src/Motors/TMC2209Driver.cpp @@ -23,7 +23,7 @@ namespace MotorDrivers { tmc2209 = new TMC2209Stepper(_uart, _r_sense, _addr); - TrinamicUartDriver::finalInit(); + registration(); } void TMC2209Driver::config_motor() { diff --git a/FluidNC/src/Motors/TMC5160Driver.cpp b/FluidNC/src/Motors/TMC5160Driver.cpp index 6da247c06..e9e219ead 100644 --- a/FluidNC/src/Motors/TMC5160Driver.cpp +++ b/FluidNC/src/Motors/TMC5160Driver.cpp @@ -21,7 +21,7 @@ namespace MotorDrivers { if (_cs_pin.capabilities().has(Pin::Capabilities::I2S)) { tmc5160->setSPISpeed(_spi_freq); } - TrinamicSpiDriver::finalInit(); + registration(); } void TMC5160Driver::config_motor() { @@ -29,9 +29,7 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC5160Driver::test() { - return checkVersion(0x30, tmc5160->version()); - } + bool TMC5160Driver::test() { return checkVersion(0x30, tmc5160->version()); } void TMC5160Driver::set_registers(bool isHoming) { if (_has_errors) { diff --git a/FluidNC/src/Motors/TMC5160ProDriver.cpp b/FluidNC/src/Motors/TMC5160ProDriver.cpp index 18361006a..ed1956b25 100644 --- a/FluidNC/src/Motors/TMC5160ProDriver.cpp +++ b/FluidNC/src/Motors/TMC5160ProDriver.cpp @@ -18,7 +18,7 @@ namespace MotorDrivers { if (_cs_pin.capabilities().has(Pin::Capabilities::I2S)) { tmc5160->setSPISpeed(_spi_freq); } - TrinamicSpiDriver::finalInit(); + registration(); } void TMC5160ProDriver::config_motor() { @@ -26,9 +26,7 @@ namespace MotorDrivers { TrinamicBase::config_motor(); } - bool TMC5160ProDriver::test() { - return checkVersion(0x30, tmc5160->version()); - } + bool TMC5160ProDriver::test() { return checkVersion(0x30, tmc5160->version()); } void TMC5160ProDriver::set_registers(bool isHoming) { if (_has_errors) { diff --git a/FluidNC/src/Motors/TrinamicBase.cpp b/FluidNC/src/Motors/TrinamicBase.cpp index a4202a56d..67dcdda99 100644 --- a/FluidNC/src/Motors/TrinamicBase.cpp +++ b/FluidNC/src/Motors/TrinamicBase.cpp @@ -12,34 +12,18 @@ namespace MotorDrivers { { TrinamicMode::StallGuard, "StallGuard" }, EnumItem(TrinamicMode::StealthChop) }; - TrinamicBase* TrinamicBase::List = NULL; // a static list of all drivers for stallguard reporting - - // Prints StallGuard data that is useful for tuning. - void TrinamicBase::readSgTask(void* pvParameters) { - auto trinamicDriver = static_cast(pvParameters); - - TickType_t xLastWakeTime; - const TickType_t xreadSg = 200; // in ticks (typically ms) - auto n_axis = config->_axes->_numberAxis; - - xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time. - while (true) { // don't ever return from this or the task dies - std::atomic_thread_fence(std::memory_order::memory_order_seq_cst); // read fence for settings - if (inMotionState()) { - for (TrinamicBase* p = List; p; p = p->link) { - if (p->_stallguardDebugMode) { - //log_info("SG:" << p->_stallguardDebugMode); - p->debug_message(); - } + std::vector TrinamicBase::_instances; // static list of all drivers for stallguard reporting + + // Another approach would be to register a separate timer for each instance. + // I think that timers are cheap so having only a single timer might not buy us much + void TrinamicBase::read_sg(TimerHandle_t obj) { + if (inMotionState()) { + for (TrinamicBase* t : _instances) { + if (t->_stallguardDebugMode) { + //log_info("SG:" << t->_stallguardDebugMode); + t->debug_message(); } - } // sys.state - - vTaskDelayUntil(&xLastWakeTime, xreadSg); - - static UBaseType_t uxHighWaterMark = 0; -#ifdef DEBUG_TASK_STACK - reportTaskStackSize(uxHighWaterMark); -#endif + } } } @@ -158,4 +142,16 @@ namespace MotorDrivers { set_registers(false); } + void TrinamicBase::registration() { + // Display the stepper library version message once, before the first + // TMC config message. + if (_instances.empty()) { + log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); + xTimerCreate("Stallguard", 200, true, nullptr, read_sg); + } + + _instances.push_back(this); + + config_message(); + } } diff --git a/FluidNC/src/Motors/TrinamicBase.h b/FluidNC/src/Motors/TrinamicBase.h index ada4fcefc..267376f5c 100644 --- a/FluidNC/src/Motors/TrinamicBase.h +++ b/FluidNC/src/Motors/TrinamicBase.h @@ -19,6 +19,11 @@ namespace MotorDrivers { extern EnumItem trinamicModes[]; class TrinamicBase : public StandardStepper { + private: + static void read_sg(TimerHandle_t); + + static std::vector _instances; + protected: uint32_t calc_tstep(float speed, float percent); @@ -44,12 +49,6 @@ namespace MotorDrivers { uint8_t _toff_stealthchop = 5; uint8_t _toff_coolstep = 3; - // Linked list of Trinamic driver instances, used by the - // StallGuard reporting task. - static TrinamicBase* List; - TrinamicBase* link; - static void readSgTask(void*); - const double fclk = 12700000.0; // Internal clock Approx (Hz) used to calculate TSTEP from homing rate float holdPercent(); @@ -67,6 +66,8 @@ namespace MotorDrivers { const char* yn(bool v) { return v ? "Y" : "N"; } + void registration(); + public: TrinamicBase() = default; diff --git a/FluidNC/src/Motors/TrinamicSpiDriver.cpp b/FluidNC/src/Motors/TrinamicSpiDriver.cpp index df4ffcd29..15d995b2c 100644 --- a/FluidNC/src/Motors/TrinamicSpiDriver.cpp +++ b/FluidNC/src/Motors/TrinamicSpiDriver.cpp @@ -35,34 +35,6 @@ namespace MotorDrivers { return cs_id; } - void TrinamicSpiDriver::finalInit() { - _has_errors = false; - - link = List; - List = this; - - // Display the stepper library version message once, before the first - // TMC config message. Link is NULL for the first TMC instance. - if (!link) { - log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); - } - - config_message(); - - // After initializing all of the TMC drivers, create a task to - // display StallGuard data. List == this for the final instance. - if (List == this) { - xTaskCreatePinnedToCore(readSgTask, // task - "readSgTask", // name for task - 4096, // size of task stack - this, // parameters - 1, // priority - NULL, - SUPPORT_TASK_CORE // must run the task on same core - ); - } - } - /* This is the startup message showing the basic definition */ diff --git a/FluidNC/src/Motors/TrinamicSpiDriver.h b/FluidNC/src/Motors/TrinamicSpiDriver.h index 4599549b2..d56de23f4 100644 --- a/FluidNC/src/Motors/TrinamicSpiDriver.h +++ b/FluidNC/src/Motors/TrinamicSpiDriver.h @@ -73,7 +73,6 @@ namespace MotorDrivers { void config_message() override; uint8_t setupSPI(); - void finalInit(); bool reportTest(uint8_t result); uint8_t toffValue(); diff --git a/FluidNC/src/Motors/TrinamicUartDriver.cpp b/FluidNC/src/Motors/TrinamicUartDriver.cpp index af4667f6b..3533f9e39 100644 --- a/FluidNC/src/Motors/TrinamicUartDriver.cpp +++ b/FluidNC/src/Motors/TrinamicUartDriver.cpp @@ -35,34 +35,6 @@ namespace MotorDrivers { << " Disable:" << _disable_pin.name() << " R:" << _r_sense); } - void TrinamicUartDriver::finalInit() { - _has_errors = false; - - link = List; - List = this; - - // Display the stepper library version message once, before the first - // TMC config message. Link is NULL for the first TMC instance. - if (!link) { - log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); - } - - config_message(); - - // After initializing all of the TMC drivers, create a task to - // display StallGuard data. List == this for the final instance. - if (List == this) { - xTaskCreatePinnedToCore(readSgTask, // task - "readSgTask", // name for task - 4096, // size of task stack - this, // parameters - 1, // priority - NULL, - SUPPORT_TASK_CORE // must run the task on same core - ); - } - } - uint8_t TrinamicUartDriver::toffValue() { if (_disabled) { return _toff_disable; diff --git a/FluidNC/src/Motors/TrinamicUartDriver.h b/FluidNC/src/Motors/TrinamicUartDriver.h index eb0f8e443..081755763 100644 --- a/FluidNC/src/Motors/TrinamicUartDriver.h +++ b/FluidNC/src/Motors/TrinamicUartDriver.h @@ -49,8 +49,6 @@ namespace MotorDrivers { static bool _uart_started; void config_message() override; - void finalInit(); - uint8_t toffValue(); // TO DO move to Base? private: From c95f1d676abb9aab8e6c7b0ce3bbff85c00dc981 Mon Sep 17 00:00:00 2001 From: bdring Date: Mon, 17 Apr 2023 10:03:46 -0500 Subject: [PATCH 32/51] Allowing out of range nudge. --- FluidNC/src/Limits.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index f4ba85fd8..edbfc8fdb 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -65,6 +65,17 @@ void constrainToSoftLimits(float* cartesian) { auto axisSetting = axes->_axis[axis]; // If the axis is moving from the current location and soft limits are on. if (axisSetting->_softLimits && cartesian[axis] != current_position[axis]) { + // When outside the axis range, only small nudges to clear switches are allowed + if (current_position[axis] < limitsMinPosition(axis) || current_position[axis] > limitsMaxPosition(axis)) { + float jog_dist = cartesian[axis] - current_position[axis]; + auto nudge_max = axisSetting->_motors[0]->_pulloff; + if (abs(jog_dist) < nudge_max) { + cartesian[axis] = (jog_dist >= 0) ? current_position[axis] + nudge_max : current_position[axis] + nudge_max; + log_debug("Jog amount limited when outside soft limits") + } + continue; + } + if (cartesian[axis] < limitsMinPosition(axis)) { cartesian[axis] = limitsMinPosition(axis); } From 37666e059a7f28d2c8668d090a5d09b703ca346d Mon Sep 17 00:00:00 2001 From: bdring Date: Mon, 17 Apr 2023 13:26:44 -0500 Subject: [PATCH 33/51] Updates for testing 1. Jogging will never cause a soft limit alarm 2. You can only nudge if a switch is active on the axis. --- FluidNC/src/Limits.cpp | 20 +++++++++++++++----- FluidNC/src/MotionControl.cpp | 4 +++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index edbfc8fdb..876e038ae 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -59,7 +59,8 @@ void constrainToSoftLimits(float* cartesian) { auto axes = config->_axes; auto n_axis = config->_axes->_numberAxis; - float* current_position = get_mpos(); + float* current_position = get_mpos(); + MotorMask lim_pin_state = limits_get_state(); for (int axis = 0; axis < n_axis; axis++) { auto axisSetting = axes->_axis[axis]; @@ -67,9 +68,16 @@ void constrainToSoftLimits(float* cartesian) { if (axisSetting->_softLimits && cartesian[axis] != current_position[axis]) { // When outside the axis range, only small nudges to clear switches are allowed if (current_position[axis] < limitsMinPosition(axis) || current_position[axis] > limitsMaxPosition(axis)) { - float jog_dist = cartesian[axis] - current_position[axis]; + // only allow a nudge if a switch is active + if (bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 0)) && + bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 1))) { + cartesian[axis] = current_position[axis]; // cancel the move on this axis + log_debug("Soft limit violation on axis " << axis); + continue; + } + float jog_dist = cartesian[axis] - current_position[axis]; auto nudge_max = axisSetting->_motors[0]->_pulloff; - if (abs(jog_dist) < nudge_max) { + if (abs(jog_dist) > nudge_max) { cartesian[axis] = (jog_dist >= 0) ? current_position[axis] + nudge_max : current_position[axis] + nudge_max; log_debug("Jog amount limited when outside soft limits") } @@ -78,10 +86,12 @@ void constrainToSoftLimits(float* cartesian) { if (cartesian[axis] < limitsMinPosition(axis)) { cartesian[axis] = limitsMinPosition(axis); - } - if (cartesian[axis] > limitsMaxPosition(axis)) { + } else if (cartesian[axis] > limitsMaxPosition(axis)) { cartesian[axis] = limitsMaxPosition(axis); + } else { + continue; } + log_debug("Jog constrained to axis range"); } } } diff --git a/FluidNC/src/MotionControl.cpp b/FluidNC/src/MotionControl.cpp index 4afcff0c8..e3b2ba9bc 100644 --- a/FluidNC/src/MotionControl.cpp +++ b/FluidNC/src/MotionControl.cpp @@ -102,7 +102,9 @@ void mc_cancel_jog() { // unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in // (1 minute)/feed_rate time. bool mc_linear(float* target, plan_line_data_t* pl_data, float* position) { - limits_soft_check(target); + if (!pl_data->is_jog) { + limits_soft_check(target); + } return config->_kinematics->cartesian_to_motors(target, pl_data, position); } From a911d21f821a1e9f0bdeeca9a0262709c11b40ad Mon Sep 17 00:00:00 2001 From: bdring Date: Mon, 17 Apr 2023 13:54:12 -0500 Subject: [PATCH 34/51] Add TODO --- FluidNC/src/Limits.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index 876e038ae..9036b55d8 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -63,7 +63,8 @@ void constrainToSoftLimits(float* cartesian) { MotorMask lim_pin_state = limits_get_state(); for (int axis = 0; axis < n_axis; axis++) { - auto axisSetting = axes->_axis[axis]; + auto axisSetting = axes->_axis[axis]; + String axis_letter = String(Machine::Axes::_names[axis]); // If the axis is moving from the current location and soft limits are on. if (axisSetting->_softLimits && cartesian[axis] != current_position[axis]) { // When outside the axis range, only small nudges to clear switches are allowed @@ -71,12 +72,16 @@ void constrainToSoftLimits(float* cartesian) { // only allow a nudge if a switch is active if (bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 0)) && bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 1))) { - cartesian[axis] = current_position[axis]; // cancel the move on this axis - log_debug("Soft limit violation on axis " << axis); + cartesian[axis] = current_position[axis]; // cancel the move on this axis + log_debug("Soft limit violation on axis " << axis_letter); continue; - } - float jog_dist = cartesian[axis] - current_position[axis]; - auto nudge_max = axisSetting->_motors[0]->_pulloff; + } + float jog_dist = cartesian[axis] - current_position[axis]; + //TODO + // if jog is positive and only the positive switch is active, then kill the move + // if jog is negative and only the negative switch is active, then kill the move + + auto nudge_max = axisSetting->_motors[0]->_pulloff; if (abs(jog_dist) > nudge_max) { cartesian[axis] = (jog_dist >= 0) ? current_position[axis] + nudge_max : current_position[axis] + nudge_max; log_debug("Jog amount limited when outside soft limits") From 63a3c6caceccc6b7e3badebb370024ae8920db69 Mon Sep 17 00:00:00 2001 From: bdring Date: Mon, 17 Apr 2023 18:00:26 -0500 Subject: [PATCH 35/51] Jogging off switches - Can jog away from known switch - Can jog off either way if switch is not known (both or all) --- FluidNC/src/Limits.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index 9036b55d8..976fcd432 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -73,13 +73,24 @@ void constrainToSoftLimits(float* cartesian) { if (bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 0)) && bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 1))) { cartesian[axis] = current_position[axis]; // cancel the move on this axis - log_debug("Soft limit violation on axis " << axis_letter); + log_debug("Soft limit violation on " << axis_letter); continue; } float jog_dist = cartesian[axis] - current_position[axis]; - //TODO + + MotorMask axisMotors = Machine::Axes::axes_to_motors(1 << axis); + bool posLimited = bits_are_true(Machine::Axes::posLimitMask, axisMotors); + bool negLimited = bits_are_true(Machine::Axes::negLimitMask, axisMotors); + // if jog is positive and only the positive switch is active, then kill the move // if jog is negative and only the negative switch is active, then kill the move + if (posLimited != negLimited) { // XOR, because ambiguous (both) is OK + if ((negLimited && (jog_dist < 0)) || (posLimited && (jog_dist > 0))) { + cartesian[axis] = current_position[axis]; // cancel the move on this axis + log_debug("Jog into active switch blocked on " << axis_letter); + continue; + } + } auto nudge_max = axisSetting->_motors[0]->_pulloff; if (abs(jog_dist) > nudge_max) { From 20b19a58f4d76d30a53b4dca336621d1e60fa600 Mon Sep 17 00:00:00 2001 From: bdring Date: Tue, 18 Apr 2023 09:00:26 -0500 Subject: [PATCH 36/51] added comment --- FluidNC/src/MotionControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/MotionControl.cpp b/FluidNC/src/MotionControl.cpp index e3b2ba9bc..9c986f8dd 100644 --- a/FluidNC/src/MotionControl.cpp +++ b/FluidNC/src/MotionControl.cpp @@ -102,7 +102,7 @@ void mc_cancel_jog() { // unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in // (1 minute)/feed_rate time. bool mc_linear(float* target, plan_line_data_t* pl_data, float* position) { - if (!pl_data->is_jog) { + if (!pl_data->is_jog) { // soft limits for jogs have already been dealt with limits_soft_check(target); } return config->_kinematics->cartesian_to_motors(target, pl_data, position); From 63f130a7e4f9245fed9f540a2aa0331722eceba9 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 18 Apr 2023 12:41:19 -1000 Subject: [PATCH 37/51] Removed unnecessary debug message --- FluidNC/esp32/gpio.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/FluidNC/esp32/gpio.cpp b/FluidNC/esp32/gpio.cpp index 21975ccc6..c71053e7c 100644 --- a/FluidNC/esp32/gpio.cpp +++ b/FluidNC/esp32/gpio.cpp @@ -38,7 +38,6 @@ void gpio_mode(pinnum_t pin, bool input, bool output, bool pullup, bool pulldown if (opendrain) { conf.mode = (gpio_mode_t)((int)conf.mode | GPIO_MODE_DEF_OD); } - log_debug("gpio conf " << conf.pull_up_en << " " << pin); gpio_config(&conf); } void IRAM_ATTR gpio_set_interrupt_type(pinnum_t pin, int mode) { From 73d2aaa9151196df3f8ffbf91f66f643dc65f22b Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 18 Apr 2023 12:43:28 -1000 Subject: [PATCH 38/51] Fixed problem with watchdog timer usage for fs reformatting --- FluidNC/esp32/wdt.cpp | 38 +++++++++++++++++++++---- FluidNC/src/Configuration/HandlerBase.h | 9 ++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/FluidNC/esp32/wdt.cpp b/FluidNC/esp32/wdt.cpp index 2feede8c3..e0baaab81 100644 --- a/FluidNC/esp32/wdt.cpp +++ b/FluidNC/esp32/wdt.cpp @@ -6,16 +6,42 @@ #include #include "src/Config.h" -void enable_core0_WDT() { +static TaskHandle_t wdt_task_handle = nullptr; + +static void get_wdt_task_handle() { TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0); - if (idle_0 == NULL || esp_task_wdt_add(idle_0) != ESP_OK) { - log_error("Failed to add Core 0 IDLE task to WDT"); + esp_err_t err; + err = esp_task_wdt_status(idle_0); + switch (err) { + case ESP_OK: + wdt_task_handle = idle_0; + break; + case ESP_ERR_NOT_FOUND: + wdt_task_handle = nullptr; + return; + case ESP_ERR_INVALID_STATE: + wdt_task_handle = nullptr; + return; + } +} + +void enable_core0_WDT() { + if (!wdt_task_handle) { + return; + } + esp_err_t err; + if ((err = esp_task_wdt_add(wdt_task_handle)) != ESP_OK) { + log_error("Failed to add Core 0 IDLE task to WDT " << err); } } void disable_core0_WDT() { - TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0); - if (idle_0 == NULL || esp_task_wdt_delete(idle_0) != ESP_OK) { - log_error("Failed to remove Core 0 IDLE task from WDT"); + get_wdt_task_handle(); + if (!wdt_task_handle) { + return; + } + esp_err_t err; + if ((err = esp_task_wdt_delete(wdt_task_handle)) != ESP_OK) { + log_error("Failed to remove Core 0 IDLE task from WDT " << err); } } diff --git a/FluidNC/src/Configuration/HandlerBase.h b/FluidNC/src/Configuration/HandlerBase.h index 5f94cfd67..4bb2bd27d 100644 --- a/FluidNC/src/Configuration/HandlerBase.h +++ b/FluidNC/src/Configuration/HandlerBase.h @@ -61,9 +61,12 @@ namespace Configuration { void section(const char* name, T*& value, U... args) { if (handlerType() == HandlerType::Parser) { // For Parser, matchesUninitialized(name) resolves to _parser.is(name) - if (value == nullptr && matchesUninitialized(name)) { - value = new T(args...); - enterSection(name, value); + if (matchesUninitialized(name)) { + Assert(value == nullptr, "Duplicate section %s", name); + if (value == nullptr) { + value = new T(args...); + enterSection(name, value); + } } } else { if (value != nullptr) { From f8607b136158319bbfd5e889ca8adeca1fd7cc9c Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 18 Apr 2023 12:45:11 -1000 Subject: [PATCH 39/51] Improved reporting of configuration errors --- FluidNC/src/Configuration/ParseException.h | 6 +++--- FluidNC/src/Configuration/Tokenizer.cpp | 2 +- FluidNC/src/Machine/MachineConfig.cpp | 8 ++++---- FluidNC/src/Protocol.cpp | 8 ++++---- FluidNC/src/Report.cpp | 6 ++++++ FluidNC/src/Report.h | 1 + 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/FluidNC/src/Configuration/ParseException.h b/FluidNC/src/Configuration/ParseException.h index 8f4974273..173e01355 100644 --- a/FluidNC/src/Configuration/ParseException.h +++ b/FluidNC/src/Configuration/ParseException.h @@ -6,7 +6,7 @@ namespace Configuration { class ParseException { int line_; - const char* description_; + std::string description_; public: ParseException() = default; @@ -14,7 +14,7 @@ namespace Configuration { ParseException(int line, const char* description) : line_(line), description_(description) {} - inline int LineNumber() const { return line_; } - inline const char* What() const { return description_; } + inline int LineNumber() const { return line_; } + inline const std::string& What() const { return description_; } }; } diff --git a/FluidNC/src/Configuration/Tokenizer.cpp b/FluidNC/src/Configuration/Tokenizer.cpp index a75defcd2..eb1d4a150 100644 --- a/FluidNC/src/Configuration/Tokenizer.cpp +++ b/FluidNC/src/Configuration/Tokenizer.cpp @@ -95,7 +95,7 @@ namespace Configuration { if (Current() != ':') { std::string err = "Key "; err += StringRange(token_.keyStart_, token_.keyEnd_).str().c_str(); - err += "must be followed by ':'"; + err += " must be followed by ':'"; ParseError(err.c_str()); } Inc(); diff --git a/FluidNC/src/Machine/MachineConfig.cpp b/FluidNC/src/Machine/MachineConfig.cpp index b49b36f4c..11b16ee77 100644 --- a/FluidNC/src/Machine/MachineConfig.cpp +++ b/FluidNC/src/Machine/MachineConfig.cpp @@ -65,7 +65,7 @@ namespace Machine { handler.section("user_outputs", _userOutputs); handler.section("oled", _oled); - + Spindles::SpindleFactory::factory(handler, _spindles); // TODO: Consider putting these under a gcode: hierarchy level? Or motion control? @@ -221,7 +221,7 @@ namespace Machine { Configuration::AfterParse afterParse; config->afterParse(); config->group(afterParse); - } catch (std::exception& ex) { log_info("Validation error: " << ex.what()); } + } catch (std::exception& ex) { log_error("Validation error: " << ex.what()); } log_debug("Checking configuration"); @@ -229,14 +229,14 @@ namespace Machine { Configuration::Validator validator; config->validate(); config->group(validator); - } catch (std::exception& ex) { log_info("Validation error: " << ex.what()); } + } catch (std::exception& ex) { log_error("Validation error: " << ex.what()); } // log_info("Heap size after configuation load is " << uint32_t(xPortGetFreeHeapSize())); successful = (sys.state != State::ConfigAlarm); if (!successful) { - log_info("Configuration is invalid"); + log_error("Configuration is invalid"); } } catch (const Configuration::ParseException& ex) { diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index 877356498..eb4835333 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -232,13 +232,13 @@ static void check_startup_state() { // 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::ConfigAlarm) { - report_feedback_message(Message::ConfigAlarmLock); + report_error_message(Message::ConfigAlarmLock); } else { // Perform some machine checks to make sure everything is good to go. if (config->_start->_checkLimits && config->_axes->hasHardLimits()) { if (limits_get_state()) { sys.state = State::Alarm; // Ensure alarm state is active. - report_feedback_message(Message::CheckLimits); + report_error_message(Message::CheckLimits); } } if (config->_control->startup_check()) { @@ -246,7 +246,7 @@ static void check_startup_state() { } if (sys.state == State::Alarm || sys.state == State::Sleep) { - report_feedback_message(Message::AlarmLock); + report_error_message(Message::AlarmLock); sys.state = State::Alarm; // Ensure alarm state is set. } else { // Check if the safety door is open. @@ -375,7 +375,7 @@ static void protocol_do_alarm() { sys.state = State::Alarm; // Set system alarm state alarm_msg(rtAlarm); if (rtAlarm == ExecAlarm::HardLimit || rtAlarm == ExecAlarm::SoftLimit) { - report_feedback_message(Message::CriticalEvent); + report_error_message(Message::CriticalEvent); protocol_disable_steppers(); rtReset = false; // Disable any existing reset do { diff --git a/FluidNC/src/Report.cpp b/FluidNC/src/Report.cpp index cc28272a4..dc43c3dec 100644 --- a/FluidNC/src/Report.cpp +++ b/FluidNC/src/Report.cpp @@ -137,6 +137,12 @@ void report_feedback_message(Message message) { // ok to send to all channels log_info(it->second); } } +void report_error_message(Message message) { // ok to send to all channels + auto it = MessageText.find(message); + if (it != MessageText.end()) { + log_error(it->second); + } +} const char* radio = #if defined(ENABLE_WIFI) || defined(ENABLE_BLUETOOTH) diff --git a/FluidNC/src/Report.h b/FluidNC/src/Report.h index 35d8f2b26..1c1885a80 100644 --- a/FluidNC/src/Report.h +++ b/FluidNC/src/Report.h @@ -51,6 +51,7 @@ void _notifyf(const char* title, const char* format, ...); // Prints miscellaneous feedback messages. void report_feedback_message(Message message); +void report_error_message(Message message); // Prints welcome message void report_init_message(Channel& channel); From 6212ff7684b1f94d8ef16101ff0c12aba5089ac2 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 18 Apr 2023 12:45:54 -1000 Subject: [PATCH 40/51] $localfs/migrate does nothing if the localfs is already new --- FluidNC/src/WebUI/WebSettings.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FluidNC/src/WebUI/WebSettings.cpp b/FluidNC/src/WebUI/WebSettings.cpp index 8d29868ef..45f9ab4d8 100644 --- a/FluidNC/src/WebUI/WebSettings.cpp +++ b/FluidNC/src/WebUI/WebSettings.cpp @@ -505,12 +505,16 @@ namespace WebUI { return copyDir("/sd/localfs", "/localfs", out); } static Error migrateLocalFS(char* parameter, AuthenticationLevel auth_level, Channel& out) { // No ESP command + const char* newfs = parameter && *parameter ? parameter : "littlefs"; + if (strcmp(newfs, localfsName) == 0) { + log_error("localfs format is already " << newfs); + return Error::InvalidValue; + } log_info("Backing up local filesystem contents to SD"); Error err = copyDir("/localfs", "/sd/localfs", out); if (err != Error::Ok) { return err; } - const char* newfs = parameter && *parameter ? parameter : "littlefs"; log_info("Reformatting local filesystem to " << newfs); if (localfs_format(newfs)) { return Error::FsFailedFormat; From 80cced3406de4d29013c2a3532b45dd53d9dcb66 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 19 Apr 2023 09:46:12 -1000 Subject: [PATCH 41/51] Fixed compile problems --- FluidNC/src/Motors/Servo.h | 2 ++ FluidNC/src/Motors/TrinamicBase.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/FluidNC/src/Motors/Servo.h b/FluidNC/src/Motors/Servo.h index 83afb458b..f5aea8697 100644 --- a/FluidNC/src/Motors/Servo.h +++ b/FluidNC/src/Motors/Servo.h @@ -2,6 +2,8 @@ // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. #pragma once +#include +#include // TimerHandle_t /* This is a base class for servo-type motors - ones that autonomously diff --git a/FluidNC/src/Motors/TrinamicBase.cpp b/FluidNC/src/Motors/TrinamicBase.cpp index 28c2044e3..617a547ca 100644 --- a/FluidNC/src/Motors/TrinamicBase.cpp +++ b/FluidNC/src/Motors/TrinamicBase.cpp @@ -146,7 +146,7 @@ namespace MotorDrivers { // Display the stepper library version message once, before the first // TMC config message. if (_instances.empty()) { - log_debug("TMCStepper Library Ver. 0x" << String(TMCSTEPPER_VERSION, HEX)); + log_debug("TMCStepper Library Ver. 0x" << to_hex(TMCSTEPPER_VERSION)); xTimerCreate("Stallguard", 200, true, nullptr, read_sg); } From ddb5628a0f888628b4685d1edc914977ef8961e7 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 19 Apr 2023 10:14:55 -1000 Subject: [PATCH 42/51] Start timers after creation, with error messages --- FluidNC/src/Motors/Dynamixel2.h | 2 ++ FluidNC/src/Motors/RcServo.h | 2 ++ FluidNC/src/Motors/Servo.cpp | 17 ++++++++++++----- FluidNC/src/Motors/Servo.h | 2 ++ FluidNC/src/Motors/TrinamicBase.cpp | 8 +++++++- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index 81ac54bc2..529593819 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -111,6 +111,8 @@ namespace MotorDrivers { static void update_all(); void config_motor() override; + const char* name() override { return "Dynamixel2"; } + // Configuration handlers: void validate() override { Assert(_uart_num != -1, "Dynamixel: Missing uart_num configuration"); diff --git a/FluidNC/src/Motors/RcServo.h b/FluidNC/src/Motors/RcServo.h index f8253e89f..0b93f46e9 100644 --- a/FluidNC/src/Motors/RcServo.h +++ b/FluidNC/src/Motors/RcServo.h @@ -48,6 +48,8 @@ namespace MotorDrivers { void _write_pwm(uint32_t duty); + const char* name() override { return "RcServo"; } + // Configuration handlers: void group(Configuration::HandlerBase& handler) override { handler.item("output_pin", _output_pin); diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index 0418e5342..b0706d5a3 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -31,10 +31,17 @@ namespace MotorDrivers { } void Servo::schedule_update(Servo* object, int interval) { - xTimerCreate("", - interval, - true, // auto reload - (TimerHandle_t)object, - update_servo); + auto timer = xTimerCreate("", + interval, + true, // auto reload + (TimerHandle_t)object, + update_servo); + if (timer) { + log_error("Failed to create timer for " << object->name()); + return; + } + if (xTimerStart(timer, 0) == pdFAIL) { + log_error("Failed to start timer for " << object->name()); + } } } diff --git a/FluidNC/src/Motors/Servo.h b/FluidNC/src/Motors/Servo.h index f5aea8697..f62aaac2c 100644 --- a/FluidNC/src/Motors/Servo.h +++ b/FluidNC/src/Motors/Servo.h @@ -23,6 +23,8 @@ namespace MotorDrivers { virtual void update() = 0; // This must be implemented by derived classes void group(Configuration::HandlerBase& handler) override { handler.item("timer_ms", _timer_ms); } + virtual const char* name() = 0; // This must be implemented by derived classes + protected: static void update_servo(TimerHandle_t object); static void schedule_update(Servo* object, int interval); diff --git a/FluidNC/src/Motors/TrinamicBase.cpp b/FluidNC/src/Motors/TrinamicBase.cpp index 617a547ca..15432e729 100644 --- a/FluidNC/src/Motors/TrinamicBase.cpp +++ b/FluidNC/src/Motors/TrinamicBase.cpp @@ -147,7 +147,13 @@ namespace MotorDrivers { // TMC config message. if (_instances.empty()) { log_debug("TMCStepper Library Ver. 0x" << to_hex(TMCSTEPPER_VERSION)); - xTimerCreate("Stallguard", 200, true, nullptr, read_sg); + auto timer = xTimerCreate("Stallguard", 200, true, nullptr, read_sg); + // Timer failure is not fatal because you can still use the system + if (!timer) { + log_error("Failed to create timer for stallguard"); + } else if (xTimerStart(timer, 0) == pdFAIL) { + log_error("Failed to start timer for stallguard"); + } } _instances.push_back(this); From c50a2f5c189c8f9e7a33390944a41af31686bfb9 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 19 Apr 2023 10:21:06 -1000 Subject: [PATCH 43/51] Missing ! --- FluidNC/src/Motors/Servo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index b0706d5a3..b904c1526 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -36,7 +36,7 @@ namespace MotorDrivers { true, // auto reload (TimerHandle_t)object, update_servo); - if (timer) { + if (!timer) { log_error("Failed to create timer for " << object->name()); return; } From f201ee03dd5083e6a4b54920346b7403196fc923 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Wed, 19 Apr 2023 12:49:58 -1000 Subject: [PATCH 44/51] Arg to timer callback is not an opaque object --- FluidNC/src/Motors/Servo.cpp | 6 +++--- FluidNC/src/Motors/Servo.h | 2 +- FluidNC/src/Motors/TrinamicBase.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index b904c1526..9bd9b1180 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -25,8 +25,8 @@ namespace MotorDrivers { Servo::Servo() : MotorDriver() {} - void Servo::update_servo(TimerHandle_t object) { - Servo* servo = static_cast(object); + void Servo::update_servo(TimerHandle_t timer) { + Servo* servo = static_cast(pvTimerGetTimerID(timer)); servo->update(); } @@ -34,7 +34,7 @@ namespace MotorDrivers { auto timer = xTimerCreate("", interval, true, // auto reload - (TimerHandle_t)object, + (void*)object, update_servo); if (!timer) { log_error("Failed to create timer for " << object->name()); diff --git a/FluidNC/src/Motors/Servo.h b/FluidNC/src/Motors/Servo.h index f62aaac2c..3255f4bdf 100644 --- a/FluidNC/src/Motors/Servo.h +++ b/FluidNC/src/Motors/Servo.h @@ -26,7 +26,7 @@ namespace MotorDrivers { virtual const char* name() = 0; // This must be implemented by derived classes protected: - static void update_servo(TimerHandle_t object); + static void update_servo(TimerHandle_t timer); static void schedule_update(Servo* object, int interval); }; } diff --git a/FluidNC/src/Motors/TrinamicBase.cpp b/FluidNC/src/Motors/TrinamicBase.cpp index 15432e729..ba6324600 100644 --- a/FluidNC/src/Motors/TrinamicBase.cpp +++ b/FluidNC/src/Motors/TrinamicBase.cpp @@ -16,7 +16,7 @@ namespace MotorDrivers { // Another approach would be to register a separate timer for each instance. // I think that timers are cheap so having only a single timer might not buy us much - void TrinamicBase::read_sg(TimerHandle_t obj) { + void TrinamicBase::read_sg(TimerHandle_t timer) { if (inMotionState()) { for (TrinamicBase* t : _instances) { if (t->_stallguardDebugMode) { From 0ffdf2f266d6f5652361ed351ed2a90476b24530 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 20 Apr 2023 09:16:24 -1000 Subject: [PATCH 45/51] Separate timer_ms for different servo subclasses ... so they can have different default values, and so the dynamixel version can be shared. --- FluidNC/src/Motors/Dynamixel2.cpp | 3 ++- FluidNC/src/Motors/Dynamixel2.h | 8 ++++++-- FluidNC/src/Motors/RcServo.h | 5 ++++- FluidNC/src/Motors/Servo.cpp | 1 + FluidNC/src/Motors/Servo.h | 4 +--- FluidNC/src/Motors/Solenoid.h | 3 +++ 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.cpp b/FluidNC/src/Motors/Dynamixel2.cpp index 21388062c..db9344314 100644 --- a/FluidNC/src/Motors/Dynamixel2.cpp +++ b/FluidNC/src/Motors/Dynamixel2.cpp @@ -29,6 +29,8 @@ namespace MotorDrivers { std::vector Dynamixel2::_instances; bool Dynamixel2::_has_errors = false; + int Dynamixel2::_timer_ms = 1000; + uint8_t Dynamixel2::_tx_message[100]; // send to dynamixel uint8_t Dynamixel2::_rx_message[50]; // received from dynamixel uint8_t Dynamixel2::_msg_index = 0; // Current length of message being constructed @@ -91,7 +93,6 @@ namespace MotorDrivers { std::string msg("Axis ping reply "); msg += axisName().c_str(); if (model_num == 1060) { - msg += " Model XL430-W250"; } else { msg += " M/N " + std::to_string(model_num); diff --git a/FluidNC/src/Motors/Dynamixel2.h b/FluidNC/src/Motors/Dynamixel2.h index 529593819..eabe096f4 100644 --- a/FluidNC/src/Motors/Dynamixel2.h +++ b/FluidNC/src/Motors/Dynamixel2.h @@ -21,7 +21,10 @@ namespace MotorDrivers { void set_location(); - uint8_t _id; + uint8_t _id; + + static int _timer_ms; + static uint8_t _tx_message[100]; // outgoing to dynamixel static uint8_t _msg_index; static uint8_t _rx_message[50]; // received from dynamixel @@ -111,7 +114,7 @@ namespace MotorDrivers { static void update_all(); void config_motor() override; - const char* name() override { return "Dynamixel2"; } + const char* name() override { return "dynamixel2"; } // Configuration handlers: void validate() override { @@ -124,6 +127,7 @@ namespace MotorDrivers { handler.item("id", _id); handler.item("count_min", _countMin); handler.item("count_max", _countMax); + handler.item("timer_ms", _timer_ms); Servo::group(handler); } diff --git a/FluidNC/src/Motors/RcServo.h b/FluidNC/src/Motors/RcServo.h index 0b93f46e9..1585e4920 100644 --- a/FluidNC/src/Motors/RcServo.h +++ b/FluidNC/src/Motors/RcServo.h @@ -10,6 +10,8 @@ namespace MotorDrivers { class RcServo : public Servo { protected: + int _timer_ms = 75; + void config_message() override; void set_location(); @@ -48,7 +50,7 @@ namespace MotorDrivers { void _write_pwm(uint32_t duty); - const char* name() override { return "RcServo"; } + const char* name() override { return "rc_servo"; } // Configuration handlers: void group(Configuration::HandlerBase& handler) override { @@ -56,6 +58,7 @@ namespace MotorDrivers { handler.item("pwm_hz", _pwm_freq, SERVO_PWM_FREQ_MIN, SERVO_PWM_FREQ_MAX); handler.item("min_pulse_us", _min_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); handler.item("max_pulse_us", _max_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX); + handler.item("timer_ms", _timer_ms); Servo::group(handler); } diff --git a/FluidNC/src/Motors/Servo.cpp b/FluidNC/src/Motors/Servo.cpp index 9bd9b1180..01e4e82b5 100644 --- a/FluidNC/src/Motors/Servo.cpp +++ b/FluidNC/src/Motors/Servo.cpp @@ -43,5 +43,6 @@ namespace MotorDrivers { if (xTimerStart(timer, 0) == pdFAIL) { log_error("Failed to start timer for " << object->name()); } + log_info(" Update timer for " << object->name() << " at " << interval << " ms"); } } diff --git a/FluidNC/src/Motors/Servo.h b/FluidNC/src/Motors/Servo.h index 3255f4bdf..36610186c 100644 --- a/FluidNC/src/Motors/Servo.h +++ b/FluidNC/src/Motors/Servo.h @@ -16,12 +16,10 @@ namespace MotorDrivers { class Servo : public MotorDriver { public: - int _timer_ms = 75; - Servo(); virtual void update() = 0; // This must be implemented by derived classes - void group(Configuration::HandlerBase& handler) override { handler.item("timer_ms", _timer_ms); } + void group(Configuration::HandlerBase& handler) override {} virtual const char* name() = 0; // This must be implemented by derived classes diff --git a/FluidNC/src/Motors/Solenoid.h b/FluidNC/src/Motors/Solenoid.h index ce220d0bb..ce19fb1a8 100644 --- a/FluidNC/src/Motors/Solenoid.h +++ b/FluidNC/src/Motors/Solenoid.h @@ -46,6 +46,9 @@ namespace MotorDrivers { handler.item("hold_percent", _hold_percent, 0.0f, 100.0f); handler.item("pull_ms", _pull_ms, 0, 3000); handler.item("direction_invert", _dir_invert); + handler.item("timer_ms", _timer_ms); + + Servo::group(handler); } // Name of the configurable. Must match the name registered in the cpp file. From 01ca759ffa22af21904410a86006284ef6c949aa Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 20 Apr 2023 09:41:34 -1000 Subject: [PATCH 46/51] Different default values for different update timers --- FluidNC/src/Motors/Dynamixel2.cpp | 2 +- FluidNC/src/Motors/RcServo.h | 2 +- FluidNC/src/Motors/Solenoid.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/FluidNC/src/Motors/Dynamixel2.cpp b/FluidNC/src/Motors/Dynamixel2.cpp index db9344314..0c01cc258 100644 --- a/FluidNC/src/Motors/Dynamixel2.cpp +++ b/FluidNC/src/Motors/Dynamixel2.cpp @@ -29,7 +29,7 @@ namespace MotorDrivers { std::vector Dynamixel2::_instances; bool Dynamixel2::_has_errors = false; - int Dynamixel2::_timer_ms = 1000; + int Dynamixel2::_timer_ms = 75; uint8_t Dynamixel2::_tx_message[100]; // send to dynamixel uint8_t Dynamixel2::_rx_message[50]; // received from dynamixel diff --git a/FluidNC/src/Motors/RcServo.h b/FluidNC/src/Motors/RcServo.h index 1585e4920..de867409f 100644 --- a/FluidNC/src/Motors/RcServo.h +++ b/FluidNC/src/Motors/RcServo.h @@ -10,7 +10,7 @@ namespace MotorDrivers { class RcServo : public Servo { protected: - int _timer_ms = 75; + int _timer_ms = 20; void config_message() override; diff --git a/FluidNC/src/Motors/Solenoid.h b/FluidNC/src/Motors/Solenoid.h index ce19fb1a8..9a695f9c2 100644 --- a/FluidNC/src/Motors/Solenoid.h +++ b/FluidNC/src/Motors/Solenoid.h @@ -5,6 +5,8 @@ namespace MotorDrivers { class Solenoid : public RcServo { protected: + int _timer_ms = 50; + void config_message() override; void update() override; From 2e659d8811aa76cf6bb770b5293f379cb98ced81 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Fri, 21 Apr 2023 09:58:44 -1000 Subject: [PATCH 47/51] Fixed DeathToStrings patch oops that broke WebUI --- FluidNC/src/WebUI/WebServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/WebUI/WebServer.cpp b/FluidNC/src/WebUI/WebServer.cpp index 2e0341554..6dbca60bd 100644 --- a/FluidNC/src/WebUI/WebServer.cpp +++ b/FluidNC/src/WebUI/WebServer.cpp @@ -470,7 +470,7 @@ namespace WebUI { } else if (cmd.length() == 1 && is_realtime_command(cmd[0])) { wsChannel->pushRT(cmd[0]); } else { - if (cmd.length() && cmd[cmd.length() - 1] == '\n') { + if (cmd.length() && cmd[cmd.length() - 1] != '\n') { cmd += '\n'; } hasError = !wsChannel->push(cmd); From 9dd8d7f640d5aef8210d0f065f8e2008ee15bad8 Mon Sep 17 00:00:00 2001 From: bdring Date: Fri, 21 Apr 2023 15:02:43 -0500 Subject: [PATCH 48/51] UpdateToDevt --- FluidNC/src/Limits.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/FluidNC/src/Limits.cpp b/FluidNC/src/Limits.cpp index 021b5b971..b6b1b05b8 100644 --- a/FluidNC/src/Limits.cpp +++ b/FluidNC/src/Limits.cpp @@ -63,8 +63,7 @@ void constrainToSoftLimits(float* cartesian) { MotorMask lim_pin_state = limits_get_state(); for (int axis = 0; axis < n_axis; axis++) { - auto axisSetting = axes->_axis[axis]; - String axis_letter = String(Machine::Axes::_names[axis]); + auto axisSetting = axes->_axis[axis]; // If the axis is moving from the current location and soft limits are on. if (axisSetting->_softLimits && cartesian[axis] != current_position[axis]) { // When outside the axis range, only small nudges to clear switches are allowed @@ -73,7 +72,7 @@ void constrainToSoftLimits(float* cartesian) { if (bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 0)) && bitnum_is_false(lim_pin_state, Machine::Axes::motor_bit(axis, 1))) { cartesian[axis] = current_position[axis]; // cancel the move on this axis - log_debug("Soft limit violation on " << axis_letter); + log_debug("Soft limit violation on " << Machine::Axes::_names[axis]); continue; } float jog_dist = cartesian[axis] - current_position[axis]; @@ -87,7 +86,7 @@ void constrainToSoftLimits(float* cartesian) { if (posLimited != negLimited) { // XOR, because ambiguous (both) is OK if ((negLimited && (jog_dist < 0)) || (posLimited && (jog_dist > 0))) { cartesian[axis] = current_position[axis]; // cancel the move on this axis - log_debug("Jog into active switch blocked on " << axis_letter); + log_debug("Jog into active switch blocked on " << Machine::Axes::_names[axis]); continue; } } From 4c7fd178219f56879b33bb5d481c5eecb30e20ad Mon Sep 17 00:00:00 2001 From: bdring Date: Sun, 23 Apr 2023 13:16:15 -0500 Subject: [PATCH 49/51] Changed config default and range 1. Default is now 8M 2. Range is 1M to 20M 3. 0 is no longer used for default, so it is easier to show the current value. --- FluidNC/esp32/sdspi.cpp | 6 +----- FluidNC/src/SDCard.h | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/FluidNC/esp32/sdspi.cpp b/FluidNC/esp32/sdspi.cpp index a2a3dd32f..dc507702f 100644 --- a/FluidNC/esp32/sdspi.cpp +++ b/FluidNC/esp32/sdspi.cpp @@ -78,10 +78,7 @@ bool sd_init_slot(uint32_t freq_hz, int cs_pin, int cd_pin, int wp_pin) { sdspi_device_config_t slot_config; - // If freq_hz is 0, use the system default - if (freq_hz) { - host_config.max_freq_khz = freq_hz / 1000; - } + host_config.max_freq_khz = freq_hz / 1000; err = host_config.init(); CHECK_EXECUTE_RESULT(err, "host init failed"); @@ -104,7 +101,6 @@ bool sd_init_slot(uint32_t freq_hz, int cs_pin, int cd_pin, int wp_pin) { // If you do it only once below, the attempt to change it seems to // be ignored, and you get 20 MHz regardless of what you ask for. if (freq_hz) { - printf("hz = %d\n", freq_hz); err = sdspi_host_set_card_clk(host_config.slot, freq_hz / 1000); CHECK_EXECUTE_RESULT(err, "set slot clock speed failed"); } diff --git a/FluidNC/src/SDCard.h b/FluidNC/src/SDCard.h index f016ff931..5abe8f606 100644 --- a/FluidNC/src/SDCard.h +++ b/FluidNC/src/SDCard.h @@ -42,7 +42,7 @@ class SDCard : public Configuration::Configurable { Pin _cardDetect; Pin _cs; - uint32_t _frequency_hz = 0; // Set to nonzero to override the default + uint32_t _frequency_hz = 8000000; // Set to nonzero to override the default public: SDCard(); @@ -60,7 +60,7 @@ class SDCard : public Configuration::Configurable { void group(Configuration::HandlerBase& handler) override { handler.item("cs_pin", _cs); handler.item("card_detect_pin", _cardDetect); - handler.item("frequency_hz", _frequency_hz); + handler.item("frequency_hz", _frequency_hz, 1000000, 20000000); } ~SDCard(); From e504ce9ed8e0115778922977e2733883fcc23a2b Mon Sep 17 00:00:00 2001 From: bdring Date: Sun, 23 Apr 2023 13:42:05 -0500 Subject: [PATCH 50/51] Update SDCard.h Change lower end of range to 4000000 --- FluidNC/src/SDCard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/SDCard.h b/FluidNC/src/SDCard.h index 5abe8f606..e6f5b148d 100644 --- a/FluidNC/src/SDCard.h +++ b/FluidNC/src/SDCard.h @@ -60,7 +60,7 @@ class SDCard : public Configuration::Configurable { void group(Configuration::HandlerBase& handler) override { handler.item("cs_pin", _cs); handler.item("card_detect_pin", _cardDetect); - handler.item("frequency_hz", _frequency_hz, 1000000, 20000000); + handler.item("frequency_hz", _frequency_hz, 400000, 20000000); } ~SDCard(); From d3163e000a776347930fa5bc36517826aae0acf5 Mon Sep 17 00:00:00 2001 From: bdring Date: Mon, 24 Apr 2023 10:09:04 -0500 Subject: [PATCH 51/51] Change startup homing req'd message Reverting it to an info message rather than an ERR message. To prevent people thinking something is wrong with the startup. --- FluidNC/src/Protocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index eb4835333..3937c9c6d 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -246,7 +246,7 @@ static void check_startup_state() { } if (sys.state == State::Alarm || sys.state == State::Sleep) { - report_error_message(Message::AlarmLock); + report_feedback_message(Message::AlarmLock); sys.state = State::Alarm; // Ensure alarm state is set. } else { // Check if the safety door is open.