tmc2130: More init
parent
1022603f9d
commit
e9046eed42
|
|
@ -9,11 +9,11 @@ using namespace unit;
|
|||
/// Axis configuration data
|
||||
struct AxisConfig {
|
||||
bool dirOn; ///< direction ON state (for inversion)
|
||||
uint8_t uSteps; ///< microstepping [0-8, where 0 is x256 and 8 is fullstepping]
|
||||
bool vSense; ///< vSense scaling
|
||||
uint8_t iRun; ///< running current
|
||||
uint8_t iHold; ///< holding current
|
||||
bool stealth; ///< Default to Stealth mode
|
||||
uint8_t uSteps; ///< microstepping [1-256]
|
||||
long double stepsPerUnit; ///< steps per unit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ static constexpr AxisConfig pulley = {
|
|||
//static constexpr AxisConfig idler = {
|
||||
//>>>>>>> tmc2130: Define the SPI bus for the tmc drivers
|
||||
.dirOn = true,
|
||||
.uSteps = 4, //x16
|
||||
.vSense = false,
|
||||
.iRun = 20,
|
||||
.iHold = 20,
|
||||
|
|
@ -79,6 +80,7 @@ static constexpr PulleyLimits pulleyLimits = {
|
|||
/// Selector configuration
|
||||
static constexpr AxisConfig selector = {
|
||||
.dirOn = true,
|
||||
.uSteps = 4, //x16
|
||||
.vSense = false,
|
||||
.iRun = 20,
|
||||
.iHold = 20,
|
||||
|
|
@ -97,6 +99,7 @@ static constexpr SelectorLimits selectorLimits = {
|
|||
/// Idler configuration
|
||||
static constexpr AxisConfig idler = {
|
||||
.dirOn = true,
|
||||
.uSteps = 4, //x16
|
||||
.vSense = false,
|
||||
.iRun = 20,
|
||||
.iHold = 20,
|
||||
|
|
|
|||
|
|
@ -5,28 +5,71 @@ namespace tmc2130 {
|
|||
|
||||
TMC2130::TMC2130(const MotorParams ¶ms,
|
||||
const MotorCurrents ¤ts,
|
||||
MotorMode mode) {
|
||||
MotorMode mode)
|
||||
: currents(currents) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void TMC2130::Init(const MotorParams ¶ms) {
|
||||
// TODO
|
||||
gpio::Init(params.csPin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high));
|
||||
gpio::Init(params.sgPin, gpio::GPIO_InitTypeDef(gpio::Mode::input, gpio::Pull::up));
|
||||
gpio::Init(params.stepPin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::low));
|
||||
|
||||
///check for compatible tmc driver (IOIN version field)
|
||||
uint32_t IOIN = ReadRegister(params, Registers::IOIN);
|
||||
if (((IOIN >> 24) != 0x11) | !(IOIN & (1 << 6))) ///if the version is incorrect or an always 1 bit is 0 (the supposed SD_MODE pin that doesn't exist on this driver variant)
|
||||
return; // @todo return some kind of failure
|
||||
|
||||
///clear reset flag as we are (re)initializing
|
||||
errorFlags.reset = false;
|
||||
|
||||
///apply chopper parameters
|
||||
uint32_t chopconf = 0;
|
||||
chopconf |= (uint32_t)(3 & 0x0F) << 0; //toff
|
||||
chopconf |= (uint32_t)(5 & 0x07) << 4; //hstrt
|
||||
chopconf |= (uint32_t)(1 & 0x0F) << 7; //hend
|
||||
chopconf |= (uint32_t)(2 & 0x03) << 15; //tbl
|
||||
chopconf |= (uint32_t)(currents.vSense & 0x01) << 17; //vsense
|
||||
chopconf |= (uint32_t)(params.uSteps & 0x0F) << 24; //mres
|
||||
chopconf |= (uint32_t)((bool)params.uSteps) << 28; //intpol
|
||||
chopconf |= (uint32_t)(1 & 0x01) << 29; //dedge
|
||||
WriteRegister(params, Registers::CHOPCONF, chopconf);
|
||||
|
||||
///apply currents
|
||||
uint32_t ihold_irun = 0;
|
||||
ihold_irun |= (uint32_t)(currents.iHold & 0x1F) << 0; //ihold
|
||||
ihold_irun |= (uint32_t)(currents.iRun & 0x1F) << 8; //irun
|
||||
ihold_irun |= (uint32_t)(15 & 0x0F) << 16; //IHOLDDELAY
|
||||
WriteRegister(params, Registers::IHOLD_IRUN, ihold_irun);
|
||||
|
||||
///instant powerdown ramp
|
||||
WriteRegister(params, Registers::TPOWERDOWN, 0);
|
||||
|
||||
///Stallguard parameters
|
||||
int8_t sg_thrs = 3; // @todo 7bit two's complement for the sg_thrs
|
||||
WriteRegister(params, Registers::COOLCONF, (((uint32_t)sg_thrs) << 16)); // @todo should be configurable
|
||||
WriteRegister(params, Registers::TCOOLTHRS, 400); // @todo should be configurable
|
||||
|
||||
///Write stealth mode config and setup diag0 output
|
||||
uint32_t gconf = 0;
|
||||
gconf |= (uint32_t)((uint8_t)mode & 0x01) << 2; //en_pwm_mode
|
||||
gconf |= (uint32_t)(1 & 0x01) << 7; //diag0_stall
|
||||
WriteRegister(params, Registers::GCONF, gconf);
|
||||
}
|
||||
|
||||
uint32_t TMC2130::ReadRegister(const MotorParams ¶ms, Registers reg) {
|
||||
uint8_t pData[5] = {(uint8_t)reg};
|
||||
_spi_tx_rx(params, pData);
|
||||
// _handle_spi_status(pData[0]); /// could be outdated. Safer not to use it.
|
||||
pData[0] = 0;
|
||||
_spi_tx_rx(params, pData);
|
||||
_handle_spi_status(pData[0]);
|
||||
return ((uint32_t)pData[1] << 24 | (uint32_t)pData[2] << 16 | (uint32_t)pData[3] << 8 | (uint32_t)pData[4]);
|
||||
uint8_t pData[5] = { (uint8_t)reg };
|
||||
_spi_tx_rx(params, pData);
|
||||
pData[0] = 0;
|
||||
_spi_tx_rx(params, pData);
|
||||
_handle_spi_status(params, pData[0]);
|
||||
return ((uint32_t)pData[1] << 24 | (uint32_t)pData[2] << 16 | (uint32_t)pData[3] << 8 | (uint32_t)pData[4]);
|
||||
}
|
||||
|
||||
void TMC2130::WriteRegister(const MotorParams ¶ms, Registers reg, uint32_t data) {
|
||||
uint8_t pData[5] = {(uint8_t)((uint8_t)(reg) | 0x80), (uint8_t)(data >> 24), (uint8_t)(data >> 16), (uint8_t)(data >> 8), (uint8_t)data};
|
||||
_spi_tx_rx(params, pData);
|
||||
_handle_spi_status(pData[0]);
|
||||
uint8_t pData[5] = { (uint8_t)((uint8_t)(reg) | 0x80), (uint8_t)(data >> 24), (uint8_t)(data >> 16), (uint8_t)(data >> 8), (uint8_t)data };
|
||||
_spi_tx_rx(params, pData);
|
||||
_handle_spi_status(params, pData[0]);
|
||||
}
|
||||
|
||||
void TMC2130::_spi_tx_rx(const MotorParams ¶ms, uint8_t (&pData)[5]) {
|
||||
|
|
@ -36,8 +79,26 @@ void TMC2130::_spi_tx_rx(const MotorParams ¶ms, uint8_t (&pData)[5]) {
|
|||
hal::gpio::WritePin(params.csPin, hal::gpio::Level::high);
|
||||
}
|
||||
|
||||
void TMC2130::_handle_spi_status(uint8_t status) {
|
||||
spi_status |= status & 0x03; /// update reset_flag and driver_error
|
||||
void TMC2130::_handle_spi_status(const MotorParams ¶ms, uint8_t status) {
|
||||
status &= 0x03;
|
||||
if (status) {
|
||||
uint32_t GSTAT = ReadRegister(params, Registers::GSTAT);
|
||||
if (GSTAT & (1 << 0))
|
||||
errorFlags.reset |= true;
|
||||
if (GSTAT & (1 << 1)) {
|
||||
uint32_t DRV_STATUS = ReadRegister(params, Registers::DRV_STATUS);
|
||||
if (DRV_STATUS & (1ul << 25))
|
||||
errorFlags.ot |= true;
|
||||
if (DRV_STATUS & (1ul << 26))
|
||||
errorFlags.otpw |= true;
|
||||
if (DRV_STATUS & (1ul << 27))
|
||||
errorFlags.s2ga |= true;
|
||||
if (DRV_STATUS & (1ul << 28))
|
||||
errorFlags.s2gb |= true;
|
||||
}
|
||||
if (GSTAT & (1 << 2))
|
||||
errorFlags.uv_cp |= true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tmc2130
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ struct MotorParams {
|
|||
gpio::GPIO_pin csPin; ///< CS pin
|
||||
gpio::GPIO_pin stepPin; ///< step pin
|
||||
gpio::GPIO_pin sgPin; ///< stallguard pin
|
||||
uint8_t uSteps; ///< microstep resolution
|
||||
uint8_t uSteps; ///< microstep resolution (mres)
|
||||
};
|
||||
|
||||
struct MotorCurrents {
|
||||
|
|
@ -35,7 +35,14 @@ struct MotorCurrents {
|
|||
class TMC2130 {
|
||||
MotorMode mode;
|
||||
MotorCurrents currents;
|
||||
uint8_t spi_status = 0;
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t reset : 1;
|
||||
uint8_t uv_cp : 1;
|
||||
uint8_t s2ga : 1;
|
||||
uint8_t s2gb : 1;
|
||||
uint8_t otpw : 1;
|
||||
uint8_t ot : 1;
|
||||
} errorFlags;
|
||||
|
||||
public:
|
||||
enum class Registers : uint8_t {
|
||||
|
|
@ -115,7 +122,7 @@ public:
|
|||
|
||||
private:
|
||||
void _spi_tx_rx(const MotorParams ¶ms, uint8_t (&pData)[5]);
|
||||
void _handle_spi_status(uint8_t status);
|
||||
void _handle_spi_status(const MotorParams ¶ms, uint8_t status);
|
||||
};
|
||||
|
||||
} // namespace tmc2130
|
||||
|
|
|
|||
Loading…
Reference in New Issue