/* * pse_stepper_planer.c * * Created on: Aug 14, 2023 * Author: leo */ #include #include "PSE_unit.h" #include "pse_stepper_planer.h" static int units_running = 0; // counter of currently running units, to disable interrupts when unnecessary static TIM_HandleTypeDef* htim; // main interrupt timer handle void pse_stepper_planer_tick(pse_unit* units, uint8_t units_num){ for(int i = 0; i < units_num; i++){ pse_stepper_conf* c = units[i].stepper_conf; int state; if(c->step_max){ c->tick_counter %= 2; state = c->tick_counter; } else{ c->tick_counter %= c->step_itvl; state = c->tick_counter == 0; } c->tick_counter++; HAL_GPIO_WritePin(c->STEP_GPIO_Port, c->STEP_GPIO_Pin, state); c->steps_counter += (pse_sp_get_dir(c)?1:-1) * (state?1:0); if(c->stopAtHome && c->steps_counter == 0){ pse_sp_stop_axis(c); } } } void pse_sp_start_axis(pse_stepper_conf* conf){ if(HAL_GPIO_ReadPin(conf->EN_GPIO_Port, conf->EN_GPIO_Pin) == GPIO_PIN_SET){ if(units_running == 0) HAL_TIM_Base_Start_IT(htim); units_running++; } HAL_GPIO_WritePin(conf->EN_GPIO_Port, conf->EN_GPIO_Pin, GPIO_PIN_RESET); } void pse_sp_stop_axis(pse_stepper_conf* conf){ if(HAL_GPIO_ReadPin(conf->EN_GPIO_Port, conf->EN_GPIO_Pin) == GPIO_PIN_RESET){ units_running--; if(units_running == 0) HAL_TIM_Base_Stop_IT(htim); } HAL_GPIO_WritePin(conf->EN_GPIO_Port, conf->EN_GPIO_Pin, GPIO_PIN_SET); } void pse_sp_set_dir(pse_stepper_conf* conf, int dir){ HAL_GPIO_WritePin(conf->DIR_GPIO_Port, conf->DIR_GPIO_Pin, dir); } int pse_sp_get_dir(pse_stepper_conf* conf){ return HAL_GPIO_ReadPin(conf->DIR_GPIO_Port, conf->DIR_GPIO_Pin); } void pse_stepper_planer_compute_sps(pse_unit* unit){ pse_stepper_conf* c = unit->stepper_conf; // magic constants are used to approximate pi and other multiplicatives constant as a rationnal uint64_t numerator = (uint64_t)1 * unit->syringe->diameter * unit->syringe->diameter * PSE_STEPPER_INTERRUPT_RATE * PSE_STEPPER_SCREW_PITCH; uint64_t denominator = (uint64_t)21220209 * unit->flow * PSE_STEPPER_STEPS_PER_ROTATION; c->step_itvl = numerator / denominator; } void pse_sp_set_dir_all(pse_unit* units, int units_num, int dir){ for(int i = 0; i < units_num; i++){ pse_sp_set_dir(units[i].stepper_conf, dir); } } void pse_sp_start_all(pse_unit* units, int units_num){ HAL_TIM_Base_Start_IT(htim); for(int i = 0; i < units_num; i++){ if(units[i].enabled){ pse_sp_start_axis(units[i].stepper_conf); units_running++; } } } void pse_sp_stop_all(pse_unit* units, int units_num){ for(int i = 0; i < units_num; i++){ if(units[i].enabled) pse_sp_stop_axis(units[i].stepper_conf); } HAL_TIM_Base_Stop_IT(htim); units_running = 0; } void pse_sp_set_timer(TIM_HandleTypeDef* tim){ htim = tim; }