Merge branch 'player' into edge
[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
da24d6ae 55void Extruder::on_config_reload(void* argument){
436a2cd1
AW
56 this->microseconds_per_step_pulse = 5; //this->kernel->config->value(microseconds_per_step_pulse_ckeckusm)->by_default(5)->as_number();
57}
58
59// Computer extrusion speed based on parameters and gcode distance of travel
60void Extruder::on_gcode_execute(void* argument){
61 Gcode* gcode = static_cast<Gcode*>(argument);
62
63 // Absolute/relative mode
64 if( gcode->has_letter('M')){
65 int code = gcode->get_value('M');
66 if( code == 82 ){ this->absolute_mode == true; }
67 if( code == 83 ){ this->absolute_mode == false; }
68 }
69
70 // Extrusion length
71 if( gcode->has_letter('E' )){
72 double extrusion_distance = gcode->get_value('E');
73 //this->kernel->serial->printf("extrusion_distance: %f, millimeters_of_travel: %f\r\n", extrusion_distance, gcode->millimeters_of_travel);
74 if( gcode->millimeters_of_travel == 0.0 ){
75 this->solo_mode = true;
76 this->travel_distance = extrusion_distance;
77 //this->kernel->serial->printf("solo mode distance: %f\r\n", this->travel_distance );
78 }else{
79 this->solo_mode = false;
80 this->travel_ratio = extrusion_distance / gcode->millimeters_of_travel;
81 //this->kernel->serial->printf("follow mode ratio: %f\r\n", this->travel_ratio);
82 }
83 }else{
84 this->travel_ratio = 0;
85 }
da24d6ae
AW
86}
87
436a2cd1
AW
88
89
4cff3ded
AW
90void Extruder::on_block_begin(void* argument){
91 Block* block = static_cast<Block*>(argument);
92 this->current_block = block;
436a2cd1 93 //this->kernel->serial->printf("block: solomode: %d, travel_distance: %f, travel_ratio: %f \r\n", this->solo_mode, this->travel_distance, this->travel_ratio);
4cff3ded 94 this->start_position = this->current_position;
436a2cd1
AW
95 this->target_position = this->start_position + ( this->current_block->millimeters * this->travel_ratio * 159 ); //TODO : Get from config ( extruder_steps_per_mm )
96 this->acceleration_tick();
4cff3ded
AW
97}
98
99void Extruder::on_block_end(void* argument){
100 Block* block = static_cast<Block*>(argument);
101 this->current_block = NULL;
102}
103
104void Extruder::acceleration_tick(){
105 // If we are currently taking care of a block
106 if( this->current_block ){
107 double steps_by_acceleration_tick = this->kernel->stepper->trapezoid_adjusted_rate / 60 / this->kernel->stepper->acceleration_ticks_per_second;
108 // Get position along the block at next tick
436a2cd1
AW
109 double current_position_ratio = double( (this->kernel->stepper->step_events_completed>>16) ) / double(this->kernel->stepper->current_block->steps_event_count);
110 double next_position_ratio = ( (this->kernel->stepper->step_events_completed>>16) + steps_by_acceleration_tick ) / this->kernel->stepper->current_block->steps_event_count;
4cff3ded
AW
111 // Get wanted next position
112 double next_absolute_position = ( this->target_position - this->start_position ) * next_position_ratio;
113 // Get desired speed in steps per minute to get to the next position by the next acceleration tick
436a2cd1
AW
114 double desired_speed = ( ( next_absolute_position + this->start_position ) - this->current_position ) * double(this->kernel->stepper->acceleration_ticks_per_second); //TODO : Replace with the actual current_position
115
116 //this->kernel->serial->printf("stp->sec: %d, stp->cb->secnt: %u, sbat: %.4f, npr: %.4f, ds: %f --> tap: %u, nap: %f, sp: %u, cp: %u, (tp-sp): %d, cpr: %f\r\n", this->kernel->stepper->step_events_completed>>16, this->kernel->stepper->current_block->steps_event_count, steps_by_acceleration_tick, next_position_ratio, desired_speed,this->target_position, next_absolute_position, this->start_position, this->current_position, int(this->target_position-this->start_position), current_position_ratio );
117
118 if( desired_speed <= 0 ){ return; }
4cff3ded
AW
119
120 // Set timer
436a2cd1 121 LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(desired_speed));
4cff3ded
AW
122
123 // In case we are trying to set the timer to a limit it has already past by
124 if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
125 LPC_TIM1->TCR = 3;
126 LPC_TIM1->TCR = 1;
127 }
128
129 // Update Timer1
130 LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse;
131 }
132}
133
134inline void Extruder::stepping_tick(){
135 if( this->current_position < this->target_position ){
136 this->current_position++;
137 this->step_pin = 1;
138 }else{
139 if( this->current_block == NULL ){
140 //this->stepping_ticker.detach();
141 }
142 }
143}
144
145
146