@ -95,7 +95,7 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even
volatile unsigned char Stepper : : eISR_Rate = 200 ; // Keep the ISR at a low rate until needed
volatile unsigned char Stepper : : eISR_Rate = 200 ; // Keep the ISR at a low rate until needed
# if ENABLED(LIN_ADVANCE)
# if ENABLED(LIN_ADVANCE)
volatile long Stepper : : e_steps [ E_STEPPERS ] ;
volatile int Stepper : : e_steps [ E_STEPPERS ] ;
int Stepper : : extruder_advance_k = LIN_ADVANCE_K ,
int Stepper : : extruder_advance_k = LIN_ADVANCE_K ,
Stepper : : final_estep_rate ,
Stepper : : final_estep_rate ,
Stepper : : current_estep_rate [ E_STEPPERS ] ,
Stepper : : current_estep_rate [ E_STEPPERS ] ,
@ -311,8 +311,20 @@ void Stepper::set_directions() {
# endif // !ADVANCE && !LIN_ADVANCE
# endif // !ADVANCE && !LIN_ADVANCE
}
}
// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
/**
// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
* Stepper Driver Interrupt
*
* Directly pulses the stepper motors at high frequency .
* Timer 1 runs at a base frequency of 2 MHz , with this ISR using OCR1A compare mode .
*
* OCR1A Frequency
* 1 2 MHz
* 50 40 KHz
* 100 20 KHz - capped max rate
* 200 10 KHz - nominal max rate
* 2000 1 KHz - sleep rate
* 4000 500 Hz - init rate
*/
ISR ( TIMER1_COMPA_vect ) { Stepper : : isr ( ) ; }
ISR ( TIMER1_COMPA_vect ) { Stepper : : isr ( ) ; }
void Stepper : : isr ( ) {
void Stepper : : isr ( ) {
@ -323,7 +335,7 @@ void Stepper::isr() {
if ( ( cleaning_buffer_counter = = 1 ) & & ( SD_FINISHED_STEPPERRELEASE ) ) enqueue_and_echo_commands_P ( PSTR ( SD_FINISHED_RELEASECOMMAND ) ) ;
if ( ( cleaning_buffer_counter = = 1 ) & & ( SD_FINISHED_STEPPERRELEASE ) ) enqueue_and_echo_commands_P ( PSTR ( SD_FINISHED_RELEASECOMMAND ) ) ;
# endif
# endif
cleaning_buffer_counter - - ;
cleaning_buffer_counter - - ;
OCR1A = 200 ;
OCR1A = 200 ; // Run at max speed - 10 KHz
return ;
return ;
}
}
@ -348,7 +360,7 @@ void Stepper::isr() {
# if ENABLED(Z_LATE_ENABLE)
# if ENABLED(Z_LATE_ENABLE)
if ( current_block - > steps [ Z_AXIS ] > 0 ) {
if ( current_block - > steps [ Z_AXIS ] > 0 ) {
enable_z ( ) ;
enable_z ( ) ;
OCR1A = 2000 ; // 1ms wait
OCR1A = 2000 ; // Run at slow speed - 1 KHz
return ;
return ;
}
}
# endif
# endif
@ -358,7 +370,7 @@ void Stepper::isr() {
// #endif
// #endif
}
}
else {
else {
OCR1A = 2000 ; // 1kHz.
OCR1A = 2000 ; // Run at slow speed - 1 KHz
return ;
return ;
}
}
}
}
@ -391,7 +403,7 @@ void Stepper::isr() {
# if ENABLED(MIXING_EXTRUDER)
# if ENABLED(MIXING_EXTRUDER)
// Step mixing steppers proportionally
// Step mixing steppers proportionally
bool dir = motor_direction ( E_AXIS ) ;
const bool dir = motor_direction ( E_AXIS ) ;
MIXING_STEPPERS_LOOP ( j ) {
MIXING_STEPPERS_LOOP ( j ) {
counter_m [ j ] + = current_block - > steps [ E_AXIS ] ;
counter_m [ j ] + = current_block - > steps [ E_AXIS ] ;
if ( counter_m [ j ] > 0 ) {
if ( counter_m [ j ] > 0 ) {
@ -401,22 +413,6 @@ void Stepper::isr() {
}
}
# endif
# endif
if ( current_block - > use_advance_lead ) {
int delta_adv_steps = ( ( ( long ) extruder_advance_k * current_estep_rate [ TOOL_E_INDEX ] ) > > 9 ) - current_adv_steps [ TOOL_E_INDEX ] ;
# if ENABLED(MIXING_EXTRUDER)
// Mixing extruders apply advance lead proportionally
MIXING_STEPPERS_LOOP ( j ) {
int steps = delta_adv_steps * current_block - > step_event_count / current_block - > mix_event_count [ j ] ;
e_steps [ j ] + = steps ;
current_adv_steps [ j ] + = steps ;
}
# else
// For most extruders, advance the single E stepper
e_steps [ TOOL_E_INDEX ] + = delta_adv_steps ;
current_adv_steps [ TOOL_E_INDEX ] + = delta_adv_steps ;
# endif
}
# elif ENABLED(ADVANCE)
# elif ENABLED(ADVANCE)
// Always count the unified E axis
// Always count the unified E axis
@ -432,7 +428,7 @@ void Stepper::isr() {
# if ENABLED(MIXING_EXTRUDER)
# if ENABLED(MIXING_EXTRUDER)
// Step mixing steppers proportionally
// Step mixing steppers proportionally
bool dir = motor_direction ( E_AXIS ) ;
const bool dir = motor_direction ( E_AXIS ) ;
MIXING_STEPPERS_LOOP ( j ) {
MIXING_STEPPERS_LOOP ( j ) {
counter_m [ j ] + = current_block - > steps [ E_AXIS ] ;
counter_m [ j ] + = current_block - > steps [ E_AXIS ] ;
if ( counter_m [ j ] > 0 ) {
if ( counter_m [ j ] > 0 ) {
@ -536,6 +532,21 @@ void Stepper::isr() {
}
}
}
}
# if ENABLED(LIN_ADVANCE)
if ( current_block - > use_advance_lead ) {
int delta_adv_steps = ( ( ( long ) extruder_advance_k * current_estep_rate [ TOOL_E_INDEX ] ) > > 9 ) - current_adv_steps [ TOOL_E_INDEX ] ;
current_adv_steps [ TOOL_E_INDEX ] + = delta_adv_steps ;
# if ENABLED(MIXING_EXTRUDER)
// Mixing extruders apply advance lead proportionally
MIXING_STEPPERS_LOOP ( j )
e_steps [ j ] + = delta_adv_steps * current_block - > step_event_count / current_block - > mix_event_count [ j ] ;
# else
// For most extruders, advance the single E stepper
e_steps [ TOOL_E_INDEX ] + = delta_adv_steps ;
# endif
}
# endif
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
// If we have esteps to execute, fire the next advance_isr "now"
// If we have esteps to execute, fire the next advance_isr "now"
if ( e_steps [ TOOL_E_INDEX ] ) OCR0A = TCNT0 + 2 ;
if ( e_steps [ TOOL_E_INDEX ] ) OCR0A = TCNT0 + 2 ;
@ -593,7 +604,7 @@ void Stepper::isr() {
# endif // ADVANCE or LIN_ADVANCE
# endif // ADVANCE or LIN_ADVANCE
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
eISR_Rate = ( timer > > 2 ) * step_loops / abs ( e_steps [ TOOL_E_INDEX ] ) ;
eISR_Rate = ( timer > > 3 ) * step_loops / abs ( e_steps [ TOOL_E_INDEX ] ) ; //>> 3 is divide by 8. Reason: Timer 0 runs at 16/8=2MHz, Timer 1 at 16/64=0.25MHz. ==> 2/0.25=8.
# endif
# endif
}
}
else if ( step_events_completed > ( uint32_t ) current_block - > decelerate_after ) {
else if ( step_events_completed > ( uint32_t ) current_block - > decelerate_after ) {
@ -643,7 +654,7 @@ void Stepper::isr() {
# endif // ADVANCE or LIN_ADVANCE
# endif // ADVANCE or LIN_ADVANCE
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
# if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
eISR_Rate = ( timer > > 2 ) * step_loops / abs ( e_steps [ TOOL_E_INDEX ] ) ;
eISR_Rate = ( timer > > 3 ) * step_loops / abs ( e_steps [ TOOL_E_INDEX ] ) ;
# endif
# endif
}
}
else {
else {
@ -653,7 +664,7 @@ void Stepper::isr() {
if ( current_block - > use_advance_lead )
if ( current_block - > use_advance_lead )
current_estep_rate [ TOOL_E_INDEX ] = final_estep_rate ;
current_estep_rate [ TOOL_E_INDEX ] = final_estep_rate ;
eISR_Rate = ( OCR1A_nominal > > 2 ) * step_loops_nominal / abs ( e_steps [ TOOL_E_INDEX ] ) ;
eISR_Rate = ( OCR1A_nominal > > 3 ) * step_loops_nominal / abs ( e_steps [ TOOL_E_INDEX ] ) ;
# endif
# endif
@ -904,6 +915,7 @@ void Stepper::init() {
// output mode = 00 (disconnected)
// output mode = 00 (disconnected)
TCCR1A & = ~ ( 3 < < COM1A0 ) ;
TCCR1A & = ~ ( 3 < < COM1A0 ) ;
TCCR1A & = ~ ( 3 < < COM1B0 ) ;
TCCR1A & = ~ ( 3 < < COM1B0 ) ;
// Set the timer pre-scaler
// Set the timer pre-scaler
// Generally we use a divider of 8, resulting in a 2MHz timer
// Generally we use a divider of 8, resulting in a 2MHz timer
// frequency on a 16MHz MCU. If you are going to change this, be
// frequency on a 16MHz MCU. If you are going to change this, be
@ -911,6 +923,7 @@ void Stepper::init() {
// create_speed_lookuptable.py
// create_speed_lookuptable.py
TCCR1B = ( TCCR1B & ~ ( 0x07 < < CS10 ) ) | ( 2 < < CS10 ) ;
TCCR1B = ( TCCR1B & ~ ( 0x07 < < CS10 ) ) | ( 2 < < CS10 ) ;
// Init Stepper ISR to 122 Hz for quick starting
OCR1A = 0x4000 ;
OCR1A = 0x4000 ;
TCNT1 = 0 ;
TCNT1 = 0 ;
ENABLE_STEPPER_DRIVER_INTERRUPT ( ) ;
ENABLE_STEPPER_DRIVER_INTERRUPT ( ) ;