added per-axis speed limit, with config file setting
[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
21Extruder::Extruder(PinName stppin) : step_pin(stppin){}
22
23void Extruder::on_module_loaded() {
f5598f5b
AW
24
25 if( this->kernel->config->value( extruder_module_enable_checksum )->by_default(false)->as_bool() ){ return; }
26
4cff3ded
AW
27 extruder_for_irq = this;
28
29 // Settings
da24d6ae 30 this->on_config_reload(this);
4cff3ded
AW
31
32 // We work on the same Block as Stepper, so we need to know when it gets a new one and drops one
33 this->register_for_event(ON_BLOCK_BEGIN);
34 this->register_for_event(ON_BLOCK_END);
35
36 // Configuration
37 this->acceleration_ticker.attach_us(this, &Extruder::acceleration_tick, 1000000/this->kernel->stepper->acceleration_ticks_per_second);
38
39 this->start_position = 0;
40 this->target_position = 0;
41 this->current_position = 0;
42 this->current_block = NULL;
43
44 // Start Timer1
45 LPC_TIM1->MR0 = 10000;
46 LPC_TIM1->MR1 = 500;
47 LPC_TIM1->MCR = 11; // For MR0 and MR1, with no reset at MR1
48 NVIC_EnableIRQ(TIMER1_IRQn);
49 LPC_TIM1->TCR = 1;
50}
51
da24d6ae 52void Extruder::on_config_reload(void* argument){
b66fb830 53 this->microseconds_per_step_pulse = this->kernel->config->value(microseconds_per_step_pulse_ckeckusm)->by_default(5)->as_number();
da24d6ae
AW
54}
55
4cff3ded
AW
56void Extruder::on_block_begin(void* argument){
57 Block* block = static_cast<Block*>(argument);
58 this->current_block = block;
59 this->start_position = this->current_position;
60 this->target_position = this->start_position + ( this->current_block->millimeters * 159 ); //TODO : Get from config ( extruder_steps_per_mm )
61}
62
63void Extruder::on_block_end(void* argument){
64 Block* block = static_cast<Block*>(argument);
65 this->current_block = NULL;
66}
67
68void Extruder::acceleration_tick(){
69 // If we are currently taking care of a block
70 if( this->current_block ){
71 double steps_by_acceleration_tick = this->kernel->stepper->trapezoid_adjusted_rate / 60 / this->kernel->stepper->acceleration_ticks_per_second;
72 // Get position along the block at next tick
73 double next_position_ratio = ( this->kernel->stepper->step_events_completed + steps_by_acceleration_tick ) / this->kernel->stepper->current_block->steps_event_count;
74 // Get wanted next position
75 double next_absolute_position = ( this->target_position - this->start_position ) * next_position_ratio;
76 // Get desired speed in steps per minute to get to the next position by the next acceleration tick
77 double desired_speed = ( ( next_absolute_position + this->start_position ) - this->current_position ) * double(this->kernel->stepper->acceleration_ticks_per_second) * 60L; //TODO : Replace with the actual current_position
78
79 // Set timer
80 LPC_TIM1->MR0 = ((SystemCoreClock/4)*60)/int(floor(desired_speed));
81
82 // In case we are trying to set the timer to a limit it has already past by
83 if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){
84 LPC_TIM1->TCR = 3;
85 LPC_TIM1->TCR = 1;
86 }
87
88 // Update Timer1
89 LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse;
90 }
91}
92
93inline void Extruder::stepping_tick(){
94 if( this->current_position < this->target_position ){
95 this->current_position++;
96 this->step_pin = 1;
97 }else{
98 if( this->current_block == NULL ){
99 //this->stepping_ticker.detach();
100 }
101 }
102}
103
104
105