TMC2209_ATY.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /**
  2. * @file TMC2209_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief functions of SteppingMotor control
  20. *
  21. * @version
  22. * - 1_01_221231 > ATY
  23. * -# Preliminary version, first Release
  24. * - 1_02_230408 > ATY
  25. * -# Add State Machine and so
  26. * - 1_03_230426 > ATY
  27. * -# Change name "SteppingMotor_ATY" to "TMC2209_ATY"
  28. * - 1_01_240111 > ATY
  29. * -# add multy addr and channel
  30. * -# add lock
  31. * - 1_01_240112 > ATY
  32. * -# change name from MOTOR_STEP to TMC2209
  33. ********************************************************************************
  34. */
  35. #ifndef __TMC2209_ATY_C
  36. #define __TMC2209_ATY_C
  37. #include "TMC2209_ATY.h"
  38. /******************************* For user *************************************/
  39. /******************************************************************************/
  40. /**
  41. * @brief set motor enable or disbale
  42. *
  43. * @param enable 0 for disable, 1 for enable
  44. * @param dev
  45. * @return uint8_t
  46. */
  47. uint8_t TMC2209_SetAble(uint8_t en, struct TMC2209_ATY_Dev* dev)
  48. {
  49. __ATY_LOCK(dev);
  50. dev->motorEn = en;
  51. if(en){ dev->enSet(__ATY_HL_L); }
  52. else{ dev->enSet(__ATY_HL_H); }
  53. __ATY_UNLOCK(dev);
  54. return 0;
  55. }
  56. /**
  57. * @brief set motor direction
  58. *
  59. * @param dir 0 for forward, 1 for reversal
  60. * @param dev
  61. * @return uint8_t
  62. */
  63. uint8_t TMC2209_SetDirection(uint8_t dir, struct TMC2209_ATY_Dev* dev)
  64. {
  65. __ATY_LOCK(dev);
  66. dev->motorDir = dir;
  67. if(dir){ dev->dirSet(__ATY_HL_H); }
  68. else{ dev->dirSet(__ATY_HL_L); }
  69. __ATY_UNLOCK(dev);
  70. return 0;
  71. }
  72. /**
  73. * @brief get TMC2209 diag pin voltage level
  74. *
  75. * @param dev
  76. * @return uint8_t 0 for low, 1 fo high
  77. * @return uint8_t
  78. */
  79. uint8_t TMC2209_GetDiagLevel(struct TMC2209_ATY_Dev* dev)
  80. {
  81. __ATY_LOCK(dev);
  82. dev->motorDiag = dev->diagGet();
  83. __ATY_UNLOCK(dev);
  84. return dev->motorDiag;
  85. }
  86. /**
  87. * @brief start motor with direction set
  88. *
  89. * @param dir direction to move
  90. * @param speed direction to move
  91. * @param dev
  92. */
  93. void TMC2209_Start(uint8_t dir, uint32_t speed, struct TMC2209_ATY_Dev* dev)
  94. {
  95. TMC2209_SetDirection(dir, dev);
  96. TMC2209_SetAble(1, dev);
  97. dev->freqSet(speed);
  98. }
  99. /**
  100. * @brief stop motor
  101. *
  102. * @param dev
  103. */
  104. void TMC2209_Stop(struct TMC2209_ATY_Dev* dev)
  105. {
  106. // TMC2209_PARAM_SET(0, 0, 0, 0, 0, 0, dev);
  107. if(dev->motorEn == 0)
  108. return;
  109. else{
  110. dev->freqSet(0);
  111. TMC2209_SetAble(0, dev);
  112. dev->motorSpeedCounter = 0;
  113. dev->motorStopCounter = 0;
  114. }
  115. }
  116. /**
  117. * @brief process motor error
  118. *
  119. * @param dev
  120. * @note put at 1ms cycle
  121. */
  122. void MotorSelfCycle(struct TMC2209_ATY_Dev* dev)
  123. {
  124. if(TMC2209_GetDiagLevel(dev)){
  125. if(dev->motorEn == 1)
  126. TMC2209_SetAble(0, dev);
  127. if(dev->motorStopCounter >= 10000)
  128. TMC2209_SetAble(1, dev);
  129. }
  130. }
  131. /**
  132. * @brief deal step motor state
  133. *
  134. * @param dev
  135. * @note put at 1ms cycle;
  136. * set motorSetState = 4 to change motor dir with speed no changed
  137. * set motorSetState = 3 to start motor directly, motorSoftSteps need to be 0
  138. * set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftSteps/motorSteps need to be set
  139. * set motorSetState = 0 to stop motor flow
  140. * set motorSetState = 10 to scram motor
  141. * when motorSetState = 5 means last cycle finished, set others to start a new cycle
  142. * when motorSetState = 1 means motor running and state not changing
  143. */
  144. void TMC2209_StateMachine_PWM(struct TMC2209_ATY_Dev* dev)
  145. {
  146. if(dev->motorSoftSpeed < dev->motorSpeed)
  147. dev->motorSoftSpeed = dev->motorSpeed;
  148. if(dev->motorSetState == TMC2209_SET_REVERSE){
  149. dev->motorStopCounter = 0;
  150. dev->motorStepCounter = 0;
  151. dev->motorSetState = TMC2209_SET_START_SOFT;
  152. dev->motorDir = !dev->motorDir;
  153. }
  154. else if(dev->motorSetState == TMC2209_SET_START_DIRECTLY){
  155. dev->motorStepCounter = dev->motorSoftSteps;
  156. TMC2209_Start(dev->motorDir, dev->motorSpeed, dev);
  157. dev->motorSetState = TMC2209_SET_RUNNING;
  158. }
  159. else if(dev->motorSetState == TMC2209_SET_START_SOFT){
  160. dev->motorStepCounter = 0;
  161. TMC2209_Start(dev->motorDir, dev->motorSoftSpeed, dev);
  162. dev->motorSetState = TMC2209_SET_RUNNING;
  163. }
  164. else if(dev->motorSetState == TMC2209_SET_RUNNING){
  165. if(dev->motorStepCounter < dev->motorSoftSteps){
  166. if(dev->lineProType == 'T'){
  167. dev->speedIncreaseStep = ((float)(dev->motorSoftSpeed - dev->motorSpeed) / (float)dev->motorSoftSteps); // at 1ms cycle
  168. TMC2209_Start(dev->motorDir,
  169. dev->motorSpeed < (dev->motorSoftSpeed - (dev->speedIncreaseStep * dev->motorStepCounter)) ?
  170. (dev->motorSoftSpeed - (dev->speedIncreaseStep * dev->motorStepCounter)) : dev->motorSpeed, dev);
  171. }
  172. else if(dev->lineProType == 'S'){
  173. // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users
  174. float S_param_A = (((float)(dev->motorSoftSpeed - dev->motorSpeed) / 2)
  175. - (dev->lineProParam * (float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2) / 2))
  176. / ((float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2)
  177. * (float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2)) * 4;
  178. // mbG[27] = S_param_A * 10000000;
  179. if(dev->motorStepCounter < (dev->motorSoftSteps / 2))
  180. dev->speedIncreaseStep =
  181. ((float)(S_param_A * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter) / 4)
  182. + ((float)(dev->lineProParam * dev->motorStepCounter * dev->motorStepCounter) / 2);
  183. // (S_param_A * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter)
  184. // + (lineProParam * dev->motorStepCounter);
  185. else
  186. dev->speedIncreaseStep =
  187. (float)((float)(dev->motorSoftSpeed - dev->motorSpeed) / 2)
  188. + ((float)(S_param_A * dev->motorSoftSteps * dev->motorSoftSteps * dev->motorSoftSteps * dev->motorSoftSteps) / 64)
  189. + ((float)(dev->lineProParam * dev->motorSoftSteps * dev->motorSoftSteps) / 8)
  190. - ((float)(S_param_A * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter)
  191. * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter)) / 4)
  192. - ((float)(dev->lineProParam * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter)) / 2);
  193. // 0
  194. // - (S_param_A * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps)
  195. // * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps)
  196. // * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps))
  197. // - (dev->lineProParam * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps));
  198. TMC2209_Start(dev->motorDir,
  199. dev->motorSpeed < (dev->motorSoftSpeed - dev->speedIncreaseStep) ?
  200. (dev->motorSoftSpeed - dev->speedIncreaseStep) : dev->motorSpeed, dev);
  201. }
  202. else if(dev->lineProType == '2'){}
  203. }
  204. if(dev->motorStepCounter == dev->motorSoftSteps)
  205. dev->motorSetState = TMC2209_SET_START_DIRECTLY;
  206. else if(dev->motorStepCounter >= (dev->motorSoftSteps + dev->motorSteps))
  207. dev->motorSetState = TMC2209_SET_FINISHED;
  208. }
  209. else if(dev->motorSetState == TMC2209_SET_SCRAM){
  210. TMC2209_Stop(dev);
  211. dev->motorSetState = TMC2209_SET_STOP;
  212. }
  213. else{ TMC2209_Stop(dev); } // 5 0
  214. if(dev->motorEn == 0){
  215. dev->motorStepCounter = 0;
  216. dev->motorStopCounter++;
  217. }
  218. else{
  219. dev->motorStepCounter++;
  220. dev->motorStopCounter = 0;
  221. }
  222. }
  223. #endif /* __TMC2209_ATY_C */
  224. /************************************ etc *************************************/
  225. /* init */
  226. // void MOTOR_1_EN_SET(uint8_t level) {
  227. // if(level == __ATY_HL_L)
  228. // GPIO_SET_L(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin);
  229. // else if(level == __ATY_HL_H)
  230. // GPIO_SET_H(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin);
  231. // }
  232. // void MOTOR_1_DIR_SET(uint8_t level) {
  233. // if(level == __ATY_HL_L)
  234. // GPIO_SET_L(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin);
  235. // else if(level == __ATY_HL_H)
  236. // GPIO_SET_H(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin);
  237. // }
  238. // void MOTOR_1_DIAG_GET(void) { }
  239. // void MOTOR_1_FREQ_SET(uint16_t freq) {
  240. // HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
  241. // __HAL_TIM_SET_AUTORELOAD(&htim3, freq);
  242. // __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, (uint16_t)(freq * 0.5));
  243. // HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
  244. // }
  245. // struct TMC2209_ATY_Dev TMC2209_ATY_Dev_1 = {
  246. // .id = 'M',
  247. // .motorEn = 0,
  248. // .motorDir = 0,
  249. // .motorStepLevel = 0,
  250. // .motorDiag = 0,
  251. // .motorSoftSpeed = 0,
  252. // .motorSpeed = 0,
  253. // .motorSpeedCounter = 0,
  254. // .motorSoftSteps = 0,
  255. // .motorSteps = 0,
  256. // .motorStepCounter = 0,
  257. // .motorStopCounter = 0,
  258. // .motorSetState = 0,
  259. // .speedIncreaseStep = 0,
  260. // .lineProType = 'T',
  261. // .lineProParam = TMC2209_S_PARAM_C,
  262. // .enSet = MOTOR_1_EN_SET,
  263. // .dirSet = MOTOR_1_DIR_SET,
  264. // .diagGet = MOTOR_1_DIAG_GET,
  265. // .freqSet = MOTOR_1_FREQ_SET,
  266. // .lock = __ATY_UNLOCKED,
  267. // .debugEnable = 0,
  268. // };
  269. // SetMotorDefault(&TMC2209_ATY_Dev_1){
  270. // TMC2209_PARAM_SET(
  271. // (uint8_t)mbP_TMC2209_DIR,
  272. // (uint32_t)mbP_TMC2209_SOFT_SPEED,
  273. // (uint32_t)mbP_TMC2209_RUN_SPEED,
  274. // (uint32_t)mbP_TMC2209_SOFT_TIME,
  275. // (uint32_t)mbP_TMC2209_RUN_TIME,
  276. // (uint8_t)mbP_TMC2209_SET_STATE,
  277. // dev);
  278. // HAL_GPIO_WritePin(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin, GPIO_PIN_RESET);
  279. // HAL_GPIO_WritePin(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin, GPIO_PIN_SET);
  280. // }
  281. // HAL_TIM_Base_Start(&htim3);
  282. // __HAL_TIM_SET_AUTORELOAD(&htim3, STEP_MOTOR_PARAM_RUN_SPEED);
  283. // __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
  284. // HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
  285. /* use */
  286. // // in 1ms loop
  287. // StepMotorProcess();
  288. // TMC2209_StateMachine_PWM(&TMC2209_ATY_Dev_1);
  289. // TMC2209_PARAM_GET(
  290. // mbP_TMC2209_DIR,
  291. // mbP_TMC2209_SOFT_SPEED,
  292. // mbP_TMC2209_RUN_SPEED,
  293. // mbP_TMC2209_SOFT_TIME,
  294. // mbP_TMC2209_RUN_TIME,
  295. // mbP_TMC2209_SET_STATE,
  296. // TMC2209_ATY_Dev_1);
  297. // // uart change(in uart process)
  298. // TMC2209_PARAM_SET(
  299. // (uint8_t)mbP_TMC2209_DIR,
  300. // (uint32_t)mbP_TMC2209_SOFT_SPEED,
  301. // (uint32_t)mbP_TMC2209_RUN_SPEED,
  302. // (uint32_t)mbP_TMC2209_SOFT_TIME,
  303. // (uint32_t)mbP_TMC2209_RUN_TIME,
  304. // (uint8_t)mbP_TMC2209_SET_STATE,
  305. // (&TMC2209_ATY_Dev_1));
  306. // // set state or others to use
  307. // if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_SCRAM){
  308. // mbP_TMC2209_SET_STATE = TMC2209_SET_SCRAM;
  309. // }
  310. // else if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_UP){
  311. // mbP_TMC2209_DIR = STEP_MOTOR_PARAM_DIR_UP;
  312. // mbP_TMC2209_SET_STATE = TMC2209_SET_START_SOFT;
  313. // }
  314. // else if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_DOWN){
  315. // mbP_TMC2209_DIR = STEP_MOTOR_PARAM_DIR_DOWN;
  316. // mbP_TMC2209_SET_STATE = TMC2209_SET_START_SOFT;
  317. // }
  318. /******************************************************************************/
  319. /******************************** End Of File *********************************/