diff --git a/src/config/axis.h b/src/config/axis.h index c55afbe..11a67b7 100644 --- a/src/config/axis.h +++ b/src/config/axis.h @@ -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 }; diff --git a/src/config/config.h b/src/config/config.h index dcad1d8..41ced4f 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -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, diff --git a/src/hal/avr/tmc2130.cpp b/src/hal/avr/tmc2130.cpp index be9ac1f..4c88e8d 100644 --- a/src/hal/avr/tmc2130.cpp +++ b/src/hal/avr/tmc2130.cpp @@ -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 diff --git a/src/hal/tmc2130.h b/src/hal/tmc2130.h index 610e1d1..2f57b55 100644 --- a/src/hal/tmc2130.h +++ b/src/hal/tmc2130.h @@ -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