/** * @file TMC2209_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2026 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief functions of SteppingMotor control * * @version * - 1_01_221231 > ATY * -# Preliminary version, first Release * - 1_02_230408 > ATY * -# Add State Machine and so * - 1_03_230426 > ATY * -# Change name "SteppingMotor_ATY" to "TMC2209_ATY" * - 1_01_240111 > ATY * -# add multy addr and channel * -# add lock * - 1_01_240112 > ATY * -# change name from MOTOR_STEP to TMC2209 ******************************************************************************** */ #ifndef __TMC2209_ATY_C #define __TMC2209_ATY_C #include "TMC2209_ATY.h" /******************************* For user *************************************/ /******************************************************************************/ /** * @brief set motor enable or disbale * * @param enable 0 for disable, 1 for enable * @param dev * @return uint8_t */ uint8_t TMC2209_SetAble(uint8_t en, struct TMC2209_ATY_Dev* dev) { __ATY_LOCK(dev); dev->motorEn = en; if(en){ dev->enSet(__ATY_HL_L); } else{ dev->enSet(__ATY_HL_H); } __ATY_UNLOCK(dev); return 0; } /** * @brief set motor direction * * @param dir 0 for forward, 1 for reversal * @param dev * @return uint8_t */ uint8_t TMC2209_SetDirection(uint8_t dir, struct TMC2209_ATY_Dev* dev) { __ATY_LOCK(dev); dev->motorDir = dir; if(dir){ dev->dirSet(__ATY_HL_H); } else{ dev->dirSet(__ATY_HL_L); } __ATY_UNLOCK(dev); return 0; } /** * @brief get TMC2209 diag pin voltage level * * @param dev * @return uint8_t 0 for low, 1 fo high * @return uint8_t */ uint8_t TMC2209_GetDiagLevel(struct TMC2209_ATY_Dev* dev) { __ATY_LOCK(dev); dev->motorDiag = dev->diagGet(); __ATY_UNLOCK(dev); return dev->motorDiag; } /** * @brief start motor with direction set * * @param dir direction to move * @param speed direction to move * @param dev */ void TMC2209_Start(uint8_t dir, uint32_t speed, struct TMC2209_ATY_Dev* dev) { TMC2209_SetDirection(dir, dev); TMC2209_SetAble(1, dev); dev->freqSet(speed); } /** * @brief stop motor * * @param dev */ void TMC2209_Stop(struct TMC2209_ATY_Dev* dev) { // TMC2209_PARAM_SET(0, 0, 0, 0, 0, 0, dev); if(dev->motorEn == 0) return; else{ dev->freqSet(0); TMC2209_SetAble(0, dev); dev->motorSpeedCounter = 0; dev->motorStopCounter = 0; } } /** * @brief process motor error * * @param dev * @note put at 1ms cycle */ void MotorSelfCycle(struct TMC2209_ATY_Dev* dev) { if(TMC2209_GetDiagLevel(dev)){ if(dev->motorEn == 1) TMC2209_SetAble(0, dev); if(dev->motorStopCounter >= 10000) TMC2209_SetAble(1, dev); } } /** * @brief deal step motor state * * @param dev * @note put at 1ms cycle; * set motorSetState = 4 to change motor dir with speed no changed * set motorSetState = 3 to start motor directly, motorSoftSteps need to be 0 * set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftSteps/motorSteps need to be set * set motorSetState = 0 to stop motor flow * set motorSetState = 10 to scram motor * when motorSetState = 5 means last cycle finished, set others to start a new cycle * when motorSetState = 1 means motor running and state not changing */ void TMC2209_StateMachine_PWM(struct TMC2209_ATY_Dev* dev) { if(dev->motorSoftSpeed < dev->motorSpeed) dev->motorSoftSpeed = dev->motorSpeed; if(dev->motorSetState == TMC2209_SET_REVERSE){ dev->motorStopCounter = 0; dev->motorStepCounter = 0; dev->motorSetState = TMC2209_SET_START_SOFT; dev->motorDir = !dev->motorDir; } else if(dev->motorSetState == TMC2209_SET_START_DIRECTLY){ dev->motorStepCounter = dev->motorSoftSteps; TMC2209_Start(dev->motorDir, dev->motorSpeed, dev); dev->motorSetState = TMC2209_SET_RUNNING; } else if(dev->motorSetState == TMC2209_SET_START_SOFT){ dev->motorStepCounter = 0; TMC2209_Start(dev->motorDir, dev->motorSoftSpeed, dev); dev->motorSetState = TMC2209_SET_RUNNING; } else if(dev->motorSetState == TMC2209_SET_RUNNING){ if(dev->motorStepCounter < dev->motorSoftSteps){ if(dev->lineProType == 'T'){ dev->speedIncreaseStep = ((float)(dev->motorSoftSpeed - dev->motorSpeed) / (float)dev->motorSoftSteps); // at 1ms cycle TMC2209_Start(dev->motorDir, dev->motorSpeed < (dev->motorSoftSpeed - (dev->speedIncreaseStep * dev->motorStepCounter)) ? (dev->motorSoftSpeed - (dev->speedIncreaseStep * dev->motorStepCounter)) : dev->motorSpeed, dev); } else if(dev->lineProType == 'S'){ // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users float S_param_A = (((float)(dev->motorSoftSpeed - dev->motorSpeed) / 2) - (dev->lineProParam * (float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2) / 2)) / ((float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2) * (float)((float)dev->motorSoftSteps / 2)) * 4; // mbG[27] = S_param_A * 10000000; if(dev->motorStepCounter < (dev->motorSoftSteps / 2)) dev->speedIncreaseStep = ((float)(S_param_A * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter) / 4) + ((float)(dev->lineProParam * dev->motorStepCounter * dev->motorStepCounter) / 2); // (S_param_A * dev->motorStepCounter * dev->motorStepCounter * dev->motorStepCounter) // + (lineProParam * dev->motorStepCounter); else dev->speedIncreaseStep = (float)((float)(dev->motorSoftSpeed - dev->motorSpeed) / 2) + ((float)(S_param_A * dev->motorSoftSteps * dev->motorSoftSteps * dev->motorSoftSteps * dev->motorSoftSteps) / 64) + ((float)(dev->lineProParam * dev->motorSoftSteps * dev->motorSoftSteps) / 8) - ((float)(S_param_A * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter)) / 4) - ((float)(dev->lineProParam * (dev->motorSoftSteps - dev->motorStepCounter) * (dev->motorSoftSteps - dev->motorStepCounter)) / 2); // 0 // - (S_param_A * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps) // * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps) // * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps)) // - (dev->lineProParam * (float)((float)dev->motorStepCounter - (float)dev->motorSoftSteps)); TMC2209_Start(dev->motorDir, dev->motorSpeed < (dev->motorSoftSpeed - dev->speedIncreaseStep) ? (dev->motorSoftSpeed - dev->speedIncreaseStep) : dev->motorSpeed, dev); } else if(dev->lineProType == '2'){} } if(dev->motorStepCounter == dev->motorSoftSteps) dev->motorSetState = TMC2209_SET_START_DIRECTLY; else if(dev->motorStepCounter >= (dev->motorSoftSteps + dev->motorSteps)) dev->motorSetState = TMC2209_SET_FINISHED; } else if(dev->motorSetState == TMC2209_SET_SCRAM){ TMC2209_Stop(dev); dev->motorSetState = TMC2209_SET_STOP; } else{ TMC2209_Stop(dev); } // 5 0 if(dev->motorEn == 0){ dev->motorStepCounter = 0; dev->motorStopCounter++; } else{ dev->motorStepCounter++; dev->motorStopCounter = 0; } } #endif /* __TMC2209_ATY_C */ /************************************ etc *************************************/ /* init */ // void MOTOR_1_EN_SET(uint8_t level) { // if(level == __ATY_HL_L) // GPIO_SET_L(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin); // else if(level == __ATY_HL_H) // GPIO_SET_H(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin); // } // void MOTOR_1_DIR_SET(uint8_t level) { // if(level == __ATY_HL_L) // GPIO_SET_L(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin); // else if(level == __ATY_HL_H) // GPIO_SET_H(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin); // } // void MOTOR_1_DIAG_GET(void) { } // void MOTOR_1_FREQ_SET(uint16_t freq) { // HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // __HAL_TIM_SET_AUTORELOAD(&htim3, freq); // __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, (uint16_t)(freq * 0.5)); // HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // } // struct TMC2209_ATY_Dev TMC2209_ATY_Dev_1 = { // .id = 'M', // .motorEn = 0, // .motorDir = 0, // .motorStepLevel = 0, // .motorDiag = 0, // .motorSoftSpeed = 0, // .motorSpeed = 0, // .motorSpeedCounter = 0, // .motorSoftSteps = 0, // .motorSteps = 0, // .motorStepCounter = 0, // .motorStopCounter = 0, // .motorSetState = 0, // .speedIncreaseStep = 0, // .lineProType = 'T', // .lineProParam = TMC2209_S_PARAM_C, // .enSet = MOTOR_1_EN_SET, // .dirSet = MOTOR_1_DIR_SET, // .diagGet = MOTOR_1_DIAG_GET, // .freqSet = MOTOR_1_FREQ_SET, // .lock = __ATY_UNLOCKED, // .debugEnable = 0, // }; // SetMotorDefault(&TMC2209_ATY_Dev_1){ // TMC2209_PARAM_SET( // (uint8_t)mbP_TMC2209_DIR, // (uint32_t)mbP_TMC2209_SOFT_SPEED, // (uint32_t)mbP_TMC2209_RUN_SPEED, // (uint32_t)mbP_TMC2209_SOFT_TIME, // (uint32_t)mbP_TMC2209_RUN_TIME, // (uint8_t)mbP_TMC2209_SET_STATE, // dev); // HAL_GPIO_WritePin(STEP_MOTOR_DIR_GPIO_Port, STEP_MOTOR_DIR_Pin, GPIO_PIN_RESET); // HAL_GPIO_WritePin(STEP_MOTOR_EN_GPIO_Port, STEP_MOTOR_EN_Pin, GPIO_PIN_SET); // } // HAL_TIM_Base_Start(&htim3); // __HAL_TIM_SET_AUTORELOAD(&htim3, STEP_MOTOR_PARAM_RUN_SPEED); // __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); /* use */ // // in 1ms loop // StepMotorProcess(); // TMC2209_StateMachine_PWM(&TMC2209_ATY_Dev_1); // TMC2209_PARAM_GET( // mbP_TMC2209_DIR, // mbP_TMC2209_SOFT_SPEED, // mbP_TMC2209_RUN_SPEED, // mbP_TMC2209_SOFT_TIME, // mbP_TMC2209_RUN_TIME, // mbP_TMC2209_SET_STATE, // TMC2209_ATY_Dev_1); // // uart change(in uart process) // TMC2209_PARAM_SET( // (uint8_t)mbP_TMC2209_DIR, // (uint32_t)mbP_TMC2209_SOFT_SPEED, // (uint32_t)mbP_TMC2209_RUN_SPEED, // (uint32_t)mbP_TMC2209_SOFT_TIME, // (uint32_t)mbP_TMC2209_RUN_TIME, // (uint8_t)mbP_TMC2209_SET_STATE, // (&TMC2209_ATY_Dev_1)); // // set state or others to use // if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_SCRAM){ // mbP_TMC2209_SET_STATE = TMC2209_SET_SCRAM; // } // else if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_UP){ // mbP_TMC2209_DIR = STEP_MOTOR_PARAM_DIR_UP; // mbP_TMC2209_SET_STATE = TMC2209_SET_START_SOFT; // } // else if((uint8_t)mbP_TMC2209_FAST_CMD == STEP_MOTOR_CMD_DOWN){ // mbP_TMC2209_DIR = STEP_MOTOR_PARAM_DIR_DOWN; // mbP_TMC2209_SET_STATE = TMC2209_SET_START_SOFT; // } /******************************************************************************/ /******************************** End Of File *********************************/