don;t cal lprintf in play unless -v is specified
[clinton/Smoothieware.git] / src / modules / utils / player / Player.cpp
index 3eb1a32..1d5f8ee 100644 (file)
@@ -17,7 +17,6 @@
 #include "libs/StreamOutput.h"
 #include "Gcode.h"
 #include "checksumm.h"
-#include "Pauser.h"
 #include "Config.h"
 #include "ConfigValue.h"
 #include "SDFAT.h"
@@ -64,6 +63,7 @@ void Player::on_module_loaded()
     this->register_for_event(ON_GET_PUBLIC_DATA);
     this->register_for_event(ON_SET_PUBLIC_DATA);
     this->register_for_event(ON_GCODE_RECEIVED);
+    this->register_for_event(ON_HALT);
 
     this->on_boot_gcode = THEKERNEL->config->value(on_boot_gcode_checksum)->by_default("/sd/on_boot.gcode")->as_string();
     this->on_boot_gcode_enable = THEKERNEL->config->value(on_boot_gcode_enable_checksum)->by_default(true)->as_bool();
@@ -75,6 +75,13 @@ void Player::on_module_loaded()
     this->leave_heaters_on = THEKERNEL->config->value(leave_heaters_on_suspend_checksum)->by_default(false)->as_bool();
 }
 
+void Player::on_halt(void* argument)
+{
+    if(argument == nullptr && this->playing_file ) {
+        abort_command("1", &(StreamOutput::NullStream));
+    }
+}
+
 void Player::on_second_tick(void *)
 {
     if(this->playing_file) this->elapsed_secs++;
@@ -106,7 +113,7 @@ void Player::on_gcode_received(void *argument)
 
         } else if (gcode->m == 23) { // select file
             this->filename = "/sd/" + args; // filename is whatever is in args
-            this->current_stream = &(StreamOutput::NullStream);
+            this->current_stream = nullptr;
 
             if(this->current_file_handler != NULL) {
                 this->playing_file = false;
@@ -164,7 +171,7 @@ void Player::on_gcode_received(void *argument)
                     } else {
                         this->filename = currentfn;
                         this->file_size = old_size;
-                        this->current_stream = &(StreamOutput::NullStream);
+                        this->current_stream = nullptr;
                     }
                 }
             } else {
@@ -177,7 +184,7 @@ void Player::on_gcode_received(void *argument)
         } else if (gcode->m == 32) { // select file and start print
             // Get filename
             this->filename = "/sd/" + args; // filename is whatever is in args including spaces
-            this->current_stream = &(StreamOutput::NullStream);
+            this->current_stream = nullptr;
 
             if(this->current_file_handler != NULL) {
                 this->playing_file = false;
@@ -203,12 +210,24 @@ void Player::on_gcode_received(void *argument)
             this->played_cnt = 0;
             this->elapsed_secs = 0;
 
-        } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant
-            this->suspend_command("", gcode->stream);
+        } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant, M600.1 will leave the heaters on
+            this->suspend_command((gcode->subcode == 1)?"h":"", gcode->stream);
 
         } else if (gcode->m == 601) { // resume print
             this->resume_command("", gcode->stream);
         }
+
+    }else if(gcode->has_g) {
+        if(gcode->g == 28) { // homing cancels suspend
+            if(this->suspended) {
+                // clean up
+                this->suspended= false;
+                THEROBOT->pop_state();
+                this->saved_temperatures.clear();
+                this->was_playing_file= false;
+                this->suspend_loops= 0;
+            }
+        }
     }
 }
 
@@ -271,7 +290,7 @@ void Player::play_command( string parameters, StreamOutput *stream )
 
     // Output to the current stream if we were passed the -v ( verbose ) option
     if( options.find_first_of("Vv") == string::npos ) {
-        this->current_stream = &(StreamOutput::NullStream);
+        this->current_stream = nullptr;
     } else {
         // we send to the kernels stream as it cannot go away
         this->current_stream = THEKERNEL->streams;
@@ -355,9 +374,9 @@ void Player::abort_command( string parameters, StreamOutput *stream )
         THEKERNEL->conveyor->flush_queue();
 
         // now the position will think it is at the last received pos, so we need to do FK to get the actuator position and reset the current position
-        THEKERNEL->robot->reset_position_from_current_actuator_position();
+        THEROBOT->reset_position_from_current_actuator_position();
+        stream->printf("Aborted playing or paused file. Please turn any heaters off manually\r\n");
     }
-    stream->printf("Aborted playing or paused file. Please turn any heaters off manually\r\n");
 }
 
 void Player::on_main_loop(void *argument)
