Browse Source

Merge remote-tracking branch 'upstream/MK3' into PFW-1271_PF-buildv20

3d-gussner 3 years ago
parent
commit
3c649a89d3

+ 84 - 53
Firmware/Marlin_main.cpp

@@ -454,10 +454,13 @@ static void print_time_remaining_init();
 static void wait_for_heater(long codenum, uint8_t extruder);
 static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis);
 static void gcode_M105(uint8_t extruder);
+
+#ifndef PINDA_THERMISTOR
 static void temp_compensation_start();
 static void temp_compensation_apply();
+#endif
 
-static bool get_PRUSA_SN(char* SN);
+static uint8_t get_PRUSA_SN(char* SN);
 
 uint16_t gcode_in_progress = 0;
 uint16_t mcode_in_progress = 0;
@@ -741,7 +744,7 @@ static void factory_reset(char level)
 
 	case 2: // Level 2: Prepare for shipping
 		factory_reset_stats();
-		// [[fallthrough]] // there is no break intentionally
+		// FALLTHRU
 
 	case 3: // Level 3: Preparation after being serviced
 		// Force language selection at the next boot up.
@@ -1071,18 +1074,21 @@ void setup()
     }
 #endif //TMC2130
 
-    //saved EEPROM SN is not valid. Try to retrieve it.
-    //SN is valid only if it is NULL terminated. Any other character means either uninitialized or corrupted
-    if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19))
+    //Check for valid SN in EEPROM. Try to retrieve it in case it's invalid.
+    //SN is valid only if it is NULL terminated and starts with "CZPX".
     {
         char SN[20];
-        if (get_PRUSA_SN(SN))
+        eeprom_read_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20);
+        if (SN[19] || strncmp_P(SN, PSTR("CZPX"), 4))
         {
-            eeprom_update_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20);
-            puts_P(PSTR("SN updated"));
+            if (!get_PRUSA_SN(SN))
+            {
+                eeprom_update_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20);
+                puts_P(PSTR("SN updated"));
+            }
+            else
+                puts_P(PSTR("SN update failed"));
         }
-        else
-            puts_P(PSTR("SN update failed"));
     }
 
 
@@ -1727,6 +1733,32 @@ void serial_read_stream() {
     }
 }
 
+
+/**
+ * Output autoreport values according to features requested in M155
+ */
+#if defined(AUTO_REPORT)
+static void host_autoreport()
+{
+    if (autoReportFeatures.TimerExpired())
+    {
+        if(autoReportFeatures.Temp()){
+            gcode_M105(active_extruder);
+        }
+        if(autoReportFeatures.Pos()){
+            gcode_M114();
+        }
+#if defined(AUTO_REPORT) && (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1)))))
+        if(autoReportFeatures.Fans()){
+            gcode_M123();
+        }
+#endif //AUTO_REPORT and (FANCHECK and TACH_0 or TACH_1)
+        autoReportFeatures.TimerStart();
+    }
+}
+#endif //AUTO_REPORT
+
+
 /**
 * Output a "busy" message at regular intervals
 * while the machine is not accepting commands.
@@ -1738,27 +1770,6 @@ void host_keepalive() {
   if (farm_mode) return;
   long ms = _millis();
 
-#if defined(AUTO_REPORT)
-  {
-    if (autoReportFeatures.TimerExpired())
-    {
-      if(autoReportFeatures.Temp()){
-        gcode_M105(active_extruder);
-      }
-      if(autoReportFeatures.Pos()){
-        gcode_M114();
-      }
- #if defined(AUTO_REPORT) && (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1)))))      
-      if(autoReportFeatures.Fans()){
-        gcode_M123();
-      }
-#endif //AUTO_REPORT and (FANCHECK and TACH_0 or TACH_1)
-     autoReportFeatures.TimerStart();
-    }
-  }
-#endif //AUTO_REPORT
-
-
   if (host_keepalive_interval && busy_state != NOT_BUSY) {
     if ((ms - prev_busy_signal_ms) < (long)(1000L * host_keepalive_interval)) return;
      switch (busy_state) {
@@ -3493,11 +3504,13 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 				bool result = sample_mesh_and_store_reference();
 				if (result)
 				{
-					if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION)
-						// Shipped, the nozzle height has been set already. The user can start printing now.
-						calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
-						final_result = true;
-					// babystep_apply();
+                    if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION)
+                    {
+                        // Shipped, the nozzle height has been set already. The user can start printing now.
+                        calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
+                    }
+                    final_result = true;
+                    // babystep_apply();
 				}
 			}
 			else
@@ -3823,33 +3836,47 @@ void gcode_M701()
  *
  * Send command ;S to serial port 0 to retrieve serial number stored in 32U2 processor,
  * reply is stored in *SN.
- * Operation takes typically 23 ms. If the retransmit is not finished until 100 ms,
- * it is interrupted, so less, or no characters are retransmitted, the function returns false
+ * Operation takes typically 23 ms. If no valid SN can be retrieved within the 250ms window, the function aborts 
+ * and returns a general failure flag.
  * The command will fail if the 32U2 processor is unpowered via USB since it is isolated from the rest of the electronics.
  * In that case the value that is stored in the EEPROM should be used instead.
  *
- * @return 1 on success
- * @return 0 on general failure
+ * @return 0 on success
+ * @return 1 on general failure
  */
