fixing merge conflict
[clinton/Smoothieware.git] / src / libs / StepTicker.cpp
index 38a372f..f6087b6 100644 (file)
@@ -25,14 +25,14 @@ StepTicker* global_step_ticker;
 
 StepTicker::StepTicker(){
     global_step_ticker = this;
-    LPC_TIM0->MR0 = 10000000;        // Initial dummy value for Match Register
+    LPC_TIM0->MR0 = 10000000;       // Initial dummy value for Match Register
     LPC_TIM0->MCR = 3;              // Match on MR0, reset on MR0, match on MR1
-    LPC_TIM0->TCR = 1;               // Enable interrupt
+    LPC_TIM0->TCR = 0;              // Disable interrupt
 
-    LPC_SC->PCONP |= (1 << 2);     // Power Ticker ON
+    LPC_SC->PCONP |= (1 << 2);      // Power Ticker ON
     LPC_TIM1->MR0 = 1000000;
     LPC_TIM1->MCR = 1;
-    LPC_TIM1->TCR = 1;               // Enable interrupt
+    LPC_TIM1->TCR = 1;              // Enable interrupt
 
     // Default start values
     this->moves_finished = false;
@@ -42,8 +42,9 @@ StepTicker::StepTicker(){
     this->set_frequency(0.001);
     this->set_reset_delay(100);
     this->last_duration = 0;
-    for (int i = 0; i < 12; i++)
+    for (int i = 0; i < 12; i++){
         this->active_motors[i] = NULL;
+    }
     this->active_motor_bm = 0;
 
     NVIC_EnableIRQ(TIMER0_IRQn);     // Enable interrupt handler
@@ -78,17 +79,14 @@ StepperMotor* StepTicker::add_stepper_motor(StepperMotor* stepper_motor){
 // Call tick() on each active motor
 inline void StepTicker::tick(){
     _isr_context = true;
-
     int i;
-    uint32_t bm;
-    for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
-    {
-        if (this->active_motor_bm & bm)
-        {
+    uint32_t bm = 1;
+    // We iterate over each active motor 
+    for (i = 0; i < 12; i++, bm <<= 1){
+        if (this->active_motor_bm & bm){
             this->active_motors[i]->tick();
         }
     }
-
     _isr_context = false;
 }
 
@@ -97,21 +95,15 @@ inline void StepTicker::tick(){
 void StepTicker::signal_moves_finished(){
     _isr_context = true;
 
-    int i;
-    uint32_t bm;
-    for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
-    {
-        if (this->active_motor_bm & bm)
-        {
-            if (this->active_motors[i]->is_move_finished)
-            {
-                this->active_motors[i]->signal_move_finished();
-                if (this->active_motors[i]->moving == false)
-                {
-                    if (i > 0)
-                    {
-                        i--;
-                        bm >>= 1;
+    uint16_t bitmask = 1;
+    for ( uint8_t motor = 0; motor < 12; motor++, bitmask <<= 1){
+        if (this->active_motor_bm & bitmask){
+            if(this->active_motors[motor]->is_move_finished){
+                this->active_motors[motor]->signal_move_finished();
+                if(this->active_motors[motor]->moving == false){
+                    if (motor > 0){
+                        motor--;
+                        bitmask >>= 1;
                     }
                 }
             }
@@ -124,6 +116,7 @@ void StepTicker::signal_moves_finished(){
 
 // Reset step pins on all active motors
 inline void StepTicker::reset_tick(){
+    LPC_GPIO3->FIOSET = 1<<25;
     _isr_context = true;
 
     int i;
@@ -135,6 +128,7 @@ inline void StepTicker::reset_tick(){
     }
 
     _isr_context = false;
+    LPC_GPIO3->FIOCLR = 1<<25;
 }
 
 extern "C" void TIMER1_IRQHandler (void){
@@ -150,94 +144,99 @@ extern "C" void TIMER1_IRQHandler (void){
 // The actual interrupt handler where we do all the work
 extern "C" void TIMER0_IRQHandler (void){
 
-    LPC_GPIO1->FIODIR |= 1<<18;
-    LPC_GPIO1->FIOSET = 1<<18;
-
-//     uint32_t initial_tc = LPC_TIM0->TC;
+    LPC_GPIO3->FIODIR |= 1<<25;
+    LPC_GPIO1->FIODIR |= 1<<22;
+    LPC_GPIO1->FIODIR |= 1<<23;
+    LPC_GPIO1->FIODIR |= 1<<30;
+    LPC_GPIO1->FIODIR |= 1<<31;
+    LPC_GPIO1->FIOSET =  1<<22;
 
+    // Reset interrupt register
     LPC_TIM0->IR |= 1 << 0;
 
-    // If no axes enabled, just ignore for now
-    if( global_step_ticker->active_motor_bm == 0 ){
-        LPC_GPIO1->FIOCLR = 1<<18;
-        return;
-    }
-
-    // Do not get out of here before everything is nice and tidy
-    LPC_TIM0->MR0 = 2000000;
-
     // Step pins
-    global_step_ticker->tick();
+    //global_step_ticker->tick();
+    _isr_context = true;
+    uint16_t bitmask = 1;
+    for (uint8_t motor = 0; motor < 12; motor++, bitmask <<= 1){
+        if (global_step_ticker->active_motor_bm & bitmask){
+            global_step_ticker->active_motors[motor]->tick();
+        }
+    }
+    _isr_context = false;
 
     // We may have set a pin on in this tick, now we start the timer to set it off
     if( global_step_ticker->reset_step_pins ){
         LPC_TIM1->TCR = 3;
         LPC_TIM1->TCR = 1;
         global_step_ticker->reset_step_pins = false;
+    }else{
+        // Nothing happened, nothing after this really matters
+        // TODO : This could be a problem when we use Actuators instead of StepperMotors, because this flag is specific to step generation
+        LPC_TIM0->MR0 = global_step_ticker->period;
+        LPC_GPIO1->FIOCLR = 1<<22;
+        return;
     }
-
+    
     // If a move finished in this tick, we have to tell the actuator to act accordingly
-    if( global_step_ticker->moves_finished ){ global_step_ticker->signal_moves_finished(); }
-
-//     uint32_t after_signal = LPC_TIM0->TC;
-
-    // If we went over the duration an interrupt is supposed to last, we have a problem
-    // That can happen tipically when we change blocks, where more than usual computation is done
-    // This can be OK, if we take notice of it, which we do now
-    if( LPC_TIM0->TC > global_step_ticker->period ){ // TODO: remove the size condition
-
-        LPC_GPIO1->FIODIR |= 1<<19;
-        LPC_GPIO1->FIOSET = 1<<19;
+    if( global_step_ticker->moves_finished ){ 
+        // Do not get out of here before everything is nice and tidy
+        LPC_TIM0->MR0 = 2000000;
+        
+        global_step_ticker->signal_moves_finished();
+
+        // If we went over the duration an interrupt is supposed to last, we have a problem
+        // That can happen tipically when we change blocks, where more than usual computation is done
+        // This can be OK, if we take notice of it, which we do now
+        if( LPC_TIM0->TC > global_step_ticker->period ){ // TODO: remove the size condition
+
+            LPC_GPIO1->FIOCLR = 1<<22;
+            uint32_t start_tc = LPC_TIM0->TC;
+            LPC_GPIO1->FIOSET = 1<<22;
+
+            // How many ticks we want to skip ( this does not include the current tick, but we add the time we spent doing this computation last time )
+            uint32_t ticks_to_skip = (  ( LPC_TIM0->TC + global_step_ticker->last_duration ) / global_step_ticker->period );
+
+            // Next step is now to reduce this to how many steps we can *actually* skip
+            uint32_t ticks_we_actually_can_skip = ticks_to_skip;
+
+            int i;
+            uint32_t bm;
+            for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
+            {
+                if (global_step_ticker->active_motor_bm & bm)
+                    ticks_we_actually_can_skip =
+                        min(ticks_we_actually_can_skip,
+                            (uint32_t)((uint64_t)( (uint64_t)global_step_ticker->active_motors[i]->fx_ticks_per_step - (uint64_t)global_step_ticker->active_motors[i]->fx_counter ) >> 32)
+                            );
+            }
 
-       uint32_t start_tc = LPC_TIM0->TC;
+            // Adding to MR0 for this time is not enough, we must also increment the counters ourself artificially
+            for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
+            {
+                if (global_step_ticker->active_motor_bm & bm)
+                    global_step_ticker->active_motors[i]->fx_counter += (uint64_t)((uint64_t)(ticks_we_actually_can_skip)<<32);
+            }
 
-        // How many ticks we want to skip ( this does not include the current tick, but we add the time we spent doing this computation last time )
-        uint32_t ticks_to_skip = (  ( LPC_TIM0->TC + global_step_ticker->last_duration ) / global_step_ticker->period );
+            // When must we have our next MR0 ? ( +1 is here to account that we are actually doing a legit MR0 match here too, not only overtime )
+            LPC_TIM0->MR0 = ( ticks_to_skip + 1 ) * global_step_ticker->period;
 
-        // Next step is now to reduce this to how many steps we can *actually* skip
-        uint32_t ticks_we_actually_can_skip = ticks_to_skip;
+            // This is so that we know how long this computation takes, and we can take it into account next time
+            int difference = (int)(LPC_TIM0->TC) - (int)(start_tc);
+            if( difference > 0 ){ global_step_ticker->last_duration = (uint32_t)difference; }
 
-        int i;
-        uint32_t bm;
-        for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
-        {
-            if (global_step_ticker->active_motor_bm & bm)
-                ticks_we_actually_can_skip =
-                    min(ticks_we_actually_can_skip,
-                        (uint32_t)((uint64_t)( (uint64_t)global_step_ticker->active_motors[i]->fx_ticks_per_step - (uint64_t)global_step_ticker->active_motors[i]->fx_counter ) >> 32)
-                        );
+        }else{
+            LPC_TIM0->MR0 = global_step_ticker->period;
         }
 
-        // Adding to MR0 for this time is not enough, we must also increment the counters ourself artificially
-        for (i = 0, bm = 1; i < 12; i++, bm <<= 1)
-        {
-            if (global_step_ticker->active_motor_bm & bm)
-                global_step_ticker->active_motors[i]->fx_counter += (uint64_t)((uint64_t)(ticks_we_actually_can_skip)<<32);
+        while( LPC_TIM0->TC > LPC_TIM0->MR0 ){
+            LPC_TIM0->MR0 += global_step_ticker->period;
         }
 
-        // When must we have our next MR0 ? ( +1 is here to account that we are actually doing a legit MR0 match here too, not only overtime )
-        // LPC_TIM0->MR0 = ( ticks_we_actually_can_skip + 1 ) * global_step_ticker->period;
-        LPC_TIM0->MR0 = ( ticks_to_skip + 1 ) * global_step_ticker->period;
-
-        // This is so that we know how long this computation takes, and we can take it into account next time
-        int difference = (int)(LPC_TIM0->TC) - (int)(start_tc);
-        if( difference > 0 ){ global_step_ticker->last_duration = (uint32_t)difference; }
-
-        //if( global_step_ticker->last_duration > 2000 || LPC_TIM0->MR0 > 2000 || LPC_TIM0->TC > 2000 || initial_tc > 2000 ){ __debugbreak(); }
-
-        LPC_GPIO1->FIOCLR = 1<<19;
-
-    }else{
-        LPC_TIM0->MR0 = global_step_ticker->period;
     }
 
-    LPC_GPIO1->FIOCLR = 1<<18;
-
-    while( LPC_TIM0->TC > LPC_TIM0->MR0 ){
-        LPC_TIM0->MR0 += global_step_ticker->period;
-    }
-
-    LPC_GPIO1->FIOCLR = 1<<18;
+    LPC_GPIO1->FIOCLR = 1<<22;
 }
 
 
@@ -253,12 +252,24 @@ void StepTicker::add_motor_to_active_list(StepperMotor* motor)
         if (this->active_motors[i] == motor)
         {
             this->active_motor_bm |= bm;
+            // If we have no motor to work on, disable the whole interrupt
+            if( this->active_motor_bm == 0 ){
+                LPC_TIM0->TCR = 0;               // Disable interrupt
+            }else{
+                LPC_TIM0->TCR = 1;               // Enable interrupt
+            }
             return;
         }
         if (this->active_motors[i] == NULL)
         {
             this->active_motors[i] = motor;
             this->active_motor_bm |= bm;
+            // If we have no motor to work on, disable the whole interrupt
+            if( this->active_motor_bm == 0 ){
+                LPC_TIM0->TCR = 0;               // Disable interrupt
+            }else{
+                LPC_TIM0->TCR = 1;               // Enable interrupt
+            }
             return;
         }
     }
@@ -274,6 +285,12 @@ void StepTicker::remove_motor_from_active_list(StepperMotor* motor)
         if (this->active_motors[i] == motor)
         {
             this->active_motor_bm &= ~bm;
+            // If we have no motor to work on, disable the whole interrupt
+            if( this->active_motor_bm == 0 ){
+                LPC_TIM0->TCR = 0;               // Disable interrupt
+            }else{
+                LPC_TIM0->TCR = 1;               // Enable interrupt
+            }
             return;
         }
     }