@@ -381,7 +400,6 @@ void Player::on_main_loop(void *argument)
 
     if( this->playing_file ) {
         if(THEKERNEL->is_halted()) {
-            abort_command("1", &(StreamOutput::NullStream));
             return;
         }
 
@@ -398,10 +416,13 @@ void Player::on_main_loop(void *argument)
                 }
                 if(len == 1) continue; // empty line
 
-                this->current_stream->printf("%s", buf);
+                if(this->current_stream != nullptr) {
+                    this->current_stream->printf("%s", buf);
+                }
+
                 struct SerialMessage message;
                 message.message = buf;
-                message.stream = this->current_stream;
+                message.stream = this->current_stream == nullptr ? &(StreamOutput::NullStream) : this->current_stream;
 
                 // waits for the queue to have enough room
                 THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
@@ -410,7 +431,7 @@ void Player::on_main_loop(void *argument)
 
             } else {
                 // discard long line
-                this->current_stream->printf("Warning: Discarded long line\n");
+                if(this->current_stream != nullptr) { this->current_stream->printf("Warning: Discarded long line\n"); }
                 discard = true;
             }
         }
@@ -489,6 +510,9 @@ void Player::suspend_command(string parameters, StreamOutput *stream )
 
     stream->printf("Suspending print, waiting for queue to empty...\n");
 
+    // override the leave_heaters_on setting
+    this->override_leave_heaters_on= (parameters == "h");
+
     suspended= true;
     if( this->playing_file ) {
         // pause an sd print
@@ -510,23 +534,23 @@ void Player::suspend_part2()
     //  need to use streams here as the original stream may have changed
     THEKERNEL->streams->printf("// Waiting for queue to empty (Host must stop sending)...\n");
     // wait for queue to empty
-    THEKERNEL->conveyor->wait_for_empty_queue();
+    THEKERNEL->conveyor->wait_for_idle();
 
     THEKERNEL->streams->printf("// Saving current state...\n");
 
     // save current XYZ position
-    THEKERNEL->robot->get_axis_position(this->saved_position);
+    THEROBOT->get_axis_position(this->saved_position);
 
     // save current extruder state
     PublicData::set_value( extruder_checksum, save_state_checksum, nullptr );
 
     // save state use M120
-    THEKERNEL->robot->push_state();
+    THEROBOT->push_state();
 
     // TODO retract by optional amount...
 
     this->saved_temperatures.clear();
-    if(!this->leave_heaters_on) {
+    if(!this->leave_heaters_on && !this->override_leave_heaters_on) {
         // save current temperatures, get a vector of all the controllers data
         std::vector<struct pad_temperature> controllers;
         bool ok = PublicData::get_value(temperature_control_checksum, poll_controls_checksum, &controllers);
@@ -609,7 +633,7 @@ void Player::resume_command(string parameters, StreamOutput *stream )
             if(THEKERNEL->is_halted()) {
                 // abort temp wait and rest of resume
                 THEKERNEL->streams->printf("Resume aborted by kill\n");
-                THEKERNEL->robot->pop_state();
+                THEROBOT->pop_state();
                 this->saved_temperatures.clear();
                 suspended= false;
                 return;
@@ -628,18 +652,20 @@ void Player::resume_command(string parameters, StreamOutput *stream )
 
     // Restore position
     stream->printf("Restoring saved XYZ positions and state...\n");
-    THEKERNEL->robot->pop_state();
-    bool abs_mode= THEKERNEL->robot->absolute_mode; // what mode we were in
+    THEROBOT->pop_state();
+    bool abs_mode= THEROBOT->absolute_mode; // what mode we were in
     // force absolute mode for restoring position, then set to the saved relative/absolute mode
-    THEKERNEL->robot->absolute_mode= true;
+    THEROBOT->absolute_mode= true;
     {
+        // NOTE position was saved in MCS so must use G53 to restore position
         char buf[128];
-        int n = snprintf(buf, sizeof(buf), "G1 X%f Y%f Z%f", saved_position[0], saved_position[1], saved_position[2]);
-        string g(buf, n);
-        Gcode gcode(g, &(StreamOutput::NullStream));
-        THEKERNEL->call_event(ON_GCODE_RECEIVED, &gcode );
+        snprintf(buf, sizeof(buf), "G53 G0 X%f Y%f Z%f", saved_position[0], saved_position[1], saved_position[2]);
+        struct SerialMessage message;
+        message.message = buf;
+        message.stream = &(StreamOutput::NullStream);
+        THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
     }
-    THEKERNEL->robot->absolute_mode= abs_mode;
+    THEROBOT->absolute_mode= abs_mode;
 
     // restore extruder state
     PublicData::set_value( extruder_checksum, restore_state_checksum, nullptr );