-static bool get_PRUSA_SN(char* SN)
+static uint8_t get_PRUSA_SN(char* SN)
 {
     uint8_t selectedSerialPort_bak = selectedSerialPort;
-    selectedSerialPort = 0;
-    SERIAL_ECHOLNRPGM(PSTR(";S"));
-    uint8_t numbersRead = 0;
+    uint8_t rxIndex;
+    bool SN_valid = false;
     ShortTimer timeout;
-    timeout.start();
 
-    while (numbersRead < 19) {
-        if (MSerial.available() > 0) {
-            SN[numbersRead] = MSerial.read();
-            numbersRead++;
+    selectedSerialPort = 0;
+    timeout.start();
+    
+    while (!SN_valid)
+    {
+        rxIndex = 0;
+        _delay(50);
+        MYSERIAL.flush(); //clear RX buffer
+        SERIAL_ECHOLNRPGM(PSTR(";S"));
+        while (rxIndex < 19)
+        {
+            if (timeout.expired(250u))
+                goto exit;
+            if (MYSERIAL.available() > 0)
+            {
+                SN[rxIndex] = MYSERIAL.read();
+                rxIndex++;
+            }
         }
-        if (timeout.expired(100u)) break;
+        SN[rxIndex] = 0;
+        // printf_P(PSTR("SN:%s\n"), SN);
+        SN_valid = (strncmp_P(SN, PSTR("CZPX"), 4) == 0);
     }
-    SN[numbersRead] = 0;
+exit:
     selectedSerialPort = selectedSerialPort_bak;
-    return (numbersRead == 19);
+    return !SN_valid;
 }
 //! Detection of faulty RAMBo 1.1b boards equipped with bigger capacitors
 //! at the TACH_1 pin, which causes bad detection of print fan speed.
@@ -8841,7 +8868,7 @@ Sigma_Exit:
       bool load_to_nozzle = false;
       for (index = 1; *(strchr_pointer + index) == ' ' || *(strchr_pointer + index) == '\t'; index++);
 
-	  *(strchr_pointer + index) = tolower(*(strchr_pointer + index));
+      *(strchr_pointer + index) = tolower(*(strchr_pointer + index));
 
       if ((*(strchr_pointer + index) < '0' || *(strchr_pointer + index) > '4') && *(strchr_pointer + index) != '?' && *(strchr_pointer + index) != 'x' && *(strchr_pointer + index) != 'c') {
           SERIAL_ECHOLNPGM("Invalid T code.");
@@ -9901,6 +9928,10 @@ if(0)
   #endif
   check_axes_activity();
   mmu_loop();
+#if defined(AUTO_REPORT)
+  host_autoreport();
+#endif //AUTO_REPORT
+  host_keepalive();
 }
 
 void kill(const char *full_screen_message, unsigned char id)

+ 3 - 2
Firmware/cardreader.cpp

@@ -196,7 +196,7 @@ void CardReader::ls(ls_param params)
 }
 
 
-void CardReader::initsd()
+void CardReader::initsd(bool doPresort/* = true*/)
 {
   cardOK = false;
   if(root.isOpen())
@@ -240,7 +240,8 @@ void CardReader::initsd()
   workDirDepth = 0;
 
   #ifdef SDCARD_SORT_ALPHA
-	presort();
+  if (doPresort)
+    presort();
   #endif
 
   /*

+ 1 - 1
Firmware/cardreader.h

@@ -27,7 +27,7 @@ public:
     inline ls_param(bool LFN, bool timestamp):LFN(LFN), timestamp(timestamp) { }
   } __attribute__((packed));
   
-  void initsd();
+  void initsd(bool doPresort = true);
   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

+ 1 - 1
Firmware/eeprom.h

@@ -564,7 +564,7 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 #ifdef __cplusplus
 #include "ConfigurationStore.h"
 static_assert(EEPROM_FIRMWARE_VERSION_END < 20, "Firmware version EEPROM address conflicts with EEPROM_M500_base");
-static constexpr M500_conf * const EEPROM_M500_base = reinterpret_cast<M500_conf*>(20); //offset for storing settings using M500
+static M500_conf * const EEPROM_M500_base = reinterpret_cast<M500_conf*>(20); //offset for storing settings using M500
 static_assert(((sizeof(M500_conf) + 20) < EEPROM_LAST_ITEM), "M500_conf address space conflicts with previous items.");
 #endif
 

+ 0 - 1
Firmware/heatbed_pwm.cpp

@@ -153,7 +153,6 @@ ISR(TIMER0_OVF_vect)          // timer compare interrupt service routine
 			return;           // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf
 		}
 		// otherwise moving towards FALL
-		state = States::ONE;//_TO_FALL;
 		state=States::FALL;
 		fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
 		TCNT0 = 255;              // force overflow on the next clock cycle

+ 1 - 1
Firmware/mmu.cpp

@@ -1555,7 +1555,7 @@ void mmu_continue_loading(bool blocking)
         {
         case Ls::Enter:
             increment_load_fail();
-            // no break
+            // FALLTHRU
         case Ls::Retry:
             ++retry; // overflow not handled, as it is not dangerous.
             if (retry >= max_retry)

+ 2 - 0
Firmware/optiboot_xflash.cpp

@@ -68,6 +68,8 @@ static void getNch(uint8_t count) {
 
 typedef uint16_t pagelen_t;
 
+//Thou shalt not change these messages, else the avrdude-slicer xflash implementation will no longer work and the language upload will fail.
+//Right now we support 2 xflash chips - the original w25x20cl and a new one GD25Q20C
 static const char entry_magic_send   [] PROGMEM = "start\n";
 static const char entry_magic_receive[] PROGMEM = "w25x20cl_enter\n";
 static const char entry_magic_cfm    [] PROGMEM = "w25x20cl_cfm\n";

+ 2 - 2
Firmware/pat9125.c

@@ -131,8 +131,8 @@ uint8_t pat9125_init(void)
     if (!pat9125_probe())
         return 0;
 
-	// Verify that the sensor responds with its correct product ID.
-	pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
+    // Verify that the sensor responds with its correct product ID.
+    pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
 	pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
 	if ((pat9125_PID1 != 0x31) || (pat9125_PID2 != 0x91))
 	{

+ 1 - 1
Firmware/sound.cpp

@@ -129,7 +129,7 @@ switch(eSoundMode)
                Sound_DoSound_Encoder_Move();
           if(eSoundType==e_SOUND_TYPE_BlindAlert)
                Sound_DoSound_Blind_Alert();
-               break;
+          break;
      default:
           break;
      }

+ 3 - 6
Firmware/temperature.cpp

@@ -197,7 +197,9 @@ static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMP
 
 static float analog2temp(int raw, uint8_t e);
 static float analog2tempBed(int raw);
+#ifdef AMBIENT_MAXTEMP
 static float analog2tempAmbient(int raw);
+#endif
 static void updateTemperaturesFromRawValues();
 
 enum TempRunawayStates
@@ -567,10 +569,7 @@ void checkFanSpeed()
 	static unsigned char fan_speed_errors[2] = { 0,0 };
 #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 >-1))
 	if ((fan_speed[0] < 20) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;}
-	else{
-    fan_speed_errors[0] = 0;
-    host_keepalive();
-  }
+	else fan_speed_errors[0] = 0;
 #endif
 #if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
 	if ((fan_speed[1] < 5) && ((blocks_queued() ? block_buffer[block_buffer_tail].fan_speed : fanSpeed) > MIN_PRINT_FAN_SPEED)) fan_speed_errors[1]++;
@@ -902,8 +901,6 @@ void manage_heater()
 		timer02_set_pwm0(soft_pwm_bed << 1);
 	  }
   #endif
-  
-  host_keepalive();
 }
 
 #define PGM_RD_W(x)   (short)pgm_read_word(&x)

+ 3 - 3
Firmware/tmc2130.cpp

@@ -826,11 +826,11 @@ void tmc2130_do_steps(uint8_t axis, uint16_t steps, uint8_t dir, uint16_t delay_
 {
     if (tmc2130_get_dir(axis) != dir)
         tmc2130_set_dir(axis, dir);
-	while (steps--)
-	{
+    while (steps--)
+    {
 		tmc2130_do_step(axis);
 		delayMicroseconds(delay_us);
-	}
+    }
 }
 
 void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_us, uint16_t microstep_resolution)

+ 41 - 26
Firmware/ultralcd.cpp

@@ -59,7 +59,9 @@ int clock_interval = 0;
 
 static void lcd_sd_updir();
 static void lcd_mesh_bed_leveling_settings();
+#ifdef LCD_BL_PIN
 static void lcd_backlight_menu();
+#endif
 
 int8_t ReInitLCD = 0;
 uint8_t scrollstuff = 0;
@@ -123,7 +125,9 @@ static void lcd_tune_menu();
 static void lcd_settings_menu();
 static void lcd_calibration_menu();
 static void lcd_control_temperature_menu();
+#ifdef TMC2130
 static void lcd_settings_linearity_correction_menu_save();
+#endif
 static void prusa_stat_printerstatus(int _status);
 static void prusa_stat_farm_number();
 static void prusa_stat_diameter();
@@ -160,7 +164,6 @@ static void lcd_selftest_v();
 #ifdef TMC2130
 static void reset_crash_det(unsigned char axis);
 static bool lcd_selfcheck_axis_sg(unsigned char axis);
-static bool lcd_selfcheck_axis(int _axis, int _travel);
 #else
 static bool lcd_selfcheck_axis(int _axis, int _travel);
 static bool lcd_selfcheck_pulleys(int axis);
@@ -248,7 +251,9 @@ static void fil_unload_menu();
 #endif // SNMM || SNMM_V2
 static void lcd_disable_farm_mode();
 static void lcd_set_fan_check();
+#ifdef MMU_HAS_CUTTER
 static void lcd_cutter_enabled();
+#endif
 #ifdef SNMM
 static char snmm_stop_print_menu();
 #endif //SNMM
@@ -635,7 +640,7 @@ void lcdui_print_status_line(void)
         case CustomMsg::MeshBedLeveling: // If mesh bed leveling in progress, show the status
             if (custom_message_state > 10) {
                 lcd_set_cursor(0, 3);
-                lcd_space(20);
+                lcd_space(LCD_WIDTH);
                 lcd_puts_at_P(0, 3, _T(MSG_CALIBRATE_Z_AUTO));
                 lcd_puts_P(PSTR(" : "));
                 lcd_print(custom_message_state-10);
@@ -690,7 +695,7 @@ void lcdui_print_status_line(void)
     }
 
     // Fill the rest of line to have nice and clean output
-    for(int fillspace = 0; fillspace < 20; fillspace++)
+    for(int fillspace = 0; fillspace < LCD_WIDTH; fillspace++)
         if ((lcd_status_message[fillspace] <= 31 ))
             lcd_print(' ');
 }
@@ -2090,7 +2095,7 @@ if(lcd_clicked())
           {
           case FilamentAction::AutoLoad:
                eFilamentAction=FilamentAction::None; // i.e. non-autoLoad
-               // no break
+               // FALLTHRU
           case FilamentAction::Load:
                loading_flag=true;
                enquecommand_P(PSTR("M701"));      // load filament
@@ -2201,14 +2206,21 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
     }
     else
     {
-        if (!bFilamentWaitingFlag)
+        if (!bFilamentWaitingFlag || lcd_draw_update)
         {
-            // First run after the filament preheat selection:
-            // setup the fixed LCD parts and raise Z as we wait
+            // First entry from another menu OR first run after the filament preheat selection. Use
+            // bFilamentWaitingFlag to distinguish: this flag is reset exactly once when entering
+            // the menu and is used to raise the carriage *once*. In other cases, the LCD has been
+            // modified elsewhere and needs to be redrawn in full.
+
+            // reset bFilamentWaitingFlag immediately to avoid re-entry from raise_z_above()!
+            bool once = !bFilamentWaitingFlag;
             bFilamentWaitingFlag = true;
 
-            lcd_clear();
+            // also force-enable lcd_draw_update (might be 0 when called from outside a menu)
             lcd_draw_update = 1;
+
+            lcd_clear();
             lcd_puts_at_P(0, 3, _T(MSG_CANCEL)); ////MSG_CANCEL
 
             lcd_set_cursor(0, 1);
@@ -2218,12 +2230,12 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
             case FilamentAction::AutoLoad:
             case FilamentAction::MmuLoad:
                 lcd_puts_P(_i("Preheating to load")); ////MSG_PREHEATING_TO_LOAD c=20
-                raise_z_above(MIN_Z_FOR_LOAD);
+                if (once) raise_z_above(MIN_Z_FOR_LOAD);
                 break;
             case FilamentAction::UnLoad:
             case FilamentAction::MmuUnLoad:
                 lcd_puts_P(_i("Preheating to unload")); ////MSG_PREHEATING_TO_UNLOAD c=20
-                raise_z_above(MIN_Z_FOR_UNLOAD);
+                if (once) raise_z_above(MIN_Z_FOR_UNLOAD);
                 break;
             case FilamentAction::MmuEject:
                 lcd_puts_P(_i("Preheating to eject")); ////MSG_PREHEATING_TO_EJECT c=20
@@ -2419,7 +2431,7 @@ void lcd_change_success() {
 
 static void lcd_loading_progress_bar(uint16_t loading_time_ms) { 
 
-	for (uint_least8_t i = 0; i < 20; i++) {
+	for (uint_least8_t i = 0; i < LCD_WIDTH; i++) {
 		lcd_putc_at(i, 3, '.');
 		//loading_time_ms/20 delay
 		for (uint_least8_t j = 0; j < 5; j++) {
@@ -3332,10 +3344,10 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg,
             // End of the message.
             break;
         lcd_set_cursor(0, row);
-        uint8_t linelen = min(strlen_P(msg), 20);
+        uint8_t linelen = min(strlen_P(msg), LCD_WIDTH);
         const char *msgend2 = msg + linelen;
         msgend = msgend2;
-        if (row == 3 && linelen == 20) {
+        if (row == 3 && linelen == LCD_WIDTH) {
             // Last line of the display, full line shall be displayed.
             // Find out, whether this message will be split into multiple screens.
             while (pgm_is_whitespace(msgend))
@@ -5999,7 +6011,7 @@ char reset_menu() {
     int8_t enc_dif = 0;
 	char cursor_pos = 0;
 
-    const char *const item[items_no] PROGMEM = {PSTR("Language"), PSTR("Statistics"), PSTR("Shipping prep"), PSTR("Service prep"), PSTR("All Data")
+    const char *const item[items_no] = {PSTR("Language"), PSTR("Statistics"), PSTR("Shipping prep"), PSTR("Service prep"), PSTR("All Data")
 #ifdef SNMM
     , PSTR("Bowden length")
 #endif
@@ -7134,8 +7146,8 @@ void lcd_sdcard_menu()
 			_md->fileCnt = card.getnrfilenames();
 			_md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT);
 			_md->menuState = _standard;
-			// FALLTHRU
 		}
+		// FALLTHRU
 		case _standard: //normal menu structure.
 		{
 			if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen.
@@ -7400,7 +7412,7 @@ bool lcd_selftest()
 			break;
 		case FanCheck::SwappedFan:
 			_swapped_fan = true;
-			// no break
+			// FALLTHRU
 		default:
 			_result = true;
 			break;
@@ -7423,7 +7435,7 @@ bool lcd_selftest()
 			break;
 		case FanCheck::SwappedFan:
 			_swapped_fan = true;
-			// no break
+			// FALLTHRU
 		default:
 			_result = true;
 			break;
@@ -8854,25 +8866,28 @@ void menu_lcd_lcdupdate_func(void)
 		lcd_draw_update = 2;
 		lcd_oldcardstatus = IS_SD_INSERTED;
 		lcd_refresh(); // to maybe revive the LCD if static electricity killed it.
-        backlight_wake();
+		backlight_wake();
 		if (lcd_oldcardstatus)
 		{
-			card.initsd();
-               LCD_MESSAGERPGM(_T(WELCOME_MSG));
-               bMain=false;                       // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
-               menu_submenu(lcd_sdcard_menu);
-			//get_description();
+			if (!card.cardOK)
+			{
+				card.initsd(false); //delay the sorting to the sd menu. Otherwise, removing the SD card while sorting will not menu_back()
+				card.presort_flag = true; //force sorting of the SD menu
+			}
+			LCD_MESSAGERPGM(_T(WELCOME_MSG));
+			bMain=false;                       // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
+			menu_submenu(lcd_sdcard_menu);
 		}
 		else
 		{
-               if(menu_menu==lcd_sdcard_menu)
-                    menu_back();
+			if(menu_menu==lcd_sdcard_menu)
+				menu_back();
 			card.release();
 			LCD_MESSAGERPGM(_i("Card removed"));////MSG_SD_REMOVED c=20
 		}
 	}
 #endif//CARDINSERTED
-    backlight_update();
+	backlight_update();
 	if (lcd_next_update_millis < _millis())
 	{
 		if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP)

+ 0 - 6
Firmware/ultralcd.h

@@ -205,12 +205,6 @@ void lcd_printer_connected();
 void lcd_ping();
 
 void lcd_calibrate_extruder();
-void lcd_farm_sdcard_menu();
-
-//void getFileDescription(char *name, char *description);
-
-void lcd_farm_sdcard_menu_w();
-//void get_description();
 
 void lcd_wait_for_heater();
 void lcd_wait_for_cool_down();