extruder module completely messed up, trying something completely
[clinton/Smoothieware.git] / src / modules / tools / extruder / Extruder.cpp
CommitLineData
4cff3ded
AW
1#include "mbed.h"
2#include "libs/Module.h"
3#include "libs/Kernel.h"
4#include "modules/robot/Block.h"
5#include "modules/tools/extruder/Extruder.h"
6
7
8
9Extruder* extruder_for_irq; // We need this global because ISRs can't be attached to an object
10extern "C" void TIMER1_IRQHandler (void){
11 if((LPC_TIM1->IR >> 1) & 1){
12 LPC_TIM1->IR |= 1 << 1;
13 extruder_for_irq->step_pin = 0;
14 }
15 if((LPC_TIM1->IR >> 0) & 1){
16 LPC_TIM1->IR |= 1 << 0;
17 extruder_for_irq->stepping_tick();
18 }
19}
20
436a2cd1
AW
21Extruder::Extruder(PinName stppin) : step_pin(stppin){
22 this->absolute_mode = true;
23}
4cff3ded
AW
24
25void Extruder::on_module_loaded() {
f5598f5b 26
436a2cd1 27 if( this->kernel->config->value( extruder_module_enable_checksum )->by_default(false)->as_bool() == false ){ return; }
f5598f5b 28
4cff3ded
AW
29 extruder_for_irq = this;
30
31 // Settings
da24d6ae 32 this->on_config_reload(this);
4cff3ded
AW
33
34 // We work on the same Block as Stepper, so we need to know when it gets a new one and drops one
35 this->register_for_event(ON_BLOCK_BEGIN);
36 this->register_for_event(ON_BLOCK_END);
436a2cd1 37 this->register_for_event(ON_GCODE_EXECUTE);
4cff3ded
AW
38
39 // Configuration
40 this->acceleration_ticker.attach_us(this, &Extruder::acceleration_tick, 1000000/this->kernel->stepper->acceleration_ticks_per_second);
41
42 this->start_position = 0;
43 this->target_position = 0;
44 this->current_position = 0;
45 this->current_block = NULL;
46
47 // Start Timer1
48 LPC_TIM1->MR0 = 10000;
49 LPC_TIM1->MR1 = 500;
50 LPC_TIM1->MCR = 11; // For MR0 and MR1, with no reset at MR1
51 NVIC_EnableIRQ(TIMER1_IRQn);
52 LPC_TIM1->TCR = 1;
53}
54
2bb8b390 55// Get config
da24d6ae 56void Extruder::on_config_reload(void* argument){
436a2cd1
AW
57 this->microseconds_per_step_pulse = 5; //this->kernel->config->value(microseconds_per_step_pulse_ckeckusm)->by_default(5)->as_number();
58}
59
60// Computer extrusion speed based on parameters and gcode distance of travel
61void Extruder::on_gcode_execute(void* argument){
62 Gcode* gcode = static_cast<Gcode*>(argument);
e2b4a32b
AW
63
64 this->kernel->serial->printf("exec: %s \r\n", gcode->command.c_str() );
65
436a2cd1
AW
66 // Absolute/relative mode
67 if( gcode->has_letter('M')){
68 int code = gcode->get_value('M');
69 if( code == 82 ){ this->absolute_mode == true; }
70 if( code == 83 ){ this->absolute_mode == false; }
71 }
1a2d88eb
AW
72
73 if( gcode->has_letter('G') ){
74
75 if( gcode->get_value('G') == 92 ){
76
77 if( gcode->has_letter('E') ){
e2b4a32b 78 this->current_position = gcode->get_value('E');
1a2d88eb
AW
79 this->target_position = this->current_position;
80 this->start_position = this->current_position;
81 }
82
436a2cd1 83 }else{
1a2d88eb
AW
84
85 // Extrusion length
86 if( gcode->has_letter('E' )){
87 double extrusion_distance = gcode->get_value('E');
e0aa02f6 88 if( fabs(gcode->millimeters_of_travel) < 0.0001 ){
1a2d88eb
AW
89 this->solo_mode = true;
90 this->travel_distance = extrusion_distance;
e2b4a32b 91 this->travel_ratio = 0.0;
1a2d88eb
AW
92 }else{
93 this->solo_mode = false;
94 this->travel_ratio = extrusion_distance / gcode->millimeters_of_travel;
e2b4a32b 95 this->travel_distance = 0.0;
1a2d88eb
AW
96 }
97 // Else do not extrude
98 }else{
99 this->travel_ratio = 0.0;
100 this->travel_distance = 0.0;
101 }
102
103 }
104
105 }
106
da24d6ae
AW
107}
108
436a2cd1
AW
109
110
4cff3ded
AW
111void Extruder::on_block_begin(void* argument){
112 Block* block = static_cast<Block*>(argument);
1a2d88eb
AW
113
114 if( fabs(this->travel_distance) > 0.001 ){
1a2d88eb
AW
115 block->take(); // In solo mode we take the block so we can move even if the stepper has nothing to do
116 this->current_block = block;
e2b4a32b
AW
117 this->start_position = this->target_position;
118 this->target_position = ( !this->absolute_mode ? this->start_position : 0 ) + this->travel_distance ;
119 //this->acceleration_tick();
1a2d88eb
AW
120 }
121 if( fabs(this->travel_ratio) > 0.001 ){
1a2d88eb
AW
122 // In non-solo mode, we just follow the stepper module
123 this->current_block = block;
e2b4a32b
AW
124 this->start_position = this->target_position;
125 this->target_position = this->start_position + ( this->current_block->millimeters * this->travel_ratio );
126 //this->acceleration_tick();
1a2d88eb 127 }
e2b4a32b
AW
128
129
4cff3ded
AW
130}
131
132void Extruder::on_block_end(void* argument){
133 Block* block = static_cast<Block*>(argument);
134 this->current_block = NULL;
135}
136
137void Extruder::acceleration_tick(){
e2b4a32b 138
4cff3ded
AW
139 // If we are currently taking care of a block
140 if( this->current_block ){
1a2d88eb 141
e2b4a32b
AW
142 this->kernel->serial->printf("tick start_position:%f current_position:%f target_position:%f travel_distance:%f travel_ratio:%f mm:%f \r\n", this->start_position, this->current_position, this->target_position, this->travel_distance, this->travel_ratio, this->current_block->millimeters);
143
1a2d88eb
AW
144 if( fabs(this->travel_ratio) > 0.001 ){
145 double steps_by_acceleration_tick = this->kernel->stepper->trapezoid_adjusted_rate / 60 / this->kernel->stepper->acceleration_ticks_per_second;
146 // Get position along the block at next tick
e2b4a32b
AW
147 if( this->kernel->stepper->current_block != NULL ){
148 this->kernel->stepper->current_block->debug( this->kernel );
149 }else{
150 this->kernel->serial->printf("NULL\r\n");
151 return;
152 }
153 double current_position_ratio = double( (this->kernel->stepper->step_events_completed>>16) ) / double(this->kernel->stepper->current_block->steps_event_count);
154 double next_position_ratio = double( (this->kernel->stepper->step_events_completed>>16) + steps_by_acceleration_tick ) / double(this->kernel->stepper->current_block->steps_event_count);
155 // Ratio differenc
156 double ratio_difference = next_position_ratio - current_position_ratio;
157 // Get total move distance
158 double distance = this->target_position - this->start_position;
159 // Get distance to run until next acceleration tick
160 double desired_distance = distance / ratio_difference;
161 // Get speed
162 double desired_speed = desired_distance * double(this->kernel->stepper->acceleration_ticks_per_second); //TODO : Replace with the actual current_position
163
164 this->kernel->serial->printf("cur_pos:%f tar_pos:%f start_pos:%f steps_by_acc_tick:%f cur_pos_ratio:%f next_pos_ratio:%f ratio_diff:%f dist:%f desired_dist:%f desired_spd:%f \r\n", this->current_position, this->target_position, this->start_position, steps_by_acceleration_tick, current_position_ratio, next_position_ratio, ratio_difference, ratio_difference, distance, desired_distance, desired_speed );
165
1a2d88eb
AW
166
167 if( desired_speed <= 0 ){ return; }
168
169 // Set timer
e2b4a32b 170 LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(desired_speed*201));
1a2d88eb
AW
171
172 // In case we are trying to set the timer to a limit it has already past by
173 if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
174 LPC_TIM1->TCR = 3;
175 LPC_TIM1->TCR = 1;
176 }
177
178 // Update Timer1
179 LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse;
180
181 }
182
183 if( fabs(this->travel_distance) > 0.001 ){
184
185 // Set timer
e2b4a32b 186 LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(200));
1a2d88eb
AW
187
188 // In case we are trying to set the timer to a limit it has already past by
189 if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
190 LPC_TIM1->TCR = 3;
191 LPC_TIM1->TCR = 1;
192 }
193
194 // Update Timer1
195 LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse;
196
4cff3ded
AW
197 }
198
4cff3ded
AW
199 }
200}
201
202inline void Extruder::stepping_tick(){
203 if( this->current_position < this->target_position ){
e2b4a32b 204 this->current_position += double(double(1)/double(201));
4cff3ded
AW
205 this->step_pin = 1;
206 }else{
1a2d88eb
AW
207 // Move finished
208 if( fabs(this->travel_distance) > 0.001 && this->current_block != NULL ){
209 this->current_block->release();
210 }
4cff3ded
AW
211 }
212}
213
214
215