#pragma once #if 1 #include #include #include #include #include "../basic/tmc_ic_interface.hpp" #include "sdk/os/zos.hpp" #include "tmc_driver_ic.hpp" extern "C" { #include "TMC2160\TMC2160.h" #include "TMC4361A\TMC4361A.h" } #ifdef HAL_SPI_MODULE_ENABLED namespace iflytop { #define TMC4361A_LISTENER_MAX 5 class TMC4361A : public IStepperMotor { public: typedef enum { IC_TMC2130 = 0, // IC_TMC2160, IC_TMC2660, } driver_ic_type_t; #if 0 typedef struct { SPI_HandleTypeDef *spi; // ZGPIO *csgpio; // ZGPIO *resetPin; // ZGPIO *fREEZEPin; // ZGPIO *ennPin; // ZGPIO *driverIC_ennPin; // ZGPIO *driverIC_resetPin; // } cfg_t; #endif class cfg_t { public: SPI_HandleTypeDef *spi = nullptr; // Pin_t csgpio = PinNull; // Pin_t resetPin = PinNull; // Pin_t fREEZEPin = PinNull; // Pin_t ennPin = PinNull; // Pin_t driverIC_ennPin = PinNull; // Pin_t driverIC_resetPin = PinNull; // }; typedef enum { kvelmode, kposmode, } motor_mode_t; private: int32_t shadowRegister[TMC_REGISTER_COUNT]; const uint8_t *m_registerAccessTable = nullptr; const int32_t *m_defaultRegisterResetState = nullptr; driver_ic_type_t m_driver_ic_type; uint32_t m_lastCallPeriodicJobTick; uint8_t m_status; SPI_HandleTypeDef *m_spi = nullptr; ZGPIO *m_csgpio = nullptr; ZGPIO *m_resetPin = nullptr; ZGPIO *m_fREEZEPin = nullptr; ZGPIO *m_ennPin = nullptr; ZGPIO *m_driverIC_ennPin = nullptr; ZGPIO *m_driverIC_resetPin = nullptr; motor_mode_t m_motor_mode = kvelmode; int32_t m_scale = 10000; int32_t m_scale_deceleration = 1; public: TMC4361A(/* args */); /******************************************************************************* * 初始化相关方 * *******************************************************************************/ /** * @brief 静态方法,创建默认的TMC4361A配置参数,使用时只需修改自己需要的参数即可 * * 注意: * 1. 该方法内部使用的是一个静态变量,所以每次调用该方法时,返回的都是同一个对象的地址 * 2. 该方法返回的数值不需要被释放 * @param config */ void initialize(cfg_t *cfg); void enableIC(bool enable); virtual void enable(bool enable) { enableIC(enable); } /******************************************************************************* * IStepperMotor impl * *******************************************************************************/ // virtual void registerListener(MotorEventListener *listener); virtual void rotate(int32_t velocity); virtual void moveTo(int32_t position, uint32_t velocityMax); virtual void moveBy(int32_t relativePosition, uint32_t velocityMax); virtual void stop(); virtual int32_t getXACTUAL(); virtual int32_t getXTARGET(); virtual void setXACTUAL(int32_t value); virtual int32_t getVACTUAL(); virtual int32_t getENC_POS(); virtual void setENC_POS(int32_t value); virtual void setAcceleration(float accelerationpps2); // 设置最大加速度,最大值4000000 virtual void setDeceleration(float accelerationpps2); // 设置最大减速度,最大值4000000 virtual void setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { driverIC_setIHOLD_IRUN(ihold, irun, iholddelay); } virtual void setMotorShaft(bool reverse) { driverIC_setMotorShaft(reverse); } virtual void setScale(int32_t scale); virtual void setScaleDenominator(int32_t scale); // Left Virtual Limit Switch XACTUAL ≤ VIRT_STOP_LEFT 时触发 void setLeftVirtualLimitSwitch(bool enable, int32_t position); // Right Virtual Limit Switch XACTUAL ≥ VIRT_STOP_RIGHT 时触发 void setRightVirtualLimitSwitch(bool enable, int32_t position); /******************************************************************************* * 驱动器初始化方法 * *******************************************************************************/ /** * @brief 初始化方 * * @param channel SPI通道 * @param driver_ic_type 驱动芯片的类 * * TMC4361A:0x2 DriverIC:0x30 */ int32_t readICVersion(); uint8_t reset(); uint8_t restore(); /******************************************************************************* * 驱动器寄存器读写方法 * *******************************************************************************/ void writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4); void writeInt(uint8_t address, int32_t value); int32_t readInt(uint8_t address); void readWriteCover(uint8_t *data, size_t length); void writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value); int32_t getENC_POS_DEV(); // ENC_POS和XACTUAL的偏差 uint32_t readEVENTS(); // 读取事件寄存 /******************************************************* * driverIc function * *******************************************************/ int32_t readSubICVersion(); virtual bool isReachTarget(); virtual bool isStoped() { return isReachTarget(); } public: // only used in tmc4361A.cpp void tmc4361AConfigCallback(ConfigState state); void readWriteArray(uint8_t *data, size_t length); private: uint32_t haspassedms(uint32_t now, uint32_t last); void driverIC_reset(); void driverIC_enableIC(bool enable); void driverIC_setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay); void driverIC_writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4); void driverIC_writeInt(uint8_t address, int32_t value); int32_t driverIC_readInt(uint8_t address); void driverIC_setMotorShaft(bool reverse); uint32_t driverIC_readICVersion(); private: int32_t to_motor_acc(int32_t acc); // rpm/s^2 int32_t to_motor_vel(int32_t vel); // rpm int32_t to_motor_pos(int32_t pos); // int32_t to_user_pos(int32_t pos); // int32_t to_user_vel(int32_t vel); }; } // namespace iflytop #endif #endif