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.

425 lines
14 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
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. #include "sdk/os/zos.hpp"
  8. using namespace iflytop;
  9. #define PRV_FIELD_WRITE(address, mask, shift, value) (writeInt(address, FIELD_SET(readInt(address), mask, shift, value)))
  10. #define PRV_FIELD_READ(address, mask, shift) FIELD_GET(readInt(address), mask, shift)
  11. #define SET_PIN(pin, val) \
  12. if (pin) { \
  13. pin->setState(val); \
  14. }
  15. #if 1
  16. void TMC4361A::readWriteArray(uint8_t *data, size_t length) {
  17. m_csgpio->setState(false);
  18. // zchip_clock_early_delayus(10);
  19. zchip_clock_early_delayus(10);
  20. HAL_SPI_TransmitReceive(m_spi, data, data, length, 1000);
  21. m_csgpio->setState(true);
  22. }
  23. void TMC4361A::writeInt(uint8_t address, int32_t value) { writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); }
  24. int32_t TMC4361A::readInt(uint8_t address) {
  25. CriticalContext cc;
  26. int value;
  27. uint8_t data[5];
  28. address = TMC_ADDRESS(address);
  29. if (!TMC_IS_READABLE(m_registerAccessTable[address])) return m_defaultRegisterResetState[address];
  30. data[0] = address;
  31. readWriteArray(&data[0], 5);
  32. data[0] = address;
  33. readWriteArray(&data[0], 5);
  34. m_status = data[0];
  35. value = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
  36. return value;
  37. }
  38. void TMC4361A::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
  39. CriticalContext cc;
  40. int value;
  41. uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC4361A_WRITE_BIT)), x1, x2, x3, x4};
  42. readWriteArray(&data[0], 5);
  43. m_status = data[0];
  44. value = ((uint32_t)x1 << 24) | ((uint32_t)x2 << 16) | (x3 << 8) | x4;
  45. // Write to the shadow register and mark the register dirty
  46. address = TMC_ADDRESS(address);
  47. shadowRegister[address] = value;
  48. }
  49. void TMC4361A::readWriteCover(uint8_t *data, size_t length) {
  50. CriticalContext cc;
  51. // Buffering old values to not interrupt manual covering
  52. int32_t old_high = shadowRegister[TMC4361A_COVER_HIGH_WR];
  53. int32_t old_low = shadowRegister[TMC4361A_COVER_LOW_WR];
  54. // Check if datagram length is valid
  55. if (length == 0 || length > 8) return;
  56. uint8_t bytes[8] = {0};
  57. uint32_t tmp;
  58. size_t i;
  59. // Copy data into buffer of maximum cover datagram length (8 bytes)
  60. for (i = 0; i < length; i++) bytes[i] = data[length - i - 1];
  61. // Send the datagram
  62. if (length > 4) writeDatagram(TMC4361A_COVER_HIGH_WR, bytes[7], bytes[6], bytes[5], bytes[4]);
  63. writeDatagram(TMC4361A_COVER_LOW_WR, bytes[3], bytes[2], bytes[1], bytes[0]);
  64. zos_delay(10);
  65. // Read the reply
  66. if (length > 4) {
  67. tmp = readInt(TMC4361A_COVER_DRV_HIGH_RD);
  68. bytes[4] = BYTE(tmp, 0);
  69. bytes[5] = BYTE(tmp, 1);
  70. bytes[6] = BYTE(tmp, 2);
  71. bytes[7] = BYTE(tmp, 3);
  72. }
  73. tmp = readInt(TMC4361A_COVER_DRV_LOW_RD);
  74. bytes[0] = BYTE(tmp, 0);
  75. bytes[1] = BYTE(tmp, 1);
  76. bytes[2] = BYTE(tmp, 2);
  77. bytes[3] = BYTE(tmp, 3);
  78. // Write the reply to the data array
  79. for (i = 0; i < length; i++) {
  80. data[length - i - 1] = bytes[i];
  81. }
  82. // Rewriting old values to prevent interrupting manual covering. Imitating unchanged values and state.
  83. writeInt(TMC4361A_COVER_HIGH_WR, old_high);
  84. shadowRegister[TMC4361A_COVER_LOW_WR] = old_low;
  85. }
  86. TMC4361A::TMC4361A(/* args */) {
  87. m_driver_ic_type = IC_TMC2130;
  88. m_lastCallPeriodicJobTick = 0;
  89. // m_reachtarget = false;
  90. }
  91. /**
  92. * @brief
  93. * TMC-APIеtmc4361A_reset/restoreʱTMC-APIеķʼоƬļĴ
  94. * Ĵʼ֮󣬻??
  95. * ǿУоƬIJּĴгʼ??
  96. * @param state
  97. */
  98. void TMC4361A::tmc4361AConfigCallback(ConfigState state) {}
  99. void TMC4361A::writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value) { //
  100. PRV_FIELD_WRITE(address, mask, shift, value);
  101. }
  102. void TMC4361A::setAcceleration(float accelerationpps2) {
  103. /**
  104. * @brief
  105. * TMC4361A_AMAX:ģʽʹõƵģʽ
  106. *
  107. * Frequency mode: [pulses per sec2]
  108. * 22 digits and 2 decimal places: 250 mpps^2 ?? AMAX ?? 4 Mpps^2
  109. * Direct mode: [?v per clk cycle]
  110. * a[?v per clk_cycle]= AMAX / 2^37
  111. * AMAX [pps2] = AMAX / 237 ?? fCLK^2
  112. */
  113. accelerationpps2 = to_motor_acc(accelerationpps2);
  114. int32_t acc = (int32_t)accelerationpps2;
  115. writeInt(TMC4361A_AMAX, acc << 2);
  116. }
  117. void TMC4361A::setDeceleration(float accelerationpps2) {
  118. /**
  119. * @brief
  120. * TMC4361A_DMAX:ģʽʹõƵģʽ
  121. *
  122. * Frequency mode: [pulses per sec2]
  123. * 22 digits and 2 decimal places: 250 mpps^2 ?? AMAX ?? 4 Mpps^2
  124. * Direct mode: [?v per clk cycle]
  125. * a[?v per clk_cycle]= AMAX / 2^37
  126. * AMAX [pps2] = AMAX / 237 ?? fCLK^2
  127. */
  128. accelerationpps2 = to_motor_acc(accelerationpps2);
  129. int32_t acc = (int32_t)accelerationpps2;
  130. writeInt(TMC4361A_DMAX, acc << 2);
  131. }
  132. #define INIT_GPIO(m_pin, pin, ...) \
  133. if (pin != PinNull) { \
  134. m_pin = new ZGPIO(); \
  135. ZASSERT(m_pin != nullptr); \
  136. m_pin->initAsOutput(pin, __VA_ARGS__); \
  137. } else { \
  138. m_pin = nullptr; \
  139. }
  140. void TMC4361A::initialize(cfg_t *cfg) {
  141. m_spi = cfg->spi;
  142. INIT_GPIO(m_csgpio, cfg->csgpio, ZGPIO::kMode_nopull, false, true);
  143. INIT_GPIO(m_resetPin, cfg->resetPin, ZGPIO::kMode_nopull, false, true);
  144. INIT_GPIO(m_fREEZEPin, cfg->fREEZEPin, ZGPIO::kMode_nopull, false, true);
  145. INIT_GPIO(m_ennPin, cfg->ennPin, ZGPIO::kMode_nopull, false, true);
  146. INIT_GPIO(m_driverIC_resetPin, cfg->driverIC_resetPin, ZGPIO::kMode_nopull, false, true);
  147. INIT_GPIO(m_driverIC_ennPin, cfg->driverIC_ennPin, ZGPIO::kMode_nopull, false, true);
  148. m_driver_ic_type = IC_TMC2160;
  149. m_registerAccessTable = &tmc4361A_defaultRegisterAccess[0];
  150. m_defaultRegisterResetState = &tmc4361A_defaultRegisterResetState[0];
  151. memset(shadowRegister, 0, sizeof(shadowRegister));
  152. SET_PIN(m_resetPin, true);
  153. SET_PIN(m_fREEZEPin, true);
  154. SET_PIN(m_ennPin, true);
  155. reset();
  156. driverIC_reset();
  157. setAcceleration(500000);
  158. setDeceleration(500000);
  159. enableIC(false);
  160. zchip_clock_early_delayus(300 * 1000);
  161. zchip_clock_early_delayus(300 * 1000);
  162. driverIC_setIHOLD_IRUN(1, 3, 0);
  163. }
  164. void TMC4361A::setScale(int32_t scale) { m_scale = scale; }
  165. void TMC4361A::setScaleDenominator(int32_t scale) { m_scale_deceleration = scale; }
  166. uint8_t TMC4361A::reset() {
  167. // Pulse the low-active hardware reset pin
  168. stop();
  169. SET_PIN(m_resetPin, false);
  170. zchip_clock_early_delayus(1000);
  171. SET_PIN(m_resetPin, true);
  172. /**
  173. * @brief оƬĴ??
  174. *
  175. */
  176. for (uint32_t add = 0; add < TMC4361A_REGISTER_COUNT; add++) {
  177. if (!TMC_IS_RESETTABLE(m_registerAccessTable[add])) {
  178. continue;
  179. }
  180. writeInt(add, m_defaultRegisterResetState[add]);
  181. }
  182. uint8_t driver, dataLength;
  183. uint32_t value;
  184. // Setup SPI
  185. switch (m_driver_ic_type) {
  186. case IC_TMC2130:
  187. case IC_TMC2160:
  188. driver = 0x0C;
  189. dataLength = 0;
  190. break;
  191. case IC_TMC2660:
  192. driver = 0x0B;
  193. dataLength = 0;
  194. break;
  195. default:
  196. driver = 0x0F;
  197. dataLength = 40;
  198. break;
  199. }
  200. value = 0x44400040 | (dataLength << 13) | (driver << 0);
  201. writeInt(TMC4361A_SPIOUT_CONF, value);
  202. writeInt(TMC4361A_CURRENT_CONF, 0x00000003);
  203. writeInt(TMC4361A_SCALE_VALUES, 0x00000000);
  204. return 1;
  205. }
  206. uint8_t TMC4361A::restore() { return 1; }
  207. int32_t TMC4361A::getXACTUAL() { return to_user_pos(readInt(TMC4361A_XACTUAL)); }
  208. void TMC4361A::setXACTUAL(int32_t value) { writeInt(TMC4361A_XACTUAL, to_motor_pos(value)); }
  209. int32_t TMC4361A::getVACTUAL() { return to_user_pos(readInt(TMC4361A_VACTUAL)); }
  210. int32_t TMC4361A::getXTARGET() { return to_user_pos(readInt(TMC4361A_X_TARGET)); }
  211. int32_t TMC4361A::getENC_POS() { return to_user_pos(readInt(TMC4361A_ENC_POS)); }
  212. void TMC4361A::setENC_POS(int32_t value) { writeInt(TMC4361A_ENC_POS, to_motor_pos(value)); }
  213. int32_t TMC4361A::getENC_POS_DEV() { return to_user_pos(readInt(TMC4361A_ENC_POS_DEV_RD)); }
  214. void TMC4361A::enableIC(bool enable) {
  215. SET_PIN(m_ennPin, !enable);
  216. SET_PIN(m_driverIC_ennPin, !enable);
  217. }
  218. int32_t tmc4361A_discardVelocityDecimals(int32_t value) {
  219. if (abs(value) > 8000000) {
  220. value = (value < 0) ? -8000000 : 8000000;
  221. }
  222. return value << 8;
  223. }
  224. void TMC4361A::rotate(int32_t velocity) {
  225. // velocity *= m_scale;
  226. velocity = to_motor_vel(velocity);
  227. m_motor_mode = kvelmode;
  228. PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 0);
  229. writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocity));
  230. }
  231. void TMC4361A::stop() { rotate(0); }
  232. void TMC4361A::moveTo(int32_t position, uint32_t velocityMax) {
  233. // position *= m_scale;
  234. // velocityMax *= m_scale;
  235. position = to_motor_pos(position);
  236. velocityMax = to_motor_vel(velocityMax);
  237. m_motor_mode = kposmode;
  238. PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 1);
  239. writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocityMax));
  240. writeInt(TMC4361A_X_TARGET, position);
  241. }
  242. void TMC4361A::moveBy(int32_t relativePosition, uint32_t velocityMax) {
  243. relativePosition += readInt(TMC4361A_XACTUAL);
  244. moveTo(relativePosition, velocityMax);
  245. }
  246. int32_t TMC4361A::readICVersion() {
  247. int32_t value = readInt(TMC4361A_VERSION_NO_RD);
  248. return (value & TMC4361A_VERSION_NO_MASK) >> TMC4361A_VERSION_NO_SHIFT;
  249. }
  250. int32_t TMC4361A::readSubICVersion() { return driverIC_readICVersion(); }
  251. /*******************************************************************************
  252. * 2160 function end *
  253. *******************************************************************************/
  254. uint32_t TMC4361A::readEVENTS() {
  255. uint32_t value = readInt(TMC4361A_EVENTS);
  256. return value;
  257. }
  258. uint32_t TMC4361A::haspassedms(uint32_t now, uint32_t last) {
  259. if (now >= last) {
  260. return now - last;
  261. } else {
  262. return 0xFFFFFFFF - last + now;
  263. }
  264. }
  265. bool TMC4361A::isReachTarget() {
  266. uint32_t value = readInt(TMC4361A_STATUS);
  267. // printf("TMC4361A_STATUS:%08x\n", value);
  268. if (m_motor_mode == kposmode) {
  269. return (value & TMC4361A_TARGET_REACHED_F_MASK) > 0;
  270. } else {
  271. return (value & TMC4361A_VEL_REACHED_F_MASK) && (readInt(TMC4361A_VMAX) == 0);
  272. }
  273. }
  274. /*******************************************************************************
  275. * DRIVER_IC *
  276. *******************************************************************************/
  277. #define DRIVER_ID_FIELD_READ(address, mask, shift) FIELD_GET(driverIC_readInt(address), mask, shift)
  278. #define DRIVER_ID_FIELD_WRITE(address, mask, shift, value) (driverIC_writeInt(address, FIELD_SET(driverIC_readInt(address), mask, shift, value)))
  279. void TMC4361A::driverIC_reset() {
  280. SET_PIN(m_driverIC_resetPin, false);
  281. zchip_clock_early_delayus(1000);
  282. SET_PIN(m_driverIC_resetPin, true);
  283. // Reset the dirty bits
  284. int index = 0;
  285. while (true) {
  286. while ((index < TMC2160_REGISTER_COUNT) && !TMC_IS_RESTORABLE(tmc2160_defaultRegisterAccess[index])) {
  287. index++;
  288. }
  289. if (index >= TMC2160_REGISTER_COUNT) {
  290. break;
  291. }
  292. // printf("Resetting register %d\n", index);
  293. driverIC_writeInt(index, tmc2160_defaultRegisterResetState[index]);
  294. index++;
  295. }
  296. driverIC_writeInt(TMC2160_PWMCONF, 0xC40C001E);
  297. driverIC_writeInt(TMC2160_DRV_CONF, 0x00080400);
  298. }
  299. void TMC4361A::driverIC_enableIC(bool enable) { SET_PIN(m_driverIC_ennPin, !enable); }
  300. void TMC4361A::driverIC_writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
  301. uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC2160_WRITE_BIT)), x1, x2, x3, x4};
  302. readWriteCover(&data[0], 5);
  303. }
  304. void TMC4361A::driverIC_writeInt(uint8_t address, int32_t value) { driverIC_writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); }
  305. int32_t TMC4361A::driverIC_readInt(uint8_t address) {
  306. address = TMC_ADDRESS(address);
  307. // register not readable -> shadow register copy
  308. if (!TMC_IS_READABLE(tmc2160_defaultRegisterAccess[address])) return 0;
  309. uint8_t data[5];
  310. data[0] = address;
  311. readWriteCover(&data[0], 5);
  312. data[0] = address;
  313. readWriteCover(&data[0], 5);
  314. return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
  315. }
  316. void TMC4361A::driverIC_setMotorShaft(bool reverse) {
  317. //
  318. int32_t val = reverse ? 1 : 0;
  319. DRIVER_ID_FIELD_WRITE(TMC2160_GCONF, TMC2160_SHAFT_MASK, TMC2160_SHAFT_SHIFT, val);
  320. }
  321. uint32_t TMC4361A::driverIC_readICVersion() {
  322. int32_t value = driverIC_readInt(TMC2160_IOIN___OUTPUT);
  323. return (value & TMC2160_VERSION_MASK) >> TMC2160_VERSION_SHIFT;
  324. }
  325. void TMC4361A::driverIC_setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { driverIC_writeInt(TMC2160_IHOLD_IRUN, (iholddelay << TMC2160_IHOLDDELAY_SHIFT) | (irun << TMC2160_IRUN_SHIFT) | (ihold << TMC2160_IHOLD_SHIFT)); }
  326. void TMC4361A::setGLOBAL_SCALER(int32_t value) {
  327. if (value > 255) value = 255;
  328. if (value != 0 && value < 32) value = 32;
  329. driverIC_writeInt(TMC2160_GLOBAL_SCALER, value);
  330. }
  331. // Left Virtual Limit Switch XACTUAL �� VIRT_STOP_LEFT ʱ����
  332. void TMC4361A::setLeftVirtualLimitSwitch(bool enable, int32_t position) {
  333. PRV_FIELD_WRITE(TMC4361A_REFERENCE_CONF, TMC4361A_VIRTUAL_LEFT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_LEFT_LIMIT_EN_SHIFT, enable ? 1 : 0);
  334. writeInt(TMC4361A_VIRT_STOP_LEFT, position);
  335. }
  336. // Right Virtual Limit Switch XACTUAL �� VIRT_STOP_RIGHT ʱ����
  337. void TMC4361A::setRightVirtualLimitSwitch(bool enable, int32_t position) {
  338. PRV_FIELD_WRITE(TMC4361A_REFERENCE_CONF, TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_SHIFT, enable ? 1 : 0);
  339. writeInt(TMC4361A_VIRT_STOP_RIGHT, position);
  340. }
  341. int32_t TMC4361A::to_motor_acc(int32_t acc) { //
  342. int32_t val = acc / 60.0 * 51200;
  343. return val;
  344. }
  345. int32_t TMC4361A::to_motor_vel(int32_t vel) { //
  346. int32_t val = vel / 60.0 * 51200;
  347. return val;
  348. } // rpm
  349. int32_t TMC4361A::to_motor_pos(int32_t pos) { //
  350. int32_t val = pos * 1.0 / m_scale * m_scale_deceleration * 51200.0;
  351. return val;
  352. } //
  353. int32_t TMC4361A::to_user_pos(int32_t pos) { //
  354. int32_t val = pos / 51200.0 * m_scale / m_scale_deceleration;
  355. return val;
  356. } //
  357. int32_t TMC4361A::to_user_vel(int32_t vel) { //
  358. int32_t val = vel * 60.0 / 51200.0;
  359. return val;
  360. }
  361. #endif
  362. #endif
  363. #endif