Library for Trinamic TMC2209 stepper modules to drive bipolar stepper motors. Ported and adapted from https://github.com/teemuatlut/TMCStepper
TMCStepper.h
- Committer:
- charly
- Date:
- 2021-12-02
- Revision:
- 2:b34e91b54373
- Parent:
- 0:f4343071c8b1
File content as of revision 2:b34e91b54373:
#pragma once //#define TMCDEBUG #include "mbed.h" #define SW_CAPABLE_PLATFORM true //#include "TMC2130_bitfields.h" //#include "TMC2160_bitfields.h" //#include "TMC5130_bitfields.h" //#include "TMC5160_bitfields.h" #include "TMC2208_bitfields.h" #include "TMC2209_bitfields.h" //#include "TMC2660_bitfields.h" #define INIT_REGISTER(REG) REG##_t REG##_register = REG##_t //#define INIT2130_REGISTER(REG) TMC2130_n::REG##_t REG##_register = TMC2130_n::REG##_t //#define INIT2160_REGISTER(REG) TMC2160_n::REG##_t REG##_register = TMC2160_n::REG##_t //#define INIT5130_REGISTER(REG) TMC5130_n::REG##_t REG##_register = TMC5130_n::REG##_t //#define INIT5160_REGISTER(REG) TMC5160_n::REG##_t REG##_register = TMC5160_n::REG##_t //#define INIT2660_REGISTER(REG) TMC2660_n::REG##_t REG##_register = TMC2660_n::REG##_t #define INIT2208_REGISTER(REG) TMC2208_n::REG##_t REG##_register = TMC2208_n::REG##_t //#define INIT2224_REGISTER(REG) TMC2224_n::REG##_t REG##_register = TMC2224_n::REG##_t #define SET_ALIAS(TYPE, DRIVER, NEW, ARG, OLD) TYPE (DRIVER::*NEW)(ARG) = &DRIVER::OLD #define TMCSTEPPER_VERSION 0x000701 // v0.7.1 #if SW_CAPABLE_PLATFORM #include <BufferedSerial.h> #include <Stream.h> #endif class TMCStepper { public: uint16_t cs2rms(uint8_t CS); void rms_current(uint16_t mA); void rms_current(uint16_t mA, float mult); uint16_t rms_current(); void hold_multiplier(float val) { holdMultiplier = val; } float hold_multiplier() { return holdMultiplier; } uint8_t test_connection(); // Helper functions void microsteps(uint16_t ms); uint16_t microsteps(); void blank_time(uint8_t value); uint8_t blank_time(); void hysteresis_end(int8_t value); int8_t hysteresis_end(); void hysteresis_start(uint8_t value); uint8_t hysteresis_start(); // R+WC: GSTAT void GSTAT( uint8_t input); uint8_t GSTAT(); bool reset(); bool drv_err(); bool uv_cp(); // W: IHOLD_IRUN void IHOLD_IRUN( uint32_t input); uint32_t IHOLD_IRUN(); void ihold( uint8_t B); void irun( uint8_t B); void iholddelay( uint8_t B); uint8_t ihold(); uint8_t irun(); uint8_t iholddelay(); // W: TPOWERDOWN uint8_t TPOWERDOWN(); void TPOWERDOWN( uint8_t input); // R: TSTEP uint32_t TSTEP(); // W: TPWMTHRS uint32_t TPWMTHRS(); void TPWMTHRS( uint32_t input); // R: MSCNT uint16_t MSCNT(); // R: MSCURACT uint32_t MSCURACT(); int16_t cur_a(); int16_t cur_b(); protected: TMCStepper(float RS) : Rsense(RS) {}; INIT_REGISTER(IHOLD_IRUN){{.sr=0}}; // 32b INIT_REGISTER(TPOWERDOWN){.sr=0}; // 8b INIT_REGISTER(TPWMTHRS){.sr=0}; // 32b static constexpr uint8_t TMC_READ = 0x00, TMC_WRITE = 0x80; struct TSTEP_t { constexpr static uint8_t address = 0x12; }; struct MSCNT_t { constexpr static uint8_t address = 0x6A; }; virtual void write(uint8_t, uint32_t) = 0; virtual uint32_t read(uint8_t) = 0; virtual void vsense(bool) = 0; virtual bool vsense(void) = 0; virtual uint32_t DRV_STATUS() = 0; virtual void hend(uint8_t) = 0; virtual uint8_t hend() = 0; virtual void hstrt(uint8_t) = 0; virtual uint8_t hstrt() = 0; virtual void mres(uint8_t) = 0; virtual uint8_t mres() = 0; virtual void tbl(uint8_t) = 0; virtual uint8_t tbl() = 0; const float Rsense; float holdMultiplier = 0.5; }; class TMC2208Stepper : public TMCStepper { public: TMC2208Stepper(Stream * SerialPort, float RS, uint8_t addr, uint16_t mul_pin1, uint16_t mul_pin2); TMC2208Stepper(Stream * SerialPort, float RS) : TMC2208Stepper(SerialPort, RS, TMC2208_SLAVE_ADDR) {} #if SW_CAPABLE_PLATFORM TMC2208Stepper(PinName SW_RX_pin, PinName SW_TX_pin, float RS) : TMC2208Stepper(SW_RX_pin, SW_TX_pin, RS, TMC2208_SLAVE_ADDR) {} __attribute__((deprecated("Boolean argument has been deprecated and does nothing"))) TMC2208Stepper(PinName SW_RX_pin, PinName SW_TX_pin, float RS, bool) : TMC2208Stepper(SW_RX_pin, SW_TX_pin, RS, TMC2208_SLAVE_ADDR) {}; #else TMC2208Stepper(PinName, PinName, float) = delete; // Your platform does not currently support Software Serial #endif void defaults(); void push(); void begin(); #if SW_CAPABLE_PLATFORM void beginSerial(uint32_t baudrate) __attribute__((weak)); #else void beginSerial(uint32_t) = delete; // Your platform does not currently support Software Serial #endif bool isEnabled(); // RW: GCONF void GCONF(uint32_t input); void I_scale_analog(bool B); void internal_Rsense(bool B); void en_spreadCycle(bool B); void shaft(bool B); void index_otpw(bool B); void index_step(bool B); void pdn_disable(bool B); void mstep_reg_select(bool B); void multistep_filt(bool B); uint32_t GCONF(); bool I_scale_analog(); bool internal_Rsense(); bool en_spreadCycle(); bool shaft(); bool index_otpw(); bool index_step(); bool pdn_disable(); bool mstep_reg_select(); bool multistep_filt(); // R: IFCNT uint8_t IFCNT(); // W: SLAVECONF void SLAVECONF(uint16_t input); uint16_t SLAVECONF(); void senddelay(uint8_t B); uint8_t senddelay(); // W: OTP_PROG void OTP_PROG(uint16_t input); // R: OTP_READ uint32_t OTP_READ(); // R: IOIN uint32_t IOIN(); bool enn(); bool ms1(); bool ms2(); bool diag(); bool pdn_uart(); bool step(); bool sel_a(); bool dir(); uint8_t version(); // RW: FACTORY_CONF void FACTORY_CONF(uint16_t input); uint16_t FACTORY_CONF(); void fclktrim(uint8_t B); void ottrim(uint8_t B); uint8_t fclktrim(); uint8_t ottrim(); // W: VACTUAL void VACTUAL(uint32_t input); uint32_t VACTUAL(); // RW: CHOPCONF void CHOPCONF(uint32_t input); void toff(uint8_t B); void hstrt(uint8_t B); void hend(uint8_t B); void tbl(uint8_t B); void vsense(bool B); void mres(uint8_t B); void intpol(bool B); void dedge(bool B); void diss2g(bool B); void diss2vs(bool B); uint32_t CHOPCONF(); uint8_t toff(); uint8_t hstrt(); uint8_t hend(); uint8_t tbl(); bool vsense(); uint8_t mres(); bool intpol(); bool dedge(); bool diss2g(); bool diss2vs(); // R: DRV_STATUS uint32_t DRV_STATUS(); bool otpw(); bool ot(); bool s2ga(); bool s2gb(); bool s2vsa(); bool s2vsb(); bool ola(); bool olb(); bool t120(); bool t143(); bool t150(); bool t157(); uint16_t cs_actual(); bool stealth(); bool stst(); // RW: PWMCONF void PWMCONF(uint32_t input); void pwm_ofs(uint8_t B); void pwm_grad(uint8_t B); void pwm_freq(uint8_t B); void pwm_autoscale(bool B); void pwm_autograd(bool B); void freewheel(uint8_t B); void pwm_reg(uint8_t B); void pwm_lim(uint8_t B); uint32_t PWMCONF(); uint8_t pwm_ofs(); uint8_t pwm_grad(); uint8_t pwm_freq(); bool pwm_autoscale(); bool pwm_autograd(); uint8_t freewheel(); uint8_t pwm_reg(); uint8_t pwm_lim(); // R: PWM_SCALE uint32_t PWM_SCALE(); uint8_t pwm_scale_sum(); int16_t pwm_scale_auto(); // R: PWM_AUTO (0x72) uint32_t PWM_AUTO(); uint8_t pwm_ofs_auto(); uint8_t pwm_grad_auto(); uint16_t bytesWritten = 0; float Rsense = 0.11; bool CRCerror = false; protected: INIT2208_REGISTER(GCONF) {{.sr=0}}; INIT_REGISTER(SLAVECONF) {{.sr=0}}; INIT_REGISTER(FACTORY_CONF) {{.sr=0}}; INIT2208_REGISTER(VACTUAL) {.sr=0}; INIT2208_REGISTER(CHOPCONF) {{.sr=0}}; INIT2208_REGISTER(PWMCONF) {{.sr=0}}; struct IFCNT_t { constexpr static uint8_t address = 0x02; }; struct OTP_PROG_t { constexpr static uint8_t address = 0x04; }; struct OTP_READ_t { constexpr static uint8_t address = 0x05; }; TMC2208Stepper(Stream * SerialPort, float RS, uint8_t addr); #if SW_CAPABLE_PLATFORM TMC2208Stepper(PinName SW_RX_pin, PinName SW_TX_pin, float RS, uint8_t addr); #endif Stream * HWSerial = nullptr; #if SW_CAPABLE_PLATFORM BufferedSerial * SWSerial = nullptr; const uint16_t RXTX_pin = 0; // Half duplex #endif // SSwitch *sswitch = nullptr; int available(); void preWriteCommunication(); void preReadCommunication(); int16_t serial_read(); uint8_t serial_write(const uint8_t data); void postWriteCommunication(); void postReadCommunication(); void write(uint8_t, uint32_t); uint32_t read(uint8_t); const uint8_t slave_address; uint8_t calcCRC(uint8_t datagram[], uint8_t len); static constexpr uint8_t TMC2208_SYNC = 0x05, TMC2208_SLAVE_ADDR = 0x00; static constexpr uint8_t replyDelay = 2; //ms static constexpr uint8_t abort_window = 5; static constexpr uint8_t max_retries = 2; uint64_t _sendDatagram(uint8_t [], const uint8_t, uint16_t); }; class TMC2209Stepper : public TMC2208Stepper { public: TMC2209Stepper(Stream * SerialPort, float RS, uint8_t addr) : TMC2208Stepper(SerialPort, RS, addr) {} #if SW_CAPABLE_PLATFORM TMC2209Stepper(PinName SW_RX_pin, PinName SW_TX_pin, float RS, uint8_t addr) : TMC2208Stepper(SW_RX_pin, SW_TX_pin, RS, addr) {} #else TMC2209Stepper(PinName, PinName, float, uint8_t) = delete; // Your platform does not currently support Software Serial #endif void push(); // R: IOIN uint32_t IOIN(); bool enn(); bool ms1(); bool ms2(); bool diag(); bool pdn_uart(); bool step(); bool spread_en(); bool dir(); uint8_t version(); // W: TCOOLTHRS uint32_t TCOOLTHRS(); void TCOOLTHRS(uint32_t input); // W: SGTHRS void SGTHRS(uint8_t B); uint8_t SGTHRS(); // R: SG_RESULT uint16_t SG_RESULT(); // W: COOLCONF void COOLCONF(uint16_t B); uint16_t COOLCONF(); void semin(uint8_t B); void seup(uint8_t B); void semax(uint8_t B); void sedn(uint8_t B); void seimin(bool B); uint8_t semin(); uint8_t seup(); uint8_t semax(); uint8_t sedn(); bool seimin(); protected: INIT_REGISTER(TCOOLTHRS){.sr=0}; TMC2209_n::SGTHRS_t SGTHRS_register{.sr=0}; TMC2209_n::COOLCONF_t COOLCONF_register{{.sr=0}}; };