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.

310 lines
11 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
1 year 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. #include "ztmc5130.hpp"
  2. #include "sdk/os/zos.hpp"
  3. #ifdef HAL_SPI_MODULE_ENABLED
  4. using namespace iflytop;
  5. /**
  6. * @brief ̬ĬϵTMC5130ò,ʹʱֻ޸ԼҪIJ
  7. *
  8. * ע:
  9. * 1. ÷ڲʹõǸ̬ÿεø÷ʱصĶͬһĵַ??
  10. * 2. ÷صֵҪͷ??
  11. * @param config
  12. */
  13. #define PRV_FIELD_WRITE(address, mask, shift, value) (writeInt(address, FIELD_SET(readInt(address), mask, shift, value)))
  14. #define PRV_FIELD_READ(address, mask, shift) FIELD_GET(readInt(address), mask, shift)
  15. #define SET_PIN(pin, val) \
  16. if (pin) { \
  17. pin->setState(val); \
  18. }
  19. TMC5130::TMC5130(/* args */) {}
  20. void TMC5130::initialize(cfg_t *cfg) {
  21. m_cfg = *cfg;
  22. // m_channel = channel;
  23. // m_config = config;
  24. // m_port = config->m_port;
  25. m_registerAccessTable = &tmc5130_defaultRegisterAccess[0];
  26. m_defaultRegisterResetState = &tmc5130_defaultRegisterResetState[0];
  27. if (cfg->csgpio != PinNull) {
  28. m_csnpin = new ZGPIO();
  29. m_csnpin->initAsOutput(cfg->csgpio, ZGPIO::kMode_nopull, false, true);
  30. ZASSERT(m_csnpin);
  31. }
  32. if (cfg->ennPin != PinNull) {
  33. m_ennpin = new ZGPIO();
  34. m_ennpin->initAsOutput(cfg->ennPin, ZGPIO::kMode_nopull, false, true);
  35. ZASSERT(m_ennpin);
  36. }
  37. if (cfg->spi_mode_select != PinNull) {
  38. m_spi_mode_select_gpio = new ZGPIO();
  39. m_spi_mode_select_gpio->initAsOutput(cfg->spi_mode_select, ZGPIO::kMode_nopull, false, false);
  40. }
  41. m_hspi = cfg->spi;
  42. enableIC(false);
  43. // tmc5130_init(&m_TMC5130, channel, &m_tmc_api_config, &tmc5130_defaultRegisterResetState[0]);
  44. // tmc5130_setCallback(&m_TMC5130, pri_tmc4361A_callback);
  45. reset();
  46. writeInt(TMC5130_PWMCONF, 0x000500C8);
  47. // writeInt( TMC5130_GCONF, 0x00000004);
  48. writeInt(TMC5130_CHOPCONF, 0x000100c3);
  49. writeInt(TMC5130_IHOLD_IRUN, 0x00051A00);
  50. writeInt(TMC5130_PWMCONF, 0x000401c8);
  51. writeInt(TMC5130_XTARGET, 0);
  52. writeInt(TMC5130_XACTUAL, 0x00000000);
  53. writeInt(TMC5130_VACTUAL, 0x00000000);
  54. writeInt(TMC5130_VSTART, 100);
  55. writeInt(TMC5130_A1, 1000);
  56. writeInt(TMC5130_V1, 0);
  57. writeInt(TMC5130_D1, 1000);
  58. writeInt(TMC5130_VSTOP, 100);
  59. writeInt(TMC5130_TZEROWAIT, 0);
  60. // writeInt(TMC5130_VSTART, 100);
  61. // writeInt(TMC5130_V1, 0);
  62. // writeInt(TMC5130_VSTOP, 100);
  63. // writeInt(TMC5130_TZEROWAIT, 0);
  64. setAcceleration(100);
  65. setDeceleration(100);
  66. setIHOLD_IRUN(2, 10, 1);
  67. enableIC(true);
  68. }
  69. void TMC5130::setMRES(mres_type_t value) {
  70. PRV_FIELD_WRITE(TMC5130_CHOPCONF, TMC5130_MRES_MASK, TMC5130_MRES_SHIFT, value);
  71. m_MRES = value;
  72. if (m_MRES == kmres_256) {
  73. m_onecirclepulse = 51200;
  74. } else if (m_MRES == kmres_128) {
  75. m_onecirclepulse = 25600;
  76. } else if (m_MRES == kmres_64) {
  77. m_onecirclepulse = 12800;
  78. } else if (m_MRES == kmres_32) {
  79. m_onecirclepulse = 6400;
  80. } else if (m_MRES == kmres_16) {
  81. m_onecirclepulse = 3200;
  82. } else if (m_MRES == kmres_8) {
  83. m_onecirclepulse = 1600;
  84. } else if (m_MRES == kmres_4) {
  85. m_onecirclepulse = 800;
  86. } else if (m_MRES == kmres_2) {
  87. m_onecirclepulse = 400;
  88. } else if (m_MRES == kmres_1) {
  89. m_onecirclepulse = 200;
  90. } else {
  91. ZASSERT(false);
  92. }
  93. }
  94. void TMC5130::setNoAccLimit(bool enable) {
  95. if (!enable) {
  96. writeInt(TMC5130_VSTART, 100);
  97. writeInt(TMC5130_VSTOP, 100);
  98. } else {
  99. writeInt(TMC5130_VSTART, 262144 - 1); // 2^18-1
  100. writeInt(TMC5130_VSTOP, 262144 - 1); // 2^18-1
  101. }
  102. }
  103. void TMC5130::enableIC(bool enable) {
  104. // m_port->TMC5130Port_setENNPinState(m_channel, !enable);
  105. SET_PIN(m_ennpin, !enable);
  106. }
  107. uint8_t TMC5130::reset() {
  108. stop();
  109. // m_port->TMC5130Port_setResetNPinState(m_channel, false);
  110. SET_PIN(m_csnpin, false);
  111. // m_port->TMC5130Port_sleepus(1000);
  112. zchip_clock_early_delayus(1000);
  113. // m_port->TMC5130Port_setResetNPinState(m_channel, true);
  114. SET_PIN(m_csnpin, true);
  115. for (uint32_t add = 0; add < TMC5130_REGISTER_COUNT; add++) {
  116. if (!TMC_IS_RESETTABLE(m_registerAccessTable[add])) {
  117. continue;
  118. }
  119. writeInt(add, m_defaultRegisterResetState[add]);
  120. }
  121. return 0;
  122. }
  123. int32_t TMC5130::getXACTUAL() { return to_user_pos(readInt(TMC5130_XACTUAL)); }
  124. void TMC5130::setXACTUAL(int32_t value) { writeInt(TMC5130_XACTUAL, to_motor_pos(value)); }
  125. void TMC5130::setENCVAL(int32_t val) { writeInt(TMC5130_XENC, to_motor_pos(val)); }
  126. int32_t TMC5130::getVACTUAL() { return to_user_pos(readInt(TMC5130_VACTUAL)); }
  127. int32_t TMC5130::getENCVAL() { return to_user_pos(readInt(TMC5130_XENC)); }
  128. void TMC5130::setAcceleration(float accelerationpps2) { writeInt(TMC5130_AMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // �����������ٶ�
  129. void TMC5130::setDeceleration(float accelerationpps2) { writeInt(TMC5130_DMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // �����������ٶ�
  130. void TMC5130::setMotorShaft(bool reverse) { PRV_FIELD_WRITE(TMC5130_GCONF, TMC5130_SHAFT_MASK, TMC5130_SHAFT_SHIFT, reverse); }
  131. void TMC5130::setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { writeInt(TMC5130_IHOLD_IRUN, (iholddelay << TMC5130_IHOLDDELAY_SHIFT) | (irun << TMC5130_IRUN_SHIFT) | (ihold << TMC5130_IHOLD_SHIFT)); }
  132. #define TMC5160_GLOBAL_SCALER 0x0B
  133. #define TMC5160_GLOBAL_SCALER_MASK 0xFF
  134. #define TMC5160_GLOBAL_SCALER_SHIFT 0
  135. void TMC5130::setGlobalScale(uint8_t globalscale) { //
  136. if (globalscale == 0) {
  137. globalscale = 0;
  138. } else if (globalscale <= 31 || globalscale >= 1) {
  139. globalscale = 32;
  140. } else {
  141. globalscale = globalscale;
  142. }
  143. writeInt(TMC5160_GLOBAL_SCALER, (readInt(TMC5160_GLOBAL_SCALER) & ~TMC5160_GLOBAL_SCALER_MASK) | (globalscale << TMC5160_GLOBAL_SCALER_SHIFT));
  144. }
  145. uint8_t TMC5130::getGlobalScale() { //
  146. return PRV_FIELD_READ(TMC5160_GLOBAL_SCALER, TMC5160_GLOBAL_SCALER_MASK, TMC5160_GLOBAL_SCALER_SHIFT);
  147. }
  148. uint32_t TMC5130::readICVersion() {
  149. uint32_t chipID = PRV_FIELD_READ(TMC5130_IOIN, TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT);
  150. return chipID;
  151. }
  152. uint32_t TMC5130::getTMC5130_RAMPSTAT() { return readInt(TMC5130_RAMPSTAT); }
  153. Tmc5130RampStat TMC5130::getTMC5130_RAMPSTAT2() {
  154. uint32_t value = getTMC5130_RAMPSTAT();
  155. return Tmc5130RampStat(value);
  156. }
  157. void TMC5130::stop() { rotate(0); }
  158. void TMC5130::rotate(int32_t velocity) {
  159. // velocity *= m_scale;
  160. velocity = to_motor_vel(velocity);
  161. writeInt(TMC5130_VMAX, abs(velocity));
  162. writeInt(TMC5130_RAMPMODE, (velocity >= 0) ? TMC5130_MODE_VELPOS : TMC5130_MODE_VELNEG);
  163. }
  164. void TMC5130::right(int32_t velocity) { rotate(velocity); }
  165. void TMC5130::left(int32_t velocity) { rotate(-velocity); }
  166. void TMC5130::moveTo(int32_t position, uint32_t velocityMax) {
  167. // position *= m_scale;
  168. // velocityMax *= m_scale;
  169. position = to_motor_pos(position);
  170. velocityMax = to_motor_vel(velocityMax);
  171. // ZLOGI("TMC5130", "moveTo %d %d", position, velocityMax);
  172. writeInt(TMC5130_RAMPMODE, TMC5130_MODE_POSITION);
  173. writeInt(TMC5130_VMAX, velocityMax);
  174. writeInt(TMC5130_XTARGET, position);
  175. }
  176. void TMC5130::moveBy(int32_t relativePosition, uint32_t velocityMax) { // determine actual position and add numbers of ticks to move
  177. relativePosition += readInt(TMC5130_XACTUAL);
  178. moveTo(relativePosition, velocityMax);
  179. }
  180. uint32_t TMC5130::readXTARGET() { return readInt(TMC5130_XTARGET); }
  181. uint32_t TMC5130::haspassedms(uint32_t now, uint32_t last) {
  182. if (now >= last) {
  183. return now - last;
  184. } else {
  185. return 0xFFFFFFFF - last + now;
  186. }
  187. }
  188. bool TMC5130::isReachTarget() {
  189. /**
  190. * @brief
  191. */
  192. int mode = readInt(TMC5130_RAMPMODE);
  193. if (mode == TMC5130_MODE_POSITION) {
  194. uint32_t state = getTMC5130_RAMPSTAT();
  195. Tmc5130RampStat event = Tmc5130RampStat(state);
  196. return event.isSetted(Tmc5130RampStat::ktmc5130_rs_posreached);
  197. } else {
  198. uint32_t state = getTMC5130_RAMPSTAT();
  199. Tmc5130RampStat event = Tmc5130RampStat(state);
  200. return event.isSetted(Tmc5130RampStat::ktmc5130_rs_vzero) && event.isSetted(Tmc5130RampStat::ktmc5130_rs_velreached);
  201. }
  202. }
  203. void TMC5130::setScale(int32_t scale) { m_scale = scale; }
  204. void TMC5130::setScaleDenominator(int32_t scale) { m_scale_deceleration = scale; }
  205. /*******************************************************************************
  206. * basic *
  207. *******************************************************************************/
  208. // void TMC5130::writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value) {
  209. // CriticalContext cc;
  210. // writeInt(address, readInt(address) & ~mask | value << shift);
  211. // }
  212. void TMC5130::readWriteArray(uint8_t *data, size_t length) {
  213. CriticalContext cc;
  214. // m_port->TMC5130Port_readWriteArray(m_channel, data, length);
  215. // m_csnpin
  216. SET_PIN(m_csnpin, false);
  217. HAL_SPI_TransmitReceive(m_hspi, data, data, length, 100);
  218. SET_PIN(m_csnpin, true);
  219. }
  220. void TMC5130::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
  221. CriticalContext cc;
  222. uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC5130_WRITE_BIT)), x1, x2, x3, x4};
  223. readWriteArray(&data[0], 5);
  224. int32_t value = ((uint32_t)x1 << 24) | ((uint32_t)x2 << 16) | (x3 << 8) | x4;
  225. // Write to the shadow register and mark the register dirty
  226. address = TMC_ADDRESS(address);
  227. m_shadowRegister[address] = value;
  228. }
  229. void TMC5130::writeInt(uint8_t address, int32_t value) {
  230. CriticalContext cc;
  231. writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0));
  232. }
  233. void TMC5130::writeInt(uint8_t address, int32_t mask, int32_t shift, int32_t value){
  234. CriticalContext cc;
  235. writeInt(address, FIELD_SET(readInt(address), mask, shift, value));
  236. }
  237. int32_t TMC5130::readInt(uint8_t address) {
  238. CriticalContext cc;
  239. address = TMC_ADDRESS(address);
  240. // register not readable -> shadow register copy
  241. if (!TMC_IS_READABLE(tmc5130_defaultRegisterAccess[address])) return m_shadowRegister[address];
  242. uint8_t data[5] = {0, 0, 0, 0, 0};
  243. data[0] = address;
  244. readWriteArray(&data[0], 5);
  245. data[0] = address;
  246. readWriteArray(&data[0], 5);
  247. return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
  248. }
  249. int32_t TMC5130::to_motor_acc(int32_t acc) { //
  250. int32_t val = acc / 60.0 * m_onecirclepulse; // 65535
  251. if (val > 65535) val = 65535;
  252. return val;
  253. }
  254. int32_t TMC5130::to_motor_vel(int32_t vel) { //
  255. int32_t val = vel / 60.0 * m_onecirclepulse;
  256. if (val > 8388095 /*2^23-512*/) {
  257. val = 8388095;
  258. }
  259. return val;
  260. } // rpm
  261. int32_t TMC5130::to_motor_pos(int32_t pos) { //
  262. int32_t val = pos * 1.0 / m_scale * m_scale_deceleration * m_onecirclepulse;
  263. return val;
  264. } //
  265. int32_t TMC5130::to_user_pos(int32_t pos) { //
  266. int32_t val = pos / m_onecirclepulse * m_scale / m_scale_deceleration;
  267. return val;
  268. } //
  269. int32_t TMC5130::to_user_vel(int32_t vel) { //
  270. int32_t val = vel * 60.0 / m_onecirclepulse;
  271. return val;
  272. }
  273. #endif