Implement check sum for Serial upload as mandatory for Marlin

Add 2 new [ESPXXX] command as check sum helper
* Send GCode with check sum caching right line numbering
[ESP600]<gcode>

* Send line checksum
[ESP601]<line>

Implemented only for Sync WebServer at this moment, so Async is disabled in Travis
This commit is contained in:
Luc 2018-11-02 11:21:56 +01:00
parent f24dfe9d23
commit 8a2c39869a
6 changed files with 310 additions and 139 deletions

View File

@ -62,12 +62,12 @@ script:
- build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
- arduino --board esp32:esp32:esp32 --save-prefs
- build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
- sed -i "s/\/\/#define ASYNCWEBSERVER /#define ASYNCWEBSERVER/g" $HOME/arduino_ide/libraries/ESP3D/src/config.h
- arduino --board esp8266com:esp8266:generic --save-prefs
- arduino --get-pref sketchbook.path
- build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
- arduino --board esp32:esp32:esp32 --save-prefs
- build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
# - sed -i "s/\/\/#define ASYNCWEBSERVER /#define ASYNCWEBSERVER/g" $HOME/arduino_ide/libraries/ESP3D/src/config.h
# - arduino --board esp8266com:esp8266:generic --save-prefs
# - arduino --get-pref sketchbook.path
# - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
# - arduino --board esp32:esp32:esp32 --save-prefs
# - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino
notifications:
email:

View File

@ -136,6 +136,12 @@ if authentication is on, need admin password for RESET, RESTART and SAFEMODE
[ESP555]<password>pwd=<admin password>
if no password set it use default one
* Send GCode with check sum caching right line numbering
[ESP600]<gcode>
* Send line checksum
[ESP601]<line>
* Read SPIFFS file and send each line to serial
[ESP700]<filename>

View File

