Inital rewrite of stepticker and associated code to implement accleration per tick.
[clinton/Smoothieware.git] / src / libs / StepTicker.h
1 /*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6 */
7
8
9
10 #pragma once
11
12 #include <stdint.h>
13 #include <array>
14 #include <bitset>
15 #include <functional>
16 #include <atomic>
17
18 #include "ActuatorCoordinates.h"
19
20 class StepperMotor;
21 class Block;
22
23 class StepTicker{
24 public:
25 StepTicker();
26 ~StepTicker();
27 void set_frequency( float frequency );
28 void signal_a_move_finished();
29 void set_unstep_time( float microseconds );
30 int register_motor(StepperMotor* motor);
31 float get_frequency() const { return frequency; }
32 void unstep_tick();
33
34 void TIMER0_IRQHandler (void);
35 void PendSV_IRQHandler (void);
36
37 void start();
38 void copy_block(Block *block);
39 void set_next_block(Block *block) { next_block= block; }
40 bool is_next_block() const { return next_block != nullptr; }
41
42 // whatever setup the block should register this to know when it is done
43 std::function<void()> finished_fnc{nullptr};
44
45 static StepTicker *getInstance() { return instance; }
46
47 private:
48 static StepTicker *instance;
49
50 float frequency;
51 uint32_t period;
52 std::array<StepperMotor*, k_max_actuators> motor;
53 std::atomic_uchar do_move_finished;
54 std::bitset<k_max_actuators> unstep;
55
56 // this is tick info needed for this block. applies to all motors
57 struct block_info_t {
58 uint32_t accelerate_until;
59 uint32_t decelerate_after;
60 uint32_t maximum_rate;
61 uint32_t deceleration_per_tick;
62 uint32_t total_move_ticks;
63 };
64 block_info_t block_info;
65 Block *next_block{nullptr};
66
67 // this is the data needed to determine when each motor needs to be issued a step
68 struct tickinfo_t {
69 float steps_per_tick; // 2.30 fixed point
70 float counter; // 2.30 fixed point
71 float acceleration_change; // 1.30 fixed point signed
72 float axis_ratio;
73 uint32_t steps_to_move;
74 uint32_t step_count;
75 uint32_t next_accel_event;
76 };
77 std::array<tickinfo_t, k_max_actuators> tick_info;
78
79 struct {
80 volatile bool move_issued:1;
81 uint8_t num_motors:4;
82 };
83 };