Michael Spencer / Smoothie

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Update to latest Smoothie.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 /*
Michael J. Spencer 2:1df0b61d3b5a 2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
Michael J. Spencer 2:1df0b61d3b5a 3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Michael J. Spencer 2:1df0b61d3b5a 4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Michael J. Spencer 2:1df0b61d3b5a 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
Michael J. Spencer 2:1df0b61d3b5a 6 */
Michael J. Spencer 2:1df0b61d3b5a 7
Michael J. Spencer 2:1df0b61d3b5a 8
Michael J. Spencer 2:1df0b61d3b5a 9 #include "libs/Kernel.h"
Michael J. Spencer 2:1df0b61d3b5a 10 #include "Player.h"
Michael J. Spencer 2:1df0b61d3b5a 11 #include "libs/nuts_bolts.h"
Michael J. Spencer 2:1df0b61d3b5a 12 #include "libs/utils.h"
Michael J. Spencer 2:1df0b61d3b5a 13 #include "libs/SerialMessage.h"
Michael J. Spencer 2:1df0b61d3b5a 14 #include "libs/StreamOutput.h"
Michael J. Spencer 2:1df0b61d3b5a 15 #include "modules/robot/Conveyor.h"
Michael J. Spencer 2:1df0b61d3b5a 16 #include "DirHandle.h"
Michael J. Spencer 2:1df0b61d3b5a 17 #include "PublicDataRequest.h"
Michael J. Spencer 2:1df0b61d3b5a 18 #include "PlayerPublicAccess.h"
Michael J. Spencer 2:1df0b61d3b5a 19
Michael J. Spencer 2:1df0b61d3b5a 20 #define play_command_checksum CHECKSUM("play")
Michael J. Spencer 2:1df0b61d3b5a 21 #define progress_command_checksum CHECKSUM("progress")
Michael J. Spencer 2:1df0b61d3b5a 22 #define abort_command_checksum CHECKSUM("abort")
Michael J. Spencer 2:1df0b61d3b5a 23 #define on_boot_gcode_checksum CHECKSUM("on_boot_gcode")
Michael J. Spencer 2:1df0b61d3b5a 24 #define on_boot_gcode_enable_checksum CHECKSUM("on_boot_gcode_enable")
Michael J. Spencer 2:1df0b61d3b5a 25
Michael J. Spencer 2:1df0b61d3b5a 26 void Player::on_module_loaded(){
Michael J. Spencer 2:1df0b61d3b5a 27 this->playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 28 this->booted = false;
Michael J. Spencer 2:1df0b61d3b5a 29 this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
Michael J. Spencer 2:1df0b61d3b5a 30 this->register_for_event(ON_MAIN_LOOP);
Michael J. Spencer 2:1df0b61d3b5a 31 this->register_for_event(ON_SECOND_TICK);
Michael J. Spencer 2:1df0b61d3b5a 32 this->register_for_event(ON_GET_PUBLIC_DATA);
Michael J. Spencer 2:1df0b61d3b5a 33 this->register_for_event(ON_SET_PUBLIC_DATA);
Michael J. Spencer 2:1df0b61d3b5a 34 this->register_for_event(ON_GCODE_RECEIVED);
Michael J. Spencer 2:1df0b61d3b5a 35
Michael J. Spencer 2:1df0b61d3b5a 36 this->on_boot_gcode = THEKERNEL->config->value(on_boot_gcode_checksum)->by_default("/sd/on_boot.gcode")->as_string();
Michael J. Spencer 2:1df0b61d3b5a 37 this->on_boot_gcode_enable = THEKERNEL->config->value(on_boot_gcode_enable_checksum)->by_default(true)->as_bool();
Michael J. Spencer 2:1df0b61d3b5a 38 this->elapsed_secs= 0;
Michael J. Spencer 2:1df0b61d3b5a 39 this->reply_stream= NULL;
Michael J. Spencer 2:1df0b61d3b5a 40 }
Michael J. Spencer 2:1df0b61d3b5a 41
Michael J. Spencer 2:1df0b61d3b5a 42 void Player::on_second_tick(void*) {
Michael J. Spencer 2:1df0b61d3b5a 43 if (!THEKERNEL->pauser->paused()) this->elapsed_secs++;
Michael J. Spencer 2:1df0b61d3b5a 44 }
Michael J. Spencer 2:1df0b61d3b5a 45
Michael J. Spencer 2:1df0b61d3b5a 46 void Player::on_gcode_received(void *argument) {
Michael J. Spencer 2:1df0b61d3b5a 47 Gcode *gcode = static_cast<Gcode*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 48 string args= get_arguments(gcode->command);
Michael J. Spencer 2:1df0b61d3b5a 49 if (gcode->has_m) {
Michael J. Spencer 2:1df0b61d3b5a 50 if (gcode->m == 21) { // Dummy code; makes Octoprint happy -- supposed to initialize SD card
Michael J. Spencer 2:1df0b61d3b5a 51 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 52 gcode->stream->printf("SD card ok\r\n");
Michael J. Spencer 2:1df0b61d3b5a 53
Michael J. Spencer 2:1df0b61d3b5a 54 }else if (gcode->m == 23) { // select file
Michael J. Spencer 2:1df0b61d3b5a 55 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 56 // Get filename
Michael J. Spencer 2:1df0b61d3b5a 57 this->filename= "/sd/" + shift_parameter( args );
Michael J. Spencer 2:1df0b61d3b5a 58 this->current_stream = &(StreamOutput::NullStream);
Michael J. Spencer 2:1df0b61d3b5a 59
Michael J. Spencer 2:1df0b61d3b5a 60 if(this->current_file_handler != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 61 this->playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 62 fclose(this->current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 63 }
Michael J. Spencer 2:1df0b61d3b5a 64 this->current_file_handler = fopen( this->filename.c_str(), "r");
Michael J. Spencer 2:1df0b61d3b5a 65
Michael J. Spencer 2:1df0b61d3b5a 66 if(this->current_file_handler == NULL){
Michael J. Spencer 2:1df0b61d3b5a 67 gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
Michael J. Spencer 2:1df0b61d3b5a 68 return;
Michael J. Spencer 2:1df0b61d3b5a 69
Michael J. Spencer 2:1df0b61d3b5a 70 }else{
Michael J. Spencer 2:1df0b61d3b5a 71 // get size of file
Michael J. Spencer 2:1df0b61d3b5a 72 int result = fseek(this->current_file_handler, 0, SEEK_END);
Michael J. Spencer 2:1df0b61d3b5a 73 if (0 != result){
Michael J. Spencer 2:1df0b61d3b5a 74 this->file_size= 0;
Michael J. Spencer 2:1df0b61d3b5a 75 }else{
Michael J. Spencer 2:1df0b61d3b5a 76 this->file_size= ftell(this->current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 77 fseek(this->current_file_handler, 0, SEEK_SET);
Michael J. Spencer 2:1df0b61d3b5a 78 }
Michael J. Spencer 2:1df0b61d3b5a 79 gcode->stream->printf("File opened:%s Size:%ld\r\n", this->filename.c_str(), this->file_size);
Michael J. Spencer 2:1df0b61d3b5a 80 gcode->stream->printf("File selected\r\n");
Michael J. Spencer 2:1df0b61d3b5a 81 }
Michael J. Spencer 2:1df0b61d3b5a 82
Michael J. Spencer 2:1df0b61d3b5a 83
Michael J. Spencer 2:1df0b61d3b5a 84 this->played_cnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 85 this->elapsed_secs= 0;
Michael J. Spencer 2:1df0b61d3b5a 86
Michael J. Spencer 2:1df0b61d3b5a 87 }else if (gcode->m == 24) { // start print
Michael J. Spencer 2:1df0b61d3b5a 88 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 89 if (this->current_file_handler != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 90 this->playing_file = true;
Michael J. Spencer 2:1df0b61d3b5a 91 // this would be a problem if the stream goes away before the file has finished,
Michael J. Spencer 2:1df0b61d3b5a 92 // so we attach it to the kernel stream, however network connections from pronterface
Michael J. Spencer 2:1df0b61d3b5a 93 // do not connect to the kernel streams so won't see this FIXME
Michael J. Spencer 2:1df0b61d3b5a 94 this->reply_stream= THEKERNEL->streams;
Michael J. Spencer 2:1df0b61d3b5a 95 }
Michael J. Spencer 2:1df0b61d3b5a 96
Michael J. Spencer 2:1df0b61d3b5a 97 }else if (gcode->m == 25) { // pause print
Michael J. Spencer 2:1df0b61d3b5a 98 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 99 this->playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 100
Michael J. Spencer 2:1df0b61d3b5a 101 }else if (gcode->m == 26) { // Reset print. Slightly different than M26 in Marlin and the rest
Michael J. Spencer 2:1df0b61d3b5a 102 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 103 if(this->current_file_handler != NULL){
Michael J. Spencer 2:1df0b61d3b5a 104 string currentfn= this->filename.c_str();
Michael J. Spencer 2:1df0b61d3b5a 105 unsigned long old_size= this->file_size;
Michael J. Spencer 2:1df0b61d3b5a 106
Michael J. Spencer 2:1df0b61d3b5a 107 // abort the print
Michael J. Spencer 2:1df0b61d3b5a 108 abort_command("", gcode->stream);
Michael J. Spencer 2:1df0b61d3b5a 109
Michael J. Spencer 2:1df0b61d3b5a 110 if(!currentfn.empty()) {
Michael J. Spencer 2:1df0b61d3b5a 111 // reload the last file opened
Michael J. Spencer 2:1df0b61d3b5a 112 this->current_file_handler = fopen(currentfn.c_str() , "r");
Michael J. Spencer 2:1df0b61d3b5a 113
Michael J. Spencer 2:1df0b61d3b5a 114 if(this->current_file_handler == NULL){
Michael J. Spencer 2:1df0b61d3b5a 115 gcode->stream->printf("file.open failed: %s\r\n", currentfn.c_str());
Michael J. Spencer 2:1df0b61d3b5a 116 }else{
Michael J. Spencer 2:1df0b61d3b5a 117 this->filename= currentfn;
Michael J. Spencer 2:1df0b61d3b5a 118 this->file_size= old_size;
Michael J. Spencer 2:1df0b61d3b5a 119 this->current_stream = &(StreamOutput::NullStream);
Michael J. Spencer 2:1df0b61d3b5a 120 }
Michael J. Spencer 2:1df0b61d3b5a 121 }
Michael J. Spencer 2:1df0b61d3b5a 122
Michael J. Spencer 2:1df0b61d3b5a 123 }else{
Michael J. Spencer 2:1df0b61d3b5a 124 gcode->stream->printf("No file loaded\r\n");
Michael J. Spencer 2:1df0b61d3b5a 125 }
Michael J. Spencer 2:1df0b61d3b5a 126
Michael J. Spencer 2:1df0b61d3b5a 127 }else if (gcode->m == 27) { // report print progress, in format used by Marlin
Michael J. Spencer 2:1df0b61d3b5a 128 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 129 progress_command("-b", gcode->stream);
Michael J. Spencer 2:1df0b61d3b5a 130
Michael J. Spencer 2:1df0b61d3b5a 131 }else if (gcode->m == 32) { // select file and start print
Michael J. Spencer 2:1df0b61d3b5a 132 gcode->mark_as_taken();
Michael J. Spencer 2:1df0b61d3b5a 133 // Get filename
Michael J. Spencer 2:1df0b61d3b5a 134 this->filename= "/sd/" + shift_parameter( args );
Michael J. Spencer 2:1df0b61d3b5a 135 this->current_stream = &(StreamOutput::NullStream);
Michael J. Spencer 2:1df0b61d3b5a 136
Michael J. Spencer 2:1df0b61d3b5a 137 if(this->current_file_handler != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 138 this->playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 139 fclose(this->current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 140 }
Michael J. Spencer 2:1df0b61d3b5a 141
Michael J. Spencer 2:1df0b61d3b5a 142 this->current_file_handler = fopen( this->filename.c_str(), "r");
Michael J. Spencer 2:1df0b61d3b5a 143 if(this->current_file_handler == NULL){
Michael J. Spencer 2:1df0b61d3b5a 144 gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
Michael J. Spencer 2:1df0b61d3b5a 145 }else{
Michael J. Spencer 2:1df0b61d3b5a 146 this->playing_file = true;
Michael J. Spencer 2:1df0b61d3b5a 147 }
Michael J. Spencer 2:1df0b61d3b5a 148 }
Michael J. Spencer 2:1df0b61d3b5a 149 }
Michael J. Spencer 2:1df0b61d3b5a 150 }
Michael J. Spencer 2:1df0b61d3b5a 151
Michael J. Spencer 2:1df0b61d3b5a 152
Michael J. Spencer 2:1df0b61d3b5a 153 // When a new line is received, check if it is a command, and if it is, act upon it
Michael J. Spencer 2:1df0b61d3b5a 154 void Player::on_console_line_received( void* argument ){
Michael J. Spencer 2:1df0b61d3b5a 155 SerialMessage new_message = *static_cast<SerialMessage*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 156
Michael J. Spencer 2:1df0b61d3b5a 157 // ignore comments
Michael J. Spencer 2:1df0b61d3b5a 158 if(new_message.message[0] == ';') return;
Michael J. Spencer 2:1df0b61d3b5a 159
Michael J. Spencer 2:1df0b61d3b5a 160 string possible_command = new_message.message;
Michael J. Spencer 2:1df0b61d3b5a 161
Michael J. Spencer 2:1df0b61d3b5a 162 //new_message.stream->printf("Received %s\r\n", possible_command.c_str());
Michael J. Spencer 2:1df0b61d3b5a 163
Michael J. Spencer 2:1df0b61d3b5a 164 // We don't compare to a string but to a checksum of that string, this saves some space in flash memory
Michael J. Spencer 2:1df0b61d3b5a 165 unsigned short check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient
Michael J. Spencer 2:1df0b61d3b5a 166
Michael J. Spencer 2:1df0b61d3b5a 167 // Act depending on command
Michael J. Spencer 2:1df0b61d3b5a 168 if (check_sum == play_command_checksum)
Michael J. Spencer 2:1df0b61d3b5a 169 this->play_command( get_arguments(possible_command), new_message.stream );
Michael J. Spencer 2:1df0b61d3b5a 170 else if (check_sum == progress_command_checksum)
Michael J. Spencer 2:1df0b61d3b5a 171 this->progress_command(get_arguments(possible_command),new_message.stream );
Michael J. Spencer 2:1df0b61d3b5a 172 else if (check_sum == abort_command_checksum)
Michael J. Spencer 2:1df0b61d3b5a 173 this->abort_command(get_arguments(possible_command),new_message.stream );
Michael J. Spencer 2:1df0b61d3b5a 174 }
Michael J. Spencer 2:1df0b61d3b5a 175
Michael J. Spencer 2:1df0b61d3b5a 176 // Play a gcode file by considering each line as if it was received on the serial console
Michael J. Spencer 2:1df0b61d3b5a 177 void Player::play_command( string parameters, StreamOutput* stream ){
Michael J. Spencer 2:1df0b61d3b5a 178
Michael J. Spencer 2:1df0b61d3b5a 179 // Get filename
Michael J. Spencer 2:1df0b61d3b5a 180 this->filename = absolute_from_relative(shift_parameter( parameters ));
Michael J. Spencer 2:1df0b61d3b5a 181 string options = shift_parameter( parameters );
Michael J. Spencer 2:1df0b61d3b5a 182
Michael J. Spencer 2:1df0b61d3b5a 183 this->current_file_handler = fopen( this->filename.c_str(), "r");
Michael J. Spencer 2:1df0b61d3b5a 184 if(this->current_file_handler == NULL){
Michael J. Spencer 2:1df0b61d3b5a 185 stream->printf("File not found: %s\r\n", this->filename.c_str());
Michael J. Spencer 2:1df0b61d3b5a 186 return;
Michael J. Spencer 2:1df0b61d3b5a 187 }
Michael J. Spencer 2:1df0b61d3b5a 188
Michael J. Spencer 2:1df0b61d3b5a 189 stream->printf("Playing %s\r\n", this->filename.c_str());
Michael J. Spencer 2:1df0b61d3b5a 190
Michael J. Spencer 2:1df0b61d3b5a 191 this->playing_file = true;
Michael J. Spencer 2:1df0b61d3b5a 192
Michael J. Spencer 2:1df0b61d3b5a 193 // Output to the current stream if we were passed the -v ( verbose ) option
Michael J. Spencer 2:1df0b61d3b5a 194 if( options.find_first_of("Vv") == string::npos ){
Michael J. Spencer 2:1df0b61d3b5a 195 this->current_stream = &(StreamOutput::NullStream);
Michael J. Spencer 2:1df0b61d3b5a 196 }else{
Michael J. Spencer 2:1df0b61d3b5a 197 // we send to the kernels stream as it cannot go away
Michael J. Spencer 2:1df0b61d3b5a 198 this->current_stream = THEKERNEL->streams;
Michael J. Spencer 2:1df0b61d3b5a 199 }
Michael J. Spencer 2:1df0b61d3b5a 200
Michael J. Spencer 2:1df0b61d3b5a 201 // get size of file
Michael J. Spencer 2:1df0b61d3b5a 202 int result = fseek(this->current_file_handler, 0, SEEK_END);
Michael J. Spencer 2:1df0b61d3b5a 203 if (0 != result){
Michael J. Spencer 2:1df0b61d3b5a 204 stream->printf("WARNING - Could not get file size\r\n");
Michael J. Spencer 2:1df0b61d3b5a 205 file_size= 0;
Michael J. Spencer 2:1df0b61d3b5a 206 }else{
Michael J. Spencer 2:1df0b61d3b5a 207 file_size= ftell(this->current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 208 fseek(this->current_file_handler, 0, SEEK_SET);
Michael J. Spencer 2:1df0b61d3b5a 209 stream->printf(" File size %ld\r\n", file_size);
Michael J. Spencer 2:1df0b61d3b5a 210 }
Michael J. Spencer 2:1df0b61d3b5a 211 this->played_cnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 212 this->elapsed_secs= 0;
Michael J. Spencer 2:1df0b61d3b5a 213 }
Michael J. Spencer 2:1df0b61d3b5a 214
Michael J. Spencer 2:1df0b61d3b5a 215 void Player::progress_command( string parameters, StreamOutput* stream ){
Michael J. Spencer 2:1df0b61d3b5a 216
Michael J. Spencer 2:1df0b61d3b5a 217 // get options
Michael J. Spencer 2:1df0b61d3b5a 218 string options = shift_parameter( parameters );
Michael J. Spencer 2:1df0b61d3b5a 219
Michael J. Spencer 2:1df0b61d3b5a 220 if(!playing_file) {
Michael J. Spencer 2:1df0b61d3b5a 221 stream->printf("Not currently playing\r\n");
Michael J. Spencer 2:1df0b61d3b5a 222 return;
Michael J. Spencer 2:1df0b61d3b5a 223 }
Michael J. Spencer 2:1df0b61d3b5a 224
Michael J. Spencer 2:1df0b61d3b5a 225 if(file_size > 0) {
Michael J. Spencer 2:1df0b61d3b5a 226 unsigned long est= 0;
Michael J. Spencer 2:1df0b61d3b5a 227 if(this->elapsed_secs > 10) {
Michael J. Spencer 2:1df0b61d3b5a 228 unsigned long bytespersec= played_cnt / this->elapsed_secs;
Michael J. Spencer 2:1df0b61d3b5a 229 if(bytespersec > 0)
Michael J. Spencer 2:1df0b61d3b5a 230 est= (file_size - played_cnt) / bytespersec;
Michael J. Spencer 2:1df0b61d3b5a 231 }
Michael J. Spencer 2:1df0b61d3b5a 232
Michael J. Spencer 2:1df0b61d3b5a 233 unsigned int pcnt= (file_size - (file_size - played_cnt)) * 100 / file_size;
Michael J. Spencer 2:1df0b61d3b5a 234 // If -b or -B is passed, report in the format used by Marlin and the others.
Michael J. Spencer 2:1df0b61d3b5a 235 if ( options.find_first_of("Bb") == string::npos ){
Michael J. Spencer 2:1df0b61d3b5a 236 stream->printf("%u %% complete, elapsed time: %lu s", pcnt, this->elapsed_secs);
Michael J. Spencer 2:1df0b61d3b5a 237 if(est > 0){
Michael J. Spencer 2:1df0b61d3b5a 238 stream->printf(", est time: %lu s", est);
Michael J. Spencer 2:1df0b61d3b5a 239 }
Michael J. Spencer 2:1df0b61d3b5a 240 stream->printf("\r\n");
Michael J. Spencer 2:1df0b61d3b5a 241 }else{
Michael J. Spencer 2:1df0b61d3b5a 242 stream->printf("SD printing byte %lu/%lu\r\n", played_cnt, file_size);
Michael J. Spencer 2:1df0b61d3b5a 243 }
Michael J. Spencer 2:1df0b61d3b5a 244
Michael J. Spencer 2:1df0b61d3b5a 245 }else{
Michael J. Spencer 2:1df0b61d3b5a 246 stream->printf("File size is unknown\r\n");
Michael J. Spencer 2:1df0b61d3b5a 247 }
Michael J. Spencer 2:1df0b61d3b5a 248 }
Michael J. Spencer 2:1df0b61d3b5a 249
Michael J. Spencer 2:1df0b61d3b5a 250 void Player::abort_command( string parameters, StreamOutput* stream ){
Michael J. Spencer 2:1df0b61d3b5a 251 if(!playing_file) {
Michael J. Spencer 2:1df0b61d3b5a 252 stream->printf("Not currently playing\r\n");
Michael J. Spencer 2:1df0b61d3b5a 253 return;
Michael J. Spencer 2:1df0b61d3b5a 254 }
Michael J. Spencer 2:1df0b61d3b5a 255 playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 256 played_cnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 257 file_size= 0;
Michael J. Spencer 2:1df0b61d3b5a 258 this->filename= "";
Michael J. Spencer 2:1df0b61d3b5a 259 this->current_stream= NULL;
Michael J. Spencer 2:1df0b61d3b5a 260 fclose(current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 261 stream->printf("Aborted playing file\r\n");
Michael J. Spencer 2:1df0b61d3b5a 262 }
Michael J. Spencer 2:1df0b61d3b5a 263
Michael J. Spencer 2:1df0b61d3b5a 264 void Player::on_main_loop(void* argument){
Michael J. Spencer 2:1df0b61d3b5a 265 if( !this->booted ) {
Michael J. Spencer 2:1df0b61d3b5a 266 this->booted = true;
Michael J. Spencer 2:1df0b61d3b5a 267 if( this->on_boot_gcode_enable ){
Michael J. Spencer 2:1df0b61d3b5a 268 this->play_command(this->on_boot_gcode, THEKERNEL->serial);
Michael J. Spencer 2:1df0b61d3b5a 269 }else{
Michael J. Spencer 2:1df0b61d3b5a 270 //THEKERNEL->serial->printf("On boot gcode disabled! skipping...\n");
Michael J. Spencer 2:1df0b61d3b5a 271 }
Michael J. Spencer 2:1df0b61d3b5a 272 }
Michael J. Spencer 2:1df0b61d3b5a 273
Michael J. Spencer 2:1df0b61d3b5a 274 if( this->playing_file ){
Michael J. Spencer 2:1df0b61d3b5a 275 string buffer;
Michael J. Spencer 2:1df0b61d3b5a 276 bool discard= false;
Michael J. Spencer 2:1df0b61d3b5a 277 int c;
Michael J. Spencer 2:1df0b61d3b5a 278 buffer.reserve(20);
Michael J. Spencer 2:1df0b61d3b5a 279 // Print each line of the file
Michael J. Spencer 2:1df0b61d3b5a 280 while ((c = fgetc(this->current_file_handler)) != EOF){
Michael J. Spencer 2:1df0b61d3b5a 281 if (c == '\n'){
Michael J. Spencer 2:1df0b61d3b5a 282 if(discard) {
Michael J. Spencer 2:1df0b61d3b5a 283 // we hit a long line and discarded it
Michael J. Spencer 2:1df0b61d3b5a 284 discard= false;
Michael J. Spencer 2:1df0b61d3b5a 285 buffer.clear();
Michael J. Spencer 2:1df0b61d3b5a 286 this->current_stream->printf("Warning: Discarded long line\n");
Michael J. Spencer 2:1df0b61d3b5a 287 return;
Michael J. Spencer 2:1df0b61d3b5a 288 }
Michael J. Spencer 2:1df0b61d3b5a 289 this->current_stream->printf("%s\n", buffer.c_str());
Michael J. Spencer 2:1df0b61d3b5a 290 struct SerialMessage message;
Michael J. Spencer 2:1df0b61d3b5a 291 message.message = buffer;
Michael J. Spencer 2:1df0b61d3b5a 292 message.stream = &(StreamOutput::NullStream); // we don't really need to see the ok
Michael J. Spencer 2:1df0b61d3b5a 293 // wait for the queue to have enough room that a serial message could still be received before sending
Michael J. Spencer 2:1df0b61d3b5a 294 THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
Michael J. Spencer 2:1df0b61d3b5a 295 played_cnt += buffer.size();
Michael J. Spencer 2:1df0b61d3b5a 296 buffer.clear();
Michael J. Spencer 2:1df0b61d3b5a 297 return;
Michael J. Spencer 2:1df0b61d3b5a 298
Michael J. Spencer 2:1df0b61d3b5a 299 }else if(buffer.size() > 128) {
Michael J. Spencer 2:1df0b61d3b5a 300 // discard rest of line
Michael J. Spencer 2:1df0b61d3b5a 301 discard= true;
Michael J. Spencer 2:1df0b61d3b5a 302
Michael J. Spencer 2:1df0b61d3b5a 303 }else{
Michael J. Spencer 2:1df0b61d3b5a 304 buffer += c;
Michael J. Spencer 2:1df0b61d3b5a 305 }
Michael J. Spencer 2:1df0b61d3b5a 306 }
Michael J. Spencer 2:1df0b61d3b5a 307
Michael J. Spencer 2:1df0b61d3b5a 308 this->playing_file = false;
Michael J. Spencer 2:1df0b61d3b5a 309 this->filename= "";
Michael J. Spencer 2:1df0b61d3b5a 310 played_cnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 311 file_size= 0;
Michael J. Spencer 2:1df0b61d3b5a 312 fclose(this->current_file_handler);
Michael J. Spencer 2:1df0b61d3b5a 313 this->current_stream= NULL;
Michael J. Spencer 2:1df0b61d3b5a 314
Michael J. Spencer 2:1df0b61d3b5a 315 if(this->reply_stream != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 316 // if we were printing from an M command from pronterface we need to send this back
Michael J. Spencer 2:1df0b61d3b5a 317 this->reply_stream->printf("Done printing file\r\n");
Michael J. Spencer 2:1df0b61d3b5a 318 this->reply_stream= NULL;
Michael J. Spencer 2:1df0b61d3b5a 319 }
Michael J. Spencer 2:1df0b61d3b5a 320 }
Michael J. Spencer 2:1df0b61d3b5a 321 }
Michael J. Spencer 2:1df0b61d3b5a 322
Michael J. Spencer 2:1df0b61d3b5a 323 void Player::on_get_public_data(void* argument) {
Michael J. Spencer 2:1df0b61d3b5a 324 PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 325
Michael J. Spencer 2:1df0b61d3b5a 326 if(!pdr->starts_with(player_checksum)) return;
Michael J. Spencer 2:1df0b61d3b5a 327
Michael J. Spencer 2:1df0b61d3b5a 328 if(pdr->second_element_is(is_playing_checksum)) {
Michael J. Spencer 2:1df0b61d3b5a 329 static bool bool_data;
Michael J. Spencer 2:1df0b61d3b5a 330 bool_data= this->playing_file;
Michael J. Spencer 2:1df0b61d3b5a 331 pdr->set_data_ptr(&bool_data);
Michael J. Spencer 2:1df0b61d3b5a 332 pdr->set_taken();
Michael J. Spencer 2:1df0b61d3b5a 333
Michael J. Spencer 2:1df0b61d3b5a 334 }else if(pdr->second_element_is(get_progress_checksum)) {
Michael J. Spencer 2:1df0b61d3b5a 335 static struct pad_progress p;
Michael J. Spencer 2:1df0b61d3b5a 336 if(file_size > 0 && playing_file) {
Michael J. Spencer 2:1df0b61d3b5a 337 p.elapsed_secs= this->elapsed_secs;
Michael J. Spencer 2:1df0b61d3b5a 338 p.percent_complete= (this->file_size - (this->file_size - this->played_cnt)) * 100 / this->file_size;
Michael J. Spencer 2:1df0b61d3b5a 339 p.filename= this->filename;
Michael J. Spencer 2:1df0b61d3b5a 340 pdr->set_data_ptr(&p);
Michael J. Spencer 2:1df0b61d3b5a 341 pdr->set_taken();
Michael J. Spencer 2:1df0b61d3b5a 342 }
Michael J. Spencer 2:1df0b61d3b5a 343 }
Michael J. Spencer 2:1df0b61d3b5a 344 }
Michael J. Spencer 2:1df0b61d3b5a 345
Michael J. Spencer 2:1df0b61d3b5a 346 void Player::on_set_public_data(void* argument) {
Michael J. Spencer 2:1df0b61d3b5a 347 PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 348
Michael J. Spencer 2:1df0b61d3b5a 349 if(!pdr->starts_with(player_checksum)) return;
Michael J. Spencer 2:1df0b61d3b5a 350
Michael J. Spencer 2:1df0b61d3b5a 351 if(pdr->second_element_is(abort_play_checksum)) {
Michael J. Spencer 2:1df0b61d3b5a 352 abort_command("", &(StreamOutput::NullStream));
Michael J. Spencer 2:1df0b61d3b5a 353 pdr->set_taken();
Michael J. Spencer 2:1df0b61d3b5a 354 }
Michael J. Spencer 2:1df0b61d3b5a 355 }