Skip to content

Commit

Permalink
Merge pull request #596 from bdring/Devt
Browse files Browse the repository at this point in the history
Devt
  • Loading branch information
MitchBradley authored Sep 6, 2022
2 parents 7e4dcfe + 491e66f commit 0a78bbe
Show file tree
Hide file tree
Showing 52 changed files with 1,199 additions and 997 deletions.
2 changes: 1 addition & 1 deletion FluidNC/src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace SpindleSpeedOverride {
const int Min = 10; // Percent of programmed spindle speed (1-100). Usually 10%.
const int CoarseIncrement = 10; // (1-99). Usually 10%.
const int FineIncrement = 1; // (1-99). Usually 1%.
}
};

// When a M2 or M30 program end command is executed, most GCode states are restored to their defaults.
// This compile-time option includes the restoring of the feed, rapid, and spindle speed override values
Expand Down
23 changes: 12 additions & 11 deletions FluidNC/src/Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@

#include "Control.h"

#include "Protocol.h" // rtSafetyDoor, etc
#include "Protocol.h" // *Event
#include "Machine/Macros.h" // macro0Event

Control::Control() {
// The SafetyDoor pin must be defined first because it is checked explicity in safety_door_ajar()
_pins.push_back(new ControlPin(rtSafetyDoor, "safety_door_pin", 'D'));
_pins.push_back(new ControlPin(rtReset, "reset_pin", 'R'));
_pins.push_back(new ControlPin(rtFeedHold, "feed_hold_pin", 'H'));
_pins.push_back(new ControlPin(rtCycleStart, "cycle_start_pin", 'S'));
_pins.push_back(new ControlPin(rtButtonMacro0, "macro0_pin", '0'));
_pins.push_back(new ControlPin(rtButtonMacro1, "macro1_pin", '1'));
_pins.push_back(new ControlPin(rtButtonMacro2, "macro2_pin", '2'));
_pins.push_back(new ControlPin(rtButtonMacro3, "macro3_pin", '3'));
_pins.push_back(new ControlPin(&safetyDoorEvent, "safety_door_pin", 'D'));
_pins.push_back(new ControlPin(&resetEvent, "reset_pin", 'R'));
_pins.push_back(new ControlPin(&feedHoldEvent, "feed_hold_pin", 'H'));
_pins.push_back(new ControlPin(&cycleStartEvent, "cycle_start_pin", 'S'));
_pins.push_back(new ControlPin(&macro0Event, "macro0_pin", '0'));
_pins.push_back(new ControlPin(&macro1Event, "macro1_pin", '1'));
_pins.push_back(new ControlPin(&macro2Event, "macro2_pin", '2'));
_pins.push_back(new ControlPin(&macro3Event, "macro3_pin", '3'));
}

