diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index d339d3c59c69..76a4f61d1d22 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -163,7 +163,7 @@ //#define CHAMBER_FAN // Enable a fan on the chamber #if ENABLED(CHAMBER_FAN) - #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve. + #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on. #if CHAMBER_FAN_MODE == 0 #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) #elif CHAMBER_FAN_MODE == 1 @@ -172,6 +172,9 @@ #elif CHAMBER_FAN_MODE == 2 #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target + #elif CHAMBER_FAN_MODE == 3 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target #endif #endif @@ -1475,6 +1478,15 @@ // Enable if SD detect is rendered useless (e.g., by using an SD extender) //#define NO_SD_DETECT + // Multiple volume support - EXPERIMENTAL. + //#define MULTI_VOLUME + #if ENABLED(MULTI_VOLUME) + #define VOLUME_SD_ONBOARD + #define VOLUME_USB_FLASH_DRIVE + #define DEFAULT_VOLUME SD_ONBOARD + #define DEFAULT_SHARED_VOLUME USB_FLASH_DRIVE + #endif + #endif // SDSUPPORT /** @@ -2103,6 +2115,15 @@ */ //#define EMERGENCY_PARSER +/** + * Realtime Reporting + * Add support for commands S000 State, P000 Pause, and R000 Resume + */ +//#define REALTIME_REPORTING_COMMANDS +#if ENABLED(REALTIME_REPORTING_COMMANDS) + //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC +#endif + // Bad Serial-connections can miss a received command by sending an 'ok' // Therefore some clients abort after 30 seconds in a timeout. // Some other clients start sending commands while receiving a 'wait'. @@ -2177,6 +2198,12 @@ //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change #endif + /** + * Tool Sensors detect when tools have been picked up or dropped. + * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. + */ + //#define TOOL_SENSOR + /** * Retract and prime filament on tool-change to reduce * ooze and stringing and to get cleaner transitions. @@ -2653,22 +2680,22 @@ * { , , hysteresis_start[1..8] } */ #define CHOPPER_TIMING CHOPPER_DEFAULT_24V // All axes (override below) - //#define CHOPPER_TIMING_X CHOPPER_DEFAULT_12V // For X Axes (override below) - //#define CHOPPER_TIMING_X2 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_12V // For Y Axes (override below) - //#define CHOPPER_TIMING_Y2 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_Z CHOPPER_DEFAULT_12V // For Z Axes (override below) - //#define CHOPPER_TIMING_Z2 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_Z3 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_Z4 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E CHOPPER_DEFAULT_12V // For Extruders (override below) - //#define CHOPPER_TIMING_E1 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E2 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E3 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E4 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E5 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E6 CHOPPER_DEFAULT_12V - //#define CHOPPER_TIMING_E7 CHOPPER_DEFAULT_12V + //#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below) + //#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X + //#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below) + //#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y + //#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below) + //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below) + //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E /** * Monitor Trinamic drivers @@ -3303,13 +3330,18 @@ */ //#define POWER_MONITOR_CURRENT // Monitor the system current //#define POWER_MONITOR_VOLTAGE // Monitor the system voltage -#if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) - #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! - #define POWER_MONITOR_CURRENT_OFFSET -1 // Offset value for current sensors with linear function output - #define POWER_MONITOR_VOLTS_PER_VOLT 0.11786 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! + +#if ENABLED(POWER_MONITOR_CURRENT) + #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) #endif +#if ENABLED(POWER_MONITOR_VOLTAGE) + #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage +#endif + /** * CNC Coordinate Systems * diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp index d92d332c1efd..3dcbbaecd28f 100644 --- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp +++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp @@ -32,7 +32,7 @@ Ctrl_status sd_mmc_spi_test_unit_ready() { Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) { if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) return CTRL_NO_PRESENT; - *nb_sector = card.getSd2Card().cardSize() - 1; + *nb_sector = card.diskIODriver()->cardSize() - 1; return CTRL_GOOD; } @@ -74,24 +74,24 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) { #endif // Start reading - if (!card.getSd2Card().readStart(addr)) + if (!card.diskIODriver()->readStart(addr)) return CTRL_FAIL; // For each specified sector while (nb_sector--) { // Read a sector - card.getSd2Card().readData(sector_buf); + card.diskIODriver()->readData(sector_buf); // RAM -> USB if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) { - card.getSd2Card().readStop(); + card.diskIODriver()->readStop(); return CTRL_FAIL; } } // Stop reading - card.getSd2Card().readStop(); + card.diskIODriver()->readStop(); // Done return CTRL_GOOD; @@ -113,7 +113,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) { } #endif - if (!card.getSd2Card().writeStart(addr, nb_sector)) + if (!card.diskIODriver()->writeStart(addr, nb_sector)) return CTRL_FAIL; // For each specified sector @@ -121,16 +121,16 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) { // USB -> RAM if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) { - card.getSd2Card().writeStop(); + card.diskIODriver()->writeStop(); return CTRL_FAIL; } // Write a sector - card.getSd2Card().writeData(sector_buf); + card.diskIODriver()->writeData(sector_buf); } // Stop writing - card.getSd2Card().writeStop(); + card.diskIODriver()->writeStop(); // Done return CTRL_GOOD; diff --git a/Marlin/src/HAL/DUE/usb/usb_task.c b/Marlin/src/HAL/DUE/usb/usb_task.c index acb1d5b933ba..54a808d7f4f1 100644 --- a/Marlin/src/HAL/DUE/usb/usb_task.c +++ b/Marlin/src/HAL/DUE/usb/usb_task.c @@ -322,7 +322,7 @@ void usb_task_init(void) { char *sptr; // Patch in the filament diameter - sprintf_P(diam, PSTR("%d"), (int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000.0)); + itoa((int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000), diam, 10); // And copy it to the proper place, expanding it to unicode sptr = &diam[0]; diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp index 7dc909b6ea23..3cb4e9d03af4 100644 --- a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp +++ b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp @@ -86,8 +86,8 @@ #define SDIO_CMD_PIN PD2 SD_HandleTypeDef hsd; // create SDIO structure - // F4 support one dma for RX and another for TX. - // But Marlin will never do read and write at same time, so we use always one dma for both. + // F4 supports one DMA for RX and another for TX, but Marlin will never + // do read and write at same time, so we use the same DMA for both. DMA_HandleTypeDef hdma_sdio; /* @@ -275,7 +275,7 @@ } static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) { - if(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false; + if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false; TERN_(USE_WATCHDOG, HAL_watchdog_refresh()); @@ -297,10 +297,10 @@ return false; } - uint32_t timeout = millis() + 500; + millis_t timeout = millis() + 500; // Wait the transfer while (hsd.State != HAL_SD_STATE_READY) { - if (millis() > timeout) { + if (ELAPSED(millis(), timeout)) { HAL_DMA_Abort_IT(&hdma_sdio); HAL_DMA_DeInit(&hdma_sdio); return false; @@ -314,8 +314,7 @@ HAL_DMA_DeInit(&hdma_sdio); timeout = millis() + 500; - while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) - if (millis() > timeout) return false; + while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (ELAPSED(millis(), timeout)) return false; return true; } diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index 63ce7808f183..20e1ab3cf96c 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -30,54 +30,66 @@ class Sd2CardUSBMscHandler : public USBMscHandler { public: + DiskIODriver* diskIODriver() { + #if ENABLED(MULTI_VOLUME) + #if SHARED_VOLUME_IS(SD_ONBOARD) + return &card.media_sd_spi; + #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) + return &card.media_usbFlashDrive; + #endif + #else + return diskIODriver(); + #endif + } + bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) { - *pBlockNum = card.getSd2Card().cardSize(); + *pBlockNum = diskIODriver()->cardSize(); *pBlockSize = BLOCK_SIZE; return true; } bool Write(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { - auto sd2card = card.getSd2Card(); + auto sd2card = diskIODriver(); // single block if (blkLen == 1) { watchdog_refresh(); - sd2card.writeBlock(blkAddr, pBuf); + sd2card->writeBlock(blkAddr, pBuf); return true; } // multi block optmization - sd2card.writeStart(blkAddr, blkLen); + sd2card->writeStart(blkAddr, blkLen); while (blkLen--) { watchdog_refresh(); - sd2card.writeData(pBuf); + sd2card->writeData(pBuf); pBuf += BLOCK_SIZE; } - sd2card.writeStop(); + sd2card->writeStop(); return true; } bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { - auto sd2card = card.getSd2Card(); + auto sd2card = diskIODriver(); // single block if (blkLen == 1) { watchdog_refresh(); - sd2card.readBlock(blkAddr, pBuf); + sd2card->readBlock(blkAddr, pBuf); return true; } // multi block optmization - sd2card.readStart(blkAddr); + sd2card->readStart(blkAddr); while (blkLen--) { watchdog_refresh(); - sd2card.readData(pBuf); + sd2card->readData(pBuf); pBuf += BLOCK_SIZE; } - sd2card.readStop(); + sd2card->readStop(); return true; } bool IsReady() { - return card.isMounted(); + return diskIODriver()->isReady(); } }; @@ -105,8 +117,8 @@ USBMscHandler *pSingleMscHandler = &usbMscHandler; void MSC_SD_init() { USBDevice.end(); delay(200); - USBDevice.begin(); USBDevice.registerMscHandlers(1, &pSingleMscHandler, Marlin_STORAGE_Inquirydata); + USBDevice.begin(); } #endif // __STM32F1__ && HAS_SD_HOST_DRIVE diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index 4f430ab4d9cb..94b0ad7ead83 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -53,7 +53,7 @@ // ------------------------ #ifndef STM32_FLASH_SIZE - #if EITHER(MCU_STM32F103RE, MCU_STM32F103VE) + #if ANY(MCU_STM32F103RE, MCU_STM32F103VE, MCU_STM32F103ZE) #define STM32_FLASH_SIZE 512 #else #define STM32_FLASH_SIZE 256 diff --git a/Marlin/src/HAL/shared/cpu_exception/exception_arm.cpp b/Marlin/src/HAL/shared/cpu_exception/exception_arm.cpp index ae9600038a3f..124f0b7c43c6 100644 --- a/Marlin/src/HAL/shared/cpu_exception/exception_arm.cpp +++ b/Marlin/src/HAL/shared/cpu_exception/exception_arm.cpp @@ -320,8 +320,8 @@ void hook_cpu_exceptions() { // So we'll simply mask the top 8 bits of the first handler as an hint of being in the flash or not -that's poor and will // probably break if the flash happens to be more than 128MB, but in this case, we are not magician, we need help from outside. - unsigned long * vecAddr = (unsigned long*)get_vtor(); - SERIAL_ECHO("Vector table addr: "); + unsigned long *vecAddr = (unsigned long*)get_vtor(); + SERIAL_ECHOPGM("Vector table addr: "); SERIAL_PRINTLN(get_vtor(), HEX); #ifdef VECTOR_TABLE_SIZE @@ -348,7 +348,7 @@ void hook_cpu_exceptions() { // 128 bytes alignement is required for writing the VTOR register alignas(128) static unsigned long vectable[VECTOR_TABLE_SENTINEL]; - SERIAL_ECHO("Detected vector table size: "); + SERIAL_ECHOPGM("Detected vector table size: "); SERIAL_PRINTLN(vec_size, HEX); #endif @@ -372,7 +372,7 @@ void hook_cpu_exceptions() { HW_REG(0xE000ED08) = (unsigned long)vectable | _BV32(29); // 29th bit is for telling the CPU the table is now in SRAM (should be present already) - SERIAL_ECHOLN("Installed fault handlers"); + SERIAL_ECHOLNPGM("Installed fault handlers"); #endif } diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 75cf8eeed8b4..28a121decb07 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -210,9 +210,7 @@ #include "feature/fanmux.h" #endif -#if DO_SWITCH_EXTRUDER || ANY(SWITCHING_NOZZLE, PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER, ELECTROMAGNETIC_SWITCHING_TOOLHEAD, SWITCHING_TOOLHEAD) - #include "module/tool_change.h" -#endif +#include "module/tool_change.h" #if ENABLED(USE_CONTROLLER_FAN) #include "feature/controllerfan.h" @@ -731,6 +729,9 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) { // Return if setup() isn't completed if (marlin_state == MF_INITIALIZING) goto IDLE_DONE; + // TODO: Still causing errors + (void)check_tool_sensor_stats(active_extruder, true); + // Handle filament runout sensors TERN_(HAS_FILAMENT_SENSOR, runout.run()); @@ -757,7 +758,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) { TERN_(SDSUPPORT, card.manage_media()); // Handle USB Flash Drive insert / remove - TERN_(USB_FLASH_DRIVE_SUPPORT, Sd2Card::idle()); + TERN_(USB_FLASH_DRIVE_SUPPORT, card.diskIODriver()->idle()); // Announce Host Keepalive state (if any) TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive()); diff --git a/Marlin/src/core/bug_on.h b/Marlin/src/core/bug_on.h index 3c9dec0f96e0..cc745f259b7b 100644 --- a/Marlin/src/core/bug_on.h +++ b/Marlin/src/core/bug_on.h @@ -28,11 +28,11 @@ // This is used like SERIAL_ECHOPAIR, that is: a key-value call of the local variables you want // to dump to the serial port before stopping the CPU. // \/ Don't replace by SERIAL_ECHOPAIR since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building - #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLN(": "); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0) + #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": "); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0) #elif ENABLED(MARLIN_DEV_MODE) // Don't stop the CPU here, but at least dump the bug on the serial port // \/ Don't replace by SERIAL_ECHOPAIR since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building - #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLN(": BUG!"); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); } while(0) + #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": BUG!"); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); } while(0) #else // Release mode, let's ignore the bug #define BUG_ON(V...) NOOP diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h index eadcc28aa478..1ae8135458f3 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h @@ -114,9 +114,10 @@ class mesh_bed_leveling { const float x1 = index_to_xpos[ind.x], x2 = index_to_xpos[ind.x+1], y1 = index_to_xpos[ind.y], y2 = index_to_xpos[ind.y+1], z1 = calc_z0(pos.x, x1, z_values[ind.x][ind.y ], x2, z_values[ind.x+1][ind.y ]), - z2 = calc_z0(pos.x, x1, z_values[ind.x][ind.y+1], x2, z_values[ind.x+1][ind.y+1]); + z2 = calc_z0(pos.x, x1, z_values[ind.x][ind.y+1], x2, z_values[ind.x+1][ind.y+1]), + zf = calc_z0(pos.y, y1, z1, y2, z2); - return z_offset + calc_z0(pos.y, y1, z1, y2, z2) * factor; + return z_offset + zf * factor; } #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index dd6c2613410f..0a758a57e9f9 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -264,24 +264,10 @@ class unified_bed_leveling { return UBL_Z_RAISE_WHEN_OFF_MESH; #endif - const float z1 = calc_z0(rx0, - mesh_index_to_xpos(cx), z_values[cx][cy], - mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, (GRID_MAX_POINTS_X) - 2) + 1][cy]); - - const float z2 = calc_z0(rx0, - mesh_index_to_xpos(cx), z_values[cx][_MIN(cy, (GRID_MAX_POINTS_Y) - 2) + 1], - mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, (GRID_MAX_POINTS_X) - 2) + 1][_MIN(cy, (GRID_MAX_POINTS_Y) - 2) + 1]); - - float z0 = calc_z0(ry0, - mesh_index_to_ypos(cy), z1, - mesh_index_to_ypos(cy + 1), z2); - - if (DEBUGGING(MESH_ADJUST)) { - DEBUG_ECHOPAIR(" raw get_z_correction(", rx0); - DEBUG_CHAR(','); DEBUG_ECHO(ry0); - DEBUG_ECHOPAIR_F(") = ", z0, 6); - DEBUG_ECHOLNPAIR_F(" >>>---> ", z0, 6); - } + const uint8_t mx = _MIN(cx, (GRID_MAX_POINTS_X) - 2) + 1, my = _MIN(cy, (GRID_MAX_POINTS_Y) - 2) + 1; + const float z1 = calc_z0(rx0, mesh_index_to_xpos(cx), z_values[cx][cy], mesh_index_to_xpos(cx + 1), z_values[mx][cy]); + const float z2 = calc_z0(rx0, mesh_index_to_xpos(cx), z_values[cx][my], mesh_index_to_xpos(cx + 1), z_values[mx][my]); + float z0 = calc_z0(ry0, mesh_index_to_ypos(cy), z1, mesh_index_to_ypos(cy + 1), z2); if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN z0 = 0.0; // in ubl.z_values[][] and propagate through the @@ -289,14 +275,14 @@ class unified_bed_leveling { // because part of the Mesh is undefined and we don't have the // information we need to complete the height correction. - if (DEBUGGING(MESH_ADJUST)) { - DEBUG_ECHOPAIR("??? Yikes! NAN in get_z_correction(", rx0); - DEBUG_CHAR(','); - DEBUG_ECHO(ry0); - DEBUG_CHAR(')'); - DEBUG_EOL(); - } + if (DEBUGGING(MESH_ADJUST)) DEBUG_ECHOLNPAIR("??? Yikes! NAN in "); } + + if (DEBUGGING(MESH_ADJUST)) { + DEBUG_ECHOPAIR("get_z_correction(", rx0, ", ", ry0); + DEBUG_ECHOLNPAIR_F(") => ", z0, 6); + } + return z0; } static inline float get_z_correction(const xy_pos_t &pos) { return get_z_correction(pos.x, pos.y); } diff --git a/Marlin/src/feature/e_parser.h b/Marlin/src/feature/e_parser.h index 659e516787fc..c12fd14ad193 100644 --- a/Marlin/src/feature/e_parser.h +++ b/Marlin/src/feature/e_parser.h @@ -34,29 +34,33 @@ // External references extern bool wait_for_user, wait_for_heatup; +#if ENABLED(REALTIME_REPORTING_COMMANDS) + // From motion.h, which cannot be included here + void report_current_position_moving(); + void quickpause_stepper(); + void quickresume_stepper(); +#endif + class EmergencyParser { public: - // Currently looking for: M108, M112, M410, M876 - enum State : char { + // Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000 + enum State : uint8_t { EP_RESET, EP_N, EP_M, EP_M1, - EP_M10, - EP_M108, - EP_M11, - EP_M112, - EP_M4, - EP_M41, - EP_M410, + EP_M10, EP_M108, + EP_M11, EP_M112, + EP_M4, EP_M41, EP_M410, #if ENABLED(HOST_PROMPT_SUPPORT) - EP_M8, - EP_M87, - EP_M876, - EP_M876S, - EP_M876SN, + EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN, + #endif + #if ENABLED(REALTIME_REPORTING_COMMANDS) + EP_S, EP_S0, EP_S00, EP_GRBL_STATUS, + EP_R, EP_R0, EP_R00, EP_GRBL_RESUME, + EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE, #endif EP_IGNORE // to '\n' }; @@ -71,7 +75,6 @@ class EmergencyParser { EmergencyParser() { enable(); } FORCE_INLINE static void enable() { enabled = true; } - FORCE_INLINE static void disable() { enabled = false; } FORCE_INLINE static void update(State &state, const uint8_t c) { @@ -79,21 +82,45 @@ class EmergencyParser { case EP_RESET: switch (c) { case ' ': case '\n': case '\r': break; - case 'N': state = EP_N; break; - case 'M': state = EP_M; break; - default: state = EP_IGNORE; + case 'N': state = EP_N; break; + case 'M': state = EP_M; break; + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case 'S': state = EP_S; break; + case 'P': state = EP_P; break; + case 'R': state = EP_R; break; + #endif + default: state = EP_IGNORE; } break; case EP_N: switch (c) { case '0' ... '9': - case '-': case ' ': break; - case 'M': state = EP_M; break; - default: state = EP_IGNORE; + case '-': case ' ': break; + case 'M': state = EP_M; break; + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case 'S': state = EP_S; break; + case 'P': state = EP_P; break; + case 'R': state = EP_R; break; + #endif + default: state = EP_IGNORE; } break; + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case EP_S: state = (c == '0') ? EP_S0 : EP_IGNORE; break; + case EP_S0: state = (c == '0') ? EP_S00 : EP_IGNORE; break; + case EP_S00: state = (c == '0') ? EP_GRBL_STATUS : EP_IGNORE; break; + + case EP_R: state = (c == '0') ? EP_R0 : EP_IGNORE; break; + case EP_R0: state = (c == '0') ? EP_R00 : EP_IGNORE; break; + case EP_R00: state = (c == '0') ? EP_GRBL_RESUME : EP_IGNORE; break; + + case EP_P: state = (c == '0') ? EP_P0 : EP_IGNORE; break; + case EP_P0: state = (c == '0') ? EP_P00 : EP_IGNORE; break; + case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break; + #endif + case EP_M: switch (c) { case ' ': break; @@ -114,48 +141,34 @@ class EmergencyParser { } break; - case EP_M10: - state = (c == '8') ? EP_M108 : EP_IGNORE; - break; - - case EP_M11: - state = (c == '2') ? EP_M112 : EP_IGNORE; - break; - - case EP_M4: - state = (c == '1') ? EP_M41 : EP_IGNORE; - break; - - case EP_M41: - state = (c == '0') ? EP_M410 : EP_IGNORE; - break; + case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break; + case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break; + case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break; + case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break; #if ENABLED(HOST_PROMPT_SUPPORT) - case EP_M8: - state = (c == '7') ? EP_M87 : EP_IGNORE; - break; - case EP_M87: - state = (c == '6') ? EP_M876 : EP_IGNORE; - break; + case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break; + case EP_M87: state = (c == '6') ? EP_M876 : EP_IGNORE; break; - case EP_M876: - switch (c) { - case ' ': break; - case 'S': state = EP_M876S; break; - default: state = EP_IGNORE; break; - } - break; + case EP_M876: + switch (c) { + case ' ': break; + case 'S': state = EP_M876S; break; + default: state = EP_IGNORE; break; + } + break; + + case EP_M876S: + switch (c) { + case ' ': break; + case '0' ... '9': + state = EP_M876SN; + M876_reason = uint8_t(c - '0'); + break; + } + break; - case EP_M876S: - switch (c) { - case ' ': break; - case '0' ... '9': - state = EP_M876SN; - M876_reason = (uint8_t)(c - '0'); - break; - } - break; #endif case EP_IGNORE: @@ -171,6 +184,11 @@ class EmergencyParser { #if ENABLED(HOST_PROMPT_SUPPORT) case EP_M876SN: host_response_handler(M876_reason); break; #endif + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case EP_GRBL_STATUS: report_current_position_moving(); break; + case EP_GRBL_PAUSE: quickpause_stepper(); break; + case EP_GRBL_RESUME: quickresume_stepper(); break; + #endif default: break; } state = EP_RESET; diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 5990c09a90b8..8a1701d0b694 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -597,11 +597,13 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_ unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); if (!axes_should_home()) { - // Move XY to starting position, then Z - do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); + // Move XY back to saved position + destination.set(resume_position.x, resume_position.y, current_position.z); + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); - // Move Z_AXIS to saved position - do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); + // Move Z back to saved position + destination.z = resume_position.z; + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); } // Unretract diff --git a/Marlin/src/feature/power_monitor.cpp b/Marlin/src/feature/power_monitor.cpp index 97c4a933637e..1937a54102a8 100644 --- a/Marlin/src/feature/power_monitor.cpp +++ b/Marlin/src/feature/power_monitor.cpp @@ -26,8 +26,11 @@ #include "power_monitor.h" -#include "../lcd/marlinui.h" -#include "../lcd/lcdprint.h" +#if HAS_LCD_MENU + #include "../lcd/marlinui.h" + #include "../lcd/lcdprint.h" +#endif + #include "../libs/numtostr.h" uint8_t PowerMonitor::flags; // = 0 @@ -54,7 +57,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor } #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) void PowerMonitor::draw_voltage() { const float volts = getVolts(); lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts)); diff --git a/Marlin/src/feature/power_monitor.h b/Marlin/src/feature/power_monitor.h index f378ee2a107c..f6e0b292e30c 100644 --- a/Marlin/src/feature/power_monitor.h +++ b/Marlin/src/feature/power_monitor.h @@ -23,7 +23,7 @@ #include "../inc/MarlinConfig.h" -#define PM_SAMPLE_RANGE 1024 +#define PM_SAMPLE_RANGE HAL_ADC_RANGE #define PM_K_VALUE 6 #define PM_K_SCALE 6 @@ -35,7 +35,7 @@ struct pm_lpf_t { filter_buf = filter_buf - (filter_buf >> K_VALUE) + (uint32_t(sample) << K_SCALE); } void capture() { - value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE)))) + (POWER_MONITOR_CURRENT_OFFSET); + value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE)))); } void reset(uint16_t reset_value = 0) { filter_buf = uint32_t(reset_value) << (K_VALUE + K_SCALE); @@ -69,19 +69,15 @@ class PowerMonitor { }; #if ENABLED(POWER_MONITOR_CURRENT) - FORCE_INLINE static float getAmps() { return amps.value; } + FORCE_INLINE static float getAmps() { return amps.value + (POWER_MONITOR_CURRENT_OFFSET); } void add_current_sample(const uint16_t value) { amps.add_sample(value); } #endif - #if HAS_POWER_MONITOR_VREF - #if ENABLED(POWER_MONITOR_VOLTAGE) - FORCE_INLINE static float getVolts() { return volts.value; } - #else - FORCE_INLINE static float getVolts() { return POWER_MONITOR_FIXED_VOLTAGE; } // using a specified fixed valtage as the voltage measurement - #endif - #if ENABLED(POWER_MONITOR_VOLTAGE) - void add_voltage_sample(const uint16_t value) { volts.add_sample(value); } - #endif + #if ENABLED(POWER_MONITOR_VOLTAGE) + FORCE_INLINE static float getVolts() { return volts.value + (POWER_MONITOR_VOLTAGE_OFFSET); } + void add_voltage_sample(const uint16_t value) { volts.add_sample(value); } + #else + FORCE_INLINE static float getVolts() { return POWER_MONITOR_FIXED_VOLTAGE; } #endif #if HAS_POWER_MONITOR_WATTS @@ -98,7 +94,7 @@ class PowerMonitor { FORCE_INLINE static void set_current_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_I, b); } FORCE_INLINE static void toggle_current_display() { TBI(flags, PM_DISP_BIT_I); } #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) static void draw_voltage(); FORCE_INLINE static bool voltage_display_enabled() { return TEST(flags, PM_DISP_BIT_V); } FORCE_INLINE static void set_voltage_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_V, b); } diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 657f906c14de..fe039def7360 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -205,8 +205,8 @@ typedef struct { layer_height = MESH_TEST_LAYER_HEIGHT, prime_length = PRIME_LENGTH; - int16_t bed_temp = MESH_TEST_BED_TEMP, - hotend_temp = MESH_TEST_HOTEND_TEMP; + celsius_t bed_temp = MESH_TEST_BED_TEMP, + hotend_temp = MESH_TEST_HOTEND_TEMP; float nozzle = MESH_TEST_NOZZLE_SIZE, filament_diameter = DEFAULT_NOMINAL_FILAMENT_DIA, diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 654a381383f3..735fad015e6e 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -217,9 +217,10 @@ class G29_State { * There's no extra effect if you have a fixed Z probe. */ G29_TYPE GcodeSuite::G29() { - TERN_(PROBE_MANUALLY, static) G29_State abl; + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); + reset_stepper_timeout(); const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen('Q'); @@ -897,7 +898,10 @@ G29_TYPE GcodeSuite::G29() { report_current_position(); + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); + G29_RETURN(isnan(abl.measured_z)); + } #endif // HAS_ABL_NOT_UBL diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index 1ec514c3ec3b..2da584fd49f1 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -60,6 +60,8 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM(" */ void GcodeSuite::G29() { + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); + static int mbl_probe_index = -1; MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport); @@ -187,6 +189,8 @@ void GcodeSuite::G29() { } report_current_position(); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); } #endif // MESH_BED_LEVELING diff --git a/Marlin/src/gcode/bedlevel/ubl/G29.cpp b/Marlin/src/gcode/bedlevel/ubl/G29.cpp index 2ef3ab4ceca9..932503d72b97 100644 --- a/Marlin/src/gcode/bedlevel/ubl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/ubl/G29.cpp @@ -31,6 +31,17 @@ #include "../../gcode.h" #include "../../../feature/bedlevel/bedlevel.h" -void GcodeSuite::G29() { ubl.G29(); } +#if ENABLED(FULL_REPORT_TO_HOST_FEATURE) + #include "../../../module/motion.h" +#endif + +void GcodeSuite::G29() { + + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); + + ubl.G29(); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); +} #endif // AUTO_BED_LEVELING_UBL diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 73bfc3bdc6c0..10e094cba7c5 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -211,6 +211,8 @@ void GcodeSuite::G28() { TERN_(LASER_MOVE_G28_OFF, cutter.set_inline_enabled(false)); // turn off laser + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOMING)); + #if ENABLED(DUAL_X_CARRIAGE) bool IDEX_saved_duplication_state = extruder_duplication_enabled; DualXMode IDEX_saved_mode = dual_x_carriage_mode; @@ -479,6 +481,8 @@ void GcodeSuite::G28() { if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS))) SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); + #if HAS_L64XX // Set L6470 absolute position registers to counts // constexpr *might* move this to PROGMEM. diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index 1b8eb889c64d..d60099a33006 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -387,6 +387,8 @@ static float auto_tune_a() { */ void GcodeSuite::G33() { + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); + const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); if (!WITHIN(probe_points, 0, 10)) { SERIAL_ECHOLNPGM("?(P)oints implausible (0-10)."); @@ -645,6 +647,8 @@ void GcodeSuite::G33() { while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index)); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); } #endif // DELTA_AUTO_CALIBRATION diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp index 9a2b77493667..6be63346dc39 100644 --- a/Marlin/src/gcode/feature/pause/M701_M702.cpp +++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp @@ -88,9 +88,17 @@ void GcodeSuite::M701() { tool_change(target_extruder, false); #endif - // Lift Z axis - if (park_point.z > 0) - do_blocking_move_to_z(_MIN(current_position.z + park_point.z, Z_MAX_POS), feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); + auto move_z_by = [](const_float_t zdist) { + if (zdist) { + destination = current_position; + destination.z += zdist; + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + } + }; + + // Raise the Z axis (with max limit) + const float park_raise = _MIN(0, park_point.z, (Z_MAX_POS) - current_position.z); + move_z_by(park_raise); // Load filament #if HAS_PRUSA_MMU2 @@ -113,8 +121,7 @@ void GcodeSuite::M701() { #endif // Restore Z axis - if (park_point.z > 0) - do_blocking_move_to_z(_MAX(current_position.z - park_point.z, 0), feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); + move_z_by(-park_raise); #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU) // Restore toolhead if it was changed diff --git a/Marlin/src/gcode/feature/power_monitor/M430.cpp b/Marlin/src/gcode/feature/power_monitor/M430.cpp index 9559404456f5..34430fbc388e 100644 --- a/Marlin/src/gcode/feature/power_monitor/M430.cpp +++ b/Marlin/src/gcode/feature/power_monitor/M430.cpp @@ -42,7 +42,7 @@ void GcodeSuite::M430() { #if ENABLED(POWER_MONITOR_CURRENT) if (parser.seen('I')) { power_monitor.set_current_display(parser.value_bool()); do_report = false; } #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) if (parser.seen('V')) { power_monitor.set_voltage_display(parser.value_bool()); do_report = false; } #endif #if HAS_POWER_MONITOR_WATTS @@ -53,11 +53,11 @@ void GcodeSuite::M430() { SERIAL_ECHOLNPAIR( #if ENABLED(POWER_MONITOR_CURRENT) "Current: ", power_monitor.getAmps(), "A" - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) " " #endif #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) "Voltage: ", power_monitor.getVolts(), "V" #endif #if HAS_POWER_MONITOR_WATTS diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 574e93aeccc3..efea0876027e 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -289,8 +289,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { } #endif - // Handle a known G, M, or T + // Handle a known command or reply "unknown command" + switch (parser.command_letter) { + case 'G': switch (parser.codenum) { case 0: case 1: // G0: Fast Move, G1: Linear Move @@ -995,6 +997,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 'D': D(parser.codenum); break; // Dn: Debug codes #endif + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case 'S': case 'P': case 'R': break; // Invalid S, P, R commands already filtered + #endif + default: #if ENABLED(WIFI_CUSTOM_COMMAND) if (wifi_custom_command(parser.command_ptr)) break; @@ -1087,12 +1093,15 @@ void GcodeSuite::process_subcommands_now(char * gcode) { case IN_HANDLER: case IN_PROCESS: SERIAL_ECHO_MSG(STR_BUSY_PROCESSING); + TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_position_moving()); break; case PAUSED_FOR_USER: SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER); + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD)); break; case PAUSED_FOR_INPUT: SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_INPUT); + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD)); break; default: break; diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp index 75356ff66fee..dd62f0ad2e26 100644 --- a/Marlin/src/gcode/host/M114.cpp +++ b/Marlin/src/gcode/host/M114.cpp @@ -176,6 +176,8 @@ const xyze_float_t diff = from_steppers - leveled; SERIAL_ECHOPGM("Diff: "); report_xyze(diff); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving()); } #endif // M114_DETAIL @@ -211,4 +213,6 @@ void GcodeSuite::M114() { TERN_(M114_LEGACY, planner.synchronize()); report_current_position_projected(); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving()); } diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp index 9ac49bd93cf1..64c07d1d8908 100644 --- a/Marlin/src/gcode/motion/G0_G1.cpp +++ b/Marlin/src/gcode/motion/G0_G1.cpp @@ -54,6 +54,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { | (parser.seen('Z') ? _BV(Z_AXIS) : 0) ) #endif ) { + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING)); #ifdef G0_FEEDRATE feedRate_t old_feedrate; @@ -116,6 +117,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { planner.synchronize(); SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); } + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); + #else + TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving()); #endif } } diff --git a/Marlin/src/gcode/motion/G2_G3.cpp b/Marlin/src/gcode/motion/G2_G3.cpp index 61e50247f3f7..5a8324362a26 100644 --- a/Marlin/src/gcode/motion/G2_G3.cpp +++ b/Marlin/src/gcode/motion/G2_G3.cpp @@ -306,6 +306,8 @@ void plan_arc( void GcodeSuite::G2_G3(const bool clockwise) { if (MOTION_CONDITIONS) { + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING)); + #if ENABLED(SF_ARC_FIX) const bool relative_mode_backup = relative_mode; relative_mode = true; @@ -364,6 +366,8 @@ void GcodeSuite::G2_G3(const bool clockwise) { } else SERIAL_ERROR_MSG(STR_ERR_ARC_ARGS); + + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); } } diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index f7812bf3f630..8cbbe1d19d6d 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -106,8 +106,10 @@ void GCodeParser::reset() { #endif -// Populate all fields by parsing a single line of GCode -// 58 bytes of SRAM are used to speed up seen/value +/** + * Populate the command line state (command_letter, codenum, subcode, and string_arg) + * by parsing a single line of GCode. 58 bytes of SRAM are used to speed up seen/value. + */ void GCodeParser::parse(char *p) { reset(); // No codes to report @@ -147,10 +149,12 @@ void GCodeParser::parse(char *p) { #define SIGNED_CODENUM 1 #endif - // Bail if the letter is not G, M, or T - // (or a valid parameter for the current motion mode) + /** + * Screen for good command letters. G, M, and T are always accepted. + * With Motion Modes enabled any axis letter can come first. + * With Realtime Reporting, commands S000, P000, and R000 are allowed. + */ switch (letter) { - case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) // Skip spaces to get the numeric part while (*p == ' ') p++; @@ -213,10 +217,10 @@ void GCodeParser::parse(char *p) { #if ENABLED(GCODE_MOTION_MODES) #if ENABLED(ARC_SUPPORT) - case 'I' ... 'J': case 'R': + case 'I' ... 'J': if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return; #endif - case 'P' ... 'Q': + case 'Q': if (motion_mode_codenum != 5) return; case 'X' ... 'Z': case 'E' ... 'F': if (motion_mode_codenum < 0) return; @@ -225,7 +229,24 @@ void GCodeParser::parse(char *p) { TERN_(USE_GCODE_SUBCODES, subcode = motion_mode_subcode); p--; // Back up one character to use the current parameter break; - #endif // GCODE_MOTION_MODES + #endif + + #if ENABLED(REALTIME_REPORTING_COMMANDS) + case 'P': case 'R': { + if (letter == 'R') { + #if ENABLED(GCODE_MOTION_MODES) + if (ENABLED(ARC_SUPPORT) && !WITHIN(motion_mode_codenum, 2, 3)) return; + #endif + } + else if (TERN0(GCODE_MOTION_MODES, motion_mode_codenum != 5)) return; + } // fall-thru + case 'S': { + codenum = 0; // The only valid codenum is 0 + uint8_t digits = 0; + while (*p++ == '0') digits++; // Count up '0' characters + command_letter = (digits == 3) ? letter : '?'; // Three '0' digits is a good command + } return; // No parameters needed, so return now + #endif default: return; } diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 2177dc48611d..735e6464d93f 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -245,7 +245,7 @@ #define _CUTTER_POWER_PERCENT 2 #define _CUTTER_POWER_RPM 3 #define _CUTTER_POWER(V) _CAT(_CUTTER_POWER_, V) - #define CUTTER_UNIT_IS(V) (_CUTTER_POWER(CUTTER_POWER_UNIT) == _CUTTER_POWER(V)) + #define CUTTER_UNIT_IS(V) (_CUTTER_POWER(CUTTER_POWER_UNIT) == _CUTTER_POWER(V)) #endif // Add features that need hardware PWM here @@ -498,12 +498,9 @@ // Power Monitor sensors #if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) #define HAS_POWER_MONITOR 1 -#endif -#if ENABLED(POWER_MONITOR_CURRENT) && defined(POWER_MONITOR_FIXED_VOLTAGE) - #define HAS_POWER_MONITOR_VREF 1 -#endif -#if BOTH(HAS_POWER_MONITOR_VREF, POWER_MONITOR_CURRENT) - #define HAS_POWER_MONITOR_WATTS 1 + #if ENABLED(POWER_MONITOR_CURRENT) && (ENABLED(POWER_MONITOR_VOLTAGE) || defined(POWER_MONITOR_FIXED_VOLTAGE)) + #define HAS_POWER_MONITOR_WATTS 1 + #endif #endif // Flag if an EEPROM type is pre-selected diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 0169039426d5..82d6d1f0dd6c 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -357,6 +357,15 @@ #define SD_DETECT_STATE LOW #endif #endif + + #if DISABLED(USB_FLASH_DRIVE_SUPPORT) || BOTH(MULTI_VOLUME, VOLUME_SD_ONBOARD) + #if ENABLED(SDIO_SUPPORT) + #define NEED_SD2CARD_SDIO 1 + #else + #define NEED_SD2CARD_SPI 1 + #endif + #endif + #endif #if ANY(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 0db2a080d48d..a598a3154c49 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-04-11" + #define STRING_DISTRIBUTION_DATE "2021-04-18" #endif /** diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index 98ca1c093075..6ed4d3363092 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -684,12 +684,15 @@ void MarlinUI::draw_status_message(const bool blink) { // If the remaining string doesn't completely fill the screen if (rlen < LCD_WIDTH) { - lcd_put_wchar('.'); // Always at 1+ spaces left, draw a dot uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters - if (--chars) { // Draw a second dot if there's space - lcd_put_wchar('.'); - if (--chars) - lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + lcd_put_wchar(' '); // Always at 1+ spaces left, draw a space + if (--chars) { // Draw a second space if there's room + lcd_put_wchar(' '); + if (--chars) { // Draw a third space if there's room + lcd_put_wchar(' '); + if (--chars) + lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + } } } if (last_blink != blink) { @@ -944,7 +947,7 @@ void MarlinUI::draw_status_screen() { #if ENABLED(ADAPTIVE_FAN_SLOWING) else { c = '*'; spd = thermalManager.scaledFanSpeed(0, spd); } #endif - per = thermalManager.fanPercent(spd); + per = thermalManager.pwmToPercent(spd); } else #endif diff --git a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp index 6976bfed22bb..ddc33c492360 100644 --- a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp +++ b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp @@ -581,12 +581,15 @@ void MarlinUI::draw_status_message(const bool blink) { // If the remaining string doesn't completely fill the screen if (rlen < LCD_WIDTH) { - lcd.write('.'); // Always at 1+ spaces left, draw a dot uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters - if (--chars) { // Draw a second dot if there's space - lcd.write('.'); - if (--chars) - lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + lcd.write(' '); // Always at 1+ spaces left, draw a space + if (--chars) { // Draw a second space if there's room + lcd.write(' '); + if (--chars) { // Draw a third space if there's room + lcd.write(' '); + if (--chars) + lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + } } } if (last_blink != blink) { @@ -668,9 +671,9 @@ void MarlinUI::draw_status_screen() { // lcd.setCursor(0, 0); - _draw_axis_value(X_AXIS, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS])), blink); lcd.write(' '); - _draw_axis_value(Y_AXIS, ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS])), blink); lcd.write(' '); - _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position[Z_AXIS])), blink); + _draw_axis_value(X_AXIS, ftostr4sign(LOGICAL_X_POSITION(current_position.x)), blink); lcd.write(' '); + _draw_axis_value(Y_AXIS, ftostr4sign(LOGICAL_Y_POSITION(current_position.y)), blink); lcd.write(' '); + _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink); #if HAS_LEVELING && !HAS_HEATED_BED lcd.write(planner.leveling_active || blink ? '_' : ' '); @@ -750,7 +753,7 @@ void MarlinUI::draw_status_screen() { #if HOTENDS > 2 _draw_heater_status(H_E2, "HE3", blink); // Hotend 3 Temperature #endif - #endif // HOTENDS <= 1 + #endif #if HAS_HEATED_BED #if HAS_LEVELING @@ -758,16 +761,15 @@ void MarlinUI::draw_status_screen() { #else _draw_heater_status(H_BED, "BED", blink); #endif - #endif // HAS_HEATED_BED + #endif #if HAS_FAN uint16_t spd = thermalManager.fan_speed[0]; - #if ENABLED(ADAPTIVE_FAN_SLOWING) if (!blink) spd = thermalManager.scaledFanSpeed(0, spd); #endif + uint16_t per = thermalManager.pwmToPercent(spd); - uint16_t per = thermalManager.fanPercent(spd); #if HOTENDS < 2 #define FANX 11 #else diff --git a/Marlin/src/lcd/dogm/dogm_Statusscreen.h b/Marlin/src/lcd/dogm/dogm_Statusscreen.h index f0e37aa249f4..6d2c5369dc2f 100644 --- a/Marlin/src/lcd/dogm/dogm_Statusscreen.h +++ b/Marlin/src/lcd/dogm/dogm_Statusscreen.h @@ -547,7 +547,7 @@ #endif #ifndef STATUS_COOLER_TEXT_X - #define STATUS_COOLER_TEXT_X (STATUS_COOLER_X + 8) + #define STATUS_COOLER_TEXT_X (STATUS_COOLER_X + 12) #endif static_assert( @@ -583,7 +583,7 @@ #endif #ifndef STATUS_FLOWMETER_TEXT_X - #define STATUS_FLOWMETER_TEXT_X (STATUS_FLOWMETER_X + 8) + #define STATUS_FLOWMETER_TEXT_X (STATUS_FLOWMETER_X + 12) #endif static_assert( diff --git a/Marlin/src/lcd/dogm/status/cooler.h b/Marlin/src/lcd/dogm/status/cooler.h index df596b5c5af8..6cf67a4b6264 100644 --- a/Marlin/src/lcd/dogm/status/cooler.h +++ b/Marlin/src/lcd/dogm/status/cooler.h @@ -25,90 +25,95 @@ // lcd/dogm/status/cooler.h - Status Screen Laser Cooler bitmaps // #if HAS_COOLER - #define STATUS_COOLER_WIDTH 16 + + #define STATUS_COOLER_WIDTH 22 + const unsigned char status_cooler_bmp2[] PROGMEM = { - B00010000,B00001000, - B00010010,B01001001, - B01010100,B00101010, - B00111000,B00011100, - B11111110,B11111111, - B00111000,B00011100, - B01010100,B00101010, - B10010000,B10001001, - B00010000,B10000000, - B00000100,B10010000, - B00000010,B10100000, - B00000001,B11000000, - B00011111,B11111100, - B00000001,B11000000, - B00000010,B10100000, - B00000100,B10010000 + B00000100,B00000010,B00000000, + B00000100,B10010010,B01000000, + B00010101,B00001010,B10000000, + B00001110,B00000111,B00000000, + B00111111,B10111111,B11000000, + B00001110,B00000111,B00000000, + B00010101,B00001010,B10000000, + B00100100,B00100010,B01000000, + B00000100,B00100000,B00000000, + B00000001,B00100100,B00000000, + B00000000,B10101000,B00000000, + B00000000,B01110000,B00000000, + B00000111,B11111111,B00000000, + B00000000,B01110000,B00000000, + B00000000,B10101000,B00000000, + B00000001,B00100100,B00000000 }; const unsigned char status_cooler_bmp1[] PROGMEM = { - B00010000,B00001000, - B00010010,B01001001, - B01010100,B00101010, - B00101000,B00010100, - B11000111,B01100011, - B00101000,B00010100, - B01010100,B00101010, - B10010000,B10001001, - B00010000,B10000000, - B00000100,B10010000, - B00000010,B10100000, - B00000001,B01000000, - B00011110,B00111100, - B00000001,B01000000, - B00000010,B10100000, - B00000100,B10010000 + B00000100,B00000010,B00000000, + B00000100,B10010010,B01000000, + B00010101,B00001010,B10000000, + B00001010,B00000101,B00000000, + B00110001,B11011000,B11000000, + B00001010,B00000101,B00000000, + B00010101,B00001010,B10000000, + B00100100,B00100010,B01000000, + B00000100,B00100000,B00000000, + B00000001,B00100100,B00000000, + B00000000,B10101000,B00000000, + B00000000,B01010000,B00000000, + B00000111,B10001111,B00000000, + B00000000,B01010000,B00000000, + B00000000,B10101000,B00000000, + B00000001,B00100100,B00000000 }; + #endif #if ENABLED(LASER_COOLANT_FLOW_METER) + #define STATUS_FLOWMETER_WIDTH 24 + const unsigned char status_flowmeter_bmp2[] PROGMEM = { - B00000001,B11111000,B00000000, - B00000110,B00000110,B00000000, - B00001000,B01100001,B00000000, - B00010000,B01100000,B10000000, - B00100000,B01100000,B01000000, - B00100000,B01100000,B01000000, - B01000000,B01100000,B00100000, - B01000000,B01100000,B00100000, - B01011111,B11111111,B10100000, - B01011111,B11111111,B10100000, - B01000000,B01100000,B00100000, - B01000000,B01100000,B00100000, - B00100000,B01100000,B01000000, - B00100000,B01100000,B01000000, - B00010000,B01100000,B10000000, - B00001000,B01100001,B00000000, - B00000110,B00000110,B00000000, - B00000001,B11111000,B00000000, - B00000000,B01100000,B00000000, - B00011111,B11111111,B10000000 + B00000000,B01111110,B00000000, + B00000001,B10000001,B10000000, + B00000010,B00011000,B01000000, + B00000100,B00011000,B00100000, + B00001000,B00011000,B00010000, + B00001000,B00011000,B00010000, + B00010000,B00011000,B00001000, + B00010000,B00011000,B00001000, + B00010111,B11111111,B11101000, + B00010111,B11111111,B11101000, + B00010000,B00011000,B00001000, + B00010000,B00011000,B00001000, + B00001000,B00011000,B00010000, + B00001000,B00011000,B00010000, + B00000100,B00011000,B00100000, + B00000010,B00011000,B01000000, + B00000001,B10000001,B10000000, + B00000000,B01111110,B00000000, + B00000000,B00011000,B00000000, + B00000111,B11111111,B11100000 }; const unsigned char status_flowmeter_bmp1[] PROGMEM = { - B00000001,B11111000,B00000000, - B00000110,B00000110,B00000000, - B00001000,B00000001,B00000000, - B00010100,B00000010,B10000000, - B00101110,B00000111,B01000000, - B00100111,B00001110,B01000000, - B01000011,B10011100,B00100000, - B01000001,B11111000,B00100000, - B01000000,B11110000,B00100000, - B01000000,B11110000,B00100000, - B01000001,B11111000,B00100000, - B01000011,B10011100,B00100000, - B00100111,B00001110,B01000000, - B00101110,B00000111,B01000000, - B00010100,B00000010,B10000000, - B00001000,B00000001,B00000000, - B00000110,B00000110,B00000000, - B00000001,B11111000,B00000000, - B00000000,B01100000,B00000000, - B00011111,B11111111,B10000000 + B00000000,B01111110,B00000000, + B00000001,B10000001,B10000000, + B00000010,B00000000,B01000000, + B00000101,B00000000,B10100000, + B00001011,B10000001,B11010000, + B00001001,B11000011,B10010000, + B00010000,B11100111,B00001000, + B00010000,B01111110,B00001000, + B00010000,B00111100,B00001000, + B00010000,B00111100,B00001000, + B00010000,B01111110,B00001000, + B00010000,B11100111,B00001000, + B00001001,B11000011,B10010000, + B00001011,B10000001,B11010000, + B00000101,B00000000,B10100000, + B00000010,B00000000,B01000000, + B00000001,B10000001,B10000000, + B00000000,B01111110,B00000000, + B00000000,B00011000,B00000000, + B00000111,B11111111,B11100000 }; -#endif +#endif diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 921dee0e34c0..e2bffb7fe010 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -136,7 +136,7 @@ #if ENABLED(POWER_MONITOR_CURRENT) const bool iflag = power_monitor.current_display_enabled(); #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) const bool vflag = power_monitor.voltage_display_enabled(); #endif @@ -148,7 +148,7 @@ } #elif ENABLED(POWER_MONITOR_CURRENT) power_monitor.display_item = 0; - #elif HAS_POWER_MONITOR_VREF + #elif ENABLED(POWER_MONITOR_VOLTAGE) power_monitor.display_item = 1; #endif @@ -157,7 +157,7 @@ #if ENABLED(POWER_MONITOR_CURRENT) if (power_monitor.display_item == 0 && !iflag) ++power_monitor.display_item; #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) if (power_monitor.display_item == 1 && !vflag) ++power_monitor.display_item; #endif #if HAS_POWER_MONITOR_WATTS @@ -170,7 +170,7 @@ #if ENABLED(POWER_MONITOR_CURRENT) // Current case 0: if (iflag) power_monitor.draw_current(); break; #endif - #if HAS_POWER_MONITOR_VREF // Voltage + #if ENABLED(POWER_MONITOR_VOLTAGE) // Voltage case 1: if (vflag) power_monitor.draw_voltage(); break; #endif #if HAS_POWER_MONITOR_WATTS // Power @@ -696,7 +696,7 @@ void MarlinUI::draw_status_screen() { c = '*'; } #endif - lcd_put_u8str(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y, i16tostr3rj(thermalManager.fanPercent(spd))); + lcd_put_u8str(STATUS_FAN_TEXT_X, STATUS_FAN_TEXT_Y, i16tostr3rj(thermalManager.pwmToPercent(spd))); lcd_put_wchar(c); } } @@ -835,13 +835,17 @@ void MarlinUI::draw_status_screen() { mix_label = PSTR("Mx"); } - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wformat-overflow" + #if GCC_VERSION <= 50000 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow" + #endif sprintf_P(mixer_messages, PSTR(S_FMT " %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); lcd_put_u8str(X_LABEL_POS, XYZ_BASELINE, mixer_messages); - #pragma GCC diagnostic pop + #if GCC_VERSION <= 50000 + #pragma GCC diagnostic pop + #endif #else @@ -955,13 +959,16 @@ void MarlinUI::draw_status_message(const bool blink) { // If the remaining string doesn't completely fill the screen if (rlen < lcd_width) { - lcd_put_wchar('.'); // Always at 1+ spaces left, draw a dot uint8_t chars = lcd_width - rlen; // Amount of space left in characters - if (--chars) { // Draw a second dot if there's space - lcd_put_wchar('.'); - if (--chars) { // Print a second copy of the message - lcd_put_u8str_max(status_message, pixel_width - (rlen + 2) * (MENU_FONT_WIDTH)); + lcd_put_wchar(' '); // Always at 1+ spaces left, draw a space + if (--chars) { // Draw a second space if there's room + lcd_put_wchar(' '); + if (--chars) { // Draw a third space if there's room lcd_put_wchar(' '); + if (--chars) { // Print a second copy of the message + lcd_put_u8str_max(status_message, pixel_width - (rlen + 2) * (MENU_FONT_WIDTH)); + lcd_put_wchar(' '); + } } } } diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp index a2dfb74a57d0..b8257d32ffe8 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp @@ -642,11 +642,14 @@ void ST7920_Lite_Status_Screen::draw_status_message() { // If the remaining string doesn't completely fill the screen if (rlen < TEXT_MODE_LCD_WIDTH) { - write_byte('.'); // Always at 1+ spaces left, draw a dot - uint8_t chars = TEXT_MODE_LCD_WIDTH - rlen; // Amount of space left in characters - if (--chars) { // Draw a second dot if there's space - write_byte('.'); - if (--chars) write_str(str, chars); // Print a second copy of the message + uint8_t chars = TEXT_MODE_LCD_WIDTH - rlen; // Amount of space left in characters + write_byte(' '); // Always at 1+ spaces left, draw a space + if (--chars) { // Draw a second space if there's room + write_byte(' '); + if (--chars) { // Draw a third space if there's room + write_byte(' '); + if (--chars) write_str(str, chars); // Print a second copy of the message + } } } ui.advance_status_scroll(); @@ -733,14 +736,12 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { TERN_(HAS_MULTI_HOTEND, draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate)); TERN_(HAS_HEATED_BED, draw_bed_temp(bed_temp, bed_target, forceUpdate)); - uint16_t spd = thermalManager.fan_speed[0]; - + uint8_t spd = thermalManager.fan_speed[0]; #if ENABLED(ADAPTIVE_FAN_SLOWING) if (!blink && thermalManager.fan_speed_scaler[0] < 128) spd = thermalManager.scaledFanSpeed(0, spd); #endif - - draw_fan_speed(thermalManager.fanPercent(spd)); + draw_fan_speed(thermalManager.pwmToPercent(spd)); // Draw elapsed/remaining time const bool show_remaining = ENABLED(SHOW_REMAINING_TIME) && (DISABLED(ROTATE_PROGRESS_DISPLAY) || blink); diff --git a/Marlin/src/lcd/dogm/u8g_dev_ssd1309_12864.cpp b/Marlin/src/lcd/dogm/u8g_dev_ssd1309_12864.cpp index 8ba19216b113..7b4c470afe61 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_ssd1309_12864.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_ssd1309_12864.cpp @@ -88,7 +88,7 @@ static const uint8_t u8g_dev_ssd13xx_sleep_off[] PROGMEM = { }; uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch(msg) { + switch (msg) { case U8G_DEV_MSG_INIT: u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1309_128x64_init_seq); diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h index 8e03614a4649..c70941587908 100644 --- a/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h @@ -35,22 +35,27 @@ using namespace ExtUI; namespace Anycubic { - class FileNavigator { - public: - FileNavigator(); - void reset(); - void getFiles(uint16_t); - void upDIR(); - void changeDIR(char *); - void sendFile(); - void refresh(); - char * getCurrentFolderName(); - private: - static FileList filelist; - static char currentfoldername[MAX_PATH_LEN]; - static uint16_t lastindex; - static uint8_t folderdepth; - static uint16_t currentindex; - }; - extern FileNavigator filenavigator; + +class FileNavigator { + public: + FileNavigator(); + void reset(); + void getFiles(uint16_t, panel_type_t, uint8_t filesneeded=4); + void upDIR(); + void changeDIR(const char *); + void sendFile(panel_type_t); + void refresh(); + void skiptofileindex(uint16_t); + + static FileList filelist; + private: + static uint16_t lastpanelindex; + static uint16_t currentindex; + static uint8_t currentfolderdepth; + static uint16_t currentfolderindex[MAX_FOLDER_DEPTH]; + static char currentfoldername[MAX_PATH_LEN]; +}; + +extern FileNavigator filenavigator; + } diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp index 5eb8611b5e66..065e4e178963 100644 --- a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp @@ -43,843 +43,843 @@ namespace Anycubic { - printer_state_t ChironTFT::printer_state; - paused_state_t ChironTFT::pause_state; - heater_state_t ChironTFT::hotend_state; - heater_state_t ChironTFT::hotbed_state; - xy_uint8_t ChironTFT::selectedmeshpoint; - char ChironTFT::selectedfile[MAX_PATH_LEN]; - char ChironTFT::panel_command[MAX_CMND_LEN]; - uint8_t ChironTFT::command_len; - float ChironTFT::live_Zoffset; - file_menu_t ChironTFT::file_menu; - - ChironTFT Chiron; - - ChironTFT::ChironTFT(){} - - void ChironTFT::Startup() { - selectedfile[0] = '\0'; - panel_command[0] = '\0'; - command_len = 0; - printer_state = AC_printer_idle; - pause_state = AC_paused_idle; - hotend_state = AC_heater_off; - hotbed_state = AC_heater_off; - live_Zoffset = 0.0; - file_menu = AC_menu_file; - - // Setup pins for powerloss detection - // Two IO pins are connected on the Trigorilla Board - // On a power interruption the OUTAGECON_PIN goes low. - - #if ENABLED(POWER_LOSS_RECOVERY) - OUT_WRITE(OUTAGECON_PIN, HIGH); - #endif - - // Filament runout is handled by Marlin settings in Configuration.h - // opt_set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present. - // opt_enable FIL_RUNOUT_PULLUP - - TFTSer.begin(115200); - - // Signal Board has reset - SendtoTFTLN(AC_msg_main_board_has_reset); - - safe_delay(200); - - // Enable leveling and Disable end stops during print - // as Z home places nozzle above the bed so we need to allow it past the end stops - injectCommands_P(AC_cmnd_enable_leveling); - - // Startup tunes are defined in Tunes.h - //PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1); - PlayTune(BEEPER_PIN, GB_PowerOn, 1); - #if ACDEBUGLEVEL - SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL); - #endif - SendtoTFTLN(AC_msg_ready); +printer_state_t ChironTFT::printer_state; +paused_state_t ChironTFT::pause_state; +heater_state_t ChironTFT::hotend_state; +heater_state_t ChironTFT::hotbed_state; +xy_uint8_t ChironTFT::selectedmeshpoint; +char ChironTFT::selectedfile[MAX_PATH_LEN]; +char ChironTFT::panel_command[MAX_CMND_LEN]; +uint8_t ChironTFT::command_len; +float ChironTFT::live_Zoffset; +file_menu_t ChironTFT::file_menu; + +ChironTFT Chiron; + +ChironTFT::ChironTFT(){} + +void ChironTFT::Startup() { + selectedfile[0] = '\0'; + panel_command[0] = '\0'; + command_len = 0; + printer_state = AC_printer_idle; + pause_state = AC_paused_idle; + hotend_state = AC_heater_off; + hotbed_state = AC_heater_off; + live_Zoffset = 0.0; + file_menu = AC_menu_file; + + // Setup pins for powerloss detection + // Two IO pins are connected on the Trigorilla Board + // On a power interruption the OUTAGECON_PIN goes low. + + #if ENABLED(POWER_LOSS_RECOVERY) + OUT_WRITE(OUTAGECON_PIN, HIGH); + #endif + + // Filament runout is handled by Marlin settings in Configuration.h + // opt_set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present. + // opt_enable FIL_RUNOUT_PULLUP + + TFTSer.begin(115200); + + // Signal Board has reset + SendtoTFTLN(AC_msg_main_board_has_reset); + + safe_delay(200); + + // Enable leveling and Disable end stops during print + // as Z home places nozzle above the bed so we need to allow it past the end stops + injectCommands_P(AC_cmnd_enable_leveling); + + // Startup tunes are defined in Tunes.h + //PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1); + PlayTune(BEEPER_PIN, GB_PowerOn, 1); + #if ACDEBUGLEVEL + SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL); + #endif + SendtoTFTLN(AC_msg_ready); +} + +void ChironTFT::IdleLoop() { + if (ReadTFTCommand()) { + ProcessPanelRequest(); + command_len = 0; } - - void ChironTFT::IdleLoop() { - if (ReadTFTCommand()) { - ProcessPanelRequest(); - command_len = 0; - } - CheckHeaters(); + CheckHeaters(); +} + +void ChironTFT::PrinterKilled(PGM_P error,PGM_P component) { + SendtoTFTLN(AC_msg_kill_lcd); + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("PrinterKilled()\nerror: ", error , "\ncomponent: ", component); + #endif +} + +void ChironTFT::MediaEvent(media_event_t event) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("ProcessMediaStatus() ", event); + #endif + switch (event) { + case AC_media_inserted: + SendtoTFTLN(AC_msg_sd_card_inserted); + break; + + case AC_media_removed: + SendtoTFTLN(AC_msg_sd_card_removed); + break; + + case AC_media_error: + SendtoTFTLN(AC_msg_no_sd_card); + break; } - - void ChironTFT::PrinterKilled(PGM_P error,PGM_P component) { - SendtoTFTLN(AC_msg_kill_lcd); - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("PrinterKilled()\nerror: ", error , "\ncomponent: ", component); - #endif +} + +void ChironTFT::TimerEvent(timer_event_t event) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("TimerEvent() ", event); + SERIAL_ECHOLNPAIR("Printer State: ", printer_state); + #endif + + switch (event) { + case AC_timer_started: { + live_Zoffset = 0.0; // reset print offset + setSoftEndstopState(false); // disable endstops to print + printer_state = AC_printer_printing; + SendtoTFTLN(AC_msg_print_from_sd_card); + } break; + + case AC_timer_paused: { + printer_state = AC_printer_paused; + pause_state = AC_paused_idle; + SendtoTFTLN(AC_msg_paused); + } break; + + case AC_timer_stopped: { + if (printer_state != AC_printer_idle) { + printer_state = AC_printer_stopping; + SendtoTFTLN(AC_msg_print_complete); + } + setSoftEndstopState(true); // enable endstops + } break; } - - void ChironTFT::MediaEvent(media_event_t event) { - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("ProcessMediaStatus() ", event); - #endif - switch (event) { - case AC_media_inserted: - SendtoTFTLN(AC_msg_sd_card_inserted); - break; - - case AC_media_removed: - SendtoTFTLN(AC_msg_sd_card_removed); - break; - - case AC_media_error: - SendtoTFTLN(AC_msg_no_sd_card); - break; - } +} + +void ChironTFT::FilamentRunout() { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state); + #endif + // 1 Signal filament out + SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); + //printer_state = AC_printer_filament_out; + PlayTune(BEEPER_PIN, FilamentOut, 1); +} + +void ChironTFT::ConfirmationRequest(const char * const msg) { + // M108 continue + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state); + #endif + switch (printer_state) { + case AC_printer_pausing: { + if (strcmp_P(msg, MARLIN_msg_print_paused) == 0 || strcmp_P(msg, MARLIN_msg_nozzle_parked) == 0) { + SendtoTFTLN(AC_msg_paused); // enable continue button + printer_state = AC_printer_paused; + } + } break; + + case AC_printer_resuming_from_power_outage: + case AC_printer_printing: + case AC_printer_paused: { + // Heater timout, send acknowledgement + if (strcmp_P(msg, MARLIN_msg_heater_timeout) == 0) { + pause_state = AC_paused_heater_timed_out; + SendtoTFTLN(AC_msg_paused); // enable continue button + PlayTune(BEEPER_PIN,Heater_Timedout,1); + } + // Reheat finished, send acknowledgement + else if (strcmp_P(msg, MARLIN_msg_reheat_done) == 0) { + pause_state = AC_paused_idle; + SendtoTFTLN(AC_msg_paused); // enable continue button + } + // Filament Purging, send acknowledgement enter run mode + else if (strcmp_P(msg, MARLIN_msg_filament_purging) == 0) { + pause_state = AC_paused_purging_filament; + SendtoTFTLN(AC_msg_paused); // enable continue button + } + } break; + default: + break; } +} + +void ChironTFT::StatusChange(const char * const msg) { + #if ACDEBUG(AC_MARLIN) + SERIAL_ECHOLNPAIR("StatusChange() ", msg); + SERIAL_ECHOLNPAIR("printer_state:", printer_state); + #endif + bool msg_matched = false; + // The only way to get printer status is to parse messages + // Use the state to minimise the work we do here. + switch (printer_state) { + case AC_printer_probing: { + // If probing completes ok save the mesh and park + // Ignore the custom machine name + if (strcmp_P(msg + strlen(CUSTOM_MACHINE_NAME), MARLIN_msg_ready) == 0) { + injectCommands_P(PSTR("M500\nG27")); + SendtoTFTLN(AC_msg_probing_complete); + printer_state = AC_printer_idle; + msg_matched = true; + } + // If probing fails dont save the mesh raise the probe above the bad point + if (strcmp_P(msg, MARLIN_msg_probing_failed) == 0) { + PlayTune(BEEPER_PIN, BeepBeepBeeep, 1); + injectCommands_P(PSTR("G1 Z50 F500")); + SendtoTFTLN(AC_msg_probing_complete); + printer_state = AC_printer_idle; + msg_matched = true; + } + } break; - void ChironTFT::TimerEvent(timer_event_t event) { - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("TimerEvent() ", event); - SERIAL_ECHOLNPAIR("Printer State: ", printer_state); - #endif - - switch (event) { - case AC_timer_started: { - live_Zoffset = 0.0; // reset print offset - setSoftEndstopState(false); // disable endstops to print - printer_state = AC_printer_printing; - SendtoTFTLN(AC_msg_print_from_sd_card); - } break; + case AC_printer_printing: { + if (strcmp_P(msg, MARLIN_msg_reheating) == 0) { + SendtoTFTLN(AC_msg_paused); // enable continue button + msg_matched = true; + } + } break; - case AC_timer_paused: { - printer_state = AC_printer_paused; - pause_state = AC_paused_idle; + case AC_printer_pausing: { + if (strcmp_P(msg, MARLIN_msg_print_paused) == 0) { SendtoTFTLN(AC_msg_paused); - } break; + printer_state = AC_printer_paused; + pause_state = AC_paused_idle; + msg_matched = true; + } + } break; + + case AC_printer_stopping: { + if (strcmp_P(msg, MARLIN_msg_print_aborted) == 0) { + SendtoTFTLN(AC_msg_stop); + printer_state = AC_printer_idle; + msg_matched = true; + } + } break; + default: + break; + } - case AC_timer_stopped: { - if (printer_state != AC_printer_idle) { - printer_state = AC_printer_stopping; - SendtoTFTLN(AC_msg_print_complete); - } - setSoftEndstopState(true); // enable endstops - } break; + // If not matched earlier see if this was a heater message + if (!msg_matched) { + if (strcmp_P(msg, MARLIN_msg_extruder_heating) == 0) { + SendtoTFTLN(AC_msg_nozzle_heating); + hotend_state = AC_heater_temp_set; + } + else if (strcmp_P(msg, MARLIN_msg_bed_heating) == 0) { + SendtoTFTLN(AC_msg_bed_heating); + hotbed_state = AC_heater_temp_set; } } - - void ChironTFT::FilamentRunout() { - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state); +} + +void ChironTFT::PowerLossRecovery() { + printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover. + PlayTune(BEEPER_PIN, SOS, 1); + SERIAL_ECHOLNPGM("Resuming from power outage..."); + SERIAL_ECHOLNPGM("Select SD file then press resume"); +} + +void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel + #if ACDEBUG(AC_SOME) + SERIAL_ECHOPGM_P(str); + #endif + while (const char c = pgm_read_byte(str++)) TFTSer.write(c); +} + +void ChironTFT::SendtoTFTLN(PGM_P str = nullptr) { + if (str) { + #if ACDEBUG(AC_SOME) + SERIAL_ECHOPGM("> "); #endif - // 1 Signal filament out - SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); - //printer_state = AC_printer_filament_out; - PlayTune(BEEPER_PIN, FilamentOut, 1); - } - - void ChironTFT::ConfirmationRequest(const char * const msg) { - // M108 continue - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state); + SendtoTFT(str); + #if ACDEBUG(AC_SOME) + SERIAL_EOL(); #endif - switch (printer_state) { - case AC_printer_pausing: { - if (strcmp_P(msg, MARLIN_msg_print_paused) == 0 || strcmp_P(msg, MARLIN_msg_nozzle_parked) == 0) { - SendtoTFTLN(AC_msg_paused); // enable continue button - printer_state = AC_printer_paused; - } - } break; - - case AC_printer_resuming_from_power_outage: - case AC_printer_printing: - case AC_printer_paused: { - // Heater timout, send acknowledgement - if (strcmp_P(msg, MARLIN_msg_heater_timeout) == 0) { - pause_state = AC_paused_heater_timed_out; - SendtoTFTLN(AC_msg_paused); // enable continue button - PlayTune(BEEPER_PIN,Heater_Timedout,1); - } - // Reheat finished, send acknowledgement - else if (strcmp_P(msg, MARLIN_msg_reheat_done) == 0) { - pause_state = AC_paused_idle; - SendtoTFTLN(AC_msg_paused); // enable continue button - } - // Filament Purging, send acknowledgement enter run mode - else if (strcmp_P(msg, MARLIN_msg_filament_purging) == 0) { - pause_state = AC_paused_purging_filament; - SendtoTFTLN(AC_msg_paused); // enable continue button - } - } break; - default: - break; - } } - - void ChironTFT::StatusChange(const char * const msg) { - #if ACDEBUG(AC_MARLIN) - SERIAL_ECHOLNPAIR("StatusChange() ", msg); - SERIAL_ECHOLNPAIR("printer_state:", printer_state); - #endif - bool msg_matched = false; - // The only way to get printer status is to parse messages - // Use the state to minimise the work we do here. - switch (printer_state) { - case AC_printer_probing: { - // If probing completes ok save the mesh and park - // Ignore the custom machine name - if (strcmp_P(msg + strlen(CUSTOM_MACHINE_NAME), MARLIN_msg_ready) == 0) { - injectCommands_P(PSTR("M500\nG27")); - SendtoTFTLN(AC_msg_probing_complete); - printer_state = AC_printer_idle; - msg_matched = true; - } - // If probing fails dont save the mesh raise the probe above the bad point - if (strcmp_P(msg, MARLIN_msg_probing_failed) == 0) { - PlayTune(BEEPER_PIN, BeepBeepBeeep, 1); - injectCommands_P(PSTR("G1 Z50 F500")); - SendtoTFTLN(AC_msg_probing_complete); - printer_state = AC_printer_idle; - msg_matched = true; - } - } break; - - case AC_printer_printing: { - if (strcmp_P(msg, MARLIN_msg_reheating) == 0) { - SendtoTFTLN(AC_msg_paused); // enable continue button - msg_matched = true; - } - } break; - - case AC_printer_pausing: { - if (strcmp_P(msg, MARLIN_msg_print_paused) == 0) { - SendtoTFTLN(AC_msg_paused); - printer_state = AC_printer_paused; - pause_state = AC_paused_idle; - msg_matched = true; - } - } break; - - case AC_printer_stopping: { - if (strcmp_P(msg, MARLIN_msg_print_aborted) == 0) { - SendtoTFTLN(AC_msg_stop); - printer_state = AC_printer_idle; - msg_matched = true; - } - } break; - default: + TFTSer.println(); +} + +bool ChironTFT::ReadTFTCommand() { + bool command_ready = false; + while (TFTSer.available() > 0 && command_len < MAX_CMND_LEN) { + panel_command[command_len] = TFTSer.read(); + if (panel_command[command_len] == '\n') { + command_ready = true; break; } - - // If not matched earlier see if this was a heater message - if (!msg_matched) { - if (strcmp_P(msg, MARLIN_msg_extruder_heating) == 0) { - SendtoTFTLN(AC_msg_nozzle_heating); - hotend_state = AC_heater_temp_set; - } - else if (strcmp_P(msg, MARLIN_msg_bed_heating) == 0) { - SendtoTFTLN(AC_msg_bed_heating); - hotbed_state = AC_heater_temp_set; - } - } - } - - void ChironTFT::PowerLossRecovery() { - printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover. - PlayTune(BEEPER_PIN, SOS, 1); - SERIAL_ECHOLNPGM("Resuming from power outage..."); - SERIAL_ECHOLNPGM("Select SD file then press resume"); + command_len++; } - void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel + if (command_ready) { + panel_command[command_len] = 0x00; + #if ACDEBUG(AC_ALL) + SERIAL_ECHOLNPAIR("< ", panel_command); + #endif #if ACDEBUG(AC_SOME) - SERIAL_ECHOPGM_P(str); + // Ignore status request commands + uint8_t req = atoi(&panel_command[1]); + if (req > 7 && req != 20) { + SERIAL_ECHOLNPAIR("> ", panel_command); + SERIAL_ECHOLNPAIR("printer_state:", printer_state); + } #endif - while (const char c = pgm_read_byte(str++)) TFTSer.write(c); } - - void ChironTFT::SendtoTFTLN(PGM_P str = nullptr) { - if (str) { - #if ACDEBUG(AC_SOME) - SERIAL_ECHOPGM("> "); - #endif - SendtoTFT(str); - #if ACDEBUG(AC_SOME) - SERIAL_EOL(); - #endif + return command_ready; +} + +int8_t ChironTFT::Findcmndpos(const char * buff, char q) { + int8_t pos = 0; + do { if (buff[pos] == q) return pos; } while (++pos < MAX_CMND_LEN); + return -1; +} + +void ChironTFT::CheckHeaters() { + uint8_t faultDuration = 0; + float temp = 0; + + // if the hotend temp is abnormal, confirm state before signalling panel + temp = getActualTemp_celsius(E0); + while (!WITHIN(temp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP)) { + faultDuration++; + if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); + SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp); + break; } - TFTSer.println(); + delay_ms(500); + temp = getActualTemp_celsius(E0); } - bool ChironTFT::ReadTFTCommand() { - bool command_ready = false; - while (TFTSer.available() > 0 && command_len < MAX_CMND_LEN) { - panel_command[command_len] = TFTSer.read(); - if (panel_command[command_len] == '\n') { - command_ready = true; - break; - } - command_len++; + // If the hotbed temp is abnormal, confirm state before signaling panel + faultDuration = 0; + temp = getActualTemp_celsius(BED); + while (!WITHIN(temp, BED_MINTEMP, BED_MAXTEMP)) { + faultDuration++; + if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); + SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp); + break; } + delay_ms(500); + temp = getActualTemp_celsius(E0); + } - if (command_ready) { - panel_command[command_len] = 0x00; - #if ACDEBUG(AC_ALL) - SERIAL_ECHOLNPAIR("< ", panel_command); - #endif - #if ACDEBUG(AC_SOME) - // Ignore status request commands - uint8_t req = atoi(&panel_command[1]); - if (req > 7 && req != 20) { - SERIAL_ECHOLNPAIR("> ", panel_command); - SERIAL_ECHOLNPAIR("printer_state:", printer_state); - } - #endif + // Update panel with hotend heater status + if (hotend_state != AC_heater_temp_reached) { + if (WITHIN(getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -1, 1)) { + SendtoTFTLN(AC_msg_nozzle_heating_done); + hotend_state = AC_heater_temp_reached; } - return command_ready; } - int8_t ChironTFT::Findcmndpos(const char * buff, char q) { - int8_t pos = 0; - do { if (buff[pos] == q) return pos; } while (++pos < MAX_CMND_LEN); - return -1; + // Update panel with bed heater status + if (hotbed_state != AC_heater_temp_reached) { + if (WITHIN(getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -0.5, 0.5)) { + SendtoTFTLN(AC_msg_bed_heating_done); + hotbed_state = AC_heater_temp_reached; + } } +} + +void ChironTFT::SendFileList(int8_t startindex) { + // Respond to panel request for 4 files starting at index + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex); + #endif + SendtoTFTLN(PSTR("FN ")); + filenavigator.getFiles(startindex); + SendtoTFTLN(PSTR("END")); +} + +void ChironTFT::SelectFile() { + strncpy(selectedfile, panel_command + 4, command_len - 4); + selectedfile[command_len - 5] = '\0'; + #if ACDEBUG(AC_FILE) + SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile); + #endif + switch (selectedfile[0]) { + case '/': // Valid file selected + SendtoTFTLN(AC_msg_sd_file_open_success); + break; - void ChironTFT::CheckHeaters() { - uint8_t faultDuration = 0; - float temp = 0; + case '<': // .. (go up folder level) + filenavigator.upDIR(); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); + break; + default: // enter sub folder + filenavigator.changeDIR(selectedfile); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); + break; + } +} - // if the hotend temp is abnormal, confirm state before signalling panel - temp = getActualTemp_celsius(E0); - while (!WITHIN(temp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP)) { - faultDuration++; - if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { - SendtoTFTLN(AC_msg_nozzle_temp_abnormal); - SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp); - break; - } - delay_ms(500); - temp = getActualTemp_celsius(E0); - } +void ChironTFT::InjectCommandandWait(PGM_P cmd) { + //injectCommands_P(cmnd); queue.enqueue_now_P(cmd); + //SERIAL_ECHOLN(PSTR("Inject>")); +} - // If the hotbed temp is abnormal, confirm state before signaling panel - faultDuration = 0; - temp = getActualTemp_celsius(BED); - while (!WITHIN(temp, BED_MINTEMP, BED_MAXTEMP)) { - faultDuration++; - if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { - SendtoTFTLN(AC_msg_nozzle_temp_abnormal); - SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp); - break; - } - delay_ms(500); - temp = getActualTemp_celsius(E0); - } +void ChironTFT::ProcessPanelRequest() { + // Break these up into logical blocks // as its easier to navigate than one huge switch case! + int8_t req = atoi(&panel_command[1]); - // Update panel with hotend heater status - if (hotend_state != AC_heater_temp_reached) { - if (WITHIN(getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -1, 1)) { - SendtoTFTLN(AC_msg_nozzle_heating_done); - hotend_state = AC_heater_temp_reached; - } - } + // Information requests A0 - A8 and A33 + if (req <= 8 || req == 33) PanelInfo(req); - // Update panel with bed heater status - if (hotbed_state != AC_heater_temp_reached) { - if (WITHIN(getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -0.5, 0.5)) { - SendtoTFTLN(AC_msg_bed_heating_done); - hotbed_state = AC_heater_temp_reached; - } - } - } + // Simple Actions A9 - A28 + else if ( req <= 28) PanelAction(req); - void ChironTFT::SendFileList(int8_t startindex) { - // Respond to panel request for 4 files starting at index - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex); - #endif - SendtoTFTLN(PSTR("FN ")); - filenavigator.getFiles(startindex); - SendtoTFTLN(PSTR("END")); - } + // Process Initiation + else if (req <= 34) PanelProcess(req); - void ChironTFT::SelectFile() { - strncpy(selectedfile, panel_command + 4, command_len - 4); - selectedfile[command_len - 5] = '\0'; - #if ACDEBUG(AC_FILE) - SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile); - #endif - switch (selectedfile[0]) { - case '/': // Valid file selected - SendtoTFTLN(AC_msg_sd_file_open_success); - break; + else SendtoTFTLN(); +} - case '<': // .. (go up folder level) - filenavigator.upDIR(); - SendtoTFTLN(AC_msg_sd_file_open_failed); - SendFileList( 0 ); - break; - default: // enter sub folder - filenavigator.changeDIR(selectedfile); - SendtoTFTLN(AC_msg_sd_file_open_failed); - SendFileList( 0 ); - break; - } - } +void ChironTFT::PanelInfo(uint8_t req) { + // information requests A0-A8 and A33 + switch (req) { + case 0: // A0 Get HOTEND Temp + SendtoTFT(PSTR("A0V ")); + TFTSer.println(getActualTemp_celsius(E0)); + break; - void ChironTFT::InjectCommandandWait(PGM_P cmd) { - //injectCommands_P(cmnd); queue.enqueue_now_P(cmd); - //SERIAL_ECHOLN(PSTR("Inject>")); - } + case 1: // A1 Get HOTEND Target Temp + SendtoTFT(PSTR("A1V ")); + TFTSer.println(getTargetTemp_celsius(E0)); + break; - void ChironTFT::ProcessPanelRequest() { - // Break these up into logical blocks // as its easier to navigate than one huge switch case! - int8_t req = atoi(&panel_command[1]); + case 2: // A2 Get BED Temp + SendtoTFT(PSTR("A2V ")); + TFTSer.println(getActualTemp_celsius(BED)); + break; - // Information requests A0 - A8 and A33 - if (req <= 8 || req == 33) PanelInfo(req); + case 3: // A3 Get BED Target Temp + SendtoTFT(PSTR("A3V ")); + TFTSer.println(getTargetTemp_celsius(BED)); + break; - // Simple Actions A9 - A28 - else if ( req <= 28) PanelAction(req); + case 4: // A4 Get FAN Speed + SendtoTFT(PSTR("A4V ")); + TFTSer.println(getActualFan_percent(FAN0)); + break; - // Process Initiation - else if (req <= 34) PanelProcess(req); + case 5: // A5 Get Current Coordinates + SendtoTFT(PSTR("A5V X: ")); + TFTSer.print(getAxisPosition_mm(X)); + SendtoTFT(PSTR(" Y: ")); + TFTSer.print(getAxisPosition_mm(Y)); + SendtoTFT(PSTR(" Z: ")); + TFTSer.println(getAxisPosition_mm(Z)); + break; - else SendtoTFTLN(); - } + case 6: // A6 Get printing progress + if (isPrintingFromMedia()) { + SendtoTFT(PSTR("A6V ")); + TFTSer.println(ui8tostr2(getProgress_percent())); + } + else + SendtoTFTLN(PSTR("A6V ---")); + break; - void ChironTFT::PanelInfo(uint8_t req) { - // information requests A0-A8 and A33 - switch (req) { - case 0: // A0 Get HOTEND Temp - SendtoTFT(PSTR("A0V ")); - TFTSer.println(getActualTemp_celsius(E0)); - break; + case 7: { // A7 Get Printing Time + uint32_t time = getProgress_seconds_elapsed() / 60; + SendtoTFT(PSTR("A7V ")); + TFTSer.print(ui8tostr2(time / 60)); + SendtoTFT(PSTR(" H ")); + TFTSer.print(ui8tostr2(time % 60)); + SendtoTFT(PSTR(" M")); + #if ACDEBUG(AC_ALL) + SERIAL_ECHOLNPAIR("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); + #endif + } break; - case 1: // A1 Get HOTEND Target Temp - SendtoTFT(PSTR("A1V ")); - TFTSer.println(getTargetTemp_celsius(E0)); - break; + case 8: // A8 Get SD Card list A8 S0 + if (!isMediaInserted()) safe_delay(500); + if (!isMediaInserted()) // Make sure the card is removed + SendtoTFTLN(AC_msg_no_sd_card); + else if (panel_command[3] == 'S') + SendFileList( atoi( &panel_command[4] ) ); + break; - case 2: // A2 Get BED Temp - SendtoTFT(PSTR("A2V ")); - TFTSer.println(getActualTemp_celsius(BED)); - break; + case 33: // A33 Get firmware info + SendtoTFT(PSTR("J33 ")); + SendtoTFTLN(PSTR(SHORT_BUILD_VERSION)); + break; + } +} + +void ChironTFT::PanelAction(uint8_t req) { + switch (req) { + case 9: // A9 Pause SD print + if (isPrintingFromMedia()) { + SendtoTFTLN(AC_msg_pause); + pausePrint(); + printer_state = AC_printer_pausing; + } + else + SendtoTFTLN(AC_msg_stop); + break; - case 3: // A3 Get BED Target Temp - SendtoTFT(PSTR("A3V ")); - TFTSer.println(getTargetTemp_celsius(BED)); - break; + case 10: // A10 Resume SD Print + if (pause_state == AC_paused_idle || printer_state == AC_printer_resuming_from_power_outage) + resumePrint(); + else + setUserConfirmed(); + break; - case 4: // A4 Get FAN Speed - SendtoTFT(PSTR("A4V ")); - TFTSer.println(getActualFan_percent(FAN0)); - break; + case 11: // A11 Stop SD print + if (isPrintingFromMedia()) { + printer_state = AC_printer_stopping; + stopPrint(); + } + else { + if (printer_state == AC_printer_resuming_from_power_outage) + injectCommands_P(PSTR("M1000 C")); // Cancel recovery + SendtoTFTLN(AC_msg_stop); + printer_state = AC_printer_idle; + } + break; - case 5: // A5 Get Current Coordinates - SendtoTFT(PSTR("A5V X: ")); - TFTSer.print(getAxisPosition_mm(X)); - SendtoTFT(PSTR(" Y: ")); - TFTSer.print(getAxisPosition_mm(Y)); - SendtoTFT(PSTR(" Z: ")); - TFTSer.println(getAxisPosition_mm(Z)); - break; + case 12: // A12 Kill printer + kill(); // from marlincore.h + break; - case 6: // A6 Get printing progress - if (isPrintingFromMedia()) { - SendtoTFT(PSTR("A6V ")); - TFTSer.println(ui8tostr2(getProgress_percent())); - } - else - SendtoTFTLN(PSTR("A6V ---")); - break; + case 13: // A13 Select file + SelectFile(); + break; - case 7: { // A7 Get Printing Time - uint32_t time = getProgress_seconds_elapsed() / 60; - SendtoTFT(PSTR("A7V ")); - TFTSer.print(ui8tostr2(time / 60)); - SendtoTFT(PSTR(" H ")); - TFTSer.print(ui8tostr2(time % 60)); - SendtoTFT(PSTR(" M")); - #if ACDEBUG(AC_ALL) - SERIAL_ECHOLNPAIR("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); - #endif - } break; - - case 8: // A8 Get SD Card list A8 S0 - if (!isMediaInserted()) safe_delay(500); - if (!isMediaInserted()) // Make sure the card is removed - SendtoTFTLN(AC_msg_no_sd_card); - else if (panel_command[3] == 'S') - SendFileList( atoi( &panel_command[4] ) ); - break; + case 14: { // A14 Start Printing + // Allows printer to restart the job if we dont want to recover + if (printer_state == AC_printer_resuming_from_power_outage) { + injectCommands_P(PSTR("M1000 C")); // Cancel recovery + printer_state = AC_printer_idle; + } + #if ACDebugLevel >= 1 + SERIAL_ECHOLNPAIR_F("Print: ", selectedfile); + #endif + // the card library needs a path starting // but the File api doesn't... + char file[MAX_PATH_LEN]; + file[0] = '/'; + strcpy(file + 1, selectedfile); + printFile(file); + SendtoTFTLN(AC_msg_print_from_sd_card); + } break; + + case 15: // A15 Resuming from outage + if (printer_state == AC_printer_resuming_from_power_outage) { + // Need to home here to restore the Z position + injectCommands_P(AC_cmnd_power_loss_recovery); + injectCommands_P(PSTR("M1000")); // home and start recovery + } + break; - case 33: // A33 Get firmware info - SendtoTFT(PSTR("J33 ")); - SendtoTFTLN(PSTR(SHORT_BUILD_VERSION)); - break; - } - } + case 16: { // A16 Set HotEnd temp A17 S170 + const float set_Htemp = atof(&panel_command[5]); + hotend_state = set_Htemp ? AC_heater_temp_set : AC_heater_off; + switch ((char)panel_command[4]) { + // Set Temp + case 'S': case 'C': setTargetTemp_celsius(set_Htemp, E0); + } + } break; + + case 17: { // A17 Set bed temp + const float set_Btemp = atof(&panel_command[5]); + hotbed_state = set_Btemp ? AC_heater_temp_set : AC_heater_off; + if (panel_command[4] == 'S') + setTargetTemp_celsius(set_Btemp, BED); + } break; + + case 18: // A18 Set Fan Speed + if (panel_command[4] == 'S') + setTargetFan_percent(atof(&panel_command[5]), FAN0); + break; - void ChironTFT::PanelAction(uint8_t req) { - switch (req) { - case 9: // A9 Pause SD print - if (isPrintingFromMedia()) { - SendtoTFTLN(AC_msg_pause); - pausePrint(); - printer_state = AC_printer_pausing; - } - else - SendtoTFTLN(AC_msg_stop); - break; + case 19: // A19 Motors off + if (!isPrinting()) { + disable_all_steppers(); // from marlincore.h + SendtoTFTLN(AC_msg_ready); + } + break; - case 10: // A10 Resume SD Print - if (pause_state == AC_paused_idle || printer_state == AC_printer_resuming_from_power_outage) - resumePrint(); - else - setUserConfirmed(); - break; + case 20: // A20 Read/write print speed + if (panel_command[4] == 'S') + setFeedrate_percent(atoi(&panel_command[5])); + else { + SendtoTFT(PSTR("A20V ")); + TFTSer.println(getFeedrate_percent()); + } + break; - case 11: // A11 Stop SD print - if (isPrintingFromMedia()) { - printer_state = AC_printer_stopping; - stopPrint(); - } - else { - if (printer_state == AC_printer_resuming_from_power_outage) - injectCommands_P(PSTR("M1000 C")); // Cancel recovery - SendtoTFTLN(AC_msg_stop); - printer_state = AC_printer_idle; + case 21: // A21 Home Axis A21 X + if (!isPrinting()) { + switch ((char)panel_command[4]) { + case 'X': injectCommands_P(PSTR("G28X")); break; + case 'Y': injectCommands_P(PSTR("G28Y")); break; + case 'Z': injectCommands_P(PSTR("G28Z")); break; + case 'C': injectCommands_P(G28_STR); break; } - break; - - case 12: // A12 Kill printer - kill(); // from marlincore.h - break; + } + break; - case 13: // A13 Select file - SelectFile(); - break; + case 22: // A22 Move Axis A22 Y +10F3000 + // Ignore request if printing + if (!isPrinting()) { + // setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel + setSoftEndstopState(true); // enable endstops + float newposition = atof(&panel_command[6]); - case 14: { // A14 Start Printing - // Allows printer to restart the job if we dont want to recover - if (printer_state == AC_printer_resuming_from_power_outage) { - injectCommands_P(PSTR("M1000 C")); // Cancel recovery - printer_state = AC_printer_idle; - } - #if ACDebugLevel >= 1 - SERIAL_ECHOLNPAIR_F("Print: ", selectedfile); + #if ACDEBUG(AC_ACTION) + SERIAL_ECHOLNPAIR("Nudge ", AS_CHAR(panel_command[4]), " axis ", newposition); #endif - // the card library needs a path starting // but the File api doesn't... - char file[MAX_PATH_LEN]; - file[0] = '/'; - strcpy(file + 1, selectedfile); - printFile(file); - SendtoTFTLN(AC_msg_print_from_sd_card); - } break; - - case 15: // A15 Resuming from outage - if (printer_state == AC_printer_resuming_from_power_outage) { - // Need to home here to restore the Z position - injectCommands_P(AC_cmnd_power_loss_recovery); - injectCommands_P(PSTR("M1000")); // home and start recovery - } - break; - case 16: { // A16 Set HotEnd temp A17 S170 - const float set_Htemp = atof(&panel_command[5]); - hotend_state = set_Htemp ? AC_heater_temp_set : AC_heater_off; - switch ((char)panel_command[4]) { - // Set Temp - case 'S': case 'C': setTargetTemp_celsius(set_Htemp, E0); + switch (panel_command[4]) { + case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break; + case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break; + case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break; + case 'E': // The only time we get this command is from the filament load/unload menu + // the standard movement is too slow so we will use the load unlod GCode to speed it up a bit + if (canMove(E0) && !commandsInQueue()) + injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament); + break; } - } break; - - case 17: { // A17 Set bed temp - const float set_Btemp = atof(&panel_command[5]); - hotbed_state = set_Btemp ? AC_heater_temp_set : AC_heater_off; - if (panel_command[4] == 'S') - setTargetTemp_celsius(set_Btemp, BED); - } break; - - case 18: // A18 Set Fan Speed - if (panel_command[4] == 'S') - setTargetFan_percent(atof(&panel_command[5]), FAN0); - break; + } + break; - case 19: // A19 Motors off - if (!isPrinting()) { - disable_all_steppers(); // from marlincore.h - SendtoTFTLN(AC_msg_ready); - } - break; + case 23: // A23 Preheat PLA + // Ignore request if printing + if (!isPrinting()) { + // Temps defined in configuration.h + setTargetTemp_celsius(PREHEAT_1_TEMP_BED, BED); + setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, E0); + SendtoTFTLN(); + hotbed_state = AC_heater_temp_set; + hotend_state = AC_heater_temp_set; + } + break; - case 20: // A20 Read/write print speed - if (panel_command[4] == 'S') - setFeedrate_percent(atoi(&panel_command[5])); - else { - SendtoTFT(PSTR("A20V ")); - TFTSer.println(getFeedrate_percent()); - } - break; + case 24: // A24 Preheat ABS + // Ignore request if printing + if (!isPrinting()) { + setTargetTemp_celsius(PREHEAT_2_TEMP_BED, BED); + setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, E0); + SendtoTFTLN(); + hotbed_state = AC_heater_temp_set; + hotend_state = AC_heater_temp_set; + } + break; - case 21: // A21 Home Axis A21 X - if (!isPrinting()) { - switch ((char)panel_command[4]) { - case 'X': injectCommands_P(PSTR("G28X")); break; - case 'Y': injectCommands_P(PSTR("G28Y")); break; - case 'Z': injectCommands_P(PSTR("G28Z")); break; - case 'C': injectCommands_P(G28_STR); break; - } - } - break; + case 25: // A25 Cool Down + // Ignore request if printing + if (!isPrinting()) { + setTargetTemp_celsius(0, E0); + setTargetTemp_celsius(0, BED); + SendtoTFTLN(AC_msg_ready); + hotbed_state = AC_heater_off; + hotend_state = AC_heater_off; + } + break; - case 22: // A22 Move Axis A22 Y +10F3000 - // Ignore request if printing - if (!isPrinting()) { - // setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel - setSoftEndstopState(true); // enable endstops - float newposition = atof(&panel_command[6]); - - #if ACDEBUG(AC_ACTION) - SERIAL_ECHOLNPAIR("Nudge ", AS_CHAR(panel_command[4]), " axis ", newposition); - #endif - - switch (panel_command[4]) { - case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break; - case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break; - case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break; - case 'E': // The only time we get this command is from the filament load/unload menu - // the standard movement is too slow so we will use the load unlod GCode to speed it up a bit - if (canMove(E0) && !commandsInQueue()) - injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament); - break; - } - } - break; + case 26: // A26 Refresh SD + // M22 M21 maybe needed here to reset sd card + filenavigator.reset(); + break; - case 23: // A23 Preheat PLA - // Ignore request if printing - if (!isPrinting()) { - // Temps defined in configuration.h - setTargetTemp_celsius(PREHEAT_1_TEMP_BED, BED); - setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, E0); - SendtoTFTLN(); - hotbed_state = AC_heater_temp_set; - hotend_state = AC_heater_temp_set; - } - break; + case 27: // A27 Servo Angles adjust + break; - case 24: // A24 Preheat ABS - // Ignore request if printing - if (!isPrinting()) { - setTargetTemp_celsius(PREHEAT_2_TEMP_BED, BED); - setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, E0); - SendtoTFTLN(); - hotbed_state = AC_heater_temp_set; - hotend_state = AC_heater_temp_set; + case 28: // A28 Filament set A28 O/C + // Ignore request if printing + if (isPrinting()) break; + SendtoTFTLN(); + break; + } +} + +void ChironTFT::PanelProcess(uint8_t req) { + switch (req) { + case 29: { // A29 Read Mesh Point A29 X1 Y1 + xy_uint8_t pos; + float pos_z; + pos.x = atoi(&panel_command[5]); + pos.y = atoi(&panel_command[8]); + pos_z = getMeshPoint(pos); + + SendtoTFT(PSTR("A29V ")); + TFTSer.println(pos_z * 100); + if (!isPrinting()) { + setSoftEndstopState(true); // disable endstops + // If the same meshpoint is selected twice in a row, move the head to that ready for adjustment + if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { + if (!isPositionKnown()) + injectCommands_P(G28_STR); // home + + if (isPositionKnown()) { + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); + #endif + // Go up before moving + setAxisPosition_mm(3.0,Z); + + setAxisPosition_mm(17 + (93 * pos.x), X); + setAxisPosition_mm(20 + (93 * pos.y), Y); + setAxisPosition_mm(0.0, Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Current Z: ", getAxisPosition_mm(Z)); + #endif + } } - break; + selectedmeshpoint.x = pos.x; + selectedmeshpoint.y = pos.y; + } + } break; - case 25: // A25 Cool Down + case 30: { // A30 Auto leveling + if (panel_command[3] == 'S') { // Start probing // Ignore request if printing - if (!isPrinting()) { - setTargetTemp_celsius(0, E0); - setTargetTemp_celsius(0, BED); - SendtoTFTLN(AC_msg_ready); - hotbed_state = AC_heater_off; - hotend_state = AC_heater_off; + if (isPrinting()) + SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling + else { + injectCommands_P(PSTR("G28O\nG29")); + printer_state = AC_printer_probing; + SendtoTFTLN(AC_msg_start_probing); } + } + else SendtoTFTLN(AC_msg_start_probing); + } break; + + case 31: { // A31 Adjust all Probe Points + switch (panel_command[3]) { + case 'C': // Restore and apply original offsets + if (!isPrinting()) { + injectCommands_P(PSTR("M501\nM420 S1")); + selectedmeshpoint.x = selectedmeshpoint.y = 99; + } break; - - case 26: // A26 Refresh SD - // M22 M21 maybe needed here to reset sd card - filenavigator.reset(); - break; - - case 27: // A27 Servo Angles adjust + case 'D': // Save Z Offset tables and restore leveling state + if (!isPrinting()) { + setAxisPosition_mm(1.0,Z); + injectCommands_P(PSTR("M500")); + selectedmeshpoint.x = selectedmeshpoint.y = 99; + } break; - - case 28: // A28 Filament set A28 O/C - // Ignore request if printing - if (isPrinting()) break; - SendtoTFTLN(); + case 'G': // Get current offset + SendtoTFT(PSTR("A31V ")); + // When printing use the live z Offset position + // we will use babystepping to move the print head + if (isPrinting()) + TFTSer.println(live_Zoffset); + else { + TFTSer.println(getZOffset_mm()); + selectedmeshpoint.x = selectedmeshpoint.y = 99; + } break; - } - } - - void ChironTFT::PanelProcess(uint8_t req) { - switch (req) { - case 29: { // A29 Read Mesh Point A29 X1 Y1 - xy_uint8_t pos; - float pos_z; - pos.x = atoi(&panel_command[5]); - pos.y = atoi(&panel_command[8]); - pos_z = getMeshPoint(pos); - - SendtoTFT(PSTR("A29V ")); - TFTSer.println(pos_z * 100); - if (!isPrinting()) { - setSoftEndstopState(true); // disable endstops - // If the same meshpoint is selected twice in a row, move the head to that ready for adjustment - if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { - if (!isPositionKnown()) - injectCommands_P(G28_STR); // home - - if (isPositionKnown()) { + case 'S': { // Set offset (adjusts all points by value) + float Zshift = atof(&panel_command[4]); + setSoftEndstopState(false); // disable endstops + // Allow temporary Z position nudging during print + // From the leveling panel use the all points UI to adjust the print pos. + if (isPrinting()) { + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); + #endif + if (isAxisPositionKnown(Z)) { #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); + const float currZpos = getAxisPosition_mm(Z); + SERIAL_ECHOLNPAIR("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); #endif - // Go up before moving - setAxisPosition_mm(3.0,Z); - - setAxisPosition_mm(17 + (93 * pos.x), X); - setAxisPosition_mm(20 + (93 * pos.y), Y); - setAxisPosition_mm(0.0, Z); + // Use babystepping to adjust the head position + int16_t steps = mmToWholeSteps(constrain(Zshift,-0.05,0.05), Z); #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Current Z: ", getAxisPosition_mm(Z)); + SERIAL_ECHOLNPAIR("Steps to move Z: ", steps); #endif + babystepAxis_steps(steps, Z); + live_Zoffset += Zshift; } + SendtoTFT(PSTR("A31V ")); + TFTSer.println(live_Zoffset); } - selectedmeshpoint.x = pos.x; - selectedmeshpoint.y = pos.y; - } - } break; - - case 30: { // A30 Auto leveling - if (panel_command[3] == 'S') { // Start probing - // Ignore request if printing - if (isPrinting()) - SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling else { - injectCommands_P(PSTR("G28O\nG29")); - printer_state = AC_printer_probing; - SendtoTFTLN(AC_msg_start_probing); - } - } - else SendtoTFTLN(AC_msg_start_probing); - } break; - - case 31: { // A31 Adjust all Probe Points - switch (panel_command[3]) { - case 'C': // Restore and apply original offsets - if (!isPrinting()) { - injectCommands_P(PSTR("M501\nM420 S1")); - selectedmeshpoint.x = selectedmeshpoint.y = 99; - } - break; - case 'D': // Save Z Offset tables and restore leveling state - if (!isPrinting()) { - setAxisPosition_mm(1.0,Z); - injectCommands_P(PSTR("M500")); - selectedmeshpoint.x = selectedmeshpoint.y = 99; - } - break; - case 'G': // Get current offset - SendtoTFT(PSTR("A31V ")); - // When printing use the live z Offset position - // we will use babystepping to move the print head - if (isPrinting()) - TFTSer.println(live_Zoffset); - else { - TFTSer.println(getZOffset_mm()); - selectedmeshpoint.x = selectedmeshpoint.y = 99; - } - break; - case 'S': { // Set offset (adjusts all points by value) - float Zshift = atof(&panel_command[4]); - setSoftEndstopState(false); // disable endstops - // Allow temporary Z position nudging during print - // From the leveling panel use the all points UI to adjust the print pos. - if (isPrinting()) { - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); - #endif - if (isAxisPositionKnown(Z)) { - #if ACDEBUG(AC_INFO) - const float currZpos = getAxisPosition_mm(Z); - SERIAL_ECHOLNPAIR("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); - #endif - // Use babystepping to adjust the head position - int16_t steps = mmToWholeSteps(constrain(Zshift,-0.05,0.05), Z); - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Steps to move Z: ", steps); - #endif - babystepAxis_steps(steps, Z); - live_Zoffset += Zshift; - } - SendtoTFT(PSTR("A31V ")); - TFTSer.println(live_Zoffset); + GRID_LOOP(x, y) { + const xy_uint8_t pos { x, y }; + const float currval = getMeshPoint(pos); + setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2)); } - else { - GRID_LOOP(x, y) { - const xy_uint8_t pos { x, y }; - const float currval = getMeshPoint(pos); - setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2)); - } - const float currZOffset = getZOffset_mm(); - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); - #endif + const float currZOffset = getZOffset_mm(); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); + #endif - setZOffset_mm(currZOffset + Zshift); - SendtoTFT(PSTR("A31V ")); - TFTSer.println(getZOffset_mm()); - - if (isAxisPositionKnown(Z)) { - // Move Z axis - const float currZpos = getAxisPosition_mm(Z); - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); - #endif - setAxisPosition_mm(currZpos+constrain(Zshift,-0.05,0.05),Z); - } - } - } break; - } // end switch - } break; + setZOffset_mm(currZOffset + Zshift); + SendtoTFT(PSTR("A31V ")); + TFTSer.println(getZOffset_mm()); - case 32: { // A32 clean leveling beep flag - // Ignore request if printing - //if (isPrinting()) break; - //injectCommands_P(PSTR("M500\nM420 S1\nG1 Z10 F240\nG1 X0 Y0 F6000")); - //TFTSer.println(); - } break; - - // A33 firmware info request seet PanelInfo() - - case 34: { // A34 Adjust single mesh point A34 C/S X1 Y1 V123 - if (panel_command[3] == 'C') { // Restore original offsets - injectCommands_P(PSTR("M501\nM420 S1")); - selectedmeshpoint.x = selectedmeshpoint.y = 99; - //printer_state = AC_printer_idle; - } - else { - xy_uint8_t pos; - pos.x = atoi(&panel_command[5]); - pos.y = atoi(&panel_command[8]); - - float currmesh = getMeshPoint(pos); - float newval = atof(&panel_command[11])/100; - #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Change mesh point x:", pos.x, " y:", pos.y); - SERIAL_ECHOLNPAIR("from ", currmesh, " to ", newval); - #endif - // Update Meshpoint - setMeshPoint(pos,newval); - if (printer_state == AC_printer_idle || printer_state == AC_printer_probing /*!isPrinting()*/) { - // if we are at the current mesh point indicated on the panel Move Z pos +/- 0.05mm - // (The panel changes the mesh value by +/- 0.05mm on each button press) - if (selectedmeshpoint.x == pos.x && selectedmeshpoint.y == pos.y) { - setSoftEndstopState(false); - float currZpos = getAxisPosition_mm(Z); + if (isAxisPositionKnown(Z)) { + // Move Z axis + const float currZpos = getAxisPosition_mm(Z); #if ACDEBUG(AC_INFO) - SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); + SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); #endif - setAxisPosition_mm(currZpos + constrain(newval - currmesh, -0.05, 0.05), Z); + setAxisPosition_mm(currZpos+constrain(Zshift,-0.05,0.05),Z); } } } - } break; - } + } + } break; + + case 32: { // A32 clean leveling beep flag + // Ignore request if printing + //if (isPrinting()) break; + //injectCommands_P(PSTR("M500\nM420 S1\nG1 Z10 F240\nG1 X0 Y0 F6000")); + //TFTSer.println(); + } break; + + // A33 firmware info request see PanelInfo() + + case 34: { // A34 Adjust single mesh point A34 C/S X1 Y1 V123 + if (panel_command[3] == 'C') { // Restore original offsets + injectCommands_P(PSTR("M501\nM420 S1")); + selectedmeshpoint.x = selectedmeshpoint.y = 99; + //printer_state = AC_printer_idle; + } + else { + xy_uint8_t pos; + pos.x = atoi(&panel_command[5]); + pos.y = atoi(&panel_command[8]); + + float currmesh = getMeshPoint(pos); + float newval = atof(&panel_command[11])/100; + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Change mesh point x:", pos.x, " y:", pos.y); + SERIAL_ECHOLNPAIR("from ", currmesh, " to ", newval); + #endif + // Update Meshpoint + setMeshPoint(pos,newval); + if (printer_state == AC_printer_idle || printer_state == AC_printer_probing /*!isPrinting()*/) { + // if we are at the current mesh point indicated on the panel Move Z pos +/- 0.05mm + // (The panel changes the mesh value by +/- 0.05mm on each button press) + if (selectedmeshpoint.x == pos.x && selectedmeshpoint.y == pos.y) { + setSoftEndstopState(false); + float currZpos = getAxisPosition_mm(Z); + #if ACDEBUG(AC_INFO) + SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); + #endif + setAxisPosition_mm(currZpos + constrain(newval - currmesh, -0.05, 0.05), Z); + } + } + } + } break; } +} } // Anycubic diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h index e7bbd3cbbfb8..3c26cc0aec51 100644 --- a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h @@ -35,46 +35,46 @@ namespace Anycubic { - class ChironTFT { - private: - static printer_state_t printer_state; - static paused_state_t pause_state; - static heater_state_t hotend_state; - static heater_state_t hotbed_state; - static xy_uint8_t selectedmeshpoint; - static char panel_command[MAX_CMND_LEN]; - static uint8_t command_len; - static char selectedfile[MAX_PATH_LEN]; - static float live_Zoffset; - static file_menu_t file_menu; +class ChironTFT { + private: + static printer_state_t printer_state; + static paused_state_t pause_state; + static heater_state_t hotend_state; + static heater_state_t hotbed_state; + static xy_uint8_t selectedmeshpoint; + static char panel_command[MAX_CMND_LEN]; + static uint8_t command_len; + static char selectedfile[MAX_PATH_LEN]; + static float live_Zoffset; + static file_menu_t file_menu; - public: - ChironTFT(); - static void Startup(); - static void IdleLoop(); - static void PrinterKilled(PGM_P,PGM_P); - static void MediaEvent(media_event_t); - static void TimerEvent(timer_event_t); - static void FilamentRunout(); - static void ConfirmationRequest(const char * const ); - static void StatusChange(const char * const ); - static void PowerLossRecovery(); + public: + ChironTFT(); + static void Startup(); + static void IdleLoop(); + static void PrinterKilled(PGM_P,PGM_P); + static void MediaEvent(media_event_t); + static void TimerEvent(timer_event_t); + static void FilamentRunout(); + static void ConfirmationRequest(const char * const ); + static void StatusChange(const char * const ); + static void PowerLossRecovery(); - private: - static void SendtoTFT(PGM_P); - static void SendtoTFTLN(PGM_P); - static bool ReadTFTCommand(); - static int8_t Findcmndpos(const char *, char); - static void CheckHeaters(); - static void SendFileList(int8_t); - static void SelectFile(); - static void InjectCommandandWait(PGM_P); - static void ProcessPanelRequest(); - static void PanelInfo(uint8_t); - static void PanelAction(uint8_t); - static void PanelProcess(uint8_t); - }; + private: + static void SendtoTFT(PGM_P); + static void SendtoTFTLN(PGM_P); + static bool ReadTFTCommand(); + static int8_t Findcmndpos(const char *, char); + static void CheckHeaters(); + static void SendFileList(int8_t); + static void SelectFile(); + static void InjectCommandandWait(PGM_P); + static void ProcessPanelRequest(); + static void PanelInfo(uint8_t); + static void PanelAction(uint8_t); + static void PanelProcess(uint8_t); +}; - extern ChironTFT Chiron; +extern ChironTFT Chiron; } // Anycubic diff --git a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h index 3087d8380181..a8ebe9c776f3 100644 --- a/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h +++ b/Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h @@ -109,19 +109,16 @@ #define AC_cmnd_power_loss_recovery PSTR("G28XYR5\nG28Z") // Lift, home X and Y then home Z when in 'safe' position namespace Anycubic { - enum heater_state_t : uint8_t { AC_heater_off, AC_heater_temp_set, AC_heater_temp_reached }; - enum paused_state_t : uint8_t { AC_paused_heater_timed_out, AC_paused_purging_filament, AC_paused_idle }; - enum printer_state_t : uint8_t { AC_printer_idle, AC_printer_probing, @@ -131,13 +128,11 @@ namespace Anycubic { AC_printer_stopping, AC_printer_resuming_from_power_outage }; - enum timer_event_t : uint8_t { AC_timer_started, AC_timer_paused, AC_timer_stopped }; - enum media_event_t : uint8_t { AC_media_inserted, AC_media_removed, @@ -149,5 +144,4 @@ namespace Anycubic { AC_menu_change_to_file, AC_menu_change_to_command }; - } // Anycubic diff --git a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp index aa08f683f7ef..ecc516108c99 100644 --- a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp +++ b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp @@ -583,8 +583,7 @@ void AnycubicTFTClass::GetCommandFromTFT() { } break; case 4: { // A4 GET FAN SPEED - const float fanPercent = getActualFan_percent(FAN0); - SEND_PGM_VAL("A4V ", int(LIMIT(fanPercent, 0, 100))); + SEND_PGM_VAL("A4V ", int(getActualFan_percent(FAN0))); } break; case 5: { // A5 GET CURRENT COORDINATE diff --git a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp index 911965b9ae9d..667442b31c20 100644 --- a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp @@ -72,12 +72,24 @@ void MKS_reset_settings() { } xyz_pos_t position_before_pause; +constexpr feedRate_t park_speed_xy = TERN(NOZZLE_PARK_FEATURE, NOZZLE_PARK_XY_FEEDRATE, 100), + park_speed_z = TERN(NOZZLE_PARK_FEATURE, NOZZLE_PARK_Z_FEEDRATE, 5); + void MKS_pause_print_move() { queue.exhaust(); position_before_pause = current_position; - do_blocking_move_to(X_MIN_POS + mks_park_pos.x, Y_MIN_POS + mks_park_pos.y, current_position.z + mks_park_pos.z); + destination.z = _MIN(current_position.z + mks_park_pos.z, Z_MAX_POS); + prepare_internal_move_to_destination(park_speed_z); + destination.set(X_MIN_POS + mks_park_pos.x, Y_MIN_POS + mks_park_pos.y); + prepare_internal_move_to_destination(park_speed_xy); +} + +void MKS_resume_print_move() { + destination.set(position_before_pause.x, position_before_pause.y); + prepare_internal_move_to_destination(park_speed_xy); + destination.z = position_before_pause.z; + prepare_internal_move_to_destination(park_speed_z); } -void MKS_resume_print_move() { do_blocking_move_to(position_before_pause); } float z_offset_add = 0; diff --git a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp index e6e2af42ebe2..8833423b3743 100644 --- a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp @@ -1271,7 +1271,7 @@ void GcodeSuite::M1002() { #endif const uint8_t old_axis_relative = axis_relative; - set_e_relative(true); // M83 + set_e_relative(); // M83 { char buf[20]; snprintf_P(buf, 20, PSTR("G1E%dF%d"), parser.intval('E'), parser.intval('F')); diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h index c34d5b77560f..9de9623e198b 100644 --- a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/language/language_en.h @@ -147,6 +147,7 @@ namespace Language_en { PROGMEM Language_Str MSG_PROBE_BED = u8"Probe Mesh"; PROGMEM Language_Str MSG_SHOW_MESH = u8"View Mesh"; PROGMEM Language_Str MSG_PRINT_TEST = u8"Print Test"; + PROGMEM Language_Str MSG_MOVE_Z_TO_TOP = u8"Raise Z to Top"; #if ENABLED(TOUCH_UI_LULZBOT_BIO) PROGMEM Language_Str MSG_MOVE_TO_HOME = u8"Move to Home"; diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.cpp b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.cpp index 117ac0e452f1..f2c775c9937b 100644 --- a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.cpp +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.cpp @@ -30,7 +30,7 @@ using namespace Theme; using namespace ExtUI; constexpr static BedMeshEditScreenData &mydata = screen_data.BedMeshEditScreen; -constexpr static float gaugeThickness = 0.25; +constexpr static float gaugeThickness = 0.1; #if ENABLED(TOUCH_UI_PORTRAIT) #define GRID_COLS 3 @@ -54,20 +54,29 @@ constexpr static float gaugeThickness = 0.25; #define SAVE_POS BTN_POS(5,5), BTN_SIZE(1,1) #endif +constexpr uint8_t NONE = 255; + static float meshGetter(uint8_t x, uint8_t y, void*) { xy_uint8_t pos; pos.x = x; pos.y = y; - return ExtUI::getMeshPoint(pos) + (mydata.highlight.x != -1 && mydata.highlight == pos ? mydata.zAdjustment : 0); + return ExtUI::getMeshPoint(pos) + (mydata.highlight.x != NONE && mydata.highlight == pos ? mydata.zAdjustment : 0); } void BedMeshEditScreen::onEntry() { mydata.needSave = false; - mydata.highlight.x = -1; + mydata.highlight.x = NONE; mydata.zAdjustment = 0; + mydata.savedMeshLevelingState = ExtUI::getLevelingActive(); + mydata.savedEndstopState = ExtUI::getSoftEndstopState(); BaseScreen::onEntry(); } +void BedMeshEditScreen::onExit() { + ExtUI::setLevelingActive(mydata.savedMeshLevelingState); + ExtUI::setSoftEndstopState(mydata.savedEndstopState); +} + float BedMeshEditScreen::getHighlightedValue() { const float val = ExtUI::getMeshPoint(mydata.highlight); return (isnan(val) ? 0 : val) + mydata.zAdjustment; @@ -80,12 +89,13 @@ void BedMeshEditScreen::setHighlightedValue(float value) { void BedMeshEditScreen::moveToHighlightedValue() { if (ExtUI::getMeshValid()) { ExtUI::setLevelingActive(true); + ExtUI::setSoftEndstopState(false); ExtUI::moveToMeshPoint(mydata.highlight, gaugeThickness + mydata.zAdjustment); } } void BedMeshEditScreen::adjustHighlightedValue(float increment) { - if(mydata.highlight.x != -1) { + if (mydata.highlight.x != NONE) { mydata.zAdjustment += increment; moveToHighlightedValue(); mydata.needSave = true; @@ -114,7 +124,7 @@ void BedMeshEditScreen::drawHighlightedPointValue() { .colors(normal_btn) .text(Z_LABEL_POS, GET_TEXT_F(MSG_MESH_EDIT_Z)) .font(font_small); - if(mydata.highlight.x != -1) + if (mydata.highlight.x != NONE) draw_adjuster(cmd, Z_VALUE_POS, 3, getHighlightedValue(), GET_TEXT_F(MSG_UNITS_MM), 4, 3); cmd.colors(mydata.needSave ? normal_btn : action_btn) .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_BACK)) diff --git a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.h b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.h index 62121941b1a8..b856b9b33b3a 100644 --- a/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.h +++ b/Marlin/src/lcd/extui/lib/ftdi_eve_touch_ui/screens/bed_mesh_edit_screen.h @@ -25,7 +25,7 @@ #define FTDI_BED_MESH_EDIT_SCREEN_CLASS BedMeshEditScreen struct BedMeshEditScreenData { - bool needSave; + bool needSave, savedMeshLevelingState, savedEndstopState; xy_uint8_t highlight; float zAdjustment; }; @@ -41,6 +41,7 @@ class BedMeshEditScreen : public BedMeshBase, public CachedScreen { + private: + static void move(float inc); + static void runWizard(); public: + static void onEntry(); static void onRedraw(draw_mode_t); static bool onTouchHeld(uint8_t tag); }; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp index 4bc01c9e2d44..8137c3a909bb 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp @@ -109,33 +109,32 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { void lv_draw_acceleration_settings() { scr = lv_screen_create(ACCELERATION_UI, machine_menu.AccelerationConfTitle); - char str_1[16]; if (!uiCfg.para_ui_page) { - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.acceleration, 1, 1, str_1)); + dtostrf(planner.settings.acceleration, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.PrintAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_ACCE_PRINT, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.retract_acceleration, 1, 1, str_1)); + dtostrf(planner.settings.retract_acceleration, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.RetractAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_ACCE_RETRA, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.travel_acceleration, 1, 1, str_1)); + dtostrf(planner.settings.travel_acceleration, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.TravelAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_ACCE_TRAVEL, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[X_AXIS], public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.X_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_ACCE_X, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_ACCE_DOWN, true); } else { - sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.Y_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_ACCE_Y, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.Z_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_ACCE_Z, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[E_AXIS], public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.E0_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_ACCE_E0, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]); + itoa(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)], public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.E1_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_ACCE_E1, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_ACCE_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp index f1cdbfe414a4..3de078f37576 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp @@ -65,16 +65,15 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } void lv_draw_auto_level_offset_settings() { - char str_1[16]; scr = lv_screen_create(NOZZLE_PROBE_OFFSET_UI, machine_menu.OffsetConfTitle); - sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET, dtostrf(probe.offset.x, 1, 1, str_1) , 0)); + dtostrf(TERN0(HAS_PROBE_XY_OFFSET, probe.offset.x), 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Xoffset, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_OFFSET_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET, dtostrf(probe.offset.y, 1, 1, str_1) , 0)); + dtostrf(TERN0(HAS_PROBE_XY_OFFSET, probe.offset.y), 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Yoffset, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_OFFSET_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET, dtostrf(probe.offset.z, 1, 1, str_1) , 0)); + dtostrf(TERN0(HAS_PROBE_XY_OFFSET, probe.offset.z), 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Zoffset, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_OFFSET_Z, 2, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", common_menu.text_back, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y, event_handler, ID_OFFSET_RETURN, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp index ae8fe3a3212b..c6752939dde3 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp @@ -190,7 +190,7 @@ void display_qrcode(uint8_t *qrcode_data) { } void cloud_unbind() { - package_to_wifi(WIFI_CLOUD_UNBIND, (uint8_t *)0, 0); + package_to_wifi(WIFI_CLOUD_UNBIND, nullptr, 0); unbinding_flag = 1; } diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp index 553cb29895e0..d78c9ed0cb15 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp @@ -92,22 +92,22 @@ void lv_draw_filament_settings() { scr = lv_screen_create(FILAMENT_SETTINGS_UI, machine_menu.FilamentConfTitle); if (!uiCfg.para_ui_page) { - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_length); + itoa(gCfgItems.filamentchange_load_length, public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.InLength, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FILAMENT_SET_IN_LENGTH, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_speed); + itoa(gCfgItems.filamentchange_load_speed, public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.InSpeed, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_FILAMENT_SET_IN_SPEED, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_length); + itoa(gCfgItems.filamentchange_unload_length, public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.OutLength, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_FILAMENT_SET_OUT_LENGTH, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_speed); + itoa(gCfgItems.filamentchange_unload_speed, public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.OutSpeed, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_FILAMENT_SET_OUT_SPEED, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_FILAMENT_SET_DOWN, true); } else { - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filament_limit_temp); + itoa(gCfgItems.filament_limit_temp, public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.FilamentTemperature, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FILAMENT_SET_TEMP, 0, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_FILAMENT_SET_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp index 9a1c9dec2a3c..696463d3ebb3 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp @@ -77,17 +77,17 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { void lv_draw_homing_sensitivity_settings() { scr = lv_screen_create(HOMING_SENSITIVITY_UI, machine_menu.HomingSensitivityConfTitle); - sprintf_P(public_buf_l, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0)); + itoa(TERN(X_SENSORLESS, stepperX.homing_threshold(), 0), public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.X_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_SENSITIVITY_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0)); + itoa(TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0), public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.Y_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_SENSITIVITY_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0)); + itoa(TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0), public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.Z_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_SENSITIVITY_Z, 2, public_buf_l); #if Z2_SENSORLESS - sprintf_P(public_buf_l, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0)); + itoa(TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0), public_buf_l, 10); lv_screen_menu_item_1_edit(scr, machine_menu.Z2_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_SENSITIVITY_Z2, 3, public_buf_l); #endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp index c911b09128ae..4067262f2002 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp @@ -71,19 +71,18 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } void lv_draw_jerk_settings() { - char str_1[16]; scr = lv_screen_create(JERK_UI, machine_menu.JerkConfTitle); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[X_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[X_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.X_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_JERK_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[Y_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Y_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_JERK_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[Z_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Z_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_JERK_Z, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[E_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[E_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_JERK_E, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", common_menu.text_back, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y, event_handler, ID_JERK_RETURN, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp index 1f84ca6f599d..3572991813a0 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp @@ -137,7 +137,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) { gCfgItems.wifi_mode_sel = STA_MODEL; - package_to_wifi(WIFI_PARA_SET, (uint8_t *)0, 0); + package_to_wifi(WIFI_PARA_SET, nullptr, 0); public_buf_l[0] = 0xA5; public_buf_l[1] = 0x09; @@ -148,7 +148,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) { public_buf_l[6] = 0x00; raw_send_to_wifi((uint8_t*)public_buf_l, 6); - last_disp_state = KEY_BOARD_UI; + last_disp_state = KEYBOARD_UI; lv_clear_keyboard(); wifi_tips_type = TIPS_TYPE_JOINING; lv_draw_wifi_tips(); @@ -216,7 +216,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) { } void lv_draw_keyboard() { - scr = lv_screen_create(KEY_BOARD_UI, ""); + scr = lv_screen_create(KEYBOARD_UI, ""); // Create styles for the keyboard static lv_style_t rel_style, pr_style; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp index 9734dd94aeda..f25c7c0c257d 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp @@ -54,7 +54,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { queue.inject_P(G28_STR); } const int ind = obj->mks_obj_id - ID_M_POINT1; - sprintf_P(public_buf_l, PSTR("G1 Z10\nG1 X%d Y%d\nG1 Z0"), (int)gCfgItems.trammingPos[ind][X_AXIS], (int)gCfgItems.trammingPos[ind][Y_AXIS]); + sprintf_P(public_buf_l, PSTR("G1Z10\nG1X%dY%d\nG1Z0"), gCfgItems.trammingPos[ind].x, gCfgItems.trammingPos[ind].y); queue.inject(public_buf_l); } break; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp index cf74f42ee7e0..238a9af6ae9d 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp @@ -80,26 +80,25 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } void lv_draw_max_feedrate_settings() { - char str_1[16]; scr = lv_screen_create(MAXFEEDRATE_UI, machine_menu.MaxFeedRateConfTitle); if (!uiCfg.para_ui_page) { - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.XMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FEED_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.YMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_FEED_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.ZMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_FEED_Z, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E0MaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_FEED_E0, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_FEED_DOWN, true); } else { - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E1MaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FEED_E1, 0, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_FEED_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.cpp new file mode 100644 index 000000000000..6dc816cc234e --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.cpp @@ -0,0 +1,73 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program 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. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_TFT_LVGL_UI, MULTI_VOLUME) + +#include "draw_ui.h" +#include + +#include "../../../../inc/MarlinConfig.h" +#include "../../../../sd/cardreader.h" + +extern lv_group_t *g; +static lv_obj_t *scr; + +enum { + ID_T_USB_DISK = 1, + ID_T_SD_DISK, + ID_T_RETURN +}; + +#if ENABLED(MKS_TEST) + extern uint8_t curent_disp_ui; +#endif + +static void event_handler(lv_obj_t *obj, lv_event_t event) { + if (event != LV_EVENT_RELEASED) return; + lv_clear_media_select(); + switch (obj->mks_obj_id) { + case ID_T_USB_DISK: card.changeMedia(&card.media_usbFlashDrive); break; + case ID_T_SD_DISK: card.changeMedia(&card.media_sd_spi); break; + case ID_T_RETURN: + TERN_(MKS_TEST, curent_disp_ui = 1); + lv_draw_ready_print(); + return; + } + lv_draw_print_file(); +} + +void lv_draw_media_select() { + scr = lv_screen_create(MEDIA_SELECT_UI); + lv_big_button_create(scr, "F:/bmp_sd.bin", media_select_menu.sd_disk, INTERVAL_V, titleHeight, event_handler, ID_T_SD_DISK); + lv_big_button_create(scr, "F:/bmp_usb_disk.bin", media_select_menu.usb_disk, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_T_USB_DISK); + lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_T_RETURN); +} + +void lv_clear_media_select() { + #if HAS_ROTARY_ENCODER + if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g); + #endif + lv_obj_del(scr); +} + +#endif // HAS_TFT_LVGL_UI diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.h new file mode 100644 index 000000000000..a698714a9dce --- /dev/null +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_media_select.h @@ -0,0 +1,33 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program 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. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#ifdef __cplusplus + extern "C" { /* C-declarations for C++ */ +#endif + +extern void lv_draw_media_select(); +extern void lv_clear_media_select(); + +#ifdef __cplusplus + } /* C-declarations for C++ */ +#endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp index 092dcce083b5..70e1bba9909c 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp @@ -73,214 +73,211 @@ enum { static void disp_key_value() { char *temp; - char str_1[16]; - #if HAS_TRINAMIC_CONFIG - float milliamps; - #endif + TERN_(HAS_TRINAMIC_CONFIG, float milliamps); switch (value) { case PrintAcceleration: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.acceleration, 1, 1, str_1)); + dtostrf(planner.settings.acceleration, 1, 1, public_buf_m); break; case RetractAcceleration: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.retract_acceleration, 1, 1, str_1)); + dtostrf(planner.settings.retract_acceleration, 1, 1, public_buf_m); break; case TravelAcceleration: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.travel_acceleration, 1, 1, str_1)); + dtostrf(planner.settings.travel_acceleration, 1, 1, public_buf_m); break; case XAcceleration: - sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[X_AXIS], public_buf_m, 10); break; case YAcceleration: - sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], public_buf_m, 10); break; case ZAcceleration: - sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], public_buf_m, 10); break; case E0Acceleration: - sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]); + itoa(planner.settings.max_acceleration_mm_per_s2[E_AXIS], public_buf_m, 10); break; case E1Acceleration: - sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]); + itoa(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)], public_buf_m, 10); break; case XMaxFeedRate: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, public_buf_m); break; case YMaxFeedRate: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, public_buf_m); break; case ZMaxFeedRate: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, public_buf_m); break; case E0MaxFeedRate: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, public_buf_m); break; case E1MaxFeedRate: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, str_1)); + dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, public_buf_m); break; case XJerk: #if HAS_CLASSIC_JERK - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[X_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[X_AXIS], 1, 1, public_buf_m); #endif break; case YJerk: #if HAS_CLASSIC_JERK - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[Y_AXIS], 1, 1, public_buf_m); #endif break; case ZJerk: #if HAS_CLASSIC_JERK - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[Z_AXIS], 1, 1, public_buf_m); #endif break; case EJerk: #if HAS_CLASSIC_JERK - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[E_AXIS], 1, 1, str_1)); + dtostrf(planner.max_jerk[E_AXIS], 1, 1, public_buf_m); #endif break; case Xstep: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, public_buf_m); break; case Ystep: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, public_buf_m); break; case Zstep: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, public_buf_m); break; case E0step: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, public_buf_m); break; case E1step: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, public_buf_m); break; case Xcurrent: #if AXIS_IS_TMC(X) milliamps = stepperX.getMilliamps(); - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_m); #endif break; case Ycurrent: #if AXIS_IS_TMC(Y) milliamps = stepperY.getMilliamps(); - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_m); #endif break; case Zcurrent: #if AXIS_IS_TMC(Z) milliamps = stepperZ.getMilliamps(); - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_m); #endif break; case E0current: #if AXIS_IS_TMC(E0) milliamps = stepperE0.getMilliamps(); - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_m); #endif break; case E1current: #if AXIS_IS_TMC(E1) milliamps = stepperE1.getMilliamps(); - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_m); #endif break; case pause_pos_x: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosX, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosX, 1, 1, public_buf_m); break; case pause_pos_y: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosY, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosY, 1, 1, public_buf_m); break; case pause_pos_z: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosZ, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosZ, 1, 1, public_buf_m); break; case level_pos_x1: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[0][X_AXIS]); + itoa(gCfgItems.trammingPos[0].x, public_buf_m, 10); break; case level_pos_y1: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[0][Y_AXIS]); + itoa(gCfgItems.trammingPos[0].y, public_buf_m, 10); break; case level_pos_x2: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[1][X_AXIS]); + itoa(gCfgItems.trammingPos[1].x, public_buf_m, 10); break; case level_pos_y2: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[1][Y_AXIS]); + itoa(gCfgItems.trammingPos[1].y, public_buf_m, 10); break; case level_pos_x3: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[2][X_AXIS]); + itoa(gCfgItems.trammingPos[2].x, public_buf_m, 10); break; case level_pos_y3: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[2][Y_AXIS]); + itoa(gCfgItems.trammingPos[2].y, public_buf_m, 10); break; case level_pos_x4: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[3][X_AXIS]); + itoa(gCfgItems.trammingPos[3].x, public_buf_m, 10); break; case level_pos_y4: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[3][Y_AXIS]); + itoa(gCfgItems.trammingPos[3].y, public_buf_m, 10); break; case level_pos_x5: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[4][X_AXIS]); + itoa(gCfgItems.trammingPos[4].x, public_buf_m, 10); break; case level_pos_y5: - sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.trammingPos[4][Y_AXIS]); + itoa(gCfgItems.trammingPos[4].y, public_buf_m, 10); break; #if HAS_BED_PROBE case x_offset: #if HAS_PROBE_XY_OFFSET - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.x, 1, 3, str_1)); + dtostrf(probe.offset.x, 1, 3, public_buf_m); #endif break; case y_offset: #if HAS_PROBE_XY_OFFSET - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.y, 1, 3, str_1)); + dtostrf(probe.offset.y, 1, 3, public_buf_m); #endif break; case z_offset: - sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.z, 1, 3, str_1)); + dtostrf(probe.offset.z, 1, 3, public_buf_m); break; #endif case load_length: - sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_length); + itoa(gCfgItems.filamentchange_load_length, public_buf_m, 10); break; case load_speed: - sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_speed); + itoa(gCfgItems.filamentchange_load_speed, public_buf_m, 10); break; case unload_length: - sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_length); + itoa(gCfgItems.filamentchange_unload_length, public_buf_m, 10); break; case unload_speed: - sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_speed); + itoa(gCfgItems.filamentchange_unload_speed, public_buf_m, 10); break; case filament_temp: - sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filament_limit_temp); + itoa(gCfgItems.filament_limit_temp, public_buf_m, 10); break; case x_sensitivity: #if X_SENSORLESS - sprintf_P(public_buf_m, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0)); + itoa(TERN(X_SENSORLESS, stepperX.homing_threshold(), 0), public_buf_m, 10); #endif break; case y_sensitivity: #if Y_SENSORLESS - sprintf_P(public_buf_m, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0)); + itoa(TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0), public_buf_m, 10); #endif break; case z_sensitivity: #if Z_SENSORLESS - sprintf_P(public_buf_m, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0)); + itoa(TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0), public_buf_m, 10); #endif break; case z2_sensitivity: #if Z2_SENSORLESS - sprintf_P(public_buf_m, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0)); + itoa(TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0), public_buf_m, 10); #endif break; } @@ -346,16 +343,16 @@ static void set_value_confirm() { case pause_pos_x: gCfgItems.pausePosX = atof(key_value); update_spi_flash(); break; case pause_pos_y: gCfgItems.pausePosY = atof(key_value); update_spi_flash(); break; case pause_pos_z: gCfgItems.pausePosZ = atof(key_value); update_spi_flash(); break; - case level_pos_x1: gCfgItems.trammingPos[0][X_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_y1: gCfgItems.trammingPos[0][Y_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_x2: gCfgItems.trammingPos[1][X_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_y2: gCfgItems.trammingPos[1][Y_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_x3: gCfgItems.trammingPos[2][X_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_y3: gCfgItems.trammingPos[2][Y_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_x4: gCfgItems.trammingPos[3][X_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_y4: gCfgItems.trammingPos[3][Y_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_x5: gCfgItems.trammingPos[4][X_AXIS] = atoi(key_value); update_spi_flash(); break; - case level_pos_y5: gCfgItems.trammingPos[4][Y_AXIS] = atoi(key_value); update_spi_flash(); break; + case level_pos_x1: gCfgItems.trammingPos[0].x = atoi(key_value); update_spi_flash(); break; + case level_pos_y1: gCfgItems.trammingPos[0].y = atoi(key_value); update_spi_flash(); break; + case level_pos_x2: gCfgItems.trammingPos[1].x = atoi(key_value); update_spi_flash(); break; + case level_pos_y2: gCfgItems.trammingPos[1].y = atoi(key_value); update_spi_flash(); break; + case level_pos_x3: gCfgItems.trammingPos[2].x = atoi(key_value); update_spi_flash(); break; + case level_pos_y3: gCfgItems.trammingPos[2].y = atoi(key_value); update_spi_flash(); break; + case level_pos_x4: gCfgItems.trammingPos[3].x = atoi(key_value); update_spi_flash(); break; + case level_pos_y4: gCfgItems.trammingPos[3].y = atoi(key_value); update_spi_flash(); break; + case level_pos_x5: gCfgItems.trammingPos[4].x = atoi(key_value); update_spi_flash(); break; + case level_pos_y5: gCfgItems.trammingPos[4].y = atoi(key_value); update_spi_flash(); break; #if HAS_BED_PROBE case x_offset: { #if HAS_PROBE_XY_OFFSET diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp index 385276af3938..2f60bc668598 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp @@ -60,16 +60,15 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } void lv_draw_pause_position() { - char str_1[16]; scr = lv_screen_create(PAUSE_POS_UI, machine_menu.PausePosText); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosX, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosX, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.xPos, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_PAUSE_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosY, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosY, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.yPos, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_PAUSE_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosZ, 1, 1, str_1)); + dtostrf(gCfgItems.pausePosZ, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.zPos, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_PAUSE_Z, 2, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", common_menu.text_back, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y, event_handler, ID_PAUSE_RETURN, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp index d32851f76167..17f5d95d2ae0 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp @@ -177,7 +177,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } else { lv_clear_print_file(); - lv_draw_ready_print(); + TERN(MULTI_VOLUME, lv_draw_media_select(), lv_draw_ready_print()); } } else { @@ -248,6 +248,7 @@ static char test_public_buf_l[40]; void disp_gcode_icon(uint8_t file_num) { uint8_t i; + // TODO: set current media title?! scr = lv_screen_create(PRINT_FILE_UI, ""); // Create image buttons diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp index 6025968d3b1f..e9cfd8179a71 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp @@ -236,7 +236,7 @@ void disp_bed_temp() { } void disp_fan_speed() { - sprintf_P(public_buf_l, PSTR("%d%%"), thermalManager.fanPercent(thermalManager.fan_speed[0])); + sprintf_P(public_buf_l, PSTR("%d%%"), thermalManager.fanSpeedPercent(0)); lv_label_set_text(labelFan, public_buf_l); } @@ -251,8 +251,7 @@ void disp_print_time() { } void disp_fan_Zpos() { - char str_1[16]; - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(current_position[Z_AXIS], 1, 3, str_1)); + dtostrf(current_position.z, 1, 3, public_buf_l); lv_label_set_text(labelZpos, public_buf_l); } diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp index 45a2167a05b9..8340e2ae8742 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp @@ -45,7 +45,6 @@ #define ICON_POS_Y 38 #define TARGET_LABEL_MOD_Y -36 #define LABEL_MOD_Y 30 -#define SECOND_EXT_MOD_Y 100 extern lv_group_t* g; static lv_obj_t *scr; @@ -74,7 +73,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { case ID_INFO_EXT: uiCfg.curTempType = 0; lv_draw_preHeat(); break; case ID_INFO_BED: uiCfg.curTempType = 1; lv_draw_preHeat(); break; case ID_INFO_FAN: lv_draw_fan(); break; - case ID_PRINT: lv_draw_print_file(); break; + case ID_PRINT: TERN(MULTI_VOLUME, lv_draw_media_select(), lv_draw_print_file()); break; } } @@ -186,29 +185,38 @@ void lv_draw_ready_print() { // Monitoring lv_obj_t *buttonExt1 = lv_big_button_create(scr, "F:/bmp_ext1_state.bin", " ", 55, ICON_POS_Y, event_handler, ID_INFO_EXT); #if HAS_MULTI_EXTRUDER - lv_obj_t *buttonExt2 = lv_big_button_create(scr, "F:/bmp_ext2_state.bin", " ", 55, ICON_POS_Y + SECOND_EXT_MOD_Y, event_handler, ID_INFO_EXT); - #endif - #if HAS_HEATED_BED + lv_obj_t *buttonExt2 = lv_big_button_create(scr, "F:/bmp_ext2_state.bin", " ", 163, ICON_POS_Y, event_handler, ID_INFO_EXT); + #if HAS_HEATED_BED + lv_obj_t *buttonBedstate = lv_big_button_create(scr, "F:/bmp_bed_state.bin", " ", 271, ICON_POS_Y, event_handler, ID_INFO_BED); + #endif + #else + #if HAS_HEATED_BED lv_obj_t *buttonBedstate = lv_big_button_create(scr, "F:/bmp_bed_state.bin", " ", 210, ICON_POS_Y, event_handler, ID_INFO_BED); + #endif #endif + lv_obj_t *buttonFanstate = lv_big_button_create(scr, "F:/bmp_fan_state.bin", " ", 380, ICON_POS_Y, event_handler, ID_INFO_FAN); labelExt1 = lv_label_create(scr, 55, LABEL_MOD_Y, nullptr); labelExt1Target = lv_label_create(scr, 55, LABEL_MOD_Y, nullptr); #if HAS_MULTI_EXTRUDER - labelExt2 = lv_label_create(scr, 55, LABEL_MOD_Y + SECOND_EXT_MOD_Y, nullptr); - labelExt2Target = lv_label_create(scr, 55, LABEL_MOD_Y + SECOND_EXT_MOD_Y, nullptr); - #endif - - #if HAS_HEATED_BED - labelBed = lv_label_create(scr, 210, LABEL_MOD_Y, nullptr); - labelBedTarget = lv_label_create(scr, 210, LABEL_MOD_Y, nullptr); + labelExt2 = lv_label_create(scr, 163, LABEL_MOD_Y, nullptr); + labelExt2Target = lv_label_create(scr, 163, LABEL_MOD_Y, nullptr); + #if HAS_HEATED_BED + labelBed = lv_label_create(scr, 271, LABEL_MOD_Y, nullptr); + labelBedTarget = lv_label_create(scr, 271, LABEL_MOD_Y, nullptr); + #endif + #else + #if HAS_HEATED_BED + labelBed = lv_label_create(scr, 210, LABEL_MOD_Y, nullptr); + labelBedTarget = lv_label_create(scr, 210, LABEL_MOD_Y, nullptr); + #endif #endif labelFan = lv_label_create(scr, 380, 80, nullptr); - sprintf_P(buf, PSTR("%d"), (int)thermalManager.degHotend(0)); + itoa(thermalManager.degHotend(0), buf, 10); lv_label_set_text(labelExt1, buf); lv_obj_align(labelExt1, buttonExt1, LV_ALIGN_CENTER, 0, LABEL_MOD_Y); sprintf_P(buf, PSTR("-> %d"), (int)thermalManager.degTargetHotend(0)); @@ -216,7 +224,7 @@ void lv_draw_ready_print() { lv_obj_align(labelExt1Target, buttonExt1, LV_ALIGN_CENTER, 0, TARGET_LABEL_MOD_Y); #if HAS_MULTI_EXTRUDER - sprintf_P(buf, PSTR("%d"), (int)thermalManager.degHotend(1)); + itoa(thermalManager.degHotend(1), buf, 10); lv_label_set_text(labelExt2, buf); lv_obj_align(labelExt2, buttonExt2, LV_ALIGN_CENTER, 0, LABEL_MOD_Y); sprintf_P(buf, PSTR("-> %d"), (int)thermalManager.degTargetHotend(1)); @@ -225,7 +233,7 @@ void lv_draw_ready_print() { #endif #if HAS_HEATED_BED - sprintf_P(buf, PSTR("%d"), (int)thermalManager.degBed()); + itoa(thermalManager.degBed(), buf, 10); lv_label_set_text(labelBed, buf); lv_obj_align(labelBed, buttonBedstate, LV_ALIGN_CENTER, 0, LABEL_MOD_Y); sprintf_P(buf, PSTR("-> %d"), (int)thermalManager.degTargetBed()); @@ -233,7 +241,7 @@ void lv_draw_ready_print() { lv_obj_align(labelBedTarget, buttonBedstate, LV_ALIGN_CENTER, 0, TARGET_LABEL_MOD_Y); #endif - sprintf_P(buf, PSTR("%d%%"), thermalManager.fanPercent(thermalManager.fan_speed[0])); + sprintf_P(buf, PSTR("%d%%"), (int)thermalManager.fanSpeedPercent(0)); lv_label_set_text(labelFan, buf); lv_obj_align(labelFan, buttonFanstate, LV_ALIGN_CENTER, 0, LABEL_MOD_Y); } diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp index a88669f371f6..f48d533691e5 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp @@ -79,26 +79,25 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { } void lv_draw_step_settings() { - char str_1[16]; scr = lv_screen_create(STEPS_UI, machine_menu.StepsConfTitle); if (!uiCfg.para_ui_page) { - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.X_Steps, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_STEP_X, 0, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Y_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_STEP_Y, 1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Z_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_STEP_Z, 2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E0_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_STEP_E0, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_STEP_DOWN, true); } else { - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, str_1)); + dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E1_Steps, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_STEP_E1, 0, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_STEP_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp index 7f889461eaa9..7c0fc97c9315 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp @@ -95,14 +95,13 @@ void lv_draw_tmc_current_settings() { scr = lv_screen_create(TMC_CURRENT_UI, machine_menu.TmcCurrentConfTitle); float milliamps; - char str_1[16]; if (!uiCfg.para_ui_page) { #if AXIS_IS_TMC(X) milliamps = stepperX.getMilliamps(); #else milliamps = -1; #endif - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.X_Current, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_CURRENT_X, 0, public_buf_l); #if AXIS_IS_TMC(Y) @@ -110,7 +109,7 @@ void lv_draw_tmc_current_settings() { #else milliamps = -1; #endif - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Y_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_TMC_CURRENT_Y, 1, public_buf_l); #if AXIS_IS_TMC(Z) @@ -118,7 +117,7 @@ void lv_draw_tmc_current_settings() { #else milliamps = -1; #endif - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.Z_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_TMC_CURRENT_Z, 2, public_buf_l); #if AXIS_IS_TMC(E0) @@ -126,7 +125,7 @@ void lv_draw_tmc_current_settings() { #else milliamps = -1; #endif - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E0_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_TMC_CURRENT_E0, 3, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_TMC_CURRENT_DOWN, true); @@ -137,7 +136,7 @@ void lv_draw_tmc_current_settings() { #else milliamps = -1; #endif - sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1)); + dtostrf(milliamps, 1, 1, public_buf_l); lv_screen_menu_item_1_edit(scr, machine_menu.E1_Current, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_CURRENT_E1, 0, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_TMC_CURRENT_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tramming_pos_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tramming_pos_settings.cpp index d5307232d6d9..539c7639dc02 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_tramming_pos_settings.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tramming_pos_settings.cpp @@ -107,27 +107,27 @@ void lv_draw_tramming_pos_settings() { scr = lv_screen_create(MANUAL_LEVELING_POSIGION_UI, machine_menu.LevelingParaConfTitle); if (!uiCfg.para_ui_page) { - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.trammingPos[0][X_AXIS]); - sprintf_P(buf2, PSTR("%d"), gCfgItems.trammingPos[0][Y_AXIS]); + itoa(gCfgItems.trammingPos[0].x, public_buf_l, 10); + itoa(gCfgItems.trammingPos[0].y, buf2, 10); lv_screen_menu_item_2_edit(scr, leveling_menu.position1, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MANUAL_POS_Y1, 0, buf2, ID_MANUAL_POS_X1, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.trammingPos[1][X_AXIS]); - sprintf_P(buf2, PSTR("%d"), gCfgItems.trammingPos[1][Y_AXIS]); + itoa(gCfgItems.trammingPos[1].x, public_buf_l, 10); + itoa(gCfgItems.trammingPos[1].y, buf2, 10); lv_screen_menu_item_2_edit(scr, leveling_menu.position2, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_MANUAL_POS_Y2, 1, buf2, ID_MANUAL_POS_X2, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.trammingPos[2][X_AXIS]); - sprintf_P(buf2, PSTR("%d"), gCfgItems.trammingPos[2][Y_AXIS]); + itoa(gCfgItems.trammingPos[2].x, public_buf_l, 10); + itoa(gCfgItems.trammingPos[2].y, buf2, 10); lv_screen_menu_item_2_edit(scr, leveling_menu.position3, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_MANUAL_POS_Y3, 2, buf2, ID_MANUAL_POS_X3, public_buf_l); - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.trammingPos[3][X_AXIS]); - sprintf_P(buf2, PSTR("%d"), gCfgItems.trammingPos[3][Y_AXIS]); + itoa(gCfgItems.trammingPos[3].x, public_buf_l, 10); + itoa(gCfgItems.trammingPos[3].y, buf2, 10); lv_screen_menu_item_2_edit(scr, leveling_menu.position4, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_MANUAL_POS_Y4, 3, buf2, ID_MANUAL_POS_X4, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_MANUAL_POS_DOWN, true); } else { - sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.trammingPos[4][X_AXIS]); - sprintf_P(buf2, PSTR("%d"), gCfgItems.trammingPos[4][Y_AXIS]); + itoa(gCfgItems.trammingPos[4].x, public_buf_l, 10); + itoa(gCfgItems.trammingPos[4].y, buf2, 10); lv_screen_menu_item_2_edit(scr, leveling_menu.position4, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MANUAL_POS_Y5, 0, buf2, ID_MANUAL_POS_X5, public_buf_l); lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.previous, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_MANUAL_POS_UP, true); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp index 68baea30c79a..0a99df08e5a4 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp @@ -125,16 +125,16 @@ void gCfgItems_init() { gCfgItems.pausePosX = -1; gCfgItems.pausePosY = -1; gCfgItems.pausePosZ = 5; - gCfgItems.trammingPos[0][X_AXIS] = X_MIN_POS + 30; - gCfgItems.trammingPos[0][Y_AXIS] = Y_MIN_POS + 30; - gCfgItems.trammingPos[1][X_AXIS] = X_MAX_POS - 30; - gCfgItems.trammingPos[1][Y_AXIS] = Y_MIN_POS + 30; - gCfgItems.trammingPos[2][X_AXIS] = X_MAX_POS - 30; - gCfgItems.trammingPos[2][Y_AXIS] = Y_MAX_POS - 30; - gCfgItems.trammingPos[3][X_AXIS] = X_MIN_POS + 30; - gCfgItems.trammingPos[3][Y_AXIS] = Y_MAX_POS - 30; - gCfgItems.trammingPos[4][X_AXIS] = X_BED_SIZE / 2; - gCfgItems.trammingPos[4][Y_AXIS] = Y_BED_SIZE / 2; + gCfgItems.trammingPos[0].x = X_MIN_POS + 30; + gCfgItems.trammingPos[0].y = Y_MIN_POS + 30; + gCfgItems.trammingPos[1].x = X_MAX_POS - 30; + gCfgItems.trammingPos[1].y = Y_MIN_POS + 30; + gCfgItems.trammingPos[2].x = X_MAX_POS - 30; + gCfgItems.trammingPos[2].y = Y_MAX_POS - 30; + gCfgItems.trammingPos[3].x = X_MIN_POS + 30; + gCfgItems.trammingPos[3].y = Y_MAX_POS - 30; + gCfgItems.trammingPos[4].x = X_BED_SIZE / 2; + gCfgItems.trammingPos[4].y = Y_BED_SIZE / 2; gCfgItems.cloud_enable = false; gCfgItems.wifi_mode_sel = STA_MODEL; gCfgItems.fileSysType = FILE_SYS_SD; @@ -447,111 +447,63 @@ char *getDispText(int index) { ZERO(public_buf_l); switch (disp_state_stack._disp_state[index]) { - case PRINT_READY_UI: - strcpy(public_buf_l, main_menu.title); - break; - case PRINT_FILE_UI: - strcpy(public_buf_l, file_menu.title); - break; + case PRINT_READY_UI: strcpy(public_buf_l, main_menu.title); break; + case PRINT_FILE_UI: strcpy(public_buf_l, file_menu.title); break; case PRINTING_UI: - if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI - #ifndef TFT35 - || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI - || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI - #endif - ) strcpy(public_buf_l, common_menu.print_special_title); - else strcpy(public_buf_l, printing_menu.title); - break; - case MOVE_MOTOR_UI: - strcpy(public_buf_l, move_menu.title); + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + IF_DISABLED(TFT35, case OPERATE_UI: case PAUSE_UI:) + case PRINTING_UI: strcpy(public_buf_l, common_menu.print_special_title); break; + default: strcpy(public_buf_l, printing_menu.title); break; + } break; + case MOVE_MOTOR_UI: strcpy(public_buf_l, move_menu.title); break; case OPERATE_UI: - if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI - #ifndef TFT35 - || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI - || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI - #endif - ) strcpy(public_buf_l, common_menu.operate_special_title); - else strcpy(public_buf_l, operation_menu.title); + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + IF_DISABLED(TFT35, case OPERATE_UI: case PAUSE_UI:) + case PRINTING_UI: strcpy(public_buf_l, common_menu.operate_special_title); break; + default: strcpy(public_buf_l, operation_menu.title); break; + } break; case PAUSE_UI: - if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI - || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI - || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI - ) strcpy(public_buf_l, common_menu.pause_special_title); - else strcpy(public_buf_l, pause_menu.title); - break; - - case EXTRUSION_UI: - strcpy(public_buf_l, extrude_menu.title); - break; - case CHANGE_SPEED_UI: - strcpy(public_buf_l, speed_menu.title); - break; - case FAN_UI: - strcpy(public_buf_l, fan_menu.title); + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + case OPERATE_UI: + case PAUSE_UI: + case PRINTING_UI: strcpy(public_buf_l, common_menu.pause_special_title); break; + default: strcpy(public_buf_l, pause_menu.title); break; + } break; + case EXTRUSION_UI: strcpy(public_buf_l, extrude_menu.title); break; + case CHANGE_SPEED_UI: strcpy(public_buf_l, speed_menu.title); break; + case FAN_UI: strcpy(public_buf_l, fan_menu.title); break; case PRE_HEAT_UI: - if ((disp_state_stack._disp_state[disp_state_stack._disp_index - 1] == OPERATE_UI)) - strcpy(public_buf_l, preheat_menu.adjust_title); - else strcpy(public_buf_l, preheat_menu.title); - break; - case SET_UI: - strcpy(public_buf_l, set_menu.title); - break; - case ZERO_UI: - strcpy(public_buf_l, home_menu.title); - break; - case SPRAYER_UI: break; - case MACHINE_UI: break; - case LANGUAGE_UI: - strcpy(public_buf_l, language_menu.title); - break; - case ABOUT_UI: - strcpy(public_buf_l, about_menu.title); - break; - case LOG_UI: break; - case DISK_UI: - strcpy(public_buf_l, filesys_menu.title); - break; - case DIALOG_UI: - strcpy(public_buf_l, common_menu.dialog_confirm_title); - break; - case WIFI_UI: - strcpy(public_buf_l, wifi_menu.title); + switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) { + case OPERATE_UI: strcpy(public_buf_l, preheat_menu.adjust_title); + default: strcpy(public_buf_l, preheat_menu.title); break; + } break; + case SET_UI: strcpy(public_buf_l, set_menu.title); break; + case ZERO_UI: strcpy(public_buf_l, home_menu.title); break; + case SPRAYER_UI: break; + case MACHINE_UI: break; + case LANGUAGE_UI: strcpy(public_buf_l, language_menu.title); break; + case ABOUT_UI: strcpy(public_buf_l, about_menu.title); break; + case LOG_UI: break; + case DISK_UI: strcpy(public_buf_l, filesys_menu.title); break; + case DIALOG_UI: strcpy(public_buf_l, common_menu.dialog_confirm_title); break; + case WIFI_UI: strcpy(public_buf_l, wifi_menu.title); break; case MORE_UI: - case PRINT_MORE_UI: - strcpy(public_buf_l, more_menu.title); - break; - case FILAMENTCHANGE_UI: - strcpy(public_buf_l, filament_menu.title); - break; + case PRINT_MORE_UI: strcpy(public_buf_l, more_menu.title); break; + case FILAMENTCHANGE_UI: strcpy(public_buf_l, filament_menu.title); break; case LEVELING_UI: - case MESHLEVELING_UI: - strcpy(public_buf_l, leveling_menu.title); - break; - case BIND_UI: - strcpy(public_buf_l, cloud_menu.title); - break; - case TOOL_UI: - strcpy(public_buf_l, tool_menu.title); - break; - case WIFI_LIST_UI: - #if ENABLED(MKS_WIFI_MODULE) - strcpy(public_buf_l, list_menu.title); - break; - #endif - case MACHINE_PARA_UI: - strcpy(public_buf_l, MachinePara_menu.title); - break; - case BABY_STEP_UI: - strcpy(public_buf_l, operation_menu.babystep); - break; - case EEPROM_SETTINGS_UI: - strcpy(public_buf_l, eeprom_menu.title); - break; + case MESHLEVELING_UI: strcpy(public_buf_l, leveling_menu.title); break; + case BIND_UI: strcpy(public_buf_l, cloud_menu.title); break; + case TOOL_UI: strcpy(public_buf_l, tool_menu.title); break; + case WIFI_LIST_UI: TERN_(MKS_WIFI_MODULE, strcpy(public_buf_l, list_menu.title)); break; + case MACHINE_PARA_UI: strcpy(public_buf_l, MachinePara_menu.title); break; + case BABY_STEP_UI: strcpy(public_buf_l, operation_menu.babystep); break; + case EEPROM_SETTINGS_UI: strcpy(public_buf_l, eeprom_menu.title); break; + case MEDIA_SELECT_UI: strcpy(public_buf_l, media_select_menu.title); break; default: break; } @@ -828,11 +780,9 @@ void GUI_RefreshPage() { } break; - case OPERATE_UI: - break; + case OPERATE_UI: break; - case PAUSE_UI: - break; + case PAUSE_UI: break; case FAN_UI: if (temps_update_flag) { @@ -841,8 +791,7 @@ void GUI_RefreshPage() { } break; - case MOVE_MOTOR_UI: - break; + case MOVE_MOTOR_UI: break; #if ENABLED(MKS_WIFI_MODULE) case WIFI_UI: @@ -852,10 +801,9 @@ void GUI_RefreshPage() { } break; - case BIND_UI: - refresh_bind_ui(); - break; + case BIND_UI: refresh_bind_ui(); break; #endif + case FILAMENTCHANGE_UI: if (temps_update_flag) { temps_update_flag = false; @@ -866,10 +814,8 @@ void GUI_RefreshPage() { filament_dialog_handle(); TERN_(MKS_WIFI_MODULE, wifi_scan_handle()); break; - case MESHLEVELING_UI: - break; - case HARDWARE_TEST_UI: - break; + case MESHLEVELING_UI: break; + case HARDWARE_TEST_UI: break; case WIFI_LIST_UI: #if ENABLED(MKS_WIFI_MODULE) if (printing_rate_update_flag) { @@ -878,8 +824,8 @@ void GUI_RefreshPage() { } #endif break; - case KEY_BOARD_UI: - break; + case KEYBOARD_UI: break; + #if ENABLED(MKS_WIFI_MODULE) case WIFI_TIPS_UI: switch (wifi_tips_type) { @@ -932,6 +878,7 @@ void GUI_RefreshPage() { disp_z_offset_value(); } break; + default: break; } @@ -982,7 +929,7 @@ void clear_cur_ui() { #if ENABLED(MKS_WIFI_MODULE) case WIFI_LIST_UI: lv_clear_wifi_list(); break; #endif - case KEY_BOARD_UI: lv_clear_keyboard(); break; + case KEYBOARD_UI: lv_clear_keyboard(); break; #if ENABLED(MKS_WIFI_MODULE) case WIFI_TIPS_UI: lv_clear_wifi_tips(); break; #endif @@ -1013,9 +960,9 @@ void clear_cur_ui() { case NUMBER_KEY_UI: lv_clear_number_key(); break; case BABY_STEP_UI: lv_clear_baby_stepping(); break; case PAUSE_POS_UI: lv_clear_pause_position(); break; - #if HAS_TRINAMIC_CONFIG - case TMC_CURRENT_UI: lv_clear_tmc_current_settings(); break; - #endif + #if HAS_TRINAMIC_CONFIG + case TMC_CURRENT_UI: lv_clear_tmc_current_settings(); break; + #endif case EEPROM_SETTINGS_UI: lv_clear_eeprom_settings(); break; #if HAS_STEALTHCHOP case TMC_MODE_UI: lv_clear_tmc_step_mode_settings(); break; @@ -1032,6 +979,9 @@ void clear_cur_ui() { #if ENABLED(TOUCH_SCREEN_CALIBRATION) case TOUCH_CALIBRATION_UI: lv_clear_touch_calibration_screen(); break; #endif + #if ENABLED(MULTI_VOLUME) + case MEDIA_SELECT_UI: lv_clear_media_select(); break; + #endif default: break; } } @@ -1087,7 +1037,7 @@ void draw_return_ui() { #if ENABLED(MKS_WIFI_MODULE) case WIFI_LIST_UI: lv_draw_wifi_list(); break; #endif - case KEY_BOARD_UI: lv_draw_keyboard(); break; + case KEYBOARD_UI: lv_draw_keyboard(); break; #if ENABLED(MKS_WIFI_MODULE) case WIFI_TIPS_UI: lv_draw_wifi_tips(); break; #endif diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h index 2be4f7d70b04..2809e4e93791 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h +++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h @@ -76,6 +76,7 @@ #include "draw_homing_sensitivity_settings.h" #include "draw_baby_stepping.h" #include "draw_keyboard.h" +#include "draw_media_select.h" #include "draw_encoder_settings.h" #include "../../../../inc/MarlinConfigPre.h" @@ -197,7 +198,7 @@ typedef struct { uint8_t wifi_type; bool cloud_enable, encoder_enable; - int trammingPos[5][2]; // XY + xy_int_t trammingPos[5]; int filamentchange_load_length, filamentchange_load_speed, filamentchange_unload_length, @@ -289,7 +290,7 @@ typedef enum { TOOL_UI, HARDWARE_TEST_UI, WIFI_LIST_UI, - KEY_BOARD_UI, + KEYBOARD_UI, WIFI_TIPS_UI, MACHINE_PARA_UI, MACHINE_SETTINGS_UI, @@ -327,6 +328,7 @@ typedef enum { ENCODER_SETTINGS_UI, TOUCH_CALIBRATION_UI, GCODE_UI, + MEDIA_SELECT_UI, } DISP_STATE; typedef struct { diff --git a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp index 36f276c21b28..9318b50d2bca 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp @@ -197,6 +197,13 @@ static const char assets[][LONG_FILENAME_LENGTH] = { "bmp_cloud.bin", #endif + #if ENABLED(MULTI_VOLUME) + "bmp_usb_disk.bin", + // "bmp_usb_disk_sel.bin", + "bmp_sd.bin", + // "bmp_sd_sel.bin", + #endif + // Babystep screen "bmp_baby_move0_01.bin", "bmp_baby_move0_05.bin", diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h index 104e1fdcafd6..b6eef183682a 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h @@ -540,6 +540,7 @@ #define USB_DRIVE_BACK_EN "< Back" #define FILE_PAGES_EN "%d/%d" #define FILE_NEXT_PAGE_EN "Next Page" +#define MEDIA_SELECT_TITLE_EN "Select Media" //BUILD PLATE #define PLATE_TITLE_EN "Build Plate" diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp index 20b7d5f60603..5e37acb2b4d8 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp @@ -56,6 +56,7 @@ tool_menu_def tool_menu; MachinePara_menu_def MachinePara_menu; pause_msg_def pause_msg_menu; eeprom_def eeprom_menu; +media_select_menu_def media_select_menu; machine_common_def machine_menu; void machine_setting_disp() { @@ -821,6 +822,10 @@ void disp_language_init() { filament_menu.stat_temp = TEXT_VALUE; + media_select_menu.title = MEDIA_SELECT_TITLE_EN; + media_select_menu.sd_disk = SD_CARD_TITLE_EN; + media_select_menu.usb_disk = USB_DRIVE_TITLE_EN; + machine_menu.key_0 = KEYBOARD_KEY0_EN; machine_menu.key_1 = KEYBOARD_KEY1_EN; machine_menu.key_2 = KEYBOARD_KEY2_EN; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h index 61e3524c5838..79faad74e208 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h +++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h @@ -706,6 +706,14 @@ typedef struct tool_menu_disp { extern tool_menu_def tool_menu; +typedef struct media_select_menu_disp { + const char *title; + const char *sd_disk; + const char *usb_disk; +} media_select_menu_def; + +extern media_select_menu_def media_select_menu; + typedef struct MachinePara_menu_disp { const char *title; const char *MachineSetting; diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp index 1057a0c6893a..1162f7a228ed 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp @@ -178,14 +178,14 @@ void changeFlashMode(const bool dmaMode) { } } -static bool longName2DosName(const char *longName, uint8_t *dosName) { +static bool longName2DosName(const char *longName, char *dosName) { uint8_t i; for (i = FILENAME_LENGTH; i--;) dosName[i] = '\0'; while (*longName) { uint8_t c = *longName++; if (c == '.') { // For a dot... if (i == 0) return false; - strcat_P((char *)dosName, PSTR(".GCO")); + strcat_P(dosName, PSTR(".GCO")); break; } else { @@ -196,7 +196,7 @@ static bool longName2DosName(const char *longName, uint8_t *dosName) { dosName[i++] = c + (WITHIN(c, 'a', 'z') ? 'A' - 'a' : 0); // Uppercase required for 8.3 name } if (i >= 5) { - strcat_P((char *)dosName, PSTR("~1.GCO")); + strcat_P(dosName, PSTR("~1.GCO")); break; } } @@ -680,7 +680,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { strcat_P((char *)list_file.file_name[sel_id], PSTR("/")); if (file_writer.fileTransfer == 1) { - uint8_t dosName[FILENAME_LENGTH]; + char dosName[FILENAME_LENGTH]; uint8_t fileName[sizeof(list_file.file_name[sel_id])]; fileName[0] = '\0'; if (has_path_selected == 1) { @@ -690,8 +690,8 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { else strcat((char *)fileName, (char *)&tmpStr[index]); if (!longName2DosName((const char *)fileName, dosName)) strcpy_P(list_file.file_name[sel_id], PSTR("notValid")); - strcat((char *)list_file.file_name[sel_id], (char *)dosName); - strcat((char *)list_file.long_name[sel_id], (char *)dosName); + strcat((char *)list_file.file_name[sel_id], dosName); + strcat((char *)list_file.long_name[sel_id], dosName); } else { strcat((char *)list_file.file_name[sel_id], (char *)&tmpStr[index]); @@ -883,7 +883,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { SEND_OK_TO_WIFI; char *outBuf = (char *)tempBuf; - char str_1[16], tbuf[34]; + char tbuf[34]; sprintf_P(tbuf, PSTR("%d /%d"), (int)thermalManager.degHotend(0), (int)thermalManager.degTargetHotend(0)); @@ -1142,7 +1142,7 @@ static void wifi_list_msg_handle(uint8_t * msg, uint16_t msgLen) { int8_t valid_name_num; if (msgLen <= 0) return; - if (disp_state == KEY_BOARD_UI) return; + if (disp_state == KEYBOARD_UI) return; wifi_list.getNameNum = msg[0]; @@ -1303,9 +1303,9 @@ static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) { #if ENABLED(SDSUPPORT) - uint8_t dosName[FILENAME_LENGTH]; + char dosName[FILENAME_LENGTH]; - if (!longName2DosName((const char *)file_writer.saveFileName,dosName)) { + if (!longName2DosName((const char *)file_writer.saveFileName, dosName)) { clear_cur_ui(); upload_result = 2; wifiTransError.flag = 1; @@ -1313,7 +1313,7 @@ static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) { lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE); return; } - sprintf_P((char *)saveFilePath, PSTR("%s"), dosName); + strcpy((char *)saveFilePath, dosName); card.cdroot(); upload_file.close(); diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h index 048996e9194d..0886641b2d2f 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h @@ -178,18 +178,18 @@ extern CLOUD_PARA cloud_para; extern WIFI_GCODE_BUFFER espGcodeFifo; -extern uint32_t getWifiTick(); -extern uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick); +uint32_t getWifiTick(); +uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick); void mks_esp_wifi_init(); -extern int cfg_cloud_flag; -extern int send_to_wifi(uint8_t *buf, int len); +extern int cfg_cloud_flag; +int send_to_wifi(uint8_t *buf, int len); void wifi_looping(); -extern int raw_send_to_wifi(uint8_t *buf, int len); -extern int package_to_wifi(WIFI_RET_TYPE type, uint8_t *buf, int len); +int raw_send_to_wifi(uint8_t *buf, int len); +int package_to_wifi(WIFI_RET_TYPE type, uint8_t *buf, int len); void get_wifi_list_command_send(); void get_wifi_commands(); -extern int readWifiBuf(int8_t *buf, int32_t len); +int readWifiBuf(int8_t *buf, int32_t len); void mks_wifi_firmware_update(); #ifdef __cplusplus diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 2cac0f8e77b9..66bc10c411ce 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -297,7 +297,7 @@ namespace ExtUI { float getTargetFan_percent(const fan_t fan) { #if HAS_FAN - return thermalManager.fanPercent(thermalManager.fan_speed[fan - FAN0]); + return thermalManager.fanSpeedPercent(fan - FAN0); #else UNUSED(fan); return 0; @@ -306,7 +306,7 @@ namespace ExtUI { float getActualFan_percent(const fan_t fan) { #if HAS_FAN - return thermalManager.fanPercent(thermalManager.scaledFanSpeed(fan - FAN0)); + return thermalManager.scaledFanSpeedPercent(fan - FAN0); #else UNUSED(fan); return 0; @@ -870,19 +870,19 @@ namespace ExtUI { const feedRate_t old_feedrate = feedrate_mm_s; const float x_target = MESH_MIN_X + pos.x * (MESH_X_DIST), y_target = MESH_MIN_Y + pos.y * (MESH_Y_DIST); - if (x_target != current_position[X_AXIS] || y_target != current_position[Y_AXIS]) { + if (x_target != current_position.x || y_target != current_position.y) { // If moving across bed, raise nozzle to safe height over bed feedrate_mm_s = Z_PROBE_FEEDRATE_FAST; destination = current_position; - destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; + destination.z = Z_CLEARANCE_BETWEEN_PROBES; prepare_line_to_destination(); feedrate_mm_s = XY_PROBE_FEEDRATE; - destination[X_AXIS] = x_target; - destination[Y_AXIS] = y_target; + destination.x = x_target; + destination.y = y_target; prepare_line_to_destination(); } feedrate_mm_s = Z_PROBE_FEEDRATE_FAST; - destination[Z_AXIS] = z; + destination.z = z; prepare_line_to_destination(); feedrate_mm_s = old_feedrate; #else diff --git a/Marlin/src/lcd/menu/menu_bed_corners.cpp b/Marlin/src/lcd/menu/menu_bed_corners.cpp index 8635661d013e..d28ef1182e86 100644 --- a/Marlin/src/lcd/menu/menu_bed_corners.cpp +++ b/Marlin/src/lcd/menu/menu_bed_corners.cpp @@ -102,7 +102,7 @@ static int8_t bed_corner; /** * Select next corner coordinates */ -static inline void _lcd_level_bed_corners_get_next_position() { +static void _lcd_level_bed_corners_get_next_position() { if (level_corners_3_points) { if (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner @@ -268,7 +268,7 @@ static inline void _lcd_level_bed_corners_get_next_position() { ui.goto_screen(_lcd_draw_probing); do { ui.refresh(LCDVIEW_REDRAW_NOW); - _lcd_draw_probing(); // update screen with # of good points + _lcd_draw_probing(); // update screen with # of good points do_blocking_move_to_z(SUM_TERN(BLTOUCH_HS_MODE, current_position.z + LEVEL_CORNERS_Z_HOP, 7)); // clearance _lcd_level_bed_corners_get_next_position(); // Select next corner coordinates @@ -308,7 +308,7 @@ static inline void _lcd_level_bed_corners_get_next_position() { #else // !LEVEL_CORNERS_USE_PROBE - static inline void _lcd_goto_next_corner() { + static void _lcd_goto_next_corner() { line_to_z(LEVEL_CORNERS_Z_HOP); // Select next corner coordinates @@ -321,7 +321,7 @@ static inline void _lcd_level_bed_corners_get_next_position() { #endif // !LEVEL_CORNERS_USE_PROBE -static inline void _lcd_level_bed_corners_homing() { +static void _lcd_level_bed_corners_homing() { _lcd_draw_homing(); if (!all_axes_homed()) return; #if ENABLED(LEVEL_CORNERS_USE_PROBE) diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index 7ef49f0cf85a..7ea355b795b8 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -130,6 +130,7 @@ void menu_advanced_settings(); #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) #include "../../module/motion.h" // for active_extruder + #include "../../gcode/queue.h" void menu_toolchange_migration() { PGM_P const msg_migrate = GET_TEXT(MSG_TOOL_MIGRATION_SWAP); diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 525b8c8a7045..34d1d6c6f452 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -105,8 +105,8 @@ void menu_configuration(); void _lcd_custom_menu_main_gcode(PGM_P const cmd) { queue.inject_P(cmd); - TERN_(MAIN_MENU_ITEM_SCRIPT_AUDIBLE_FEEDBACK, ui.completion_feedback()); - TERN_(MAIN_MENU_ITEM_SCRIPT_RETURN, ui.return_to_status()); + TERN_(CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK, ui.completion_feedback()); + TERN_(CUSTOM_MENU_MAIN_SCRIPT_RETURN, ui.return_to_status()); } void custom_menus_main() { diff --git a/Marlin/src/lcd/menu/menu_power_monitor.cpp b/Marlin/src/lcd/menu/menu_power_monitor.cpp index d31ebd36b27f..b43327f63bc2 100644 --- a/Marlin/src/lcd/menu/menu_power_monitor.cpp +++ b/Marlin/src/lcd/menu/menu_power_monitor.cpp @@ -42,7 +42,7 @@ void menu_power_monitor() { } #endif - #if HAS_POWER_MONITOR_VREF + #if ENABLED(POWER_MONITOR_VOLTAGE) { bool ena = power_monitor.voltage_display_enabled(); EDIT_ITEM(bool, MSG_VOLTAGE, &ena, power_monitor.toggle_voltage_display); diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 34aea73f0303..35cbba33e7c8 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -230,6 +230,50 @@ void report_current_position_projected() { stepper.report_a_position(planner.position); } +#if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) + + M_StateEnum M_State_grbl = M_INIT; + + /** + * Output the current grbl compatible state to serial while moving + */ + void report_current_grblstate_moving() { SERIAL_ECHOLNPAIR("S_XYZ:", int(M_State_grbl)); } + + /** + * Output the current position (processed) to serial while moving + */ + void report_current_position_moving() { + + get_cartesian_from_steppers(); + const xyz_pos_t lpos = cartes.asLogical(); + SERIAL_ECHOPAIR("X:", lpos.x, " Y:", lpos.y, " Z:", lpos.z, " E:", current_position.e); + + stepper.report_positions(); + #if IS_SCARA + scara_report_positions(); + #endif + + report_current_grblstate_moving(); + } + + /** + * Set a Grbl-compatible state from the current marlin_state + */ + M_StateEnum grbl_state_for_marlin_state() { + switch (marlin_state) { + case MF_INITIALIZING: return M_INIT; + case MF_SD_COMPLETE: return M_ALARM; + case MF_WAITING: return M_IDLE; + case MF_STOPPED: return M_END; + case MF_RUNNING: return M_RUNNING; + case MF_PAUSED: return M_HOLD; + case MF_KILLED: return M_ERROR; + default: return M_IDLE; + } + } + +#endif + /** * Run out the planner buffer and re-sync the current * position from the last-updated stepper positions. @@ -241,6 +285,20 @@ void quickstop_stepper() { sync_plan_position(); } +#if ENABLED(REALTIME_REPORTING_COMMANDS) + + void quickpause_stepper() { + planner.quick_pause(); + //planner.synchronize(); + } + + void quickresume_stepper() { + planner.quick_resume(); + //planner.synchronize(); + } + +#endif + /** * Set the planner/stepper positions directly from current_position with * no kinematic translation. Used for homing axes and cartesian/core syncing. @@ -367,12 +425,10 @@ void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/ planner.e_factor[active_extruder] = 1.0f; #endif - #if IS_KINEMATIC - if (is_fast) - prepare_fast_move_to_destination(); - else - #endif - prepare_line_to_destination(); + if (TERN0(IS_KINEMATIC, is_fast)) + TERN(IS_KINEMATIC, NOOP, prepare_line_to_destination()); + else + prepare_line_to_destination(); feedrate_mm_s = old_feedrate; feedrate_percentage = old_pct; @@ -382,7 +438,12 @@ void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/ } /** - * Plan a move to (X, Y, Z) and set the current_position + * Plan a move to (X, Y, Z) with separation of the XY and Z components. + * + * - If Z is moving up, the Z move is done before XY. + * - If Z is moving down, the Z move is done after XY. + * - Delta may lower Z first to get into the free motion zone. + * - Before returning, wait for the planner buffer to empty. */ void do_blocking_move_to(const float rx, const float ry, const float rz, const_feedRate_t fr_mm_s/*=0.0*/) { DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING)); @@ -391,20 +452,21 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const_f const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS), xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S); - #if ENABLED(DELTA) - + #if EITHER(DELTA, IS_SCARA) if (!position_is_reachable(rx, ry)) return; + destination = current_position; // sync destination at the start + #endif - REMEMBER(fr, feedrate_mm_s, xy_feedrate); + #if ENABLED(DELTA) - destination = current_position; // sync destination at the start + REMEMBER(fr, feedrate_mm_s, xy_feedrate); if (DEBUGGING(LEVELING)) DEBUG_POS("destination = current_position", destination); // when in the danger zone if (current_position.z > delta_clip_start_height) { - if (rz > delta_clip_start_height) { // staying in the danger zone - destination.set(rx, ry, rz); // move directly (uninterpolated) + if (rz > delta_clip_start_height) { // staying in the danger zone + destination.set(rx, ry, rz); // move directly (uninterpolated) prepare_internal_fast_move_to_destination(); // set current_position from destination if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); return; @@ -432,10 +494,6 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const_f #elif IS_SCARA - if (!position_is_reachable(rx, ry)) return; - - destination = current_position; - // If Z needs to raise, do it before moving XY if (destination.z < rz) { destination.z = rz; diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 2cfc8406a58d..647b3af52af9 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -211,14 +211,49 @@ void report_real_position(); void report_current_position(); void report_current_position_projected(); +#if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) + #define HAS_GRBL_STATE 1 + /** + * Machine states for GRBL or TinyG + */ + enum M_StateEnum : uint8_t { + M_INIT = 0, // 0 machine is initializing + M_RESET, // 1 machine is ready for use + M_ALARM, // 2 machine is in alarm state (soft shut down) + M_IDLE, // 3 program stop or no more blocks (M0, M1, M60) + M_END, // 4 program end via M2, M30 + M_RUNNING, // 5 motion is running + M_HOLD, // 6 motion is holding + M_PROBE, // 7 probe cycle active + M_CYCLING, // 8 machine is running (cycling) + M_HOMING, // 9 machine is homing + M_JOGGING, // 10 machine is jogging + M_ERROR // 11 machine is in hard alarm state (shut down) + }; + extern M_StateEnum M_State_grbl; + M_StateEnum grbl_state_for_marlin_state(); + void report_current_grblstate_moving(); + void report_current_position_moving(); + + #if ENABLED(FULL_REPORT_TO_HOST_FEATURE) + inline void set_and_report_grblstate(const M_StateEnum state) { + M_State_grbl = state; + report_current_grblstate_moving(); + } + #endif + + #if ENABLED(REALTIME_REPORTING_COMMANDS) + void quickpause_stepper(); + void quickresume_stepper(); + #endif +#endif + void get_cartesian_from_steppers(); void set_current_from_steppers_for_axis(const AxisEnum axis); void quickstop_stepper(); /** - * sync_plan_position - * * Set the planner/stepper positions directly from current_position with * no kinematic translation. Used for homing axes and cartesian/core syncing. */ diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index d6356432e75c..f11f2738676d 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -207,7 +207,7 @@ skew_factor_t Planner::skew_factor; // Initialized by settings.load() xyze_long_t Planner::position{0}; -uint32_t Planner::cutoff_long; +uint32_t Planner::acceleration_long_cutoff; xyze_float_t Planner::previous_speed; float Planner::previous_nominal_speed_sqr; @@ -1650,6 +1650,24 @@ void Planner::quick_stop() { stepper.quick_stop(); } +#if ENABLED(REALTIME_REPORTING_COMMANDS) + + void Planner::quick_pause() { + // Suspend until quick_resume is called + // Don't empty buffers or queues + const bool did_suspend = stepper.suspend(); + if (did_suspend) + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD)); + } + + // Resume if suspended + void Planner::quick_resume() { + TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(grbl_state_for_marlin_state())); + stepper.wake_up(); + } + +#endif + void Planner::endstop_triggered(const AxisEnum axis) { // Record stepper position and discard the current block stepper.endstop_triggered(axis); @@ -2271,23 +2289,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move, // Compute and limit the acceleration rate for the trapezoid generator. const float steps_per_mm = block->step_event_count * inverse_millimeters; uint32_t accel; - if (!block->steps.a && !block->steps.b && !block->steps.c) { - // convert to: acceleration steps/sec^2 - accel = CEIL(settings.retract_acceleration * steps_per_mm); - TERN_(LIN_ADVANCE, block->use_advance_lead = false); + if (!block->steps.a && !block->steps.b && !block->steps.c) { // Is this a retract / recover move? + accel = CEIL(settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2 + TERN_(LIN_ADVANCE, block->use_advance_lead = false); // No linear advance for simple retract/recover } else { #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \ if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \ - const uint32_t comp = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count; \ - if (accel * block->steps[AXIS] > comp) accel = comp / block->steps[AXIS]; \ + const uint32_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \ + NOMORE(accel, max_possible); \ } \ }while(0) #define LIMIT_ACCEL_FLOAT(AXIS,INDX) do{ \ if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \ - const float comp = (float)max_acceleration_steps_per_s2[AXIS+INDX] * (float)block->step_event_count; \ - if ((float)accel * (float)block->steps[AXIS] > comp) accel = comp / (float)block->steps[AXIS]; \ + const float max_possible = float(max_acceleration_steps_per_s2[AXIS+INDX]) * float(block->step_event_count) / float(block->steps[AXIS]); \ + NOMORE(accel, max_possible); \ } \ }while(0) @@ -2336,7 +2353,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif // Limit acceleration per axis - if (block->step_event_count <= cutoff_long) { + if (block->step_event_count <= acceleration_long_cutoff) { LIMIT_ACCEL_LONG(A_AXIS, 0); LIMIT_ACCEL_LONG(B_AXIS, 0); LIMIT_ACCEL_LONG(C_AXIS, 0); @@ -2352,7 +2369,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, block->acceleration_steps_per_s2 = accel; block->acceleration = accel / steps_per_mm; #if DISABLED(S_CURVE_ACCELERATION) - block->acceleration_rate = (uint32_t)(accel * (4096.0f * 4096.0f / (STEPPER_TIMER_RATE))); + block->acceleration_rate = (uint32_t)(accel * (sq(4096.0f) / (STEPPER_TIMER_RATE))); #endif #if ENABLED(LIN_ADVANCE) if (block->use_advance_lead) { @@ -3020,7 +3037,7 @@ void Planner::reset_acceleration_rates() { max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i]; if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); } - cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL + acceleration_long_cutoff = 4294967295UL / highest_rate; // 0xFFFFFFFFUL TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk()); } diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index d4ed00d2fa6a..30eeb758a477 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -443,7 +443,7 @@ class Planner { /** * Limit where 64bit math is necessary for acceleration calculation */ - static uint32_t cutoff_long; + static uint32_t acceleration_long_cutoff; #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) static float last_fade_z; @@ -873,6 +873,13 @@ class Planner { // a Full Shutdown is required, or when endstops are hit) static void quick_stop(); + #if ENABLED(REALTIME_REPORTING_COMMANDS) + // Force a quick pause of the machine (e.g., when a pause is required in the middle of move). + // NOTE: Hard-stops will lose steps so encoders are highly recommended if using these! + static void quick_pause(); + static void quick_resume(); + #endif + // Called when an endstop is triggered. Causes the machine to stop inmediately static void endstop_triggered(const AxisEnum axis); diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index d8272c31b66f..75aba76ef3e4 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -185,10 +185,10 @@ class Probe { ); } - static float min_x() { return _min_x() - TERN0(NOZZLE_AS_PROBE, TERN0(HAS_HOME_OFFSET, home_offset.x)); } - static float max_x() { return _max_x() - TERN0(NOZZLE_AS_PROBE, TERN0(HAS_HOME_OFFSET, home_offset.x)); } - static float min_y() { return _min_y() - TERN0(NOZZLE_AS_PROBE, TERN0(HAS_HOME_OFFSET, home_offset.y)); } - static float max_y() { return _max_y() - TERN0(NOZZLE_AS_PROBE, TERN0(HAS_HOME_OFFSET, home_offset.y)); } + static float min_x() { return _min_x() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.x)); } + static float max_x() { return _max_x() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.x)); } + static float min_y() { return _min_y() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.y)); } + static float max_y() { return _max_y() TERN_(NOZZLE_AS_PROBE, TERN_(HAS_HOME_OFFSET, - home_offset.y)); } // constexpr helpers used in build-time static_asserts, relying on default probe offsets. class build_time { diff --git a/Marlin/src/module/scara.cpp b/Marlin/src/module/scara.cpp index cc177f76c25d..e058804c904d 100644 --- a/Marlin/src/module/scara.cpp +++ b/Marlin/src/module/scara.cpp @@ -204,7 +204,7 @@ float segments_per_second = TERN(AXEL_TPARA, TPARA_SEGMENTS_PER_SECOND, SCARA_SE y = r * sin(RADIANS(a)), rho2 = L1_2 + L2_2 - 2.0f * L1 * L2 * cos(RADIANS(w)); - cartes = robot_offset + xyz_pos_t({ x, y, SQRT(rho2 - x * x - y * y) }); + cartes = robot_offset + xyz_pos_t({ x, y, SQRT(rho2 - sq(x) - sq(y)) }); } // Home YZ together, then X (or all at once). Based on quick_home_xy & home_delta diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index e2f7672a44dc..9b8730829ef3 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -315,34 +315,34 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, /** * Set the print fan speed for a target extruder */ - void Temperature::set_fan_speed(uint8_t target, uint16_t speed) { + void Temperature::set_fan_speed(uint8_t fan, uint16_t speed) { NOMORE(speed, 255U); #if ENABLED(SINGLENOZZLE_STANDBY_FAN) - if (target != active_extruder) { - if (target < EXTRUDERS) singlenozzle_fan_speed[target] = speed; + if (fan != active_extruder) { + if (fan < EXTRUDERS) singlenozzle_fan_speed[fan] = speed; return; } #endif - TERN_(SINGLENOZZLE, target = 0); // Always use fan index 0 with SINGLENOZZLE + TERN_(SINGLENOZZLE, fan = 0); // Always use fan index 0 with SINGLENOZZLE - if (target >= FAN_COUNT) return; + if (fan >= FAN_COUNT) return; - fan_speed[target] = speed; + fan_speed[fan] = speed; - TERN_(REPORT_FAN_CHANGE, report_fan_speed(target)); + TERN_(REPORT_FAN_CHANGE, report_fan_speed(fan)); } #if ENABLED(REPORT_FAN_CHANGE) /** * Report print fan speed for a target extruder */ - void Temperature::report_fan_speed(const uint8_t target) { - if (target >= FAN_COUNT) return; + void Temperature::report_fan_speed(const uint8_t fan) { + if (fan >= FAN_COUNT) return; PORT_REDIRECT(SerialMask::All); - SERIAL_ECHOLNPAIR("M106 P", target, " S", fan_speed[target]); + SERIAL_ECHOLNPAIR("M106 P", fan, " S", fan_speed[fan]); } #endif @@ -1406,6 +1406,8 @@ void Temperature::manage_heater() { fan_chamber_pwm = (CHAMBER_FAN_BASE) + (CHAMBER_FAN_FACTOR) * ABS(temp_chamber.celsius - temp_chamber.target); if (temp_chamber.soft_pwm_amount) fan_chamber_pwm += (CHAMBER_FAN_FACTOR) * 2; + #elif CHAMBER_FAN_MODE == 3 + fan_chamber_pwm = CHAMBER_FAN_BASE + _MAX((CHAMBER_FAN_FACTOR) * (temp_chamber.celsius - temp_chamber.target), 0); #endif NOMORE(fan_chamber_pwm, 225); set_fan_speed(2, fan_chamber_pwm); // TODO: instead of fan 2, set to chamber fan @@ -2208,19 +2210,19 @@ void Temperature::init() { #if HAS_HOTEND #define _TEMP_MIN_E(NR) do{ \ - const celsius_t tmin = _MAX(HEATER_##NR##_MINTEMP, TERN(TEMP_SENSOR_##NR##_IS_CUSTOM, 0, pgm_read_word(&TEMPTABLE_##NR [TEMP_SENSOR_##NR##_MINTEMP_IND].celsius))); \ + const celsius_t tmin = _MAX(HEATER_##NR##_MINTEMP, TERN(TEMP_SENSOR_##NR##_IS_CUSTOM, 0, (int)pgm_read_word(&TEMPTABLE_##NR [TEMP_SENSOR_##NR##_MINTEMP_IND].celsius))); \ temp_range[NR].mintemp = tmin; \ while (analog_to_celsius_hotend(temp_range[NR].raw_min, NR) < tmin) \ temp_range[NR].raw_min += TEMPDIR(NR) * (OVERSAMPLENR); \ }while(0) #define _TEMP_MAX_E(NR) do{ \ - const celsius_t tmax = _MIN(HEATER_##NR##_MAXTEMP, TERN(TEMP_SENSOR_##NR##_IS_CUSTOM, 2000, pgm_read_word(&TEMPTABLE_##NR [TEMP_SENSOR_##NR##_MAXTEMP_IND].celsius) - 1)); \ + const celsius_t tmax = _MIN(HEATER_##NR##_MAXTEMP, TERN(TEMP_SENSOR_##NR##_IS_CUSTOM, 2000, (int)pgm_read_word(&TEMPTABLE_##NR [TEMP_SENSOR_##NR##_MAXTEMP_IND].celsius) - 1)); \ temp_range[NR].maxtemp = tmax; \ while (analog_to_celsius_hotend(temp_range[NR].raw_max, NR) > tmax) \ temp_range[NR].raw_max -= TEMPDIR(NR) * (OVERSAMPLENR); \ }while(0) - #define _MINMAX_TEST(N,M) (HOTENDS > N && TEMP_SENSOR_ ##N## THERMISTOR_ID && TEMP_SENSOR_ ##N## THERMISTOR_ID != 998 && TEMP_SENSOR_ ##N## THERMISTOR_ID != 999 && defined(HEATER_##N##_##M##TEMP)) + #define _MINMAX_TEST(N,M) (HOTENDS > N && TEMP_SENSOR_ ##N## _THERMISTOR_ID && TEMP_SENSOR_ ##N## _THERMISTOR_ID != 998 && TEMP_SENSOR_ ##N## _THERMISTOR_ID != 999 && defined(HEATER_##N##_##M##TEMP)) #if _MINMAX_TEST(0, MIN) _TEMP_MIN_E(0); diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 13dcca293281..d2b3db874705 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -553,10 +553,10 @@ class Temperature { static uint8_t fan_speed[FAN_COUNT]; #define FANS_LOOP(I) LOOP_L_N(I, FAN_COUNT) - static void set_fan_speed(const uint8_t target, const uint16_t speed); + static void set_fan_speed(const uint8_t fan, const uint16_t speed); #if ENABLED(REPORT_FAN_CHANGE) - static void report_fan_speed(const uint8_t target); + static void report_fan_speed(const uint8_t fan); #endif #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) @@ -564,21 +564,23 @@ class Temperature { static uint8_t saved_fan_speed[FAN_COUNT]; #endif - static constexpr inline uint8_t fanPercent(const uint8_t speed) { return ui8_to_percent(speed); } - #if ENABLED(ADAPTIVE_FAN_SLOWING) static uint8_t fan_speed_scaler[FAN_COUNT]; #endif - static inline uint8_t scaledFanSpeed(const uint8_t target, const uint8_t fs) { - UNUSED(target); // Potentially unused! - return (fs * uint16_t(TERN(ADAPTIVE_FAN_SLOWING, fan_speed_scaler[target], 128))) >> 7; + static inline uint8_t scaledFanSpeed(const uint8_t fan, const uint8_t fs) { + UNUSED(fan); // Potentially unused! + return (fs * uint16_t(TERN(ADAPTIVE_FAN_SLOWING, fan_speed_scaler[fan], 128))) >> 7; } - static inline uint8_t scaledFanSpeed(const uint8_t target) { - return scaledFanSpeed(target, fan_speed[target]); + static inline uint8_t scaledFanSpeed(const uint8_t fan) { + return scaledFanSpeed(fan, fan_speed[fan]); } + static constexpr inline uint8_t pwmToPercent(const uint8_t speed) { return ui8_to_percent(speed); } + static inline uint8_t fanSpeedPercent(const uint8_t fan) { return ui8_to_percent(fan_speed[fan]); } + static inline uint8_t scaledFanSpeedPercent(const uint8_t fan) { return ui8_to_percent(scaledFanSpeed(fan)); } + #if ENABLED(EXTRA_FAN_SPEED) typedef struct { uint8_t saved, speed; } extra_fan_t; static extra_fan_t extra_fan_speed[FAN_COUNT]; @@ -629,7 +631,7 @@ class Temperature { //inline so that there is no performance decrease. //deg=degreeCelsius - FORCE_INLINE static float degHotend(const uint8_t E_NAME) { + FORCE_INLINE static celsius_t degHotend(const uint8_t E_NAME) { return TERN0(HAS_HOTEND, temp_hotend[HOTEND_INDEX].celsius); } @@ -734,7 +736,7 @@ class Temperature { #if ENABLED(SHOW_TEMP_ADC_VALUES) FORCE_INLINE static int16_t rawProbeTemp() { return temp_probe.raw; } #endif - FORCE_INLINE static float degProbe() { return temp_probe.celsius; } + FORCE_INLINE static celsius_t degProbe() { return temp_probe.celsius; } FORCE_INLINE static bool isProbeBelowTemp(const_float_t target_temp) { return temp_probe.celsius < target_temp; } FORCE_INLINE static bool isProbeAboveTemp(const_float_t target_temp) { return temp_probe.celsius > target_temp; } static bool wait_for_probe(const_float_t target_temp, bool no_wait_for_cooling=true); @@ -750,7 +752,7 @@ class Temperature { #if ENABLED(SHOW_TEMP_ADC_VALUES) FORCE_INLINE static int16_t rawChamberTemp() { return temp_chamber.raw; } #endif - FORCE_INLINE static float degChamber() { return temp_chamber.celsius; } + FORCE_INLINE static celsius_t degChamber() { return temp_chamber.celsius; } #if HAS_HEATED_CHAMBER FORCE_INLINE static celsius_t degTargetChamber() { return temp_chamber.target; } FORCE_INLINE static bool isHeatingChamber() { return temp_chamber.target > temp_chamber.celsius; } @@ -776,7 +778,7 @@ class Temperature { #if ENABLED(SHOW_TEMP_ADC_VALUES) FORCE_INLINE static int16_t rawCoolerTemp() { return temp_cooler.raw; } #endif - FORCE_INLINE static float degCooler() { return temp_cooler.celsius; } + FORCE_INLINE static celsius_t degCooler() { return temp_cooler.celsius; } #if HAS_COOLER FORCE_INLINE static celsius_t degTargetCooler() { return temp_cooler.target; } FORCE_INLINE static bool isLaserHeating() { return temp_cooler.target > temp_cooler.celsius; } diff --git a/Marlin/src/module/thermistor/thermistors.h b/Marlin/src/module/thermistor/thermistors.h index 6f5ad874cb74..e35737a76dd2 100644 --- a/Marlin/src/module/thermistor/thermistors.h +++ b/Marlin/src/module/thermistor/thermistors.h @@ -338,7 +338,8 @@ static_assert( // For thermistors the highest temperature results in the lowest ADC value // For thermocouples the highest temperature results in the highest ADC value -#define _TT_REV(N) REVERSE_TEMP_SENSOR_RANGE_##N +#define __TT_REV(N) REVERSE_TEMP_SENSOR_RANGE_##N +#define _TT_REV(N) __TT_REV(N) #define TT_REV(N) _TT_REV(TEMP_SENSOR_##N##_THERMISTOR_ID) #define _TT_REVRAW(N) !TEMP_SENSOR_##N##_IS_THERMISTOR #define TT_REVRAW(N) (TT_REV(N) || _TT_REVRAW(N)) @@ -346,72 +347,72 @@ static_assert( #ifdef TEMPTABLE_0 #if TT_REV(0) #define TEMP_SENSOR_0_MINTEMP_IND 0 - #define TEMPTABLE_0_MAXTEMP_IND HEATER_0_LEN - 1 + #define TEMP_SENSOR_0_MAXTEMP_IND TEMPTABLE_0_LEN - 1 #else - #define TEMPTABLE_0_MINTEMP_IND HEATER_0_LEN - 1 + #define TEMP_SENSOR_0_MINTEMP_IND TEMPTABLE_0_LEN - 1 #define TEMP_SENSOR_0_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_1 #if TT_REV(1) #define TEMP_SENSOR_1_MINTEMP_IND 0 - #define TEMPTABLE_1_MAXTEMP_IND HEATER_1_LEN - 1 + #define TEMP_SENSOR_1_MAXTEMP_IND TEMPTABLE_1_LEN - 1 #else - #define TEMPTABLE_1_MINTEMP_IND HEATER_1_LEN - 1 + #define TEMP_SENSOR_1_MINTEMP_IND TEMPTABLE_1_LEN - 1 #define TEMP_SENSOR_1_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_2 #if TT_REV(2) #define TEMP_SENSOR_2_MINTEMP_IND 0 - #define TEMPTABLE_2_MAXTEMP_IND HEATER_2_LEN - 1 + #define TEMP_SENSOR_2_MAXTEMP_IND TEMPTABLE_2_LEN - 1 #else - #define TEMPTABLE_2_MINTEMP_IND HEATER_2_LEN - 1 + #define TEMP_SENSOR_2_MINTEMP_IND TEMPTABLE_2_LEN - 1 #define TEMP_SENSOR_2_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_3 #if TT_REV(3) #define TEMP_SENSOR_3_MINTEMP_IND 0 - #define TEMPTABLE_3_MAXTEMP_IND HEATER_3_LEN - 1 + #define TEMP_SENSOR_3_MAXTEMP_IND TEMPTABLE_3_LEN - 1 #else - #define TEMPTABLE_3_MINTEMP_IND HEATER_3_LEN - 1 + #define TEMP_SENSOR_3_MINTEMP_IND TEMPTABLE_3_LEN - 1 #define TEMP_SENSOR_3_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_4 #if TT_REV(4) #define TEMP_SENSOR_4_MINTEMP_IND 0 - #define TEMPTABLE_4_MAXTEMP_IND HEATER_4_LEN - 1 + #define TEMP_SENSOR_4_MAXTEMP_IND TEMPTABLE_4_LEN - 1 #else - #define TEMPTABLE_4_MINTEMP_IND HEATER_4_LEN - 1 + #define TEMP_SENSOR_4_MINTEMP_IND TEMPTABLE_4_LEN - 1 #define TEMP_SENSOR_4_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_5 #if TT_REV(5) #define TEMP_SENSOR_5_MINTEMP_IND 0 - #define TEMPTABLE_5_MAXTEMP_IND HEATER_5_LEN - 1 + #define TEMP_SENSOR_5_MAXTEMP_IND TEMPTABLE_5_LEN - 1 #else - #define TEMPTABLE_5_MINTEMP_IND HEATER_5_LEN - 1 + #define TEMP_SENSOR_5_MINTEMP_IND TEMPTABLE_5_LEN - 1 #define TEMP_SENSOR_5_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_6 #if TT_REV(6) #define TEMP_SENSOR_6_MINTEMP_IND 0 - #define TEMPTABLE_6_MAXTEMP_IND HEATER_6_LEN - 1 + #define TEMP_SENSOR_6_MAXTEMP_IND TEMPTABLE_6_LEN - 1 #else - #define TEMPTABLE_6_MINTEMP_IND HEATER_6_LEN - 1 + #define TEMP_SENSOR_6_MINTEMP_IND TEMPTABLE_6_LEN - 1 #define TEMP_SENSOR_6_MAXTEMP_IND 0 #endif #endif #ifdef TEMPTABLE_7 #if TT_REV(7) #define TEMP_SENSOR_7_MINTEMP_IND 0 - #define TEMPTABLE_7_MAXTEMP_IND HEATER_7_LEN - 1 + #define TEMP_SENSOR_7_MAXTEMP_IND TEMPTABLE_7_LEN - 1 #else - #define TEMPTABLE_7_MINTEMP_IND HEATER_7_LEN - 1 + #define TEMP_SENSOR_7_MINTEMP_IND TEMPTABLE_7_LEN - 1 #define TEMP_SENSOR_7_MAXTEMP_IND 0 #endif #endif @@ -525,6 +526,7 @@ static_assert( #endif #endif +#undef __TT_REV #undef _TT_REV #undef TT_REV #undef _TT_REVRAW diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 1ed395dfe436..2b8a4341726c 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -49,10 +49,14 @@ bool toolchange_extruder_ready[EXTRUDERS]; #endif -#if ENABLED(MAGNETIC_PARKING_EXTRUDER) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0) +#if EITHER(MAGNETIC_PARKING_EXTRUDER, TOOL_SENSOR) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0) #include "../gcode/gcode.h" #endif +#if ENABLED(TOOL_SENSOR) + #include "../lcd/marlinui.h" +#endif + #if ENABLED(DUAL_X_CARRIAGE) #include "stepper.h" #endif @@ -147,11 +151,11 @@ #endif // SWITCHING_NOZZLE -inline void _line_to_current(const AxisEnum fr_axis, const float fscale=1) { +void _line_to_current(const AxisEnum fr_axis, const float fscale=1) { line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale); } -inline void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); } -inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis); } +void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.2f); } +void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); } #if ENABLED(MAGNETIC_PARKING_EXTRUDER) @@ -370,7 +374,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a DEBUG_POS("PE Tool-Change done.", current_position); parking_extruder_set_parked(false); } - else if (do_solenoid_activation) { // && nomove == true + else if (do_solenoid_activation) { // Deactivate current extruder solenoid pe_solenoid_set_pin_state(active_extruder, !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE); // Engage new extruder magnetic field @@ -384,12 +388,117 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a #if ENABLED(SWITCHING_TOOLHEAD) - inline void swt_lock(const bool locked=true) { - const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; - MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]); + // Return a bitmask of tool sensor states + inline uint8_t poll_tool_sensor_pins() { + return (0 + #if ENABLED(TOOL_SENSOR) + #if PIN_EXISTS(TOOL_SENSOR1) + | (READ(TOOL_SENSOR1_PIN) << 0) + #endif + #if PIN_EXISTS(TOOL_SENSOR2) + | (READ(TOOL_SENSOR2_PIN) << 1) + #endif + #if PIN_EXISTS(TOOL_SENSOR3) + | (READ(TOOL_SENSOR3_PIN) << 2) + #endif + #if PIN_EXISTS(TOOL_SENSOR4) + | (READ(TOOL_SENSOR4_PIN) << 3) + #endif + #if PIN_EXISTS(TOOL_SENSOR5) + | (READ(TOOL_SENSOR5_PIN) << 4) + #endif + #if PIN_EXISTS(TOOL_SENSOR6) + | (READ(TOOL_SENSOR6_PIN) << 5) + #endif + #if PIN_EXISTS(TOOL_SENSOR7) + | (READ(TOOL_SENSOR7_PIN) << 6) + #endif + #if PIN_EXISTS(TOOL_SENSOR8) + | (READ(TOOL_SENSOR8_PIN) << 7) + #endif + #endif + ); + } + + #if ENABLED(TOOL_SENSOR) + + bool tool_sensor_disabled; // = false + + uint8_t check_tool_sensor_stats(const uint8_t tool_index, const bool kill_on_error/*=false*/, const bool disable/*=false*/) { + static uint8_t sensor_tries; // = 0 + for (;;) { + if (poll_tool_sensor_pins() == _BV(tool_index)) { + sensor_tries = 0; + return tool_index; + } + else if (kill_on_error && (!tool_sensor_disabled || disable)) { + sensor_tries++; + if (sensor_tries > 10) kill(PSTR("Tool Sensor error")); + safe_delay(5); + } + else { + sensor_tries++; + if (sensor_tries > 10) return -1; + safe_delay(5); + } + } + } + + #endif + + inline void switching_toolhead_lock(const bool locked) { + #ifdef SWITCHING_TOOLHEAD_SERVO_ANGLES + const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; + MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]); + #elif PIN_EXISTS(SWT_SOLENOID) + OUT_WRITE(SWT_SOLENOID_PIN, locked); + gcode.dwell(10); + #else + #error "No toolhead locking mechanism configured." + #endif } - void swt_init() { swt_lock(); } + #include + + void swt_init() { + switching_toolhead_lock(true); + + #if ENABLED(TOOL_SENSOR) + // Init tool sensors + #if PIN_EXISTS(TOOL_SENSOR1) + SET_INPUT_PULLUP(TOOL_SENSOR1_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR2) + SET_INPUT_PULLUP(TOOL_SENSOR2_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR3) + SET_INPUT_PULLUP(TOOL_SENSOR3_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR4) + SET_INPUT_PULLUP(TOOL_SENSOR4_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR5) + SET_INPUT_PULLUP(TOOL_SENSOR5_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR6) + SET_INPUT_PULLUP(TOOL_SENSOR6_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR7) + SET_INPUT_PULLUP(TOOL_SENSOR7_PIN); + #endif + #if PIN_EXISTS(TOOL_SENSOR8) + SET_INPUT_PULLUP(TOOL_SENSOR8_PIN); + #endif + + if (check_tool_sensor_stats(0)) { + ui.set_status_P("TC error"); + switching_toolhead_lock(false); + while (check_tool_sensor_stats(0)) { /* nada */ } + switching_toolhead_lock(true); + } + ui.set_status_P("TC Success"); + #endif + } inline void switching_toolhead_tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (no_move) return; @@ -398,6 +507,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a const float placexpos = toolheadposx[active_extruder], grabxpos = toolheadposx[new_tool]; + (void)check_tool_sensor_stats(active_extruder, true); + /** * 1. Move to switch position of current toolhead * 2. Unlock tool and drop it in the dock @@ -421,13 +532,14 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a DEBUG_SYNCHRONIZE(); DEBUG_POS("Move Y SwitchPos + Security", current_position); - fast_line_to_current(Y_AXIS); + slow_line_to_current(Y_AXIS); // 2. Unlock tool and drop it in the dock + TERN_(TOOL_SENSOR, tool_sensor_disabled = true); planner.synchronize(); DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead"); - swt_lock(false); + switching_toolhead_lock(false); safe_delay(500); current_position.y = SWITCHING_TOOLHEAD_Y_POS; @@ -440,7 +552,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; DEBUG_POS("Move back Y clear", current_position); - fast_line_to_current(Y_AXIS); // move away from docked toolhead + slow_line_to_current(Y_AXIS); // move away from docked toolhead + + (void)check_tool_sensor_stats(active_extruder); // 3. Move to the new toolhead @@ -457,7 +571,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a DEBUG_SYNCHRONIZE(); DEBUG_POS("Move Y SwitchPos + Security", current_position); - fast_line_to_current(Y_AXIS); + slow_line_to_current(Y_AXIS); // 4. Grab and lock the new toolhead @@ -472,14 +586,19 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // Wait for move to finish, pause 0.2s, move servo, pause 0.5s planner.synchronize(); safe_delay(200); - swt_lock(); + + (void)check_tool_sensor_stats(new_tool, true, true); + + switching_toolhead_lock(true); safe_delay(500); current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; DEBUG_POS("Move back Y clear", current_position); - fast_line_to_current(Y_AXIS); // Move away from docked toolhead + slow_line_to_current(Y_AXIS); // Move away from docked toolhead planner.synchronize(); // Always sync the final move + (void)check_tool_sensor_stats(new_tool, true, true); + DEBUG_POS("ST Tool-Change done.", current_position); } @@ -836,9 +955,10 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a #if ENABLED(TOOLCHANGE_PARK) if (ok) { #if ENABLED(TOOLCHANGE_NO_RETURN) - do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]); + destination.set(current_position.x, current_position.y); + prepare_internal_move_to_destination(planner.settings.max_feedrate_mm_s[Z_AXIS]); #else - do_blocking_move_to(destination, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE)); + prepare_internal_move_to_destination(MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE)); #endif } #endif @@ -846,9 +966,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a // Cutting recover unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed)); - planner.synchronize(); + // Resume at the old E position current_position.e = destination.e; - sync_plan_position_e(); // Resume at the old E position + sync_plan_position_e(); } } @@ -927,13 +1047,15 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { #endif // First tool priming. To prime again, reboot the machine. - #if BOTH(TOOLCHANGE_FILAMENT_SWAP, TOOLCHANGE_FS_PRIME_FIRST_USED) + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) static bool first_tool_is_primed = false; if (new_tool == old_tool && !first_tool_is_primed && enable_first_prime) { tool_change_prime(); first_tool_is_primed = true; - toolchange_extruder_ready[old_tool] = true; // Primed and initialized + TERN_(TOOLCHANGE_FS_INIT_BEFORE_SWAP, toolchange_extruder_ready[old_tool] = true); // Primed and initialized } + #else + constexpr bool first_tool_is_primed = true; #endif if (new_tool != old_tool || TERN0(PARKING_EXTRUDER, extruder_parked)) { // PARKING_EXTRUDER may need to attach old_tool when homing @@ -969,12 +1091,10 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; } } else { - #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) - // For first new tool, change without unloading the old. 'Just prime/init the new' - if (first_tool_is_primed) - unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); - first_tool_is_primed = true; // The first new tool will be primed by toolchanging - #endif + // For first new tool, change without unloading the old. 'Just prime/init the new' + if (first_tool_is_primed) + unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); + TERN_(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_primed = true); // The first new tool will be primed by toolchanging } } #endif @@ -1052,8 +1172,11 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { move_nozzle_servo(new_tool); #endif - // Set the new active extruder - if (DISABLED(DUAL_X_CARRIAGE)) active_extruder = new_tool; + IF_DISABLED(DUAL_X_CARRIAGE, active_extruder = new_tool); // Set the new active extruder + + TERN_(TOOL_SENSOR, tool_sensor_disabled = false); + + (void)check_tool_sensor_stats(active_extruder, true); // The newly-selected extruder XYZ is actually at... DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }"); diff --git a/Marlin/src/module/tool_change.h b/Marlin/src/module/tool_change.h index b79ec676a0de..bbdc0b686278 100644 --- a/Marlin/src/module/tool_change.h +++ b/Marlin/src/module/tool_change.h @@ -79,10 +79,9 @@ #if ENABLED(PARKING_EXTRUDER) - #define PE_MAGNET_ON_STATE TERN_(PARKING_EXTRUDER_SOLENOIDS_INVERT, !)PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE - void pe_solenoid_set_pin_state(const uint8_t extruder_num, const uint8_t state); + #define PE_MAGNET_ON_STATE TERN_(PARKING_EXTRUDER_SOLENOIDS_INVERT, !)PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE inline void pe_solenoid_magnet_on(const uint8_t extruder_num) { pe_solenoid_set_pin_state(extruder_num, PE_MAGNET_ON_STATE); } inline void pe_solenoid_magnet_off(const uint8_t extruder_num) { pe_solenoid_set_pin_state(extruder_num, !PE_MAGNET_ON_STATE); } @@ -115,6 +114,12 @@ void swt_init(); #endif +#if ENABLED(TOOL_SENSOR) + uint8_t check_tool_sensor_stats(const uint8_t active_tool, const bool kill_on_error=false, const bool disable=false); +#else + inline uint8_t check_tool_sensor_stats(const uint8_t, const bool=false, const bool=false) { return 0; } +#endif + /** * Perform a tool-change, which may result in moving the * previous tool out of the way and the new tool into place. diff --git a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h index 0df8b10292f8..cbf6ca2d3c3f 100644 --- a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h +++ b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h @@ -119,6 +119,7 @@ // Misc. Functions // #define LED_PIN P1_31 +#define POWER_MONITOR_VOLTAGE_PIN P0_25_A2 // // LCD @@ -156,9 +157,8 @@ #define SD_MISO_PIN P0_17 #define SD_MOSI_PIN P0_18 #define SD_SS_PIN P0_16 + #define SD_DETECT_PIN P1_22 #elif SD_CONNECTION_IS(ONBOARD) - #undef SD_DETECT_PIN - #define SD_DETECT_PIN P0_27 #define SD_SCK_PIN P0_07 #define SD_MISO_PIN P0_08 #define SD_MOSI_PIN P0_09 diff --git a/Marlin/src/pins/samd/pins_RAMPS_144.h b/Marlin/src/pins/samd/pins_RAMPS_144.h index 7a72ef651f1d..8311ac9012a0 100644 --- a/Marlin/src/pins/samd/pins_RAMPS_144.h +++ b/Marlin/src/pins/samd/pins_RAMPS_144.h @@ -89,13 +89,6 @@ #define Z_CS_PIN 32 #endif -#define Z2_STEP_PIN 36 -#define Z2_DIR_PIN 34 -#define Z2_ENABLE_PIN 30 -#ifndef Z2_CS_PIN - #define Z2_CS_PIN 22 -#endif - #define E0_STEP_PIN 26 #define E0_DIR_PIN 28 #define E0_ENABLE_PIN 24 @@ -103,18 +96,33 @@ #define E0_CS_PIN 43 #endif +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 +#ifndef E1_CS_PIN + #define E1_CS_PIN 22 +#endif + // // Temperature Sensors // #define TEMP_0_PIN 13 -#define TEMP_BED_PIN 14 +#if TEMP_SENSOR_BED + #define TEMP_BED_PIN 14 +#else + #define TEMP_1_PIN 14 +#endif #define TEMP_CHAMBER_PIN 15 // // Heaters / Fans // #define HEATER_0_PIN 10 -#define HEATER_BED_PIN 8 +#if TEMP_SENSOR_BED + #define HEATER_BED_PIN 8 +#else + #define HEATER_1_PIN 8 +#endif #define FAN_PIN 9 #define FAN1_PIN 7 #define FAN2_PIN 12 @@ -186,9 +194,6 @@ //#define Z2_HARDWARE_SERIAL Serial1 //#define E0_HARDWARE_SERIAL Serial1 //#define E1_HARDWARE_SERIAL Serial1 - //#define E2_HARDWARE_SERIAL Serial1 - //#define E3_HARDWARE_SERIAL Serial1 - //#define E4_HARDWARE_SERIAL Serial1 // // Software serial @@ -245,42 +250,6 @@ #ifndef E1_SERIAL_RX_PIN #define E1_SERIAL_RX_PIN -1 #endif - #ifndef E2_SERIAL_TX_PIN - #define E2_SERIAL_TX_PIN -1 - #endif - #ifndef E2_SERIAL_RX_PIN - #define E2_SERIAL_RX_PIN -1 - #endif - #ifndef E3_SERIAL_TX_PIN - #define E3_SERIAL_TX_PIN -1 - #endif - #ifndef E3_SERIAL_RX_PIN - #define E3_SERIAL_RX_PIN -1 - #endif - #ifndef E4_SERIAL_TX_PIN - #define E4_SERIAL_TX_PIN -1 - #endif - #ifndef E4_SERIAL_RX_PIN - #define E4_SERIAL_RX_PIN -1 - #endif - #ifndef E5_SERIAL_TX_PIN - #define E5_SERIAL_TX_PIN -1 - #endif - #ifndef E5_SERIAL_RX_PIN - #define E5_SERIAL_RX_PIN -1 - #endif - #ifndef E6_SERIAL_TX_PIN - #define E6_SERIAL_TX_PIN -1 - #endif - #ifndef E6_SERIAL_RX_PIN - #define E6_SERIAL_RX_PIN -1 - #endif - #ifndef E7_SERIAL_TX_PIN - #define E7_SERIAL_TX_PIN -1 - #endif - #ifndef E7_SERIAL_RX_PIN - #define E7_SERIAL_RX_PIN -1 - #endif #endif ////////////////////////// diff --git a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h index 6c59f27c5efe..cae1261a81fa 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h @@ -38,17 +38,21 @@ // USB Flash Drive support #define HAS_OTG_USB_HOST_SUPPORT -#define TP // Enable to define servo and probe pins #define M5_EXTENDER // The M5 extender is attached // // Servos // -#if ENABLED(TP) - #define SERVO0_PIN PB11 -#endif +#define SERVO0_PIN PB11 // BLTOUCH +#define SOL0_PIN PC7 // Toolchanger -#define PS_ON_PIN PH6 +#if ENABLED(TOOL_SENSOR) + #define TOOL_SENSOR1_PIN PH6 + #define TOOL_SENSOR2_PIN PI4 + //#define TOOL_SENSOR3_PIN PF4 +#else + #define PS_ON_PIN PH6 +#endif // // Trinamic Stallguard pins @@ -110,7 +114,7 @@ #define Z4_STOP_PIN PF6 // M5 M3_STOP #endif -#if ENABLED(TP) && !defined(Z_MIN_PROBE_PIN) +#ifndef Z_MIN_PROBE_PIN #define Z_MIN_PROBE_PIN PH11 // Z Probe must be PH11 #endif diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 28049c7e7e39..3e714fe9fefe 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -30,7 +30,7 @@ #include "../inc/MarlinConfig.h" -#if ENABLED(SDSUPPORT) && NONE(USB_FLASH_DRIVE_SUPPORT, SDIO_SUPPORT) +#if NEED_SD2CARD_SPI /* Enable FAST CRC computations - You can trade speed for FLASH space if * needed by disabling the following define */ @@ -88,7 +88,7 @@ #endif // Send command and return error code. Return zero for OK -uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) { +uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) { // Select card chipSelect(); @@ -133,7 +133,7 @@ uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) { * \return The number of 512 byte data blocks in the card * or zero if an error occurs. */ -uint32_t Sd2Card::cardSize() { +uint32_t DiskIODriver_SPI_SD::cardSize() { csd_t csd; if (!readCSD(&csd)) return 0; if (csd.v1.csd_ver == 0) { @@ -155,12 +155,12 @@ uint32_t Sd2Card::cardSize() { } } -void Sd2Card::chipDeselect() { +void DiskIODriver_SPI_SD::chipDeselect() { extDigitalWrite(chipSelectPin_, HIGH); spiSend(0xFF); // Ensure MISO goes high impedance } -void Sd2Card::chipSelect() { +void DiskIODriver_SPI_SD::chipSelect() { spiInit(spiRate_); extDigitalWrite(chipSelectPin_, LOW); } @@ -178,7 +178,7 @@ void Sd2Card::chipSelect() { * * \return true for success, false for failure. */ -bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { +bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { if (ENABLED(SDCARD_READONLY)) return false; csd_t csd; @@ -216,7 +216,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { * \return true if single block erase is supported. * false if single block erase is not supported. */ -bool Sd2Card::eraseSingleBlockEnable() { +bool DiskIODriver_SPI_SD::eraseSingleBlockEnable() { csd_t csd; return readCSD(&csd) ? csd.v1.erase_blk_en : false; } @@ -230,7 +230,7 @@ bool Sd2Card::eraseSingleBlockEnable() { * \return true for success, false for failure. * The reason for failure can be determined by calling errorCode() and errorData(). */ -bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { +bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPin) { #if IS_TEENSY_35_36 || IS_TEENSY_40_41 chipSelectPin_ = BUILTIN_SDCARD; const uint8_t ret = SDHC_CardInit(); @@ -324,10 +324,12 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { } chipDeselect(); + ready = true; return setSckRate(sckRateID); FAIL: chipDeselect(); + ready = false; return false; } @@ -338,7 +340,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) { * \param[out] dst Pointer to the location that will receive the data. * \return true for success, false for failure. */ -bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) { +bool DiskIODriver_SPI_SD::readBlock(uint32_t blockNumber, uint8_t *dst) { #if IS_TEENSY_35_36 || IS_TEENSY_40_41 return 0 == SDHC_CardReadBlock(dst, blockNumber); #endif @@ -378,7 +380,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) { * * \return true for success, false for failure. */ -bool Sd2Card::readData(uint8_t *dst) { +bool DiskIODriver_SPI_SD::readData(uint8_t *dst) { chipSelect(); return readData(dst, 512); } @@ -445,7 +447,7 @@ bool Sd2Card::readData(uint8_t *dst) { #endif #endif // SD_CHECK_AND_RETRY -bool Sd2Card::readData(uint8_t *dst, const uint16_t count) { +bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { bool success = false; const millis_t read_timeout = millis() + SD_READ_TIMEOUT; @@ -477,7 +479,7 @@ bool Sd2Card::readData(uint8_t *dst, const uint16_t count) { } /** read CID or CSR register */ -bool Sd2Card::readRegister(const uint8_t cmd, void *buf) { +bool DiskIODriver_SPI_SD::readRegister(const uint8_t cmd, void *buf) { uint8_t *dst = reinterpret_cast(buf); if (cardCommand(cmd, 0)) { error(SD_CARD_ERROR_READ_REG); @@ -497,7 +499,7 @@ bool Sd2Card::readRegister(const uint8_t cmd, void *buf) { * * \return true for success, false for failure. */ -bool Sd2Card::readStart(uint32_t blockNumber) { +bool DiskIODriver_SPI_SD::readStart(uint32_t blockNumber) { if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; const bool success = !cardCommand(CMD18, blockNumber); @@ -511,7 +513,7 @@ bool Sd2Card::readStart(uint32_t blockNumber) { * * \return true for success, false for failure. */ -bool Sd2Card::readStop() { +bool DiskIODriver_SPI_SD::readStop() { chipSelect(); const bool success = !cardCommand(CMD12, 0); if (!success) error(SD_CARD_ERROR_CMD12); @@ -531,7 +533,7 @@ bool Sd2Card::readStop() { * \return The value one, true, is returned for success and the value zero, * false, is returned for an invalid value of \a sckRateID. */ -bool Sd2Card::setSckRate(const uint8_t sckRateID) { +bool DiskIODriver_SPI_SD::setSckRate(const uint8_t sckRateID) { const bool success = (sckRateID <= 6); if (success) spiRate_ = sckRateID; else error(SD_CARD_ERROR_SCK_RATE); return success; @@ -542,12 +544,14 @@ bool Sd2Card::setSckRate(const uint8_t sckRateID) { * \param[in] timeout_ms Timeout to abort. * \return true for success, false for timeout. */ -bool Sd2Card::waitNotBusy(const millis_t timeout_ms) { +bool DiskIODriver_SPI_SD::waitNotBusy(const millis_t timeout_ms) { const millis_t wait_timeout = millis() + timeout_ms; while (spiRec() != 0xFF) if (ELAPSED(millis(), wait_timeout)) return false; return true; } +void DiskIODriver_SPI_SD::error(const uint8_t code) { errorCode_ = code; } + /** * Write a 512 byte block to an SD card. * @@ -555,7 +559,7 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) { * \param[in] src Pointer to the location of the data to be written. * \return true for success, false for failure. */ -bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) { +bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { if (ENABLED(SDCARD_READONLY)) return false; #if IS_TEENSY_35_36 || IS_TEENSY_40_41 @@ -586,7 +590,7 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) { * \param[in] src Pointer to the location of the data to be written. * \return true for success, false for failure. */ -bool Sd2Card::writeData(const uint8_t *src) { +bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) { if (ENABLED(SDCARD_READONLY)) return false; bool success = true; @@ -601,7 +605,7 @@ bool Sd2Card::writeData(const uint8_t *src) { } // Send one block of data for write block or write multiple blocks -bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) { +bool DiskIODriver_SPI_SD::writeData(const uint8_t token, const uint8_t *src) { if (ENABLED(SDCARD_READONLY)) return false; const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF); @@ -629,7 +633,7 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) { * * \return true for success, false for failure. */ -bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) { +bool DiskIODriver_SPI_SD::writeStart(uint32_t blockNumber, const uint32_t eraseCount) { if (ENABLED(SDCARD_READONLY)) return false; bool success = false; @@ -650,7 +654,7 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) { * * \return true for success, false for failure. */ -bool Sd2Card::writeStop() { +bool DiskIODriver_SPI_SD::writeStop() { if (ENABLED(SDCARD_READONLY)) return false; bool success = false; @@ -666,4 +670,4 @@ bool Sd2Card::writeStop() { return success; } -#endif // SDSUPPORT +#endif // NEED_SD2CARD_SPI diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h index eb7f9bb2cac1..e0dce02a0236 100644 --- a/Marlin/src/sd/Sd2Card.h +++ b/Marlin/src/sd/Sd2Card.h @@ -35,47 +35,50 @@ #include "SdFatConfig.h" #include "SdInfo.h" +#include "disk_io_driver.h" #include -uint16_t const SD_INIT_TIMEOUT = 2000, // init timeout ms - SD_ERASE_TIMEOUT = 10000, // erase timeout ms - SD_READ_TIMEOUT = 300, // read timeout ms - SD_WRITE_TIMEOUT = 600; // write time out ms +uint16_t const SD_INIT_TIMEOUT = 2000, // (ms) Init timeout + SD_ERASE_TIMEOUT = 10000, // (ms) Erase timeout + SD_READ_TIMEOUT = 300, // (ms) Read timeout + SD_WRITE_TIMEOUT = 600; // (ms) Write timeout // SD card errors -uint8_t const SD_CARD_ERROR_CMD0 = 0x01, // timeout error for command CMD0 (initialize card in SPI mode) - SD_CARD_ERROR_CMD8 = 0x02, // CMD8 was not accepted - not a valid SD card - SD_CARD_ERROR_CMD12 = 0x03, // card returned an error response for CMD12 (write stop) - SD_CARD_ERROR_CMD17 = 0x04, // card returned an error response for CMD17 (read block) - SD_CARD_ERROR_CMD18 = 0x05, // card returned an error response for CMD18 (read multiple block) - SD_CARD_ERROR_CMD24 = 0x06, // card returned an error response for CMD24 (write block) - SD_CARD_ERROR_CMD25 = 0x07, // WRITE_MULTIPLE_BLOCKS command failed - SD_CARD_ERROR_CMD58 = 0x08, // card returned an error response for CMD58 (read OCR) - SD_CARD_ERROR_ACMD23 = 0x09, // SET_WR_BLK_ERASE_COUNT failed - SD_CARD_ERROR_ACMD41 = 0x0A, // ACMD41 initialization process timeout - SD_CARD_ERROR_BAD_CSD = 0x0B, // card returned a bad CSR version field - SD_CARD_ERROR_ERASE = 0x0C, // erase block group command failed - SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D, // card not capable of single block erase - SD_CARD_ERROR_ERASE_TIMEOUT = 0x0E, // Erase sequence timed out - SD_CARD_ERROR_READ = 0x0F, // card returned an error token instead of read data - SD_CARD_ERROR_READ_REG = 0x10, // read CID or CSD failed - SD_CARD_ERROR_READ_TIMEOUT = 0x11, // timeout while waiting for start of read data - SD_CARD_ERROR_STOP_TRAN = 0x12, // card did not accept STOP_TRAN_TOKEN - SD_CARD_ERROR_WRITE = 0x13, // card returned an error token as a response to a write operation - SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero - SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // card did not go ready for a multiple block write - SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // card returned an error to a CMD13 status check after a write - SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // timeout occurred during write programming - SD_CARD_ERROR_SCK_RATE = 0x18, // incorrect rate selected - SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // init() not called - // 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF) - SD_CARD_ERROR_READ_CRC = 0x1B; // invalid read CRC +typedef enum : uint8_t { + SD_CARD_ERROR_CMD0 = 0x01, // Timeout error for command CMD0 (initialize card in SPI mode) + SD_CARD_ERROR_CMD8 = 0x02, // CMD8 was not accepted - not a valid SD card + SD_CARD_ERROR_CMD12 = 0x03, // Card returned an error response for CMD12 (write stop) + SD_CARD_ERROR_CMD17 = 0x04, // Card returned an error response for CMD17 (read block) + SD_CARD_ERROR_CMD18 = 0x05, // Card returned an error response for CMD18 (read multiple block) + SD_CARD_ERROR_CMD24 = 0x06, // Card returned an error response for CMD24 (write block) + SD_CARD_ERROR_CMD25 = 0x07, // WRITE_MULTIPLE_BLOCKS command failed + SD_CARD_ERROR_CMD58 = 0x08, // Card returned an error response for CMD58 (read OCR) + SD_CARD_ERROR_ACMD23 = 0x09, // SET_WR_BLK_ERASE_COUNT failed + SD_CARD_ERROR_ACMD41 = 0x0A, // ACMD41 initialization process timeout + SD_CARD_ERROR_BAD_CSD = 0x0B, // Card returned a bad CSR version field + SD_CARD_ERROR_ERASE = 0x0C, // Erase block group command failed + SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D, // Card not capable of single block erase + SD_CARD_ERROR_ERASE_TIMEOUT = 0x0E, // Erase sequence timed out + SD_CARD_ERROR_READ = 0x0F, // Card returned an error token instead of read data + SD_CARD_ERROR_READ_REG = 0x10, // Read CID or CSD failed + SD_CARD_ERROR_READ_TIMEOUT = 0x11, // Timeout while waiting for start of read data + SD_CARD_ERROR_STOP_TRAN = 0x12, // Card did not accept STOP_TRAN_TOKEN + SD_CARD_ERROR_WRITE = 0x13, // Card returned an error token as a response to a write operation + SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero + SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // Card did not go ready for a multiple block write + SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // Card returned an error to a CMD13 status check after a write + SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // Timeout occurred during write programming + SD_CARD_ERROR_SCK_RATE = 0x18, // Incorrect rate selected + SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // Init() not called + // 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF) + SD_CARD_ERROR_READ_CRC = 0x1B // Invalid read CRC +} sd_error_code_t; // card types -uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card - SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card - SD_CARD_TYPE_SDHC = 3; // High Capacity SD card +uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card + SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card + SD_CARD_TYPE_SDHC = 3; // High Capacity SD card /** * Define SOFTWARE_SPI to use bit-bang SPI @@ -93,12 +96,11 @@ uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 * \class Sd2Card * \brief Raw access to SD and SDHC flash memory cards. */ -class Sd2Card { +class DiskIODriver_SPI_SD : public DiskIODriver { public: - Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + DiskIODriver_SPI_SD() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} - uint32_t cardSize(); bool erase(uint32_t firstBlock, uint32_t lastBlock); bool eraseSingleBlockEnable(); @@ -106,7 +108,7 @@ class Sd2Card { * Set SD error code. * \param[in] code value for error code. */ - inline void error(const uint8_t code) { errorCode_ = code; } + void error(const uint8_t code); /** * \return error code for last error. See Sd2Card.h for a list of error codes. @@ -122,9 +124,15 @@ class Sd2Card { * * \return true for success or false for failure. */ - bool init(const uint8_t sckRateID, const pin_t chipSelectPin); + bool init(const uint8_t sckRateID, const pin_t chipSelectPin) override; - bool readBlock(uint32_t block, uint8_t *dst); + bool setSckRate(const uint8_t sckRateID); + + /** + * Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const { return type_; } /** * Read a card's CID register. The CID contains card identification @@ -145,24 +153,27 @@ class Sd2Card { * * \return true for success or false for failure. */ - inline bool readCSD(csd_t *csd) { return readRegister(CMD9, csd); } + inline bool readCSD(csd_t *csd) override { return readRegister(CMD9, csd); } - bool readData(uint8_t *dst); - bool readStart(uint32_t blockNumber); - bool readStop(); - bool setSckRate(const uint8_t sckRateID); + bool readData(uint8_t *dst) override; + bool readStart(uint32_t blockNumber) override; + bool readStop() override; - /** - * Return the card type: SD V1, SD V2 or SDHC - * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. - */ - int type() const {return type_;} - bool writeBlock(uint32_t blockNumber, const uint8_t *src); - bool writeData(const uint8_t *src); - bool writeStart(uint32_t blockNumber, const uint32_t eraseCount); - bool writeStop(); + bool writeData(const uint8_t *src) override; + bool writeStart(const uint32_t blockNumber, const uint32_t eraseCount) override; + bool writeStop() override; + + bool readBlock(uint32_t block, uint8_t *dst) override; + bool writeBlock(uint32_t blockNumber, const uint8_t *src) override; + + uint32_t cardSize() override; + + bool isReady() override { return ready; }; + + void idle() override {} private: + bool ready = false; uint8_t chipSelectPin_, errorCode_, spiRate_, diff --git a/Marlin/src/sd/Sd2Card_sdio.h b/Marlin/src/sd/Sd2Card_sdio.h index 10fb757359f4..158034480597 100644 --- a/Marlin/src/sd/Sd2Card_sdio.h +++ b/Marlin/src/sd/Sd2Card_sdio.h @@ -23,17 +23,33 @@ #include "../inc/MarlinConfig.h" -#if ENABLED(SDIO_SUPPORT) +#include "SdInfo.h" +#include "disk_io_driver.h" bool SDIO_Init(); bool SDIO_ReadBlock(uint32_t block, uint8_t *dst); bool SDIO_WriteBlock(uint32_t block, const uint8_t *src); -class Sd2Card { +class DiskIODriver_SDIO : public DiskIODriver { public: - bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = 0) { return SDIO_Init(); } - bool readBlock(uint32_t block, uint8_t *dst) { return SDIO_ReadBlock(block, dst); } - bool writeBlock(uint32_t block, const uint8_t *src) { return SDIO_WriteBlock(block, src); } -}; + bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=0) override { return SDIO_Init(); } + + bool readCSD(csd_t *csd) override { return false; } + + bool readStart(const uint32_t block) override { return false; } + bool readData(uint8_t *dst) override { return false; } + bool readStop() override { return false; } + + bool writeStart(const uint32_t block, const uint32_t) override { return false; } + bool writeData(const uint8_t *src) override { return false; } + bool writeStop() override { return false; } -#endif // SDIO_SUPPORT + bool readBlock(uint32_t block, uint8_t *dst) override { return SDIO_ReadBlock(block, dst); } + bool writeBlock(uint32_t block, const uint8_t *src) override { return SDIO_WriteBlock(block, src); } + + uint32_t cardSize() override { return 0; } + + bool isReady() override { return true; } + + void idle() override {} +}; diff --git a/Marlin/src/sd/SdFatConfig.h b/Marlin/src/sd/SdFatConfig.h index 13ac3a748785..dfba64129526 100644 --- a/Marlin/src/sd/SdFatConfig.h +++ b/Marlin/src/sd/SdFatConfig.h @@ -39,7 +39,7 @@ * * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. */ -#define USE_MULTIPLE_CARDS 0 +#define USE_MULTIPLE_CARDS 0 //TODO? ENABLED(MULTI_VOLUME) /** * Call flush for endl if ENDL_CALLS_FLUSH is nonzero diff --git a/Marlin/src/sd/SdVolume.cpp b/Marlin/src/sd/SdVolume.cpp index 7fcebd640d24..1b1fdc5a7c1e 100644 --- a/Marlin/src/sd/SdVolume.cpp +++ b/Marlin/src/sd/SdVolume.cpp @@ -41,10 +41,10 @@ // raw block cache uint32_t SdVolume::cacheBlockNumber_; // current block number cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card - Sd2Card* SdVolume::sdCard_; // pointer to SD card object + DiskIODriver *SdVolume::sdCard_; // pointer to SD card object bool SdVolume::cacheDirty_; // cacheFlush() will write block if true uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT -#endif // USE_MULTIPLE_CARDS +#endif // find a contiguous group of clusters bool SdVolume::allocContiguous(uint32_t count, uint32_t *curCluster) { @@ -326,7 +326,7 @@ int32_t SdVolume::freeClusterCount() { * Reasons for failure include not finding a valid partition, not finding a valid * FAT file system in the specified partition or an I/O error. */ -bool SdVolume::init(Sd2Card* dev, uint8_t part) { +bool SdVolume::init(DiskIODriver* dev, uint8_t part) { uint32_t totalBlocks, volumeStartBlock = 0; fat32_boot_t *fbs; diff --git a/Marlin/src/sd/SdVolume.h b/Marlin/src/sd/SdVolume.h index c2eaf0bd1387..b8e70ca9d7f5 100644 --- a/Marlin/src/sd/SdVolume.h +++ b/Marlin/src/sd/SdVolume.h @@ -36,9 +36,11 @@ #if ENABLED(USB_FLASH_DRIVE_SUPPORT) #include "usb_flashdrive/Sd2Card_FlashDrive.h" -#elif ENABLED(SDIO_SUPPORT) +#endif + +#if NEED_SD2CARD_SDIO #include "Sd2Card_sdio.h" -#else +#elif NEED_SD2CARD_SPI #include "Sd2Card.h" #endif @@ -47,6 +49,7 @@ //============================================================================== // SdVolume class + /** * \brief Cache for an SD data block */ @@ -84,14 +87,14 @@ class SdVolume { * Initialize a FAT volume. Try partition one first then try super * floppy format. * - * \param[in] dev The Sd2Card where the volume is located. + * \param[in] dev The DiskIODriver where the volume is located. * * \return true for success, false for failure. * Reasons for failure include not finding a valid partition, not finding * a valid FAT file system or an I/O error. */ - bool init(Sd2Card *dev) { return init(dev, 1) ? true : init(dev, 0); } - bool init(Sd2Card *dev, uint8_t part); + bool init(DiskIODriver *dev) { return init(dev, 1) || init(dev, 0); } + bool init(DiskIODriver *dev, uint8_t part); // inline functions that return volume info uint8_t blocksPerCluster() const { return blocksPerCluster_; } //> \return The volume's cluster size in blocks. @@ -112,10 +115,10 @@ class SdVolume { uint32_t rootDirStart() const { return rootDirStart_; } /** - * Sd2Card object for this volume - * \return pointer to Sd2Card object. + * DiskIODriver object for this volume + * \return pointer to DiskIODriver object. */ - Sd2Card* sdCard() { return sdCard_; } + DiskIODriver* sdCard() { return sdCard_; } /** * Debug access to FAT table @@ -138,13 +141,13 @@ class SdVolume { #if USE_MULTIPLE_CARDS cache_t cacheBuffer_; // 512 byte cache for device blocks uint32_t cacheBlockNumber_; // Logical number of block in the cache - Sd2Card *sdCard_; // Sd2Card object for cache + DiskIODriver *sdCard_; // DiskIODriver object for cache bool cacheDirty_; // cacheFlush() will write block if true uint32_t cacheMirrorBlock_; // block number for mirror FAT #else static cache_t cacheBuffer_; // 512 byte cache for device blocks static uint32_t cacheBlockNumber_; // Logical number of block in the cache - static Sd2Card *sdCard_; // Sd2Card object for cache + static DiskIODriver *sdCard_; // DiskIODriver object for cache static bool cacheDirty_; // cacheFlush() will write block if true static uint32_t cacheMirrorBlock_; // block number for mirror FAT #endif diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index f0797d653811..a54884bec127 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -120,7 +120,16 @@ uint8_t CardReader::workDirDepth; #endif // SDCARD_SORT_ALPHA -Sd2Card CardReader::sd2card; +#if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT) + DiskIODriver_USBFlash CardReader::media_usbFlashDrive; +#endif +#if NEED_SD2CARD_SDIO + DiskIODriver_SDIO CardReader::media_sdio; +#elif NEED_SD2CARD_SPI + DiskIODriver_SPI_SD CardReader::media_sd_spi; +#endif + +DiskIODriver* CardReader::driver = nullptr; SdVolume CardReader::volume; SdFile CardReader::file; @@ -133,6 +142,16 @@ SdFile CardReader::file; uint32_t CardReader::filesize, CardReader::sdpos; CardReader::CardReader() { + changeMedia(& + #if SHARED_VOLUME_IS(SD_ONBOARD) + media_sd_spi + #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT) + media_usbFlashDrive + #else + TERN(SDIO_SUPPORT, media_sdio, media_sd_spi) + #endif + ); + #if ENABLED(SDCARD_SORT_ALPHA) sort_count = 0; #if ENABLED(SDSORT_GCODE) @@ -383,12 +402,12 @@ void CardReader::mount() { flag.mounted = false; if (root.isOpen()) root.close(); - if (!sd2card.init(SD_SPI_SPEED, SDSS) + if (!driver->init(SD_SPI_SPEED, SDSS) #if defined(LCD_SDSS) && (LCD_SDSS != SDSS) - && !sd2card.init(SD_SPI_SPEED, LCD_SDSS) + && !driver->init(SD_SPI_SPEED, LCD_SDSS) #endif ) SERIAL_ECHO_MSG(STR_SD_INIT_FAIL); - else if (!volume.init(&sd2card)) + else if (!volume.init(driver)) SERIAL_ERROR_MSG(STR_SD_VOL_INIT_FAIL); else if (!root.openRoot(&volume)) SERIAL_ERROR_MSG(STR_SD_OPENROOT_FAIL); @@ -565,7 +584,7 @@ void announceOpen(const uint8_t doing, const char * const path) { // - 1 : (no file open) Opening a macro (M98). // - 2 : Resuming from a sub-procedure // -void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0*/) { +void CardReader::openFileRead(const char * const path, const uint8_t subcall_type/*=0*/) { if (!isMounted()) return; switch (subcall_type) { diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 482fb1c5ccff..5fdd1222aea4 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -42,6 +42,29 @@ extern const char M23_STR[], M24_STR[]; #define MAXPATHNAMELENGTH (1 + (MAXDIRNAMELENGTH + 1) * (MAX_DIR_DEPTH) + 1 + FILENAME_LENGTH) // "/" + N * ("ADIRNAME/") + "filename.ext" #include "SdFile.h" +#include "disk_io_driver.h" + +#if ENABLED(USB_FLASH_DRIVE_SUPPORT) + #include "usb_flashdrive/Sd2Card_FlashDrive.h" +#endif + +#if NEED_SD2CARD_SDIO + #include "Sd2Card_sdio.h" +#elif NEED_SD2CARD_SPI + #include "Sd2Card.h" +#endif + +#if ENABLED(MULTI_VOLUME) + #define SV_SD_ONBOARD 1 + #define SV_USB_FLASH_DRIVE 2 + #define _VOLUME_ID(N) _CAT(SV_, N) + #define SHARED_VOLUME_IS(N) (DEFAULT_SHARED_VOLUME == _VOLUME_ID(N)) + #if !SHARED_VOLUME_IS(SD_ONBOARD) && !SHARED_VOLUME_IS(USB_FLASH_DRIVE) + #error "DEFAULT_SHARED_VOLUME must be either SD_ONBOARD or USB_FLASH_DRIVE." + #endif +#else + #define SHARED_VOLUME_IS(...) 0 +#endif typedef struct { bool saving:1, @@ -80,6 +103,8 @@ class CardReader { CardReader(); + static void changeMedia(DiskIODriver *_driver) { driver = _driver; } + static SdFile getroot() { return root; } static void mount(); @@ -102,7 +127,7 @@ class CardReader { #endif // Basic file ops - static void openFileRead(char * const path, const uint8_t subcall=0); + static void openFileRead(const char * const path, const uint8_t subcall=0); static void openFileWrite(const char * const path); static void closefile(const bool store_location=false); static bool fileExists(const char * const name); @@ -171,7 +196,8 @@ class CardReader { static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; } static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; } - static Sd2Card& getSd2Card() { return sd2card; } + // TODO: rename to diskIODriver() + static DiskIODriver* diskIODriver() { return driver; } #if ENABLED(AUTO_REPORT_SD_STATUS) // @@ -181,6 +207,15 @@ class CardReader { static AutoReporter auto_reporter; #endif + #if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT) + static DiskIODriver_USBFlash media_usbFlashDrive; + #endif + #if NEED_SD2CARD_SDIO + static DiskIODriver_SDIO media_sdio; + #elif NEED_SD2CARD_SPI + static DiskIODriver_SPI_SD media_sd_spi; + #endif + private: // // Working directory and parents @@ -236,7 +271,7 @@ class CardReader { #if ENABLED(SDSORT_DYNAMIC_RAM) static uint8_t *isDir; #elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK) - static uint8_t isDir[(SDSORT_LIMIT+7)>>3]; + static uint8_t isDir[(SDSORT_LIMIT + 7) >> 3]; #endif #endif @@ -244,7 +279,7 @@ class CardReader { #endif // SDCARD_SORT_ALPHA - static Sd2Card sd2card; + static DiskIODriver *driver; static SdVolume volume; static SdFile file; @@ -275,7 +310,7 @@ class CardReader { }; #if ENABLED(USB_FLASH_DRIVE_SUPPORT) - #define IS_SD_INSERTED() Sd2Card::isInserted() + #define IS_SD_INSERTED() DiskIODriver_USBFlash::isInserted() #elif PIN_EXISTS(SD_DETECT) #define IS_SD_INSERTED() (READ(SD_DETECT_PIN) == SD_DETECT_STATE) #else diff --git a/Marlin/src/sd/disk_io_driver.h b/Marlin/src/sd/disk_io_driver.h new file mode 100644 index 000000000000..73c12efcfab0 --- /dev/null +++ b/Marlin/src/sd/disk_io_driver.h @@ -0,0 +1,67 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program 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. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +/** + * DiskIO Interace + * + * Interface for low level disk io + */ +class DiskIODriver { +public: + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + * + * \return true for success or false for failure. + */ + virtual bool init(const uint8_t sckRateID, const pin_t chipSelectPin) = 0; //TODO: only for SPI + + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + virtual bool readCSD(csd_t* csd) = 0; + + virtual bool readStart(const uint32_t block) = 0; + virtual bool readData(uint8_t* dst) = 0; + virtual bool readStop() = 0; + + virtual bool writeStart(const uint32_t block, const uint32_t) = 0; + virtual bool writeData(const uint8_t* src) = 0; + virtual bool writeStop() = 0; + + virtual bool readBlock(uint32_t block, uint8_t* dst) = 0; + virtual bool writeBlock(uint32_t blockNumber, const uint8_t* src) = 0; + + virtual uint32_t cardSize() = 0; + + virtual bool isReady() = 0; + + virtual void idle() = 0; +}; diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp index dc9efcb672e0..19754184154e 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp @@ -121,7 +121,7 @@ static enum { uint32_t lun0_capacity; #endif -bool Sd2Card::usbStartup() { +bool DiskIODriver_USBFlash::usbStartup() { if (state <= DO_STARTUP) { SERIAL_ECHOPGM("Starting USB host..."); if (!UHS_START) { @@ -147,7 +147,7 @@ bool Sd2Card::usbStartup() { // the USB library to monitor for such events. This function also takes care // of initializing the USB library for the first time. -void Sd2Card::idle() { +void DiskIODriver_USBFlash::idle() { usb.Task(); const uint8_t task_state = usb.getUsbTaskState(); @@ -258,16 +258,16 @@ void Sd2Card::idle() { // Marlin calls this function to check whether an USB drive is inserted. // This is equivalent to polling the SD_DETECT when using SD cards. -bool Sd2Card::isInserted() { +bool DiskIODriver_USBFlash::isInserted() { return state == MEDIA_READY; } -bool Sd2Card::isReady() { - return state > DO_STARTUP; +bool DiskIODriver_USBFlash::isReady() { + return state > DO_STARTUP && usb.getUsbTaskState() == UHS_STATE(RUNNING); } // Marlin calls this to initialize an SD card once it is inserted. -bool Sd2Card::init(const uint8_t, const pin_t) { +bool DiskIODriver_USBFlash::init(const uint8_t, const pin_t) { if (!isInserted()) return false; #if USB_DEBUG >= 1 @@ -286,7 +286,7 @@ bool Sd2Card::init(const uint8_t, const pin_t) { } // Returns the capacity of the card in blocks. -uint32_t Sd2Card::cardSize() { +uint32_t DiskIODriver_USBFlash::cardSize() { if (!isInserted()) return false; #if USB_DEBUG < 3 const uint32_t @@ -295,7 +295,7 @@ uint32_t Sd2Card::cardSize() { return lun0_capacity; } -bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) { +bool DiskIODriver_USBFlash::readBlock(uint32_t block, uint8_t *dst) { if (!isInserted()) return false; #if USB_DEBUG >= 3 if (block >= lun0_capacity) { @@ -309,7 +309,7 @@ bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) { return bulk.Read(0, block, 512, 1, dst) == 0; } -bool Sd2Card::writeBlock(uint32_t block, const uint8_t *src) { +bool DiskIODriver_USBFlash::writeBlock(uint32_t block, const uint8_t *src) { if (!isInserted()) return false; #if USB_DEBUG >= 3 if (block >= lun0_capacity) { diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h index 320678d091cd..3390bc51becc 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h @@ -27,6 +27,7 @@ */ #include "../SdFatConfig.h" #include "../SdInfo.h" +#include "../disk_io_driver.h" #if DISABLED(USE_OTG_USB_HOST) /** @@ -46,7 +47,7 @@ #endif #endif -class Sd2Card { +class DiskIODriver_USBFlash : public DiskIODriver { private: uint32_t pos; @@ -54,25 +55,26 @@ class Sd2Card { public: static bool usbStartup(); + static bool isInserted(); - bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN)); + bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN)) override; - static void idle(); + inline bool readCSD(csd_t*) override { return true; } - inline bool readStart(const uint32_t block) { pos = block; return isReady(); } - inline bool readData(uint8_t *dst) { return readBlock(pos++, dst); } - inline bool readStop() const { return true; } + inline bool readStart(const uint32_t block) override { pos = block; return isReady(); } + inline bool readData(uint8_t *dst) override { return readBlock(pos++, dst); } + inline bool readStop() override { return true; } - inline bool writeStart(const uint32_t block, const uint32_t) { pos = block; return isReady(); } - inline bool writeData(uint8_t *src) { return writeBlock(pos++, src); } - inline bool writeStop() const { return true; } + inline bool writeStart(const uint32_t block, const uint32_t) override { pos = block; return isReady(); } + inline bool writeData(const uint8_t *src) override { return writeBlock(pos++, src); } + inline bool writeStop() override { return true; } - bool readBlock(uint32_t block, uint8_t *dst); - bool writeBlock(uint32_t blockNumber, const uint8_t *src); + bool readBlock(uint32_t block, uint8_t *dst) override; + bool writeBlock(uint32_t blockNumber, const uint8_t *src) override; - bool readCSD(csd_t*) { return true; } + uint32_t cardSize() override; - uint32_t cardSize(); - static bool isInserted(); - bool isReady(); + bool isReady() override; + + void idle() override; }; diff --git a/buildroot/share/PlatformIO/scripts/common-cxxflags.py b/buildroot/share/PlatformIO/scripts/common-cxxflags.py index 856a246fba76..02cf124942e3 100644 --- a/buildroot/share/PlatformIO/scripts/common-cxxflags.py +++ b/buildroot/share/PlatformIO/scripts/common-cxxflags.py @@ -3,6 +3,12 @@ # Convenience script to apply customizations to CPP flags # Import("env") + +# Detect that 'vscode init' is running +from SCons.Script import COMMAND_LINE_TARGETS +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + env.Append(CXXFLAGS=[ "-Wno-register" #"-Wno-incompatible-pointer-types", diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies-post.py b/buildroot/share/PlatformIO/scripts/common-dependencies-post.py index 2b1b948119f0..fa095f704cac 100644 --- a/buildroot/share/PlatformIO/scripts/common-dependencies-post.py +++ b/buildroot/share/PlatformIO/scripts/common-dependencies-post.py @@ -2,8 +2,13 @@ # common-dependencies-post.py # Convenience script to add build flags for Marlin Enabled Features # - Import("env") + +# Detect that 'vscode init' is running +from SCons.Script import COMMAND_LINE_TARGETS +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + Import("projenv") def apply_board_build_flags(): diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies.py b/buildroot/share/PlatformIO/scripts/common-dependencies.py index fe6ae7dba5dd..5b17c3586f86 100644 --- a/buildroot/share/PlatformIO/scripts/common-dependencies.py +++ b/buildroot/share/PlatformIO/scripts/common-dependencies.py @@ -2,6 +2,15 @@ # common-dependencies.py # Convenience script to check dependencies and add libs and sources for Marlin Enabled Features # +Import("env") + +#print(env.Dump()) + +# Detect that 'vscode init' is running +from SCons.Script import COMMAND_LINE_TARGETS +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + import subprocess,os,re PIO_VERSION_MIN = (5, 0, 3) @@ -31,10 +40,6 @@ from platformio.package.meta import PackageSpec from platformio.project.config import ProjectConfig -Import("env") - -#print(env.Dump()) - try: verbose = int(env.GetProjectOption('custom_verbose')) except: diff --git a/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py index 15c953156caf..955f002016dc 100644 --- a/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py +++ b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py @@ -1,6 +1,13 @@ # # copy_marlin_variant_to_framework.py # +Import("env") + +# Detect that 'vscode init' is running +from SCons.Script import COMMAND_LINE_TARGETS +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + import os,shutil from SCons.Script import DefaultEnvironment from platformio import util diff --git a/buildroot/share/PlatformIO/scripts/preflight-checks.py b/buildroot/share/PlatformIO/scripts/preflight-checks.py index 6b499a8bcdc5..f89c89132325 100644 --- a/buildroot/share/PlatformIO/scripts/preflight-checks.py +++ b/buildroot/share/PlatformIO/scripts/preflight-checks.py @@ -2,9 +2,15 @@ # preflight-checks.py # Check for common issues prior to compiling # -import os,re,sys Import("env") +# Detect that 'vscode init' is running +from SCons.Script import COMMAND_LINE_TARGETS +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + +import os,re,sys + def get_envs_for_board(board): with open(os.path.join("Marlin", "src", "pins", "pins.h"), "r") as file: diff --git a/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h b/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h index 81f2ae3e19a1..dbbb7b48327a 100644 --- a/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h +++ b/buildroot/share/PlatformIO/variants/megaextendedpins/pins_arduino.h @@ -89,7 +89,7 @@ static const uint8_t A15 = PIN_A15; #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ (((p) >= 50) && ((p) <= 53)) || \ - (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : nullptr ) #define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ @@ -97,7 +97,7 @@ static const uint8_t A15 = PIN_A15; #define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ - ((uint8_t *)0) ) ) + nullptr ) ) #define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ ( ((p) == 50) ? 3 : \ diff --git a/buildroot/tests/BIGTREE_GTR_V1_0 b/buildroot/tests/BIGTREE_GTR_V1_0 index 95a1e0acac9e..24293a49325a 100755 --- a/buildroot/tests/BIGTREE_GTR_V1_0 +++ b/buildroot/tests/BIGTREE_GTR_V1_0 @@ -26,5 +26,12 @@ opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_INIT_BEFORE_SWAP TOOLCHANGE_FS_PRIME_FIRST_USED PID_PARAMS_PER_HOTEND exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Triple Z" "$3" +restore_configs +opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ + EXTRUDERS 3 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 \ + SERVO_DELAY '{ 300, 300, 300 }' +opt_enable SWITCHING_TOOLHEAD TOOL_SENSOR +exec_test $1 $2 "BigTreeTech GTR | Switching Toolhead | Tool Sensors" "$3" + # clean up restore_configs diff --git a/buildroot/tests/LPC1768 b/buildroot/tests/LPC1768 index eef0857dac8e..152a49852a14 100755 --- a/buildroot/tests/LPC1768 +++ b/buildroot/tests/LPC1768 @@ -26,8 +26,8 @@ restore_configs opt_set MOTHERBOARD BOARD_MKS_SBASE \ EXTRUDERS 2 TEMP_SENSOR_1 1 \ NUM_SERVOS 2 SERVO_DELAY '{ 300, 300 }' -opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR ULTIMAKERCONTROLLER -exec_test $1 $2 "MKS SBASE with SWITCHING_NOZZLE" "$3" +opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR ULTIMAKERCONTROLLER REALTIME_REPORTING_COMMANDS FULL_REPORT_TO_HOST_FEATURE +exec_test $1 $2 "MKS SBASE with SWITCHING_NOZZLE, Grbl Realtime Report" "$3" restore_configs opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EEB \ diff --git a/ini/avr.ini b/ini/avr.ini index 944646190a1e..1b208400a35b 100644 --- a/ini/avr.ini +++ b/ini/avr.ini @@ -13,6 +13,7 @@ # AVR (8-bit) Common Environment values # [common_avr8] +build_flags = ${common.build_flags} -Wl,--relax board_build.f_cpu = 16000000L src_filter = ${common.default_src_filter} + diff --git a/platformio.ini.orig b/platformio.ini.orig index 913bb44ae0b2..87b6e8a90b4a 100644 --- a/platformio.ini.orig +++ b/platformio.ini.orig @@ -38,6 +38,13 @@ extra_configs = # The 'common' values are used for most Marlin builds # [common] +build_flags = -fmax-errors=5 -g3 -D__MARLIN_FIRMWARE__ -fmerge-constants +extra_scripts = + pre:buildroot/share/PlatformIO/scripts/common-dependencies.py + pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py + pre:buildroot/share/PlatformIO/scripts/preflight-checks.py + post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py +lib_deps = default_src_filter = + - - + - - - - - - - - @@ -227,13 +234,6 @@ default_src_filter = + - - + - - - - - -extra_scripts = - pre:buildroot/share/PlatformIO/scripts/common-dependencies.py - pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py - pre:buildroot/share/PlatformIO/scripts/preflight-checks.py - post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py -build_flags = -fmax-errors=5 -g3 -D__MARLIN_FIRMWARE__ -fmerge-constants -lib_deps = # # Default values apply to all 'env:' prefixed environments