mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-09-01 18:32:37 +02:00
Trinamic define elimination and factoring
This commit is contained in:
@@ -16,12 +16,16 @@
|
|||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "TrinamicBase.h"
|
#include "TrinamicBase.h"
|
||||||
#include "../Machine/MachineConfig.h"
|
#include "../Machine/MachineConfig.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
namespace Motors {
|
namespace Motors {
|
||||||
|
EnumItem trinamicModes[] = { { TrinamicMode::StealthChop, "StealthChop" },
|
||||||
|
{ TrinamicMode::CoolStep, "CoolStep" },
|
||||||
|
{ TrinamicMode::StallGuard, "StallGuard" },
|
||||||
|
EnumItem(TrinamicMode::StealthChop) };
|
||||||
|
|
||||||
TrinamicBase* TrinamicBase::List = NULL; // a static list of all drivers for stallguard reporting
|
TrinamicBase* TrinamicBase::List = NULL; // a static list of all drivers for stallguard reporting
|
||||||
|
|
||||||
uint8_t TrinamicBase::get_next_index() {
|
uint8_t TrinamicBase::get_next_index() {
|
||||||
@@ -57,17 +61,52 @@ namespace Motors {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate a tstep from a rate
|
// calculate a tstep from a rate
|
||||||
// tstep = TRINAMIC_FCLK / (time between 1/256 steps)
|
// tstep = fclk / (time between 1/256 steps)
|
||||||
// This is used to set the stallguard window from the homing speed.
|
// This is used to set the stallguard window from the homing speed.
|
||||||
// The percent is the offset on the window
|
// The percent is the offset on the window
|
||||||
uint32_t TrinamicBase::calc_tstep(float speed, float percent) {
|
uint32_t TrinamicBase::calc_tstep(float speed, float percent) {
|
||||||
double tstep = speed / 60.0 * config->_axes->_axis[axis_index()]->_stepsPerMm * (256.0 / _microsteps);
|
double tstep = speed / 60.0 * config->_axes->_axis[axis_index()]->_stepsPerMm * (256.0 / _microsteps);
|
||||||
tstep = TRINAMIC_FCLK / tstep * percent / 100.0;
|
tstep = fclk / tstep * percent / 100.0;
|
||||||
|
|
||||||
return static_cast<uint32_t>(tstep);
|
return static_cast<uint32_t>(tstep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========== Reporting functions ========================
|
||||||
|
|
||||||
|
bool TrinamicBase::report_open_load(bool ola, bool olb) {
|
||||||
|
if (ola || olb) {
|
||||||
|
info_serial("%s Driver Open Load a:%s b:%s", reportAxisNameMsg(axis_index(), dual_axis_index()), ola ? "Y" : "N", olb ? "Y" : "N");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrinamicBase::report_short_to_ground(bool s2ga, bool s2gb) {
|
||||||
|
if (s2ga || s2gb) {
|
||||||
|
info_serial(
|
||||||
|
"%s Driver Short Coil a:%s b:%s", reportAxisNameMsg(axis_index(), dual_axis_index()), s2ga ? "Y" : "N", s2gb ? "Y" : "N");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrinamicBase::report_over_temp(bool ot, bool otpw) {
|
||||||
|
if (ot || otpw) {
|
||||||
|
info_serial(
|
||||||
|
"%s Driver Temp Warning:%s Fault:%s", reportAxisNameMsg(axis_index(), dual_axis_index()), otpw ? "Y" : "N", ot ? "Y" : "N");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrinamicBase::report_short_to_ps(bool vsa, bool vsb) {
|
||||||
|
// check for short to power supply
|
||||||
|
if (vsa || vsb) {
|
||||||
|
info_serial("%s Driver Short vsa:%s vsb:%s", reportAxisNameMsg(axis_index(), dual_axis_index()), vsa ? "Y" : "N", vsb ? "Y" : "N");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,32 +21,30 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "StandardStepper.h"
|
#include "StandardStepper.h"
|
||||||
|
|
||||||
#ifndef TRINAMIC_RUN_MODE
|
|
||||||
# define TRINAMIC_RUN_MODE TrinamicMode ::StealthChop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_HOMING_MODE
|
|
||||||
# define TRINAMIC_HOMING_MODE TRINAMIC_RUN_MODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Motors {
|
namespace Motors {
|
||||||
|
|
||||||
enum class TrinamicMode : uint8_t {
|
enum TrinamicMode {
|
||||||
None = 0, // not for machine defs!
|
StealthChop = 1, // very quiet
|
||||||
StealthChop = 1,
|
CoolStep = 2, // cooler so higher current possible
|
||||||
CoolStep = 2,
|
StallGuard = 3, // coolstep plus stall indication
|
||||||
StallGuard = 3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern EnumItem trinamicModes[];
|
||||||
|
|
||||||
class TrinamicBase : public StandardStepper {
|
class TrinamicBase : public StandardStepper {
|
||||||
protected:
|
protected:
|
||||||
uint32_t calc_tstep(float speed, float percent);
|
uint32_t calc_tstep(float speed, float percent);
|
||||||
|
|
||||||
uint16_t _driver_part_number; // example: use 2130 for TMC2130
|
|
||||||
TrinamicMode _homing_mode;
|
|
||||||
float _r_sense;
|
|
||||||
bool _has_errors;
|
bool _has_errors;
|
||||||
bool _disabled;
|
uint16_t _driver_part_number; // example: use 2130 for TMC2130
|
||||||
|
bool _disabled = false;
|
||||||
|
TrinamicMode _mode = StealthChop;
|
||||||
|
|
||||||
|
// Configurable
|
||||||
|
int _homing_mode = StealthChop;
|
||||||
|
int _run_mode = StealthChop;
|
||||||
|
float _r_sense = 0.11;
|
||||||
|
bool _use_enable = false;
|
||||||
|
|
||||||
float _run_current = 0.25;
|
float _run_current = 0.25;
|
||||||
float _hold_current = 0.25;
|
float _hold_current = 0.25;
|
||||||
@@ -54,7 +52,9 @@ namespace Motors {
|
|||||||
int _stallguard = 0;
|
int _stallguard = 0;
|
||||||
bool _stallguardDebugMode = false;
|
bool _stallguardDebugMode = false;
|
||||||
|
|
||||||
TrinamicMode _mode = TrinamicMode::None;
|
uint8_t _toff_disable = 0;
|
||||||
|
uint8_t _toff_stealthchop = 5;
|
||||||
|
uint8_t _toff_coolstep = 3;
|
||||||
|
|
||||||
uint8_t get_next_index();
|
uint8_t get_next_index();
|
||||||
|
|
||||||
@@ -64,10 +64,15 @@ namespace Motors {
|
|||||||
TrinamicBase* link;
|
TrinamicBase* link;
|
||||||
static void readSgTask(void*);
|
static void readSgTask(void*);
|
||||||
|
|
||||||
const double TRINAMIC_FCLK = 12700000.0; // Internal clock Approx (Hz) used to calculate TSTEP from homing rate
|
const double fclk = 12700000.0; // Internal clock Approx (Hz) used to calculate TSTEP from homing rate
|
||||||
|
|
||||||
|
bool report_open_load(bool ola, bool olb);
|
||||||
|
bool report_short_to_ground(bool s2ga, bool s2gb);
|
||||||
|
bool report_over_temp(bool ot, bool otpw);
|
||||||
|
bool report_short_to_ps(bool vsa, bool vsb);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TrinamicBase(uint16_t partNumber) : StandardStepper(), _driver_part_number(partNumber), _homing_mode(TRINAMIC_HOMING_MODE) {}
|
TrinamicBase(uint16_t partNumber) : StandardStepper(), _driver_part_number(partNumber) {}
|
||||||
|
|
||||||
void group(Configuration::HandlerBase& handler) override {
|
void group(Configuration::HandlerBase& handler) override {
|
||||||
handler.item("r_sense", _r_sense);
|
handler.item("r_sense", _r_sense);
|
||||||
@@ -76,6 +81,12 @@ namespace Motors {
|
|||||||
handler.item("microsteps", _microsteps);
|
handler.item("microsteps", _microsteps);
|
||||||
handler.item("stallguard", _stallguard);
|
handler.item("stallguard", _stallguard);
|
||||||
handler.item("stallguardDebugMode", _stallguardDebugMode);
|
handler.item("stallguardDebugMode", _stallguardDebugMode);
|
||||||
|
handler.item("toff_disable", _toff_disable);
|
||||||
|
handler.item("toff_stealthchop", _toff_stealthchop);
|
||||||
|
handler.item("toff_coolstep", _toff_coolstep);
|
||||||
|
handler.item("run_mode", _run_mode, trinamicModes);
|
||||||
|
handler.item("homing_mode", _homing_mode, trinamicModes);
|
||||||
|
handler.item("use_enable", _use_enable);
|
||||||
|
|
||||||
StandardStepper::group(handler);
|
StandardStepper::group(handler);
|
||||||
}
|
}
|
||||||
|
@@ -62,8 +62,7 @@ void TMC2130Stepper::switchCSpin(bool state) {
|
|||||||
|
|
||||||
namespace Motors {
|
namespace Motors {
|
||||||
TrinamicDriver::TrinamicDriver(uint16_t driver_part_number, int8_t spi_index) :
|
TrinamicDriver::TrinamicDriver(uint16_t driver_part_number, int8_t spi_index) :
|
||||||
TrinamicBase(driver_part_number),
|
TrinamicBase(driver_part_number), _spi_index(spi_index) {}
|
||||||
_spi_index(spi_index) {}
|
|
||||||
|
|
||||||
void TrinamicDriver::init() {
|
void TrinamicDriver::init() {
|
||||||
_has_errors = false;
|
_has_errors = false;
|
||||||
@@ -84,7 +83,7 @@ namespace Motors {
|
|||||||
|
|
||||||
// use slower speed if I2S
|
// use slower speed if I2S
|
||||||
if (_cs_pin.capabilities().has(Pin::Capabilities::I2S)) {
|
if (_cs_pin.capabilities().has(Pin::Capabilities::I2S)) {
|
||||||
tmcstepper->setSPISpeed(TRINAMIC_SPI_FREQ);
|
tmcstepper->setSPISpeed(_spi_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
link = List;
|
link = List;
|
||||||
@@ -174,18 +173,20 @@ namespace Motors {
|
|||||||
bool err = false;
|
bool err = false;
|
||||||
|
|
||||||
// look for errors
|
// look for errors
|
||||||
if (report_short_to_ground(status)) {
|
if (report_short_to_ground(status.s2ga, status.s2gb)) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_over_temp(status)) {
|
if (report_over_temp(status.ot, status.otpw)) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_short_to_ps(status)) {
|
if (report_short_to_ps(bit_istrue(status.sr, 12), bit_istrue(status.sr, 13))) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX why not report_open_load(status.ola, status.olb) ?
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -196,12 +197,11 @@ namespace Motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
o Read setting and send them to the driver. Called at init() and whenever related settings change
|
Read setting and send them to the driver. Called at init() and whenever related settings change
|
||||||
both are stored as float Amps, but TMCStepper library expects...
|
both are stored as float Amps, but TMCStepper library expects...
|
||||||
uint16_t run (mA)
|
uint16_t run (mA)
|
||||||
float hold (as a percentage of run)
|
float hold (as a percentage of run)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TrinamicDriver::read_settings() {
|
void TrinamicDriver::read_settings() {
|
||||||
if (_has_errors) {
|
if (_has_errors) {
|
||||||
return;
|
return;
|
||||||
@@ -214,8 +214,9 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
hold_i_percent = 0;
|
hold_i_percent = 0;
|
||||||
} else {
|
} else {
|
||||||
hold_i_percent = _hold_current / _run_current;
|
hold_i_percent = _hold_current / _run_current;
|
||||||
if (hold_i_percent > 1.0)
|
if (hold_i_percent > 1.0) {
|
||||||
hold_i_percent = 1.0;
|
hold_i_percent = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmcstepper->microsteps(_microsteps);
|
tmcstepper->microsteps(_microsteps);
|
||||||
@@ -231,7 +232,7 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
There are ton of settings. I'll start by grouping then into modes for now.
|
There are ton of settings. I'll start by grouping then into modes for now.
|
||||||
Many people will want quiet and stallgaurd homing. Stallguard only run in
|
Many people will want quiet and stallguard homing. Stallguard only run in
|
||||||
Coolstep mode, so it will need to switch to Coolstep when homing
|
Coolstep mode, so it will need to switch to Coolstep when homing
|
||||||
*/
|
*/
|
||||||
void TrinamicDriver::set_mode(bool isHoming) {
|
void TrinamicDriver::set_mode(bool isHoming) {
|
||||||
@@ -239,7 +240,7 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrinamicMode newMode = isHoming ? TRINAMIC_HOMING_MODE : TRINAMIC_RUN_MODE;
|
TrinamicMode newMode = static_cast<TrinamicMode>(trinamicModes[isHoming ? _homing_mode : _run_mode].value);
|
||||||
|
|
||||||
if (newMode == _mode) {
|
if (newMode == _mode) {
|
||||||
return;
|
return;
|
||||||
@@ -274,8 +275,6 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
tmcstepper->sgt(constrain(_stallguard, -64, 63));
|
tmcstepper->sgt(constrain(_stallguard, -64, 63));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
info_serial("TRINAMIC_MODE_UNDEFINED");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,14 +300,16 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
feedrate,
|
feedrate,
|
||||||
constrain(_stallguard, -64, 63));
|
constrain(_stallguard, -64, 63));
|
||||||
|
|
||||||
|
// The bit locations differ somewhat between different chips.
|
||||||
|
// The layout is very different between 2130 and 2208
|
||||||
TMC2130_n ::DRV_STATUS_t status { 0 }; // a useful struct to access the bits.
|
TMC2130_n ::DRV_STATUS_t status { 0 }; // a useful struct to access the bits.
|
||||||
status.sr = tmcstepper->DRV_STATUS();
|
status.sr = tmcstepper->DRV_STATUS();
|
||||||
|
|
||||||
// these only report if there is a fault condition
|
// these only report if there is a fault condition
|
||||||
report_open_load(status);
|
report_open_load(status.ola, status.olb);
|
||||||
report_short_to_ground(status);
|
report_short_to_ground(status.s2ga, status.s2gb);
|
||||||
report_over_temp(status);
|
report_over_temp(status.ot, status.otpw);
|
||||||
report_short_to_ps(status);
|
report_short_to_ps(bit_istrue(status.sr, 12), bit_istrue(status.sr, 13));
|
||||||
|
|
||||||
// info_serial("%s Status Register %08x GSTAT %02x",
|
// info_serial("%s Status Register %08x GSTAT %02x",
|
||||||
// reportAxisNameMsg(axis_index(), dual_axis_index()),
|
// reportAxisNameMsg(axis_index(), dual_axis_index()),
|
||||||
@@ -331,68 +332,21 @@ o Read setting and send them to the driver. Called at init() and whenever rel
|
|||||||
|
|
||||||
_disable_pin.write(_disabled);
|
_disable_pin.write(_disabled);
|
||||||
|
|
||||||
#ifdef USE_TRINAMIC_ENABLE
|
if (_use_enable) {
|
||||||
if (_disabled) {
|
if (_disabled) {
|
||||||
tmcstepper->toff(TRINAMIC_TOFF_DISABLE);
|
tmcstepper->toff(_toff_disable);
|
||||||
} else {
|
|
||||||
if (_mode == TrinamicMode::StealthChop) {
|
|
||||||
tmcstepper->toff(TRINAMIC_TOFF_STEALTHCHOP);
|
|
||||||
} else {
|
} else {
|
||||||
tmcstepper->toff(TRINAMIC_TOFF_COOLSTEP);
|
if (_mode == TrinamicMode::StealthChop) {
|
||||||
|
tmcstepper->toff(_toff_stealthchop);
|
||||||
|
} else {
|
||||||
|
tmcstepper->toff(_toff_coolstep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// the pin based enable could be added here.
|
// the pin based enable could be added here.
|
||||||
// This would be for individual motors, not the single pin for all motors.
|
// This would be for individual motors, not the single pin for all motors.
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========== Reporting functions ========================
|
|
||||||
|
|
||||||
bool TrinamicDriver::report_open_load(TMC2130_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.ola || status.olb) {
|
|
||||||
info_serial("%s Driver Open Load a:%s b:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.ola ? "Y" : "N",
|
|
||||||
status.olb ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicDriver::report_short_to_ground(TMC2130_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.s2ga || status.s2gb) {
|
|
||||||
info_serial("%s Driver Short Coil a:%s b:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.s2ga ? "Y" : "N",
|
|
||||||
status.s2gb ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicDriver::report_over_temp(TMC2130_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.ot || status.otpw) {
|
|
||||||
info_serial("%s Driver Temp Warning:%s Fault:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.otpw ? "Y" : "N",
|
|
||||||
status.ot ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicDriver::report_short_to_ps(TMC2130_n ::DRV_STATUS_t status) {
|
|
||||||
// check for short to power supply
|
|
||||||
if ((status.sr & bit(12)) || (status.sr & bit(13))) {
|
|
||||||
info_serial("%s Driver Short vsa:%s vsb:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
(status.sr & bit(12)) ? "Y" : "N",
|
|
||||||
(status.sr & bit(13)) ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configuration registration
|
// Configuration registration
|
||||||
namespace {
|
namespace {
|
||||||
MotorFactory::InstanceBuilder<TMC2130> registration_2130("tmc_2130");
|
MotorFactory::InstanceBuilder<TMC2130> registration_2130("tmc_2130");
|
||||||
|
@@ -24,36 +24,18 @@
|
|||||||
|
|
||||||
#include <TMCStepper.h> // https://github.com/teemuatlut/TMCStepper
|
#include <TMCStepper.h> // https://github.com/teemuatlut/TMCStepper
|
||||||
|
|
||||||
//#define TRINAMIC_MODE_STEALTHCHOP 0 // very quiet
|
|
||||||
//#define TRINAMIC_MODE_COOLSTEP 1 // everything runs cooler so higher current possible
|
|
||||||
//#define TRINAMIC_MODE_STALLGUARD 2 // coolstep plus generates stall indication
|
|
||||||
|
|
||||||
const float TMC2130_RSENSE_DEFAULT = 0.11f;
|
const float TMC2130_RSENSE_DEFAULT = 0.11f;
|
||||||
const float TMC5160_RSENSE_DEFAULT = 0.075f;
|
const float TMC5160_RSENSE_DEFAULT = 0.075f;
|
||||||
|
|
||||||
const int NORMAL_TCOOLTHRS = 0xFFFFF; // 20 bit is max
|
const int NORMAL_TCOOLTHRS = 0xFFFFF; // 20 bit is max
|
||||||
const int NORMAL_THIGH = 0;
|
const int NORMAL_THIGH = 0;
|
||||||
|
|
||||||
const int TRINAMIC_SPI_FREQ = 100000;
|
|
||||||
|
|
||||||
// ==== defaults OK to define them in your machine definition ====
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_TOFF_DISABLE
|
|
||||||
# define TRINAMIC_TOFF_DISABLE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_TOFF_STEALTHCHOP
|
|
||||||
# define TRINAMIC_TOFF_STEALTHCHOP 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_TOFF_COOLSTEP
|
|
||||||
# define TRINAMIC_TOFF_COOLSTEP 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Motors {
|
namespace Motors {
|
||||||
|
|
||||||
class TrinamicDriver : public TrinamicBase {
|
class TrinamicDriver : public TrinamicBase {
|
||||||
private:
|
private:
|
||||||
|
const int _spi_freq = 100000;
|
||||||
|
|
||||||
TMC2130Stepper* tmcstepper; // all other driver types are subclasses of this one
|
TMC2130Stepper* tmcstepper; // all other driver types are subclasses of this one
|
||||||
Pin _cs_pin; // The chip select pin (can be the same for daisy chain)
|
Pin _cs_pin; // The chip select pin (can be the same for daisy chain)
|
||||||
int8_t _spi_index;
|
int8_t _spi_index;
|
||||||
@@ -63,11 +45,6 @@ namespace Motors {
|
|||||||
void trinamic_test_response();
|
void trinamic_test_response();
|
||||||
void trinamic_stepper_enable(bool enable);
|
void trinamic_stepper_enable(bool enable);
|
||||||
|
|
||||||
bool report_open_load(TMC2130_n ::DRV_STATUS_t status);
|
|
||||||
bool report_short_to_ground(TMC2130_n ::DRV_STATUS_t status);
|
|
||||||
bool report_over_temp(TMC2130_n ::DRV_STATUS_t status);
|
|
||||||
bool report_short_to_ps(TMC2130_n ::DRV_STATUS_t status);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void config_message() override;
|
void config_message() override;
|
||||||
|
|
||||||
@@ -90,7 +67,10 @@ namespace Motors {
|
|||||||
StandardStepper::validate();
|
StandardStepper::validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void group(Configuration::HandlerBase& handler) override { TrinamicBase::group(handler); }
|
void group(Configuration::HandlerBase& handler) override {
|
||||||
|
handler.item("cs", _cs_pin);
|
||||||
|
TrinamicBase::group(handler);
|
||||||
|
}
|
||||||
|
|
||||||
// Name of the configurable. Must match the name registered in the cpp file.
|
// Name of the configurable. Must match the name registered in the cpp file.
|
||||||
const char* name() const override { return "trinamic_spi"; }
|
const char* name() const override { return "trinamic_spi"; }
|
||||||
|
@@ -34,10 +34,8 @@ namespace Motors {
|
|||||||
|
|
||||||
bool TrinamicUartDriver::_uart_started = false;
|
bool TrinamicUartDriver::_uart_started = false;
|
||||||
|
|
||||||
|
|
||||||
/* HW Serial Constructor. */
|
/* HW Serial Constructor. */
|
||||||
TrinamicUartDriver::TrinamicUartDriver(uint16_t driver_part_number, uint8_t addr) :
|
TrinamicUartDriver::TrinamicUartDriver(uint16_t driver_part_number, uint8_t addr) : TrinamicBase(driver_part_number), _addr(addr) {}
|
||||||
TrinamicBase(driver_part_number), _addr(addr) {}
|
|
||||||
|
|
||||||
void TrinamicUartDriver::init() {
|
void TrinamicUartDriver::init() {
|
||||||
if (!_uart_started) {
|
if (!_uart_started) {
|
||||||
@@ -52,16 +50,16 @@ namespace Motors {
|
|||||||
link = List;
|
link = List;
|
||||||
List = this;
|
List = this;
|
||||||
|
|
||||||
|
if (_has_errors) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Display the stepper library version message once, before the first
|
// Display the stepper library version message once, before the first
|
||||||
// TMC config message. Link is NULL for the first TMC instance.
|
// TMC config message. Link is NULL for the first TMC instance.
|
||||||
if (!link) {
|
if (!link) {
|
||||||
info_serial("TMCStepper Library Ver. 0x%06x", TMCSTEPPER_VERSION);
|
info_serial("TMCStepper Library Ver. 0x%06x", TMCSTEPPER_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_has_errors) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_message();
|
config_message();
|
||||||
|
|
||||||
tmcstepper->begin();
|
tmcstepper->begin();
|
||||||
@@ -124,10 +122,10 @@ namespace Motors {
|
|||||||
|
|
||||||
switch (tmcstepper->test_connection()) {
|
switch (tmcstepper->test_connection()) {
|
||||||
case 1:
|
case 1:
|
||||||
info_serial("%s driver test failed. Check connection", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
info_serial("%s Trinamic driver test failed. Check connection", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
||||||
return false;
|
return false;
|
||||||
case 2:
|
case 2:
|
||||||
info_serial("%s driver test failed. Check motor power", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
info_serial("%s Trinamic driver test failed. Check motor power", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
// driver responded, so check for other errors from the DRV_STATUS register
|
// driver responded, so check for other errors from the DRV_STATUS register
|
||||||
@@ -138,23 +136,25 @@ namespace Motors {
|
|||||||
bool err = false;
|
bool err = false;
|
||||||
|
|
||||||
// look for errors
|
// look for errors
|
||||||
if (report_short_to_ground(status)) {
|
if (report_short_to_ground(status.s2ga, status.s2gb)) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_over_temp(status)) {
|
if (report_over_temp(status.ot, status.otpw)) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_short_to_ps(status)) {
|
if (report_short_to_ps(bit_istrue(status.sr, 12), bit_istrue(status.sr, 13))) {
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX why not report_open_load(status.ola, status.olb) ?
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info_serial("%s driver test passed", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
info_serial("%s Trinamic driver test passed", reportAxisNameMsg(axis_index(), dual_axis_index()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,6 +165,7 @@ namespace Motors {
|
|||||||
uint16_t run (mA)
|
uint16_t run (mA)
|
||||||
float hold (as a percentage of run)
|
float hold (as a percentage of run)
|
||||||
*/
|
*/
|
||||||
|
// XXX Identical to TrinamicDriver::read_settings()
|
||||||
void TrinamicUartDriver::read_settings() {
|
void TrinamicUartDriver::read_settings() {
|
||||||
if (_has_errors) {
|
if (_has_errors) {
|
||||||
return;
|
return;
|
||||||
@@ -177,8 +178,9 @@ namespace Motors {
|
|||||||
hold_i_percent = 0;
|
hold_i_percent = 0;
|
||||||
} else {
|
} else {
|
||||||
hold_i_percent = _hold_current / _run_current;
|
hold_i_percent = _hold_current / _run_current;
|
||||||
if (hold_i_percent > 1.0)
|
if (hold_i_percent > 1.0) {
|
||||||
hold_i_percent = 1.0;
|
hold_i_percent = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmcstepper->microsteps(_microsteps);
|
tmcstepper->microsteps(_microsteps);
|
||||||
@@ -187,6 +189,7 @@ namespace Motors {
|
|||||||
init_step_dir_pins();
|
init_step_dir_pins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX Identical to TrinamicDriver::set_homing_mode()
|
||||||
bool TrinamicUartDriver::set_homing_mode(bool isHoming) {
|
bool TrinamicUartDriver::set_homing_mode(bool isHoming) {
|
||||||
set_mode(isHoming);
|
set_mode(isHoming);
|
||||||
return true;
|
return true;
|
||||||
@@ -194,7 +197,7 @@ namespace Motors {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
There are ton of settings. I'll start by grouping then into modes for now.
|
There are ton of settings. I'll start by grouping then into modes for now.
|
||||||
Many people will want quiet and stallgaurd homing. Stallguard only run in
|
Many people will want quiet and stallguard homing. Stallguard only run in
|
||||||
Coolstep mode, so it will need to switch to Coolstep when homing
|
Coolstep mode, so it will need to switch to Coolstep when homing
|
||||||
*/
|
*/
|
||||||
void TrinamicUartDriver::set_mode(bool isHoming) {
|
void TrinamicUartDriver::set_mode(bool isHoming) {
|
||||||
@@ -202,7 +205,7 @@ namespace Motors {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrinamicMode newMode = isHoming ? TRINAMIC_HOMING_MODE : TRINAMIC_RUN_MODE;
|
TrinamicMode newMode = static_cast<TrinamicMode>(trinamicModes[isHoming ? _homing_mode : _run_mode].value);
|
||||||
|
|
||||||
if (newMode == _mode) {
|
if (newMode == _mode) {
|
||||||
return;
|
return;
|
||||||
@@ -244,6 +247,7 @@ namespace Motors {
|
|||||||
if (_has_errors) {
|
if (_has_errors) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tstep = tmcstepper->TSTEP();
|
uint32_t tstep = tmcstepper->TSTEP();
|
||||||
|
|
||||||
if (tstep == 0xFFFFF || tstep < 1) { // if axis is not moving return
|
if (tstep == 0xFFFFF || tstep < 1) { // if axis is not moving return
|
||||||
@@ -261,10 +265,10 @@ namespace Motors {
|
|||||||
status.sr = tmcstepper->DRV_STATUS();
|
status.sr = tmcstepper->DRV_STATUS();
|
||||||
|
|
||||||
// these only report if there is a fault condition
|
// these only report if there is a fault condition
|
||||||
report_open_load(status);
|
report_open_load(status.ola, status.olb);
|
||||||
report_short_to_ground(status);
|
report_short_to_ground(status.s2ga, status.s2gb);
|
||||||
report_over_temp(status);
|
report_over_temp(status.ot, status.otpw);
|
||||||
report_short_to_ps(status);
|
report_short_to_ps(bit_istrue(status.sr, 12), bit_istrue(status.sr, 13));
|
||||||
|
|
||||||
// info_serial("%s Status Register %08x GSTAT %02x",
|
// info_serial("%s Status Register %08x GSTAT %02x",
|
||||||
// reportAxisNameMsg(axis_index(), dual_axis_index()),
|
// reportAxisNameMsg(axis_index(), dual_axis_index()),
|
||||||
@@ -272,6 +276,7 @@ namespace Motors {
|
|||||||
// tmcstepper->GSTAT());
|
// tmcstepper->GSTAT());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX Identical to TrinamicDriver::set_disable()
|
||||||
// this can use the enable feature over SPI. The dedicated pin must be in the enable mode,
|
// this can use the enable feature over SPI. The dedicated pin must be in the enable mode,
|
||||||
// but that can be hardwired that way.
|
// but that can be hardwired that way.
|
||||||
void TrinamicUartDriver::set_disable(bool disable) {
|
void TrinamicUartDriver::set_disable(bool disable) {
|
||||||
@@ -287,68 +292,21 @@ namespace Motors {
|
|||||||
|
|
||||||
_disable_pin.write(_disabled);
|
_disable_pin.write(_disabled);
|
||||||
|
|
||||||
#ifdef USE_TRINAMIC_ENABLE
|
if (_use_enable) {
|
||||||
if (_disabled) {
|
if (_disabled) {
|
||||||
tmcstepper->toff(TRINAMIC_UART_TOFF_DISABLE);
|
tmcstepper->toff(_toff_disable);
|
||||||
} else {
|
|
||||||
if (_mode == TrinamicMode::StealthChop) {
|
|
||||||
tmcstepper->toff(TRINAMIC_UART_TOFF_STEALTHCHOP);
|
|
||||||
} else {
|
} else {
|
||||||
tmcstepper->toff(TRINAMIC_UART_TOFF_COOLSTEP);
|
if (_mode == TrinamicMode::StealthChop) {
|
||||||
|
tmcstepper->toff(_toff_stealthchop);
|
||||||
|
} else {
|
||||||
|
tmcstepper->toff(_toff_coolstep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// the pin based enable could be added here.
|
// the pin based enable could be added here.
|
||||||
// This would be for individual motors, not the single pin for all motors.
|
// This would be for individual motors, not the single pin for all motors.
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========== Reporting functions ========================
|
|
||||||
|
|
||||||
bool TrinamicUartDriver::report_open_load(TMC2208_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.ola || status.olb) {
|
|
||||||
info_serial("%s Driver Open Load a:%s b:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.ola ? "Y" : "N",
|
|
||||||
status.olb ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicUartDriver::report_short_to_ground(TMC2208_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.s2ga || status.s2gb) {
|
|
||||||
info_serial("%s Driver Short Coil a:%s b:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.s2ga ? "Y" : "N",
|
|
||||||
status.s2gb ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicUartDriver::report_over_temp(TMC2208_n ::DRV_STATUS_t status) {
|
|
||||||
if (status.ot || status.otpw) {
|
|
||||||
info_serial("%s Driver Temp Warning:%s Fault:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
status.otpw ? "Y" : "N",
|
|
||||||
status.ot ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrinamicUartDriver::report_short_to_ps(TMC2208_n ::DRV_STATUS_t status) {
|
|
||||||
// check for short to power supply
|
|
||||||
if ((status.sr & bit(12)) || (status.sr & bit(13))) {
|
|
||||||
info_serial("%s Driver Short vsa:%s vsb:%s",
|
|
||||||
reportAxisNameMsg(axis_index(), dual_axis_index()),
|
|
||||||
(status.sr & bit(12)) ? "Y" : "N",
|
|
||||||
(status.sr & bit(13)) ? "Y" : "N");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false; // no error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configuration registration
|
// Configuration registration
|
||||||
namespace {
|
namespace {
|
||||||
MotorFactory::InstanceBuilder<TMC2208> registration_2208("tmc_2208");
|
MotorFactory::InstanceBuilder<TMC2208> registration_2208("tmc_2208");
|
||||||
|
@@ -28,20 +28,6 @@
|
|||||||
const float TMC2208_RSENSE_DEFAULT = 0.11f;
|
const float TMC2208_RSENSE_DEFAULT = 0.11f;
|
||||||
const float TMC2209_RSENSE_DEFAULT = 0.11f;
|
const float TMC2209_RSENSE_DEFAULT = 0.11f;
|
||||||
|
|
||||||
// ==== defaults OK to define them in your machine definition ====
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_UART_TOFF_DISABLE
|
|
||||||
# define TRINAMIC_UART_TOFF_DISABLE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_UART_TOFF_STEALTHCHOP
|
|
||||||
# define TRINAMIC_UART_TOFF_STEALTHCHOP 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRINAMIC_UART_TOFF_COOLSTEP
|
|
||||||
# define TRINAMIC_UART_TOFF_COOLSTEP 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TMC_UART
|
#ifndef TMC_UART
|
||||||
# define TMC_UART UART_NUM_2
|
# define TMC_UART UART_NUM_2
|
||||||
#endif
|
#endif
|
||||||
@@ -71,11 +57,6 @@ namespace Motors {
|
|||||||
void trinamic_test_response();
|
void trinamic_test_response();
|
||||||
void trinamic_stepper_enable(bool enable);
|
void trinamic_stepper_enable(bool enable);
|
||||||
|
|
||||||
bool report_open_load(TMC2208_n ::DRV_STATUS_t status);
|
|
||||||
bool report_short_to_ground(TMC2208_n ::DRV_STATUS_t status);
|
|
||||||
bool report_over_temp(TMC2208_n ::DRV_STATUS_t status);
|
|
||||||
bool report_short_to_ps(TMC2208_n ::DRV_STATUS_t status);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void config_message() override;
|
void config_message() override;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user