void Control::init() {
Expand All @@ -25,15 +26,15 @@ void Control::init() {

void Control::group(Configuration::HandlerBase& handler) {
for (auto pin : _pins) {
handler.item(pin->_legend, pin->_pin);
handler.item(pin->_legend.c_str(), pin->_pin);
}
}

String Control::report_status() {
String ret = "";
for (auto pin : _pins) {
if (pin->get()) {
ret += pin->_letter;
ret += pin->letter();
}
}
return ret;
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/Control.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ControlPin.h"
#include <vector>

using namespace Machine;
class Control : public Configuration::Configurable {
public:
Control();
Expand Down
45 changes: 9 additions & 36 deletions FluidNC/src/ControlPin.cpp
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
#include "ControlPin.h"

#include "Report.h" // addPinReport
#include "Protocol.h" // ExecAlarm
#include <esp_attr.h> // IRAM_ATTR
#include <esp32-hal-gpio.h> // CHANGE

void IRAM_ATTR ControlPin::handleISR() {
bool pinState = _pin.read();
_value = pinState;

// Rate limit control pin events so switch bounce does not cause multiple events
if (pinState && (_debounceEnd == 0 || ((getCpuTicks() - _debounceEnd) >= 0))) {
_debounceEnd = usToEndTicks(debounceUs);
// We use 0 to mean that the debounce lockout is inactive,
// so if the end time happens to be 0, bump it up by one tick.
if (_debounceEnd == 0) {
_debounceEnd = 1;
namespace Machine {
void ControlPin::run(void* arg) {
if (get()) {
// log_debug(_legend);
block();
startTimer();
_event->run(arg);
} else {
reArm();
}
_rtVariable = true;
}
}

void ControlPin::init() {
if (_pin.undefined()) {
return;
}
_pin.report(_legend);
auto attr = Pin::Attr::Input | Pin::Attr::ISR;
if (_pin.capabilities().has(Pins::PinCapabilities::PullUp)) {
attr = attr | Pin::Attr::PullUp;
}
_pin.setAttr(attr);
_pin.attachInterrupt(ISRHandler, CHANGE, this);
_rtVariable = false;
_value = _pin.read();
}

ControlPin::~ControlPin() {
_pin.detachInterrupt();
}
37 changes: 12 additions & 25 deletions FluidNC/src/ControlPin.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,19 @@

#include "Pin.h"
#include <esp_attr.h> // IRAM_ATTR
#include "Machine/EventPin.h"
namespace Machine {
class ControlPin : public Machine::EventPin {
private:
const char _letter; // The name that appears in init() messages and the name of the configuration item

class ControlPin {
private:
bool _value;
volatile bool& _rtVariable; // The variable that is set when the pin is asserted
int32_t _debounceEnd = 0;
public:
ControlPin(Event* event, const char* legend, char letter) : EventPin(event, legend), _letter(letter) {}

void IRAM_ATTR handleISR();
CreateISRHandlerFor(ControlPin, handleISR);
char letter() { return _letter; };

// Interval during which we ignore repeated control pin activations
const int debounceUs = 10000; // 10000 us = 10 ms
void run(void* arg) override;

public:
const char* _legend; // The name that appears in init() messages and the name of the configuration item
const char _letter; // The letter that appears in status reports when the pin is active

ControlPin(volatile bool& rtVariable, const char* legend, char letter) :
_value(false), _letter(letter), _rtVariable(rtVariable), _legend(legend) {
_rtVariable = _value;
}

Pin _pin;

void init();
bool get() { return _value; }

~ControlPin();
};
~ControlPin();
};
}
37 changes: 37 additions & 0 deletions FluidNC/src/Event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2022 - Mitch Bradley
// Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file.

#pragma once
#include <Arduino.h> // String

// Objects derived from the Event base class are placed in the event queue.
// Protocol dequeues them and calls their run methods.
class Event {
public:
Event() {}
virtual void run(void* arg) = 0;
};

class NoArgEvent : public Event {
void (*_function)() = nullptr;

public:
NoArgEvent(void (*function)()) : _function(function) {}
void run(void* arg) override {
if (_function) {
_function();
}
}
};

class ArgEvent : public Event {
void (*_function)(void*) = nullptr;

public:
ArgEvent(void (*function)(void*)) : _function(function) {}
void run(void* arg) override {
if (_function) {
_function(arg);
}
}
};
2 changes: 1 addition & 1 deletion FluidNC/src/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ Error gc_execute_line(char* line, Channel& channel) {
case ProgramFlow::Paused:
protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
if (sys.state != State::CheckMode) {
rtFeedHold = true; // Use feed hold for program pause.
protocol_send_event(&feedHoldEvent);
protocol_execute_realtime(); // Execute suspend.
}
break;
Expand Down
55 changes: 45 additions & 10 deletions FluidNC/src/Kinematics/Cartesian.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
#include "Cartesian.h"

#include "../Machine/MachineConfig.h"
#include "src/Machine/MachineConfig.h"
#include "src/Machine/Axes.h" // ambiguousLimit()
#include "src/Limits.h"

namespace Kinematics {
void Cartesian::init() { log_info("Kinematic system: " << name()); }

bool Cartesian::kinematics_homing(AxisMask cycle_mask) {
// Do nothing.
return false;
}

void Cartesian::kinematics_post_homing() {
// Do nothing.
}

bool Cartesian::cartesian_to_motors(float* target, plan_line_data_t* pl_data, float* position) {
// Motor space is cartesian space, so we do no transform.
return mc_move_motors(target, pl_data);
Expand All @@ -24,6 +17,48 @@ namespace Kinematics {
copyAxes(cartesian, motors);
}

void Cartesian::transform_cartesian_to_motors(float* motors, float* cartesian) {
// Motor space is cartesian space, so we do no transform.
copyAxes(motors, cartesian);
}

bool Cartesian::canHome(AxisMask axisMask) {
if (ambiguousLimit()) {
log_error("Ambiguous limit switch touching. Manually clear all switches");
return false;
}
return true;
}

bool Cartesian::limitReached(AxisMask& axisMask, MotorMask& motorMask, MotorMask limited) {
// For Cartesian, the limit switches are associated with individual motors, since
// an axis can have dual motors each with its own limit switch. We clear the motors in
// the mask whose limits have been reached.
clear_bits(motorMask, limited);

// Set axisMask according to the motors that are still running.
axisMask = Machine::Axes::motors_to_axes(motorMask);

// We do not have to stop until all motors have reached their limits
return !axisMask;
}

void Cartesian::releaseMotors(AxisMask axisMask, MotorMask motors, Machine::Homing::Phase phase) {
auto axes = config->_axes;
auto n_axis = axes->_numberAxis;
for (int axis = 0; axis < n_axis; axis++) {
if (bitnum_is_true(axisMask, axis)) {
auto paxis = axes->_axis[axis];
if (bitnum_is_true(motors, Machine::Axes::motor_bit(axis, 0))) {
paxis->_motors[0]->unlimit();
}
if (bitnum_is_true(motors, Machine::Axes::motor_bit(axis, 1))) {
paxis->_motors[1]->unlimit();
}
}
}
}

// Configuration registration
namespace {
KinematicsFactory::InstanceBuilder<Cartesian> registration("Cartesian");
Expand Down
9 changes: 6 additions & 3 deletions FluidNC/src/Kinematics/Cartesian.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ namespace Kinematics {

virtual bool cartesian_to_motors(float* target, plan_line_data_t* pl_data, float* position) override;
virtual void init() override;
virtual bool kinematics_homing(AxisMask cycle_mask) override;
virtual void kinematics_post_homing() override;
virtual void motors_to_cartesian(float* cartesian, float* motors, int n_axis) override;
void motors_to_cartesian(float* cartesian, float* motors, int n_axis) override;
void transform_cartesian_to_motors(float* cartesian, float* motors) override;

bool canHome(AxisMask axisMask) override;
void releaseMotors(AxisMask axisMask, MotorMask motors, Machine::Homing::Phase phase) override;
bool limitReached(AxisMask& axisMask, MotorMask& motors, MotorMask limited) override;

// Configuration handlers:
void afterParse() override {}
Expand Down
Loading

0 comments on commit 0a78bbe

Please sign in to comment.