From c58453a7265ae4c39104781b90833cb02333c8b8 Mon Sep 17 00:00:00 2001 From: Andre Sklenar <andre.sklenar@gmail.com> Date: Wed, 14 Dec 2016 14:38:36 +0100 Subject: [PATCH] main: add chunk write to sd card --- Firmware/Marlin_main.cpp | 138 +++++++++++++++++++++++++++++++++++++-- Firmware/cardreader.cpp | 13 ++++ Firmware/cardreader.h | 1 + 3 files changed, 147 insertions(+), 5 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 62a8bed4..efe9f259 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -261,6 +261,8 @@ int lcd_change_fil_state = 0; int feedmultiplyBckp = 100; unsigned char lang_selected = 0; +bool prusa_sd_card_upload = false; + unsigned long total_filament_used; unsigned int heating_status; @@ -1069,6 +1071,80 @@ void setup() update_current_firmware_version_to_eeprom(); } +void trace(); + +#define CHUNK_SIZE 64 // bytes +#define SAFETY_MARGIN 1 +char chunk[CHUNK_SIZE+SAFETY_MARGIN]; +int chunkHead = 0; + +int serial_read_stream() { + + setTargetHotend(0, 0); + setTargetBed(0); + + lcd_implementation_clear(); + lcd_printPGM(PSTR(" Upload in progress")); + + // first wait for how many bytes we will receive + uint32_t bytesToReceive; + + // receive the four bytes + char bytesToReceiveBuffer[4]; + for (int i=0; i<4; i++) { + int data; + while ((data = MYSERIAL.read()) == -1) {}; + bytesToReceiveBuffer[i] = data; + + } + + // make it a uint32 + memcpy(&bytesToReceive, &bytesToReceiveBuffer, 4); + + // we're ready, notify the sender + MYSERIAL.write('+'); + + // lock in the routine + uint32_t receivedBytes = 0; + while (prusa_sd_card_upload) { + int i; + for (i=0; i<CHUNK_SIZE; i++) { + int data; + + // check if we're not done + if (receivedBytes == bytesToReceive) { + break; + } + + // read the next byte + while ((data = MYSERIAL.read()) == -1) {}; + receivedBytes++; + + // save it to the chunk + chunk[i] = data; + } + + // write the chunk to SD + card.write_command_no_newline(&chunk[0]); + + // notify the sender we're ready for more data + MYSERIAL.write('+'); + + // for safety + manage_heater(); + + // check if we're done + if(receivedBytes == bytesToReceive) { + trace(); // beep + card.closefile(); + prusa_sd_card_upload = false; + SERIAL_PROTOCOLLNRPGM(MSG_FILE_SAVED); + return 0; + } + + } +} + // The loop() function is called in an endless loop by the Arduino framework from the default main() routine. // Before loop(), the setup() function is called by the main() routine. void loop() @@ -1085,7 +1161,14 @@ void loop() is_usb_printing = false; } - get_command(); + if (prusa_sd_card_upload) + { + //we read byte-by byte + serial_read_stream(); + } else + { + + get_command(); #ifdef SDSUPPORT card.checkautostart(false); @@ -1643,6 +1726,13 @@ void refresh_cmd_timeout(void) } //retract #endif //FWRETRACT +void trace() { + tone(BEEPER, 440); + delay(25); + noTone(BEEPER); + delay(20); +} + void process_commands() { #ifdef FILAMENT_RUNOUT_SUPPORT @@ -1667,7 +1757,36 @@ void process_commands() // PRUSA GCODES if(code_seen("PRUSA")){ - if(code_seen("Fir")){ + if (code_seen("fv")) { + // get file version + #ifdef SDSUPPORT + card.openFile(strchr_pointer + 3,true); + while (true) { + uint16_t readByte = card.get(); + MYSERIAL.write(readByte); + if (readByte=='\n') { + break; + } + } + card.closefile(); + + #endif // SDSUPPORT + + } else if(code_seen("fd")) { + char description[30]; + memset(description, ' ', 30); + getFileDescription(strchr_pointer + 3, description); + MYSERIAL.print(">"); + MYSERIAL.println(description); + MYSERIAL.print("<"); + + } else if (code_seen("M28")) { + trace(); + prusa_sd_card_upload = true; + card.openFile(strchr_pointer+4,false); + } else if (code_seen("mkdir")) { + card.mkdir(strchr_pointer+6); + } else if(code_seen("Fir")){ SERIAL_PROTOCOLLN(FW_version); @@ -1679,14 +1798,23 @@ void process_commands() lcd_force_language_selection(); } else if(code_seen("Lz")) { EEPROM_save_B(EEPROM_BABYSTEP_Z,0); - } + } else if (code_seen("SERIAL LOW")) { + MYSERIAL.println("SERIAL LOW"); + MYSERIAL.begin(BAUDRATE); + return; + } else if (code_seen("SERIAL HIGH")) { + MYSERIAL.println("SERIAL HIGH"); + MYSERIAL.begin(1152000); + return; + } //else if (code_seen('Cal')) { // lcd_calibration(); // } } - else - if(code_seen('G')) + else if (code_seen('^')) { + // nothing, this is a version line + } else if(code_seen('G')) { switch((int)code_value()) { diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 85bfbe30..a9ee7e57 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -501,6 +501,19 @@ void CardReader::write_command(char *buf) } } +#define CHUNK_SIZE 64 + +void CardReader::write_command_no_newline(char *buf) +{ + file.write(buf, CHUNK_SIZE); + if (file.writeError) + { + SERIAL_ERROR_START; + SERIAL_ERRORLNRPGM(MSG_SD_ERR_WRITE_TO_FILE); + MYSERIAL.println("An error while writing to the SD Card."); + } +} + void CardReader::checkautostart(bool force) { diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index a488bee6..3e87b331 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -14,6 +14,7 @@ public: void initsd(); void write_command(char *buf); + void write_command_no_newline(char *buf); //files auto[0-9].g on the sd card are performed in a row //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset