You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
12 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #if 1
  2. #include "ztmc4361A.hpp"
  3. #ifdef HAL_SPI_MODULE_ENABLED
  4. #include <stdarg.h>
  5. #include "../basic/basic.hpp"
  6. #include "./TMC4361A/TMC4361A.h"
  7. using namespace iflytop;
  8. #define PRV_FIELD_WRITE(address, mask, shift, value) (writeInt(address, FIELD_SET(readInt(address), mask, shift, value)))
  9. #define PRV_FIELD_READ(address, mask, shift) FIELD_GET(readInt(address), mask, shift)
  10. #define SET_PIN(pin, val) \
  11. if (pin) { \
  12. pin->setState(val); \
  13. }
  14. #if 1
  15. void TMC4361A::readWriteArray(uint8_t *data, size_t length) {
  16. m_csgpio->setState(false);
  17. chip_delay_us(10);
  18. HAL_SPI_TransmitReceive(m_spi, data, data, length, 1000);
  19. m_csgpio->setState(true);
  20. }
  21. void TMC4361A::writeInt(uint8_t address, int32_t value) { writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); }
  22. int32_t TMC4361A::readInt(uint8_t address) {
  23. CriticalContext cc;
  24. int value;
  25. uint8_t data[5];
  26. address = TMC_ADDRESS(address);
  27. if (!TMC_IS_READABLE(m_registerAccessTable[address])) return m_defaultRegisterResetState[address];
  28. data[0] = address;
  29. readWriteArray(&data[0], 5);
  30. data[0] = address;
  31. readWriteArray(&data[0], 5);
  32. m_status = data[0];
  33. value = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
  34. return value;
  35. }
  36. void TMC4361A::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
  37. CriticalContext cc;
  38. int value;
  39. uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC4361A_WRITE_BIT)), x1, x2, x3, x4};
  40. readWriteArray(&data[0], 5);
  41. m_status = data[0];
  42. value = ((uint32_t)x1 << 24) | ((uint32_t)x2 << 16) | (x3 << 8) | x4;
  43. // Write to the shadow register and mark the register dirty
  44. address = TMC_ADDRESS(address);
  45. shadowRegister[address] = value;
  46. }
  47. void TMC4361A::readWriteCover(uint8_t *data, size_t length) {
  48. CriticalContext cc;
  49. // Buffering old values to not interrupt manual covering
  50. int32_t old_high = shadowRegister[TMC4361A_COVER_HIGH_WR];
  51. int32_t old_low = shadowRegister[TMC4361A_COVER_LOW_WR];
  52. // Check if datagram length is valid
  53. if (length == 0 || length > 8) return;
  54. uint8_t bytes[8] = {0};
  55. uint32_t tmp;
  56. size_t i;
  57. // Copy data into buffer of maximum cover datagram length (8 bytes)
  58. for (i = 0; i < length; i++) bytes[i] = data[length - i - 1];
  59. // Send the datagram
  60. if (length > 4) writeDatagram(TMC4361A_COVER_HIGH_WR, bytes[7], bytes[6], bytes[5], bytes[4]);
  61. writeDatagram(TMC4361A_COVER_LOW_WR, bytes[3], bytes[2], bytes[1], bytes[0]);
  62. chip_delay_us(10 * 1000);
  63. // Read the reply
  64. if (length > 4) {
  65. tmp = readInt(TMC4361A_COVER_DRV_HIGH_RD);
  66. bytes[4] = BYTE(tmp, 0);
  67. bytes[5] = BYTE(tmp, 1);
  68. bytes[6] = BYTE(tmp, 2);
  69. bytes[7] = BYTE(tmp, 3);
  70. }
  71. tmp = readInt(TMC4361A_COVER_DRV_LOW_RD);
  72. bytes[0] = BYTE(tmp, 0);
  73. bytes[1] = BYTE(tmp, 1);
  74. bytes[2] = BYTE(tmp, 2);
  75. bytes[3] = BYTE(tmp, 3);
  76. // Write the reply to the data array
  77. for (i = 0; i < length; i++) {
  78. data[length - i - 1] = bytes[i];
  79. }
  80. // Rewriting old values to prevent interrupting manual covering. Imitating unchanged values and state.
  81. writeInt(TMC4361A_COVER_HIGH_WR, old_high);
  82. shadowRegister[TMC4361A_COVER_LOW_WR] = old_low;
  83. }
  84. TMC4361A::TMC4361A(/* args */) {
  85. m_driver_ic_type = IC_TMC2130;
  86. m_lastCallPeriodicJobTick = 0;
  87. // m_reachtarget = false;
  88. }
  89. /**
  90. * @brief
  91. * TMC-API中的tmc4361A_reset/restore时候TMC-API中的方法会初始化整个芯片的寄存器
  92. *
  93. *
  94. * @param state
  95. */
  96. void TMC4361A::tmc4361AConfigCallback(ConfigState state) {}
  97. void TMC4361A::writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value) { //
  98. PRV_FIELD_WRITE(address, mask, shift, value);
  99. }
  100. void TMC4361A::setAcceleration(float accelerationpps2) {
  101. /**
  102. * @brief
  103. * TMC4361A_AMAX:使
  104. *
  105. * Frequency mode: [pulses per sec2]
  106. * 22 digits and 2 decimal places: 250 mpps^2 AMAX 4 Mpps^2
  107. * Direct mode: [v per clk cycle]
  108. * a[v per clk_cycle]= AMAX / 2^37
  109. * AMAX [pps2] = AMAX / 237 fCLK^2
  110. */
  111. int32_t acc = (int32_t)accelerationpps2;
  112. writeInt(TMC4361A_AMAX, acc << 2);
  113. }
  114. void TMC4361A::setDeceleration(float accelerationpps2) {
  115. /**
  116. * @brief
  117. * TMC4361A_DMAX:使
  118. *
  119. * Frequency mode: [pulses per sec2]
  120. * 22 digits and 2 decimal places: 250 mpps^2 AMAX 4 Mpps^2
  121. * Direct mode: [v per clk cycle]
  122. * a[v per clk_cycle]= AMAX / 2^37
  123. * AMAX [pps2] = AMAX / 237 fCLK^2
  124. */
  125. int32_t acc = (int32_t)accelerationpps2;
  126. writeInt(TMC4361A_DMAX, acc << 2);
  127. }
  128. void TMC4361A::initialize(cfg_t *cfg) {
  129. m_spi = cfg->spi;
  130. m_csgpio = cfg->csgpio;
  131. m_resetPin = cfg->resetPin;
  132. m_fREEZEPin = cfg->fREEZEPin;
  133. m_ennPin = cfg->ennPin;
  134. m_driverIC_resetPin = cfg->driverIC_resetPin;
  135. m_driverIC_ennPin = cfg->driverIC_ennPin;
  136. m_driver_ic_type = IC_TMC2160;
  137. m_registerAccessTable = &tmc4361A_defaultRegisterAccess[0];
  138. m_defaultRegisterResetState = &tmc4361A_defaultRegisterResetState[0];
  139. memset(shadowRegister, 0, sizeof(shadowRegister));
  140. SET_PIN(m_resetPin, true);
  141. SET_PIN(m_fREEZEPin, true);
  142. SET_PIN(m_ennPin, true);
  143. reset();
  144. driverIC_reset();
  145. setAcceleration(500000);
  146. setDeceleration(500000);
  147. enableIC(true);
  148. chip_delay_us(300 * 1000);
  149. chip_delay_us(300 * 1000);
  150. driverIC_setIHOLD_IRUN(1, 3, 0); // 注意要先设置IHOLD再设置IRUN,否则电机跑不起来
  151. }
  152. uint8_t TMC4361A::reset() {
  153. // Pulse the low-active hardware reset pin
  154. stop();
  155. SET_PIN(m_resetPin, false);
  156. chip_delay_us(1000);
  157. SET_PIN(m_resetPin, true);
  158. /**
  159. * @brief
  160. *
  161. */
  162. for (uint32_t add = 0; add < TMC4361A_REGISTER_COUNT; add++) {
  163. if (!TMC_IS_RESETTABLE(m_registerAccessTable[add])) {
  164. continue;
  165. }
  166. writeInt(add, m_defaultRegisterResetState[add]);
  167. }
  168. uint8_t driver, dataLength;
  169. uint32_t value;
  170. // Setup SPI
  171. switch (m_driver_ic_type) {
  172. case IC_TMC2130:
  173. case IC_TMC2160:
  174. driver = 0x0C;
  175. dataLength = 0;
  176. break;
  177. case IC_TMC2660:
  178. driver = 0x0B;
  179. dataLength = 0;
  180. break;
  181. default:
  182. driver = 0x0F;
  183. dataLength = 40;
  184. break;
  185. }
  186. value = 0x44400040 | (dataLength << 13) | (driver << 0);
  187. writeInt(TMC4361A_SPIOUT_CONF, value);
  188. writeInt(TMC4361A_CURRENT_CONF, 0x00000003);
  189. writeInt(TMC4361A_SCALE_VALUES, 0x00000000);
  190. return 1;
  191. }
  192. uint8_t TMC4361A::restore() { return 1; }
  193. int32_t TMC4361A::getXACTUAL() { return readInt(TMC4361A_XACTUAL); }
  194. void TMC4361A::setXACTUAL(int32_t value) { writeInt(TMC4361A_XACTUAL, value); }
  195. int32_t TMC4361A::getVACTUAL() { return readInt(TMC4361A_VACTUAL); }
  196. int32_t TMC4361A::getXTARGET() { return readInt(TMC4361A_X_TARGET); }
  197. int32_t TMC4361A::getENC_POS() { return readInt(TMC4361A_ENC_POS); }
  198. void TMC4361A::setENC_POS(int32_t value) { writeInt(TMC4361A_ENC_POS, value); }
  199. int32_t TMC4361A::getENC_POS_DEV() { return readInt(TMC4361A_ENC_POS_DEV_RD); }
  200. void TMC4361A::enableIC(bool enable) {
  201. SET_PIN(m_ennPin, !enable);
  202. SET_PIN(m_driverIC_ennPin, !enable);
  203. }
  204. int32_t tmc4361A_discardVelocityDecimals(int32_t value) {
  205. if (abs(value) > 8000000) {
  206. value = (value < 0) ? -8000000 : 8000000;
  207. }
  208. return value << 8;
  209. }
  210. void TMC4361A::rotate(int32_t velocity) {
  211. m_motor_mode = kvelmode;
  212. PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 0);
  213. writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocity));
  214. }
  215. void TMC4361A::stop() { rotate(0); }
  216. void TMC4361A::moveTo(int32_t position, uint32_t velocityMax) {
  217. m_motor_mode = kposmode;
  218. PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 1);
  219. writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocityMax));
  220. writeInt(TMC4361A_X_TARGET, position);
  221. }
  222. void TMC4361A::moveBy(int32_t relativePosition, uint32_t velocityMax) {
  223. relativePosition += readInt(TMC4361A_XACTUAL);
  224. moveTo(relativePosition, velocityMax);
  225. }
  226. int32_t TMC4361A::readICVersion() {
  227. int32_t value = readInt(TMC4361A_VERSION_NO_RD);
  228. return (value & TMC4361A_VERSION_NO_MASK) >> TMC4361A_VERSION_NO_SHIFT;
  229. }
  230. int32_t TMC4361A::readSubICVersion() { return driverIC_readICVersion(); }
  231. /*******************************************************************************
  232. * 2160 function end *
  233. *******************************************************************************/
  234. uint32_t TMC4361A::readEVENTS() {
  235. uint32_t value = readInt(TMC4361A_EVENTS);
  236. return value;
  237. }
  238. uint32_t TMC4361A::haspassedms(uint32_t now, uint32_t last) {
  239. if (now >= last) {
  240. return now - last;
  241. } else {
  242. return 0xFFFFFFFF - last + now;
  243. }
  244. }
  245. bool TMC4361A::isReachTarget() {
  246. uint32_t value = readInt(TMC4361A_STATUS);
  247. if (m_motor_mode == kposmode) {
  248. return (value & TMC4361A_TARGET_REACHED_F_MASK) > 0;
  249. } else {
  250. return (value & TMC4361A_VEL_REACHED_F_MASK) && (readInt(TMC4361A_VMAX) == 0);
  251. }
  252. }
  253. /*******************************************************************************
  254. * DRIVER_IC *
  255. *******************************************************************************/
  256. #define DRIVER_ID_FIELD_READ(address, mask, shift) FIELD_GET(driverIC_readInt(address), mask, shift)
  257. #define DRIVER_ID_FIELD_WRITE(address, mask, shift, value) (driverIC_writeInt(address, FIELD_SET(driverIC_readInt(address), mask, shift, value)))
  258. void TMC4361A::driverIC_reset() {
  259. SET_PIN(m_driverIC_resetPin, false);
  260. chip_delay_us(1000);
  261. SET_PIN(m_driverIC_resetPin, true);
  262. // Reset the dirty bits
  263. int index = 0;
  264. while (true) {
  265. while ((index < TMC2160_REGISTER_COUNT) && !TMC_IS_RESTORABLE(tmc2160_defaultRegisterAccess[index])) {
  266. index++;
  267. }
  268. if (index >= TMC2160_REGISTER_COUNT) {
  269. break;
  270. }
  271. // printf("Resetting register %d\n", index);
  272. driverIC_writeInt(index, tmc2160_defaultRegisterResetState[index]);
  273. index++;
  274. }
  275. driverIC_writeInt(TMC2160_PWMCONF, 0xC40C001E);
  276. driverIC_writeInt(TMC2160_DRV_CONF, 0x00080400);
  277. }
  278. void TMC4361A::driverIC_enableIC(bool enable) { SET_PIN(m_driverIC_ennPin, !enable); }
  279. void TMC4361A::driverIC_writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
  280. uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC2160_WRITE_BIT)), x1, x2, x3, x4};
  281. readWriteCover(&data[0], 5);
  282. }
  283. void TMC4361A::driverIC_writeInt(uint8_t address, int32_t value) {
  284. driverIC_writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0));
  285. }
  286. int32_t TMC4361A::driverIC_readInt(uint8_t address) {
  287. address = TMC_ADDRESS(address);
  288. // register not readable -> shadow register copy
  289. if (!TMC_IS_READABLE(tmc2160_defaultRegisterAccess[address])) return 0;
  290. uint8_t data[5];
  291. data[0] = address;
  292. readWriteCover(&data[0], 5);
  293. data[0] = address;
  294. readWriteCover(&data[0], 5);
  295. return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
  296. }
  297. void TMC4361A::driverIC_setMotorShaft(bool reverse) {
  298. //
  299. int32_t val = reverse ? 1 : 0;
  300. DRIVER_ID_FIELD_WRITE(TMC2160_GCONF, TMC2160_SHAFT_MASK, TMC2160_SHAFT_SHIFT, val);
  301. }
  302. uint32_t TMC4361A::driverIC_readICVersion() {
  303. int32_t value = driverIC_readInt(TMC2160_IOIN___OUTPUT);
  304. return (value & TMC2160_VERSION_MASK) >> TMC2160_VERSION_SHIFT;
  305. }
  306. void TMC4361A::driverIC_setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) {
  307. driverIC_writeInt(TMC2160_IHOLD_IRUN, (iholddelay << TMC2160_IHOLDDELAY_SHIFT) | (irun << TMC2160_IRUN_SHIFT) | (ihold << TMC2160_IHOLD_SHIFT));
  308. }
  309. #endif
  310. #endif
  311. #endif