@ -49,6 +49,9 @@ String COMMAND::buffer_tcp;
#define INCORRECT_CMD_MSG (output == WEB_PIPE)?F("Error: Incorrect Command"):F("Incorrect Cmd")
#define OK_CMD_MSG (output == WEB_PIPE)?F("ok"):F("Cmd Ok")
extern uint8_t Checksum(const char * line, uint16_t lineSize);
extern bool sendLine2Serial (String & line, int32_t linenb, int32_t* newlinenb);
String COMMAND::get_param (String & cmd_params, const char * id, bool withspace)
{
static String parameter;
@ -1403,6 +1406,47 @@ bool COMMAND::execute_command (int cmd, String cmd_params, tpipe output, level_a
break;
}
#endif
//[ESP600]<gcode>
case 600: { //send GCode with check sum caching right line numbering
//be sure serial is locked
if ( (web_interface->blockserial) ) {
break;
}
int32_t linenb = 1;
cmd_params.trim() ;
if (sendLine2Serial (cmd_params, linenb, &linenb))ESPCOM::println (OK_CMD_MSG, output, espresponse);
else { //it may failed because of skip if repetier so let's reset numbering first
if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) {
//reset numbering
String cmd = "M110 N0";
if (sendLine2Serial (cmd, -1, NULL)){
linenb = 1;
//if success let's try again to send the command
if (sendLine2Serial (cmd_params, linenb, &linenb))ESPCOM::println (OK_CMD_MSG, output, espresponse);
else {
ESPCOM::println (ERROR_CMD_MSG, output, espresponse);
response = false;
}
} else {
ESPCOM::println (ERROR_CMD_MSG, output, espresponse);
response = false;
}
} else {
ESPCOM::println (ERROR_CMD_MSG, output, espresponse);
response = false;
}
}
}
break;
//[ESP601]<line>
case 601: { //send line checksum
cmd_params.trim();
int8_t chk = Checksum(cmd_params.c_str(),cmd_params.length());
String schecksum = "Checksum: " + String(chk);
ESPCOM::println (schecksum, output, espresponse);
}
break;
//[ESP700]<filename>
case 700: { //read local file
//be sure serial is locked

View File

@ -19,7 +19,7 @@
*/
//version and sources location
#define FW_VERSION "2.0.0.c20"
#define FW_VERSION "2.0.0.c21"
#define REPOSITORY "https://github.com/luc-github/ESP3D"
//Customize ESP3D ////////////////////////////////////////////////////////////////////////
@ -71,10 +71,10 @@
#define DIRECT_PIN_FEATURE
//ESP_OLED_FEATURE: allow oled screen output
#define ESP_OLED_FEATURE
//#define ESP_OLED_FEATURE
//DHT_FEATURE: send update of temperature / humidity based on DHT 11/22
#define DHT_FEATURE
//#define DHT_FEATURE
//AUTHENTICATION_FEATURE: protect pages by login password
//#define AUTHENTICATION_FEATURE
@ -83,7 +83,7 @@
#define WS_DATA_FEATURE
//TIMESTAMP_FEATURE: Time stamp feature on direct SD files
#define TIMESTAMP_FEATURE
//#define TIMESTAMP_FEATURE
//Extra features /////////////////////////////////////////////////////////////////////////
@ -216,7 +216,7 @@ using fs::File;
#endif
#ifdef DEBUG_OUTPUT_TCP
#include "espcom.h"
#define LOG(string) {ESPCOM::send2TCP(string, true);}
#define LOG(string) {ESPCOM::send2TCP(string, false);}
#define DEBUG_PIPE TCP_PIPE
#endif
#else

View File

@ -101,9 +101,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length
extern bool deleteRecursive(String path);
extern void CloseSerialUpload (bool iserror, String & filename);
extern bool sendLine2Serial (String & line);
extern void CloseSerialUpload (bool iserror, String & filename, int32_t linenb);
extern bool sendLine2Serial (String & line, int32_t linenb, int32_t* newlinenb);
extern bool purge_serial();
const uint8_t PAGE_404 [] PROGMEM = "<HTML>\n<HEAD>\n<title>Redirecting...</title> \n</HEAD>\n<BODY>\n<CENTER>Unknown page : $QUERY$- you will be redirected...\n<BR><BR>\nif not redirected, <a href='http://$WEB_ADDRESS$'>click here</a>\n<BR><BR>\n<PROGRESS name='prg' id='prg'></PROGRESS>\n\n<script>\nvar i = 0; \nvar x = document.getElementById(\"prg\"); \nx.max=5; \nvar interval=setInterval(function(){\ni=i+1; \nvar x = document.getElementById(\"prg\"); \nx.value=i; \nif (i>5) \n{\nclearInterval(interval);\nwindow.location.href='/';\n}\n},1000);\n</script>\n</CENTER>\n</BODY>\n</HTML>\n\n";
const uint8_t PAGE_CAPTIVE [] PROGMEM = "<HTML>\n<HEAD>\n<title>Captive Portal</title> \n</HEAD>\n<BODY>\n<CENTER>Captive Portal page : $QUERY$- you will be redirected...\n<BR><BR>\nif not redirected, <a href='http://$WEB_ADDRESS$'>click here</a>\n<BR><BR>\n<PROGRESS name='prg' id='prg'></PROGRESS>\n\n<script>\nvar i = 0; \nvar x = document.getElementById(\"prg\"); \nx.max=5; \nvar interval=setInterval(function(){\ni=i+1; \nvar x = document.getElementById(\"prg\"); \nx.value=i; \nif (i>5) \n{\nclearInterval(interval);\nwindow.location.href='/';\n}\n},1000);\n</script>\n</CENTER>\n</BODY>\n</HTML>\n\n";
@ -559,7 +559,6 @@ void SPIFFSFileupload()
if(upload.status == UPLOAD_FILE_START) {
String upload_filename = upload.filename;
String sizeargname = upload_filename + "S";
if (web_interface->web_server.hasArg ("plain") ) Serial.println("Yes");
if (upload_filename[0] != '/') filename = "/" + upload_filename;
else filename = upload.filename;
//according User or Admin the root is different as user is isolate to /user when admin has full access
@ -1152,6 +1151,7 @@ void handle_serial_SDFileList()
//SD file upload by serial
void SDFile_serial_upload()
{
static int32_t lineNb =-1;
static String current_line;
static bool is_comment = false;
static String current_filename;
@ -1174,93 +1174,70 @@ void SDFile_serial_upload()
//Upload start
//**************
if(upload.status == UPLOAD_FILE_START) {
LOG("Upload Start\r\n")
String command = "M29";
String resetcmd = "M110 N0";
if (CONFIG::GetFirmwareTarget() == SMOOTHIEWARE)resetcmd = "N0 M110";
lineNb=1;
//close any ongoing upload and get current line number
if(!sendLine2Serial (command,1, &lineNb)){
//it can failed for repetier
if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) {
if(!sendLine2Serial (command,-1, NULL)){
LOG("Start Upload failed")
web_interface->_upload_status= UPLOAD_STATUS_FAILED;
return;
}
} else {
LOG("Start Upload failed")
web_interface->_upload_status= UPLOAD_STATUS_FAILED;
return;
}
}
//Reset line numbering
if(!sendLine2Serial (resetcmd,-1, NULL)){
LOG("Reset Numbering failed")
web_interface->_upload_status= UPLOAD_STATUS_FAILED;
return;
}
lineNb=1;
//need to lock serial out to avoid garbage in file
(web_interface->blockserial) = true;
current_line ="";
is_comment = false;
String response;
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
ESPCOM::println (F ("Uploading..."), PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
LOG("Clear Serial\r\n");
if(ESPCOM::available(DEFAULT_PRINTER_PIPE)) {
ESPCOM::bridge();
CONFIG::wait(1);
}
//command to pritnter to start print
String command = "M28 " + upload.filename;
LOG(command);
LOG("\r\n");
ESPCOM::println (command, DEFAULT_PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
current_filename = upload.filename;
CONFIG::wait (500);
uint32_t timeout = millis();
bool done = false;
while (!done) { //time out is 2000ms
CONFIG::wait(0);
//if there is something in serial buffer
size_t len = ESPCOM::available(DEFAULT_PRINTER_PIPE);
//get size of buffer
if (len > 0) {
CONFIG::wait(0);
uint8_t * sbuf = (uint8_t *)malloc(len+1);
if(!sbuf){
ESPCOM::println (F ("SD upload rejected"), PRINTER_PIPE);
LOG("SD upload rejected\r\n");
LOG("Need to stop");
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
web_interface->web_server.client().stop();
#endif
return ;
}
//read buffer
ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, sbuf, len);
//convert buffer to zero end array
sbuf[len] = '\0';
//use string because easier to handle
response = (const char*) sbuf;
LOG (response);
//if there is a wait it means purge is done
if (response.indexOf ("wait") > -1) {
LOG ("Exit start writing\r\n");
done = true;
free(sbuf);
break;
}
//it is first command if it is failed no need to continue
//and resend command won't help
if (response.indexOf ("Resend") > -1 || response.indexOf ("failed") > -1) {
web_interface->blockserial = false;
LOG ("Error start writing\r\n");
web_interface->_upload_status = UPLOAD_STATUS_FAILED;
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
web_interface->web_server.client().stop();
#endif
free(sbuf);
return;
}
free(sbuf);
}
if ( (millis() - timeout) > SERIAL_CHECK_TIMEOUT) {
done = true;
}
is_comment = false;
String response;
ESPCOM::println (F ("Uploading..."), PRINTER_PIPE);
//Clear all serial
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
purge_serial();
//besure nothing left again
purge_serial();
command = "M28 " + upload.filename;
//send start upload
//no correction allowed because it means reset numbering was failed
if (sendLine2Serial(command, lineNb, NULL)){
CONFIG::wait(1200);
//additional purge, in case it is slow to answer
purge_serial();
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
LOG("Creation Ok\r\n")
} else {
web_interface->_upload_status= UPLOAD_STATUS_FAILED;
LOG("Creation failed\r\n");
}
//Upload write
//**************
//upload is on going with data coming by 2K blocks
} else if(upload.status == UPLOAD_FILE_WRITE) { //if com error no need to send more data to serial
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
if (web_interface->_upload_status == UPLOAD_STATUS_ONGOING) {
for (int pos = 0; pos < upload.currentSize; pos++) { //parse full post data
//feed watchdog
CONFIG::wait(0);
//it is a comment
if (upload.buf[pos] == ';') {
LOG ("Comment\n")
LOG ("Comment\r\n")
is_comment = true;
}
//it is an end line
@ -1271,10 +1248,11 @@ void SDFile_serial_upload()
if (current_line.length() < 126) {
//do we have something in buffer ?
if (current_line.length() > 0 ) {
current_line += "\r\n";
if (!sendLine2Serial (current_line) ) {
lineNb++;
if (!sendLine2Serial (current_line, lineNb, NULL) ) {
//fup.println("[Log]Write Error");
LOG ("Error over buffer\n")
CloseSerialUpload (true, current_filename);
CloseSerialUpload (true, current_filename,lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
@ -1291,7 +1269,8 @@ void SDFile_serial_upload()
} else {
//error buffer overload
LOG ("Error over buffer\n")
CloseSerialUpload (true, current_filename);
lineNb++;
CloseSerialUpload (true, current_filename, lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
@ -1304,7 +1283,8 @@ void SDFile_serial_upload()
current_line += char (upload.buf[pos]); //copy current char to buffer to send/resend
} else {
LOG ("Error over buffer\n")
CloseSerialUpload (true, current_filename);
lineNb++;
CloseSerialUpload (true, current_filename, lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
@ -1314,15 +1294,28 @@ void SDFile_serial_upload()
}
}
}
} else {
LOG ("Error upload\n")
web_interface->_upload_status = UPLOAD_STATUS_FAILED;
lineNb++;
CloseSerialUpload (true, current_filename, lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
web_interface->web_server.client().stop();
#endif
return;
}
//Upload end
//**************
} else if(upload.status == UPLOAD_FILE_END) {
} else if(upload.status == UPLOAD_FILE_END && web_interface->_upload_status == UPLOAD_STATUS_ONGOING) {
//if last part does not have '\n'
if (current_line.length() > 0) {
current_line += "\r\n";
if (!sendLine2Serial (current_line) ) {
lineNb++;
if (!sendLine2Serial (current_line, lineNb, NULL) ) {
LOG ("Error sending buffer\n")
CloseSerialUpload (true, current_filename);
lineNb++;
CloseSerialUpload (true, current_filename, lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else
@ -1332,12 +1325,14 @@ void SDFile_serial_upload()
}
}
LOG ("Upload finished ");
CloseSerialUpload (false, current_filename);
lineNb++;
CloseSerialUpload (false, current_filename, lineNb);
//Upload cancelled
//**************
} else { //UPLOAD_FILE_ABORTED
LOG("Error, Something happened\r\n");
CloseSerialUpload (true, current_filename);
lineNb++;
CloseSerialUpload (true, current_filename, lineNb);
#if defined ( ARDUINO_ARCH_ESP8266)
web_interface->web_server.client().stopAll();
#else

View File

@ -73,78 +73,203 @@
long id_connection = 0;
uint8_t Checksum(const char * line, uint16_t lineSize)
{
uint8_t checksum_val =0;
for (uint16_t i=0; i < lineSize; i++) checksum_val = checksum_val ^ ((uint8_t)line[i]);
return checksum_val;
}
String CheckSumLine(const char* line, uint32_t linenb){
String linechecksum = "N" + String(linenb)+ " " + line;
uint8_t crc = Checksum(linechecksum.c_str(), linechecksum.length());
linechecksum+="*"+String(crc);
return linechecksum;
}
bool purge_serial(){
uint32_t start = millis();
uint8_t buf [51];
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
CONFIG::wait (5);
LOG("Purge Serial\r\n")
while (ESPCOM::available(DEFAULT_PRINTER_PIPE) > 0 ){
if ((millis() - start ) > 2000) {
LOG("Purge timeout\r\n")
return false;
}
size_t len = ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, buf, 50);
buf[len] = '\0';
LOG("Purge ")
LOG((const char *)buf)
LOG("\r\n")
if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) {
String s = (const char *)buf;
//repetier never stop sending data so no need to wait if have 'wait' or 'busy'
if((s.indexOf ("wait") > -1) || (s.indexOf ("busy") > -1))return true;
LOG("Purge interrupted\r\n")
}
CONFIG::wait (5);
}
CONFIG::wait (0);
LOG("Purge done\r\n")
return true;
}
size_t wait_for_data(uint32_t timeout){
uint32_t start = millis();
while ((ESPCOM::available(DEFAULT_PRINTER_PIPE) < 2) && ((millis()-start) < timeout))CONFIG::wait (10);
return ESPCOM::available(DEFAULT_PRINTER_PIPE);
}
uint32_t Get_lineNumber(String & response){
int32_t l = 0;
String sresend = "Resend:";
if ( CONFIG::GetFirmwareTarget() == SMOOTHIEWARE){
sresend = "rs N";
}
int pos = response.indexOf(sresend);
if (pos == -1 ) {
return -1;
}
pos+=sresend.length();
int pos2 = response.indexOf("\n", pos);
String snum = response.substring(pos, pos2);
//remove potential unwished char
snum.replace("\r", "");
l = snum.toInt();
LOG("New number ")
LOG(String(l))
LOG("\r\n")
return l;
}
//function to send line to serial///////////////////////////////////////
bool sendLine2Serial (String & line)
//if newlinenb is NULL no auto correction of line number in case of resend
bool sendLine2Serial (String & line, int32_t linenb, int32_t * newlinenb)
{
LOG (line)
ESPCOM::println (line, DEFAULT_PRINTER_PIPE);
LOG ("Send line ")
LOG (line )
LOG (" NB:")
LOG (String(linenb))
LOG ("\r\n")
String line2send;
String sok = "ok";
String sresend = "Resend";
if (newlinenb) *newlinenb = linenb;
if ( CONFIG::GetFirmwareTarget() == SMOOTHIEWARE)sresend = "rs N";
if (linenb != -1) {
if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) sok+=" " + String(linenb);
line2send = CheckSumLine(line.c_str(),linenb);
} else line2send = line;
//purge serial as nothing is supposed to interfere with upload
purge_serial();
LOG ("Send line ")
LOG (line2send )
LOG ("\r\n")
//send line
ESPCOM::println (line2send, DEFAULT_PRINTER_PIPE);
ESPCOM::flush(DEFAULT_PRINTER_PIPE);
#ifdef ARDUINO_ARCH_ESP8266
CONFIG::wait (5);
#else
CONFIG::wait (2);
#endif
if (ESPCOM::available(DEFAULT_PRINTER_PIPE) > 0 ) {
//check answer
if (wait_for_data(2000) > 0 ) {
bool done = false;
uint32_t timeout = millis();
uint8_t count = 0;
//got data check content
String response ;
while (!done) {
CONFIG::wdtFeed();
size_t len = ESPCOM::available(DEFAULT_PRINTER_PIPE);
//get size of buffer
if (len > 0) {
uint8_t * sbuf = (uint8_t *)malloc(len+1);
if(!sbuf){
return false;
}
if(!sbuf){
return false;
}
//read buffer
ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, sbuf, len);
//convert buffer to zero end array
sbuf[len] = '\0';
//use string because easier to handle
String response = (const char*) sbuf;
if ( (response.indexOf ("ok") > -1) || (response.indexOf ("wait") > -1) ) {
free(sbuf);
return true;
//use string because easier to handle and allow to re-assemble cutted answer
response += (const char*) sbuf;
LOG ("Response: ")
LOG (response)
LOG ("\r\n")
//in that case there is no way to know what is the right number to use and so send should be failed
if (( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) && (response.indexOf ("skip") != -1)) {
LOG ("Wrong line requested\r\n")
count = 5;
}
if (response.indexOf ("Resend") > -1) {
//it is resend ?
int pos = response.indexOf (sresend);
//be sure we get full line to be able to process properly
if (( pos > -1) && (response.lastIndexOf("\n") > pos)){
LOG ("Resend detected\r\n")
uint32_t line_number = Get_lineNumber(response);
if (newlinenb){
*newlinenb = line_number;
free(sbuf);
return sendLine2Serial (line, line_number, newlinenb);
} else {
//the line requested is not the current one so we stop
if (line_number !=linenb) {
LOG ("Wrong line requested\r\n")
count = 5;
}
}
count++;
if (count > 5) {
free(sbuf);
free(sbuf);
LOG ("Exit too many resend or wrong line\r\n")
return false;
}
LOG ("resend\r\n")
ESPCOM::println (line, DEFAULT_PRINTER_PIPE);
LOG ("Resend\r\n")
purge_serial();
ESPCOM::println (line2send, DEFAULT_PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
CONFIG::wait (5);
wait_for_data(1000);
timeout = millis();
} else {
if ( (response.indexOf (sok) > -1) ) { //we have ok so it is done
free(sbuf);
LOG ("Got ok\r\n")
purge_serial();
return true;
}
}
free(sbuf);
}
//no answer so exit: no news = good news
if ( millis() - timeout > 500) {
//no answer or over buffer exit
if ( (millis() - timeout > 2000) || (response.length() >200)){
LOG ("Time out\r\n")
done = true;
}
CONFIG::wait (50);
}
}
LOG ("Send line error\r\n")
return false;
}
//send M29 / M30 command to close file on SD////////////////////////////
void CloseSerialUpload (bool iserror, String & filename , int32_t linenb)
{
purge_serial();
String command = "M29";
purge_serial();
if (!sendLine2Serial (command,linenb, &linenb)) {
wait_for_data(2000);
if (!sendLine2Serial (command,linenb, &linenb)) {
if ((CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) {
sendLine2Serial (command,-1, NULL);
}
}
}
return true;
}
//send M29 / M30 command to close file on SD////////////////////////////
void CloseSerialUpload (bool iserror, String & filename)
{
ESPCOM::println ("\r\nM29", DEFAULT_PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
CONFIG::wait (1000);
ESPCOM::println ("\r\nM29", DEFAULT_PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
if (iserror) {
String cmdfilename = "M30 " + filename;
ESPCOM::println (cmdfilename, DEFAULT_PRINTER_PIPE);
sendLine2Serial (cmdfilename,-1, NULL);
ESPCOM::println (F ("SD upload failed"), PRINTER_PIPE);
ESPCOM::flush (DEFAULT_PRINTER_PIPE);
web_interface->_upload_status = UPLOAD_STATUS_FAILED;
@ -154,7 +279,8 @@ void CloseSerialUpload (bool iserror, String & filename)
web_interface->_upload_status = UPLOAD_STATUS_SUCCESSFUL;
}
//lets give time to FW to proceed
CONFIG::wait (1000);
wait_for_data(2000);
purge_serial();
web_interface->blockserial = false;
}