- void TIM1_CC_IRQHandler(void) {
 - float max_dv, tiny_dp, vel_req;
 - int32_t pos_err;
 - TIMER_LED_ON;
 - TIM1->SR &= ~TIM_SR_CC1IF; // clear capture/compare 1 event flag
 - m1.active = 0;
 - if (m1.current_period == 0) {
 - // initiate movement
 - // Calculate initial period needed for the calculation of acceleration
 - m1.current_period = stepper_setf(1.0f / sqrtf(2.0f / (float) STEPPER_MAX_A));
 - // No movement in this iteration
 - m1.dir = 0;
 - if(m1.pos_cmd - m1.current_pos > 0) {
 - // m1.dir = 1;
 - STEPPER_SET_DIR_POS;
 - } else if(m1.pos_cmd - m1.current_pos < 0){
 - // m1.dir = -1;
 - STEPPER_SET_DIR_NEG;
 - }
 - // Set the counter to CCR1 value, so the first timer loop will not cause compare match
 - TIM1->CNT = TIM1->CCR1;
 - TIM1->EGR = TIM_EGR_UG; // Generate update event (reload registers)
 - TIM1->SR &= ~TIM_SR_UIF; // clear update event flag
 - TIM1->CCER |= TIM_CCER_CC1E; // Enable PWM output
 - TIM1->CR1 |= TIM_CR1_CEN; // Count up, Enable timer
 - }
 - m1.current_pos += m1.dir;
 - /* compute max change in velocity per servo period */
 - max_dv = STEPPER_MAX_A * (float) m1.current_period / (float) CPU_CLK;
 - /* calculate desired velocity */
 - if (m1.enabled) {
 - /* planner enabled, request a velocity that tends to drive
 - pos_err to zero, but allows for stopping without position
 - overshoot */
 - pos_err = m1.pos_cmd - m1.current_pos;
 - /* positive and negative errors require some sign flipping to
 - avoid sqrt(negative) */
 - if (pos_err > 0) {
 - vel_req = -max_dv + sqrtf(2.0f * (float) STEPPER_MAX_A * (float) pos_err + max_dv * max_dv);
 - /* mark planner as active */
 - m1.active = 1;
 - } else if (pos_err < 0) {
 - vel_req = max_dv - sqrtf(-2.0f * (float) STEPPER_MAX_A * (float) pos_err + max_dv * max_dv);
 - /* mark planner as active */
 - m1.active = 1;
 - } else {
 - /* within 'tiny_dp' of desired pos, no need to move */
 - vel_req = 0.0;
 - }
 - } else {
 - /* planner disabled, request zero velocity */
 - vel_req = 0.0;
 - /* and set command to present position to avoid movement when
 - next enabled */
 - m1.pos_cmd = m1.current_pos;
 - }
 - /* limit velocity request */
 - if (vel_req > m1.vmax) {
 - vel_req = m1.vmax;
 - } else if (vel_req < -m1.vmax) {
 - vel_req = -m1.vmax;
 - }
 - /* ramp velocity toward request at accel limit */
 - if (vel_req > m1.current_vel + max_dv) {
 - m1.current_vel += max_dv;
 - } else if (vel_req < m1.current_vel - max_dv) {
 - m1.current_vel -= max_dv;
 - } else {
 - m1.current_vel = vel_req;
 - }
 - // TODO poprawić - gubi pierwszy(?) krok
 - if(m1.current_vel > 0) {
 - m1.dir = 1;
 - STEPPER_SET_DIR_POS;
 - } else if(m1.current_vel < 0) {
 - m1.dir = -1;
 - STEPPER_SET_DIR_NEG;
 - }
 - /* check for still moving */
 - if(m1.current_vel != 0.0) {
 - /* yes, mark planner active */
 - m1.active = 1;
 - }
 - /* integrate velocity to get new position */
 - //m1.current_pos += m1.current_vel * m1.current_period;
 - if(m1.active == 0) {
 - stepper_stop();
 - } else {
 - m1.current_period = stepper_setf(fabsf(m1.current_vel));
 - }
 - TIMER_LED_OFF;
 - }